aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/OdeScene.cs')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs680
1 files changed, 338 insertions, 342 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 43d852b..0456f56 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -188,8 +188,20 @@ namespace OpenSim.Region.Physics.OdePlugin
188 private d.NearCallback nearCallback; 188 private d.NearCallback nearCallback;
189 public d.TriCallback triCallback; 189 public d.TriCallback triCallback;
190 public d.TriArrayCallback triArrayCallback; 190 public d.TriArrayCallback triArrayCallback;
191
192 /// <summary>
193 /// Avatars in the physics scene.
194 /// </summary>
191 private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); 195 private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>();
196
197 /// <summary>
198 /// Prims in the physics scene.
199 /// </summary>
192 private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>(); 200 private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>();
201
202 /// <summary>
203 /// Prims in the physics scene that are subject to physics, not just collisions.
204 /// </summary>
193 private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); 205 private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>();
194 206
195 /// <summary> 207 /// <summary>
@@ -215,7 +227,14 @@ namespace OpenSim.Region.Physics.OdePlugin
215 /// </remarks> 227 /// </remarks>
216 private readonly HashSet<OdePrim> _taintedPrimH = new HashSet<OdePrim>(); 228 private readonly HashSet<OdePrim> _taintedPrimH = new HashSet<OdePrim>();
217 229
230 /// <summary>
231 /// Record a character that has taints to be processed.
232 /// </summary>
218 private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>(); 233 private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>();
234
235 /// <summary>
236 /// Keep record of contacts in the physics loop so that we can remove duplicates.
237 /// </summary>
219 private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); 238 private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>();
220 239
221 /// <summary> 240 /// <summary>
@@ -227,18 +246,58 @@ namespace OpenSim.Region.Physics.OdePlugin
227 /// A dictionary of collision event changes that are waiting to be processed. 246 /// A dictionary of collision event changes that are waiting to be processed.
228 /// </summary> 247 /// </summary>
229 private readonly Dictionary<uint, PhysicsActor> _collisionEventPrimChanges = new Dictionary<uint, PhysicsActor>(); 248 private readonly Dictionary<uint, PhysicsActor> _collisionEventPrimChanges = new Dictionary<uint, PhysicsActor>();
230 249
231 private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); 250 /// <summary>
251 /// Maps a unique geometry id (a memory location) to a physics actor name.
252 /// </summary>
253 /// <remarks>
254 /// Only actors participating in collisions have geometries. This has to be maintained separately from
255 /// actor_name_map because terrain and water currently don't conceptually have a physics actor of their own
256 /// apart from the singleton PANull
257 /// </remarks>
232 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); 258 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>();
259
260 /// <summary>
261 /// Maps a unique geometry id (a memory location) to a physics actor.
262 /// </summary>
263 /// <remarks>
264 /// Only actors participating in collisions have geometries.
265 /// </remarks>
233 public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); 266 public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>();
267
268 /// <summary>
269 /// Defects list to remove characters that no longer have finite positions due to some other bug.
270 /// </summary>
271 /// <remarks>
272 /// Used repeatedly in Simulate() but initialized once here.
273 /// </remarks>
274 private readonly List<OdeCharacter> defects = new List<OdeCharacter>();
275
234 private bool m_NINJA_physics_joints_enabled = false; 276 private bool m_NINJA_physics_joints_enabled = false;
235 //private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>(); 277 //private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>();
236 private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>(); 278 private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>();
237 private d.ContactGeom[] contacts; 279 private d.ContactGeom[] contacts;
238 private readonly List<PhysicsJoint> requestedJointsToBeCreated = new List<PhysicsJoint>(); // lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active 280
239 private readonly List<PhysicsJoint> pendingJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene. 281 /// <summary>
240 private readonly List<PhysicsJoint> activeJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene. 282 /// Lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active
241 private readonly List<string> requestedJointsToBeDeleted = new List<string>(); // lock only briefly. accessed by external code (to request deletion of joints) and by OdeScene.Simulate() to move those joints out of pending/active 283 /// </summary>
284 private readonly List<PhysicsJoint> requestedJointsToBeCreated = new List<PhysicsJoint>();
285
286 /// <summary>
287 /// can lock for longer. accessed only by OdeScene.
288 /// </summary>
289 private readonly List<PhysicsJoint> pendingJoints = new List<PhysicsJoint>();
290
291 /// <summary>
292 /// can lock for longer. accessed only by OdeScene.
293 /// </summary>
294 private readonly List<PhysicsJoint> activeJoints = new List<PhysicsJoint>();
295
296 /// <summary>
297 /// lock only briefly. accessed by external code (to request deletion of joints) and by OdeScene.Simulate() to move those joints out of pending/active
298 /// </summary>
299 private readonly List<string> requestedJointsToBeDeleted = new List<string>();
300
242 private Object externalJointRequestsLock = new Object(); 301 private Object externalJointRequestsLock = new Object();
243 private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>(); 302 private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>();
244 private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>(); 303 private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>();
@@ -318,8 +377,7 @@ namespace OpenSim.Region.Physics.OdePlugin
318 /// <param value="name">Name of the scene. Useful in debug messages.</param> 377 /// <param value="name">Name of the scene. Useful in debug messages.</param>
319 public OdeScene(string name) 378 public OdeScene(string name)
320 { 379 {
321 m_log 380 m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name);
322 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name);
323 381
324 Name = name; 382 Name = name;
325 383
@@ -663,11 +721,11 @@ namespace OpenSim.Region.Physics.OdePlugin
663 } 721 }
664 } 722 }
665 723
666 internal void waitForSpaceUnlock(IntPtr space) 724// internal void waitForSpaceUnlock(IntPtr space)
667 { 725// {
668 //if (space != IntPtr.Zero) 726// //if (space != IntPtr.Zero)
669 //while (d.SpaceLockQuery(space)) { } // Wait and do nothing 727// //while (d.SpaceLockQuery(space)) { } // Wait and do nothing
670 } 728// }
671 729
672// /// <summary> 730// /// <summary>
673// /// Debug space message for printing the space that a prim/avatar is in. 731// /// Debug space message for printing the space that a prim/avatar is in.
@@ -710,7 +768,7 @@ namespace OpenSim.Region.Physics.OdePlugin
710 } 768 }
711 catch (AccessViolationException) 769 catch (AccessViolationException)
712 { 770 {
713 m_log.Warn("[PHYSICS]: Unable to collide test a space"); 771 m_log.Warn("[ODE SCENE]: Unable to collide test a space");
714 return; 772 return;
715 } 773 }
716 //Colliding a space or a geom with a space or a geom. so drill down 774 //Colliding a space or a geom with a space or a geom. so drill down
@@ -760,22 +818,19 @@ namespace OpenSim.Region.Physics.OdePlugin
760 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 818 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
761 return; 819 return;
762 820
763 lock (contacts) 821 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf);
764 { 822 if (count > contacts.Length)
765 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); 823 m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length);
766 if (count > contacts.Length)
767 m_log.Error("[PHYSICS]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length);
768 }
769 } 824 }
770 catch (SEHException) 825 catch (SEHException)
771 { 826 {
772 m_log.Error( 827 m_log.Error(
773 "[PHYSICS]: 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."); 828 "[ODE SCENE]: 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.");
774 base.TriggerPhysicsBasedRestart(); 829 base.TriggerPhysicsBasedRestart();
775 } 830 }
776 catch (Exception e) 831 catch (Exception e)
777 { 832 {
778 m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); 833 m_log.WarnFormat("[ODE SCENE]: Unable to collide test an object: {0}", e.Message);
779 return; 834 return;
780 } 835 }
781 836
@@ -1029,6 +1084,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1029 1084
1030 if (!skipThisContact) 1085 if (!skipThisContact)
1031 { 1086 {
1087 _perloopContact.Add(curContact);
1088
1032 // If we're colliding against terrain 1089 // If we're colliding against terrain
1033 if (name1 == "Terrain" || name2 == "Terrain") 1090 if (name1 == "Terrain" || name2 == "Terrain")
1034 { 1091 {
@@ -1038,7 +1095,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1038 { 1095 {
1039 // Use the movement terrain contact 1096 // Use the movement terrain contact
1040 AvatarMovementTerrainContact.geom = curContact; 1097 AvatarMovementTerrainContact.geom = curContact;
1041 _perloopContact.Add(curContact); 1098
1042 if (m_global_contactcount < maxContactsbeforedeath) 1099 if (m_global_contactcount < maxContactsbeforedeath)
1043 { 1100 {
1044 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); 1101 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
@@ -1051,7 +1108,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1051 { 1108 {
1052 // Use the non moving terrain contact 1109 // Use the non moving terrain contact
1053 TerrainContact.geom = curContact; 1110 TerrainContact.geom = curContact;
1054 _perloopContact.Add(curContact); 1111
1055 if (m_global_contactcount < maxContactsbeforedeath) 1112 if (m_global_contactcount < maxContactsbeforedeath)
1056 { 1113 {
1057 joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); 1114 joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
@@ -1077,7 +1134,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1077 1134
1078 //m_log.DebugFormat("Material: {0}", material); 1135 //m_log.DebugFormat("Material: {0}", material);
1079 m_materialContacts[material, movintYN].geom = curContact; 1136 m_materialContacts[material, movintYN].geom = curContact;
1080 _perloopContact.Add(curContact);
1081 1137
1082 if (m_global_contactcount < maxContactsbeforedeath) 1138 if (m_global_contactcount < maxContactsbeforedeath)
1083 { 1139 {
@@ -1098,9 +1154,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1098 1154
1099 if (p2 is OdePrim) 1155 if (p2 is OdePrim)
1100 material = ((OdePrim)p2).m_material; 1156 material = ((OdePrim)p2).m_material;
1157
1101 //m_log.DebugFormat("Material: {0}", material); 1158 //m_log.DebugFormat("Material: {0}", material);
1102 m_materialContacts[material, movintYN].geom = curContact; 1159 m_materialContacts[material, movintYN].geom = curContact;
1103 _perloopContact.Add(curContact);
1104 1160
1105 if (m_global_contactcount < maxContactsbeforedeath) 1161 if (m_global_contactcount < maxContactsbeforedeath)
1106 { 1162 {
@@ -1133,8 +1189,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1133 //contact.normal = new d.Vector3(0, 0, 1); 1189 //contact.normal = new d.Vector3(0, 0, 1);
1134 //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f); 1190 //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f);
1135 } 1191 }
1192
1136 WaterContact.geom = curContact; 1193 WaterContact.geom = curContact;
1137 _perloopContact.Add(curContact); 1194
1138 if (m_global_contactcount < maxContactsbeforedeath) 1195 if (m_global_contactcount < maxContactsbeforedeath)
1139 { 1196 {
1140 joint = d.JointCreateContact(world, contactgroup, ref WaterContact); 1197 joint = d.JointCreateContact(world, contactgroup, ref WaterContact);
@@ -1152,7 +1209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1152 { 1209 {
1153 // Use the Movement prim contact 1210 // Use the Movement prim contact
1154 AvatarMovementprimContact.geom = curContact; 1211 AvatarMovementprimContact.geom = curContact;
1155 _perloopContact.Add(curContact); 1212
1156 if (m_global_contactcount < maxContactsbeforedeath) 1213 if (m_global_contactcount < maxContactsbeforedeath)
1157 { 1214 {
1158 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); 1215 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
@@ -1182,13 +1239,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1182 1239
1183 //m_log.DebugFormat("Material: {0}", material); 1240 //m_log.DebugFormat("Material: {0}", material);
1184 m_materialContacts[material, 0].geom = curContact; 1241 m_materialContacts[material, 0].geom = curContact;
1185 _perloopContact.Add(curContact);
1186 1242
1187 if (m_global_contactcount < maxContactsbeforedeath) 1243 if (m_global_contactcount < maxContactsbeforedeath)
1188 { 1244 {
1189 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); 1245 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]);
1190 m_global_contactcount++; 1246 m_global_contactcount++;
1191
1192 } 1247 }
1193 } 1248 }
1194 } 1249 }
@@ -1217,69 +1272,65 @@ namespace OpenSim.Region.Physics.OdePlugin
1217 1272
1218 private bool checkDupe(d.ContactGeom contactGeom, int atype) 1273 private bool checkDupe(d.ContactGeom contactGeom, int atype)
1219 { 1274 {
1220 bool result = false;
1221 //return result;
1222 if (!m_filterCollisions) 1275 if (!m_filterCollisions)
1223 return false; 1276 return false;
1224 1277
1278 bool result = false;
1279
1225 ActorTypes at = (ActorTypes)atype; 1280 ActorTypes at = (ActorTypes)atype;
1226 lock (_perloopContact) 1281
1282 foreach (d.ContactGeom contact in _perloopContact)
1227 { 1283 {
1228 foreach (d.ContactGeom contact in _perloopContact) 1284 //if ((contact.g1 == contactGeom.g1 && contact.g2 == contactGeom.g2))
1285 //{
1286 // || (contact.g2 == contactGeom.g1 && contact.g1 == contactGeom.g2)
1287 if (at == ActorTypes.Agent)
1229 { 1288 {
1230 //if ((contact.g1 == contactGeom.g1 && contact.g2 == contactGeom.g2)) 1289 if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f)
1231 //{ 1290 && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f)
1232 // || (contact.g2 == contactGeom.g1 && contact.g1 == contactGeom.g2) 1291 && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f))
1233 if (at == ActorTypes.Agent) 1292 && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom)
1234 { 1293 {
1235 if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom) 1294 if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f)
1236 { 1295 {
1237 1296 //contactGeom.depth *= .00005f;
1238 if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f) 1297 //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth));
1239 { 1298 // m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z));
1240 //contactGeom.depth *= .00005f; 1299 result = true;
1241 //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); 1300 break;
1242 // m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); 1301 }
1243 result = true; 1302// else
1244 break; 1303// {
1245 } 1304// //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth));
1246 else 1305// }
1247 { 1306 }
1248 //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); 1307// else
1249 } 1308// {
1250 } 1309// //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z));
1251 else 1310// //int i = 0;
1252 { 1311// }
1253 //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); 1312 }
1254 //int i = 0; 1313 else if (at == ActorTypes.Prim)
1255 } 1314 {
1256 } 1315 //d.AABB aabb1 = new d.AABB();
1257 else if (at == ActorTypes.Prim) 1316 //d.AABB aabb2 = new d.AABB();
1317
1318 //d.GeomGetAABB(contactGeom.g2, out aabb2);
1319 //d.GeomGetAABB(contactGeom.g1, out aabb1);
1320 //aabb1.
1321 if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom)
1258 { 1322 {
1259 //d.AABB aabb1 = new d.AABB(); 1323 if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z)
1260 //d.AABB aabb2 = new d.AABB(); 1324 {
1261 1325 if (Math.Abs(contact.depth - contactGeom.depth) < 0.272f)
1262 //d.GeomGetAABB(contactGeom.g2, out aabb2);
1263 //d.GeomGetAABB(contactGeom.g1, out aabb1);
1264 //aabb1.
1265 if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom)
1266 { 1326 {
1267 if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z) 1327 result = true;
1268 { 1328 break;
1269 if (Math.Abs(contact.depth - contactGeom.depth) < 0.272f)
1270 {
1271 result = true;
1272 break;
1273 }
1274 }
1275 //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth));
1276 //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z));
1277 } 1329 }
1278 1330 }
1331 //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth));
1332 //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z));
1279 } 1333 }
1280
1281 //}
1282
1283 } 1334 }
1284 } 1335 }
1285 1336
@@ -1482,90 +1533,77 @@ namespace OpenSim.Region.Physics.OdePlugin
1482 { 1533 {
1483 _perloopContact.Clear(); 1534 _perloopContact.Clear();
1484 1535
1485 lock (_characters) 1536 foreach (OdeCharacter chr in _characters)
1486 { 1537 {
1487 foreach (OdeCharacter chr in _characters) 1538 // Reset the collision values to false
1539 // since we don't know if we're colliding yet
1540 if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
1541 continue;
1542
1543 chr.IsColliding = false;
1544 chr.CollidingGround = false;
1545 chr.CollidingObj = false;
1546
1547 // test the avatar's geometry for collision with the space
1548 // This will return near and the space that they are the closest to
1549 // And we'll run this again against the avatar and the space segment
1550 // This will return with a bunch of possible objects in the space segment
1551 // and we'll run it again on all of them.
1552 try
1488 { 1553 {
1489 // Reset the collision values to false 1554 d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
1490 // since we don't know if we're colliding yet
1491
1492 // For some reason this can happen. Don't ask...
1493 //
1494 if (chr == null)
1495 continue;
1496
1497 if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
1498 continue;
1499
1500 chr.IsColliding = false;
1501 chr.CollidingGround = false;
1502 chr.CollidingObj = false;
1503
1504 // test the avatar's geometry for collision with the space
1505 // This will return near and the space that they are the closest to
1506 // And we'll run this again against the avatar and the space segment
1507 // This will return with a bunch of possible objects in the space segment
1508 // and we'll run it again on all of them.
1509 try
1510 {
1511 d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
1512 }
1513 catch (AccessViolationException)
1514 {
1515 m_log.Warn("[PHYSICS]: Unable to space collide");
1516 }
1517 //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y);
1518 //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10)
1519 //{
1520 //chr.Position.Z = terrainheight + 10.0f;
1521 //forcedZ = true;
1522 //}
1523 } 1555 }
1556 catch (AccessViolationException)
1557 {
1558 m_log.WarnFormat("[ODE SCENE]: Unable to space collide {0}", Name);
1559 }
1560
1561 //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y);
1562 //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10)
1563 //{
1564 //chr.Position.Z = terrainheight + 10.0f;
1565 //forcedZ = true;
1566 //}
1524 } 1567 }
1525 1568
1526 lock (_activeprims) 1569 List<OdePrim> removeprims = null;
1570 foreach (OdePrim chr in _activeprims)
1527 { 1571 {
1528 List<OdePrim> removeprims = null; 1572 if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled))
1529 foreach (OdePrim chr in _activeprims)
1530 { 1573 {
1531 if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled)) 1574 try
1532 { 1575 {
1533 try 1576 lock (chr)
1534 { 1577 {
1535 lock (chr) 1578 if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false)
1536 { 1579 {
1537 if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false) 1580 d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback);
1538 { 1581 }
1539 d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback); 1582 else
1540 } 1583 {
1541 else 1584 if (removeprims == null)
1542 { 1585 {
1543 if (removeprims == null) 1586 removeprims = new List<OdePrim>();
1544 {
1545 removeprims = new List<OdePrim>();
1546 }
1547 removeprims.Add(chr);
1548 m_log.Debug("[PHYSICS]: unable to collide test active prim against space. The space was zero, the geom was zero or it was in the process of being removed. Removed it from the active prim list. This needs to be fixed!");
1549 } 1587 }
1588 removeprims.Add(chr);
1589 m_log.Debug("[ODE SCENE]: unable to collide test active prim against space. The space was zero, the geom was zero or it was in the process of being removed. Removed it from the active prim list. This needs to be fixed!");
1550 } 1590 }
1551 } 1591 }
1552 catch (AccessViolationException)
1553 {
1554 m_log.Warn("[PHYSICS]: Unable to space collide");
1555 }
1556 } 1592 }
1557 } 1593 catch (AccessViolationException)
1558
1559 if (removeprims != null)
1560 {
1561 foreach (OdePrim chr in removeprims)
1562 { 1594 {
1563 _activeprims.Remove(chr); 1595 m_log.Warn("[ODE SCENE]: Unable to space collide");
1564 } 1596 }
1565 } 1597 }
1566 } 1598 }
1567 1599
1568 _perloopContact.Clear(); 1600 if (removeprims != null)
1601 {
1602 foreach (OdePrim chr in removeprims)
1603 {
1604 _activeprims.Remove(chr);
1605 }
1606 }
1569 } 1607 }
1570 1608
1571 #endregion 1609 #endregion
@@ -1685,35 +1723,29 @@ namespace OpenSim.Region.Physics.OdePlugin
1685 1723
1686 internal void AddCharacter(OdeCharacter chr) 1724 internal void AddCharacter(OdeCharacter chr)
1687 { 1725 {
1688 lock (_characters) 1726 if (!_characters.Contains(chr))
1689 { 1727 {
1690 if (!_characters.Contains(chr)) 1728 _characters.Add(chr);
1691 {
1692 _characters.Add(chr);
1693 if (chr.bad)
1694 m_log.DebugFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid);
1695 }
1696 }
1697 }
1698 1729
1699 internal void RemoveCharacter(OdeCharacter chr) 1730 if (chr.bad)
1700 { 1731 m_log.ErrorFormat("[ODE SCENE]: Added BAD actor {0} to characters list", chr.m_uuid);
1701 lock (_characters) 1732 }
1733 else
1702 { 1734 {
1703 if (_characters.Contains(chr)) 1735 m_log.ErrorFormat(
1704 { 1736 "[ODE SCENE]: Tried to add character {0} {1} but they are already in the set!",
1705 _characters.Remove(chr); 1737 chr.Name, chr.LocalID);
1706 }
1707 } 1738 }
1708 } 1739 }
1709 1740
1710 internal void BadCharacter(OdeCharacter chr) 1741 internal void RemoveCharacter(OdeCharacter chr)
1711 { 1742 {
1712 lock (_badCharacter) 1743 if (_characters.Contains(chr))
1713 { 1744 _characters.Remove(chr);
1714 if (!_badCharacter.Contains(chr)) 1745 else
1715 _badCharacter.Add(chr); 1746 m_log.ErrorFormat(
1716 } 1747 "[ODE SCENE]: Tried to remove character {0} {1} but they are not in the list!",
1748 chr.Name, chr.LocalID);
1717 } 1749 }
1718 1750
1719 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, 1751 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
@@ -1742,13 +1774,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1742 internal void ActivatePrim(OdePrim prim) 1774 internal void ActivatePrim(OdePrim prim)
1743 { 1775 {
1744 // adds active prim.. (ones that should be iterated over in collisions_optimized 1776 // adds active prim.. (ones that should be iterated over in collisions_optimized
1745 lock (_activeprims) 1777 if (!_activeprims.Contains(prim))
1746 { 1778 _activeprims.Add(prim);
1747 if (!_activeprims.Contains(prim)) 1779 //else
1748 _activeprims.Add(prim); 1780 // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent");
1749 //else
1750 // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent");
1751 }
1752 } 1781 }
1753 1782
1754 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 1783 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
@@ -2027,7 +2056,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2027 //m_log.Debug("RemoveAllJointsConnectedToActor: start"); 2056 //m_log.Debug("RemoveAllJointsConnectedToActor: start");
2028 if (actor.SOPName != null && joints_connecting_actor.ContainsKey(actor.SOPName) && joints_connecting_actor[actor.SOPName] != null) 2057 if (actor.SOPName != null && joints_connecting_actor.ContainsKey(actor.SOPName) && joints_connecting_actor[actor.SOPName] != null)
2029 { 2058 {
2030
2031 List<PhysicsJoint> jointsToRemove = new List<PhysicsJoint>(); 2059 List<PhysicsJoint> jointsToRemove = new List<PhysicsJoint>();
2032 //TODO: merge these 2 loops (originally it was needed to avoid altering a list being iterated over, but it is no longer needed due to the joint request queue mechanism) 2060 //TODO: merge these 2 loops (originally it was needed to avoid altering a list being iterated over, but it is no longer needed due to the joint request queue mechanism)
2033 foreach (PhysicsJoint j in joints_connecting_actor[actor.SOPName]) 2061 foreach (PhysicsJoint j in joints_connecting_actor[actor.SOPName])
@@ -2122,8 +2150,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2122 /// <param name="prim"></param> 2150 /// <param name="prim"></param>
2123 internal void DeactivatePrim(OdePrim prim) 2151 internal void DeactivatePrim(OdePrim prim)
2124 { 2152 {
2125 lock (_activeprims) 2153 _activeprims.Remove(prim);
2126 _activeprims.Remove(prim);
2127 } 2154 }
2128 2155
2129 public override void RemovePrim(PhysicsActor prim) 2156 public override void RemovePrim(PhysicsActor prim)
@@ -2138,7 +2165,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2138 2165
2139 p.setPrimForRemoval(); 2166 p.setPrimForRemoval();
2140 AddPhysicsActorTaint(prim); 2167 AddPhysicsActorTaint(prim);
2141 //RemovePrimThreadLocked(p);
2142 } 2168 }
2143 } 2169 }
2144 } 2170 }
@@ -2206,7 +2232,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2206 //m_log.Warn(prim.prim_geom); 2232 //m_log.Warn(prim.prim_geom);
2207 2233
2208 if (!prim.RemoveGeom()) 2234 if (!prim.RemoveGeom())
2209 m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); 2235 m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene");
2210 2236
2211 lock (_prims) 2237 lock (_prims)
2212 _prims.Remove(prim); 2238 _prims.Remove(prim);
@@ -2293,12 +2319,12 @@ namespace OpenSim.Region.Physics.OdePlugin
2293 { 2319 {
2294 if (d.GeomIsSpace(currentspace)) 2320 if (d.GeomIsSpace(currentspace))
2295 { 2321 {
2296 waitForSpaceUnlock(currentspace); 2322// waitForSpaceUnlock(currentspace);
2297 d.SpaceRemove(currentspace, geom); 2323 d.SpaceRemove(currentspace, geom);
2298 } 2324 }
2299 else 2325 else
2300 { 2326 {
2301 m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + currentspace + 2327 m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + currentspace +
2302 " Geom:" + geom); 2328 " Geom:" + geom);
2303 } 2329 }
2304 } 2330 }
@@ -2309,12 +2335,12 @@ namespace OpenSim.Region.Physics.OdePlugin
2309 { 2335 {
2310 if (d.GeomIsSpace(currentspace)) 2336 if (d.GeomIsSpace(currentspace))
2311 { 2337 {
2312 waitForSpaceUnlock(sGeomIsIn); 2338// waitForSpaceUnlock(sGeomIsIn);
2313 d.SpaceRemove(sGeomIsIn, geom); 2339 d.SpaceRemove(sGeomIsIn, geom);
2314 } 2340 }
2315 else 2341 else
2316 { 2342 {
2317 m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + 2343 m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" +
2318 sGeomIsIn + " Geom:" + geom); 2344 sGeomIsIn + " Geom:" + geom);
2319 } 2345 }
2320 } 2346 }
@@ -2327,8 +2353,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2327 { 2353 {
2328 if (d.GeomIsSpace(currentspace)) 2354 if (d.GeomIsSpace(currentspace))
2329 { 2355 {
2330 waitForSpaceUnlock(currentspace); 2356// waitForSpaceUnlock(currentspace);
2331 waitForSpaceUnlock(space); 2357// waitForSpaceUnlock(space);
2332 d.SpaceRemove(space, currentspace); 2358 d.SpaceRemove(space, currentspace);
2333 // free up memory used by the space. 2359 // free up memory used by the space.
2334 2360
@@ -2337,7 +2363,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2337 } 2363 }
2338 else 2364 else
2339 { 2365 {
2340 m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + 2366 m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" +
2341 currentspace + " Geom:" + geom); 2367 currentspace + " Geom:" + geom);
2342 } 2368 }
2343 } 2369 }
@@ -2352,12 +2378,12 @@ namespace OpenSim.Region.Physics.OdePlugin
2352 { 2378 {
2353 if (d.GeomIsSpace(currentspace)) 2379 if (d.GeomIsSpace(currentspace))
2354 { 2380 {
2355 waitForSpaceUnlock(currentspace); 2381// waitForSpaceUnlock(currentspace);
2356 d.SpaceRemove(currentspace, geom); 2382 d.SpaceRemove(currentspace, geom);
2357 } 2383 }
2358 else 2384 else
2359 { 2385 {
2360 m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + 2386 m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" +
2361 currentspace + " Geom:" + geom); 2387 currentspace + " Geom:" + geom);
2362 } 2388 }
2363 } 2389 }
@@ -2368,12 +2394,12 @@ namespace OpenSim.Region.Physics.OdePlugin
2368 { 2394 {
2369 if (d.GeomIsSpace(sGeomIsIn)) 2395 if (d.GeomIsSpace(sGeomIsIn))
2370 { 2396 {
2371 waitForSpaceUnlock(sGeomIsIn); 2397// waitForSpaceUnlock(sGeomIsIn);
2372 d.SpaceRemove(sGeomIsIn, geom); 2398 d.SpaceRemove(sGeomIsIn, geom);
2373 } 2399 }
2374 else 2400 else
2375 { 2401 {
2376 m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + 2402 m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" +
2377 sGeomIsIn + " Geom:" + geom); 2403 sGeomIsIn + " Geom:" + geom);
2378 } 2404 }
2379 } 2405 }
@@ -2407,9 +2433,10 @@ namespace OpenSim.Region.Physics.OdePlugin
2407 // creating a new space for prim and inserting it into main space. 2433 // creating a new space for prim and inserting it into main space.
2408 staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero); 2434 staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero);
2409 d.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)CollisionCategories.Space); 2435 d.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)CollisionCategories.Space);
2410 waitForSpaceUnlock(space); 2436// waitForSpaceUnlock(space);
2411 d.SpaceSetSublevel(space, 1); 2437 d.SpaceSetSublevel(space, 1);
2412 d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]); 2438 d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]);
2439
2413 return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]; 2440 return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY];
2414 } 2441 }
2415 2442
@@ -2584,15 +2611,17 @@ namespace OpenSim.Region.Physics.OdePlugin
2584 2611
2585 /// <summary> 2612 /// <summary>
2586 /// Called after our prim properties are set Scale, position etc. 2613 /// Called after our prim properties are set Scale, position etc.
2614 /// </summary>
2615 /// <remarks>
2587 /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex 2616 /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex
2588 /// This assures us that we have no race conditions 2617 /// This assures us that we have no race conditions
2589 /// </summary> 2618 /// </remarks>
2590 /// <param name="prim"></param> 2619 /// <param name="actor"></param>
2591 public override void AddPhysicsActorTaint(PhysicsActor prim) 2620 public override void AddPhysicsActorTaint(PhysicsActor actor)
2592 { 2621 {
2593 if (prim is OdePrim) 2622 if (actor is OdePrim)
2594 { 2623 {
2595 OdePrim taintedprim = ((OdePrim) prim); 2624 OdePrim taintedprim = ((OdePrim)actor);
2596 lock (_taintedPrimLock) 2625 lock (_taintedPrimLock)
2597 { 2626 {
2598 if (!(_taintedPrimH.Contains(taintedprim))) 2627 if (!(_taintedPrimH.Contains(taintedprim)))
@@ -2604,18 +2633,17 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2604 _taintedPrimL.Add(taintedprim); // List for ordered readout 2633 _taintedPrimL.Add(taintedprim); // List for ordered readout
2605 } 2634 }
2606 } 2635 }
2607 return;
2608 } 2636 }
2609 else if (prim is OdeCharacter) 2637 else if (actor is OdeCharacter)
2610 { 2638 {
2611 OdeCharacter taintedchar = ((OdeCharacter)prim); 2639 OdeCharacter taintedchar = ((OdeCharacter)actor);
2612 lock (_taintedActors) 2640 lock (_taintedActors)
2613 { 2641 {
2614 if (!(_taintedActors.Contains(taintedchar))) 2642 if (!(_taintedActors.Contains(taintedchar)))
2615 { 2643 {
2616 _taintedActors.Add(taintedchar); 2644 _taintedActors.Add(taintedchar);
2617 if (taintedchar.bad) 2645 if (taintedchar.bad)
2618 m_log.DebugFormat("[PHYSICS]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid); 2646 m_log.DebugFormat("[ODE SCENE]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid);
2619 } 2647 }
2620 } 2648 }
2621 } 2649 }
@@ -2711,29 +2739,18 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2711 { 2739 {
2712 try 2740 try
2713 { 2741 {
2714 // Insert, remove Characters
2715 bool processedtaints = false;
2716
2717 lock (_taintedActors) 2742 lock (_taintedActors)
2718 { 2743 {
2719 if (_taintedActors.Count > 0) 2744 if (_taintedActors.Count > 0)
2720 { 2745 {
2721 foreach (OdeCharacter character in _taintedActors) 2746 foreach (OdeCharacter character in _taintedActors)
2722 {
2723 character.ProcessTaints(); 2747 character.ProcessTaints();
2724 2748
2725 processedtaints = true; 2749 if (_taintedActors.Count > 0)
2726 //character.m_collisionscore = 0;
2727 }
2728
2729 if (processedtaints)
2730 _taintedActors.Clear(); 2750 _taintedActors.Clear();
2731 } 2751 }
2732 } 2752 }
2733 2753
2734 // Modify other objects in the scene.
2735 processedtaints = false;
2736
2737 lock (_taintedPrimLock) 2754 lock (_taintedPrimLock)
2738 { 2755 {
2739 foreach (OdePrim prim in _taintedPrimL) 2756 foreach (OdePrim prim in _taintedPrimL)
@@ -2749,7 +2766,6 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2749 prim.ProcessTaints(); 2766 prim.ProcessTaints();
2750 } 2767 }
2751 2768
2752 processedtaints = true;
2753 prim.m_collisionscore = 0; 2769 prim.m_collisionscore = 0;
2754 2770
2755 // This loop can block up the Heartbeat for a very long time on large regions. 2771 // This loop can block up the Heartbeat for a very long time on large regions.
@@ -2762,7 +2778,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2762 if (SupportsNINJAJoints) 2778 if (SupportsNINJAJoints)
2763 SimulatePendingNINJAJoints(); 2779 SimulatePendingNINJAJoints();
2764 2780
2765 if (processedtaints) 2781 if (_taintedPrimL.Count > 0)
2766 { 2782 {
2767//Console.WriteLine("Simulate calls Clear of _taintedPrim list"); 2783//Console.WriteLine("Simulate calls Clear of _taintedPrim list");
2768 _taintedPrimH.Clear(); 2784 _taintedPrimH.Clear();
@@ -2771,31 +2787,25 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2771 } 2787 }
2772 2788
2773 // Move characters 2789 // Move characters
2774 lock (_characters) 2790 foreach (OdeCharacter actor in _characters)
2791 actor.Move(defects);
2792
2793 if (defects.Count != 0)
2775 { 2794 {
2776 List<OdeCharacter> defects = new List<OdeCharacter>(); 2795 foreach (OdeCharacter actor in defects)
2777 foreach (OdeCharacter actor in _characters)
2778 {
2779 if (actor != null)
2780 actor.Move(defects);
2781 }
2782 if (0 != defects.Count)
2783 { 2796 {
2784 foreach (OdeCharacter defect in defects) 2797 RemoveCharacter(actor);
2785 { 2798 actor.DestroyOdeStructures();
2786 RemoveCharacter(defect);
2787 }
2788 } 2799 }
2800
2801 defects.Clear();
2789 } 2802 }
2790 2803
2791 // Move other active objects 2804 // Move other active objects
2792 lock (_activeprims) 2805 foreach (OdePrim prim in _activeprims)
2793 { 2806 {
2794 foreach (OdePrim prim in _activeprims) 2807 prim.m_collisionscore = 0;
2795 { 2808 prim.Move(timeStep);
2796 prim.m_collisionscore = 0;
2797 prim.Move(timeStep);
2798 }
2799 } 2809 }
2800 2810
2801 //if ((framecount % m_randomizeWater) == 0) 2811 //if ((framecount % m_randomizeWater) == 0)
@@ -2836,53 +2846,41 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2836 } 2846 }
2837 catch (Exception e) 2847 catch (Exception e)
2838 { 2848 {
2839 m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); 2849 m_log.ErrorFormat("[ODE SCENE]: {0}, {1}, {2}", e.Message, e.TargetSite, e);
2840 } 2850 }
2841 2851
2842 timeLeft -= ODE_STEPSIZE; 2852 timeLeft -= ODE_STEPSIZE;
2843 } 2853 }
2844 2854
2845 lock (_characters) 2855 foreach (OdeCharacter actor in _characters)
2846 { 2856 {
2847 foreach (OdeCharacter actor in _characters) 2857 if (actor.bad)
2848 { 2858 m_log.WarnFormat("[ODE SCENE]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
2849 if (actor != null)
2850 {
2851 if (actor.bad)
2852 m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
2853 2859
2854 actor.UpdatePositionAndVelocity(); 2860 actor.UpdatePositionAndVelocity(defects);
2855 }
2856 }
2857 } 2861 }
2858 2862
2859 lock (_badCharacter) 2863 if (defects.Count != 0)
2860 { 2864 {
2861 if (_badCharacter.Count > 0) 2865 foreach (OdeCharacter actor in defects)
2862 { 2866 {
2863 foreach (OdeCharacter chr in _badCharacter) 2867 RemoveCharacter(actor);
2864 { 2868 actor.DestroyOdeStructures();
2865 RemoveCharacter(chr);
2866 }
2867
2868 _badCharacter.Clear();
2869 } 2869 }
2870
2871 defects.Clear();
2870 } 2872 }
2871 2873
2872 lock (_activeprims) 2874 //if (timeStep < 0.2f)
2875
2876 foreach (OdePrim prim in _activeprims)
2873 { 2877 {
2874 //if (timeStep < 0.2f) 2878 if (prim.IsPhysical && (d.BodyIsEnabled(prim.Body) || !prim._zeroFlag))
2875 { 2879 {
2876 foreach (OdePrim prim in _activeprims) 2880 prim.UpdatePositionAndVelocity();
2877 {
2878 if (prim.IsPhysical && (d.BodyIsEnabled(prim.Body) || !prim._zeroFlag))
2879 {
2880 prim.UpdatePositionAndVelocity();
2881 2881
2882 if (SupportsNINJAJoints) 2882 if (SupportsNINJAJoints)
2883 SimulateActorPendingJoints(prim); 2883 SimulateActorPendingJoints(prim);
2884 }
2885 }
2886 } 2884 }
2887 } 2885 }
2888 2886
@@ -3417,7 +3415,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3417 { 3415 {
3418 if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x])) 3416 if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x]))
3419 { 3417 {
3420 m_log.Warn("[PHYSICS]: Non finite heightfield element detected. Setting it to 0"); 3418 m_log.Warn("[ODE SCENE]: Non finite heightfield element detected. Setting it to 0");
3421 resultarr2[y, x] = 0; 3419 resultarr2[y, x] = 0;
3422 } 3420 }
3423 returnarr[i] = resultarr2[y, x]; 3421 returnarr[i] = resultarr2[y, x];
@@ -3448,7 +3446,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3448 private void SetTerrain(float[] heightMap, Vector3 pOffset) 3446 private void SetTerrain(float[] heightMap, Vector3 pOffset)
3449 { 3447 {
3450 int startTime = Util.EnvironmentTickCount(); 3448 int startTime = Util.EnvironmentTickCount();
3451 m_log.DebugFormat("[PHYSICS]: Setting terrain for {0}", Name); 3449 m_log.DebugFormat("[ODE SCENE]: Setting terrain for {0}", Name);
3452 3450
3453 // this._heightmap[i] = (double)heightMap[i]; 3451 // this._heightmap[i] = (double)heightMap[i];
3454 // dbm (danx0r) -- creating a buffer zone of one extra sample all around 3452 // dbm (danx0r) -- creating a buffer zone of one extra sample all around
@@ -3573,7 +3571,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3573 } 3571 }
3574 3572
3575 m_log.DebugFormat( 3573 m_log.DebugFormat(
3576 "[PHYSICS]: Setting terrain for {0} took {1}ms", Name, Util.EnvironmentTickCountSubtract(startTime)); 3574 "[ODE SCENE]: Setting terrain for {0} took {1}ms", Name, Util.EnvironmentTickCountSubtract(startTime));
3577 } 3575 }
3578 3576
3579 public override void DeleteTerrain() 3577 public override void DeleteTerrain()
@@ -3590,64 +3588,64 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3590 return true; 3588 return true;
3591 } 3589 }
3592 3590
3593 public override void UnCombine(PhysicsScene pScene) 3591// public override void UnCombine(PhysicsScene pScene)
3594 { 3592// {
3595 IntPtr localGround = IntPtr.Zero; 3593// IntPtr localGround = IntPtr.Zero;
3596// float[] localHeightfield; 3594//// float[] localHeightfield;
3597 bool proceed = false; 3595// bool proceed = false;
3598 List<IntPtr> geomDestroyList = new List<IntPtr>(); 3596// List<IntPtr> geomDestroyList = new List<IntPtr>();
3599 3597//
3600 lock (OdeLock) 3598// lock (OdeLock)
3601 { 3599// {
3602 if (RegionTerrain.TryGetValue(Vector3.Zero, out localGround)) 3600// if (RegionTerrain.TryGetValue(Vector3.Zero, out localGround))
3603 { 3601// {
3604 foreach (IntPtr geom in TerrainHeightFieldHeights.Keys) 3602// foreach (IntPtr geom in TerrainHeightFieldHeights.Keys)
3605 { 3603// {
3606 if (geom == localGround) 3604// if (geom == localGround)
3607 { 3605// {
3608// localHeightfield = TerrainHeightFieldHeights[geom]; 3606//// localHeightfield = TerrainHeightFieldHeights[geom];
3609 proceed = true; 3607// proceed = true;
3610 } 3608// }
3611 else 3609// else
3612 { 3610// {
3613 geomDestroyList.Add(geom); 3611// geomDestroyList.Add(geom);
3614 } 3612// }
3615 } 3613// }
3616 3614//
3617 if (proceed) 3615// if (proceed)
3618 { 3616// {
3619 m_worldOffset = Vector3.Zero; 3617// m_worldOffset = Vector3.Zero;
3620 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); 3618// WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize);
3621 m_parentScene = null; 3619// m_parentScene = null;
3622 3620//
3623 foreach (IntPtr g in geomDestroyList) 3621// foreach (IntPtr g in geomDestroyList)
3624 { 3622// {
3625 // removingHeightField needs to be done or the garbage collector will 3623// // removingHeightField needs to be done or the garbage collector will
3626 // collect the terrain data before we tell ODE to destroy it causing 3624// // collect the terrain data before we tell ODE to destroy it causing
3627 // memory corruption 3625// // memory corruption
3628 if (TerrainHeightFieldHeights.ContainsKey(g)) 3626// if (TerrainHeightFieldHeights.ContainsKey(g))
3629 { 3627// {
3630// float[] removingHeightField = TerrainHeightFieldHeights[g]; 3628//// float[] removingHeightField = TerrainHeightFieldHeights[g];
3631 TerrainHeightFieldHeights.Remove(g); 3629// TerrainHeightFieldHeights.Remove(g);
3632 3630//
3633 if (RegionTerrain.ContainsKey(g)) 3631// if (RegionTerrain.ContainsKey(g))
3634 { 3632// {
3635 RegionTerrain.Remove(g); 3633// RegionTerrain.Remove(g);
3636 } 3634// }
3637 3635//
3638 d.GeomDestroy(g); 3636// d.GeomDestroy(g);
3639 //removingHeightField = new float[0]; 3637// //removingHeightField = new float[0];
3640 } 3638// }
3641 } 3639// }
3642 3640//
3643 } 3641// }
3644 else 3642// else
3645 { 3643// {
3646 m_log.Warn("[PHYSICS]: Couldn't proceed with UnCombine. Region has inconsistant data."); 3644// m_log.Warn("[PHYSICS]: Couldn't proceed with UnCombine. Region has inconsistant data.");
3647 } 3645// }
3648 } 3646// }
3649 } 3647// }
3650 } 3648// }
3651 3649
3652 public override void SetWaterLevel(float baseheight) 3650 public override void SetWaterLevel(float baseheight)
3653 { 3651 {
@@ -3894,30 +3892,28 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3894 } 3892 }
3895 } 3893 }
3896 ds.SetColor(1.0f, 0.0f, 0.0f); 3894 ds.SetColor(1.0f, 0.0f, 0.0f);
3897 lock (_characters) 3895
3896 foreach (OdeCharacter chr in _characters)
3898 { 3897 {
3899 foreach (OdeCharacter chr in _characters) 3898 if (chr.Shell != IntPtr.Zero)
3900 { 3899 {
3901 if (chr.Shell != IntPtr.Zero) 3900 IntPtr body = d.GeomGetBody(chr.Shell);
3902 {
3903 IntPtr body = d.GeomGetBody(chr.Shell);
3904 3901
3905 d.Vector3 pos; 3902 d.Vector3 pos;
3906 d.GeomCopyPosition(chr.Shell, out pos); 3903 d.GeomCopyPosition(chr.Shell, out pos);
3907 //d.BodyCopyPosition(body, out pos); 3904 //d.BodyCopyPosition(body, out pos);
3908 3905
3909 d.Matrix3 R; 3906 d.Matrix3 R;
3910 d.GeomCopyRotation(chr.Shell, out R); 3907 d.GeomCopyRotation(chr.Shell, out R);
3911 //d.BodyCopyRotation(body, out R); 3908 //d.BodyCopyRotation(body, out R);
3912 3909
3913 ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f); 3910 ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f);
3914 d.Vector3 sides = new d.Vector3(); 3911 d.Vector3 sides = new d.Vector3();
3915 sides.X = 0.5f; 3912 sides.X = 0.5f;
3916 sides.Y = 0.5f; 3913 sides.Y = 0.5f;
3917 sides.Z = 0.5f; 3914 sides.Z = 0.5f;
3918 3915
3919 ds.DrawBox(ref pos, ref R, ref sides); 3916 ds.DrawBox(ref pos, ref R, ref sides);
3920 }
3921 } 3917 }
3922 } 3918 }
3923 } 3919 }