aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs45
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs6
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs40
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs2
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs2
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs38
-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
10 files changed, 1031 insertions, 739 deletions
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs
index 2945199..ec717d7 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs
@@ -140,6 +140,10 @@ namespace OpenSim.Region.Physics.OdePlugin
140 public int m_eventsubscription = 0; 140 public int m_eventsubscription = 0;
141 private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); 141 private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate();
142 142
143 private Vector3 m_taintMomentum = Vector3.Zero;
144 private bool m_haveTaintMomentum = false;
145
146
143 // unique UUID of this character object 147 // unique UUID of this character object
144 public UUID m_uuid; 148 public UUID m_uuid;
145 public bool bad = false; 149 public bool bad = false;
@@ -800,8 +804,8 @@ namespace OpenSim.Region.Physics.OdePlugin
800 { 804 {
801 if (value.IsFinite()) 805 if (value.IsFinite())
802 { 806 {
803 m_pidControllerActive = true;
804 _target_velocity = value; 807 _target_velocity = value;
808 m_pidControllerActive = true;
805 } 809 }
806 else 810 else
807 { 811 {
@@ -911,6 +915,14 @@ namespace OpenSim.Region.Physics.OdePlugin
911 915
912 public override void SetMomentum(Vector3 momentum) 916 public override void SetMomentum(Vector3 momentum)
913 { 917 {
918 if (momentum.IsFinite())
919 {
920 m_taintMomentum = momentum;
921 m_haveTaintMomentum = true;
922 _parent_scene.AddPhysicsActorTaint(this);
923 }
924 else
925 m_log.Warn("[PHYSICS] !isFinite momentum");
914 } 926 }
915 927
916 928
@@ -1110,9 +1122,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1110 } 1122 }
1111 // end add Kitto Flora 1123 // end add Kitto Flora
1112 } 1124 }
1125
1126 if (vel.X * vel.X + vel.Y * vel.Y + vel.Z * vel.Z > 2500.0f) // 50ms apply breaks
1127 {
1128 float breakfactor = 0.16f * m_mass; // will give aprox 60m/s terminal velocity at free fall
1129 vec.X -= breakfactor * vel.X;
1130 vec.Y -= breakfactor * vel.Y;
1131 vec.Z -= breakfactor * vel.Z;
1132 }
1133
1113 if (vec.IsFinite()) 1134 if (vec.IsFinite())
1114 { 1135 {
1115 if (!vec.ApproxEquals(Vector3.Zero, 0.02f)) // 0.01 allows 0.002 !! 1136 if (vec.LengthSquared() > 0.0004f) // 0.01 allows 0.002 !!
1116 { 1137 {
1117//Console.WriteLine("DF 2"); // ## 1138//Console.WriteLine("DF 2"); // ##
1118 1139
@@ -1327,7 +1348,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1327 { 1348 {
1328 lock (m_syncRoot) 1349 lock (m_syncRoot)
1329 { 1350 {
1330
1331 if (m_tainted_isPhysical != m_isPhysical) 1351 if (m_tainted_isPhysical != m_isPhysical)
1332 { 1352 {
1333 if (m_tainted_isPhysical) 1353 if (m_tainted_isPhysical)
@@ -1369,9 +1389,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1369 { 1389 {
1370 d.GeomDestroy(Shell); 1390 d.GeomDestroy(Shell);
1371 } 1391 }
1372 catch (System.AccessViolationException) 1392 catch (Exception e)
1373 { 1393 {
1374 m_log.Error("[PHYSICS]: PrimGeom dead"); 1394 m_log.ErrorFormat("[PHYSICS]: Failed to destroy character shell {0}",e.Message);
1375 } 1395 }
1376 // Remove any old entries 1396 // Remove any old entries
1377 //string tShell; 1397 //string tShell;
@@ -1418,12 +1438,21 @@ namespace OpenSim.Region.Physics.OdePlugin
1418 { 1438 {
1419 d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); 1439 d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z);
1420 1440
1421 _position.X = m_taintPosition.X;
1422 _position.Y = m_taintPosition.Y;
1423 _position.Z = m_taintPosition.Z;
1424 } 1441 }
1442 _position.X = m_taintPosition.X;
1443 _position.Y = m_taintPosition.Y;
1444 _position.Z = m_taintPosition.Z;
1425 } 1445 }
1426 1446
1447 if (m_haveTaintMomentum)
1448 {
1449 m_haveTaintMomentum = false;
1450 _velocity = m_taintMomentum;
1451 _target_velocity = m_taintMomentum;
1452 m_pidControllerActive = true;
1453 if (Body != IntPtr.Zero)
1454 d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
1455 }
1427 } 1456 }
1428 } 1457 }
1429 1458
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/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 75fa1ef..825b858 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -335,7 +335,7 @@ namespace OpenSim.Region.Physics.Meshing
335 335
336 if (primShape.SculptData.Length <= 0) 336 if (primShape.SculptData.Length <= 0)
337 { 337 {
338 m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName); 338 m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName);
339 return false; 339 return false;
340 } 340 }
341 341
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
index 8e903e8..f002bba 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
@@ -339,7 +339,7 @@ namespace OpenSim.Region.Physics.Meshing
339 339
340 if (primShape.SculptData.Length <= 0) 340 if (primShape.SculptData.Length <= 0)
341 { 341 {
342 m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName); 342 m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName);
343 return false; 343 return false;
344 } 344 }
345 345
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index 4266fda..9c1b87b 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -115,12 +115,11 @@ 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 120 | CollisionCategories.VolumeDtc
121 | CollisionCategories.Character
122 ); 121 );
123 // we do land collisions not ode | CollisionCategories.Land); 122 // we do land collisions not ode | CollisionCategories.Land);
124 public IntPtr Body = IntPtr.Zero; 123 public IntPtr Body = IntPtr.Zero;
125 private OdeScene _parent_scene; 124 private OdeScene _parent_scene;
126 public IntPtr Shell = IntPtr.Zero; 125 public IntPtr Shell = IntPtr.Zero;
@@ -639,6 +638,8 @@ namespace OpenSim.Region.Physics.OdePlugin
639 638
640 public override void SetMomentum(Vector3 momentum) 639 public override void SetMomentum(Vector3 momentum)
641 { 640 {
641 if (momentum.IsFinite())
642 AddChange(changes.Momentum, momentum);
642 } 643 }
643 644
644 645
@@ -663,8 +664,8 @@ namespace OpenSim.Region.Physics.OdePlugin
663 } 664 }
664 Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH); 665 Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
665 666
666 d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); 667 d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories);
667 d.GeomSetCollideBits(Shell, (int)m_collisionFlags); 668 d.GeomSetCollideBits(Shell, (uint)m_collisionFlags);
668 669
669 d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); 670 d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
670 671
@@ -759,7 +760,6 @@ namespace OpenSim.Region.Physics.OdePlugin
759 _parent_scene.geom_name_map.Remove(Shell); 760 _parent_scene.geom_name_map.Remove(Shell);
760 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); 761 _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
761 d.GeomDestroy(Shell); 762 d.GeomDestroy(Shell);
762 _parent_scene.geom_name_map.Remove(Shell);
763 Shell = IntPtr.Zero; 763 Shell = IntPtr.Zero;
764 } 764 }
765 } 765 }
@@ -991,6 +991,14 @@ namespace OpenSim.Region.Physics.OdePlugin
991 // end add Kitto Flora 991 // end add Kitto Flora
992 } 992 }
993 993
994 if (vel.X * vel.X + vel.Y * vel.Y + vel.Z * vel.Z > 2500.0f) // 50m/s apply breaks
995 {
996 float breakfactor = 0.16f * m_mass; // will give aprox 60m/s terminal velocity at free fall
997 vec.X -= breakfactor * vel.X;
998 vec.Y -= breakfactor * vel.Y;
999 vec.Z -= breakfactor * vel.Z;
1000 }
1001
994 if (vec.IsFinite()) 1002 if (vec.IsFinite())
995 { 1003 {
996 if (vec.X != 0 || vec.Y !=0 || vec.Z !=0) 1004 if (vec.X != 0 || vec.Y !=0 || vec.Z !=0)
@@ -1324,6 +1332,16 @@ namespace OpenSim.Region.Physics.OdePlugin
1324 } 1332 }
1325 } 1333 }
1326 1334
1335 // for now momentum is actually velocity
1336 private void changeMomentum(Vector3 newmomentum)
1337 {
1338 _velocity = newmomentum;
1339 _target_velocity = newmomentum;
1340 m_pidControllerActive = true;
1341 if (Body != IntPtr.Zero)
1342 d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z);
1343 }
1344
1327 private void donullchange() 1345 private void donullchange()
1328 { 1346 {
1329 } 1347 }
@@ -1395,6 +1413,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1395 case changes.Size: 1413 case changes.Size:
1396 changeSize((Vector3)arg); 1414 changeSize((Vector3)arg);
1397 break; 1415 break;
1416
1417 case changes.Momentum:
1418 changeMomentum((Vector3)arg);
1419 break;
1398/* not in use for now 1420/* not in use for now
1399 case changes.Shape: 1421 case changes.Shape:
1400 changeShape((PrimitiveBaseShape)arg); 1422 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..5122ebf 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.AllPrims;
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.AllPrims;
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.AllPrims;
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.AllPrims;
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.AllPrims;
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.AllPrims;
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.AllPrims;
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.AllPrims;
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)