diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 29 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 1069 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs | 326 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | 8 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 234 |
5 files changed, 937 insertions, 729 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 4266fda..b9bb06e 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | |||
@@ -115,12 +115,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
115 | private CollisionCategories m_collisionCategories = (CollisionCategories.Character); | 115 | private CollisionCategories m_collisionCategories = (CollisionCategories.Character); |
116 | 116 | ||
117 | // Default, Collide with Other Geometries, spaces, bodies and characters. | 117 | // Default, Collide with Other Geometries, spaces, bodies and characters. |
118 | private CollisionCategories m_collisionFlags = (CollisionCategories.Geom | 118 | private CollisionCategories m_collisionFlags = (CollisionCategories.Character |
119 | | CollisionCategories.Space | 119 | | CollisionCategories.Geom |
120 | | CollisionCategories.Body | ||
121 | | CollisionCategories.Character | ||
122 | ); | 120 | ); |
123 | // we do land collisions not ode | CollisionCategories.Land); | 121 | // we do land collisions not ode | CollisionCategories.Land); |
124 | public IntPtr Body = IntPtr.Zero; | 122 | public IntPtr Body = IntPtr.Zero; |
125 | private OdeScene _parent_scene; | 123 | private OdeScene _parent_scene; |
126 | public IntPtr Shell = IntPtr.Zero; | 124 | public IntPtr Shell = IntPtr.Zero; |
@@ -639,6 +637,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
639 | 637 | ||
640 | public override void SetMomentum(Vector3 momentum) | 638 | public override void SetMomentum(Vector3 momentum) |
641 | { | 639 | { |
640 | if (momentum.IsFinite()) | ||
641 | AddChange(changes.Momentum, momentum); | ||
642 | } | 642 | } |
643 | 643 | ||
644 | 644 | ||
@@ -663,8 +663,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
663 | } | 663 | } |
664 | Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH); | 664 | Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH); |
665 | 665 | ||
666 | d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); | 666 | d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories); |
667 | d.GeomSetCollideBits(Shell, (int)m_collisionFlags); | 667 | d.GeomSetCollideBits(Shell, (uint)m_collisionFlags); |
668 | 668 | ||
669 | d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); | 669 | d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH); |
670 | 670 | ||
@@ -759,7 +759,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
759 | _parent_scene.geom_name_map.Remove(Shell); | 759 | _parent_scene.geom_name_map.Remove(Shell); |
760 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); | 760 | _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); |
761 | d.GeomDestroy(Shell); | 761 | d.GeomDestroy(Shell); |
762 | _parent_scene.geom_name_map.Remove(Shell); | ||
763 | Shell = IntPtr.Zero; | 762 | Shell = IntPtr.Zero; |
764 | } | 763 | } |
765 | } | 764 | } |
@@ -1324,6 +1323,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1324 | } | 1323 | } |
1325 | } | 1324 | } |
1326 | 1325 | ||
1326 | // for now momentum is actually velocity | ||
1327 | private void changeMomentum(Vector3 newmomentum) | ||
1328 | { | ||
1329 | _velocity = newmomentum; | ||
1330 | _target_velocity = newmomentum; | ||
1331 | m_pidControllerActive = true; | ||
1332 | if (Body != IntPtr.Zero) | ||
1333 | d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); | ||
1334 | } | ||
1335 | |||
1327 | private void donullchange() | 1336 | private void donullchange() |
1328 | { | 1337 | { |
1329 | } | 1338 | } |
@@ -1395,6 +1404,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1395 | case changes.Size: | 1404 | case changes.Size: |
1396 | changeSize((Vector3)arg); | 1405 | changeSize((Vector3)arg); |
1397 | break; | 1406 | break; |
1407 | |||
1408 | case changes.Momentum: | ||
1409 | changeMomentum((Vector3)arg); | ||
1410 | break; | ||
1398 | /* not in use for now | 1411 | /* not in use for now |
1399 | case changes.Shape: | 1412 | case changes.Shape: |
1400 | changeShape((PrimitiveBaseShape)arg); | 1413 | changeShape((PrimitiveBaseShape)arg); |
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 |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs index 4b3f83b..e66580d 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs | |||
@@ -30,10 +30,11 @@ using System.Collections.Generic; | |||
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Runtime.InteropServices; | 31 | using System.Runtime.InteropServices; |
32 | using System.Text; | 32 | using System.Text; |
33 | using OpenMetaverse; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Physics.Manager; | 34 | using OpenSim.Region.Physics.Manager; |
35 | using OdeAPI; | 35 | using OdeAPI; |
36 | using log4net; | 36 | using log4net; |
37 | using OpenMetaverse; | ||
37 | 38 | ||
38 | namespace OpenSim.Region.Physics.OdePlugin | 39 | namespace OpenSim.Region.Physics.OdePlugin |
39 | { | 40 | { |
@@ -54,9 +55,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
54 | /// </summary> | 55 | /// </summary> |
55 | private OdeScene m_scene; | 56 | private OdeScene m_scene; |
56 | 57 | ||
57 | IntPtr ray; | 58 | IntPtr ray; // the ray. we only need one for our lifetime |
58 | 59 | ||
59 | private const int ColisionContactGeomsPerTest = 5; | 60 | private const int ColisionContactGeomsPerTest = 5; |
61 | private const int DefaultMaxCount = 25; | ||
62 | private const int MaxTimePerCallMS = 30; | ||
60 | 63 | ||
61 | /// <summary> | 64 | /// <summary> |
62 | /// ODE near callback delegate | 65 | /// ODE near callback delegate |
@@ -64,19 +67,22 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
64 | private d.NearCallback nearCallback; | 67 | private d.NearCallback nearCallback; |
65 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 68 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
66 | private List<ContactResult> m_contactResults = new List<ContactResult>(); | 69 | private List<ContactResult> m_contactResults = new List<ContactResult>(); |
70 | private RayFilterFlags CurrentRayFilter; | ||
71 | private int CurrentMaxCount; | ||
67 | 72 | ||
68 | public ODERayCastRequestManager(OdeScene pScene) | 73 | public ODERayCastRequestManager(OdeScene pScene) |
69 | { | 74 | { |
70 | m_scene = pScene; | 75 | m_scene = pScene; |
71 | nearCallback = near; | 76 | nearCallback = near; |
72 | ray = d.CreateRay(IntPtr.Zero, 1.0f); | 77 | ray = d.CreateRay(IntPtr.Zero, 1.0f); |
78 | d.GeomSetCategoryBits(ray,0); | ||
73 | } | 79 | } |
74 | 80 | ||
75 | /// <summary> | 81 | /// <summary> |
76 | /// Queues a raycast | 82 | /// Queues request for a raycast to all world |
77 | /// </summary> | 83 | /// </summary> |
78 | /// <param name="position">Origin of Ray</param> | 84 | /// <param name="position">Origin of Ray</param> |
79 | /// <param name="direction">Ray normal</param> | 85 | /// <param name="direction">Ray direction</param> |
80 | /// <param name="length">Ray length</param> | 86 | /// <param name="length">Ray length</param> |
81 | /// <param name="retMethod">Return method to send the results</param> | 87 | /// <param name="retMethod">Return method to send the results</param> |
82 | public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod) | 88 | public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod) |
@@ -84,14 +90,22 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
84 | ODERayRequest req = new ODERayRequest(); | 90 | ODERayRequest req = new ODERayRequest(); |
85 | req.geom = IntPtr.Zero; | 91 | req.geom = IntPtr.Zero; |
86 | req.callbackMethod = retMethod; | 92 | req.callbackMethod = retMethod; |
87 | req.Count = 0; | 93 | req.Count = DefaultMaxCount; |
88 | req.length = length; | 94 | req.length = length; |
89 | req.Normal = direction; | 95 | req.Normal = direction; |
90 | req.Origin = position; | 96 | req.Origin = position; |
97 | req.filter = RayFilterFlags.AllButLand; | ||
91 | 98 | ||
92 | m_PendingRequests.Enqueue(req); | 99 | m_PendingRequests.Enqueue(req); |
93 | } | 100 | } |
94 | 101 | ||
102 | /// <summary> | ||
103 | /// Queues request for a raycast to particular part | ||
104 | /// </summary> | ||
105 | /// <param name="position">Origin of Ray</param> | ||
106 | /// <param name="direction">Ray direction</param> | ||
107 | /// <param name="length">Ray length</param> | ||
108 | /// <param name="retMethod">Return method to send the results</param> | ||
95 | public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod) | 109 | public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod) |
96 | { | 110 | { |
97 | ODERayRequest req = new ODERayRequest(); | 111 | ODERayRequest req = new ODERayRequest(); |
@@ -100,7 +114,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
100 | req.length = length; | 114 | req.length = length; |
101 | req.Normal = direction; | 115 | req.Normal = direction; |
102 | req.Origin = position; | 116 | req.Origin = position; |
103 | req.Count = 0; | 117 | req.Count = DefaultMaxCount; |
118 | req.filter = RayFilterFlags.AllButLand; | ||
104 | 119 | ||
105 | m_PendingRequests.Enqueue(req); | 120 | m_PendingRequests.Enqueue(req); |
106 | } | 121 | } |
@@ -110,10 +125,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
110 | ODERayRequest req = new ODERayRequest(); | 125 | ODERayRequest req = new ODERayRequest(); |
111 | req.geom = IntPtr.Zero; | 126 | req.geom = IntPtr.Zero; |
112 | req.callbackMethod = retMethod; | 127 | req.callbackMethod = retMethod; |
113 | req.Count = 0; | 128 | req.Count = DefaultMaxCount; |
114 | req.length = length; | 129 | req.length = length; |
115 | req.Normal = direction; | 130 | req.Normal = direction; |
116 | req.Origin = position; | 131 | req.Origin = position; |
132 | req.filter = RayFilterFlags.AllButLand; | ||
117 | 133 | ||
118 | m_PendingRequests.Enqueue(req); | 134 | m_PendingRequests.Enqueue(req); |
119 | } | 135 | } |
@@ -126,7 +142,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
126 | req.length = length; | 142 | req.length = length; |
127 | req.Normal = direction; | 143 | req.Normal = direction; |
128 | req.Origin = position; | 144 | req.Origin = position; |
129 | req.Count = 0; | 145 | req.Count = DefaultMaxCount; |
146 | req.filter = RayFilterFlags.AllButLand; | ||
130 | 147 | ||
131 | m_PendingRequests.Enqueue(req); | 148 | m_PendingRequests.Enqueue(req); |
132 | } | 149 | } |
@@ -148,6 +165,22 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
148 | req.Normal = direction; | 165 | req.Normal = direction; |
149 | req.Origin = position; | 166 | req.Origin = position; |
150 | req.Count = count; | 167 | req.Count = count; |
168 | req.filter = RayFilterFlags.AllButLand; | ||
169 | |||
170 | m_PendingRequests.Enqueue(req); | ||
171 | } | ||
172 | |||
173 | |||
174 | public void QueueRequest(Vector3 position, Vector3 direction, float length, int count,RayFilterFlags filter , RayCallback retMethod) | ||
175 | { | ||
176 | ODERayRequest req = new ODERayRequest(); | ||
177 | req.geom = IntPtr.Zero; | ||
178 | req.callbackMethod = retMethod; | ||
179 | req.length = length; | ||
180 | req.Normal = direction; | ||
181 | req.Origin = position; | ||
182 | req.Count = count; | ||
183 | req.filter = filter; | ||
151 | 184 | ||
152 | m_PendingRequests.Enqueue(req); | 185 | m_PendingRequests.Enqueue(req); |
153 | } | 186 | } |
@@ -161,6 +194,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
161 | req.Normal = direction; | 194 | req.Normal = direction; |
162 | req.Origin = position; | 195 | req.Origin = position; |
163 | req.Count = count; | 196 | req.Count = count; |
197 | req.filter = RayFilterFlags.AllButLand; | ||
164 | 198 | ||
165 | m_PendingRequests.Enqueue(req); | 199 | m_PendingRequests.Enqueue(req); |
166 | } | 200 | } |
@@ -174,6 +208,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
174 | req.Normal = direction; | 208 | req.Normal = direction; |
175 | req.Origin = position; | 209 | req.Origin = position; |
176 | req.Count = count; | 210 | req.Count = count; |
211 | req.filter = RayFilterFlags.AllButLand; | ||
177 | 212 | ||
178 | m_PendingRequests.Enqueue(req); | 213 | m_PendingRequests.Enqueue(req); |
179 | } | 214 | } |
@@ -187,6 +222,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
187 | req.Normal = direction; | 222 | req.Normal = direction; |
188 | req.Origin = position; | 223 | req.Origin = position; |
189 | req.Count = count; | 224 | req.Count = count; |
225 | req.filter = RayFilterFlags.AllButLand; | ||
190 | 226 | ||
191 | m_PendingRequests.Enqueue(req); | 227 | m_PendingRequests.Enqueue(req); |
192 | } | 228 | } |
@@ -197,63 +233,104 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
197 | /// <returns>Time in MS the raycasts took to process.</returns> | 233 | /// <returns>Time in MS the raycasts took to process.</returns> |
198 | public int ProcessQueuedRequests() | 234 | public int ProcessQueuedRequests() |
199 | { | 235 | { |
200 | int time = System.Environment.TickCount; | ||
201 | 236 | ||
202 | if (m_PendingRequests.Count <= 0) | 237 | if (m_PendingRequests.Count <= 0) |
203 | return 0; | 238 | return 0; |
204 | 239 | ||
205 | if (m_scene.ContactgeomsArray == IntPtr.Zero) // oops something got wrong or scene isn't ready still | 240 | if (m_scene.ContactgeomsArray == IntPtr.Zero || ray == IntPtr.Zero) |
241 | // oops something got wrong or scene isn't ready still | ||
206 | { | 242 | { |
207 | m_PendingRequests.Clear(); | 243 | m_PendingRequests.Clear(); |
208 | return 0; | 244 | return 0; |
209 | } | 245 | } |
210 | 246 | ||
211 | ODERayRequest req; | 247 | int time = Util.EnvironmentTickCount(); |
212 | 248 | ||
213 | int i = 50; // arbitary limit of processed tests per frame | 249 | ODERayRequest req; |
250 | int closestHit; | ||
251 | int backfacecull; | ||
252 | CollisionCategories catflags; | ||
214 | 253 | ||
215 | while(m_PendingRequests.Dequeue(out req)) | 254 | while (m_PendingRequests.Dequeue(out req)) |
216 | { | 255 | { |
217 | if (req.geom == IntPtr.Zero) | 256 | if (req.callbackMethod != null) |
218 | doSpaceRay(req); | 257 | { |
219 | else | 258 | CurrentRayFilter = req.filter; |
220 | doGeomRay(req); | 259 | CurrentMaxCount = req.Count; |
221 | if(--i < 0) | 260 | |
222 | break; | 261 | closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1); |
262 | backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1); | ||
263 | |||
264 | d.GeomRaySetLength(ray, req.length); | ||
265 | d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); | ||
266 | d.GeomRaySetParams(ray, 0, backfacecull); | ||
267 | d.GeomRaySetClosestHit(ray, closestHit); | ||
268 | |||
269 | if (req.callbackMethod is RaycastCallback) | ||
270 | // if we only want one get only one per colision pair saving memory | ||
271 | CurrentRayFilter |= RayFilterFlags.ClosestHit; | ||
272 | |||
273 | if (req.geom == IntPtr.Zero) | ||
274 | { | ||
275 | // translate ray filter to colision flags | ||
276 | catflags = 0; | ||
277 | if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0) | ||
278 | catflags |= CollisionCategories.VolumeDtc; | ||
279 | if ((CurrentRayFilter & RayFilterFlags.phantom) != 0) | ||
280 | catflags |= CollisionCategories.Phantom; | ||
281 | if ((CurrentRayFilter & RayFilterFlags.agent) != 0) | ||
282 | catflags |= CollisionCategories.Character; | ||
283 | if ((CurrentRayFilter & RayFilterFlags.PrimsNonPhantom) != 0) | ||
284 | catflags |= CollisionCategories.Geom; | ||
285 | if ((CurrentRayFilter & RayFilterFlags.land) != 0) | ||
286 | catflags |= CollisionCategories.Land; | ||
287 | if ((CurrentRayFilter & RayFilterFlags.water) != 0) | ||
288 | catflags |= CollisionCategories.Water; | ||
289 | |||
290 | if (catflags != 0) | ||
291 | doSpaceRay(req); | ||
292 | } | ||
293 | else | ||
294 | { | ||
295 | // if we select a geom don't use filters | ||
296 | d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); | ||
297 | doGeomRay(req); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | if (Util.EnvironmentTickCountSubtract(time) > MaxTimePerCallMS) | ||
302 | break; | ||
223 | } | 303 | } |
224 | 304 | ||
225 | lock (m_contactResults) | 305 | lock (m_contactResults) |
226 | m_contactResults.Clear(); | 306 | m_contactResults.Clear(); |
227 | 307 | ||
228 | return System.Environment.TickCount - time; | 308 | return Util.EnvironmentTickCountSubtract(time); |
229 | } | 309 | } |
230 | /// <summary> | 310 | /// <summary> |
231 | /// Method that actually initiates the raycast with full top space | 311 | /// Method that actually initiates the raycast with spaces |
232 | /// </summary> | 312 | /// </summary> |
233 | /// <param name="req"></param> | 313 | /// <param name="req"></param> |
234 | private void doSpaceRay(ODERayRequest req) | 314 | /// |
235 | { | ||
236 | // Create the ray | ||
237 | // IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length); | ||
238 | d.GeomRaySetLength(ray, req.length); | ||
239 | d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); | ||
240 | 315 | ||
241 | // Collide test | 316 | private const RayFilterFlags FilterActiveSpace = RayFilterFlags.agent | RayFilterFlags.physical | RayFilterFlags.LSLPhanton; |
242 | d.SpaceCollide2(m_scene.TopSpace, ray, IntPtr.Zero, nearCallback); | 317 | private const RayFilterFlags FilterStaticSpace = RayFilterFlags.water | RayFilterFlags.land | RayFilterFlags.nonphysical | RayFilterFlags.LSLPhanton; |
243 | |||
244 | // Remove Ray | ||
245 | // d.GeomDestroy(ray); | ||
246 | 318 | ||
247 | if (req.callbackMethod == null) | 319 | private void doSpaceRay(ODERayRequest req) |
248 | return; | 320 | { |
321 | // Collide tests | ||
322 | if ((CurrentRayFilter & FilterActiveSpace) != 0) | ||
323 | d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); | ||
324 | if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) | ||
325 | d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback); | ||
249 | 326 | ||
250 | if (req.callbackMethod is RaycastCallback) | 327 | if (req.callbackMethod is RaycastCallback) |
251 | { | 328 | { |
252 | // Define default results | 329 | // Define default results |
253 | bool hitYN = false; | 330 | bool hitYN = false; |
254 | uint hitConsumerID = 0; | 331 | uint hitConsumerID = 0; |
255 | float distance = 999999999999f; | 332 | float distance = float.MaxValue; |
256 | Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f); | 333 | Vector3 closestcontact = Vector3.Zero; |
257 | Vector3 snormal = Vector3.Zero; | 334 | Vector3 snormal = Vector3.Zero; |
258 | 335 | ||
259 | // Find closest contact and object. | 336 | // Find closest contact and object. |
@@ -261,25 +338,30 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
261 | { | 338 | { |
262 | foreach (ContactResult cResult in m_contactResults) | 339 | foreach (ContactResult cResult in m_contactResults) |
263 | { | 340 | { |
264 | if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact)) | 341 | if(cResult.Depth < distance) |
265 | { | 342 | { |
266 | closestcontact = cResult.Pos; | 343 | closestcontact = cResult.Pos; |
267 | hitConsumerID = cResult.ConsumerID; | 344 | hitConsumerID = cResult.ConsumerID; |
268 | distance = cResult.Depth; | 345 | distance = cResult.Depth; |
269 | hitYN = true; | ||
270 | snormal = cResult.Normal; | 346 | snormal = cResult.Normal; |
271 | } | 347 | } |
272 | } | 348 | } |
273 | m_contactResults.Clear(); | 349 | m_contactResults.Clear(); |
274 | } | 350 | } |
275 | 351 | ||
352 | if (distance > 0 && distance < float.MaxValue) | ||
353 | hitYN = true; | ||
276 | ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal); | 354 | ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal); |
277 | } | 355 | } |
278 | else | 356 | else |
279 | { | 357 | { |
280 | ((RayCallback)req.callbackMethod)(m_contactResults); | 358 | List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count); |
281 | lock (m_PendingRequests) | 359 | lock (m_PendingRequests) |
360 | { | ||
361 | cresult.AddRange(m_contactResults); | ||
282 | m_contactResults.Clear(); | 362 | m_contactResults.Clear(); |
363 | } | ||
364 | ((RayCallback)req.callbackMethod)(cresult); | ||
283 | } | 365 | } |
284 | } | 366 | } |
285 | 367 | ||
@@ -289,27 +371,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
289 | /// <param name="req"></param> | 371 | /// <param name="req"></param> |
290 | private void doGeomRay(ODERayRequest req) | 372 | private void doGeomRay(ODERayRequest req) |
291 | { | 373 | { |
292 | // Create the ray | ||
293 | // IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length); | ||
294 | d.GeomRaySetLength(ray, req.length); | ||
295 | d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); | ||
296 | |||
297 | // Collide test | 374 | // Collide test |
298 | d.SpaceCollide2(req.geom, ray, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test | 375 | d.SpaceCollide2(ray, req.geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test |
299 | |||
300 | // Remove Ray | ||
301 | // d.GeomDestroy(ray); | ||
302 | |||
303 | if (req.callbackMethod == null) | ||
304 | return; | ||
305 | 376 | ||
306 | if (req.callbackMethod is RaycastCallback) | 377 | if (req.callbackMethod is RaycastCallback) |
307 | { | 378 | { |
308 | // Define default results | 379 | // Define default results |
309 | bool hitYN = false; | 380 | bool hitYN = false; |
310 | uint hitConsumerID = 0; | 381 | uint hitConsumerID = 0; |
311 | float distance = 999999999999f; | 382 | float distance = float.MaxValue; |
312 | Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f); | 383 | Vector3 closestcontact = Vector3.Zero; |
313 | Vector3 snormal = Vector3.Zero; | 384 | Vector3 snormal = Vector3.Zero; |
314 | 385 | ||
315 | // Find closest contact and object. | 386 | // Find closest contact and object. |
@@ -317,25 +388,31 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
317 | { | 388 | { |
318 | foreach (ContactResult cResult in m_contactResults) | 389 | foreach (ContactResult cResult in m_contactResults) |
319 | { | 390 | { |
320 | if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact)) | 391 | if(cResult.Depth < distance ) |
321 | { | 392 | { |
322 | closestcontact = cResult.Pos; | 393 | closestcontact = cResult.Pos; |
323 | hitConsumerID = cResult.ConsumerID; | 394 | hitConsumerID = cResult.ConsumerID; |
324 | distance = cResult.Depth; | 395 | distance = cResult.Depth; |
325 | hitYN = true; | ||
326 | snormal = cResult.Normal; | 396 | snormal = cResult.Normal; |
327 | } | 397 | } |
328 | } | 398 | } |
329 | m_contactResults.Clear(); | 399 | m_contactResults.Clear(); |
330 | } | 400 | } |
331 | 401 | ||
402 | if (distance > 0 && distance < float.MaxValue) | ||
403 | hitYN = true; | ||
404 | |||
332 | ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal); | 405 | ((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal); |
333 | } | 406 | } |
334 | else | 407 | else |
335 | { | 408 | { |
336 | ((RayCallback)req.callbackMethod)(m_contactResults); | 409 | List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count); |
337 | lock (m_PendingRequests) | 410 | lock (m_PendingRequests) |
411 | { | ||
412 | cresult.AddRange(m_contactResults); | ||
338 | m_contactResults.Clear(); | 413 | m_contactResults.Clear(); |
414 | } | ||
415 | ((RayCallback)req.callbackMethod)(cresult); | ||
339 | } | 416 | } |
340 | } | 417 | } |
341 | 418 | ||
@@ -350,20 +427,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
350 | return true; | 427 | return true; |
351 | } | 428 | } |
352 | 429 | ||
353 | // This is the standard Near. g2 is the ray | 430 | // This is the standard Near. g1 is the ray |
354 | private void near(IntPtr space, IntPtr g1, IntPtr g2) | 431 | private void near(IntPtr space, IntPtr g1, IntPtr g2) |
355 | { | 432 | { |
356 | //Don't test against heightfield Geom, or you'll be sorry! | 433 | if (g2 == IntPtr.Zero || g1 == g2) |
357 | // Exclude heightfield geom | ||
358 | |||
359 | if (g1 == IntPtr.Zero || g1 == g2) | ||
360 | return; | 434 | return; |
361 | 435 | ||
362 | if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass) | 436 | if (m_contactResults.Count >= CurrentMaxCount) |
363 | return; | 437 | return; |
364 | 438 | ||
365 | // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. | 439 | if (d.GeomIsSpace(g2)) |
366 | if (d.GeomIsSpace(g1)) | ||
367 | { | 440 | { |
368 | try | 441 | try |
369 | { | 442 | { |
@@ -381,10 +454,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
381 | { | 454 | { |
382 | count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); | 455 | count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); |
383 | } | 456 | } |
384 | catch (SEHException) | ||
385 | { | ||
386 | m_log.Error("[PHYSICS Ray]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); | ||
387 | } | ||
388 | catch (Exception e) | 457 | catch (Exception e) |
389 | { | 458 | { |
390 | m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message); | 459 | m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message); |
@@ -394,31 +463,116 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
394 | if (count == 0) | 463 | if (count == 0) |
395 | return; | 464 | return; |
396 | 465 | ||
397 | PhysicsActor p1 = null; | 466 | uint ID = 0; |
467 | PhysicsActor p2 = null; | ||
468 | |||
469 | m_scene.actor_name_map.TryGetValue(g2, out p2); | ||
470 | |||
471 | if (p2 == null) | ||
472 | { | ||
473 | string name; | ||
474 | |||
475 | if (!m_scene.geom_name_map.TryGetValue(g2, out name)) | ||
476 | return; | ||
477 | |||
478 | if (name == "Terrain") | ||
479 | { | ||
480 | // land colision | ||
481 | if ((CurrentRayFilter & RayFilterFlags.land) == 0) | ||
482 | return; | ||
483 | } | ||
484 | else if (name == "Water") | ||
485 | { | ||
486 | if ((CurrentRayFilter & RayFilterFlags.water) == 0) | ||
487 | return; | ||
488 | } | ||
489 | else | ||
490 | return; | ||
491 | } | ||
492 | else | ||
493 | { | ||
494 | if (p2 is OdePrim) | ||
495 | { | ||
496 | RayFilterFlags thisFlags; | ||
497 | |||
498 | if (p2.IsPhysical) | ||
499 | thisFlags = RayFilterFlags.physical; | ||
500 | else | ||
501 | thisFlags = RayFilterFlags.nonphysical; | ||
398 | 502 | ||
399 | if (g1 != IntPtr.Zero) | 503 | if (p2.Phantom) |
400 | m_scene.actor_name_map.TryGetValue(g1, out p1); | 504 | thisFlags |= RayFilterFlags.phantom; |
505 | |||
506 | if (p2.IsVolumeDtc) | ||
507 | thisFlags |= RayFilterFlags.volumedtc; | ||
508 | |||
509 | if ((thisFlags & CurrentRayFilter) == 0) | ||
510 | return; | ||
511 | |||
512 | ID = ((OdePrim)p2).m_localID; | ||
513 | } | ||
514 | else if (p2 is OdeCharacter) | ||
515 | { | ||
516 | if ((CurrentRayFilter & RayFilterFlags.agent) == 0) | ||
517 | return; | ||
518 | else | ||
519 | ID = ((OdeCharacter)p2).m_localID; | ||
520 | } | ||
521 | else //?? | ||
522 | return; | ||
523 | } | ||
401 | 524 | ||
402 | d.ContactGeom curcontact = new d.ContactGeom(); | 525 | d.ContactGeom curcontact = new d.ContactGeom(); |
403 | // Loop over contacts, build results. | 526 | |
404 | for (int i = 0; i < count; i++) | 527 | // closestHit for now only works for meshs, so must do it for others |
528 | if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0) | ||
405 | { | 529 | { |
406 | if (!GetCurContactGeom(i, ref curcontact)) | 530 | // Loop all contacts, build results. |
407 | break; | 531 | for (int i = 0; i < count; i++) |
408 | if (p1 != null) { | 532 | { |
409 | if (p1 is OdePrim) | 533 | if (!GetCurContactGeom(i, ref curcontact)) |
534 | break; | ||
535 | |||
536 | ContactResult collisionresult = new ContactResult(); | ||
537 | collisionresult.ConsumerID = ID; | ||
538 | collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z); | ||
539 | collisionresult.Depth = curcontact.depth; | ||
540 | collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y, | ||
541 | curcontact.normal.Z); | ||
542 | lock (m_contactResults) | ||
543 | { | ||
544 | m_contactResults.Add(collisionresult); | ||
545 | if (m_contactResults.Count >= CurrentMaxCount) | ||
546 | return; | ||
547 | } | ||
548 | } | ||
549 | } | ||
550 | else | ||
551 | { | ||
552 | // keep only closest contact | ||
553 | ContactResult collisionresult = new ContactResult(); | ||
554 | collisionresult.ConsumerID = ID; | ||
555 | collisionresult.Depth = float.MaxValue; | ||
556 | |||
557 | for (int i = 0; i < count; i++) | ||
558 | { | ||
559 | if (!GetCurContactGeom(i, ref curcontact)) | ||
560 | break; | ||
561 | |||
562 | if (curcontact.depth < collisionresult.Depth) | ||
410 | { | 563 | { |
411 | ContactResult collisionresult = new ContactResult(); | ||
412 | |||
413 | collisionresult.ConsumerID = ((OdePrim)p1).m_localID; | ||
414 | collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z); | 564 | collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z); |
415 | collisionresult.Depth = curcontact.depth; | 565 | collisionresult.Depth = curcontact.depth; |
416 | collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y, | 566 | collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y, |
417 | curcontact.normal.Z); | 567 | curcontact.normal.Z); |
418 | lock (m_contactResults) | ||
419 | m_contactResults.Add(collisionresult); | ||
420 | } | 568 | } |
421 | } | 569 | } |
570 | |||
571 | if (collisionresult.Depth != float.MaxValue) | ||
572 | { | ||
573 | lock (m_contactResults) | ||
574 | m_contactResults.Add(collisionresult); | ||
575 | } | ||
422 | } | 576 | } |
423 | } | 577 | } |
424 | 578 | ||
@@ -428,6 +582,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
428 | internal void Dispose() | 582 | internal void Dispose() |
429 | { | 583 | { |
430 | m_scene = null; | 584 | m_scene = null; |
585 | if (ray != IntPtr.Zero) | ||
586 | { | ||
587 | d.GeomDestroy(ray); | ||
588 | ray = IntPtr.Zero; | ||
589 | } | ||
431 | } | 590 | } |
432 | } | 591 | } |
433 | 592 | ||
@@ -439,5 +598,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
439 | public int Count; | 598 | public int Count; |
440 | public float length; | 599 | public float length; |
441 | public object callbackMethod; | 600 | public object callbackMethod; |
601 | public RayFilterFlags filter; | ||
442 | } | 602 | } |
443 | } \ No newline at end of file | 603 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs index f5129cb..0e4961b 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | |||
@@ -889,13 +889,13 @@ namespace OdeAPI | |||
889 | public static extern IntPtr GeomGetBody(IntPtr geom); | 889 | public static extern IntPtr GeomGetBody(IntPtr geom); |
890 | 890 | ||
891 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity] | 891 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity] |
892 | public static extern int GeomGetCategoryBits(IntPtr geom); | 892 | public static extern uint GeomGetCategoryBits(IntPtr geom); |
893 | 893 | ||
894 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity] | 894 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity] |
895 | public static extern IntPtr GeomGetClassData(IntPtr geom); | 895 | public static extern IntPtr GeomGetClassData(IntPtr geom); |
896 | 896 | ||
897 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity] | 897 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity] |
898 | public static extern int GeomGetCollideBits(IntPtr geom); | 898 | public static extern uint GeomGetCollideBits(IntPtr geom); |
899 | 899 | ||
900 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity] | 900 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity] |
901 | public static extern GeomClassID GeomGetClass(IntPtr geom); | 901 | public static extern GeomClassID GeomGetClass(IntPtr geom); |
@@ -1086,10 +1086,10 @@ namespace OdeAPI | |||
1086 | public static extern void GeomSetBody(IntPtr geom, IntPtr body); | 1086 | public static extern void GeomSetBody(IntPtr geom, IntPtr body); |
1087 | 1087 | ||
1088 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity] | 1088 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity] |
1089 | public static extern void GeomSetCategoryBits(IntPtr geom, int bits); | 1089 | public static extern void GeomSetCategoryBits(IntPtr geom, uint bits); |
1090 | 1090 | ||
1091 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity] | 1091 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity] |
1092 | public static extern void GeomSetCollideBits(IntPtr geom, int bits); | 1092 | public static extern void GeomSetCollideBits(IntPtr geom, uint bits); |
1093 | 1093 | ||
1094 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity] | 1094 | [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity] |
1095 | public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); | 1095 | public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 3e0ccef..7632e25 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | |||
@@ -60,19 +60,31 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
60 | public int lastframe; | 60 | public int lastframe; |
61 | } | 61 | } |
62 | 62 | ||
63 | // colision flags of things others can colide with | ||
64 | // rays, sensors, probes removed since can't be colided with | ||
65 | // The top space where things are placed provided further selection | ||
66 | // ie physical are in active space nonphysical in static | ||
67 | // this should be exclusive as possible | ||
68 | |||
63 | [Flags] | 69 | [Flags] |
64 | public enum CollisionCategories : int | 70 | public enum CollisionCategories : uint |
65 | { | 71 | { |
66 | Disabled = 0, | 72 | Disabled = 0, |
67 | Geom = 0x00000001, | 73 | //by 'things' types |
68 | Body = 0x00000002, | 74 | Space = 0x01, |
69 | Space = 0x00000004, | 75 | Geom = 0x02, // aka prim/part |
70 | Character = 0x00000008, | 76 | Character = 0x04, |
71 | Land = 0x00000010, | 77 | Land = 0x08, |
72 | Water = 0x00000020, | 78 | Water = 0x010, |
73 | Wind = 0x00000040, | 79 | |
74 | Sensor = 0x00000080, | 80 | // by state |
75 | Selected = 0x00000100 | 81 | Phantom = 0x01000, |
82 | VolumeDtc = 0x02000, | ||
83 | Selected = 0x04000, | ||
84 | NoShape = 0x08000, | ||
85 | |||
86 | |||
87 | All = 0xffffffff | ||
76 | } | 88 | } |
77 | 89 | ||
78 | /// <summary> | 90 | /// <summary> |
@@ -116,6 +128,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
116 | Acceleration, | 128 | Acceleration, |
117 | Force, | 129 | Force, |
118 | Torque, | 130 | Torque, |
131 | Momentum, | ||
119 | 132 | ||
120 | AddForce, | 133 | AddForce, |
121 | AddAngForce, | 134 | AddAngForce, |
@@ -186,7 +199,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
186 | private float waterlevel = 0f; | 199 | private float waterlevel = 0f; |
187 | private int framecount = 0; | 200 | private int framecount = 0; |
188 | 201 | ||
189 | internal IntPtr WaterGeom; | 202 | private IntPtr WaterGeom = IntPtr.Zero; |
203 | private IntPtr WaterHeightmapData = IntPtr.Zero; | ||
204 | private GCHandle WaterMapHandler = new GCHandle(); | ||
190 | 205 | ||
191 | public float avPIDD = 2200f; // make it visible | 206 | public float avPIDD = 2200f; // make it visible |
192 | public float avPIDP = 900f; // make it visible | 207 | public float avPIDP = 900f; // make it visible |
@@ -213,9 +228,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
213 | 228 | ||
214 | // public int geomCrossingFailuresBeforeOutofbounds = 6; | 229 | // public int geomCrossingFailuresBeforeOutofbounds = 6; |
215 | 230 | ||
216 | public int bodyFramesAutoDisable = 20; | 231 | public int bodyFramesAutoDisable = 5; |
217 | 232 | ||
218 | private float[] _watermap; | ||
219 | 233 | ||
220 | private d.NearCallback nearCallback; | 234 | private d.NearCallback nearCallback; |
221 | 235 | ||
@@ -350,7 +364,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
350 | // i must RtC#FM | 364 | // i must RtC#FM |
351 | } | 365 | } |
352 | 366 | ||
353 | d.HashSpaceSetLevels(TopSpace, -2, 8); // cell sizes from .25 to 256 ?? need check what this really does | 367 | d.HashSpaceSetLevels(TopSpace, -2, 8); |
354 | d.HashSpaceSetLevels(ActiveSpace, -2, 8); | 368 | d.HashSpaceSetLevels(ActiveSpace, -2, 8); |
355 | d.HashSpaceSetLevels(StaticSpace, -2, 8); | 369 | d.HashSpaceSetLevels(StaticSpace, -2, 8); |
356 | 370 | ||
@@ -358,13 +372,27 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
358 | d.SpaceSetSublevel(ActiveSpace, 1); | 372 | d.SpaceSetSublevel(ActiveSpace, 1); |
359 | d.SpaceSetSublevel(StaticSpace, 1); | 373 | d.SpaceSetSublevel(StaticSpace, 1); |
360 | 374 | ||
375 | d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | | ||
376 | CollisionCategories.Geom | | ||
377 | CollisionCategories.Character | | ||
378 | CollisionCategories.Phantom | | ||
379 | CollisionCategories.VolumeDtc | ||
380 | )); | ||
381 | d.GeomSetCollideBits(ActiveSpace, 0); | ||
382 | d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space | | ||
383 | CollisionCategories.Geom | | ||
384 | CollisionCategories.Land | | ||
385 | CollisionCategories.Water | | ||
386 | CollisionCategories.Phantom | | ||
387 | CollisionCategories.VolumeDtc | ||
388 | )); | ||
389 | d.GeomSetCollideBits(StaticSpace, 0); | ||
390 | |||
361 | contactgroup = d.JointGroupCreate(0); | 391 | contactgroup = d.JointGroupCreate(0); |
362 | //contactgroup | 392 | //contactgroup |
363 | 393 | ||
364 | d.WorldSetAutoDisableFlag(world, false); | 394 | d.WorldSetAutoDisableFlag(world, false); |
365 | } | 395 | } |
366 | |||
367 | _watermap = new float[258 * 258]; | ||
368 | } | 396 | } |
369 | 397 | ||
370 | // Initialize the mesh plugin | 398 | // Initialize the mesh plugin |
@@ -374,15 +402,18 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
374 | // checkThread(); | 402 | // checkThread(); |
375 | mesher = meshmerizer; | 403 | mesher = meshmerizer; |
376 | m_config = config; | 404 | m_config = config; |
377 | 405 | /* | |
378 | string ode_config = d.GetConfiguration("ODE"); | 406 | string ode_config = d.GetConfiguration("ODE"); |
379 | m_log.WarnFormat("ODE configuration: {0}", ode_config); | 407 | if (ode_config != null && ode_config != "") |
380 | |||
381 | if (ode_config.Contains("ODE_Ubit")) | ||
382 | { | 408 | { |
383 | OdeUbitLib = true; | 409 | m_log.WarnFormat("ODE configuration: {0}", ode_config); |
384 | } | ||
385 | 410 | ||
411 | if (ode_config.Contains("ODE_Ubit")) | ||
412 | { | ||
413 | OdeUbitLib = true; | ||
414 | } | ||
415 | } | ||
416 | */ | ||
386 | /* | 417 | /* |
387 | if (region != null) | 418 | if (region != null) |
388 | { | 419 | { |
@@ -518,6 +549,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
518 | waitForSpaceUnlock(newspace); | 549 | waitForSpaceUnlock(newspace); |
519 | d.SpaceSetSublevel(newspace, 2); | 550 | d.SpaceSetSublevel(newspace, 2); |
520 | d.HashSpaceSetLevels(newspace, -2, 8); | 551 | d.HashSpaceSetLevels(newspace, -2, 8); |
552 | d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space | | ||
553 | CollisionCategories.Geom | | ||
554 | CollisionCategories.Land | | ||
555 | CollisionCategories.Water | | ||
556 | CollisionCategories.Phantom | | ||
557 | CollisionCategories.VolumeDtc | ||
558 | )); | ||
559 | d.GeomSetCollideBits(newspace, 0); | ||
560 | |||
521 | staticPrimspace[i, j] = newspace; | 561 | staticPrimspace[i, j] = newspace; |
522 | } | 562 | } |
523 | // let this now be real maximum values | 563 | // let this now be real maximum values |
@@ -1745,8 +1785,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1745 | 1785 | ||
1746 | m_rayCastManager.ProcessQueuedRequests(); | 1786 | m_rayCastManager.ProcessQueuedRequests(); |
1747 | 1787 | ||
1748 | |||
1749 | |||
1750 | statray += Util.EnvironmentTickCountSubtract(statstart); | 1788 | statray += Util.EnvironmentTickCountSubtract(statstart); |
1751 | collision_optimized(); | 1789 | collision_optimized(); |
1752 | statcol += Util.EnvironmentTickCountSubtract(statstart); | 1790 | statcol += Util.EnvironmentTickCountSubtract(statstart); |
@@ -2125,14 +2163,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2125 | RegionTerrain.Remove(pOffset); | 2163 | RegionTerrain.Remove(pOffset); |
2126 | if (GroundGeom != IntPtr.Zero) | 2164 | if (GroundGeom != IntPtr.Zero) |
2127 | { | 2165 | { |
2166 | d.GeomDestroy(GroundGeom); | ||
2167 | |||
2128 | if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) | 2168 | if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) |
2129 | { | 2169 | { |
2130 | TerrainHeightFieldHeightsHandlers[GroundGeom].Free(); | 2170 | TerrainHeightFieldHeightsHandlers[GroundGeom].Free(); |
2131 | TerrainHeightFieldHeightsHandlers.Remove(GroundGeom); | 2171 | TerrainHeightFieldHeightsHandlers.Remove(GroundGeom); |
2132 | TerrainHeightFieldHeights.Remove(GroundGeom); | 2172 | TerrainHeightFieldHeights.Remove(GroundGeom); |
2133 | } | 2173 | } |
2134 | d.SpaceRemove(StaticSpace, GroundGeom); | ||
2135 | d.GeomDestroy(GroundGeom); | ||
2136 | } | 2174 | } |
2137 | } | 2175 | } |
2138 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); | 2176 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); |
@@ -2147,8 +2185,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2147 | GroundGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1); | 2185 | GroundGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1); |
2148 | if (GroundGeom != IntPtr.Zero) | 2186 | if (GroundGeom != IntPtr.Zero) |
2149 | { | 2187 | { |
2150 | d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); | 2188 | d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land)); |
2151 | d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); | 2189 | d.GeomSetCollideBits(GroundGeom, 0); |
2152 | 2190 | ||
2153 | } | 2191 | } |
2154 | geom_name_map[GroundGeom] = "Terrain"; | 2192 | geom_name_map[GroundGeom] = "Terrain"; |
@@ -2236,14 +2274,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2236 | RegionTerrain.Remove(pOffset); | 2274 | RegionTerrain.Remove(pOffset); |
2237 | if (GroundGeom != IntPtr.Zero) | 2275 | if (GroundGeom != IntPtr.Zero) |
2238 | { | 2276 | { |
2277 | d.GeomDestroy(GroundGeom); | ||
2278 | |||
2239 | if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) | 2279 | if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) |
2240 | { | 2280 | { |
2241 | TerrainHeightFieldHeightsHandlers[GroundGeom].Free(); | 2281 | if (TerrainHeightFieldHeightsHandlers[GroundGeom].IsAllocated) |
2282 | TerrainHeightFieldHeightsHandlers[GroundGeom].Free(); | ||
2242 | TerrainHeightFieldHeightsHandlers.Remove(GroundGeom); | 2283 | TerrainHeightFieldHeightsHandlers.Remove(GroundGeom); |
2243 | TerrainHeightFieldHeights.Remove(GroundGeom); | 2284 | TerrainHeightFieldHeights.Remove(GroundGeom); |
2244 | } | 2285 | } |
2245 | d.SpaceRemove(StaticSpace, GroundGeom); | ||
2246 | d.GeomDestroy(GroundGeom); | ||
2247 | } | 2286 | } |
2248 | } | 2287 | } |
2249 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); | 2288 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); |
@@ -2263,8 +2302,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2263 | GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1); | 2302 | GroundGeom = d.CreateUbitTerrain(StaticSpace, HeightmapData, 1); |
2264 | if (GroundGeom != IntPtr.Zero) | 2303 | if (GroundGeom != IntPtr.Zero) |
2265 | { | 2304 | { |
2266 | d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); | 2305 | d.GeomSetCategoryBits(GroundGeom, (uint)(CollisionCategories.Land)); |
2267 | d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); | 2306 | d.GeomSetCollideBits(GroundGeom, 0); |
2268 | 2307 | ||
2269 | } | 2308 | } |
2270 | geom_name_map[GroundGeom] = "Terrain"; | 2309 | geom_name_map[GroundGeom] = "Terrain"; |
@@ -2359,57 +2398,76 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2359 | 2398 | ||
2360 | public void randomizeWater(float baseheight) | 2399 | public void randomizeWater(float baseheight) |
2361 | { | 2400 | { |
2362 | const uint heightmapWidth = m_regionWidth + 2; | 2401 | const uint heightmapWidth = Constants.RegionSize + 2; |
2363 | const uint heightmapHeight = m_regionHeight + 2; | 2402 | const uint heightmapHeight = Constants.RegionSize + 2; |
2364 | const uint heightmapWidthSamples = m_regionWidth + 2; | 2403 | const uint heightmapWidthSamples = heightmapWidth + 1; |
2365 | const uint heightmapHeightSamples = m_regionHeight + 2; | 2404 | const uint heightmapHeightSamples = heightmapHeight + 1; |
2405 | |||
2366 | const float scale = 1.0f; | 2406 | const float scale = 1.0f; |
2367 | const float offset = 0.0f; | 2407 | const float offset = 0.0f; |
2368 | const float thickness = 2.9f; | ||
2369 | const int wrap = 0; | 2408 | const int wrap = 0; |
2370 | 2409 | ||
2371 | for (int i = 0; i < (258 * 258); i++) | 2410 | float[] _watermap = new float[heightmapWidthSamples * heightmapWidthSamples]; |
2411 | |||
2412 | float maxheigh = float.MinValue; | ||
2413 | float minheigh = float.MaxValue; | ||
2414 | float val; | ||
2415 | for (int i = 0; i < (heightmapWidthSamples * heightmapHeightSamples); i++) | ||
2372 | { | 2416 | { |
2373 | _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f); | 2417 | |
2374 | // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f)); | 2418 | val = (baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f); |
2419 | _watermap[i] = val; | ||
2420 | if (maxheigh < val) | ||
2421 | maxheigh = val; | ||
2422 | if (minheigh > val) | ||
2423 | minheigh = val; | ||
2375 | } | 2424 | } |
2376 | 2425 | ||
2426 | float thickness = minheigh; | ||
2427 | |||
2377 | lock (OdeLock) | 2428 | lock (OdeLock) |
2378 | { | 2429 | { |
2379 | if (WaterGeom != IntPtr.Zero) | 2430 | if (WaterGeom != IntPtr.Zero) |
2380 | { | 2431 | { |
2381 | d.SpaceRemove(StaticSpace, WaterGeom); | 2432 | d.GeomDestroy(WaterGeom); |
2433 | d.GeomHeightfieldDataDestroy(WaterHeightmapData); | ||
2434 | WaterGeom = IntPtr.Zero; | ||
2435 | WaterHeightmapData = IntPtr.Zero; | ||
2436 | if(WaterMapHandler.IsAllocated) | ||
2437 | WaterMapHandler.Free(); | ||
2382 | } | 2438 | } |
2383 | IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); | 2439 | |
2384 | d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight, | 2440 | WaterHeightmapData = d.GeomHeightfieldDataCreate(); |
2441 | |||
2442 | WaterMapHandler = GCHandle.Alloc(_watermap, GCHandleType.Pinned); | ||
2443 | |||
2444 | d.GeomHeightfieldDataBuildSingle(WaterHeightmapData, WaterMapHandler.AddrOfPinnedObject(), 0, heightmapWidth, heightmapHeight, | ||
2385 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, | 2445 | (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, |
2386 | offset, thickness, wrap); | 2446 | offset, thickness, wrap); |
2387 | d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight); | 2447 | d.GeomHeightfieldDataSetBounds(WaterHeightmapData, minheigh, maxheigh); |
2388 | WaterGeom = d.CreateHeightfield(StaticSpace, HeightmapData, 1); | 2448 | WaterGeom = d.CreateHeightfield(StaticSpace, WaterHeightmapData, 1); |
2389 | if (WaterGeom != IntPtr.Zero) | 2449 | if (WaterGeom != IntPtr.Zero) |
2390 | { | 2450 | { |
2391 | d.GeomSetCategoryBits(WaterGeom, (int)(CollisionCategories.Water)); | 2451 | d.GeomSetCategoryBits(WaterGeom, (uint)(CollisionCategories.Water)); |
2392 | d.GeomSetCollideBits(WaterGeom, (int)(CollisionCategories.Space)); | 2452 | d.GeomSetCollideBits(WaterGeom, 0); |
2393 | 2453 | ||
2394 | } | 2454 | geom_name_map[WaterGeom] = "Water"; |
2395 | geom_name_map[WaterGeom] = "Water"; | ||
2396 | 2455 | ||
2397 | d.Matrix3 R = new d.Matrix3(); | 2456 | d.Matrix3 R = new d.Matrix3(); |
2398 | 2457 | ||
2399 | Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); | 2458 | Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); |
2400 | Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); | 2459 | Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); |
2401 | 2460 | ||
2402 | q1 = q1 * q2; | 2461 | q1 = q1 * q2; |
2403 | Vector3 v3; | 2462 | Vector3 v3; |
2404 | float angle; | 2463 | float angle; |
2405 | q1.GetAxisAngle(out v3, out angle); | 2464 | q1.GetAxisAngle(out v3, out angle); |
2406 | 2465 | ||
2407 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); | 2466 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); |
2408 | d.GeomSetRotation(WaterGeom, ref R); | 2467 | d.GeomSetRotation(WaterGeom, ref R); |
2409 | d.GeomSetPosition(WaterGeom, 128, 128, 0); | 2468 | d.GeomSetPosition(WaterGeom, (float)Constants.RegionSize * 0.5f, (float)Constants.RegionSize * 0.5f, 0); |
2410 | 2469 | } | |
2411 | } | 2470 | } |
2412 | |||
2413 | } | 2471 | } |
2414 | 2472 | ||
2415 | public override void Dispose() | 2473 | public override void Dispose() |
@@ -2427,11 +2485,34 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2427 | } | 2485 | } |
2428 | } | 2486 | } |
2429 | 2487 | ||
2488 | if (TerrainHeightFieldHeightsHandlers.Count > 0) | ||
2489 | { | ||
2490 | foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values) | ||
2491 | { | ||
2492 | if (gch.IsAllocated) | ||
2493 | gch.Free(); | ||
2494 | } | ||
2495 | } | ||
2496 | |||
2497 | if (WaterGeom != IntPtr.Zero) | ||
2498 | { | ||
2499 | d.GeomDestroy(WaterGeom); | ||
2500 | WaterGeom = IntPtr.Zero; | ||
2501 | if (WaterHeightmapData != IntPtr.Zero) | ||
2502 | d.GeomHeightfieldDataDestroy(WaterHeightmapData); | ||
2503 | WaterHeightmapData = IntPtr.Zero; | ||
2504 | |||
2505 | if (WaterMapHandler.IsAllocated) | ||
2506 | WaterMapHandler.Free(); | ||
2507 | } | ||
2508 | |||
2509 | |||
2430 | if (ContactgeomsArray != IntPtr.Zero) | 2510 | if (ContactgeomsArray != IntPtr.Zero) |
2431 | Marshal.FreeHGlobal(ContactgeomsArray); | 2511 | Marshal.FreeHGlobal(ContactgeomsArray); |
2432 | if (GlobalContactsArray != IntPtr.Zero) | 2512 | if (GlobalContactsArray != IntPtr.Zero) |
2433 | Marshal.FreeHGlobal(GlobalContactsArray); | 2513 | Marshal.FreeHGlobal(GlobalContactsArray); |
2434 | 2514 | ||
2515 | |||
2435 | d.WorldDestroy(world); | 2516 | d.WorldDestroy(world); |
2436 | //d.CloseODE(); | 2517 | //d.CloseODE(); |
2437 | } | 2518 | } |
@@ -2502,6 +2583,35 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2502 | return new List<ContactResult>(ourResults); | 2583 | return new List<ContactResult>(ourResults); |
2503 | } | 2584 | } |
2504 | 2585 | ||
2586 | public override bool SuportsRaycastWorldFiltered() | ||
2587 | { | ||
2588 | return true; | ||
2589 | } | ||
2590 | |||
2591 | public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) | ||
2592 | { | ||
2593 | object SyncObject = new object(); | ||
2594 | List<ContactResult> ourresults = new List<ContactResult>(); | ||
2595 | |||
2596 | RayCallback retMethod = delegate(List<ContactResult> results) | ||
2597 | { | ||
2598 | lock (SyncObject) | ||
2599 | { | ||
2600 | ourresults = results; | ||
2601 | Monitor.PulseAll(SyncObject); | ||
2602 | } | ||
2603 | }; | ||
2604 | |||
2605 | lock (SyncObject) | ||
2606 | { | ||
2607 | m_rayCastManager.QueueRequest(position, direction, length, Count,filter, retMethod); | ||
2608 | if (!Monitor.Wait(SyncObject, 500)) | ||
2609 | return null; | ||
2610 | else | ||
2611 | return ourresults; | ||
2612 | } | ||
2613 | } | ||
2614 | |||
2505 | public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) | 2615 | public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) |
2506 | { | 2616 | { |
2507 | if (retMethod != null && actor !=null) | 2617 | if (retMethod != null && actor !=null) |