aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
diff options
context:
space:
mode:
authorUbitUmarov2012-04-16 16:16:55 +0100
committerUbitUmarov2012-04-16 16:16:55 +0100
commit86a2169d7343825c74ae271f637002377b92b438 (patch)
tree5bfc66b130edcacc738d3f4e8b4efa854a37fe7e /OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
parentUse chode character actor.SetMomentum() to force full restore Velocity in sce... (diff)
downloadopensim-SC_OLD-86a2169d7343825c74ae271f637002377b92b438.zip
opensim-SC_OLD-86a2169d7343825c74ae271f637002377b92b438.tar.gz
opensim-SC_OLD-86a2169d7343825c74ae271f637002377b92b438.tar.bz2
opensim-SC_OLD-86a2169d7343825c74ae271f637002377b92b438.tar.xz
ubitODE + physmanager: - Revised use of ODE collisions categories and bits(flags) for better use as filters together with top spaces (for example physical prims are on topactivespace and not physical are on topstaticspace) - Added new world raycast with filters. This blocks calling thread with a timeout of 500ms waiting for heartbeat ode thread signal job done. - Don't let ode bodies being disabled for 2 long except for vehicles. This is necessary to detect when the object is at rest at top of other and that is removed. Assume that vehicles can be enabled by used action.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs1069
1 files changed, 497 insertions, 572 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index f739183..32c4722 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -108,25 +108,29 @@ namespace OpenSim.Region.Physics.OdePlugin
108 private float m_waterHeight; 108 private float m_waterHeight;
109 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. 109 private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
110 110
111 private int body_autodisable_frames = 20; 111 private int body_autodisable_frames = 5;
112 private int bodydisablecontrol = 0;
113
114
115 // Default we're a Geometry
116 private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
117 // Default colide nonphysical don't try to colide with anything
118 private const CollisionCategories m_default_collisionFlagsNotPhysical = 0;
119
120 private const CollisionCategories m_default_collisionFlagsPhysical = (CollisionCategories.Geom |
121 CollisionCategories.Character |
122 CollisionCategories.Land |
123 CollisionCategories.VolumeDtc);
112 124
113 private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
114 | CollisionCategories.Space
115 | CollisionCategories.Body
116 | CollisionCategories.Character
117 );
118// private bool m_collidesLand = true; 125// private bool m_collidesLand = true;
119 private bool m_collidesWater; 126 private bool m_collidesWater;
120 public bool m_returnCollisions; 127 public bool m_returnCollisions;
121 private bool m_softcolide;
122 128
123 private bool m_NoColide; // for now only for internal use for bad meshs 129 private bool m_NoColide; // for now only for internal use for bad meshs
124 130
125 // Default we're a Geometry
126 private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
127 131
128 // Default, Collide with Other Geometries, spaces and Bodies 132 // Default, Collide with Other Geometries, spaces and Bodies
129 private CollisionCategories m_collisionFlags = m_default_collisionFlags; 133 private CollisionCategories m_collisionFlags = m_default_collisionFlagsNotPhysical;
130 134
131 public bool m_disabled; 135 public bool m_disabled;
132 136
@@ -179,6 +183,7 @@ namespace OpenSim.Region.Physics.OdePlugin
179 public float primOOBradiusSQ; 183 public float primOOBradiusSQ;
180 public d.Mass primdMass; // prim inertia information on it's own referencial 184 public d.Mass primdMass; // prim inertia information on it's own referencial
181 float primMass; // prim own mass 185 float primMass; // prim own mass
186 float primVolume; // prim own volume;
182 float _mass; // object mass acording to case 187 float _mass; // object mass acording to case
183 private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb 188 private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb
184 189
@@ -216,6 +221,14 @@ namespace OpenSim.Region.Physics.OdePlugin
216 } 221 }
217 } 222 }
218 223
224 public override bool IsVolumeDtc
225 {
226 set { return; }
227 get { return m_isVolumeDetect; }
228
229 }
230
231
219 public override bool Phantom // this is not reliable for internal use 232 public override bool Phantom // this is not reliable for internal use
220 { 233 {
221 get { return m_fakeisphantom; } 234 get { return m_fakeisphantom; }
@@ -327,10 +340,7 @@ namespace OpenSim.Region.Physics.OdePlugin
327 } 340 }
328 341
329 if (m_colliderfilter == 0) 342 if (m_colliderfilter == 0)
330 {
331 m_softcolide = false;
332 m_iscolliding = false; 343 m_iscolliding = false;
333 }
334 else 344 else
335 m_iscolliding = true; 345 m_iscolliding = true;
336 } 346 }
@@ -422,6 +432,10 @@ namespace OpenSim.Region.Physics.OdePlugin
422 432
423 public override Vector3 GeometricCenter 433 public override Vector3 GeometricCenter
424 { 434 {
435 // this is not real geometric center but a average of positions relative to root prim acording to
436 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
437 // ignoring tortured prims details since sl also seems to ignore
438 // so no real use in doing it on physics
425 get 439 get
426 { 440 {
427 return Vector3.Zero; 441 return Vector3.Zero;
@@ -949,7 +963,6 @@ namespace OpenSim.Region.Physics.OdePlugin
949 963
950 m_iscolliding = false; 964 m_iscolliding = false;
951 m_colliderfilter = 0; 965 m_colliderfilter = 0;
952 m_softcolide = true;
953 m_NoColide = false; 966 m_NoColide = false;
954 967
955 hasOOBoffsetFromMesh = false; 968 hasOOBoffsetFromMesh = false;
@@ -992,6 +1005,132 @@ namespace OpenSim.Region.Physics.OdePlugin
992 m_collisionscore = 0; 1005 m_collisionscore = 0;
993 } 1006 }
994 1007
1008 private void UpdateCollisionCatFlags()
1009 {
1010 if(m_isphysical && m_disabled)
1011 {
1012 m_collisionCategories = 0;
1013 m_collisionFlags = 0;
1014 }
1015
1016 else if (m_isSelected)
1017 {
1018 m_collisionCategories = CollisionCategories.Selected;
1019 m_collisionFlags = 0;
1020 }
1021
1022 else if (m_isVolumeDetect)
1023 {
1024 m_collisionCategories = CollisionCategories.VolumeDtc;
1025 if (m_isphysical)
1026 m_collisionFlags = CollisionCategories.Geom | CollisionCategories.Character;
1027 else
1028 m_collisionFlags = 0;
1029 }
1030 else if (m_isphantom)
1031 {
1032 m_collisionCategories = CollisionCategories.Phantom;
1033 if (m_isphysical)
1034 m_collisionFlags = CollisionCategories.Land;
1035 else
1036 m_collisionFlags = 0;
1037 }
1038 else
1039 {
1040 m_collisionCategories = CollisionCategories.Geom;
1041 if (m_isphysical)
1042 m_collisionFlags = m_default_collisionFlagsPhysical;
1043 else
1044 m_collisionFlags = m_default_collisionFlagsNotPhysical;
1045 }
1046 }
1047
1048 private void ApplyCollisionCatFlags()
1049 {
1050 if (prim_geom != IntPtr.Zero)
1051 {
1052 if (!childPrim && childrenPrim.Count > 0)
1053 {
1054 foreach (OdePrim prm in childrenPrim)
1055 {
1056 if (m_isphysical && m_disabled)
1057 {
1058 prm.m_collisionCategories = 0;
1059 prm.m_collisionFlags = 0;
1060 }
1061 else
1062 {
1063 // preserve some
1064 if (prm.m_isSelected)
1065 {
1066 prm.m_collisionCategories = CollisionCategories.Selected;
1067 prm.m_collisionFlags = 0;
1068 }
1069 else if (prm.IsVolumeDtc)
1070 {
1071 prm.m_collisionCategories = CollisionCategories.VolumeDtc;
1072 if (m_isphysical)
1073 prm.m_collisionFlags = CollisionCategories.Geom | CollisionCategories.Character;
1074 else
1075 prm.m_collisionFlags = 0;
1076 }
1077 else if (prm.m_isphantom)
1078 {
1079 prm.m_collisionCategories = CollisionCategories.Phantom;
1080 if (m_isphysical)
1081 prm.m_collisionFlags = CollisionCategories.Land;
1082 else
1083 prm.m_collisionFlags = 0;
1084 }
1085 else
1086 {
1087 prm.m_collisionCategories = m_collisionCategories;
1088 prm.m_collisionFlags = m_collisionFlags;
1089 }
1090 }
1091
1092 if (prm.prim_geom != IntPtr.Zero)
1093 {
1094 if (prm.m_NoColide)
1095 {
1096 d.GeomSetCategoryBits(prm.prim_geom, 0);
1097 if (m_isphysical)
1098 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1099 else
1100 d.GeomSetCollideBits(prm.prim_geom, 0);
1101 }
1102 else
1103 {
1104 d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
1105 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
1106 }
1107 }
1108 }
1109 }
1110
1111 if (m_NoColide)
1112 {
1113 d.GeomSetCategoryBits(prim_geom, 0);
1114 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
1115 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
1116 {
1117 d.GeomSetCategoryBits(collide_geom, 0);
1118 d.GeomSetCollideBits(collide_geom, (uint)CollisionCategories.Land);
1119 }
1120 }
1121 else
1122 {
1123 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1124 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1125 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
1126 {
1127 d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories);
1128 d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags);
1129 }
1130 }
1131 }
1132 }
1133
995 private void createAMotor(Vector3 axis) 1134 private void createAMotor(Vector3 axis)
996 { 1135 {
997 if (Body == IntPtr.Zero) 1136 if (Body == IntPtr.Zero)
@@ -1188,7 +1327,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1188 d.GeomSetCategoryBits(prim_geom, 0); 1327 d.GeomSetCategoryBits(prim_geom, 0);
1189 if (m_isphysical) 1328 if (m_isphysical)
1190 { 1329 {
1191 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); 1330 d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land);
1192 } 1331 }
1193 else 1332 else
1194 { 1333 {
@@ -1198,8 +1337,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1198 } 1337 }
1199 else 1338 else
1200 { 1339 {
1201 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1340 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1202 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1341 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1203 } 1342 }
1204 1343
1205 CalcPrimBodyData(); 1344 CalcPrimBodyData();
@@ -1296,6 +1435,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1296 } 1435 }
1297 1436
1298 prim_geom = IntPtr.Zero; 1437 prim_geom = IntPtr.Zero;
1438 collide_geom = IntPtr.Zero;
1299 } 1439 }
1300 else 1440 else
1301 { 1441 {
@@ -1319,66 +1459,23 @@ namespace OpenSim.Region.Physics.OdePlugin
1319 { 1459 {
1320 IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace); 1460 IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace);
1321 prim.m_targetSpace = targetSpace; 1461 prim.m_targetSpace = targetSpace;
1322 d.GeomEnable(prim_geom); 1462 collide_geom = IntPtr.Zero;
1323 } 1463 }
1324 1464
1325 public void enableBodySoft() 1465 public void enableBodySoft()
1326 { 1466 {
1467 m_disabled = false;
1327 if (!childPrim && !m_isSelected) 1468 if (!childPrim && !m_isSelected)
1328 { 1469 {
1329 if (m_isphysical && Body != IntPtr.Zero) 1470 if (m_isphysical && Body != IntPtr.Zero)
1330 { 1471 {
1331 if (m_isphantom && !m_isVolumeDetect) 1472 UpdateCollisionCatFlags();
1332 { 1473 ApplyCollisionCatFlags();
1333 m_collisionCategories = 0;
1334 m_collisionFlags = CollisionCategories.Land;
1335 }
1336 else
1337 {
1338 m_collisionCategories |= CollisionCategories.Body;
1339 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1340 }
1341
1342 foreach (OdePrim prm in childrenPrim)
1343 {
1344 prm.m_collisionCategories = m_collisionCategories;
1345 prm.m_collisionFlags = m_collisionFlags;
1346 1474
1347 if (prm.prim_geom != IntPtr.Zero)
1348 {
1349 if (prm.m_NoColide)
1350 {
1351 d.GeomSetCategoryBits(prm.prim_geom, 0);
1352 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1353 }
1354 else
1355 {
1356 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
1357 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
1358 }
1359 d.GeomEnable(prm.prim_geom);
1360 }
1361 }
1362
1363 if (prim_geom != IntPtr.Zero)
1364 {
1365 if (m_NoColide)
1366 {
1367 d.GeomSetCategoryBits(prim_geom, 0);
1368 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
1369 }
1370 else
1371 {
1372 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1373 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1374 }
1375 d.GeomEnable(prim_geom);
1376 }
1377 d.BodyEnable(Body); 1475 d.BodyEnable(Body);
1378 } 1476 }
1379 } 1477 }
1380 m_disabled = false; 1478 resetCollisionAccounting();
1381 resetCollisionAccounting(); // this sets m_disable to false
1382 } 1479 }
1383 1480
1384 private void disableBodySoft() 1481 private void disableBodySoft()
@@ -1388,45 +1485,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1388 { 1485 {
1389 if (m_isphysical && Body != IntPtr.Zero) 1486 if (m_isphysical && Body != IntPtr.Zero)
1390 { 1487 {
1391 m_collisionCategories &= ~CollisionCategories.Body; 1488 if (m_isSelected)
1392 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 1489 m_collisionFlags = CollisionCategories.Selected;
1393 1490 else
1394 foreach (OdePrim prm in childrenPrim) 1491 m_collisionCategories = 0;
1395 { 1492 m_collisionFlags = 0;
1396 prm.m_collisionCategories = m_collisionCategories; 1493 ApplyCollisionCatFlags();
1397 prm.m_collisionFlags = m_collisionFlags;
1398
1399 if (prm.prim_geom != IntPtr.Zero)
1400 {
1401 if (prm.m_NoColide)
1402 {
1403 d.GeomSetCategoryBits(prm.prim_geom, 0);
1404 d.GeomSetCollideBits(prm.prim_geom, 0);
1405 }
1406 else
1407 {
1408 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
1409 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
1410 }
1411 d.GeomDisable(prm.prim_geom);
1412 }
1413 }
1414
1415 if (prim_geom != IntPtr.Zero)
1416 {
1417 if (m_NoColide)
1418 {
1419 d.GeomSetCategoryBits(prim_geom, 0);
1420 d.GeomSetCollideBits(prim_geom, 0);
1421 }
1422 else
1423 {
1424 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1425 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1426 }
1427 d.GeomDisable(prim_geom);
1428 }
1429
1430 d.BodyDisable(Body); 1494 d.BodyDisable(Body);
1431 } 1495 }
1432 } 1496 }
@@ -1566,7 +1630,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1566 // d.BodySetAngularDampingThreshold(Body, 0.001f); 1630 // d.BodySetAngularDampingThreshold(Body, 0.001f);
1567 d.BodySetDamping(Body, .002f, .002f); 1631 d.BodySetDamping(Body, .002f, .002f);
1568 1632
1569
1570 if (m_targetSpace != IntPtr.Zero) 1633 if (m_targetSpace != IntPtr.Zero)
1571 { 1634 {
1572 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1635 _parent_scene.waitForSpaceUnlock(m_targetSpace);
@@ -1588,6 +1651,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1588 d.SpaceSetSublevel(m_targetSpace, 3); 1651 d.SpaceSetSublevel(m_targetSpace, 3);
1589 d.SpaceSetCleanup(m_targetSpace, false); 1652 d.SpaceSetCleanup(m_targetSpace, false);
1590 d.SpaceAdd(m_targetSpace, prim_geom); 1653 d.SpaceAdd(m_targetSpace, prim_geom);
1654
1655 d.GeomSetCategoryBits(m_targetSpace, (uint)(CollisionCategories.Space |
1656 CollisionCategories.Geom |
1657 CollisionCategories.Phantom |
1658 CollisionCategories.VolumeDtc
1659 ));
1660 d.GeomSetCollideBits(m_targetSpace, 0);
1591 collide_geom = m_targetSpace; 1661 collide_geom = m_targetSpace;
1592 } 1662 }
1593 1663
@@ -1619,38 +1689,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1619 d.SpaceAdd(m_targetSpace, prm.prim_geom); 1689 d.SpaceAdd(m_targetSpace, prm.prim_geom);
1620 } 1690 }
1621 1691
1622 if (m_isSelected || m_disabled)
1623 {
1624 prm.m_collisionCategories &= ~CollisionCategories.Body;
1625 prm.m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
1626 d.GeomDisable(prm.prim_geom);
1627 }
1628 else
1629 {
1630 if (m_isphantom && !m_isVolumeDetect)
1631 {
1632 prm.m_collisionCategories = 0;
1633 prm.m_collisionFlags = CollisionCategories.Land;
1634 }
1635 else
1636 {
1637 prm.m_collisionCategories |= CollisionCategories.Body;
1638 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1639 }
1640 d.GeomEnable(prm.prim_geom);
1641 }
1642
1643 if (prm.m_NoColide)
1644 {
1645 d.GeomSetCategoryBits(prm.prim_geom, 0);
1646 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1647 d.GeomEnable(prm.prim_geom);
1648 }
1649 else
1650 {
1651 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
1652 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
1653 }
1654 prm.m_collisionscore = 0; 1692 prm.m_collisionscore = 0;
1655 1693
1656 if(!m_disabled) 1694 if(!m_disabled)
@@ -1666,45 +1704,21 @@ namespace OpenSim.Region.Physics.OdePlugin
1666 createAMotor(m_angularlock); 1704 createAMotor(m_angularlock);
1667 } 1705 }
1668 1706
1707 m_collisionscore = 0;
1708
1709 UpdateCollisionCatFlags();
1710 ApplyCollisionCatFlags();
1711
1669 if (m_isSelected || m_disabled) 1712 if (m_isSelected || m_disabled)
1670 { 1713 {
1671 m_collisionCategories &= ~CollisionCategories.Body;
1672 m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
1673
1674 d.GeomDisable(prim_geom);
1675 d.BodyDisable(Body); 1714 d.BodyDisable(Body);
1676 } 1715 }
1677 else 1716 else
1678 { 1717 {
1679 if (m_isphantom && !m_isVolumeDetect)
1680 {
1681 m_collisionCategories = 0;
1682 m_collisionFlags = CollisionCategories.Land;
1683 }
1684 else
1685 {
1686 m_collisionCategories |= CollisionCategories.Body;
1687 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1688 }
1689
1690 d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); 1718 d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z);
1691 d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); 1719 d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
1692 } 1720 }
1693 1721
1694 if (m_NoColide)
1695 {
1696 d.GeomSetCategoryBits(prim_geom, 0);
1697 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
1698 }
1699 else
1700 {
1701 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1702 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1703 }
1704
1705 m_collisionscore = 0;
1706
1707 m_softcolide = true;
1708 _parent_scene.addActivePrim(this); 1722 _parent_scene.addActivePrim(this);
1709 _parent_scene.addActiveGroups(this); 1723 _parent_scene.addActiveGroups(this);
1710 } 1724 }
@@ -1714,8 +1728,22 @@ namespace OpenSim.Region.Physics.OdePlugin
1714 if (Body != IntPtr.Zero) 1728 if (Body != IntPtr.Zero)
1715 { 1729 {
1716 _parent_scene.remActivePrim(this); 1730 _parent_scene.remActivePrim(this);
1717 m_collisionCategories &= ~CollisionCategories.Body; 1731
1718 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 1732 collide_geom = IntPtr.Zero;
1733
1734 if (m_disabled)
1735 m_collisionCategories = 0;
1736 else if (m_isSelected)
1737 m_collisionCategories = CollisionCategories.Selected;
1738 else if (m_isVolumeDetect)
1739 m_collisionCategories = CollisionCategories.VolumeDtc;
1740 else if (m_isphantom)
1741 m_collisionCategories = CollisionCategories.Phantom;
1742 else
1743 m_collisionCategories = CollisionCategories.Geom;
1744
1745 m_collisionFlags = 0;
1746
1719 if (prim_geom != IntPtr.Zero) 1747 if (prim_geom != IntPtr.Zero)
1720 { 1748 {
1721 if (m_NoColide) 1749 if (m_NoColide)
@@ -1725,8 +1753,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1725 } 1753 }
1726 else 1754 else
1727 { 1755 {
1728 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1756 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
1729 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1757 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
1730 } 1758 }
1731 UpdateDataFromGeom(); 1759 UpdateDataFromGeom();
1732 d.GeomSetBody(prim_geom, IntPtr.Zero); 1760 d.GeomSetBody(prim_geom, IntPtr.Zero);
@@ -1740,8 +1768,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1740 foreach (OdePrim prm in childrenPrim) 1768 foreach (OdePrim prm in childrenPrim)
1741 { 1769 {
1742 _parent_scene.remActivePrim(prm); 1770 _parent_scene.remActivePrim(prm);
1743 prm.m_collisionCategories = m_collisionCategories; 1771
1744 prm.m_collisionFlags = m_collisionFlags; 1772 if (prm.m_isSelected)
1773 prm.m_collisionCategories = CollisionCategories.Selected;
1774 else if (prm.m_isVolumeDetect)
1775 prm.m_collisionCategories = CollisionCategories.VolumeDtc;
1776 else if (prm.m_isphantom)
1777 prm.m_collisionCategories = CollisionCategories.Phantom;
1778 else
1779 prm.m_collisionCategories = CollisionCategories.Geom;
1780
1781 prm.m_collisionFlags = 0;
1782
1745 if (prm.prim_geom != IntPtr.Zero) 1783 if (prm.prim_geom != IntPtr.Zero)
1746 { 1784 {
1747 if (prm.m_NoColide) 1785 if (prm.m_NoColide)
@@ -1751,8 +1789,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1751 } 1789 }
1752 else 1790 else
1753 { 1791 {
1754 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); 1792 d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories);
1755 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); 1793 d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags);
1756 } 1794 }
1757 prm.UpdateDataFromGeom(); 1795 prm.UpdateDataFromGeom();
1758 SetInStaticSpace(prm); 1796 SetInStaticSpace(prm);
@@ -2292,6 +2330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2292 // keep using basic shape mass for now 2330 // keep using basic shape mass for now
2293 volume = CalculatePrimVolume(); 2331 volume = CalculatePrimVolume();
2294 2332
2333 primVolume = volume;
2295 primMass = m_density * volume; 2334 primMass = m_density * volume;
2296 2335
2297 if (primMass <= 0) 2336 if (primMass <= 0)
@@ -2515,12 +2554,13 @@ namespace OpenSim.Region.Physics.OdePlugin
2515 d.GeomSetQuaternion(prim_geom, ref myrot); 2554 d.GeomSetQuaternion(prim_geom, ref myrot);
2516 2555
2517 if (!m_isphysical) 2556 if (!m_isphysical)
2557 {
2518 SetInStaticSpace(this); 2558 SetInStaticSpace(this);
2519 } 2559 UpdateCollisionCatFlags();
2520 2560 ApplyCollisionCatFlags();
2521 if (m_isphysical && Body == IntPtr.Zero) 2561 }
2522 { 2562 else
2523 MakeBody(); 2563 MakeBody();
2524 } 2564 }
2525 } 2565 }
2526 2566
@@ -2602,86 +2642,12 @@ namespace OpenSim.Region.Physics.OdePlugin
2602 } 2642 }
2603 } 2643 }
2604 2644
2605
2606 private void changePhantomStatus(bool newval) 2645 private void changePhantomStatus(bool newval)
2607 { 2646 {
2608 m_isphantom = newval; 2647 m_isphantom = newval;
2609 2648
2610 if (m_isSelected) 2649 UpdateCollisionCatFlags();
2611 { 2650 ApplyCollisionCatFlags();
2612 m_collisionCategories = CollisionCategories.Selected;
2613 m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
2614 }
2615 else
2616 {
2617 if (m_isphantom && !m_isVolumeDetect)
2618 {
2619 m_collisionCategories = 0;
2620 if (m_isphysical)
2621 m_collisionFlags = CollisionCategories.Land;
2622 else
2623 m_collisionFlags = 0; // should never happen
2624 }
2625
2626 else
2627 {
2628 m_collisionCategories = CollisionCategories.Geom;
2629 if (m_isphysical)
2630 m_collisionCategories |= CollisionCategories.Body;
2631
2632 m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land;
2633
2634 if (m_collidesWater)
2635 m_collisionFlags |= CollisionCategories.Water;
2636 }
2637 }
2638
2639 if (!childPrim)
2640 {
2641 foreach (OdePrim prm in childrenPrim)
2642 {
2643 prm.m_collisionCategories = m_collisionCategories;
2644 prm.m_collisionFlags = m_collisionFlags;
2645
2646 if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero)
2647 {
2648 if (prm.m_NoColide)
2649 {
2650 d.GeomSetCategoryBits(prm.prim_geom, 0);
2651 if (m_isphysical)
2652 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
2653 else
2654 d.GeomSetCollideBits(prm.prim_geom, 0);
2655 }
2656 else
2657 {
2658 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
2659 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
2660 }
2661 if(!m_isSelected)
2662 d.GeomEnable(prm.prim_geom);
2663 }
2664 }
2665 }
2666
2667 if (!m_disabled && prim_geom != IntPtr.Zero)
2668 {
2669 if (m_NoColide)
2670 {
2671 d.GeomSetCategoryBits(prim_geom, 0);
2672 if (m_isphysical)
2673 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
2674 else
2675 d.GeomSetCollideBits(prim_geom, 0);
2676 }
2677 else
2678 {
2679 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
2680 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2681 }
2682 if(!m_isSelected)
2683 d.GeomEnable(prim_geom);
2684 }
2685 } 2651 }
2686 2652
2687 private void changeSelectedStatus(bool newval) 2653 private void changeSelectedStatus(bool newval)
@@ -2714,7 +2680,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2714 if (m_delaySelect || m_isphysical) 2680 if (m_delaySelect || m_isphysical)
2715 { 2681 {
2716 m_collisionCategories = CollisionCategories.Selected; 2682 m_collisionCategories = CollisionCategories.Selected;
2717 m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); 2683 m_collisionFlags = 0;
2718 2684
2719 if (!childPrim) 2685 if (!childPrim)
2720 { 2686 {
@@ -2733,10 +2699,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2733 } 2699 }
2734 else 2700 else
2735 { 2701 {
2736 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); 2702 d.GeomSetCategoryBits(prm.prim_geom, (uint)m_collisionCategories);
2737 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); 2703 d.GeomSetCollideBits(prm.prim_geom, (uint)m_collisionFlags);
2738 } 2704 }
2739 d.GeomDisable(prm.prim_geom);
2740 } 2705 }
2741 prm.m_delaySelect = false; 2706 prm.m_delaySelect = false;
2742 } 2707 }
@@ -2748,13 +2713,23 @@ namespace OpenSim.Region.Physics.OdePlugin
2748 { 2713 {
2749 d.GeomSetCategoryBits(prim_geom, 0); 2714 d.GeomSetCategoryBits(prim_geom, 0);
2750 d.GeomSetCollideBits(prim_geom, 0); 2715 d.GeomSetCollideBits(prim_geom, 0);
2716 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
2717 {
2718 d.GeomSetCategoryBits(collide_geom, 0);
2719 d.GeomSetCollideBits(collide_geom, 0);
2720 }
2721
2751 } 2722 }
2752 else 2723 else
2753 { 2724 {
2754 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 2725 d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories);
2755 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 2726 d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags);
2727 if (collide_geom != prim_geom && collide_geom != IntPtr.Zero)
2728 {
2729 d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories);
2730 d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags);
2731 }
2756 } 2732 }
2757 d.GeomDisable(prim_geom);
2758 } 2733 }
2759 2734
2760 m_delaySelect = false; 2735 m_delaySelect = false;
@@ -2769,75 +2744,10 @@ namespace OpenSim.Region.Physics.OdePlugin
2769 if (!childPrim && Body != IntPtr.Zero && !m_disabled) 2744 if (!childPrim && Body != IntPtr.Zero && !m_disabled)
2770 d.BodyEnable(Body); 2745 d.BodyEnable(Body);
2771 2746
2772 if (m_isphantom && !m_isVolumeDetect) 2747 UpdateCollisionCatFlags();
2773 { 2748 ApplyCollisionCatFlags();
2774 m_collisionCategories = 0;
2775 if(m_isphysical)
2776 m_collisionFlags = CollisionCategories.Land;
2777 else
2778 m_collisionFlags = 0;
2779 }
2780 else
2781 {
2782 m_collisionCategories = CollisionCategories.Geom;
2783 if (m_isphysical)
2784 m_collisionCategories |= CollisionCategories.Body;
2785
2786 m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land;
2787
2788 if (m_collidesWater)
2789 m_collisionFlags |= CollisionCategories.Water;
2790 }
2791
2792 if (!childPrim)
2793 {
2794 foreach (OdePrim prm in childrenPrim)
2795 {
2796 prm.m_collisionCategories = m_collisionCategories;
2797 prm.m_collisionFlags = m_collisionFlags;
2798
2799 if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero)
2800 {
2801 if (prm.m_NoColide)
2802 {
2803 d.GeomSetCategoryBits(prm.prim_geom, 0);
2804 if (m_isphysical)
2805 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
2806 else
2807 d.GeomSetCollideBits(prm.prim_geom, 0);
2808 }
2809 else
2810 {
2811 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
2812 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
2813 }
2814 d.GeomEnable(prm.prim_geom);
2815 }
2816 prm.m_delaySelect = false;
2817 prm.m_softcolide = true;
2818 }
2819 }
2820
2821 if (!m_disabled && prim_geom != IntPtr.Zero)
2822 {
2823 if (m_NoColide)
2824 {
2825 d.GeomSetCategoryBits(prim_geom, 0);
2826 if (m_isphysical)
2827 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
2828 else
2829 d.GeomSetCollideBits(prim_geom, 0);
2830 }
2831 else
2832 {
2833 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
2834 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2835 }
2836 d.GeomEnable(prim_geom);
2837 }
2838 2749
2839 m_delaySelect = false; 2750 m_delaySelect = false;
2840 m_softcolide = true;
2841 } 2751 }
2842 2752
2843 resetCollisionAccounting(); 2753 resetCollisionAccounting();
@@ -2890,7 +2800,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2890 if (givefakepos < 0) 2800 if (givefakepos < 0)
2891 givefakepos = 0; 2801 givefakepos = 0;
2892 // changeSelectedStatus(); 2802 // changeSelectedStatus();
2893 m_softcolide = true;
2894 resetCollisionAccounting(); 2803 resetCollisionAccounting();
2895 } 2804 }
2896 2805
@@ -2951,7 +2860,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2951 givefakeori--; 2860 givefakeori--;
2952 if (givefakeori < 0) 2861 if (givefakeori < 0)
2953 givefakeori = 0; 2862 givefakeori = 0;
2954 m_softcolide = true;
2955 resetCollisionAccounting(); 2863 resetCollisionAccounting();
2956 } 2864 }
2957 2865
@@ -3022,7 +2930,6 @@ namespace OpenSim.Region.Physics.OdePlugin
3022 if (givefakeori < 0) 2930 if (givefakeori < 0)
3023 givefakeori = 0; 2931 givefakeori = 0;
3024 2932
3025 m_softcolide = true;
3026 resetCollisionAccounting(); 2933 resetCollisionAccounting();
3027 } 2934 }
3028 2935
@@ -3111,17 +3018,25 @@ namespace OpenSim.Region.Physics.OdePlugin
3111 d.GeomSetQuaternion(prim_geom, ref myrot); 3018 d.GeomSetQuaternion(prim_geom, ref myrot);
3112 } 3019 }
3113 3020
3114 if (chp) 3021 if (m_isphysical)
3115 { 3022 {
3116 if (parent != null) 3023 if (chp)
3117 { 3024 {
3118 parent.MakeBody(); 3025 if (parent != null)
3026 {
3027 parent.MakeBody();
3028 }
3119 } 3029 }
3030 else
3031 MakeBody();
3120 } 3032 }
3033
3121 else 3034 else
3122 MakeBody(); 3035 {
3036 UpdateCollisionCatFlags();
3037 ApplyCollisionCatFlags();
3038 }
3123 3039
3124 m_softcolide = true;
3125 resetCollisionAccounting(); 3040 resetCollisionAccounting();
3126 } 3041 }
3127 3042
@@ -3142,18 +3057,8 @@ namespace OpenSim.Region.Physics.OdePlugin
3142 { 3057 {
3143 m_collidesWater = newval; 3058 m_collidesWater = newval;
3144 3059
3145 if (prim_geom != IntPtr.Zero && !m_isphantom) 3060 UpdateCollisionCatFlags();
3146 { 3061 ApplyCollisionCatFlags();
3147 if (m_collidesWater)
3148 {
3149 m_collisionFlags |= CollisionCategories.Water;
3150 }
3151 else
3152 {
3153 m_collisionFlags &= ~CollisionCategories.Water;
3154 }
3155 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
3156 }
3157 } 3062 }
3158 3063
3159 private void changeSetTorque(Vector3 newtorque) 3064 private void changeSetTorque(Vector3 newtorque)
@@ -3240,6 +3145,8 @@ namespace OpenSim.Region.Physics.OdePlugin
3240 private void changeVolumedetetion(bool newVolDtc) 3145 private void changeVolumedetetion(bool newVolDtc)
3241 { 3146 {
3242 m_isVolumeDetect = newVolDtc; 3147 m_isVolumeDetect = newVolDtc;
3148 UpdateCollisionCatFlags();
3149 ApplyCollisionCatFlags();
3243 } 3150 }
3244 3151
3245 protected void changeBuilding(bool newbuilding) 3152 protected void changeBuilding(bool newbuilding)
@@ -3320,288 +3227,306 @@ namespace OpenSim.Region.Physics.OdePlugin
3320 public void Move() 3227 public void Move()
3321 { 3228 {
3322 if (!childPrim && m_isphysical && Body != IntPtr.Zero && 3229 if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
3323 !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building && !m_outbounds) 3230 !m_disabled && !m_isSelected && !m_building && !m_outbounds)
3324 // !m_disabled && !m_isSelected && !m_building && !m_outbounds) 3231 // !m_disabled && !m_isSelected && !m_building && !m_outbounds)
3325 { 3232 {
3326// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009 3233 // if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
3327
3328 float timestep = _parent_scene.ODE_STEPSIZE;
3329 3234
3330 // check outside region 3235 if (d.BodyIsEnabled(Body))
3331 d.Vector3 lpos;
3332 d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
3333
3334 if (lpos.Z < -100 || lpos.Z > 100000f)
3335 { 3236 {
3336 m_outbounds = true; 3237 float timestep = _parent_scene.ODE_STEPSIZE;
3337 3238
3338 lpos.Z = Util.Clip(lpos.Z, -100f, 100000f); 3239 // check outside region
3339 _acceleration.X = 0; 3240 d.Vector3 lpos;
3340 _acceleration.Y = 0; 3241 d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
3341 _acceleration.Z = 0;
3342 3242
3343 _velocity.X = 0; 3243 if (lpos.Z < -100 || lpos.Z > 100000f)
3344 _velocity.Y = 0; 3244 {
3345 _velocity.Z = 0; 3245 m_outbounds = true;
3346 m_rotationalVelocity.X = 0;
3347 m_rotationalVelocity.Y = 0;
3348 m_rotationalVelocity.Z = 0;
3349 3246
3350 d.BodySetLinearVel(Body, 0, 0, 0); // stop it 3247 lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
3351 d.BodySetAngularVel(Body, 0, 0, 0); // stop it 3248 _acceleration.X = 0;
3352 d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere 3249 _acceleration.Y = 0;
3353 m_lastposition = _position; 3250 _acceleration.Z = 0;
3354 m_lastorientation = _orientation;
3355 3251
3356 base.RequestPhysicsterseUpdate(); 3252 _velocity.X = 0;
3253 _velocity.Y = 0;
3254 _velocity.Z = 0;
3255 m_rotationalVelocity.X = 0;
3256 m_rotationalVelocity.Y = 0;
3257 m_rotationalVelocity.Z = 0;
3357 3258
3358 m_throttleUpdates = false; 3259 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
3359 throttleCounter = 0; 3260 d.BodySetAngularVel(Body, 0, 0, 0); // stop it
3360 _zeroFlag = true; 3261 d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere
3262 m_lastposition = _position;
3263 m_lastorientation = _orientation;
3361 3264
3362 disableBodySoft(); // disable it and colisions 3265 base.RequestPhysicsterseUpdate();
3363 base.RaiseOutOfBounds(_position);
3364 return;
3365 }
3366 3266
3367 if (lpos.X < 0f) 3267 m_throttleUpdates = false;
3368 { 3268 throttleCounter = 0;
3369 _position.X = Util.Clip(lpos.X, -2f, -0.1f); 3269 _zeroFlag = true;
3370 m_outbounds = true;
3371 }
3372 else if(lpos.X > _parent_scene.WorldExtents.X)
3373 {
3374 _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
3375 m_outbounds = true;
3376 }
3377 if (lpos.Y < 0f)
3378 {
3379 _position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
3380 m_outbounds = true;
3381 }
3382 else if(lpos.Y > _parent_scene.WorldExtents.Y)
3383 {
3384 _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
3385 m_outbounds = true;
3386 }
3387 3270
3388 if(m_outbounds) 3271 disableBodySoft(); // disable it and colisions
3389 { 3272 base.RaiseOutOfBounds(_position);
3390 m_lastposition = _position; 3273 return;
3391 m_lastorientation = _orientation; 3274 }
3392 3275
3393 d.Vector3 dtmp = d.BodyGetAngularVel(Body); 3276 if (lpos.X < 0f)
3394 m_rotationalVelocity.X = dtmp.X; 3277 {
3395 m_rotationalVelocity.Y = dtmp.Y; 3278 _position.X = Util.Clip(lpos.X, -2f, -0.1f);
3396 m_rotationalVelocity.Z = dtmp.Z; 3279 m_outbounds = true;
3280 }
3281 else if (lpos.X > _parent_scene.WorldExtents.X)
3282 {
3283 _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
3284 m_outbounds = true;
3285 }
3286 if (lpos.Y < 0f)
3287 {
3288 _position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
3289 m_outbounds = true;
3290 }
3291 else if (lpos.Y > _parent_scene.WorldExtents.Y)
3292 {
3293 _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
3294 m_outbounds = true;
3295 }
3397 3296
3398 dtmp = d.BodyGetLinearVel(Body); 3297 if (m_outbounds)
3399 _velocity.X = dtmp.X; 3298 {
3400 _velocity.Y = dtmp.Y; 3299 m_lastposition = _position;
3401 _velocity.Z = dtmp.Z; 3300 m_lastorientation = _orientation;
3402 3301
3403 d.BodySetLinearVel(Body, 0, 0, 0); // stop it 3302 d.Vector3 dtmp = d.BodyGetAngularVel(Body);
3404 d.BodySetAngularVel(Body, 0, 0, 0); 3303 m_rotationalVelocity.X = dtmp.X;
3405 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 3304 m_rotationalVelocity.Y = dtmp.Y;
3406 disableBodySoft(); // stop collisions 3305 m_rotationalVelocity.Z = dtmp.Z;
3407 base.RequestPhysicsterseUpdate();
3408 return;
3409 }
3410 3306
3307 dtmp = d.BodyGetLinearVel(Body);
3308 _velocity.X = dtmp.X;
3309 _velocity.Y = dtmp.Y;
3310 _velocity.Z = dtmp.Z;
3411 3311
3412 float fx = 0; 3312 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
3413 float fy = 0; 3313 d.BodySetAngularVel(Body, 0, 0, 0);
3414 float fz = 0; 3314 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
3315 disableBodySoft(); // stop collisions
3316 base.RequestPhysicsterseUpdate();
3317 return;
3318 }
3415 3319
3416 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) 3320 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
3417 { 3321 {
3418 // 'VEHICLES' are dealt with in ODEDynamics.cs 3322 // 'VEHICLES' are dealt with in ODEDynamics.cs
3419 m_vehicle.Step(); 3323 m_vehicle.Step();
3420 } 3324 return;
3421 else 3325 }
3422 {
3423 float m_mass = _mass;
3424 3326
3425 // fz = 0f; 3327 else
3426 //m_log.Info(m_collisionFlags.ToString());
3427 if (m_usePID)
3428 { 3328 {
3429 3329
3430 // If the PID Controller isn't active then we set our force 3330 float fx = 0;
3431 // calculating base velocity to the current position 3331 float fy = 0;
3332 float fz = 0;
3432 3333
3433 if ((m_PIDTau < 1) && (m_PIDTau != 0)) 3334 float m_mass = _mass;
3434 {
3435 //PID_G = PID_G / m_PIDTau;
3436 m_PIDTau = 1;
3437 }
3438 3335
3439 if ((PID_G - m_PIDTau) <= 0) 3336 // fz = 0f;
3337 //m_log.Info(m_collisionFlags.ToString());
3338 if (m_usePID)
3440 { 3339 {
3441 PID_G = m_PIDTau + 1;
3442 }
3443 3340
3444 d.Vector3 vel = d.BodyGetLinearVel(Body); 3341 // If the PID Controller isn't active then we set our force
3445 d.Vector3 pos = d.BodyGetPosition(Body); 3342 // calculating base velocity to the current position
3446 _target_velocity =
3447 new Vector3(
3448 (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
3449 (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
3450 (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
3451 );
3452 3343
3453 // if velocity is zero, use position control; otherwise, velocity control 3344 if ((m_PIDTau < 1) && (m_PIDTau != 0))
3454 3345 {
3455 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) 3346 //PID_G = PID_G / m_PIDTau;
3456 { 3347 m_PIDTau = 1;
3457 // keep track of where we stopped. No more slippin' & slidin' 3348 }
3458
3459 // We only want to deactivate the PID Controller if we think we want to have our surrogate
3460 // react to the physics scene by moving it's position.
3461 // Avatar to Avatar collisions
3462 // Prim to avatar collisions
3463
3464 //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
3465 //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2);
3466 //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
3467 d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
3468 d.BodySetLinearVel(Body, 0, 0, 0);
3469 d.BodyAddForce(Body, 0, 0, fz);
3470 return;
3471 }
3472 else
3473 {
3474 _zeroFlag = false;
3475 3349
3476 // We're flying and colliding with something 3350 if ((PID_G - m_PIDTau) <= 0)
3477 fx = ((_target_velocity.X) - vel.X) * (PID_D); 3351 {
3478 fy = ((_target_velocity.Y) - vel.Y) * (PID_D); 3352 PID_G = m_PIDTau + 1;
3353 }
3479 3354
3480 // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; 3355 d.Vector3 vel = d.BodyGetLinearVel(Body);
3356 d.Vector3 pos = d.BodyGetPosition(Body);
3357 _target_velocity =
3358 new Vector3(
3359 (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
3360 (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
3361 (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
3362 );
3481 3363
3482 fz = ((_target_velocity.Z - vel.Z) * (PID_D)); 3364 // if velocity is zero, use position control; otherwise, velocity control
3483 }
3484 } // end if (m_usePID)
3485 3365
3486 // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller 3366 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
3487 else if (m_useHoverPID) 3367 {
3488 { 3368 // keep track of where we stopped. No more slippin' & slidin'
3489 //Console.WriteLine("Hover " + Name); 3369
3370 // We only want to deactivate the PID Controller if we think we want to have our surrogate
3371 // react to the physics scene by moving it's position.
3372 // Avatar to Avatar collisions
3373 // Prim to avatar collisions
3374
3375 //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
3376 //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2);
3377 //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
3378 d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
3379 d.BodySetLinearVel(Body, 0, 0, 0);
3380 d.BodyAddForce(Body, 0, 0, fz);
3381 return;
3382 }
3383 else
3384 {
3385 _zeroFlag = false;
3490 3386
3491 // If we're using the PID controller, then we have no gravity 3387 // We're flying and colliding with something
3388 fx = ((_target_velocity.X) - vel.X) * (PID_D);
3389 fy = ((_target_velocity.Y) - vel.Y) * (PID_D);
3492 3390
3493 // no lock; for now it's only called from within Simulate() 3391 // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
3494 3392
3495 // If the PID Controller isn't active then we set our force 3393 fz = ((_target_velocity.Z - vel.Z) * (PID_D));
3496 // calculating base velocity to the current position 3394 }
3395 } // end if (m_usePID)
3497 3396
3498 if ((m_PIDTau < 1)) 3397 // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller
3398 else if (m_useHoverPID)
3499 { 3399 {
3500 PID_G = PID_G / m_PIDTau; 3400 //Console.WriteLine("Hover " + Name);
3501 }
3502 3401
3503 if ((PID_G - m_PIDTau) <= 0) 3402 // If we're using the PID controller, then we have no gravity
3504 {
3505 PID_G = m_PIDTau + 1;
3506 }
3507 3403
3508 // Where are we, and where are we headed? 3404 // no lock; for now it's only called from within Simulate()
3509 d.Vector3 pos = d.BodyGetPosition(Body);
3510 d.Vector3 vel = d.BodyGetLinearVel(Body);
3511 3405
3512 // Non-Vehicles have a limited set of Hover options. 3406 // If the PID Controller isn't active then we set our force
3513 // determine what our target height really is based on HoverType 3407 // calculating base velocity to the current position
3514 switch (m_PIDHoverType) 3408
3515 { 3409 if ((m_PIDTau < 1))
3516 case PIDHoverType.Ground: 3410 {
3517 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); 3411 PID_G = PID_G / m_PIDTau;
3518 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; 3412 }
3519 break; 3413
3520 case PIDHoverType.GroundAndWater: 3414 if ((PID_G - m_PIDTau) <= 0)
3521 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); 3415 {
3522 m_waterHeight = _parent_scene.GetWaterLevel(); 3416 PID_G = m_PIDTau + 1;
3523 if (m_groundHeight > m_waterHeight) 3417 }
3524 { 3418
3419 // Where are we, and where are we headed?
3420 d.Vector3 pos = d.BodyGetPosition(Body);
3421 d.Vector3 vel = d.BodyGetLinearVel(Body);
3422
3423 // Non-Vehicles have a limited set of Hover options.
3424 // determine what our target height really is based on HoverType
3425 switch (m_PIDHoverType)
3426 {
3427 case PIDHoverType.Ground:
3428 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
3525 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; 3429 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
3526 } 3430 break;
3527 else 3431 case PIDHoverType.GroundAndWater:
3528 { 3432 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
3529 m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; 3433 m_waterHeight = _parent_scene.GetWaterLevel();
3530 } 3434 if (m_groundHeight > m_waterHeight)
3531 break; 3435 {
3436 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
3437 }
3438 else
3439 {
3440 m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
3441 }
3442 break;
3532 3443
3533 } // end switch (m_PIDHoverType) 3444 } // end switch (m_PIDHoverType)
3534 3445
3535 3446
3536 _target_velocity = 3447 _target_velocity =
3537 new Vector3(0.0f, 0.0f, 3448 new Vector3(0.0f, 0.0f,
3538 (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep) 3449 (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep)
3539 ); 3450 );
3540 3451
3541 // if velocity is zero, use position control; otherwise, velocity control 3452 // if velocity is zero, use position control; otherwise, velocity control
3542 3453
3543 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) 3454 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
3544 { 3455 {
3545 // keep track of where we stopped. No more slippin' & slidin' 3456 // keep track of where we stopped. No more slippin' & slidin'
3546 3457
3547 // We only want to deactivate the PID Controller if we think we want to have our surrogate 3458 // We only want to deactivate the PID Controller if we think we want to have our surrogate
3548 // react to the physics scene by moving it's position. 3459 // react to the physics scene by moving it's position.
3549 // Avatar to Avatar collisions 3460 // Avatar to Avatar collisions
3550 // Prim to avatar collisions 3461 // Prim to avatar collisions
3462
3463 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
3464 d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
3465 // ? d.BodyAddForce(Body, 0, 0, fz);
3466 return;
3467 }
3468 else
3469 {
3470 _zeroFlag = false;
3551 3471
3552 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); 3472 // We're flying and colliding with something
3553 d.BodySetLinearVel(Body, vel.X, vel.Y, 0); 3473 fz = ((_target_velocity.Z - vel.Z) * (PID_D));
3554 // ? d.BodyAddForce(Body, 0, 0, fz); 3474 }
3555 return;
3556 } 3475 }
3557 else 3476 else
3558 { 3477 {
3559 _zeroFlag = false; 3478 float b = (1.0f - m_buoyancy);
3560 3479 fx = _parent_scene.gravityx * b;
3561 // We're flying and colliding with something 3480 fy = _parent_scene.gravityy * b;
3562 fz = ((_target_velocity.Z - vel.Z) * (PID_D)); 3481 fz = _parent_scene.gravityz * b;
3563 } 3482 }
3564 }
3565 else
3566 {
3567 float b = (1.0f - m_buoyancy);
3568 fx = _parent_scene.gravityx * b;
3569 fy = _parent_scene.gravityy * b;
3570 fz = _parent_scene.gravityz * b;
3571 }
3572 3483
3573 fx *= m_mass; 3484 fx *= m_mass;
3574 fy *= m_mass; 3485 fy *= m_mass;
3575 fz *= m_mass; 3486 fz *= m_mass;
3576 3487
3577 // constant force 3488 // constant force
3578 fx += m_force.X; 3489 fx += m_force.X;
3579 fy += m_force.Y; 3490 fy += m_force.Y;
3580 fz += m_force.Z; 3491 fz += m_force.Z;
3581 3492
3582 fx += m_forceacc.X; 3493 fx += m_forceacc.X;
3583 fy += m_forceacc.Y; 3494 fy += m_forceacc.Y;
3584 fz += m_forceacc.Z; 3495 fz += m_forceacc.Z;
3585 3496
3586 m_forceacc = Vector3.Zero; 3497 m_forceacc = Vector3.Zero;
3587 3498
3588 //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); 3499 //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
3589 if (fx != 0 || fy != 0 || fz != 0) 3500 if (fx != 0 || fy != 0 || fz != 0)
3590 { 3501 {
3591 d.BodyAddForce(Body, fx, fy, fz); 3502 d.BodyAddForce(Body, fx, fy, fz);
3592 //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); 3503 //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz);
3593 } 3504 }
3594 3505
3595 Vector3 trq; 3506 Vector3 trq;
3507
3508 trq = _torque;
3509 trq += m_angularForceacc;
3510 m_angularForceacc = Vector3.Zero;
3511 if (trq.X != 0 || trq.Y != 0 || trq.Z != 0)
3512 {
3513 d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z);
3514 }
3596 3515
3597 trq = _torque;
3598 trq += m_angularForceacc;
3599 m_angularForceacc = Vector3.Zero;
3600 if (trq.X != 0 || trq.Y != 0 || trq.Z != 0)
3601 {
3602 d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z);
3603 } 3516 }
3517 }
3518 else // body disabled
3519 {
3520 // let vehicles sleep
3521 if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
3522 return;
3604 3523
3524 if (++bodydisablecontrol < 20)
3525 return;
3526
3527 bodydisablecontrol = 0;
3528 d.BodyEnable(Body);
3529 return;
3605 } 3530 }
3606 } 3531 }
3607 else 3532 else