aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorUbitUmarov2012-04-16 16:16:55 +0100
committerUbitUmarov2012-04-16 16:16:55 +0100
commit86a2169d7343825c74ae271f637002377b92b438 (patch)
tree5bfc66b130edcacc738d3f4e8b4efa854a37fe7e /OpenSim/Region/Physics
parentUse chode character actor.SetMomentum() to force full restore Velocity in sce... (diff)
downloadopensim-SC-86a2169d7343825c74ae271f637002377b92b438.zip
opensim-SC-86a2169d7343825c74ae271f637002377b92b438.tar.gz
opensim-SC-86a2169d7343825c74ae271f637002377b92b438.tar.bz2
opensim-SC-86a2169d7343825c74ae271f637002377b92b438.tar.xz
ubitODE + physmanager: - Revised use of ODE collisions categories and bits(flags) for better use as filters together with top spaces (for example physical prims are on topactivespace and not physical are on topstaticspace) - Added new world raycast with filters. This blocks calling thread with a timeout of 500ms waiting for heartbeat ode thread signal job done. - Don't let ode bodies being disabled for 2 long except for vehicles. This is necessary to detect when the object is at rest at top of other and that is removed. Assume that vehicles can be enabled by used action.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs6
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs40
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs29
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs1069
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs326
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs8
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs234
7 files changed, 983 insertions, 729 deletions
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index be67204..b66d7f1 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -172,6 +172,12 @@ namespace OpenSim.Region.Physics.Manager
172 172
173 public virtual bool Phantom { get; set; } 173 public virtual bool Phantom { get; set; }
174 174
175 public virtual bool IsVolumeDtc
176 {
177 get { return false; }
178 set { return; }
179 }
180
175 public virtual byte PhysicsShapeType { get; set; } 181 public virtual byte PhysicsShapeType { get; set; }
176 182
177 public abstract PrimitiveBaseShape Shape { set; } 183 public abstract PrimitiveBaseShape Shape { set; }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index f2c0c28..d10a2aa 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -43,6 +43,34 @@ namespace OpenSim.Region.Physics.Manager
43 public delegate void JointDeactivated(PhysicsJoint joint); 43 public delegate void JointDeactivated(PhysicsJoint joint);
44 public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation" 44 public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation"
45 45
46 public enum RayFilterFlags:ushort
47 {
48 // the flags
49 water = 0x01,
50 land = 0x02,
51 agent = 0x04,
52 nonphysical = 0x08,
53 physical = 0x10,
54 phantom = 0x20,
55 volumedtc = 0x40,
56
57 // ray cast colision control (may only work for meshs)
58 BackFaceCull = 0x4000,
59 ClosestHit = 0x8000,
60
61 // some combinations
62 LSLPhanton = phantom | volumedtc,
63 PrimsNonPhantom = nonphysical | physical,
64 PrimsNonPhantomAgents = nonphysical | physical | agent,
65
66 AllPrims = nonphysical | phantom | volumedtc | physical,
67 AllButLand = agent | nonphysical | physical | phantom | volumedtc,
68
69 ClosestAndBackCull = ClosestHit | BackFaceCull,
70
71 All = 0x3f
72 }
73
46 /// <summary> 74 /// <summary>
47 /// Contact result from a raycast. 75 /// Contact result from a raycast.
48 /// </summary> 76 /// </summary>
@@ -54,6 +82,8 @@ namespace OpenSim.Region.Physics.Manager
54 public Vector3 Normal; 82 public Vector3 Normal;
55 } 83 }
56 84
85
86
57 public abstract class PhysicsScene 87 public abstract class PhysicsScene
58 { 88 {
59// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 89// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -280,6 +310,16 @@ namespace OpenSim.Region.Physics.Manager
280 return new List<ContactResult>(); 310 return new List<ContactResult>();
281 } 311 }
282 312
313 public virtual object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
314 {
315 return null;
316 }
317
318 public virtual bool SuportsRaycastWorldFiltered()
319 {
320 return false;
321 }
322
283 public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){} 323 public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){}
284 public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { } 324 public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
285 public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count) 325 public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index 4266fda..b9bb06e 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -115,12 +115,10 @@ namespace OpenSim.Region.Physics.OdePlugin
115 private CollisionCategories m_collisionCategories = (CollisionCategories.Character); 115 private CollisionCategories m_collisionCategories = (CollisionCategories.Character);
116 116
117 // Default, Collide with Other Geometries, spaces, bodies and characters. 117 // Default, Collide with Other Geometries, spaces, bodies and characters.
118 private CollisionCategories m_collisionFlags = (CollisionCategories.Geom 118 private CollisionCategories m_collisionFlags = (CollisionCategories.Character
119 | CollisionCategories.Space 119 | CollisionCategories.Geom
120 | CollisionCategories.Body
121 | CollisionCategories.Character
122 ); 120 );
123 // we do land collisions not ode | CollisionCategories.Land); 121 // we do land collisions not ode | CollisionCategories.Land);
124 public IntPtr Body = IntPtr.Zero; 122 public IntPtr Body = IntPtr.Zero;
125 private OdeScene _parent_scene; 123 private OdeScene _parent_scene;
126 public IntPtr Shell = IntPtr.Zero; 124 public IntPtr Shell = IntPtr.Zero;
@@ -639,6 +637,8 @@ namespace OpenSim.Region.Physics.OdePlugin
639 637
640 public override void SetMomentum(Vector3 momentum) 638 public override void SetMomentum(Vector3 momentum)
641 { 639 {
640 if (momentum.IsFinite())
641 AddChange(changes.Momentum, momentum);
642 } 642 }
643 643
644 644
@@ -663,8 +663,8 @@ namespace OpenSim.Region.Physics.OdePlugin
663 } 663 }
664 Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH); 664 Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
665 665
666 d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); 666 d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories);
667 d.GeomSetCollideBits(Shell, (int)m_collisionFlags); 667 d.GeomSetCollideBits(Shell, (uint)m_collisionFlags);
668 668
669 d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); 669 d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
670 670
@@ -759,7 +759,6 @@ namespace OpenSim.Region.Physics.OdePlugin
759 _parent_scene.geom_name_map.Remove(Shell); 759 _parent_scene.geom_name_map.Remove(Shell);
760 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); 760 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
761 d.GeomDestroy(Shell); 761 d.GeomDestroy(Shell);
762 _parent_scene.geom_name_map.Remove(Shell);
763 Shell = IntPtr.Zero; 762 Shell = IntPtr.Zero;
764 } 763 }
765 } 764 }
@@ -1324,6 +1323,16 @@ namespace OpenSim.Region.Physics.OdePlugin
1324 } 1323 }
1325 } 1324 }
1326 1325
1326 // for now momentum is actually velocity
1327 private void changeMomentum(Vector3 newmomentum)
1328 {
1329 _velocity = newmomentum;
1330 _target_velocity = newmomentum;
1331 m_pidControllerActive = true;
1332 if (Body != IntPtr.Zero)
1333 d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z);
1334 }
1335
1327 private void donullchange() 1336 private void donullchange()
1328 { 1337 {
1329 } 1338 }
@@ -1395,6 +1404,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1395 case changes.Size: 1404 case changes.Size:
1396 changeSize((Vector3)arg); 1405 changeSize((Vector3)arg);
1397 break; 1406 break;
1407
1408 case changes.Momentum:
1409 changeMomentum((Vector3)arg);
1410 break;
1398/* not in use for now 1411/* not in use for now
1399 case changes.Shape: 1412 case changes.Shape:
1400 changeShape((PrimitiveBaseShape)arg); 1413 changeShape((PrimitiveBaseShape)arg);
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index f739183..32c4722 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -108,25 +108,29 @@ namespace OpenSim.Region.Physics.OdePlugin
108 private float m_waterHeight; 108 private float m_waterHeight;
109 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. 109 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
110 110
111 private int body_autodisable_frames = 20; 111 private int body_autodisable_frames = 5;
112 private int bodydisablecontrol = 0;
113
114
115 // Default we're a Geometry
116 private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
117 // Default colide nonphysical don't try to colide with anything
118 private const CollisionCategories m_default_collisionFlagsNotPhysical = 0;
119
120 private const CollisionCategories m_default_collisionFlagsPhysical = (CollisionCategories.Geom |
121 CollisionCategories.Character |
122 CollisionCategories.Land |
123 CollisionCategories.VolumeDtc);
112 124
113 private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
114 | CollisionCategories.Space
115 | CollisionCategories.Body
116 | CollisionCategories.Character
117 );
118// private bool m_collidesLand = true; 125// private bool m_collidesLand = true;
119 private bool m_collidesWater; 126 private bool m_collidesWater;
120 public bool m_returnCollisions; 127 public bool m_returnCollisions;
121 private bool m_softcolide;
122 128
123 private bool m_NoColide; // for now only for internal use for bad meshs 129 private bool m_NoColide; // for now only for internal use for bad meshs
124 130
125 // Default we're a Geometry
126 private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
127 131
128 // Default, Collide with Other Geometries, spaces and Bodies 132 // Default, Collide with Other Geometries, spaces and Bodies
129 private CollisionCategories m_collisionFlags = m_default_collisionFlags; 133 private CollisionCategories m_collisionFlags = m_default_collisionFlagsNotPhysical;
130 134
131 public bool m_disabled; 135 public bool m_disabled;
132 136
@@ -179,6 +183,7 @@ namespace OpenSim.Region.Physics.OdePlugin
179 public float primOOBradiusSQ; 183 public float primOOBradiusSQ;
180 public d.Mass primdMass; // prim inertia information on it's own referencial 184 public d.Mass primdMass; // prim inertia information on it's own referencial
181 float primMass; // prim own mass 185 float primMass; // prim own mass
186 float primVolume; // prim own volume;
182 float _mass; // object mass acording to case 187 float _mass; // object mass acording to case
183 private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb 188 private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb
184 189
@@ -216,6 +221,14 @@ namespace OpenSim.Region.Physics.OdePlugin
216 } 221 }
217 } 222 }
218 223
224 public override bool IsVolumeDtc
225 {
226 set { return; }
227 get { return m_isVolumeDetect; }
228
229 }
230
231
219 public override bool Phantom // this is not reliable for internal use 232 public override bool Phantom // this is not reliable for internal use
220 { 233 {
221 get { return m_fakeisphantom; } 234 get { return m_fakeisphantom; }
@@ -327,10 +340,7 @@ namespace OpenSim.Region.Physics.OdePlugin
327 } 340 }
328 341
329 if (m_colliderfilter == 0) 342 if (m_colliderfilter == 0)
330 {
331 m_softcolide = false;
332 m_iscolliding = false; 343 m_iscolliding = false;
333 }
334 else 344 else
335 m_iscolliding = true; 345 m_iscolliding = true;
336 } 346 }
@@ -422,6 +432,10 @@ namespace OpenSim.Region.Physics.OdePlugin
422 432
423 public override Vector3 GeometricCenter 433 public override Vector3 GeometricCenter
424 { 434 {
435 // this is not real geometric center but a average of positions relative to root prim acording to
436 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
437 // ignoring tortured prims details since sl also seems to ignore
438 // so no real use in doing it on physics
425 get 439 get
426 { 440 {
427 return Vector3.Zero; 441 return Vector3.Zero;
@@ -949,7 +963,6 @@ namespace OpenSim.Region.Physics.OdePlugin
949 963
950 m_iscolliding = false; 964 m_iscolliding = false;
951 m_colliderfilter = 0; 965 m_colliderfilter = 0;
952 m_softcolide = true;
953 m_NoColide = false; 966 m_NoColide = false;
954 967
955 hasOOBoffsetFromMesh = false; 968 hasOOBoffsetFromMesh = false;
@@ -992,6 +1005,132 @@ namespace OpenSim.Region.Physics.OdePlugin
992 m_collisionscore = 0; 1005 m_collisionscore = 0;
993 } 1006 }
994 1007
1008 private void UpdateCollisionCatFlags()
1009 {
1010 if(m_isphysical && m_disabled)
1011 {
1012 m_collisionCategories = 0;
1013 m_collisionFlags = 0;
1014 }
1015
1016 else if (m_isSelected)
1017 {
1018 m_collisionCategories = CollisionCategories.Selected;
1019 m_collisionFlags = 0;
1020 }
1021
1022 else if (m_isVolumeDetect)
1023 {
1024 m_collisionCategories = CollisionCategories.VolumeDtc;
1025 if (m_isphysical)
1026 m_collisionFlags = CollisionCategories.Geom | CollisionCategories.Character;
1027 else
1028 m_collisionFlags = 0;
1029 }
1030 else if (m_isphantom)
1031 {
1032 m_collisionCategories = CollisionCategories.Phantom;
1033 if (m_isphysical)
1034 m_collisionFlags = CollisionCategories.Land;
1035 else
1036 m_collisionFlags = 0;
1037 }
1038 else
1039 {
1040 m_collisionCategories = CollisionCategories.Geom;
1041 if (m_isphysical)
1042 m_collisionFlags = m_default_collisionFlagsPhysical;
1043 else
1044 m_collisionFlags = m_default_collisionFlagsNotPhysical;
1045 }
1046 }
1047
1048 private void ApplyCollisionCatFlags()
1049 {
1050 if (prim_geom != IntPtr.Zero)
1051 {
1052 if (!childPrim && childrenPrim.Count > 0)
1053 {
1054 foreach (OdePrim prm in childrenPrim)
1055 {
1056 if (m_isphysical && m_disabled)
1057 {
1058 prm.m_collisionCategories = 0;
1059 prm.m_collisionFlags = 0;
1060 }
1061 else
1062 {
1063 // preserve some
1064 if (prm.m_isSelected)
1065 {
1066 prm.m_collisionCategories = CollisionCategories.Selected;
1067 prm.m_collisionFlags = 0;
1068 }
1069 else if (prm.IsVolumeDtc)
1070 {
1071 prm.m_collisionCategories = CollisionCategories.VolumeDtc;
1072 if (m_isphysical)
1073 prm.m_collisionFlags = CollisionCategories.Geom | CollisionCategories.Character;
1074 else
1075 prm.m_collisionFlags = 0;
1076 }
1077 else if (prm.m_isphantom)
1078 {
1079 prm.m_collisionCategories = CollisionCategories.Phantom;
1080 if (m_isphysical)
1081 prm.m_collisionFlags = CollisionCategories.Land;
1082 else
1083 prm.m_collisionFlags = 0;
1084 }
1085 else
1086 {
1087 prm.m_collisionCategories = m_collisionCategories;
1088 prm.m_collisionFlags = m_collisionFlags;
1089 }
1090 }
1091
1092 if (prm.prim_geom != IntPtr.Zero)
1093 {
1094 if (prm.m_NoColide)
1095 {
1096 d.GeomSetCategoryBits(prm.prim_geom, 0);
1097 if (m_isphysical)
1098 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1099 else
1100 d.GeomSetCollideBits(prm.prim_geom, 0);
1101 }
1102 else
1103 {
1104 d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
1105 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
1106 }
1107 }
1108 }
1109 }
1110
1111 if (m_NoColide)
1112 {
1113 d.GeomSetCategoryBits(prim_geom, 0);
1114 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
1115 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
1116 {
1117 d.GeomSetCategoryBits(collide_geom, 0);
1118 d.GeomSetCollideBits(collide_geom, (uint)CollisionCategories.Land);
1119 }
1120 }
1121 else
1122 {
1123 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1124 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1125 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
1126 {
1127 d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories);
1128 d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags);
1129 }
1130 }
1131 }
1132 }
1133
995 private void createAMotor(Vector3 axis) 1134 private void createAMotor(Vector3 axis)
996 { 1135 {
997 if (Body == IntPtr.Zero) 1136 if (Body == IntPtr.Zero)
@@ -1188,7 +1327,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1188 d.GeomSetCategoryBits(prim_geom, 0); 1327 d.GeomSetCategoryBits(prim_geom, 0);
1189 if (m_isphysical) 1328 if (m_isphysical)
1190 { 1329 {
1191 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); 1330 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
1192 } 1331 }
1193 else 1332 else
1194 { 1333 {
@@ -1198,8 +1337,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1198 } 1337 }
1199 else 1338 else
1200 { 1339 {
1201 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1340 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1202 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1341 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1203 } 1342 }
1204 1343
1205 CalcPrimBodyData(); 1344 CalcPrimBodyData();
@@ -1296,6 +1435,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1296 } 1435 }
1297 1436
1298 prim_geom = IntPtr.Zero; 1437 prim_geom = IntPtr.Zero;
1438 collide_geom = IntPtr.Zero;
1299 } 1439 }
1300 else 1440 else
1301 { 1441 {
@@ -1319,66 +1459,23 @@ namespace OpenSim.Region.Physics.OdePlugin
1319 { 1459 {
1320 IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace); 1460 IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace);
1321 prim.m_targetSpace = targetSpace; 1461 prim.m_targetSpace = targetSpace;
1322 d.GeomEnable(prim_geom); 1462 collide_geom = IntPtr.Zero;
1323 } 1463 }
1324 1464
1325 public void enableBodySoft() 1465 public void enableBodySoft()
1326 { 1466 {
1467 m_disabled = false;
1327 if (!childPrim && !m_isSelected) 1468 if (!childPrim && !m_isSelected)
1328 { 1469 {
1329 if (m_isphysical && Body != IntPtr.Zero) 1470 if (m_isphysical && Body != IntPtr.Zero)
1330 { 1471 {
1331 if (m_isphantom && !m_isVolumeDetect) 1472 UpdateCollisionCatFlags();
1332 { 1473 ApplyCollisionCatFlags();
1333 m_collisionCategories = 0;
1334 m_collisionFlags = CollisionCategories.Land;
1335 }
1336 else
1337 {
1338 m_collisionCategories |= CollisionCategories.Body;
1339 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1340 }
1341
1342 foreach (OdePrim prm in childrenPrim)
1343 {
1344 prm.m_collisionCategories = m_collisionCategories;
1345 prm.m_collisionFlags = m_collisionFlags;
1346 1474
1347 if (prm.prim_geom != IntPtr.Zero)
1348 {
1349 if (prm.m_NoColide)
1350 {
1351 d.GeomSetCategoryBits(prm.prim_geom, 0);
1352 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1353 }
1354 else
1355 {
1356 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
1357 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
1358 }
1359 d.GeomEnable(prm.prim_geom);
1360 }
1361 }
1362
1363 if (prim_geom != IntPtr.Zero)
1364 {
1365 if (m_NoColide)
1366 {
1367 d.GeomSetCategoryBits(prim_geom, 0);
1368 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
1369 }
1370 else
1371 {
1372 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1373 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1374 }
1375 d.GeomEnable(prim_geom);
1376 }
1377 d.BodyEnable(Body); 1475 d.BodyEnable(Body);
1378 } 1476 }
1379 } 1477 }
1380 m_disabled = false; 1478 resetCollisionAccounting();
1381 resetCollisionAccounting(); // this sets m_disable to false
1382 } 1479 }
1383 1480
1384 private void disableBodySoft() 1481 private void disableBodySoft()
@@ -1388,45 +1485,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1388 { 1485 {
1389 if (m_isphysical && Body != IntPtr.Zero) 1486 if (m_isphysical && Body != IntPtr.Zero)
1390 { 1487 {
1391 m_collisionCategories &= ~CollisionCategories.Body; 1488 if (m_isSelected)
1392 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 1489 m_collisionFlags = CollisionCategories.Selected;
1393 1490 else
1394 foreach (OdePrim prm in childrenPrim) 1491 m_collisionCategories = 0;
1395 { 1492 m_collisionFlags = 0;
1396 prm.m_collisionCategories = m_collisionCategories; 1493 ApplyCollisionCatFlags();
1397 prm.m_collisionFlags = m_collisionFlags;
1398
1399 if (prm.prim_geom != IntPtr.Zero)
1400 {
1401 if (prm.m_NoColide)
1402 {
1403 d.GeomSetCategoryBits(prm.prim_geom, 0);
1404 d.GeomSetCollideBits(prm.prim_geom, 0);
1405 }
1406 else
1407 {
1408 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
1409 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
1410 }
1411 d.GeomDisable(prm.prim_geom);
1412 }
1413 }
1414
1415 if (prim_geom != IntPtr.Zero)
1416 {
1417 if (m_NoColide)
1418 {
1419 d.GeomSetCategoryBits(prim_geom, 0);
1420 d.GeomSetCollideBits(prim_geom, 0);
1421 }
1422 else
1423 {
1424 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1425 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1426 }
1427 d.GeomDisable(prim_geom);
1428 }
1429
1430 d.BodyDisable(Body); 1494 d.BodyDisable(Body);
1431 } 1495 }
1432 } 1496 }
@@ -1566,7 +1630,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1566 // d.BodySetAngularDampingThreshold(Body, 0.001f); 1630 // d.BodySetAngularDampingThreshold(Body, 0.001f);
1567 d.BodySetDamping(Body, .002f, .002f); 1631 d.BodySetDamping(Body, .002f, .002f);
1568 1632
1569
1570 if (m_targetSpace != IntPtr.Zero) 1633 if (m_targetSpace != IntPtr.Zero)
1571 { 1634 {
1572 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1635 _parent_scene.waitForSpaceUnlock(m_targetSpace);
@@ -1588,6 +1651,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1588 d.SpaceSetSublevel(m_targetSpace, 3); 1651 d.SpaceSetSublevel(m_targetSpace, 3);
1589 d.SpaceSetCleanup(m_targetSpace, false); 1652 d.SpaceSetCleanup(m_targetSpace, false);
1590 d.SpaceAdd(m_targetSpace, prim_geom); 1653 d.SpaceAdd(m_targetSpace, prim_geom);
1654
1655 d.GeomSetCategoryBits(m_targetSpace, (uint)(CollisionCategories.Space |
1656 CollisionCategories.Geom |
1657 CollisionCategories.Phantom |
1658 CollisionCategories.VolumeDtc
1659 ));
1660 d.GeomSetCollideBits(m_targetSpace, 0);
1591 collide_geom = m_targetSpace; 1661 collide_geom = m_targetSpace;
1592 } 1662 }
1593 1663
@@ -1619,38 +1689,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1619 d.SpaceAdd(m_targetSpace, prm.prim_geom); 1689 d.SpaceAdd(m_targetSpace, prm.prim_geom);
1620 } 1690 }
1621 1691
1622 if (m_isSelected || m_disabled)
1623 {
1624 prm.m_collisionCategories &= ~CollisionCategories.Body;
1625 prm.m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
1626 d.GeomDisable(prm.prim_geom);
1627 }
1628 else
1629 {
1630 if (m_isphantom && !m_isVolumeDetect)
1631 {
1632 prm.m_collisionCategories = 0;
1633 prm.m_collisionFlags = CollisionCategories.Land;
1634 }
1635 else
1636 {
1637 prm.m_collisionCategories |= CollisionCategories.Body;
1638 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1639 }
1640 d.GeomEnable(prm.prim_geom);
1641 }
1642
1643 if (prm.m_NoColide)
1644 {
1645 d.GeomSetCategoryBits(prm.prim_geom, 0);
1646 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1647 d.GeomEnable(prm.prim_geom);
1648 }
1649 else
1650 {
1651 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
1652 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
1653 }
1654 prm.m_collisionscore = 0; 1692 prm.m_collisionscore = 0;
1655 1693
1656 if(!m_disabled) 1694 if(!m_disabled)
@@ -1666,45 +1704,21 @@ namespace OpenSim.Region.Physics.OdePlugin
1666 createAMotor(m_angularlock); 1704 createAMotor(m_angularlock);
1667 } 1705 }
1668 1706
1707 m_collisionscore = 0;
1708
1709 UpdateCollisionCatFlags();
1710 ApplyCollisionCatFlags();
1711
1669 if (m_isSelected || m_disabled) 1712 if (m_isSelected || m_disabled)
1670 { 1713 {
1671 m_collisionCategories &= ~CollisionCategories.Body;
1672 m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
1673
1674 d.GeomDisable(prim_geom);
1675 d.BodyDisable(Body); 1714 d.BodyDisable(Body);
1676 } 1715 }
1677 else 1716 else
1678 { 1717 {
1679 if (m_isphantom && !m_isVolumeDetect)
1680 {
1681 m_collisionCategories = 0;
1682 m_collisionFlags = CollisionCategories.Land;
1683 }
1684 else
1685 {
1686 m_collisionCategories |= CollisionCategories.Body;
1687 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1688 }
1689
1690 d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); 1718 d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z);
1691 d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); 1719 d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
1692 } 1720 }
1693 1721
1694 if (m_NoColide)
1695 {
1696 d.GeomSetCategoryBits(prim_geom, 0);
1697 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
1698 }
1699 else
1700 {
1701 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1702 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1703 }
1704
1705 m_collisionscore = 0;
1706
1707 m_softcolide = true;
1708 _parent_scene.addActivePrim(this); 1722 _parent_scene.addActivePrim(this);
1709 _parent_scene.addActiveGroups(this); 1723 _parent_scene.addActiveGroups(this);
1710 } 1724 }
@@ -1714,8 +1728,22 @@ namespace OpenSim.Region.Physics.OdePlugin
1714 if (Body != IntPtr.Zero) 1728 if (Body != IntPtr.Zero)
1715 { 1729 {
1716 _parent_scene.remActivePrim(this); 1730 _parent_scene.remActivePrim(this);
1717 m_collisionCategories &= ~CollisionCategories.Body; 1731
1718 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 1732 collide_geom = IntPtr.Zero;
1733
1734 if (m_disabled)
1735 m_collisionCategories = 0;
1736 else if (m_isSelected)
1737 m_collisionCategories = CollisionCategories.Selected;
1738 else if (m_isVolumeDetect)
1739 m_collisionCategories = CollisionCategories.VolumeDtc;
1740 else if (m_isphantom)
1741 m_collisionCategories = CollisionCategories.Phantom;
1742 else
1743 m_collisionCategories = CollisionCategories.Geom;
1744
1745 m_collisionFlags = 0;
1746
1719 if (prim_geom != IntPtr.Zero) 1747 if (prim_geom != IntPtr.Zero)
1720 { 1748 {
1721 if (m_NoColide) 1749 if (m_NoColide)
@@ -1725,8 +1753,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1725 } 1753 }
1726 else 1754 else
1727 { 1755 {
1728 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1756 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1729 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1757 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1730 } 1758 }
1731 UpdateDataFromGeom(); 1759 UpdateDataFromGeom();
1732 d.GeomSetBody(prim_geom, IntPtr.Zero); 1760 d.GeomSetBody(prim_geom, IntPtr.Zero);
@@ -1740,8 +1768,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1740 foreach (OdePrim prm in childrenPrim) 1768 foreach (OdePrim prm in childrenPrim)
1741 { 1769 {
1742 _parent_scene.remActivePrim(prm); 1770 _parent_scene.remActivePrim(prm);
1743 prm.m_collisionCategories = m_collisionCategories; 1771
1744 prm.m_collisionFlags = m_collisionFlags; 1772 if (prm.m_isSelected)
1773 prm.m_collisionCategories = CollisionCategories.Selected;
1774 else if (prm.m_isVolumeDetect)
1775 prm.m_collisionCategories = CollisionCategories.VolumeDtc;
1776 else if (prm.m_isphantom)
1777 prm.m_collisionCategories = CollisionCategories.Phantom;
1778 else
1779 prm.m_collisionCategories = CollisionCategories.Geom;
1780
1781 prm.m_collisionFlags = 0;
1782
1745 if (prm.prim_geom != IntPtr.Zero) 1783 if (prm.prim_geom != IntPtr.Zero)
1746 { 1784 {
1747 if (prm.m_NoColide) 1785 if (prm.m_NoColide)
@@ -1751,8 +1789,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1751 } 1789 }
1752 else 1790 else
1753 { 1791 {
1754 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); 1792 d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
1755 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); 1793 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
1756 } 1794 }
1757 prm.UpdateDataFromGeom(); 1795 prm.UpdateDataFromGeom();
1758 SetInStaticSpace(prm); 1796 SetInStaticSpace(prm);
@@ -2292,6 +2330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2292 // keep using basic shape mass for now 2330 // keep using basic shape mass for now
2293 volume = CalculatePrimVolume(); 2331 volume = CalculatePrimVolume();
2294 2332
2333 primVolume = volume;
2295 primMass = m_density * volume; 2334 primMass = m_density * volume;
2296 2335
2297 if (primMass <= 0) 2336 if (primMass <= 0)
@@ -2515,12 +2554,13 @@ namespace OpenSim.Region.Physics.OdePlugin
2515 d.GeomSetQuaternion(prim_geom, ref myrot); 2554 d.GeomSetQuaternion(prim_geom, ref myrot);
2516 2555
2517 if (!m_isphysical) 2556 if (!m_isphysical)
2557 {
2518 SetInStaticSpace(this); 2558 SetInStaticSpace(this);
2519 } 2559 UpdateCollisionCatFlags();
2520 2560 ApplyCollisionCatFlags();
2521 if (m_isphysical && Body == IntPtr.Zero) 2561 }
2522 { 2562 else
2523 MakeBody(); 2563 MakeBody();
2524 } 2564 }
2525 } 2565 }
2526 2566
@@ -2602,86 +2642,12 @@ namespace OpenSim.Region.Physics.OdePlugin
2602 } 2642 }
2603 } 2643 }
2604 2644
2605
2606 private void changePhantomStatus(bool newval) 2645 private void changePhantomStatus(bool newval)
2607 { 2646 {
2608 m_isphantom = newval; 2647 m_isphantom = newval;
2609 2648
2610 if (m_isSelected) 2649 UpdateCollisionCatFlags();
2611 { 2650 ApplyCollisionCatFlags();
2612 m_collisionCategories = CollisionCategories.Selected;
2613 m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
2614 }
2615 else
2616 {
2617 if (m_isphantom && !m_isVolumeDetect)
2618 {
2619 m_collisionCategories = 0;
2620 if (m_isphysical)
2621 m_collisionFlags = CollisionCategories.Land;
2622 else
2623 m_collisionFlags = 0; // should never happen
2624 }
2625
2626 else
2627 {
2628 m_collisionCategories = CollisionCategories.Geom;
2629 if (m_isphysical)
2630 m_collisionCategories |= CollisionCategories.Body;
2631
2632 m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land;
2633
2634 if (m_collidesWater)
2635 m_collisionFlags |= CollisionCategories.Water;
2636 }
2637 }
2638
2639 if (!childPrim)
2640 {
2641 foreach (OdePrim prm in childrenPrim)
2642 {
2643 prm.m_collisionCategories = m_collisionCategories;
2644 prm.m_collisionFlags = m_collisionFlags;
2645
2646 if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero)
2647 {
2648 if (prm.m_NoColide)
2649 {
2650 d.GeomSetCategoryBits(prm.prim_geom, 0);
2651 if (m_isphysical)
2652 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
2653 else
2654 d.GeomSetCollideBits(prm.prim_geom, 0);
2655 }
2656 else
2657 {
2658 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
2659 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
2660 }
2661 if(!m_isSelected)
2662 d.GeomEnable(prm.prim_geom);
2663 }
2664 }
2665 }
2666
2667 if (!m_disabled && prim_geom != IntPtr.Zero)
2668 {
2669 if (m_NoColide)
2670 {
2671 d.GeomSetCategoryBits(prim_geom, 0);
2672 if (m_isphysical)
2673 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
2674 else
2675 d.GeomSetCollideBits(prim_geom, 0);
2676 }
2677 else
2678 {
2679 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
2680 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2681 }
2682 if(!m_isSelected)
2683 d.GeomEnable(prim_geom);
2684 }
2685 } 2651 }
2686 2652
2687 private void changeSelectedStatus(bool newval) 2653 private void changeSelectedStatus(bool newval)
@@ -2714,7 +2680,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2714 if (m_delaySelect || m_isphysical) 2680 if (m_delaySelect || m_isphysical)
2715 { 2681 {
2716 m_collisionCategories = CollisionCategories.Selected; 2682 m_collisionCategories = CollisionCategories.Selected;
2717 m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); 2683 m_collisionFlags = 0;
2718 2684
2719 if (!childPrim) 2685 if (!childPrim)
2720 { 2686 {
@@ -2733,10 +2699,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2733 } 2699 }
2734 else 2700 else
2735 { 2701 {
2736 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); 2702 d.GeomSetCategoryBits(prm.prim_geom, (uint)m_collisionCategories);
2737 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); 2703 d.GeomSetCollideBits(prm.prim_geom, (uint)m_collisionFlags);
2738 } 2704 }
2739 d.GeomDisable(prm.prim_geom);
2740 } 2705 }
2741 prm.m_delaySelect = false; 2706 prm.m_delaySelect = false;
2742 } 2707 }
@@ -2748,13 +2713,23 @@ namespace OpenSim.Region.Physics.OdePlugin
2748 { 2713 {
2749 d.GeomSetCategoryBits(prim_geom, 0); 2714 d.GeomSetCategoryBits(prim_geom, 0);
2750 d.GeomSetCollideBits(prim_geom, 0); 2715 d.GeomSetCollideBits(prim_geom, 0);
2716 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
2717 {
2718 d.GeomSetCategoryBits(collide_geom, 0);
2719 d.GeomSetCollideBits(collide_geom, 0);
2720 }
2721
2751 } 2722 }
2752 else 2723 else
2753 { 2724 {
2754 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 2725 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
2755 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 2726 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
2727 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
2728 {
2729 d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories);
2730 d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags);
2731 }
2756 } 2732 }
2757 d.GeomDisable(prim_geom);
2758 } 2733 }
2759 2734
2760 m_delaySelect = false; 2735 m_delaySelect = false;
@@ -2769,75 +2744,10 @@ namespace OpenSim.Region.Physics.OdePlugin
2769 if (!childPrim && Body != IntPtr.Zero && !m_disabled) 2744 if (!childPrim && Body != IntPtr.Zero && !m_disabled)
2770 d.BodyEnable(Body); 2745 d.BodyEnable(Body);
2771 2746
2772 if (m_isphantom && !m_isVolumeDetect) 2747 UpdateCollisionCatFlags();
2773 { 2748 ApplyCollisionCatFlags();
2774 m_collisionCategories = 0;
2775 if(m_isphysical)
2776 m_collisionFlags = CollisionCategories.Land;
2777 else
2778 m_collisionFlags = 0;
2779 }
2780 else
2781 {
2782 m_collisionCategories = CollisionCategories.Geom;
2783 if (m_isphysical)
2784 m_collisionCategories |= CollisionCategories.Body;
2785
2786 m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land;
2787
2788 if (m_collidesWater)
2789 m_collisionFlags |= CollisionCategories.Water;
2790 }
2791
2792 if (!childPrim)
2793 {
2794 foreach (OdePrim prm in childrenPrim)
2795 {
2796 prm.m_collisionCategories = m_collisionCategories;
2797 prm.m_collisionFlags = m_collisionFlags;
2798
2799 if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero)
2800 {
2801 if (prm.m_NoColide)
2802 {
2803 d.GeomSetCategoryBits(prm.prim_geom, 0);
2804 if (m_isphysical)
2805 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
2806 else
2807 d.GeomSetCollideBits(prm.prim_geom, 0);
2808 }
2809 else
2810 {
2811 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
2812 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
2813 }
2814 d.GeomEnable(prm.prim_geom);
2815 }
2816 prm.m_delaySelect = false;
2817 prm.m_softcolide = true;
2818 }
2819 }
2820
2821 if (!m_disabled && prim_geom != IntPtr.Zero)
2822 {
2823 if (m_NoColide)
2824 {
2825 d.GeomSetCategoryBits(prim_geom, 0);
2826 if (m_isphysical)
2827 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
2828 else
2829 d.GeomSetCollideBits(prim_geom, 0);
2830 }
2831 else
2832 {
2833 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
2834 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2835 }
2836 d.GeomEnable(prim_geom);
2837 }
2838 2749
2839 m_delaySelect = false; 2750 m_delaySelect = false;
2840 m_softcolide = true;
2841 } 2751 }
2842 2752
2843 resetCollisionAccounting(); 2753 resetCollisionAccounting();
@@ -2890,7 +2800,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2890 if (givefakepos < 0) 2800 if (givefakepos < 0)
2891 givefakepos = 0; 2801 givefakepos = 0;
2892 // changeSelectedStatus(); 2802 // changeSelectedStatus();
2893 m_softcolide = true;
2894 resetCollisionAccounting(); 2803 resetCollisionAccounting();
2895 } 2804 }
2896 2805
@@ -2951,7 +2860,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2951 givefakeori--; 2860 givefakeori--;
2952 if (givefakeori < 0) 2861 if (givefakeori < 0)
2953 givefakeori = 0; 2862 givefakeori = 0;
2954 m_softcolide = true;
2955 resetCollisionAccounting(); 2863 resetCollisionAccounting();
2956 } 2864 }
2957 2865
@@ -3022,7 +2930,6 @@ namespace OpenSim.Region.Physics.OdePlugin
3022 if (givefakeori < 0) 2930 if (givefakeori < 0)
3023 givefakeori = 0; 2931 givefakeori = 0;
3024 2932
3025 m_softcolide = true;
3026 resetCollisionAccounting(); 2933 resetCollisionAccounting();
3027 } 2934 }
3028 2935
@@ -3111,17 +3018,25 @@ namespace OpenSim.Region.Physics.OdePlugin
3111 d.GeomSetQuaternion(prim_geom, ref myrot); 3018 d.GeomSetQuaternion(prim_geom, ref myrot);
3112 } 3019 }
3113 3020
3114 if (chp) 3021 if (m_isphysical)
3115 { 3022 {
3116 if (parent != null) 3023 if (chp)
3117 { 3024 {
3118 parent.MakeBody(); 3025 if (parent != null)
3026 {
3027 parent.MakeBody();
3028 }
3119 } 3029 }
3030 else
3031 MakeBody();
3120 } 3032 }
3033
3121 else 3034 else
3122 MakeBody(); 3035 {
3036 UpdateCollisionCatFlags();
3037 ApplyCollisionCatFlags();
3038 }
3123 3039
3124 m_softcolide = true;
3125 resetCollisionAccounting(); 3040 resetCollisionAccounting();
3126 } 3041 }
3127 3042
@@ -3142,18 +3057,8 @@ namespace OpenSim.Region.Physics.OdePlugin
3142 { 3057 {
3143 m_collidesWater = newval; 3058 m_collidesWater = newval;
3144 3059
3145 if (prim_geom != IntPtr.Zero && !m_isphantom) 3060 UpdateCollisionCatFlags();
3146 { 3061 ApplyCollisionCatFlags();
3147 if (m_collidesWater)
3148 {
3149 m_collisionFlags |= CollisionCategories.Water;
3150 }
3151 else
3152 {
3153 m_collisionFlags &= ~CollisionCategories.Water;
3154 }
3155 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
3156 }
3157 } 3062 }
3158 3063
3159 private void changeSetTorque(Vector3 newtorque) 3064 private void changeSetTorque(Vector3 newtorque)
@@ -3240,6 +3145,8 @@ namespace OpenSim.Region.Physics.OdePlugin
3240 private void changeVolumedetetion(bool newVolDtc) 3145 private void changeVolumedetetion(bool newVolDtc)
3241 { 3146 {
3242 m_isVolumeDetect = newVolDtc; 3147 m_isVolumeDetect = newVolDtc;
3148 UpdateCollisionCatFlags();
3149 ApplyCollisionCatFlags();
3243 } 3150 }
3244 3151
3245 protected void changeBuilding(bool newbuilding) 3152 protected void changeBuilding(bool newbuilding)
@@ -3320,288 +3227,306 @@ namespace OpenSim.Region.Physics.OdePlugin
3320 public void Move() 3227 public void Move()
3321 { 3228 {
3322 if (!childPrim && m_isphysical && Body != IntPtr.Zero && 3229 if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
3323 !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building && !m_outbounds) 3230 !m_disabled && !m_isSelected && !m_building && !m_outbounds)
3324 // !m_disabled && !m_isSelected && !m_building && !m_outbounds) 3231 // !m_disabled && !m_isSelected && !m_building && !m_outbounds)
3325 { 3232 {
3326// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009 3233 // if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
3327
3328 float timestep = _parent_scene.ODE_STEPSIZE;
3329 3234
3330 // check outside region 3235 if (d.BodyIsEnabled(Body))
3331 d.Vector3 lpos;
3332 d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
3333
3334 if (lpos.Z < -100 || lpos.Z > 100000f)
3335 { 3236 {
3336 m_outbounds = true; 3237 float timestep = _parent_scene.ODE_STEPSIZE;
3337 3238
3338 lpos.Z = Util.Clip(lpos.Z, -100f, 100000f); 3239 // check outside region
3339 _acceleration.X = 0; 3240 d.Vector3 lpos;
3340 _acceleration.Y = 0; 3241 d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
3341 _acceleration.Z = 0;
3342 3242
3343 _velocity.X = 0; 3243 if (lpos.Z < -100 || lpos.Z > 100000f)
3344 _velocity.Y = 0; 3244 {
3345 _velocity.Z = 0; 3245 m_outbounds = true;
3346 m_rotationalVelocity.X = 0;
3347 m_rotationalVelocity.Y = 0;
3348 m_rotationalVelocity.Z = 0;
3349 3246
3350 d.BodySetLinearVel(Body, 0, 0, 0); // stop it 3247 lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
3351 d.BodySetAngularVel(Body, 0, 0, 0); // stop it 3248 _acceleration.X = 0;
3352 d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere 3249 _acceleration.Y = 0;
3353 m_lastposition = _position; 3250 _acceleration.Z = 0;
3354 m_lastorientation = _orientation;
3355 3251
3356 base.RequestPhysicsterseUpdate(); 3252 _velocity.X = 0;
3253 _velocity.Y = 0;
3254 _velocity.Z = 0;
3255 m_rotationalVelocity.X = 0;
3256 m_rotationalVelocity.Y = 0;
3257 m_rotationalVelocity.Z = 0;
3357 3258
3358 m_throttleUpdates = false; 3259 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
3359 throttleCounter = 0; 3260 d.BodySetAngularVel(Body, 0, 0, 0); // stop it
3360 _zeroFlag = true; 3261 d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere
3262 m_lastposition = _position;
3263 m_lastorientation = _orientation;
3361 3264
3362 disableBodySoft(); // disable it and colisions 3265 base.RequestPhysicsterseUpdate();
3363 base.RaiseOutOfBounds(_position);
3364 return;
3365 }
3366 3266
3367 if (lpos.X < 0f) 3267 m_throttleUpdates = false;
3368 { 3268 throttleCounter = 0;
3369 _position.X = Util.Clip(lpos.X, -2f, -0.1f); 3269 _zeroFlag = true;
3370 m_outbounds = true;
3371 }
3372 else if(lpos.X > _parent_scene.WorldExtents.X)
3373 {
3374 _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
3375 m_outbounds = true;
3376 }
3377 if (lpos.Y < 0f)
3378 {
3379 _position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
3380 m_outbounds = true;
3381 }
3382 else if(lpos.Y > _parent_scene.WorldExtents.Y)
3383 {
3384 _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
3385 m_outbounds = true;
3386 }
3387 3270
3388 if(m_outbounds) 3271 disableBodySoft(); // disable it and colisions
3389 { 3272 base.RaiseOutOfBounds(_position);
3390 m_lastposition = _position; 3273 return;
3391 m_lastorientation = _orientation; 3274 }
3392 3275
3393 d.Vector3 dtmp = d.BodyGetAngularVel(Body); 3276 if (lpos.X < 0f)
3394 m_rotationalVelocity.X = dtmp.X; 3277 {
3395 m_rotationalVelocity.Y = dtmp.Y; 3278 _position.X = Util.Clip(lpos.X, -2f, -0.1f);
3396 m_rotationalVelocity.Z = dtmp.Z; 3279 m_outbounds = true;
3280 }
3281 else if (lpos.X > _parent_scene.WorldExtents.X)
3282 {
3283 _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
3284 m_outbounds = true;
3285 }
3286 if (lpos.Y < 0f)
3287 {
3288 _position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
3289 m_outbounds = true;
3290 }
3291 else if (lpos.Y > _parent_scene.WorldExtents.Y)
3292 {
3293 _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
3294 m_outbounds = true;
3295 }
3397 3296
3398 dtmp = d.BodyGetLinearVel(Body); 3297 if (m_outbounds)
3399 _velocity.X = dtmp.X; 3298 {
3400 _velocity.Y = dtmp.Y; 3299 m_lastposition = _position;
3401 _velocity.Z = dtmp.Z; 3300 m_lastorientation = _orientation;
3402 3301
3403 d.BodySetLinearVel(Body, 0, 0, 0); // stop it 3302 d.Vector3 dtmp = d.BodyGetAngularVel(Body);
3404 d.BodySetAngularVel(Body, 0, 0, 0); 3303 m_rotationalVelocity.X = dtmp.X;
3405 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 3304 m_rotationalVelocity.Y = dtmp.Y;
3406 disableBodySoft(); // stop collisions 3305 m_rotationalVelocity.Z = dtmp.Z;
3407 base.RequestPhysicsterseUpdate();
3408 return;
3409 }
3410 3306
3307 dtmp = d.BodyGetLinearVel(Body);
3308 _velocity.X = dtmp.X;
3309 _velocity.Y = dtmp.Y;
3310 _velocity.Z = dtmp.Z;
3411 3311
3412 float fx = 0; 3312 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
3413 float fy = 0; 3313 d.BodySetAngularVel(Body, 0, 0, 0);
3414 float fz = 0; 3314 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3315 disableBodySoft(); // stop collisions
3316 base.RequestPhysicsterseUpdate();
3317 return;
3318 }
3415 3319
3416 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) 3320 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
3417 { 3321 {
3418 // 'VEHICLES' are dealt with in ODEDynamics.cs 3322 // 'VEHICLES' are dealt with in ODEDynamics.cs
3419 m_vehicle.Step(); 3323 m_vehicle.Step();
3420 } 3324 return;
3421 else 3325 }
3422 {
3423 float m_mass = _mass;
3424 3326
3425 // fz = 0f; 3327 else
3426 //m_log.Info(m_collisionFlags.ToString());
3427 if (m_usePID)
3428 { 3328 {
3429 3329
3430 // If the PID Controller isn't active then we set our force 3330 float fx = 0;
3431 // calculating base velocity to the current position 3331 float fy = 0;
3332 float fz = 0;
3432 3333
3433 if ((m_PIDTau < 1) && (m_PIDTau != 0)) 3334 float m_mass = _mass;
3434 {
3435 //PID_G = PID_G / m_PIDTau;
3436 m_PIDTau = 1;
3437 }
3438 3335
3439 if ((PID_G - m_PIDTau) <= 0) 3336 // fz = 0f;
3337 //m_log.Info(m_collisionFlags.ToString());
3338 if (m_usePID)
3440 { 3339 {
3441 PID_G = m_PIDTau + 1;
3442 }
3443 3340
3444 d.Vector3 vel = d.BodyGetLinearVel(Body); 3341 // If the PID Controller isn't active then we set our force
3445 d.Vector3 pos = d.BodyGetPosition(Body); 3342 // calculating base velocity to the current position
3446 _target_velocity =
3447 new Vector3(
3448 (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
3449 (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
3450 (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
3451 );
3452 3343
3453 // if velocity is zero, use position control; otherwise, velocity control 3344 if ((m_PIDTau < 1) && (m_PIDTau != 0))
3454 3345 {
3455 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) 3346 //PID_G = PID_G / m_PIDTau;
3456 { 3347 m_PIDTau = 1;
3457 // keep track of where we stopped. No more slippin' & slidin' 3348 }
3458
3459 // We only want to deactivate the PID Controller if we think we want to have our surrogate
3460 // react to the physics scene by moving it's position.
3461 // Avatar to Avatar collisions
3462 // Prim to avatar collisions
3463
3464 //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
3465 //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2);
3466 //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
3467 d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
3468 d.BodySetLinearVel(Body, 0, 0, 0);
3469 d.BodyAddForce(Body, 0, 0, fz);
3470 return;
3471 }
3472 else
3473 {
3474 _zeroFlag = false;
3475 3349
3476 // We're flying and colliding with something 3350 if ((PID_G - m_PIDTau) <= 0)
3477 fx = ((_target_velocity.X) - vel.X) * (PID_D); 3351 {
3478 fy = ((_target_velocity.Y) - vel.Y) * (PID_D); 3352 PID_G = m_PIDTau + 1;
3353 }
3479 3354
3480 // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; 3355 d.Vector3 vel = d.BodyGetLinearVel(Body);
3356 d.Vector3 pos = d.BodyGetPosition(Body);
3357 _target_velocity =
3358 new Vector3(
3359 (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
3360 (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
3361 (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
3362 );
3481 3363
3482 fz = ((_target_velocity.Z - vel.Z) * (PID_D)); 3364 // if velocity is zero, use position control; otherwise, velocity control
3483 }
3484 } // end if (m_usePID)
3485 3365
3486 // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller 3366 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
3487 else if (m_useHoverPID) 3367 {
3488 { 3368 // keep track of where we stopped. No more slippin' & slidin'
3489 //Console.WriteLine("Hover " + Name); 3369
3370 // We only want to deactivate the PID Controller if we think we want to have our surrogate
3371 // react to the physics scene by moving it's position.
3372 // Avatar to Avatar collisions
3373 // Prim to avatar collisions
3374
3375 //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
3376 //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2);
3377 //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
3378 d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
3379 d.BodySetLinearVel(Body, 0, 0, 0);
3380 d.BodyAddForce(Body, 0, 0, fz);
3381 return;
3382 }
3383 else
3384 {
3385 _zeroFlag = false;
3490 3386
3491 // If we're using the PID controller, then we have no gravity 3387 // We're flying and colliding with something
3388 fx = ((_target_velocity.X) - vel.X) * (PID_D);
3389 fy = ((_target_velocity.Y) - vel.Y) * (PID_D);
3492 3390
3493 // no lock; for now it's only called from within Simulate() 3391 // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
3494 3392
3495 // If the PID Controller isn't active then we set our force 3393 fz = ((_target_velocity.Z - vel.Z) * (PID_D));
3496 // calculating base velocity to the current position 3394 }
3395 } // end if (m_usePID)
3497 3396
3498 if ((m_PIDTau < 1)) 3397 // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller
3398 else if (m_useHoverPID)
3499 { 3399 {
3500 PID_G = PID_G / m_PIDTau; 3400 //Console.WriteLine("Hover " + Name);
3501 }
3502 3401
3503 if ((PID_G - m_PIDTau) <= 0) 3402 // If we're using the PID controller, then we have no gravity
3504 {
3505 PID_G = m_PIDTau + 1;
3506 }
3507 3403
3508 // Where are we, and where are we headed? 3404 // no lock; for now it's only called from within Simulate()
3509 d.Vector3 pos = d.BodyGetPosition(Body);
3510 d.Vector3 vel = d.BodyGetLinearVel(Body);
3511 3405
3512 // Non-Vehicles have a limited set of Hover options. 3406 // If the PID Controller isn't active then we set our force
3513 // determine what our target height really is based on HoverType 3407 // calculating base velocity to the current position
3514 switch (m_PIDHoverType) 3408
3515 { 3409 if ((m_PIDTau < 1))
3516 case PIDHoverType.Ground: 3410 {
3517 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); 3411 PID_G = PID_G / m_PIDTau;
3518 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; 3412 }
3519 break; 3413
3520 case PIDHoverType.GroundAndWater: 3414 if ((PID_G - m_PIDTau) <= 0)
3521 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); 3415 {
3522 m_waterHeight = _parent_scene.GetWaterLevel(); 3416 PID_G = m_PIDTau + 1;
3523 if (m_groundHeight > m_waterHeight) 3417 }
3524 { 3418
3419 // Where are we, and where are we headed?
3420 d.Vector3 pos = d.BodyGetPosition(Body);
3421 d.Vector3 vel = d.BodyGetLinearVel(Body);
3422
3423 // Non-Vehicles have a limited set of Hover options.
3424 // determine what our target height really is based on HoverType
3425 switch (m_PIDHoverType)
3426 {
3427 case PIDHoverType.Ground:
3428 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
3525 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; 3429 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
3526 } 3430 break;
3527 else 3431 case PIDHoverType.GroundAndWater:
3528 { 3432 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
3529 m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; 3433 m_waterHeight = _parent_scene.GetWaterLevel();
3530 } 3434 if (m_groundHeight > m_waterHeight)
3531 break; 3435 {
3436 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
3437 }
3438 else
3439 {
3440 m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
3441 }
3442 break;
3532 3443
3533 } // end switch (m_PIDHoverType) 3444 } // end switch (m_PIDHoverType)
3534 3445
3535 3446
3536 _target_velocity = 3447 _target_velocity =
3537 new Vector3(0.0f, 0.0f, 3448 new Vector3(0.0f, 0.0f,
3538 (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep) 3449 (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep)
3539 ); 3450 );
3540 3451
3541 // if velocity is zero, use position control; otherwise, velocity control 3452 // if velocity is zero, use position control; otherwise, velocity control
3542 3453
3543 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) 3454 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
3544 { 3455 {
3545 // keep track of where we stopped. No more slippin' & slidin' 3456 // keep track of where we stopped. No more slippin' & slidin'
3546 3457
3547 // We only want to deactivate the PID Controller if we think we want to have our surrogate 3458 // We only want to deactivate the PID Controller if we think we want to have our surrogate
3548 // react to the physics scene by moving it's position. 3459 // react to the physics scene by moving it's position.
3549 // Avatar to Avatar collisions 3460 // Avatar to Avatar collisions
3550 // Prim to avatar collisions 3461 // Prim to avatar collisions
3462
3463 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
3464 d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
3465 // ? d.BodyAddForce(Body, 0, 0, fz);
3466 return;
3467 }
3468 else
3469 {
3470 _zeroFlag = false;
3551 3471
3552 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); 3472 // We're flying and colliding with something
3553 d.BodySetLinearVel(Body, vel.X, vel.Y, 0); 3473 fz = ((_target_velocity.Z - vel.Z) * (PID_D));
3554 // ? d.BodyAddForce(Body, 0, 0, fz); 3474 }
3555 return;
3556 } 3475 }
3557 else 3476 else
3558 { 3477 {
3559 _zeroFlag = false; 3478 float b = (1.0f - m_buoyancy);
3560 3479 fx = _parent_scene.gravityx * b;
3561 // We're flying and colliding with something 3480 fy = _parent_scene.gravityy * b;
3562 fz = ((_target_velocity.Z - vel.Z) * (PID_D)); 3481 fz = _parent_scene.gravityz * b;
3563 } 3482 }
3564 }
3565 else
3566 {
3567 float b = (1.0f - m_buoyancy);
3568 fx = _parent_scene.gravityx * b;
3569 fy = _parent_scene.gravityy * b;
3570 fz = _parent_scene.gravityz * b;
3571 }
3572 3483
3573 fx *= m_mass; 3484 fx *= m_mass;
3574 fy *= m_mass; 3485 fy *= m_mass;
3575 fz *= m_mass; 3486 fz *= m_mass;
3576 3487
3577 // constant force 3488 // constant force
3578 fx += m_force.X; 3489 fx += m_force.X;
3579 fy += m_force.Y; 3490 fy += m_force.Y;
3580 fz += m_force.Z; 3491 fz += m_force.Z;
3581 3492
3582 fx += m_forceacc.X; 3493 fx += m_forceacc.X;
3583 fy += m_forceacc.Y; 3494 fy += m_forceacc.Y;
3584 fz += m_forceacc.Z; 3495 fz += m_forceacc.Z;
3585 3496
3586 m_forceacc = Vector3.Zero; 3497 m_forceacc = Vector3.Zero;
3587 3498
3588 //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); 3499 //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
3589 if (fx != 0 || fy != 0 || fz != 0) 3500 if (fx != 0 || fy != 0 || fz != 0)
3590 { 3501 {
3591 d.BodyAddForce(Body, fx, fy, fz); 3502 d.BodyAddForce(Body, fx, fy, fz);
3592 //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); 3503 //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz);
3593 } 3504 }
3594 3505
3595 Vector3 trq; 3506 Vector3 trq;
3507
3508 trq = _torque;
3509 trq += m_angularForceacc;
3510 m_angularForceacc = Vector3.Zero;
3511 if (trq.X != 0 || trq.Y != 0 || trq.Z != 0)
3512 {
3513 d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z);
3514 }
3596 3515
3597 trq = _torque;
3598 trq += m_angularForceacc;
3599 m_angularForceacc = Vector3.Zero;
3600 if (trq.X != 0 || trq.Y != 0 || trq.Z != 0)
3601 {
3602 d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z);
3603 } 3516 }
3517 }
3518 else // body disabled
3519 {
3520 // let vehicles sleep
3521 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
3522 return;
3604 3523
3524 if (++bodydisablecontrol < 20)
3525 return;
3526
3527 bodydisablecontrol = 0;
3528 d.BodyEnable(Body);
3529 return;
3605 } 3530 }
3606 } 3531 }
3607 else 3532 else
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
index 4b3f83b..e66580d 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs
@@ -30,10 +30,11 @@ using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Runtime.InteropServices; 31using System.Runtime.InteropServices;
32using System.Text; 32using System.Text;
33using OpenMetaverse; 33using OpenSim.Framework;
34using OpenSim.Region.Physics.Manager; 34using OpenSim.Region.Physics.Manager;
35using OdeAPI; 35using OdeAPI;
36using log4net; 36using log4net;
37using OpenMetaverse;
37 38
38namespace OpenSim.Region.Physics.OdePlugin 39namespace OpenSim.Region.Physics.OdePlugin
39{ 40{
@@ -54,9 +55,11 @@ namespace OpenSim.Region.Physics.OdePlugin
54 /// </summary> 55 /// </summary>
55 private OdeScene m_scene; 56 private OdeScene m_scene;
56 57
57 IntPtr ray; 58 IntPtr ray; // the ray. we only need one for our lifetime
58 59
59 private const int ColisionContactGeomsPerTest = 5; 60 private const int ColisionContactGeomsPerTest = 5;
61 private const int DefaultMaxCount = 25;
62 private const int MaxTimePerCallMS = 30;
60 63
61 /// <summary> 64 /// <summary>
62 /// ODE near callback delegate 65 /// ODE near callback delegate
@@ -64,19 +67,22 @@ namespace OpenSim.Region.Physics.OdePlugin
64 private d.NearCallback nearCallback; 67 private d.NearCallback nearCallback;
65 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 68 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
66 private List<ContactResult> m_contactResults = new List<ContactResult>(); 69 private List<ContactResult> m_contactResults = new List<ContactResult>();
70 private RayFilterFlags CurrentRayFilter;
71 private int CurrentMaxCount;
67 72
68 public ODERayCastRequestManager(OdeScene pScene) 73 public ODERayCastRequestManager(OdeScene pScene)
69 { 74 {
70 m_scene = pScene; 75 m_scene = pScene;
71 nearCallback = near; 76 nearCallback = near;
72 ray = d.CreateRay(IntPtr.Zero, 1.0f); 77 ray = d.CreateRay(IntPtr.Zero, 1.0f);
78 d.GeomSetCategoryBits(ray,0);
73 } 79 }
74 80
75 /// <summary> 81 /// <summary>
76 /// Queues a raycast 82 /// Queues request for a raycast to all world
77 /// </summary> 83 /// </summary>
78 /// <param name="position">Origin of Ray</param> 84 /// <param name="position">Origin of Ray</param>
79 /// <param name="direction">Ray normal</param> 85 /// <param name="direction">Ray direction</param>
80 /// <param name="length">Ray length</param> 86 /// <param name="length">Ray length</param>
81 /// <param name="retMethod">Return method to send the results</param> 87 /// <param name="retMethod">Return method to send the results</param>
82 public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod) 88 public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod)
@@ -84,14 +90,22 @@ namespace OpenSim.Region.Physics.OdePlugin
84 ODERayRequest req = new ODERayRequest(); 90 ODERayRequest req = new ODERayRequest();
85 req.geom = IntPtr.Zero; 91 req.geom = IntPtr.Zero;
86 req.callbackMethod = retMethod; 92 req.callbackMethod = retMethod;
87 req.Count = 0; 93 req.Count = DefaultMaxCount;
88 req.length = length; 94 req.length = length;
89 req.Normal = direction; 95 req.Normal = direction;
90 req.Origin = position; 96 req.Origin = position;
97 req.filter = RayFilterFlags.AllButLand;
91 98
92 m_PendingRequests.Enqueue(req); 99 m_PendingRequests.Enqueue(req);
93 } 100 }
94 101
102 /// <summary>
103 /// Queues request for a raycast to particular part
104 /// </summary>
105 /// <param name="position">Origin of Ray</param>
106 /// <param name="direction">Ray direction</param>
107 /// <param name="length">Ray length</param>
108 /// <param name="retMethod">Return method to send the results</param>
95 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod) 109 public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
96 { 110 {
97 ODERayRequest req = new ODERayRequest(); 111 ODERayRequest req = new ODERayRequest();
@@ -100,7 +114,8 @@ namespace OpenSim.Region.Physics.OdePlugin
100 req.length = length; 114 req.length = length;
101 req.Normal = direction; 115 req.Normal = direction;
102 req.Origin = position; 116 req.Origin = position;
103 req.Count = 0; 117 req.Count = DefaultMaxCount;
118 req.filter = RayFilterFlags.AllButLand;
104 119
105 m_PendingRequests.Enqueue(req); 120 m_PendingRequests.Enqueue(req);
106 } 121 }
@@ -110,10 +125,11 @@ namespace OpenSim.Region.Physics.OdePlugin
110 ODERayRequest req = new ODERayRequest(); 125 ODERayRequest req = new ODERayRequest();
111 req.geom = IntPtr.Zero; 126 req.geom = IntPtr.Zero;
112 req.callbackMethod = retMethod; 127 req.callbackMethod = retMethod;
113 req.Count = 0; 128 req.Count = DefaultMaxCount;
114 req.length = length; 129 req.length = length;
115 req.Normal = direction; 130 req.Normal = direction;
116 req.Origin = position; 131 req.Origin = position;
132 req.filter = RayFilterFlags.AllButLand;
117 133
118 m_PendingRequests.Enqueue(req); 134 m_PendingRequests.Enqueue(req);
119 } 135 }
@@ -126,7 +142,8 @@ namespace OpenSim.Region.Physics.OdePlugin
126 req.length = length; 142 req.length = length;
127 req.Normal = direction; 143 req.Normal = direction;
128 req.Origin = position; 144 req.Origin = position;
129 req.Count = 0; 145 req.Count = DefaultMaxCount;
146 req.filter = RayFilterFlags.AllButLand;
130 147
131 m_PendingRequests.Enqueue(req); 148 m_PendingRequests.Enqueue(req);
132 } 149 }
@@ -148,6 +165,22 @@ namespace OpenSim.Region.Physics.OdePlugin
148 req.Normal = direction; 165 req.Normal = direction;
149 req.Origin = position; 166 req.Origin = position;
150 req.Count = count; 167 req.Count = count;
168 req.filter = RayFilterFlags.AllButLand;
169
170 m_PendingRequests.Enqueue(req);
171 }
172
173
174 public void QueueRequest(Vector3 position, Vector3 direction, float length, int count,RayFilterFlags filter , RayCallback retMethod)
175 {
176 ODERayRequest req = new ODERayRequest();
177 req.geom = IntPtr.Zero;
178 req.callbackMethod = retMethod;
179 req.length = length;
180 req.Normal = direction;
181 req.Origin = position;
182 req.Count = count;
183 req.filter = filter;
151 184
152 m_PendingRequests.Enqueue(req); 185 m_PendingRequests.Enqueue(req);
153 } 186 }
@@ -161,6 +194,7 @@ namespace OpenSim.Region.Physics.OdePlugin
161 req.Normal = direction; 194 req.Normal = direction;
162 req.Origin = position; 195 req.Origin = position;
163 req.Count = count; 196 req.Count = count;
197 req.filter = RayFilterFlags.AllButLand;
164 198
165 m_PendingRequests.Enqueue(req); 199 m_PendingRequests.Enqueue(req);
166 } 200 }
@@ -174,6 +208,7 @@ namespace OpenSim.Region.Physics.OdePlugin
174 req.Normal = direction; 208 req.Normal = direction;
175 req.Origin = position; 209 req.Origin = position;
176 req.Count = count; 210 req.Count = count;
211 req.filter = RayFilterFlags.AllButLand;
177 212
178 m_PendingRequests.Enqueue(req); 213 m_PendingRequests.Enqueue(req);
179 } 214 }
@@ -187,6 +222,7 @@ namespace OpenSim.Region.Physics.OdePlugin
187 req.Normal = direction; 222 req.Normal = direction;
188 req.Origin = position; 223 req.Origin = position;
189 req.Count = count; 224 req.Count = count;
225 req.filter = RayFilterFlags.AllButLand;
190 226
191 m_PendingRequests.Enqueue(req); 227 m_PendingRequests.Enqueue(req);
192 } 228 }
@@ -197,63 +233,104 @@ namespace OpenSim.Region.Physics.OdePlugin
197 /// <returns>Time in MS the raycasts took to process.</returns> 233 /// <returns>Time in MS the raycasts took to process.</returns>
198 public int ProcessQueuedRequests() 234 public int ProcessQueuedRequests()
199 { 235 {
200 int time = System.Environment.TickCount;
201 236
202 if (m_PendingRequests.Count <= 0) 237 if (m_PendingRequests.Count <= 0)
203 return 0; 238 return 0;
204 239
205 if (m_scene.ContactgeomsArray == IntPtr.Zero) // oops something got wrong or scene isn't ready still 240 if (m_scene.ContactgeomsArray == IntPtr.Zero || ray == IntPtr.Zero)
241 // oops something got wrong or scene isn't ready still
206 { 242 {
207 m_PendingRequests.Clear(); 243 m_PendingRequests.Clear();
208 return 0; 244 return 0;
209 } 245 }
210 246
211 ODERayRequest req; 247 int time = Util.EnvironmentTickCount();
212 248
213 int i = 50; // arbitary limit of processed tests per frame 249 ODERayRequest req;
250 int closestHit;
251 int backfacecull;
252 CollisionCategories catflags;
214 253
215 while(m_PendingRequests.Dequeue(out req)) 254 while (m_PendingRequests.Dequeue(out req))
216 { 255 {
217 if (req.geom == IntPtr.Zero) 256 if (req.callbackMethod != null)
218 doSpaceRay(req); 257 {
219 else 258 CurrentRayFilter = req.filter;
220 doGeomRay(req); 259 CurrentMaxCount = req.Count;
221 if(--i < 0) 260
222 break; 261 closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1);
262 backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1);
263
264 d.GeomRaySetLength(ray, req.length);
265 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
266 d.GeomRaySetParams(ray, 0, backfacecull);
267 d.GeomRaySetClosestHit(ray, closestHit);
268
269 if (req.callbackMethod is RaycastCallback)
270 // if we only want one get only one per colision pair saving memory
271 CurrentRayFilter |= RayFilterFlags.ClosestHit;
272
273 if (req.geom == IntPtr.Zero)
274 {
275 // translate ray filter to colision flags
276 catflags = 0;
277 if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0)
278 catflags |= CollisionCategories.VolumeDtc;
279 if ((CurrentRayFilter & RayFilterFlags.phantom) != 0)
280 catflags |= CollisionCategories.Phantom;
281 if ((CurrentRayFilter & RayFilterFlags.agent) != 0)
282 catflags |= CollisionCategories.Character;
283 if ((CurrentRayFilter & RayFilterFlags.PrimsNonPhantom) != 0)
284 catflags |= CollisionCategories.Geom;
285 if ((CurrentRayFilter & RayFilterFlags.land) != 0)
286 catflags |= CollisionCategories.Land;
287 if ((CurrentRayFilter & RayFilterFlags.water) != 0)
288 catflags |= CollisionCategories.Water;
289
290 if (catflags != 0)
291 doSpaceRay(req);
292 }
293 else
294 {
295 // if we select a geom don't use filters
296 d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
297 doGeomRay(req);
298 }
299 }
300
301 if (Util.EnvironmentTickCountSubtract(time) > MaxTimePerCallMS)
302 break;
223 } 303 }
224 304
225 lock (m_contactResults) 305 lock (m_contactResults)
226 m_contactResults.Clear(); 306 m_contactResults.Clear();
227 307
228 return System.Environment.TickCount - time; 308 return Util.EnvironmentTickCountSubtract(time);
229 } 309 }
230 /// <summary> 310 /// <summary>
231 /// Method that actually initiates the raycast with full top space 311 /// Method that actually initiates the raycast with spaces
232 /// </summary> 312 /// </summary>
233 /// <param name="req"></param> 313 /// <param name="req"></param>
234 private void doSpaceRay(ODERayRequest req) 314 ///
235 {
236 // Create the ray
237// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
238 d.GeomRaySetLength(ray, req.length);
239 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
240 315
241 // Collide test 316 private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton;
242 d.SpaceCollide2(m_scene.TopSpace, ray, IntPtr.Zero, nearCallback); 317 private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton;
243
244 // Remove Ray
245// d.GeomDestroy(ray);
246 318
247 if (req.callbackMethod == null) 319 private void doSpaceRay(ODERayRequest req)
248 return; 320 {
321 // Collide tests
322 if ((CurrentRayFilter & FilterActiveSpace) != 0)
323 d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
324 if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
325 d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
249 326
250 if (req.callbackMethod is RaycastCallback) 327 if (req.callbackMethod is RaycastCallback)
251 { 328 {
252 // Define default results 329 // Define default results
253 bool hitYN = false; 330 bool hitYN = false;
254 uint hitConsumerID = 0; 331 uint hitConsumerID = 0;
255 float distance = 999999999999f; 332 float distance = float.MaxValue;
256 Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f); 333 Vector3 closestcontact = Vector3.Zero;
257 Vector3 snormal = Vector3.Zero; 334 Vector3 snormal = Vector3.Zero;
258 335
259 // Find closest contact and object. 336 // Find closest contact and object.
@@ -261,25 +338,30 @@ namespace OpenSim.Region.Physics.OdePlugin
261 { 338 {
262 foreach (ContactResult cResult in m_contactResults) 339 foreach (ContactResult cResult in m_contactResults)
263 { 340 {
264 if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact)) 341 if(cResult.Depth < distance)
265 { 342 {
266 closestcontact = cResult.Pos; 343 closestcontact = cResult.Pos;
267 hitConsumerID = cResult.ConsumerID; 344 hitConsumerID = cResult.ConsumerID;
268 distance = cResult.Depth; 345 distance = cResult.Depth;
269 hitYN = true;
270 snormal = cResult.Normal; 346 snormal = cResult.Normal;
271 } 347 }
272 } 348 }
273 m_contactResults.Clear(); 349 m_contactResults.Clear();
274 } 350 }
275 351
352 if (distance > 0 && distance < float.MaxValue)
353 hitYN = true;
276 ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal); 354 ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
277 } 355 }
278 else 356 else
279 { 357 {
280 ((RayCallback)req.callbackMethod)(m_contactResults); 358 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
281 lock (m_PendingRequests) 359 lock (m_PendingRequests)
360 {
361 cresult.AddRange(m_contactResults);
282 m_contactResults.Clear(); 362 m_contactResults.Clear();
363 }
364 ((RayCallback)req.callbackMethod)(cresult);
283 } 365 }
284 } 366 }
285 367
@@ -289,27 +371,16 @@ namespace OpenSim.Region.Physics.OdePlugin
289 /// <param name="req"></param> 371 /// <param name="req"></param>
290 private void doGeomRay(ODERayRequest req) 372 private void doGeomRay(ODERayRequest req)
291 { 373 {
292 // Create the ray
293// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
294 d.GeomRaySetLength(ray, req.length);
295 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
296
297 // Collide test 374 // Collide test
298 d.SpaceCollide2(req.geom, ray, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test 375 d.SpaceCollide2(ray, req.geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
299
300 // Remove Ray
301// d.GeomDestroy(ray);
302
303 if (req.callbackMethod == null)
304 return;
305 376
306 if (req.callbackMethod is RaycastCallback) 377 if (req.callbackMethod is RaycastCallback)
307 { 378 {
308 // Define default results 379 // Define default results
309 bool hitYN = false; 380 bool hitYN = false;
310 uint hitConsumerID = 0; 381 uint hitConsumerID = 0;
311 float distance = 999999999999f; 382 float distance = float.MaxValue;
312 Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f); 383 Vector3 closestcontact = Vector3.Zero;
313 Vector3 snormal = Vector3.Zero; 384 Vector3 snormal = Vector3.Zero;
314 385
315 // Find closest contact and object. 386 // Find closest contact and object.
@@ -317,25 +388,31 @@ namespace OpenSim.Region.Physics.OdePlugin
317 { 388 {
318 foreach (ContactResult cResult in m_contactResults) 389 foreach (ContactResult cResult in m_contactResults)
319 { 390 {
320 if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact)) 391 if(cResult.Depth < distance )
321 { 392 {
322 closestcontact = cResult.Pos; 393 closestcontact = cResult.Pos;
323 hitConsumerID = cResult.ConsumerID; 394 hitConsumerID = cResult.ConsumerID;
324 distance = cResult.Depth; 395 distance = cResult.Depth;
325 hitYN = true;
326 snormal = cResult.Normal; 396 snormal = cResult.Normal;
327 } 397 }
328 } 398 }
329 m_contactResults.Clear(); 399 m_contactResults.Clear();
330 } 400 }
331 401
402 if (distance > 0 && distance < float.MaxValue)
403 hitYN = true;
404
332 ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal); 405 ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
333 } 406 }
334 else 407 else
335 { 408 {
336 ((RayCallback)req.callbackMethod)(m_contactResults); 409 List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
337 lock (m_PendingRequests) 410 lock (m_PendingRequests)
411 {
412 cresult.AddRange(m_contactResults);
338 m_contactResults.Clear(); 413 m_contactResults.Clear();
414 }
415 ((RayCallback)req.callbackMethod)(cresult);
339 } 416 }
340 } 417 }
341 418
@@ -350,20 +427,16 @@ namespace OpenSim.Region.Physics.OdePlugin
350 return true; 427 return true;
351 } 428 }
352 429
353 // This is the standard Near. g2 is the ray 430 // This is the standard Near. g1 is the ray
354 private void near(IntPtr space, IntPtr g1, IntPtr g2) 431 private void near(IntPtr space, IntPtr g1, IntPtr g2)
355 { 432 {
356 //Don't test against heightfield Geom, or you'll be sorry! 433 if (g2 == IntPtr.Zero || g1 == g2)
357 // Exclude heightfield geom
358
359 if (g1 == IntPtr.Zero || g1 == g2)
360 return; 434 return;
361 435
362 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass) 436 if (m_contactResults.Count >= CurrentMaxCount)
363 return; 437 return;
364 438
365 // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. 439 if (d.GeomIsSpace(g2))
366 if (d.GeomIsSpace(g1))
367 { 440 {
368 try 441 try
369 { 442 {
@@ -381,10 +454,6 @@ namespace OpenSim.Region.Physics.OdePlugin
381 { 454 {
382 count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); 455 count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
383 } 456 }
384 catch (SEHException)
385 {
386 m_log.Error("[PHYSICS Ray]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
387 }
388 catch (Exception e) 457 catch (Exception e)
389 { 458 {
390 m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message); 459 m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
@@ -394,31 +463,116 @@ namespace OpenSim.Region.Physics.OdePlugin
394 if (count == 0) 463 if (count == 0)
395 return; 464 return;
396 465
397 PhysicsActor p1 = null; 466 uint ID = 0;
467 PhysicsActor p2 = null;
468
469 m_scene.actor_name_map.TryGetValue(g2, out p2);
470
471 if (p2 == null)
472 {
473 string name;
474
475 if (!m_scene.geom_name_map.TryGetValue(g2, out name))
476 return;
477
478 if (name == "Terrain")
479 {
480 // land colision
481 if ((CurrentRayFilter & RayFilterFlags.land) == 0)
482 return;
483 }
484 else if (name == "Water")
485 {
486 if ((CurrentRayFilter & RayFilterFlags.water) == 0)
487 return;
488 }
489 else
490 return;
491 }
492 else
493 {
494 if (p2 is OdePrim)
495 {
496 RayFilterFlags thisFlags;
497
498 if (p2.IsPhysical)
499 thisFlags = RayFilterFlags.physical;
500 else
501 thisFlags = RayFilterFlags.nonphysical;
398 502
399 if (g1 != IntPtr.Zero) 503 if (p2.Phantom)
400 m_scene.actor_name_map.TryGetValue(g1, out p1); 504 thisFlags |= RayFilterFlags.phantom;
505
506 if (p2.IsVolumeDtc)
507 thisFlags |= RayFilterFlags.volumedtc;
508
509 if ((thisFlags & CurrentRayFilter) == 0)
510 return;
511
512 ID = ((OdePrim)p2).m_localID;
513 }
514 else if (p2 is OdeCharacter)
515 {
516 if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
517 return;
518 else
519 ID = ((OdeCharacter)p2).m_localID;
520 }
521 else //??
522 return;
523 }
401 524
402 d.ContactGeom curcontact = new d.ContactGeom(); 525 d.ContactGeom curcontact = new d.ContactGeom();
403 // Loop over contacts, build results. 526
404 for (int i = 0; i < count; i++) 527 // closestHit for now only works for meshs, so must do it for others
528 if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
405 { 529 {
406 if (!GetCurContactGeom(i, ref curcontact)) 530 // Loop all contacts, build results.
407 break; 531 for (int i = 0; i < count; i++)
408 if (p1 != null) { 532 {
409 if (p1 is OdePrim) 533 if (!GetCurContactGeom(i, ref curcontact))
534 break;
535
536 ContactResult collisionresult = new ContactResult();
537 collisionresult.ConsumerID = ID;
538 collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
539 collisionresult.Depth = curcontact.depth;
540 collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
541 curcontact.normal.Z);
542 lock (m_contactResults)
543 {
544 m_contactResults.Add(collisionresult);
545 if (m_contactResults.Count >= CurrentMaxCount)
546 return;
547 }
548 }
549 }
550 else
551 {
552 // keep only closest contact
553 ContactResult collisionresult = new ContactResult();
554 collisionresult.ConsumerID = ID;
555 collisionresult.Depth = float.MaxValue;
556
557 for (int i = 0; i < count; i++)
558 {
559 if (!GetCurContactGeom(i, ref curcontact))
560 break;
561
562 if (curcontact.depth < collisionresult.Depth)
410 { 563 {
411 ContactResult collisionresult = new ContactResult();
412
413 collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
414 collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z); 564 collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
415 collisionresult.Depth = curcontact.depth; 565 collisionresult.Depth = curcontact.depth;
416 collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y, 566 collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
417 curcontact.normal.Z); 567 curcontact.normal.Z);
418 lock (m_contactResults)
419 m_contactResults.Add(collisionresult);
420 } 568 }
421 } 569 }
570
571 if (collisionresult.Depth != float.MaxValue)
572 {
573 lock (m_contactResults)
574 m_contactResults.Add(collisionresult);
575 }
422 } 576 }
423 } 577 }
424 578
@@ -428,6 +582,11 @@ namespace OpenSim.Region.Physics.OdePlugin
428 internal void Dispose() 582 internal void Dispose()
429 { 583 {
430 m_scene = null; 584 m_scene = null;
585 if (ray != IntPtr.Zero)
586 {
587 d.GeomDestroy(ray);
588 ray = IntPtr.Zero;
589 }
431 } 590 }
432 } 591 }
433 592
@@ -439,5 +598,6 @@ namespace OpenSim.Region.Physics.OdePlugin
439 public int Count; 598 public int Count;
440 public float length; 599 public float length;
441 public object callbackMethod; 600 public object callbackMethod;
601 public RayFilterFlags filter;
442 } 602 }
443} \ No newline at end of file 603} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
index f5129cb..0e4961b 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs
@@ -889,13 +889,13 @@ namespace OdeAPI
889 public static extern IntPtr GeomGetBody(IntPtr geom); 889 public static extern IntPtr GeomGetBody(IntPtr geom);
890 890
891 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity] 891 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity]
892 public static extern int GeomGetCategoryBits(IntPtr geom); 892 public static extern uint GeomGetCategoryBits(IntPtr geom);
893 893
894 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity] 894 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity]
895 public static extern IntPtr GeomGetClassData(IntPtr geom); 895 public static extern IntPtr GeomGetClassData(IntPtr geom);
896 896
897 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity] 897 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity]
898 public static extern int GeomGetCollideBits(IntPtr geom); 898 public static extern uint GeomGetCollideBits(IntPtr geom);
899 899
900 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity] 900 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity]
901 public static extern GeomClassID GeomGetClass(IntPtr geom); 901 public static extern GeomClassID GeomGetClass(IntPtr geom);
@@ -1086,10 +1086,10 @@ namespace OdeAPI
1086 public static extern void GeomSetBody(IntPtr geom, IntPtr body); 1086 public static extern void GeomSetBody(IntPtr geom, IntPtr body);
1087 1087
1088 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity] 1088 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity]
1089 public static extern void GeomSetCategoryBits(IntPtr geom, int bits); 1089 public static extern void GeomSetCategoryBits(IntPtr geom, uint bits);
1090 1090
1091 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity] 1091 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity]
1092 public static extern void GeomSetCollideBits(IntPtr geom, int bits); 1092 public static extern void GeomSetCollideBits(IntPtr geom, uint bits);
1093 1093
1094 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity] 1094 [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity]
1095 public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); 1095 public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 3e0ccef..7632e25 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -60,19 +60,31 @@ namespace OpenSim.Region.Physics.OdePlugin
60 public int lastframe; 60 public int lastframe;
61 } 61 }
62 62
63 // colision flags of things others can colide with
64 // rays, sensors, probes removed since can't be colided with
65 // The top space where things are placed provided further selection
66 // ie physical are in active space nonphysical in static
67 // this should be exclusive as possible
68
63 [Flags] 69 [Flags]
64 public enum CollisionCategories : int 70 public enum CollisionCategories : uint
65 { 71 {
66 Disabled = 0, 72 Disabled = 0,
67 Geom = 0x00000001, 73 //by 'things' types
68 Body = 0x00000002, 74 Space = 0x01,
69 Space = 0x00000004, 75 Geom = 0x02, // aka prim/part
70 Character = 0x00000008, 76 Character = 0x04,
71 Land = 0x00000010, 77 Land = 0x08,
72 Water = 0x00000020, 78 Water = 0x010,
73 Wind = 0x00000040, 79
74 Sensor = 0x00000080, 80 // by state
75 Selected = 0x00000100 81 Phantom = 0x01000,
82 VolumeDtc = 0x02000,
83 Selected = 0x04000,
84 NoShape = 0x08000,
85
86
87 All = 0xffffffff
76 } 88 }
77 89
78 /// <summary> 90 /// <summary>
@@ -116,6 +128,7 @@ namespace OpenSim.Region.Physics.OdePlugin
116 Acceleration, 128 Acceleration,
117 Force, 129 Force,
118 Torque, 130 Torque,
131 Momentum,
119 132
120 AddForce, 133 AddForce,
121 AddAngForce, 134 AddAngForce,
@@ -186,7 +199,9 @@ namespace OpenSim.Region.Physics.OdePlugin
186 private float waterlevel = 0f; 199 private float waterlevel = 0f;
187 private int framecount = 0; 200 private int framecount = 0;
188 201
189 internal IntPtr WaterGeom; 202 private IntPtr WaterGeom = IntPtr.Zero;
203 private IntPtr WaterHeightmapData = IntPtr.Zero;
204 private GCHandle WaterMapHandler = new GCHandle();
190 205
191 public float avPIDD = 2200f; // make it visible 206 public float avPIDD = 2200f; // make it visible
192 public float avPIDP = 900f; // make it visible 207 public float avPIDP = 900f; // make it visible
@@ -213,9 +228,8 @@ namespace OpenSim.Region.Physics.OdePlugin
213 228
214// public int geomCrossingFailuresBeforeOutofbounds = 6; 229// public int geomCrossingFailuresBeforeOutofbounds = 6;
215 230
216 public int bodyFramesAutoDisable = 20; 231 public int bodyFramesAutoDisable = 5;
217 232
218 private float[] _watermap;
219 233
220 private d.NearCallback nearCallback; 234 private d.NearCallback nearCallback;
221 235
@@ -350,7 +364,7 @@ namespace OpenSim.Region.Physics.OdePlugin
350 // i must RtC#FM 364 // i must RtC#FM
351 } 365 }
352 366
353 d.HashSpaceSetLevels(TopSpace, -2, 8); // cell sizes from .25 to 256 ?? need check what this really does 367 d.HashSpaceSetLevels(TopSpace, -2, 8);
354 d.HashSpaceSetLevels(ActiveSpace, -2, 8); 368 d.HashSpaceSetLevels(ActiveSpace, -2, 8);
355 d.HashSpaceSetLevels(StaticSpace, -2, 8); 369 d.HashSpaceSetLevels(StaticSpace, -2, 8);
356 370
@@ -358,13 +372,27 @@ namespace OpenSim.Region.Physics.OdePlugin
358 d.SpaceSetSublevel(ActiveSpace, 1); 372 d.SpaceSetSublevel(ActiveSpace, 1);
359 d.SpaceSetSublevel(StaticSpace, 1); 373 d.SpaceSetSublevel(StaticSpace, 1);
360 374
375 d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
376 CollisionCategories.Geom |
377 CollisionCategories.Character |
378 CollisionCategories.Phantom |
379 CollisionCategories.VolumeDtc
380 ));
381 d.GeomSetCollideBits(ActiveSpace, 0);
382 d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space |
383 CollisionCategories.Geom |
384 CollisionCategories.Land |
385 CollisionCategories.Water |
386 CollisionCategories.Phantom |
387 CollisionCategories.VolumeDtc
388 ));
389 d.GeomSetCollideBits(StaticSpace, 0);
390
361 contactgroup = d.JointGroupCreate(0); 391 contactgroup = d.JointGroupCreate(0);
362 //contactgroup 392 //contactgroup
363 393
364 d.WorldSetAutoDisableFlag(world, false); 394 d.WorldSetAutoDisableFlag(world, false);
365 } 395 }
366
367 _watermap = new float[258 * 258];
368 } 396 }
369 397
370 // Initialize the mesh plugin 398 // Initialize the mesh plugin
@@ -374,15 +402,18 @@ namespace OpenSim.Region.Physics.OdePlugin
374// checkThread(); 402// checkThread();
375 mesher = meshmerizer; 403 mesher = meshmerizer;
376 m_config = config; 404 m_config = config;
377 405/*
378 string ode_config = d.GetConfiguration("ODE"); 406 string ode_config = d.GetConfiguration("ODE");
379 m_log.WarnFormat("ODE configuration: {0}", ode_config); 407 if (ode_config != null && ode_config != "")
380
381 if (ode_config.Contains("ODE_Ubit"))
382 { 408 {
383 OdeUbitLib = true; 409 m_log.WarnFormat("ODE configuration: {0}", ode_config);
384 }
385 410
411 if (ode_config.Contains("ODE_Ubit"))
412 {
413 OdeUbitLib = true;
414 }
415 }
416*/
386 /* 417 /*
387 if (region != null) 418 if (region != null)
388 { 419 {
@@ -518,6 +549,15 @@ namespace OpenSim.Region.Physics.OdePlugin
518 waitForSpaceUnlock(newspace); 549 waitForSpaceUnlock(newspace);
519 d.SpaceSetSublevel(newspace, 2); 550 d.SpaceSetSublevel(newspace, 2);
520 d.HashSpaceSetLevels(newspace, -2, 8); 551 d.HashSpaceSetLevels(newspace, -2, 8);
552 d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space |
553 CollisionCategories.Geom |
554 CollisionCategories.Land |
555 CollisionCategories.Water |
556 CollisionCategories.Phantom |
557 CollisionCategories.VolumeDtc
558 ));
559 d.GeomSetCollideBits(newspace, 0);
560
521 staticPrimspace[i, j] = newspace; 561 staticPrimspace[i, j] = newspace;
522 } 562 }
523 // let this now be real maximum values 563 // let this now be real maximum values
@@ -1745,8 +1785,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1745 1785
1746 m_rayCastManager.ProcessQueuedRequests(); 1786 m_rayCastManager.ProcessQueuedRequests();
1747 1787
1748
1749
1750 statray += Util.EnvironmentTickCountSubtract(statstart); 1788 statray += Util.EnvironmentTickCountSubtract(statstart);
1751 collision_optimized(); 1789 collision_optimized();
1752 statcol += Util.EnvironmentTickCountSubtract(statstart); 1790 statcol += Util.EnvironmentTickCountSubtract(statstart);
@@ -2125,14 +2163,14 @@ namespace OpenSim.Region.Physics.OdePlugin
2125 RegionTerrain.Remove(pOffset); 2163 RegionTerrain.Remove(pOffset);
2126 if (GroundGeom != IntPtr.Zero) 2164 if (GroundGeom != IntPtr.Zero)
2127 { 2165 {
2166 d.GeomDestroy(GroundGeom);
2167
2128 if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) 2168 if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
2129 { 2169 {
2130 TerrainHeightFieldHeightsHandlers[GroundGeom].Free(); 2170 TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
2131 TerrainHeightFieldHeightsHandlers.Remove(GroundGeom); 2171 TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
2132 TerrainHeightFieldHeights.Remove(GroundGeom); 2172 TerrainHeightFieldHeights.Remove(GroundGeom);
2133 } 2173 }
2134 d.SpaceRemove(StaticSpace, GroundGeom);
2135 d.GeomDestroy(GroundGeom);
2136 } 2174 }
2137 } 2175 }
2138 IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); 2176 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
@@ -2147,8 +2185,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2147 GroundGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1); 2185 GroundGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1);
2148 if (GroundGeom != IntPtr.Zero) 2186 if (GroundGeom != IntPtr.Zero)
2149 { 2187 {
2150 d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); 2188 d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
2151 d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); 2189 d.GeomSetCollideBits(GroundGeom, 0);
2152 2190
2153 } 2191 }
2154 geom_name_map[GroundGeom] = "Terrain"; 2192 geom_name_map[GroundGeom] = "Terrain";
@@ -2236,14 +2274,15 @@ namespace OpenSim.Region.Physics.OdePlugin
2236 RegionTerrain.Remove(pOffset); 2274 RegionTerrain.Remove(pOffset);
2237 if (GroundGeom != IntPtr.Zero) 2275 if (GroundGeom != IntPtr.Zero)
2238 { 2276 {
2277 d.GeomDestroy(GroundGeom);
2278
2239 if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) 2279 if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
2240 { 2280 {
2241 TerrainHeightFieldHeightsHandlers[GroundGeom].Free(); 2281 if (TerrainHeightFieldHeightsHandlers[GroundGeom].IsAllocated)
2282 TerrainHeightFieldHeightsHandlers[GroundGeom].Free();
2242 TerrainHeightFieldHeightsHandlers.Remove(GroundGeom); 2283 TerrainHeightFieldHeightsHandlers.Remove(GroundGeom);
2243 TerrainHeightFieldHeights.Remove(GroundGeom); 2284 TerrainHeightFieldHeights.Remove(GroundGeom);
2244 } 2285 }
2245 d.SpaceRemove(StaticSpace, GroundGeom);
2246 d.GeomDestroy(GroundGeom);
2247 } 2286 }
2248 } 2287 }
2249 IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); 2288 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
@@ -2263,8 +2302,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2263 GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1); 2302 GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1);
2264 if (GroundGeom != IntPtr.Zero) 2303 if (GroundGeom != IntPtr.Zero)
2265 { 2304 {
2266 d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); 2305 d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land));
2267 d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); 2306 d.GeomSetCollideBits(GroundGeom, 0);
2268 2307
2269 } 2308 }
2270 geom_name_map[GroundGeom] = "Terrain"; 2309 geom_name_map[GroundGeom] = "Terrain";
@@ -2359,57 +2398,76 @@ namespace OpenSim.Region.Physics.OdePlugin
2359 2398
2360 public void randomizeWater(float baseheight) 2399 public void randomizeWater(float baseheight)
2361 { 2400 {
2362 const uint heightmapWidth = m_regionWidth + 2; 2401 const uint heightmapWidth = Constants.RegionSize + 2;
2363 const uint heightmapHeight = m_regionHeight + 2; 2402 const uint heightmapHeight = Constants.RegionSize + 2;
2364 const uint heightmapWidthSamples = m_regionWidth + 2; 2403 const uint heightmapWidthSamples = heightmapWidth + 1;
2365 const uint heightmapHeightSamples = m_regionHeight + 2; 2404 const uint heightmapHeightSamples = heightmapHeight + 1;
2405
2366 const float scale = 1.0f; 2406 const float scale = 1.0f;
2367 const float offset = 0.0f; 2407 const float offset = 0.0f;
2368 const float thickness = 2.9f;
2369 const int wrap = 0; 2408 const int wrap = 0;
2370 2409
2371 for (int i = 0; i < (258 * 258); i++) 2410 float[] _watermap = new float[heightmapWidthSamples * heightmapWidthSamples];
2411
2412 float maxheigh = float.MinValue;
2413 float minheigh = float.MaxValue;
2414 float val;
2415 for (int i = 0; i < (heightmapWidthSamples * heightmapHeightSamples); i++)
2372 { 2416 {
2373 _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f); 2417
2374 // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f)); 2418 val = (baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f);
2419 _watermap[i] = val;
2420 if (maxheigh < val)
2421 maxheigh = val;
2422 if (minheigh > val)
2423 minheigh = val;
2375 } 2424 }
2376 2425
2426 float thickness = minheigh;
2427
2377 lock (OdeLock) 2428 lock (OdeLock)
2378 { 2429 {
2379 if (WaterGeom != IntPtr.Zero) 2430 if (WaterGeom != IntPtr.Zero)
2380 { 2431 {
2381 d.SpaceRemove(StaticSpace, WaterGeom); 2432 d.GeomDestroy(WaterGeom);
2433 d.GeomHeightfieldDataDestroy(WaterHeightmapData);
2434 WaterGeom = IntPtr.Zero;
2435 WaterHeightmapData = IntPtr.Zero;
2436 if(WaterMapHandler.IsAllocated)
2437 WaterMapHandler.Free();
2382 } 2438 }
2383 IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); 2439
2384 d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight, 2440 WaterHeightmapData = d.GeomHeightfieldDataCreate();
2441
2442 WaterMapHandler = GCHandle.Alloc(_watermap, GCHandleType.Pinned);
2443
2444 d.GeomHeightfieldDataBuildSingle(WaterHeightmapData, WaterMapHandler.AddrOfPinnedObject(), 0, heightmapWidth, heightmapHeight,
2385 (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, 2445 (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale,
2386 offset, thickness, wrap); 2446 offset, thickness, wrap);
2387 d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight); 2447 d.GeomHeightfieldDataSetBounds(WaterHeightmapData, minheigh, maxheigh);
2388 WaterGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1); 2448 WaterGeom = d.CreateHeightfield(StaticSpace, WaterHeightmapData, 1);
2389 if (WaterGeom != IntPtr.Zero) 2449 if (WaterGeom != IntPtr.Zero)
2390 { 2450 {
2391 d.GeomSetCategoryBits(WaterGeom, (int)(CollisionCategories.Water)); 2451 d.GeomSetCategoryBits(WaterGeom, (uint)(CollisionCategories.Water));
2392 d.GeomSetCollideBits(WaterGeom, (int)(CollisionCategories.Space)); 2452 d.GeomSetCollideBits(WaterGeom, 0);
2393 2453
2394 } 2454 geom_name_map[WaterGeom] = "Water";
2395 geom_name_map[WaterGeom] = "Water";
2396 2455
2397 d.Matrix3 R = new d.Matrix3(); 2456 d.Matrix3 R = new d.Matrix3();
2398 2457
2399 Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); 2458 Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f);
2400 Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); 2459 Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f);
2401 2460
2402 q1 = q1 * q2; 2461 q1 = q1 * q2;
2403 Vector3 v3; 2462 Vector3 v3;
2404 float angle; 2463 float angle;
2405 q1.GetAxisAngle(out v3, out angle); 2464 q1.GetAxisAngle(out v3, out angle);
2406 2465
2407 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); 2466 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
2408 d.GeomSetRotation(WaterGeom, ref R); 2467 d.GeomSetRotation(WaterGeom, ref R);
2409 d.GeomSetPosition(WaterGeom, 128, 128, 0); 2468 d.GeomSetPosition(WaterGeom, (float)Constants.RegionSize * 0.5f, (float)Constants.RegionSize * 0.5f, 0);
2410 2469 }
2411 } 2470 }
2412
2413 } 2471 }
2414 2472
2415 public override void Dispose() 2473 public override void Dispose()
@@ -2427,11 +2485,34 @@ namespace OpenSim.Region.Physics.OdePlugin
2427 } 2485 }
2428 } 2486 }
2429 2487
2488 if (TerrainHeightFieldHeightsHandlers.Count > 0)
2489 {
2490 foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values)
2491 {
2492 if (gch.IsAllocated)
2493 gch.Free();
2494 }
2495 }
2496
2497 if (WaterGeom != IntPtr.Zero)
2498 {
2499 d.GeomDestroy(WaterGeom);
2500 WaterGeom = IntPtr.Zero;
2501 if (WaterHeightmapData != IntPtr.Zero)
2502 d.GeomHeightfieldDataDestroy(WaterHeightmapData);
2503 WaterHeightmapData = IntPtr.Zero;
2504
2505 if (WaterMapHandler.IsAllocated)
2506 WaterMapHandler.Free();
2507 }
2508
2509
2430 if (ContactgeomsArray != IntPtr.Zero) 2510 if (ContactgeomsArray != IntPtr.Zero)
2431 Marshal.FreeHGlobal(ContactgeomsArray); 2511 Marshal.FreeHGlobal(ContactgeomsArray);
2432 if (GlobalContactsArray != IntPtr.Zero) 2512 if (GlobalContactsArray != IntPtr.Zero)
2433 Marshal.FreeHGlobal(GlobalContactsArray); 2513 Marshal.FreeHGlobal(GlobalContactsArray);
2434 2514
2515
2435 d.WorldDestroy(world); 2516 d.WorldDestroy(world);
2436 //d.CloseODE(); 2517 //d.CloseODE();
2437 } 2518 }
@@ -2502,6 +2583,35 @@ namespace OpenSim.Region.Physics.OdePlugin
2502 return new List<ContactResult>(ourResults); 2583 return new List<ContactResult>(ourResults);
2503 } 2584 }
2504 2585
2586 public override bool SuportsRaycastWorldFiltered()
2587 {
2588 return true;
2589 }
2590
2591 public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
2592 {
2593 object SyncObject = new object();
2594 List<ContactResult> ourresults = new List<ContactResult>();
2595
2596 RayCallback retMethod = delegate(List<ContactResult> results)
2597 {
2598 lock (SyncObject)
2599 {
2600 ourresults = results;
2601 Monitor.PulseAll(SyncObject);
2602 }
2603 };
2604
2605 lock (SyncObject)
2606 {
2607 m_rayCastManager.QueueRequest(position, direction, length, Count,filter, retMethod);
2608 if (!Monitor.Wait(SyncObject, 500))
2609 return null;
2610 else
2611 return ourresults;
2612 }
2613 }
2614
2505 public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) 2615 public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
2506 { 2616 {
2507 if (retMethod != null && actor !=null) 2617 if (retMethod != null && actor !=null)