diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 680 |
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 | } |