diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 121 |
1 files changed, 97 insertions, 24 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 0323b0d..4dff927 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -70,6 +70,8 @@ public class BSPrim : BSPhysObject | |||
70 | private bool _kinematic; | 70 | private bool _kinematic; |
71 | private float _buoyancy; | 71 | private float _buoyancy; |
72 | 72 | ||
73 | private int CrossingFailures { get; set; } | ||
74 | |||
73 | public BSDynamics VehicleController { get; private set; } | 75 | public BSDynamics VehicleController { get; private set; } |
74 | 76 | ||
75 | private BSVMotor _targetMotor; | 77 | private BSVMotor _targetMotor; |
@@ -197,7 +199,20 @@ public class BSPrim : BSPhysObject | |||
197 | { | 199 | { |
198 | get { return _isSelected; } | 200 | get { return _isSelected; } |
199 | } | 201 | } |
200 | public override void CrossingFailure() { return; } | 202 | |
203 | public override void CrossingFailure() | ||
204 | { | ||
205 | CrossingFailures++; | ||
206 | if (CrossingFailures > BSParam.CrossingFailuresBeforeOutOfBounds) | ||
207 | { | ||
208 | base.RaiseOutOfBounds(RawPosition); | ||
209 | } | ||
210 | else if (CrossingFailures == BSParam.CrossingFailuresBeforeOutOfBounds) | ||
211 | { | ||
212 | m_log.WarnFormat("{0} Too many crossing failures for {1}", LogHeader, Name); | ||
213 | } | ||
214 | return; | ||
215 | } | ||
201 | 216 | ||
202 | // link me to the specified parent | 217 | // link me to the specified parent |
203 | public override void link(PhysicsActor obj) { | 218 | public override void link(PhysicsActor obj) { |
@@ -239,50 +254,98 @@ public class BSPrim : BSPhysObject | |||
239 | }); | 254 | }); |
240 | } | 255 | } |
241 | 256 | ||
257 | bool TryExperimentalLockAxisCode = false; | ||
258 | BSConstraint LockAxisConstraint = null; | ||
242 | public override void LockAngularMotion(OMV.Vector3 axis) | 259 | public override void LockAngularMotion(OMV.Vector3 axis) |
243 | { | 260 | { |
244 | DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); | 261 | DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); |
245 | 262 | ||
263 | // "1" means free, "0" means locked | ||
246 | OMV.Vector3 locking = new OMV.Vector3(1f, 1f, 1f); | 264 | OMV.Vector3 locking = new OMV.Vector3(1f, 1f, 1f); |
247 | if (axis.X != 1) locking.X = 0f; | 265 | if (axis.X != 1) locking.X = 0f; |
248 | if (axis.Y != 1) locking.Y = 0f; | 266 | if (axis.Y != 1) locking.Y = 0f; |
249 | if (axis.Z != 1) locking.Z = 0f; | 267 | if (axis.Z != 1) locking.Z = 0f; |
250 | LockedAxis = locking; | 268 | LockedAxis = locking; |
251 | 269 | ||
252 | /* Not implemented yet | 270 | if (TryExperimentalLockAxisCode && LockedAxis != LockedAxisFree) |
253 | if (LockedAxis != LockedAxisFree) | ||
254 | { | 271 | { |
255 | // Something is locked so start the thingy that keeps that axis from changing | 272 | // Lock that axis by creating a 6DOF constraint that has one end in the world and |
256 | RegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion", delegate(ref EntityProperties entprop) | 273 | // the other in the object. |
274 | // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817 | ||
275 | // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380 | ||
276 | |||
277 | PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate() | ||
257 | { | 278 | { |
258 | if (LockedAxis != LockedAxisFree) | 279 | CleanUpLockAxisPhysicals(true /* inTaintTime */); |
280 | |||
281 | BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(PhysicsScene.World, PhysBody, | ||
282 | OMV.Vector3.Zero, OMV.Quaternion.Inverse(RawOrientation), | ||
283 | true /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */); | ||
284 | LockAxisConstraint = axisConstrainer; | ||
285 | PhysicsScene.Constraints.AddConstraint(LockAxisConstraint); | ||
286 | |||
287 | // The constraint is tied to the world and oriented to the prim. | ||
288 | |||
289 | // Free to move linearly | ||
290 | OMV.Vector3 linearLow = OMV.Vector3.Zero; | ||
291 | OMV.Vector3 linearHigh = PhysicsScene.TerrainManager.DefaultRegionSize; | ||
292 | axisConstrainer.SetLinearLimits(linearLow, linearHigh); | ||
293 | |||
294 | // Angular with some axis locked | ||
295 | float f2PI = (float)Math.PI * 2f; | ||
296 | OMV.Vector3 angularLow = new OMV.Vector3(-f2PI, -f2PI, -f2PI); | ||
297 | OMV.Vector3 angularHigh = new OMV.Vector3(f2PI, f2PI, f2PI); | ||
298 | if (LockedAxis.X != 1f) | ||
259 | { | 299 | { |
260 | if (IsPhysicallyActive) | 300 | angularLow.X = 0f; |
261 | { | 301 | angularHigh.X = 0f; |
262 | // Bullet can lock axis but it only works for global axis. | ||
263 | // Check if this prim is aligned on global axis and use Bullet's | ||
264 | // system if so. | ||
265 | |||
266 | ForceOrientation = entprop.Rotation; | ||
267 | ForceRotationalVelocity = entprop.RotationalVelocity; | ||
268 | } | ||
269 | } | 302 | } |
270 | else | 303 | if (LockedAxis.Y != 1f) |
304 | { | ||
305 | angularLow.Y = 0f; | ||
306 | angularHigh.Y = 0f; | ||
307 | } | ||
308 | if (LockedAxis.Z != 1f) | ||
271 | { | 309 | { |
272 | UnRegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion"); | 310 | angularLow.Z = 0f; |
311 | angularHigh.Z = 0f; | ||
273 | } | 312 | } |
313 | axisConstrainer.SetAngularLimits(angularLow, angularHigh); | ||
314 | |||
315 | DetailLog("{0},BSPrim.LockAngularMotion,create,linLow={1},linHi={2},angLow={3},angHi={4}", | ||
316 | LocalID, linearLow, linearHigh, angularLow, angularHigh); | ||
274 | 317 | ||
318 | // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. | ||
319 | axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); | ||
320 | |||
321 | axisConstrainer.RecomputeConstraintVariables(RawMass); | ||
275 | }); | 322 | }); |
276 | } | 323 | } |
277 | else | 324 | else |
278 | { | 325 | { |
279 | // Everything seems unlocked | 326 | // Everything seems unlocked |
280 | UnRegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion"); | 327 | CleanUpLockAxisPhysicals(false /* inTaintTime */); |
281 | } | 328 | } |
282 | */ | ||
283 | 329 | ||
284 | return; | 330 | return; |
285 | } | 331 | } |
332 | // Get rid of any constraint built for LockAxis | ||
333 | // Most often the constraint is removed when the constraint collection is cleaned for this prim. | ||
334 | private void CleanUpLockAxisPhysicals(bool inTaintTime) | ||
335 | { | ||
336 | if (LockAxisConstraint != null) | ||
337 | { | ||
338 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.CleanUpLockAxisPhysicals", delegate() | ||
339 | { | ||
340 | if (LockAxisConstraint != null) | ||
341 | { | ||
342 | PhysicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint); | ||
343 | LockAxisConstraint = null; | ||
344 | DetailLog("{0},BSPrim.CleanUpLockAxisPhysicals,destroyingConstraint", LocalID); | ||
345 | } | ||
346 | }); | ||
347 | } | ||
348 | } | ||
286 | 349 | ||
287 | public override OMV.Vector3 RawPosition | 350 | public override OMV.Vector3 RawPosition |
288 | { | 351 | { |
@@ -762,6 +825,7 @@ public class BSPrim : BSPhysObject | |||
762 | SetObjectDynamic(true); | 825 | SetObjectDynamic(true); |
763 | // whether phys-to-static or static-to-phys, the object is not moving. | 826 | // whether phys-to-static or static-to-phys, the object is not moving. |
764 | ZeroMotion(true); | 827 | ZeroMotion(true); |
828 | |||
765 | }); | 829 | }); |
766 | } | 830 | } |
767 | } | 831 | } |
@@ -885,6 +949,8 @@ public class BSPrim : BSPhysObject | |||
885 | 949 | ||
886 | // For good measure, make sure the transform is set through to the motion state | 950 | // For good measure, make sure the transform is set through to the motion state |
887 | ForcePosition = _position; | 951 | ForcePosition = _position; |
952 | ForceVelocity = _velocity; | ||
953 | ForceRotationalVelocity = _rotationalVelocity; | ||
888 | 954 | ||
889 | // A dynamic object has mass | 955 | // A dynamic object has mass |
890 | UpdatePhysicalMassProperties(RawMass, false); | 956 | UpdatePhysicalMassProperties(RawMass, false); |
@@ -1064,15 +1130,19 @@ public class BSPrim : BSPhysObject | |||
1064 | _buoyancy = value; | 1130 | _buoyancy = value; |
1065 | // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 1131 | // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
1066 | // Force the recalculation of the various inertia,etc variables in the object | 1132 | // Force the recalculation of the various inertia,etc variables in the object |
1067 | DetailLog("{0},BSPrim.ForceBuoyancy,buoy={1},mass={2}", LocalID, _buoyancy, _mass); | 1133 | UpdatePhysicalMassProperties(RawMass, true); |
1068 | UpdatePhysicalMassProperties(_mass, true); | 1134 | DetailLog("{0},BSPrim.ForceBuoyancy,buoy={1},mass={2},grav={3}", LocalID, _buoyancy, RawMass, Gravity); |
1069 | ActivateIfPhysical(false); | 1135 | ActivateIfPhysical(false); |
1070 | } | 1136 | } |
1071 | } | 1137 | } |
1072 | 1138 | ||
1073 | // Used for MoveTo | 1139 | // Used for MoveTo |
1074 | public override OMV.Vector3 PIDTarget { | 1140 | public override OMV.Vector3 PIDTarget { |
1075 | set { _PIDTarget = value; } | 1141 | set |
1142 | { | ||
1143 | // TODO: add a sanity check -- don't move more than a region or something like that. | ||
1144 | _PIDTarget = value; | ||
1145 | } | ||
1076 | } | 1146 | } |
1077 | public override float PIDTau { | 1147 | public override float PIDTau { |
1078 | set { _PIDTau = value; } | 1148 | set { _PIDTau = value; } |
@@ -1126,7 +1196,9 @@ public class BSPrim : BSPhysObject | |||
1126 | } | 1196 | } |
1127 | else | 1197 | else |
1128 | { | 1198 | { |
1129 | ForcePosition = movePosition; | 1199 | _position = movePosition; |
1200 | PositionSanityCheck(true /* intaintTime */); | ||
1201 | ForcePosition = _position; | ||
1130 | } | 1202 | } |
1131 | DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", LocalID, origPosition, movePosition); | 1203 | DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", LocalID, origPosition, movePosition); |
1132 | }); | 1204 | }); |
@@ -1303,6 +1375,7 @@ public class BSPrim : BSPhysObject | |||
1303 | { | 1375 | { |
1304 | if (PhysBody.HasPhysicalBody) | 1376 | if (PhysBody.HasPhysicalBody) |
1305 | { | 1377 | { |
1378 | DetailLog("{0},BSPrim.AddAngularForce,taint,angForce={1}", LocalID, angForce); | ||
1306 | PhysicsScene.PE.ApplyTorque(PhysBody, angForce); | 1379 | PhysicsScene.PE.ApplyTorque(PhysBody, angForce); |
1307 | ActivateIfPhysical(false); | 1380 | ActivateIfPhysical(false); |
1308 | } | 1381 | } |
@@ -1667,7 +1740,7 @@ public class BSPrim : BSPhysObject | |||
1667 | // _velocity = entprop.Velocity; | 1740 | // _velocity = entprop.Velocity; |
1668 | // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be | 1741 | // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be |
1669 | // very sensitive to velocity changes. | 1742 | // very sensitive to velocity changes. |
1670 | if (!entprop.Velocity.ApproxEquals(_velocity, 0.1f)) | 1743 | if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(_velocity, 0.1f)) |
1671 | _velocity = entprop.Velocity; | 1744 | _velocity = entprop.Velocity; |
1672 | _acceleration = entprop.Acceleration; | 1745 | _acceleration = entprop.Acceleration; |
1673 | _rotationalVelocity = entprop.RotationalVelocity; | 1746 | _rotationalVelocity = entprop.RotationalVelocity; |