aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs')
-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