diff options
author | Teravus Ovares | 2008-03-09 15:43:01 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-03-09 15:43:01 +0000 |
commit | 081b2ac34ec57fe0f67f0e63c9179e3a141f0ea5 (patch) | |
tree | f2d5e9658368e1479e780e5b077b99ef2616b2e5 | |
parent | Update svn properties. (diff) | |
download | opensim-SC-081b2ac34ec57fe0f67f0e63c9179e3a141f0ea5.zip opensim-SC-081b2ac34ec57fe0f67f0e63c9179e3a141f0ea5.tar.gz opensim-SC-081b2ac34ec57fe0f67f0e63c9179e3a141f0ea5.tar.bz2 opensim-SC-081b2ac34ec57fe0f67f0e63c9179e3a141f0ea5.tar.xz |
* Cleaned up some locking on the ODEPlugin to make it more developer friendly
* Expect the occasional deadlock?
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 137 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 864 |
2 files changed, 496 insertions, 505 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 36b3828..8a8a5fb 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | |||
@@ -293,6 +293,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
293 | _parent_scene.addActivePrim(this); | 293 | _parent_scene.addActivePrim(this); |
294 | } | 294 | } |
295 | 295 | ||
296 | #region Mass Calculation | ||
297 | |||
296 | private float CalculateMass() | 298 | private float CalculateMass() |
297 | { | 299 | { |
298 | float volume = 0; | 300 | float volume = 0; |
@@ -598,6 +600,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
598 | return returnMass; | 600 | return returnMass; |
599 | } | 601 | } |
600 | 602 | ||
603 | #endregion | ||
604 | |||
605 | |||
601 | public void setMass() | 606 | public void setMass() |
602 | { | 607 | { |
603 | if (Body != (IntPtr) 0) | 608 | if (Body != (IntPtr) 0) |
@@ -734,11 +739,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
734 | 739 | ||
735 | private void changelink(float timestep) | 740 | private void changelink(float timestep) |
736 | { | 741 | { |
737 | while (ode.lockquery()) | 742 | |
738 | { | ||
739 | } | ||
740 | ode.dlock(_parent_scene.world); | ||
741 | |||
742 | if (_parent == null && m_taintparent != null) | 743 | if (_parent == null && m_taintparent != null) |
743 | { | 744 | { |
744 | if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim) | 745 | if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim) |
@@ -763,18 +764,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
763 | m_linkJoint = (IntPtr)0; | 764 | m_linkJoint = (IntPtr)0; |
764 | 765 | ||
765 | } | 766 | } |
766 | ode.dunlock(_parent_scene.world); | 767 | |
767 | 768 | ||
768 | _parent = m_taintparent; | 769 | _parent = m_taintparent; |
769 | } | 770 | } |
770 | 771 | ||
771 | private void changeSelectedStatus(float timestep) | 772 | private void changeSelectedStatus(float timestep) |
772 | { | 773 | { |
773 | while (ode.lockquery()) | 774 | |
774 | { | ||
775 | } | ||
776 | ode.dlock(_parent_scene.world); | ||
777 | |||
778 | if (m_taintselected) | 775 | if (m_taintselected) |
779 | { | 776 | { |
780 | 777 | ||
@@ -831,7 +828,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
831 | 828 | ||
832 | } | 829 | } |
833 | 830 | ||
834 | ode.dunlock(_parent_scene.world); | 831 | |
835 | resetCollisionAccounting(); | 832 | resetCollisionAccounting(); |
836 | m_isSelected = m_taintselected; | 833 | m_isSelected = m_taintselected; |
837 | } | 834 | } |
@@ -860,10 +857,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
860 | } | 857 | } |
861 | public void changeadd(float timestep) | 858 | public void changeadd(float timestep) |
862 | { | 859 | { |
863 | while (ode.lockquery()) | 860 | |
864 | { | 861 | |
865 | } | ||
866 | ode.dlock(_parent_scene.world); | ||
867 | 862 | ||
868 | int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); | 863 | int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); |
869 | IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position); | 864 | IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position); |
@@ -992,7 +987,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
992 | 987 | ||
993 | 988 | ||
994 | } | 989 | } |
995 | ode.dunlock(_parent_scene.world); | 990 | |
996 | _parent_scene.geom_name_map[prim_geom] = this.m_primName; | 991 | _parent_scene.geom_name_map[prim_geom] = this.m_primName; |
997 | _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; | 992 | _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; |
998 | 993 | ||
@@ -1004,10 +999,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1004 | } | 999 | } |
1005 | public void Move(float timestep) | 1000 | public void Move(float timestep) |
1006 | { | 1001 | { |
1007 | while (ode.lockquery()) | 1002 | |
1008 | { | ||
1009 | } | ||
1010 | ode.dlock(_parent_scene.world); | ||
1011 | 1003 | ||
1012 | 1004 | ||
1013 | if (m_isphysical) | 1005 | if (m_isphysical) |
@@ -1057,7 +1049,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1057 | d.SpaceAdd(m_targetSpace, prim_geom); | 1049 | d.SpaceAdd(m_targetSpace, prim_geom); |
1058 | } | 1050 | } |
1059 | } | 1051 | } |
1060 | ode.dunlock(_parent_scene.world); | 1052 | |
1061 | 1053 | ||
1062 | changeSelectedStatus(timestep); | 1054 | changeSelectedStatus(timestep); |
1063 | 1055 | ||
@@ -1067,10 +1059,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1067 | 1059 | ||
1068 | public void rotate(float timestep) | 1060 | public void rotate(float timestep) |
1069 | { | 1061 | { |
1070 | while (ode.lockquery()) | 1062 | |
1071 | { | ||
1072 | } | ||
1073 | ode.dlock(_parent_scene.world); | ||
1074 | 1063 | ||
1075 | d.Quaternion myrot = new d.Quaternion(); | 1064 | d.Quaternion myrot = new d.Quaternion(); |
1076 | myrot.W = _orientation.w; | 1065 | myrot.W = _orientation.w; |
@@ -1082,8 +1071,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1082 | { | 1071 | { |
1083 | d.BodySetQuaternion(Body, ref myrot); | 1072 | d.BodySetQuaternion(Body, ref myrot); |
1084 | } | 1073 | } |
1085 | |||
1086 | ode.dunlock(_parent_scene.world); | ||
1087 | 1074 | ||
1088 | resetCollisionAccounting(); | 1075 | resetCollisionAccounting(); |
1089 | m_taintrot = _orientation; | 1076 | m_taintrot = _orientation; |
@@ -1098,46 +1085,35 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1098 | 1085 | ||
1099 | public void changedisable(float timestep) | 1086 | public void changedisable(float timestep) |
1100 | { | 1087 | { |
1101 | while (ode.lockquery()) | 1088 | |
1102 | { | ||
1103 | } | ||
1104 | ode.dlock(_parent_scene.world); | ||
1105 | m_disabled = true; | 1089 | m_disabled = true; |
1106 | if (Body != (IntPtr)0) | 1090 | if (Body != (IntPtr)0) |
1107 | { | 1091 | { |
1108 | d.BodyDisable(Body); | 1092 | d.BodyDisable(Body); |
1109 | Body = (IntPtr)0; | 1093 | Body = (IntPtr)0; |
1110 | } | 1094 | } |
1111 | ode.dunlock(_parent_scene.world); | 1095 | |
1112 | 1096 | ||
1113 | m_taintdisable = false; | 1097 | m_taintdisable = false; |
1114 | } | 1098 | } |
1115 | 1099 | ||
1116 | public void changePhysicsStatus(float timestep) | 1100 | public void changePhysicsStatus(float timestep) |
1117 | { | 1101 | { |
1118 | lock (ode) | 1102 | |
1119 | { | ||
1120 | while (ode.lockquery()) | ||
1121 | { | ||
1122 | } | ||
1123 | ode.dlock(_parent_scene.world); | ||
1124 | 1103 | ||
1125 | if (m_isphysical == true) | 1104 | if (m_isphysical == true) |
1105 | { | ||
1106 | if (Body == (IntPtr)0) | ||
1126 | { | 1107 | { |
1127 | if (Body == (IntPtr)0) | 1108 | enableBody(); |
1128 | { | ||
1129 | enableBody(); | ||
1130 | } | ||
1131 | } | 1109 | } |
1132 | else | 1110 | } |
1111 | else | ||
1112 | { | ||
1113 | if (Body != (IntPtr)0) | ||
1133 | { | 1114 | { |
1134 | if (Body != (IntPtr)0) | 1115 | disableBody(); |
1135 | { | ||
1136 | disableBody(); | ||
1137 | } | ||
1138 | } | 1116 | } |
1139 | |||
1140 | ode.dunlock(_parent_scene.world); | ||
1141 | } | 1117 | } |
1142 | 1118 | ||
1143 | changeSelectedStatus(timestep); | 1119 | changeSelectedStatus(timestep); |
@@ -1148,10 +1124,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1148 | 1124 | ||
1149 | public void changesize(float timestamp) | 1125 | public void changesize(float timestamp) |
1150 | { | 1126 | { |
1151 | while (ode.lockquery()) | 1127 | |
1152 | { | ||
1153 | } | ||
1154 | ode.dlock(_parent_scene.world); | ||
1155 | //if (!_parent_scene.geom_name_map.ContainsKey(prim_geom)) | 1128 | //if (!_parent_scene.geom_name_map.ContainsKey(prim_geom)) |
1156 | //{ | 1129 | //{ |
1157 | // m_taintsize = _size; | 1130 | // m_taintsize = _size; |
@@ -1311,8 +1284,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1311 | 1284 | ||
1312 | _parent_scene.geom_name_map[prim_geom] = oldname; | 1285 | _parent_scene.geom_name_map[prim_geom] = oldname; |
1313 | 1286 | ||
1314 | ode.dunlock(_parent_scene.world); | ||
1315 | |||
1316 | changeSelectedStatus(timestamp); | 1287 | changeSelectedStatus(timestamp); |
1317 | 1288 | ||
1318 | resetCollisionAccounting(); | 1289 | resetCollisionAccounting(); |
@@ -1321,12 +1292,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1321 | 1292 | ||
1322 | public void changeshape(float timestamp) | 1293 | public void changeshape(float timestamp) |
1323 | { | 1294 | { |
1324 | while (ode.lockquery()) | 1295 | |
1325 | { | ||
1326 | } | ||
1327 | ode.dlock(_parent_scene.world); | ||
1328 | |||
1329 | |||
1330 | string oldname = _parent_scene.geom_name_map[prim_geom]; | 1296 | string oldname = _parent_scene.geom_name_map[prim_geom]; |
1331 | 1297 | ||
1332 | // Cleanup of old prim geometry and Bodies | 1298 | // Cleanup of old prim geometry and Bodies |
@@ -1471,8 +1437,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1471 | 1437 | ||
1472 | _parent_scene.geom_name_map[prim_geom] = oldname; | 1438 | _parent_scene.geom_name_map[prim_geom] = oldname; |
1473 | 1439 | ||
1474 | ode.dunlock(_parent_scene.world); | ||
1475 | |||
1476 | changeSelectedStatus(timestamp); | 1440 | changeSelectedStatus(timestamp); |
1477 | 1441 | ||
1478 | resetCollisionAccounting(); | 1442 | resetCollisionAccounting(); |
@@ -1483,10 +1447,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1483 | { | 1447 | { |
1484 | if (!m_isSelected) | 1448 | if (!m_isSelected) |
1485 | { | 1449 | { |
1486 | while (ode.lockquery()) | 1450 | |
1487 | { | ||
1488 | } | ||
1489 | ode.dlock(_parent_scene.world); | ||
1490 | 1451 | ||
1491 | 1452 | ||
1492 | lock (m_forcelist) | 1453 | lock (m_forcelist) |
@@ -1505,7 +1466,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1505 | m_forcelist.Clear(); | 1466 | m_forcelist.Clear(); |
1506 | } | 1467 | } |
1507 | 1468 | ||
1508 | ode.dunlock(_parent_scene.world); | ||
1509 | 1469 | ||
1510 | m_collisionscore = 0; | 1470 | m_collisionscore = 0; |
1511 | m_interpenetrationcount = 0; | 1471 | m_interpenetrationcount = 0; |
@@ -1517,24 +1477,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1517 | { | 1477 | { |
1518 | if (!m_isSelected) | 1478 | if (!m_isSelected) |
1519 | { | 1479 | { |
1520 | lock (ode) | 1480 | |
1521 | { | ||
1522 | while (ode.lockquery()) | ||
1523 | { | ||
1524 | } | ||
1525 | ode.dlock(_parent_scene.world); | ||
1526 | 1481 | ||
1527 | System.Threading.Thread.Sleep(20); | 1482 | System.Threading.Thread.Sleep(20); |
1528 | if (IsPhysical) | 1483 | if (IsPhysical) |
1484 | { | ||
1485 | if (Body != (IntPtr)0) | ||
1529 | { | 1486 | { |
1530 | if (Body != (IntPtr)0) | 1487 | d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); |
1531 | { | ||
1532 | d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); | ||
1533 | } | ||
1534 | } | 1488 | } |
1535 | 1489 | } | |
1536 | ode.dunlock(_parent_scene.world); | 1490 | |
1537 | } | ||
1538 | //resetCollisionAccounting(); | 1491 | //resetCollisionAccounting(); |
1539 | } | 1492 | } |
1540 | m_taintVelocity = PhysicsVector.Zero; | 1493 | m_taintVelocity = PhysicsVector.Zero; |
@@ -1763,12 +1716,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1763 | if (l_position.X > 255.95f || l_position.X < 0f || l_position.Y > 255.95f || l_position.Y < 0f) | 1716 | if (l_position.X > 255.95f || l_position.X < 0f || l_position.Y > 255.95f || l_position.Y < 0f) |
1764 | { | 1717 | { |
1765 | base.RaiseOutOfBounds(_position); | 1718 | base.RaiseOutOfBounds(_position); |
1719 | |||
1720 | //if (m_crossingfailures < 5) | ||
1721 | //{ | ||
1722 | //base.RequestPhysicsterseUpdate(); | ||
1723 | //} | ||
1724 | //else | ||
1725 | //{ | ||
1726 | //base.RaiseOutOfBounds(_position); | ||
1727 | //} | ||
1766 | } | 1728 | } |
1767 | //if (m_crossingfailures < 5) | ||
1768 | //{ | ||
1769 | //base.RequestPhysicsterseUpdate(); | ||
1770 | //} | ||
1771 | //} | ||
1772 | 1729 | ||
1773 | if (l_position.Z < 0) | 1730 | if (l_position.Z < 0) |
1774 | { | 1731 | { |
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 266cb3d..5b1fd78 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | |||
@@ -229,14 +229,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
229 | } | 229 | } |
230 | } | 230 | } |
231 | 231 | ||
232 | public void starttiming() | 232 | |
233 | { | ||
234 | ms = Environment.TickCount; | ||
235 | } | ||
236 | public int stoptiming() | ||
237 | { | ||
238 | return Environment.TickCount - ms; | ||
239 | } | ||
240 | // Initialize the mesh plugin | 233 | // Initialize the mesh plugin |
241 | public override void Initialise(IMesher meshmerizer) | 234 | public override void Initialise(IMesher meshmerizer) |
242 | { | 235 | { |
@@ -245,15 +238,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
245 | 238 | ||
246 | internal void waitForSpaceUnlock(IntPtr space) | 239 | internal void waitForSpaceUnlock(IntPtr space) |
247 | { | 240 | { |
248 | 241 | while (d.SpaceLockQuery(space)){ } // Wait and do nothing | |
249 | while (d.SpaceLockQuery(space)) | ||
250 | { | ||
251 | |||
252 | } | ||
253 | |||
254 | |||
255 | |||
256 | } | 242 | } |
243 | |||
257 | /// <summary> | 244 | /// <summary> |
258 | /// Debug space message for printing the space that a prim/avatar is in. | 245 | /// Debug space message for printing the space that a prim/avatar is in. |
259 | /// </summary> | 246 | /// </summary> |
@@ -264,6 +251,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
264 | return calculateSpaceForGeom(pos).ToString(); | 251 | return calculateSpaceForGeom(pos).ToString(); |
265 | } | 252 | } |
266 | 253 | ||
254 | #region Collision Detection | ||
255 | |||
267 | /// <summary> | 256 | /// <summary> |
268 | /// This is our near callback. A geometry is near a body | 257 | /// This is our near callback. A geometry is near a body |
269 | /// </summary> | 258 | /// </summary> |
@@ -299,314 +288,359 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
299 | //Collide all geoms in each space.. | 288 | //Collide all geoms in each space.. |
300 | //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); | 289 | //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); |
301 | //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); | 290 | //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); |
291 | return; | ||
302 | } | 292 | } |
303 | else | 293 | |
304 | { | 294 | |
305 | // Colliding Geom To Geom | 295 | // Colliding Geom To Geom |
306 | // This portion of the function 'was' blatantly ripped off from BoxStack.cs | 296 | // This portion of the function 'was' blatantly ripped off from BoxStack.cs |
307 | if (g1 == (IntPtr)0 || g2 == (IntPtr)0) | 297 | if (g1 == (IntPtr)0 || g2 == (IntPtr)0) |
308 | return; | 298 | return; |
309 | 299 | ||
310 | IntPtr b1 = d.GeomGetBody(g1); | 300 | IntPtr b1 = d.GeomGetBody(g1); |
311 | IntPtr b2 = d.GeomGetBody(g2); | 301 | IntPtr b2 = d.GeomGetBody(g2); |
312 | 302 | ||
313 | if (g1 == g2) | 303 | if (g1 == g2) |
314 | return; // Can't collide with yourself | 304 | return; // Can't collide with yourself |
315 | 305 | ||
316 | if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) | 306 | if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) |
317 | return; | 307 | return; |
308 | |||
309 | |||
310 | |||
311 | d.GeomClassID id = d.GeomGetClass(g1); | ||
312 | |||
313 | String name1 = null; | ||
314 | String name2 = null; | ||
318 | 315 | ||
316 | if (!geom_name_map.TryGetValue(g1, out name1)) | ||
317 | { | ||
318 | name1 = "null"; | ||
319 | } | ||
320 | if (!geom_name_map.TryGetValue(g2, out name2)) | ||
321 | { | ||
322 | name2 = "null"; | ||
323 | } | ||
324 | |||
325 | //if (id == d.GeomClassId.TriMeshClass) | ||
326 | //{ | ||
327 | // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2); | ||
328 | //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2); | ||
329 | //} | ||
330 | |||
331 | // Figure out how many contact points we have | ||
332 | int count = 0; | ||
333 | try | ||
334 | { | ||
335 | //m_log.Warn(g1.ToString() + "|" + g2.ToString()); | ||
336 | count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf); | ||
337 | } | ||
338 | catch (SEHException) | ||
339 | { | ||
340 | m_log.Error("[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."); | ||
341 | ode.drelease(world); | ||
342 | base.TriggerPhysicsBasedRestart(); | ||
343 | } | ||
344 | catch (System.AccessViolationException) | ||
345 | { | ||
319 | 346 | ||
347 | m_log.Warn("[PHYSICS]: Unable to collide test an object"); | ||
348 | return; | ||
349 | } | ||
320 | 350 | ||
321 | d.GeomClassID id = d.GeomGetClass(g1); | 351 | PhysicsActor p1; |
352 | PhysicsActor p2; | ||
322 | 353 | ||
323 | String name1 = null; | 354 | for (int i = 0; i < count; i++) |
324 | String name2 = null; | 355 | { |
356 | //m_log.Warn("[CCOUNT]: " + count); | ||
357 | IntPtr joint; | ||
358 | // If we're colliding with terrain, use 'TerrainContact' instead of contact. | ||
359 | // allows us to have different settings | ||
325 | 360 | ||
326 | if (!geom_name_map.TryGetValue(g1, out name1)) | 361 | if (!actor_name_map.TryGetValue(g1, out p1)) |
327 | { | 362 | { |
328 | name1 = "null"; | 363 | p1 = PANull; |
329 | } | 364 | } |
330 | if (!geom_name_map.TryGetValue(g2, out name2)) | 365 | if (!actor_name_map.TryGetValue(g2, out p2)) |
331 | { | 366 | { |
332 | name2 = "null"; | 367 | p2 = PANull; |
333 | } | 368 | } |
334 | 369 | ||
335 | //if (id == d.GeomClassId.TriMeshClass) | 370 | // We only need to test p2 for 'jump crouch purposes' |
336 | //{ | 371 | p2.IsColliding = true; |
337 | // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2); | ||
338 | //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2); | ||
339 | //} | ||
340 | 372 | ||
341 | // Figure out how many contact points we have | 373 | switch (p1.PhysicsActorType) |
342 | int count = 0; | ||
343 | try | ||
344 | { | 374 | { |
345 | //m_log.Warn(g1.ToString() + "|" + g2.ToString()); | 375 | case (int)ActorTypes.Agent: |
346 | count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf); | 376 | p2.CollidingObj = true; |
347 | } | 377 | break; |
348 | catch (SEHException) | 378 | case (int)ActorTypes.Prim: |
349 | { | 379 | if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0) |
350 | m_log.Error("[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."); | 380 | p2.CollidingObj = true; |
351 | ode.drelease(world); | 381 | break; |
352 | base.TriggerPhysicsBasedRestart(); | 382 | case (int)ActorTypes.Unknown: |
353 | } | 383 | p2.CollidingGround = true; |
354 | catch (System.AccessViolationException) | 384 | break; |
355 | { | 385 | default: |
356 | 386 | p2.CollidingGround = true; | |
357 | m_log.Warn("[PHYSICS]: Unable to collide test an object"); | 387 | break; |
358 | return; | ||
359 | } | 388 | } |
360 | 389 | ||
361 | PhysicsActor p1; | 390 | // we don't want prim or avatar to explode |
362 | PhysicsActor p2; | ||
363 | 391 | ||
364 | for (int i = 0; i < count; i++) | 392 | #region InterPenetration Handling - Unintended physics explosions |
365 | { | ||
366 | //m_log.Warn("[CCOUNT]: " + count); | ||
367 | IntPtr joint; | ||
368 | // If we're colliding with terrain, use 'TerrainContact' instead of contact. | ||
369 | // allows us to have different settings | ||
370 | 393 | ||
371 | if (!actor_name_map.TryGetValue(g1, out p1)) | 394 | if (contacts[i].depth >= 0.08f) |
395 | { | ||
396 | //This is disabled at the moment only because it needs more tweaking | ||
397 | //It will eventually be uncommented | ||
398 | |||
399 | if (contacts[i].depth >= 1.00f) | ||
372 | { | 400 | { |
373 | p1 = PANull; | 401 | //m_log.Debug("[PHYSICS]: " + contacts[i].depth.ToString()); |
374 | } | 402 | } |
375 | if (!actor_name_map.TryGetValue(g2, out p2)) | 403 | |
404 | //If you interpenetrate a prim with an agent | ||
405 | if ((p2.PhysicsActorType == (int) ActorTypes.Agent && | ||
406 | p1.PhysicsActorType == (int) ActorTypes.Prim) || | ||
407 | (p1.PhysicsActorType == (int) ActorTypes.Agent && | ||
408 | p2.PhysicsActorType == (int) ActorTypes.Prim)) | ||
376 | { | 409 | { |
377 | p2 = PANull; | 410 | # region disabled code1 |
411 | //contacts[i].depth = contacts[i].depth * 4.15f; | ||
412 | /* | ||
413 | if (p2.PhysicsActorType == (int) ActorTypes.Agent) | ||
414 | { | ||
415 | p2.CollidingObj = true; | ||
416 | contacts[i].depth = 0.003f; | ||
417 | p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f); | ||
418 | OdeCharacter character = (OdeCharacter) p2; | ||
419 | character.SetPidStatus(true); | ||
420 | contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), contacts[i].pos.Y + (p1.Size.Y / 2), contacts[i].pos.Z + (p1.Size.Z / 2)); | ||
421 | |||
422 | } | ||
423 | else | ||
424 | { | ||
425 | |||
426 | //contacts[i].depth = 0.0000000f; | ||
427 | } | ||
428 | if (p1.PhysicsActorType == (int) ActorTypes.Agent) | ||
429 | { | ||
430 | |||
431 | p1.CollidingObj = true; | ||
432 | contacts[i].depth = 0.003f; | ||
433 | p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f); | ||
434 | contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p2.Size.X / 2), contacts[i].pos.Y + (p2.Size.Y / 2), contacts[i].pos.Z + (p2.Size.Z / 2)); | ||
435 | OdeCharacter character = (OdeCharacter)p1; | ||
436 | character.SetPidStatus(true); | ||
437 | } | ||
438 | else | ||
439 | { | ||
440 | |||
441 | //contacts[i].depth = 0.0000000f; | ||
442 | } | ||
443 | */ | ||
444 | #endregion | ||
378 | } | 445 | } |
446 | |||
379 | 447 | ||
380 | // We only need to test p2 for 'jump crouch purposes' | 448 | // If you interpenetrate a prim with another prim |
381 | p2.IsColliding = true; | 449 | if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim) |
382 | |||
383 | switch (p1.PhysicsActorType) | ||
384 | { | 450 | { |
385 | case (int)ActorTypes.Agent: | 451 | #region disabledcode2 |
386 | p2.CollidingObj = true; | 452 | //OdePrim op1 = (OdePrim)p1; |
387 | break; | 453 | //OdePrim op2 = (OdePrim)p2; |
388 | case (int)ActorTypes.Prim: | 454 | //op1.m_collisionscore++; |
389 | if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0) | 455 | //op2.m_collisionscore++; |
390 | p2.CollidingObj = true; | 456 | |
391 | break; | ||
392 | case (int)ActorTypes.Unknown: | ||
393 | p2.CollidingGround = true; | ||
394 | break; | ||
395 | default: | ||
396 | p2.CollidingGround = true; | ||
397 | break; | ||
398 | } | ||
399 | 457 | ||
400 | // we don't want prim or avatar to explode | 458 | //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000) |
459 | //{ | ||
460 | //op1.m_taintdisable = true; | ||
461 | //AddPhysicsActorTaint(p1); | ||
462 | //op2.m_taintdisable = true; | ||
463 | //AddPhysicsActorTaint(p2); | ||
464 | //} | ||
465 | |||
466 | //if (contacts[i].depth >= 0.25f) | ||
467 | //{ | ||
468 | // Don't collide, one or both prim will expld. | ||
469 | |||
401 | 470 | ||
402 | #region InterPenetration Handling - Unintended physics explosions | 471 | //op1.m_interpenetrationcount++; |
472 | //op2.m_interpenetrationcount++; | ||
473 | //interpenetrations_before_disable = 200; | ||
474 | //if (op1.m_interpenetrationcount >= interpenetrations_before_disable) | ||
475 | //{ | ||
476 | //op1.m_taintdisable = true; | ||
477 | //AddPhysicsActorTaint(p1); | ||
478 | //} | ||
479 | //if (op2.m_interpenetrationcount >= interpenetrations_before_disable) | ||
480 | //{ | ||
481 | // op2.m_taintdisable = true; | ||
482 | //AddPhysicsActorTaint(p2); | ||
483 | //} | ||
403 | 484 | ||
404 | if (contacts[i].depth >= 0.08f) | 485 | |
486 | //contacts[i].depth = contacts[i].depth / 8f; | ||
487 | //contacts[i].normal = new d.Vector3(0, 0, 1); | ||
488 | //} | ||
489 | //if (op1.m_disabled || op2.m_disabled) | ||
490 | //{ | ||
491 | //Manually disabled objects stay disabled | ||
492 | //contacts[i].depth = 0f; | ||
493 | //} | ||
494 | #endregion | ||
495 | } | ||
496 | if (contacts[i].depth >= 1.00f) | ||
405 | { | 497 | { |
406 | //This is disabled at the moment only because it needs more tweaking | 498 | //m_log.Info("[P]: " + contacts[i].depth.ToString()); |
407 | //It will eventually be uncommented | ||
408 | |||
409 | if (contacts[i].depth >= 1.00f) | ||
410 | { | ||
411 | //m_log.Debug("[PHYSICS]: " + contacts[i].depth.ToString()); | ||
412 | } | ||
413 | |||
414 | //If you interpenetrate a prim with an agent | ||
415 | if ((p2.PhysicsActorType == (int) ActorTypes.Agent && | 499 | if ((p2.PhysicsActorType == (int) ActorTypes.Agent && |
416 | p1.PhysicsActorType == (int) ActorTypes.Prim) || | 500 | p1.PhysicsActorType == (int) ActorTypes.Unknown) || |
417 | (p1.PhysicsActorType == (int) ActorTypes.Agent && | 501 | (p1.PhysicsActorType == (int) ActorTypes.Agent && |
418 | p2.PhysicsActorType == (int) ActorTypes.Prim)) | 502 | p2.PhysicsActorType == (int) ActorTypes.Unknown)) |
419 | { | 503 | { |
420 | //contacts[i].depth = contacts[i].depth * 4.15f; | ||
421 | /* | ||
422 | if (p2.PhysicsActorType == (int) ActorTypes.Agent) | 504 | if (p2.PhysicsActorType == (int) ActorTypes.Agent) |
423 | { | 505 | { |
424 | p2.CollidingObj = true; | ||
425 | contacts[i].depth = 0.003f; | ||
426 | p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f); | ||
427 | OdeCharacter character = (OdeCharacter) p2; | 506 | OdeCharacter character = (OdeCharacter) p2; |
507 | |||
508 | //p2.CollidingObj = true; | ||
509 | contacts[i].depth = 0.00000003f; | ||
510 | p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 0.5f); | ||
511 | contacts[i].pos = | ||
512 | new d.Vector3(contacts[i].pos.X + (p1.Size.X/2), | ||
513 | contacts[i].pos.Y + (p1.Size.Y/2), | ||
514 | contacts[i].pos.Z + (p1.Size.Z/2)); | ||
428 | character.SetPidStatus(true); | 515 | character.SetPidStatus(true); |
429 | contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), contacts[i].pos.Y + (p1.Size.Y / 2), contacts[i].pos.Z + (p1.Size.Z / 2)); | ||
430 | |||
431 | } | 516 | } |
432 | else | 517 | else |
433 | { | 518 | { |
434 | |||
435 | //contacts[i].depth = 0.0000000f; | ||
436 | } | 519 | } |
437 | if (p1.PhysicsActorType == (int) ActorTypes.Agent) | 520 | if (p1.PhysicsActorType == (int) ActorTypes.Agent) |
438 | { | 521 | { |
439 | |||
440 | p1.CollidingObj = true; | ||
441 | contacts[i].depth = 0.003f; | ||
442 | p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f); | ||
443 | contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p2.Size.X / 2), contacts[i].pos.Y + (p2.Size.Y / 2), contacts[i].pos.Z + (p2.Size.Z / 2)); | ||
444 | OdeCharacter character = (OdeCharacter)p1; | 522 | OdeCharacter character = (OdeCharacter)p1; |
523 | |||
524 | //p2.CollidingObj = true; | ||
525 | contacts[i].depth = 0.00000003f; | ||
526 | p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 0.5f); | ||
527 | contacts[i].pos = | ||
528 | new d.Vector3(contacts[i].pos.X + (p1.Size.X/2), | ||
529 | contacts[i].pos.Y + (p1.Size.Y/2), | ||
530 | contacts[i].pos.Z + (p1.Size.Z/2)); | ||
445 | character.SetPidStatus(true); | 531 | character.SetPidStatus(true); |
446 | } | 532 | } |
447 | else | 533 | else |
448 | { | 534 | { |
449 | |||
450 | //contacts[i].depth = 0.0000000f; | 535 | //contacts[i].depth = 0.0000000f; |
451 | } | 536 | } |
452 | */ | ||
453 | } | 537 | } |
454 | 538 | } | |
539 | } | ||
455 | 540 | ||
456 | // If you interpenetrate a prim with another prim | 541 | #endregion |
457 | if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim) | ||
458 | { | ||
459 | //OdePrim op1 = (OdePrim)p1; | ||
460 | //OdePrim op2 = (OdePrim)p2; | ||
461 | //op1.m_collisionscore++; | ||
462 | //op2.m_collisionscore++; | ||
463 | |||
464 | 542 | ||
465 | //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000) | 543 | if (contacts[i].depth >= 0f) |
466 | //{ | 544 | { |
467 | //op1.m_taintdisable = true; | 545 | // If we're collidng against terrain |
468 | //AddPhysicsActorTaint(p1); | 546 | if (name1 == "Terrain" || name2 == "Terrain") |
469 | //op2.m_taintdisable = true; | 547 | { |
470 | //AddPhysicsActorTaint(p2); | 548 | // If we're moving |
471 | //} | 549 | if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && |
472 | 550 | (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) | |
473 | //if (contacts[i].depth >= 0.25f) | 551 | { |
474 | //{ | 552 | // Use the movement terrain contact |
475 | // Don't collide, one or both prim will expld. | 553 | AvatarMovementTerrainContact.geom = contacts[i]; |
476 | 554 | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); | |
477 | |||
478 | //op1.m_interpenetrationcount++; | ||
479 | //op2.m_interpenetrationcount++; | ||
480 | //interpenetrations_before_disable = 200; | ||
481 | //if (op1.m_interpenetrationcount >= interpenetrations_before_disable) | ||
482 | //{ | ||
483 | //op1.m_taintdisable = true; | ||
484 | //AddPhysicsActorTaint(p1); | ||
485 | //} | ||
486 | //if (op2.m_interpenetrationcount >= interpenetrations_before_disable) | ||
487 | //{ | ||
488 | // op2.m_taintdisable = true; | ||
489 | //AddPhysicsActorTaint(p2); | ||
490 | //} | ||
491 | |||
492 | |||
493 | //contacts[i].depth = contacts[i].depth / 8f; | ||
494 | //contacts[i].normal = new d.Vector3(0, 0, 1); | ||
495 | //} | ||
496 | //if (op1.m_disabled || op2.m_disabled) | ||
497 | //{ | ||
498 | //Manually disabled objects stay disabled | ||
499 | //contacts[i].depth = 0f; | ||
500 | //} | ||
501 | } | 555 | } |
502 | if (contacts[i].depth >= 1.00f) | 556 | else |
503 | { | 557 | { |
504 | //m_log.Info("[P]: " + contacts[i].depth.ToString()); | 558 | // Use the non moving terrain contact |
505 | if ((p2.PhysicsActorType == (int) ActorTypes.Agent && | 559 | TerrainContact.geom = contacts[i]; |
506 | p1.PhysicsActorType == (int) ActorTypes.Unknown) || | 560 | joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); |
507 | (p1.PhysicsActorType == (int) ActorTypes.Agent && | ||
508 | p2.PhysicsActorType == (int) ActorTypes.Unknown)) | ||
509 | { | ||
510 | if (p2.PhysicsActorType == (int) ActorTypes.Agent) | ||
511 | { | ||
512 | OdeCharacter character = (OdeCharacter) p2; | ||
513 | |||
514 | //p2.CollidingObj = true; | ||
515 | contacts[i].depth = 0.00000003f; | ||
516 | p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 0.5f); | ||
517 | contacts[i].pos = | ||
518 | new d.Vector3(contacts[i].pos.X + (p1.Size.X/2), | ||
519 | contacts[i].pos.Y + (p1.Size.Y/2), | ||
520 | contacts[i].pos.Z + (p1.Size.Z/2)); | ||
521 | character.SetPidStatus(true); | ||
522 | } | ||
523 | else | ||
524 | { | ||
525 | } | ||
526 | if (p1.PhysicsActorType == (int) ActorTypes.Agent) | ||
527 | { | ||
528 | OdeCharacter character = (OdeCharacter)p1; | ||
529 | |||
530 | //p2.CollidingObj = true; | ||
531 | contacts[i].depth = 0.00000003f; | ||
532 | p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 0.5f); | ||
533 | contacts[i].pos = | ||
534 | new d.Vector3(contacts[i].pos.X + (p1.Size.X/2), | ||
535 | contacts[i].pos.Y + (p1.Size.Y/2), | ||
536 | contacts[i].pos.Z + (p1.Size.Z/2)); | ||
537 | character.SetPidStatus(true); | ||
538 | } | ||
539 | else | ||
540 | { | ||
541 | //contacts[i].depth = 0.0000000f; | ||
542 | } | ||
543 | } | ||
544 | } | 561 | } |
545 | } | 562 | } |
546 | 563 | else | |
547 | #endregion | ||
548 | |||
549 | if (contacts[i].depth >= 0f) | ||
550 | { | 564 | { |
551 | // If we're collidng against terrain | 565 | // we're colliding with prim or avatar |
552 | if (name1 == "Terrain" || name2 == "Terrain") | 566 | |
567 | // check if we're moving | ||
568 | if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && | ||
569 | (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) | ||
553 | { | 570 | { |
554 | // If we're moving | 571 | // Use the Movement prim contact |
555 | if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && | 572 | AvatarMovementprimContact.geom = contacts[i]; |
556 | (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) | 573 | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); |
557 | { | ||
558 | // Use the movement terrain contact | ||
559 | AvatarMovementTerrainContact.geom = contacts[i]; | ||
560 | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); | ||
561 | } | ||
562 | else | ||
563 | { | ||
564 | // Use the non moving terrain contact | ||
565 | TerrainContact.geom = contacts[i]; | ||
566 | joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); | ||
567 | } | ||
568 | } | 574 | } |
569 | else | 575 | else |
570 | { | 576 | { |
571 | // we're colliding with prim or avatar | 577 | // Use the non movement contact |
572 | 578 | contact.geom = contacts[i]; | |
573 | // check if we're moving | 579 | joint = d.JointCreateContact(world, contactgroup, ref contact); |
574 | if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && | ||
575 | (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) | ||
576 | { | ||
577 | // Use the Movement prim contact | ||
578 | AvatarMovementprimContact.geom = contacts[i]; | ||
579 | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | // Use the non movement contact | ||
584 | contact.geom = contacts[i]; | ||
585 | joint = d.JointCreateContact(world, contactgroup, ref contact); | ||
586 | } | ||
587 | } | 580 | } |
588 | d.JointAttach(joint, b1, b2); | ||
589 | } | 581 | } |
582 | d.JointAttach(joint, b1, b2); | ||
583 | } | ||
590 | 584 | ||
591 | if (count > 3) | 585 | if (count > 3) |
592 | { | 586 | { |
593 | // If there are more then 3 contact points, it's likely | 587 | // If there are more then 3 contact points, it's likely |
594 | // that we've got a pile of objects | 588 | // that we've got a pile of objects |
595 | // | 589 | // |
596 | // We don't want to send out hundreds of terse updates over and over again | 590 | // We don't want to send out hundreds of terse updates over and over again |
597 | // so lets throttle them and send them again after it's somewhat sorted out. | 591 | // so lets throttle them and send them again after it's somewhat sorted out. |
598 | p2.ThrottleUpdates = true; | 592 | p2.ThrottleUpdates = true; |
599 | } | ||
600 | //System.Console.WriteLine(count.ToString()); | ||
601 | //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2); | ||
602 | } | 593 | } |
594 | //System.Console.WriteLine(count.ToString()); | ||
595 | //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2); | ||
603 | } | 596 | } |
597 | |||
604 | } | 598 | } |
605 | private float GetTerrainHeightAtXY(float x, float y) | 599 | |
600 | public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount) | ||
606 | { | 601 | { |
607 | return (float)_origheightmap[(int)y * Constants.RegionSize + (int)x]; | 602 | /* String name1 = null; |
608 | 603 | String name2 = null; | |
609 | 604 | ||
605 | if (!geom_name_map.TryGetValue(trimesh, out name1)) | ||
606 | { | ||
607 | name1 = "null"; | ||
608 | } | ||
609 | if (!geom_name_map.TryGetValue(refObject, out name2)) | ||
610 | { | ||
611 | name2 = "null"; | ||
612 | } | ||
613 | |||
614 | m_log.InfoFormat("TriArrayCallback: A collision was detected between {1} and {2}", 0, name1, name2); | ||
615 | */ | ||
616 | return 1; | ||
617 | } | ||
618 | |||
619 | public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) | ||
620 | { | ||
621 | String name1 = null; | ||
622 | String name2 = null; | ||
623 | |||
624 | if (!geom_name_map.TryGetValue(trimesh, out name1)) | ||
625 | { | ||
626 | name1 = "null"; | ||
627 | } | ||
628 | |||
629 | if (!geom_name_map.TryGetValue(refObject, out name2)) | ||
630 | { | ||
631 | name2 = "null"; | ||
632 | } | ||
633 | |||
634 | // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex); | ||
635 | |||
636 | d.Vector3 v0 = new d.Vector3(); | ||
637 | d.Vector3 v1 = new d.Vector3(); | ||
638 | d.Vector3 v2 = new d.Vector3(); | ||
639 | |||
640 | d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2); | ||
641 | // m_log.DebugFormat("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z); | ||
642 | |||
643 | return 1; | ||
610 | } | 644 | } |
611 | 645 | ||
612 | /// <summary> | 646 | /// <summary> |
@@ -715,6 +749,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
715 | } | 749 | } |
716 | } | 750 | } |
717 | 751 | ||
752 | #endregion | ||
753 | |||
754 | private float GetTerrainHeightAtXY(float x, float y) | ||
755 | { | ||
756 | return (float)_origheightmap[(int)y * Constants.RegionSize + (int)x]; | ||
757 | |||
758 | |||
759 | } | ||
760 | |||
761 | #region Add/Remove Entities | ||
762 | |||
718 | public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size) | 763 | public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size) |
719 | { | 764 | { |
720 | PhysicsVector pos = new PhysicsVector(); | 765 | PhysicsVector pos = new PhysicsVector(); |
@@ -735,6 +780,80 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
735 | } | 780 | } |
736 | } | 781 | } |
737 | 782 | ||
783 | private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation, | ||
784 | IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) | ||
785 | { | ||
786 | PhysicsVector pos = new PhysicsVector(); | ||
787 | pos.X = position.X; | ||
788 | pos.Y = position.Y; | ||
789 | pos.Z = position.Z; | ||
790 | PhysicsVector siz = new PhysicsVector(); | ||
791 | siz.X = size.X; | ||
792 | siz.Y = size.Y; | ||
793 | siz.Z = size.Z; | ||
794 | Quaternion rot = new Quaternion(); | ||
795 | rot.w = rotation.w; | ||
796 | rot.x = rotation.x; | ||
797 | rot.y = rotation.y; | ||
798 | rot.z = rotation.z; | ||
799 | |||
800 | |||
801 | |||
802 | OdePrim newPrim; | ||
803 | lock (OdeLock) | ||
804 | { | ||
805 | newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); | ||
806 | |||
807 | _prims.Add(newPrim); | ||
808 | } | ||
809 | |||
810 | |||
811 | return newPrim; | ||
812 | } | ||
813 | |||
814 | public void addActivePrim(OdePrim activatePrim) | ||
815 | { | ||
816 | // adds active prim.. (ones that should be iterated over in collisions_optimized | ||
817 | |||
818 | _activeprims.Add(activatePrim); | ||
819 | } | ||
820 | |||
821 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, | ||
822 | PhysicsVector size, Quaternion rotation) //To be removed | ||
823 | { | ||
824 | return AddPrimShape(primName, pbs, position, size, rotation, false); | ||
825 | } | ||
826 | |||
827 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, | ||
828 | PhysicsVector size, Quaternion rotation, bool isPhysical) | ||
829 | { | ||
830 | PhysicsActor result; | ||
831 | IMesh mesh = null; | ||
832 | |||
833 | switch (pbs.ProfileShape) | ||
834 | { | ||
835 | case ProfileShape.Square: | ||
836 | /// support simple box & hollow box now; later, more shapes | ||
837 | if (needsMeshing(pbs)) | ||
838 | { | ||
839 | mesh = mesher.CreateMesh(primName, pbs, size); | ||
840 | } | ||
841 | |||
842 | break; | ||
843 | } | ||
844 | |||
845 | result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical); | ||
846 | |||
847 | |||
848 | return result; | ||
849 | } | ||
850 | |||
851 | |||
852 | public void remActivePrim(OdePrim deactivatePrim) | ||
853 | { | ||
854 | _activeprims.Remove(deactivatePrim); | ||
855 | } | ||
856 | |||
738 | public override void RemovePrim(PhysicsActor prim) | 857 | public override void RemovePrim(PhysicsActor prim) |
739 | { | 858 | { |
740 | if (prim is OdePrim) | 859 | if (prim is OdePrim) |
@@ -767,10 +886,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
767 | { | 886 | { |
768 | if (prim.prim_geom != (IntPtr)0) | 887 | if (prim.prim_geom != (IntPtr)0) |
769 | { | 888 | { |
770 | while (ode.lockquery()) | 889 | |
771 | { | 890 | |
772 | } | ||
773 | ode.dlock(world); | ||
774 | //System.Threading.Thread.Sleep(20); | 891 | //System.Threading.Thread.Sleep(20); |
775 | prim.ResetTaints(); | 892 | prim.ResetTaints(); |
776 | 893 | ||
@@ -846,11 +963,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
846 | //} | 963 | //} |
847 | } | 964 | } |
848 | 965 | ||
849 | ode.dunlock(world); | 966 | |
850 | } | 967 | } |
851 | } | 968 | } |
852 | } | 969 | } |
853 | 970 | ||
971 | #endregion | ||
972 | |||
973 | #region Space Separation Calculation | ||
974 | |||
854 | /// <summary> | 975 | /// <summary> |
855 | /// Takes a space pointer and zeros out the array we're using to hold the spaces | 976 | /// Takes a space pointer and zeros out the array we're using to hold the spaces |
856 | /// </summary> | 977 | /// </summary> |
@@ -1065,95 +1186,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1065 | 1186 | ||
1066 | return returnint; | 1187 | return returnint; |
1067 | } | 1188 | } |
1189 | #endregion | ||
1068 | 1190 | ||
1069 | private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation, | ||
1070 | IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) | ||
1071 | { | ||
1072 | PhysicsVector pos = new PhysicsVector(); | ||
1073 | pos.X = position.X; | ||
1074 | pos.Y = position.Y; | ||
1075 | pos.Z = position.Z; | ||
1076 | PhysicsVector siz = new PhysicsVector(); | ||
1077 | siz.X = size.X; | ||
1078 | siz.Y = size.Y; | ||
1079 | siz.Z = size.Z; | ||
1080 | Quaternion rot = new Quaternion(); | ||
1081 | rot.w = rotation.w; | ||
1082 | rot.x = rotation.x; | ||
1083 | rot.y = rotation.y; | ||
1084 | rot.z = rotation.z; | ||
1085 | |||
1086 | |||
1087 | |||
1088 | OdePrim newPrim; | ||
1089 | lock (OdeLock) | ||
1090 | { | ||
1091 | newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); | ||
1092 | |||
1093 | _prims.Add(newPrim); | ||
1094 | } | ||
1095 | |||
1096 | |||
1097 | return newPrim; | ||
1098 | } | ||
1099 | |||
1100 | public void addActivePrim(OdePrim activatePrim) | ||
1101 | { | ||
1102 | // adds active prim.. (ones that should be iterated over in collisions_optimized | ||
1103 | |||
1104 | _activeprims.Add(activatePrim); | ||
1105 | } | ||
1106 | |||
1107 | public void remActivePrim(OdePrim deactivatePrim) | ||
1108 | { | ||
1109 | _activeprims.Remove(deactivatePrim); | ||
1110 | } | ||
1111 | |||
1112 | public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount) | ||
1113 | { | ||
1114 | /* String name1 = null; | ||
1115 | String name2 = null; | ||
1116 | |||
1117 | if (!geom_name_map.TryGetValue(trimesh, out name1)) | ||
1118 | { | ||
1119 | name1 = "null"; | ||
1120 | } | ||
1121 | if (!geom_name_map.TryGetValue(refObject, out name2)) | ||
1122 | { | ||
1123 | name2 = "null"; | ||
1124 | } | ||
1125 | |||
1126 | m_log.InfoFormat("TriArrayCallback: A collision was detected between {1} and {2}", 0, name1, name2); | ||
1127 | */ | ||
1128 | return 1; | ||
1129 | } | ||
1130 | |||
1131 | public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) | ||
1132 | { | ||
1133 | String name1 = null; | ||
1134 | String name2 = null; | ||
1135 | |||
1136 | if (!geom_name_map.TryGetValue(trimesh, out name1)) | ||
1137 | { | ||
1138 | name1 = "null"; | ||
1139 | } | ||
1140 | |||
1141 | if (!geom_name_map.TryGetValue(refObject, out name2)) | ||
1142 | { | ||
1143 | name2 = "null"; | ||
1144 | } | ||
1145 | |||
1146 | // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex); | ||
1147 | |||
1148 | d.Vector3 v0 = new d.Vector3(); | ||
1149 | d.Vector3 v1 = new d.Vector3(); | ||
1150 | d.Vector3 v2 = new d.Vector3(); | ||
1151 | 1191 | ||
1152 | d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2); | ||
1153 | // m_log.DebugFormat("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z); | ||
1154 | 1192 | ||
1155 | return 1; | ||
1156 | } | ||
1157 | 1193 | ||
1158 | /// <summary> | 1194 | /// <summary> |
1159 | /// Routine to figure out if we need to mesh this prim with our mesher | 1195 | /// Routine to figure out if we need to mesh this prim with our mesher |
@@ -1183,36 +1219,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1183 | return false; | 1219 | return false; |
1184 | } | 1220 | } |
1185 | 1221 | ||
1186 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, | 1222 | |
1187 | PhysicsVector size, Quaternion rotation) //To be removed | ||
1188 | { | ||
1189 | return AddPrimShape(primName, pbs, position, size, rotation, false); | ||
1190 | } | ||
1191 | |||
1192 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, | ||
1193 | PhysicsVector size, Quaternion rotation, bool isPhysical) | ||
1194 | { | ||
1195 | PhysicsActor result; | ||
1196 | IMesh mesh = null; | ||
1197 | |||
1198 | switch (pbs.ProfileShape) | ||
1199 | { | ||
1200 | case ProfileShape.Square: | ||
1201 | /// support simple box & hollow box now; later, more shapes | ||
1202 | if (needsMeshing(pbs)) | ||
1203 | { | ||
1204 | mesh = mesher.CreateMesh(primName, pbs, size); | ||
1205 | } | ||
1206 | |||
1207 | break; | ||
1208 | } | ||
1209 | |||
1210 | result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical); | ||
1211 | |||
1212 | |||
1213 | return result; | ||
1214 | } | ||
1215 | |||
1216 | /// <summary> | 1223 | /// <summary> |
1217 | /// Called after our prim properties are set Scale, position etc. | 1224 | /// Called after our prim properties are set Scale, position etc. |
1218 | /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex | 1225 | /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex |
@@ -1224,8 +1231,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1224 | if (prim is OdePrim) | 1231 | if (prim is OdePrim) |
1225 | { | 1232 | { |
1226 | OdePrim taintedprim = ((OdePrim) prim); | 1233 | OdePrim taintedprim = ((OdePrim) prim); |
1227 | if (!(_taintedPrim.Contains(taintedprim))) | 1234 | lock (_taintedPrim) |
1228 | _taintedPrim.Add(taintedprim); | 1235 | { |
1236 | if (!(_taintedPrim.Contains(taintedprim))) | ||
1237 | _taintedPrim.Add(taintedprim); | ||
1238 | } | ||
1229 | } | 1239 | } |
1230 | } | 1240 | } |
1231 | 1241 | ||
@@ -1292,12 +1302,50 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1292 | ode.dlock(world); | 1302 | ode.dlock(world); |
1293 | try | 1303 | try |
1294 | { | 1304 | { |
1295 | foreach (OdeCharacter actor in _characters) | 1305 | lock (_characters) |
1296 | { | 1306 | { |
1297 | if (actor != null) | 1307 | foreach (OdeCharacter actor in _characters) |
1298 | actor.Move(timeStep); | 1308 | { |
1309 | if (actor != null) | ||
1310 | actor.Move(timeStep); | ||
1311 | } | ||
1299 | } | 1312 | } |
1300 | 1313 | ||
1314 | |||
1315 | bool processedtaints = false; | ||
1316 | |||
1317 | lock (_taintedPrim) | ||
1318 | { | ||
1319 | foreach (OdePrim prim in _taintedPrim) | ||
1320 | { | ||
1321 | if (prim.m_taintremove) | ||
1322 | { | ||
1323 | RemovePrimThreadLocked(prim); | ||
1324 | } | ||
1325 | |||
1326 | prim.ProcessTaints(timeStep); | ||
1327 | |||
1328 | processedtaints = true; | ||
1329 | prim.m_collisionscore = 0; | ||
1330 | } | ||
1331 | |||
1332 | if (processedtaints) | ||
1333 | _taintedPrim = new List<OdePrim>(); | ||
1334 | |||
1335 | } | ||
1336 | |||
1337 | lock (_activeprims) | ||
1338 | { | ||
1339 | foreach (OdePrim prim in _activeprims) | ||
1340 | { | ||
1341 | prim.m_collisionscore = 0; | ||
1342 | } | ||
1343 | } | ||
1344 | |||
1345 | |||
1346 | |||
1347 | |||
1348 | |||
1301 | collision_optimized(timeStep); | 1349 | collision_optimized(timeStep); |
1302 | 1350 | ||
1303 | d.WorldQuickStep(world, ODE_STEPSIZE); | 1351 | d.WorldQuickStep(world, ODE_STEPSIZE); |
@@ -1321,47 +1369,29 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1321 | } | 1369 | } |
1322 | } | 1370 | } |
1323 | 1371 | ||
1324 | foreach (OdeCharacter actor in _characters) | 1372 | lock (_characters) |
1325 | { | ||
1326 | if (actor != null) | ||
1327 | actor.UpdatePositionAndVelocity(); | ||
1328 | } | ||
1329 | |||
1330 | if (!ode.lockquery()) | ||
1331 | { | ||
1332 | bool processedtaints = false; | ||
1333 | foreach (OdePrim prim in _taintedPrim) | ||
1334 | { | ||
1335 | if (prim.m_taintremove) | ||
1336 | { | ||
1337 | RemovePrimThreadLocked(prim); | ||
1338 | } | ||
1339 | |||
1340 | prim.ProcessTaints(timeStep); | ||
1341 | |||
1342 | processedtaints = true; | ||
1343 | prim.m_collisionscore = 0; | ||
1344 | } | ||
1345 | if (processedtaints) | ||
1346 | _taintedPrim = new List<OdePrim>(); | ||
1347 | } | ||
1348 | foreach (OdePrim prim in _activeprims) | ||
1349 | { | 1373 | { |
1350 | prim.m_collisionscore = 0; | 1374 | foreach (OdeCharacter actor in _characters) |
1375 | { | ||
1376 | if (actor != null) | ||
1377 | actor.UpdatePositionAndVelocity(); | ||
1378 | } | ||
1351 | } | 1379 | } |
1352 | 1380 | ||
1353 | 1381 | lock (_activeprims) | |
1354 | |||
1355 | if (timeStep < 0.2f) | ||
1356 | { | 1382 | { |
1357 | foreach (OdePrim actor in _activeprims) | 1383 | if (timeStep < 0.2f) |
1358 | { | 1384 | { |
1359 | if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag)) | 1385 | foreach (OdePrim actor in _activeprims) |
1360 | { | 1386 | { |
1361 | actor.UpdatePositionAndVelocity(); | 1387 | if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag)) |
1388 | { | ||
1389 | actor.UpdatePositionAndVelocity(); | ||
1390 | } | ||
1362 | } | 1391 | } |
1363 | } | 1392 | } |
1364 | } | 1393 | } |
1394 | |||
1365 | } | 1395 | } |
1366 | return fps; | 1396 | return fps; |
1367 | } | 1397 | } |
@@ -1375,6 +1405,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1375 | // for now we won't be multithreaded | 1405 | // for now we won't be multithreaded |
1376 | get { return (false); } | 1406 | get { return (false); } |
1377 | } | 1407 | } |
1408 | |||
1409 | #region ODE Specific Terrain Fixes | ||
1378 | public float[] ResizeTerrain512NearestNeighbour(float[] heightMap) | 1410 | public float[] ResizeTerrain512NearestNeighbour(float[] heightMap) |
1379 | { | 1411 | { |
1380 | float[] returnarr = new float[262144]; | 1412 | float[] returnarr = new float[262144]; |
@@ -1637,11 +1669,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1637 | return returnarr; | 1669 | return returnarr; |
1638 | } | 1670 | } |
1639 | 1671 | ||
1672 | #endregion | ||
1673 | |||
1640 | public override void SetTerrain(float[] heightMap) | 1674 | public override void SetTerrain(float[] heightMap) |
1641 | { | 1675 | { |
1642 | // this._heightmap[i] = (double)heightMap[i]; | 1676 | // this._heightmap[i] = (double)heightMap[i]; |
1643 | // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...) | 1677 | // dbm (danx0r) -- creating a buffer zone of one extra sample all around |
1644 | // also, creating a buffer zone of one extra sample all around | ||
1645 | _origheightmap = heightMap; | 1678 | _origheightmap = heightMap; |
1646 | const uint heightmapWidth = m_regionWidth + 2; | 1679 | const uint heightmapWidth = m_regionWidth + 2; |
1647 | const uint heightmapHeight = m_regionHeight + 2; | 1680 | const uint heightmapHeight = m_regionHeight + 2; |
@@ -1654,6 +1687,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1654 | 1687 | ||
1655 | //Double resolution | 1688 | //Double resolution |
1656 | heightMap = ResizeTerrain512Interpolation(heightMap); | 1689 | heightMap = ResizeTerrain512Interpolation(heightMap); |
1690 | |||
1657 | for (int x = 0; x < heightmapWidthSamples; x++) | 1691 | for (int x = 0; x < heightmapWidthSamples; x++) |
1658 | { | 1692 | { |
1659 | for (int y = 0; y < heightmapHeightSamples; y++) | 1693 | for (int y = 0; y < heightmapHeightSamples; y++) |