aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
diff options
context:
space:
mode:
authorTeravus Ovares2008-10-14 02:48:30 +0000
committerTeravus Ovares2008-10-14 02:48:30 +0000
commit180e3de50f23436ef8800183a84259750564c157 (patch)
tree818e541c4151d122bcc8e7ab2c176d1ebd0afc52 /OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
parent* Remove a warning from BaseHttpServer (diff)
downloadopensim-SC-180e3de50f23436ef8800183a84259750564c157.zip
opensim-SC-180e3de50f23436ef8800183a84259750564c157.tar.gz
opensim-SC-180e3de50f23436ef8800183a84259750564c157.tar.bz2
opensim-SC-180e3de50f23436ef8800183a84259750564c157.tar.xz
* Cleaned up tons of code duplication in ODEPrim
* Re-enabled the native ODE prim types when possible * Fixed several invalid assumptions in the prim recycle process. * Added better message for 'reused a disposed physicsactor' * Added a way to recover from errors during collision_optimized * Added a way to recover from an error condition where prim_geom wasn't reset properly
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/ODEPrim.cs')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs398
1 files changed, 133 insertions, 265 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 5d9b169..a2c0c6b 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -161,22 +161,7 @@ namespace OpenSim.Region.Physics.OdePlugin
161 m_density = parent_scene.geomDefaultDensity; 161 m_density = parent_scene.geomDefaultDensity;
162 m_tensor = parent_scene.bodyMotorJointMaxforceTensor; 162 m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
163 body_autodisable_frames = parent_scene.bodyFramesAutoDisable; 163 body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
164 //if (_position.X > 257) 164
165 //{
166 //_position.X = 257;
167 //}
168 //if (_position.X < 0)
169 //{
170 //_position.X = 0;
171 //}
172 //if (_position.Y > 257)
173 //{
174 //_position.Y = 257;
175 //}
176 //if (_position.Y < 0)
177 //{
178 // _position.Y = 0;
179 //}
180 165
181 prim_geom = (IntPtr)0; 166 prim_geom = (IntPtr)0;
182 prev_geom = (IntPtr)0; 167 prev_geom = (IntPtr)0;
@@ -715,14 +700,14 @@ namespace OpenSim.Region.Physics.OdePlugin
715 oldMesh = null; 700 oldMesh = null;
716 } 701 }
717 702
718 if (IsPhysical && Body == (IntPtr) 0) 703 // if (IsPhysical && Body == (IntPtr) 0)
719 { 704 // {
720 // Recreate the body 705 // Recreate the body
721 m_interpenetrationcount = 0; 706 // m_interpenetrationcount = 0;
722 m_collisionscore = 0; 707 // m_collisionscore = 0;
723 708
724 enableBody(); 709 // enableBody();
725 } 710 // }
726 } 711 }
727 712
728 public void ProcessTaints(float timestep) 713 public void ProcessTaints(float timestep)
@@ -775,7 +760,7 @@ namespace OpenSim.Region.Physics.OdePlugin
775 } 760 }
776 else 761 else
777 { 762 {
778 m_log.Error("[PHYSICS]: The scene reused a disposed PhysActor! *waves finger*, Don't be evil."); 763 m_log.Error("[PHYSICS]: The scene reused a disposed PhysActor! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)");
779 } 764 }
780 } 765 }
781 766
@@ -910,69 +895,30 @@ namespace OpenSim.Region.Physics.OdePlugin
910 m_taintVelocity = PhysicsVector.Zero; 895 m_taintVelocity = PhysicsVector.Zero;
911 } 896 }
912 897
913 public void changeadd(float timestep) 898 public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh)
914 { 899 {
915 int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); 900 if (_mesh != null)
916 IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position);
917
918 if (targetspace == IntPtr.Zero)
919 targetspace = _parent_scene.createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
920
921 m_targetSpace = targetspace;
922
923 if (_mesh == null)
924 { 901 {
925 if (_parent_scene.needsMeshing(_pbs)) 902 setMesh(_parent_scene, _mesh);
926 {
927 // Don't need to re-enable body.. it's done in SetMesh
928 _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
929 // createmesh returns null when it's a shape that isn't a cube.
930 }
931 } 903 }
932 904 else
933 //if (_mesh == null )
934 // _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
935
936
937 lock (OdeScene.OdeLock)
938 { 905 {
939 if (_mesh != null) 906 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
940 {
941 setMesh(_parent_scene, _mesh);
942 }
943 else
944 { 907 {
945 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) 908 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
946 { 909 {
947 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) 910 if (((_size.X / 2f) > 0f))
948 { 911 {
949 if (((_size.X / 2f) > 0f)) 912 _parent_scene.waitForSpaceUnlock(m_targetSpace);
913 try
950 { 914 {
951 _parent_scene.waitForSpaceUnlock(m_targetSpace); 915 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
952 try
953 {
954 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
955 }
956 catch (AccessViolationException)
957 {
958 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
959 ode.dunlock(_parent_scene.world);
960 return;
961 }
962 } 916 }
963 else 917 catch (AccessViolationException)
964 { 918 {
965 _parent_scene.waitForSpaceUnlock(m_targetSpace); 919 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
966 try 920 ode.dunlock(_parent_scene.world);
967 { 921 return;
968 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
969 }
970 catch (AccessViolationException)
971 {
972 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
973 ode.dunlock(_parent_scene.world);
974 return;
975 }
976 } 922 }
977 } 923 }
978 else 924 else
@@ -980,7 +926,7 @@ namespace OpenSim.Region.Physics.OdePlugin
980 _parent_scene.waitForSpaceUnlock(m_targetSpace); 926 _parent_scene.waitForSpaceUnlock(m_targetSpace);
981 try 927 try
982 { 928 {
983 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 929 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
984 } 930 }
985 catch (AccessViolationException) 931 catch (AccessViolationException)
986 { 932 {
@@ -990,18 +936,6 @@ namespace OpenSim.Region.Physics.OdePlugin
990 } 936 }
991 } 937 }
992 } 938 }
993 //else if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
994 //{
995 //Cyllinder
996 //if (_size.X == _size.Y)
997 //{
998 //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
999 //}
1000 //else
1001 //{
1002 //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1003 //}
1004 //}
1005 else 939 else
1006 { 940 {
1007 _parent_scene.waitForSpaceUnlock(m_targetSpace); 941 _parent_scene.waitForSpaceUnlock(m_targetSpace);
@@ -1017,6 +951,49 @@ namespace OpenSim.Region.Physics.OdePlugin
1017 } 951 }
1018 } 952 }
1019 } 953 }
954
955 else
956 {
957 _parent_scene.waitForSpaceUnlock(m_targetSpace);
958 try
959 {
960 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
961 }
962 catch (AccessViolationException)
963 {
964 m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
965 ode.dunlock(_parent_scene.world);
966 return;
967 }
968 }
969 }
970 }
971
972 public void changeadd(float timestep)
973 {
974 int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
975 IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position);
976
977 if (targetspace == IntPtr.Zero)
978 targetspace = _parent_scene.createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
979
980 m_targetSpace = targetspace;
981
982 if (_mesh == null)
983 {
984 if (_parent_scene.needsMeshing(_pbs))
985 {
986 // Don't need to re-enable body.. it's done in SetMesh
987 _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
988 // createmesh returns null when it's a shape that isn't a cube.
989 }
990 }
991
992
993 lock (OdeScene.OdeLock)
994 {
995 CreateGeom(m_targetSpace, _mesh);
996
1020 if (prim_geom != (IntPtr) 0) 997 if (prim_geom != (IntPtr) 0)
1021 { 998 {
1022 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 999 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
@@ -1277,8 +1254,22 @@ namespace OpenSim.Region.Physics.OdePlugin
1277 { 1254 {
1278 if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) 1255 if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
1279 { 1256 {
1257
1258
1280 if (prim_geom != IntPtr.Zero) 1259 if (prim_geom != IntPtr.Zero)
1281 d.GeomDestroy(prim_geom); 1260 {
1261 try
1262 {
1263 d.GeomDestroy(prim_geom);
1264 prim_geom = IntPtr.Zero;
1265 _mesh = null;
1266 }
1267 catch (System.AccessViolationException)
1268 {
1269 prim_geom = IntPtr.Zero;
1270 m_log.Error("[PHYSICS]: PrimGeom dead");
1271 }
1272 }
1282 1273
1283 changeadd(2f); 1274 changeadd(2f);
1284 } 1275 }
@@ -1340,66 +1331,31 @@ namespace OpenSim.Region.Physics.OdePlugin
1340 1331
1341 //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 1332 //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
1342 1333
1343 if (mesh != null) 1334 CreateGeom(m_targetSpace, mesh);
1344 {
1345 setMesh(_parent_scene, mesh);
1346 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1347 d.Quaternion myrot = new d.Quaternion();
1348 myrot.X = _orientation.X;
1349 myrot.Y = _orientation.Y;
1350 myrot.Z = _orientation.Z;
1351 myrot.W = _orientation.W;
1352 d.GeomSetQuaternion(prim_geom, ref myrot);
1353 1335
1354 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); 1336
1355 if (IsPhysical && Body == (IntPtr)0) 1337 }
1356 { 1338 else
1357 // Re creates body on size. 1339 {
1358 // EnableBody also does setMass() 1340 _mesh = null;
1359 enableBody(); 1341 CreateGeom(m_targetSpace, _mesh);
1360 d.BodyEnable(Body); 1342 }
1361 }
1362 }
1363 else
1364 {
1365 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
1366 {
1367 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
1368 {
1369 if (((_size.X / 2f) > 0f) && ((_size.X / 2f) < 1000))
1370 {
1371 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1372 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
1373 }
1374 else
1375 {
1376 m_log.Info("[PHYSICS]: Failed to load a sphere bad size");
1377 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1378 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1379 }
1380 1343
1381 } 1344 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1382 else 1345 d.Quaternion myrot = new d.Quaternion();
1383 { 1346 myrot.X = _orientation.X;
1384 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1347 myrot.Y = _orientation.Y;
1385 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 1348 myrot.Z = _orientation.Z;
1386 } 1349 myrot.W = _orientation.W;
1387 } 1350 d.GeomSetQuaternion(prim_geom, ref myrot);
1388 1351
1389 else 1352 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
1390 { 1353 if (IsPhysical && Body == (IntPtr)0)
1391 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1354 {
1392 SetGeom(prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 1355 // Re creates body on size.
1393 } 1356 // EnableBody also does setMass()
1394 //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); 1357 enableBody();
1395 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 1358 d.BodyEnable(Body);
1396 d.Quaternion myrot = new d.Quaternion();
1397 myrot.X = _orientation.X;
1398 myrot.Y = _orientation.Y;
1399 myrot.Z = _orientation.Z;
1400 myrot.W = _orientation.W;
1401 d.GeomSetQuaternion(prim_geom, ref myrot);
1402 }
1403 } 1359 }
1404 1360
1405 _parent_scene.geom_name_map[prim_geom] = oldname; 1361 _parent_scene.geom_name_map[prim_geom] = oldname;
@@ -1609,7 +1565,15 @@ namespace OpenSim.Region.Physics.OdePlugin
1609 { 1565 {
1610 disableBody(); 1566 disableBody();
1611 } 1567 }
1612 d.GeomDestroy(prim_geom); 1568 try
1569 {
1570 d.GeomDestroy(prim_geom);
1571 }
1572 catch (System.AccessViolationException)
1573 {
1574 prim_geom = IntPtr.Zero;
1575 m_log.Error("[PHYSICS]: PrimGeom dead");
1576 }
1613 prim_geom = (IntPtr) 0; 1577 prim_geom = (IntPtr) 0;
1614 // we don't need to do space calculation because the client sends a position update also. 1578 // we don't need to do space calculation because the client sends a position update also.
1615 if (_size.X <= 0) _size.X = 0.01f; 1579 if (_size.X <= 0) _size.X = 0.01f;
@@ -1626,128 +1590,32 @@ namespace OpenSim.Region.Physics.OdePlugin
1626 meshlod = _parent_scene.MeshSculptphysicalLOD; 1590 meshlod = _parent_scene.MeshSculptphysicalLOD;
1627 1591
1628 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 1592 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
1629 // createmesh returns null when it's a shape that isn't a cube. 1593 // createmesh returns null when it doesn't mesh.
1630 if (mesh != null) 1594 CreateGeom(m_targetSpace, mesh);
1631 {
1632 setMesh(_parent_scene, mesh);
1633 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1634 d.Quaternion myrot = new d.Quaternion();
1635 myrot.X = _orientation.X;
1636 myrot.Y = _orientation.Y;
1637 myrot.Z = _orientation.Z;
1638 myrot.W = _orientation.W;
1639 d.GeomSetQuaternion(prim_geom, ref myrot);
1640
1641 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
1642 if (IsPhysical && Body == (IntPtr)0)
1643 {
1644 // Re creates body on size.
1645 // EnableBody also does setMass()
1646 enableBody();
1647 }
1648 }
1649 else
1650 {
1651 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
1652 {
1653 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
1654 {
1655 if (((_size.X / 2f) > 0f) && ((_size.X / 2f) < 1000))
1656 {
1657 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1658 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
1659 }
1660 else
1661 {
1662 m_log.Info("[PHYSICS]: Failed to load a sphere bad size");
1663 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1664 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1665 }
1666 }
1667 else
1668 {
1669 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1670 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1671 }
1672 }
1673 //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
1674 //{
1675 //Cyllinder
1676 //if (_size.X == _size.Y)
1677 //{
1678 // prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
1679 //}
1680 //else
1681 //{
1682 //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1683 //}
1684 //}
1685 else
1686 {
1687 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1688 SetGeom(prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1689 }
1690 //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1691 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1692 d.Quaternion myrot = new d.Quaternion();
1693 myrot.X = _orientation.X;
1694 myrot.Y = _orientation.Y;
1695 myrot.Z = _orientation.Z;
1696 myrot.W = _orientation.W;
1697 d.GeomSetQuaternion(prim_geom, ref myrot);
1698 }
1699 } 1595 }
1700 else 1596 else
1701 { 1597 {
1702 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) 1598 _mesh = null;
1703 { 1599 CreateGeom(m_targetSpace, null);
1704 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
1705 {
1706 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1707 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
1708 }
1709 else
1710 {
1711 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1712 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1713 }
1714 }
1715 //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
1716 //{
1717 //Cyllinder
1718 //if (_size.X == _size.Y)
1719 //{
1720 //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
1721 //}
1722 //else
1723 //{
1724 //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1725 //}
1726 //}
1727 else
1728 {
1729 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1730 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1731 }
1732 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1733 d.Quaternion myrot = new d.Quaternion();
1734 //myrot.W = _orientation.w;
1735 myrot.W = _orientation.W;
1736 myrot.X = _orientation.X;
1737 myrot.Y = _orientation.Y;
1738 myrot.Z = _orientation.Z;
1739 d.GeomSetQuaternion(prim_geom, ref myrot);
1740
1741 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
1742 if (IsPhysical && Body == (IntPtr)0)
1743 {
1744 // Re creates body on size.
1745 // EnableBody also does setMass()
1746 enableBody();
1747 d.BodyEnable(Body);
1748 }
1749 } 1600 }
1750 1601
1602 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1603 d.Quaternion myrot = new d.Quaternion();
1604 //myrot.W = _orientation.w;
1605 myrot.W = _orientation.W;
1606 myrot.X = _orientation.X;
1607 myrot.Y = _orientation.Y;
1608 myrot.Z = _orientation.Z;
1609 d.GeomSetQuaternion(prim_geom, ref myrot);
1610
1611 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
1612 if (IsPhysical && Body == (IntPtr)0)
1613 {
1614 // Re creates body on size.
1615 // EnableBody also does setMass()
1616 enableBody();
1617 d.BodyEnable(Body);
1618 }
1751 _parent_scene.geom_name_map[prim_geom] = oldname; 1619 _parent_scene.geom_name_map[prim_geom] = oldname;
1752 1620
1753 changeSelectedStatus(timestamp); 1621 changeSelectedStatus(timestamp);