diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 172 |
1 files changed, 108 insertions, 64 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 400d5d6..79fe632 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -50,7 +50,10 @@ public sealed class BSPrim : BSPhysObject | |||
50 | private bool _grabbed; | 50 | private bool _grabbed; |
51 | private bool _isSelected; | 51 | private bool _isSelected; |
52 | private bool _isVolumeDetect; | 52 | private bool _isVolumeDetect; |
53 | |||
54 | // _position is what the simulator thinks the positions of the prim is. | ||
53 | private OMV.Vector3 _position; | 55 | private OMV.Vector3 _position; |
56 | |||
54 | private float _mass; // the mass of this object | 57 | private float _mass; // the mass of this object |
55 | private float _density; | 58 | private float _density; |
56 | private OMV.Vector3 _force; | 59 | private OMV.Vector3 _force; |
@@ -169,6 +172,7 @@ public sealed class BSPrim : BSPhysObject | |||
169 | public override PrimitiveBaseShape Shape { | 172 | public override PrimitiveBaseShape Shape { |
170 | set { | 173 | set { |
171 | BaseShape = value; | 174 | BaseShape = value; |
175 | LastAssetBuildFailed = false; | ||
172 | ForceBodyShapeRebuild(false); | 176 | ForceBodyShapeRebuild(false); |
173 | } | 177 | } |
174 | } | 178 | } |
@@ -178,7 +182,6 @@ public sealed class BSPrim : BSPhysObject | |||
178 | 182 | ||
179 | public override bool ForceBodyShapeRebuild(bool inTaintTime) | 183 | public override bool ForceBodyShapeRebuild(bool inTaintTime) |
180 | { | 184 | { |
181 | LastAssetBuildFailed = false; | ||
182 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() | 185 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() |
183 | { | 186 | { |
184 | _mass = CalculateMass(); // changing the shape changes the mass | 187 | _mass = CalculateMass(); // changing the shape changes the mass |
@@ -204,6 +207,10 @@ public sealed class BSPrim : BSPhysObject | |||
204 | } | 207 | } |
205 | } | 208 | } |
206 | } | 209 | } |
210 | public override bool IsSelected | ||
211 | { | ||
212 | get { return _isSelected; } | ||
213 | } | ||
207 | public override void CrossingFailure() { return; } | 214 | public override void CrossingFailure() { return; } |
208 | 215 | ||
209 | // link me to the specified parent | 216 | // link me to the specified parent |
@@ -290,7 +297,7 @@ public sealed class BSPrim : BSPhysObject | |||
290 | */ | 297 | */ |
291 | 298 | ||
292 | // don't do the GetObjectPosition for root elements because this function is called a zillion times. | 299 | // don't do the GetObjectPosition for root elements because this function is called a zillion times. |
293 | // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody); | 300 | // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement; |
294 | return _position; | 301 | return _position; |
295 | } | 302 | } |
296 | set { | 303 | set { |
@@ -316,18 +323,37 @@ public sealed class BSPrim : BSPhysObject | |||
316 | } | 323 | } |
317 | public override OMV.Vector3 ForcePosition { | 324 | public override OMV.Vector3 ForcePosition { |
318 | get { | 325 | get { |
319 | _position = PhysicsScene.PE.GetPosition(PhysBody); | 326 | _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement; |
320 | return _position; | 327 | return _position; |
321 | } | 328 | } |
322 | set { | 329 | set { |
323 | _position = value; | 330 | _position = value; |
324 | if (PhysBody.HasPhysicalBody) | 331 | if (PhysBody.HasPhysicalBody) |
325 | { | 332 | { |
326 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 333 | PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); |
327 | ActivateIfPhysical(false); | 334 | ActivateIfPhysical(false); |
328 | } | 335 | } |
329 | } | 336 | } |
330 | } | 337 | } |
338 | // Override to have position displacement immediately update the physical position. | ||
339 | // A feeble attempt to keep the sim and physical positions in sync | ||
340 | // Must be called at taint time. | ||
341 | public override OMV.Vector3 PositionDisplacement | ||
342 | { | ||
343 | get | ||
344 | { | ||
345 | return base.PositionDisplacement; | ||
346 | } | ||
347 | set | ||
348 | { | ||
349 | base.PositionDisplacement = value; | ||
350 | PhysicsScene.TaintedObject(PhysicsScene.InTaintTime, "BSPrim.setPosition", delegate() | ||
351 | { | ||
352 | if (PhysBody.HasPhysicalBody) | ||
353 | PhysicsScene.PE.SetTranslation(PhysBody, _position + base.PositionDisplacement, _orientation); | ||
354 | }); | ||
355 | } | ||
356 | } | ||
331 | 357 | ||
332 | // Check that the current position is sane and, if not, modify the position to make it so. | 358 | // Check that the current position is sane and, if not, modify the position to make it so. |
333 | // Check for being below terrain and being out of bounds. | 359 | // Check for being below terrain and being out of bounds. |
@@ -336,7 +362,7 @@ public sealed class BSPrim : BSPhysObject | |||
336 | { | 362 | { |
337 | bool ret = false; | 363 | bool ret = false; |
338 | 364 | ||
339 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) | 365 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) |
340 | { | 366 | { |
341 | // The physical object is out of the known/simulated area. | 367 | // The physical object is out of the known/simulated area. |
342 | // Upper levels of code will handle the transition to other areas so, for | 368 | // Upper levels of code will handle the transition to other areas so, for |
@@ -350,8 +376,11 @@ public sealed class BSPrim : BSPhysObject | |||
350 | { | 376 | { |
351 | DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); | 377 | DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); |
352 | float targetHeight = terrainHeight + (Size.Z / 2f); | 378 | float targetHeight = terrainHeight + (Size.Z / 2f); |
353 | // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. | 379 | // If the object is below ground it just has to be moved up because pushing will |
354 | upForce.Z = (terrainHeight - RawPosition.Z) * 1f; | 380 | // not get it through the terrain |
381 | _position.Z = targetHeight; | ||
382 | if (inTaintTime) | ||
383 | ForcePosition = _position; | ||
355 | ret = true; | 384 | ret = true; |
356 | } | 385 | } |
357 | 386 | ||
@@ -363,20 +392,15 @@ public sealed class BSPrim : BSPhysObject | |||
363 | { | 392 | { |
364 | // Upforce proportional to the distance away from the water. Correct the error in 1 sec. | 393 | // Upforce proportional to the distance away from the water. Correct the error in 1 sec. |
365 | upForce.Z = (waterHeight - RawPosition.Z) * 1f; | 394 | upForce.Z = (waterHeight - RawPosition.Z) * 1f; |
395 | |||
396 | // Apply upforce and overcome gravity. | ||
397 | OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; | ||
398 | DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); | ||
399 | AddForce(correctionForce, false, inTaintTime); | ||
366 | ret = true; | 400 | ret = true; |
367 | } | 401 | } |
368 | } | 402 | } |
369 | 403 | ||
370 | // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. | ||
371 | // TODO: This should be intergrated with a geneal physics action mechanism. | ||
372 | // TODO: This should be moderated with PID'ness. | ||
373 | if (ret) | ||
374 | { | ||
375 | // Apply upforce and overcome gravity. | ||
376 | OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; | ||
377 | DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); | ||
378 | AddForce(correctionForce, false, inTaintTime); | ||
379 | } | ||
380 | return ret; | 404 | return ret; |
381 | } | 405 | } |
382 | 406 | ||
@@ -410,7 +434,7 @@ public sealed class BSPrim : BSPhysObject | |||
410 | } | 434 | } |
411 | else | 435 | else |
412 | { | 436 | { |
413 | OMV.Vector3 grav = ComputeGravity(); | 437 | OMV.Vector3 grav = ComputeGravity(Buoyancy); |
414 | 438 | ||
415 | if (inWorld) | 439 | if (inWorld) |
416 | { | 440 | { |
@@ -445,12 +469,12 @@ public sealed class BSPrim : BSPhysObject | |||
445 | } | 469 | } |
446 | 470 | ||
447 | // Return what gravity should be set to this very moment | 471 | // Return what gravity should be set to this very moment |
448 | private OMV.Vector3 ComputeGravity() | 472 | public OMV.Vector3 ComputeGravity(float buoyancy) |
449 | { | 473 | { |
450 | OMV.Vector3 ret = PhysicsScene.DefaultGravity; | 474 | OMV.Vector3 ret = PhysicsScene.DefaultGravity; |
451 | 475 | ||
452 | if (!IsStatic) | 476 | if (!IsStatic) |
453 | ret *= (1f - Buoyancy); | 477 | ret *= (1f - buoyancy); |
454 | 478 | ||
455 | return ret; | 479 | return ret; |
456 | } | 480 | } |
@@ -586,6 +610,7 @@ public sealed class BSPrim : BSPhysObject | |||
586 | _velocity = value; | 610 | _velocity = value; |
587 | if (PhysBody.HasPhysicalBody) | 611 | if (PhysBody.HasPhysicalBody) |
588 | { | 612 | { |
613 | DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity); | ||
589 | PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); | 614 | PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); |
590 | ActivateIfPhysical(false); | 615 | ActivateIfPhysical(false); |
591 | } | 616 | } |
@@ -650,12 +675,7 @@ public sealed class BSPrim : BSPhysObject | |||
650 | 675 | ||
651 | PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() | 676 | PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() |
652 | { | 677 | { |
653 | if (PhysBody.HasPhysicalBody) | 678 | ForceOrientation = _orientation; |
654 | { | ||
655 | // _position = PhysicsScene.PE.GetObjectPosition(PhysicsScene.World, BSBody); | ||
656 | // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); | ||
657 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
658 | } | ||
659 | }); | 679 | }); |
660 | } | 680 | } |
661 | } | 681 | } |
@@ -670,7 +690,8 @@ public sealed class BSPrim : BSPhysObject | |||
670 | set | 690 | set |
671 | { | 691 | { |
672 | _orientation = value; | 692 | _orientation = value; |
673 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 693 | if (PhysBody.HasPhysicalBody) |
694 | PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); | ||
674 | } | 695 | } |
675 | } | 696 | } |
676 | public override int PhysicsActorType { | 697 | public override int PhysicsActorType { |
@@ -809,7 +830,7 @@ public sealed class BSPrim : BSPhysObject | |||
809 | // PhysicsScene.PE.ClearAllForces(BSBody); | 830 | // PhysicsScene.PE.ClearAllForces(BSBody); |
810 | 831 | ||
811 | // For good measure, make sure the transform is set through to the motion state | 832 | // For good measure, make sure the transform is set through to the motion state |
812 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 833 | PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); |
813 | 834 | ||
814 | // Center of mass is at the center of the object | 835 | // Center of mass is at the center of the object |
815 | // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation); | 836 | // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation); |
@@ -1153,33 +1174,70 @@ public sealed class BSPrim : BSPhysObject | |||
1153 | // This added force will only last the next simulation tick. | 1174 | // This added force will only last the next simulation tick. |
1154 | public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { | 1175 | public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { |
1155 | // for an object, doesn't matter if force is a pushforce or not | 1176 | // for an object, doesn't matter if force is a pushforce or not |
1156 | if (!IsStatic && force.IsFinite()) | 1177 | if (!IsStatic) |
1157 | { | 1178 | { |
1158 | float magnitude = force.Length(); | 1179 | if (force.IsFinite()) |
1159 | if (magnitude > BSParam.MaxAddForceMagnitude) | ||
1160 | { | 1180 | { |
1161 | // Force has a limit | 1181 | float magnitude = force.Length(); |
1162 | force = force / magnitude * BSParam.MaxAddForceMagnitude; | 1182 | if (magnitude > BSParam.MaxAddForceMagnitude) |
1163 | } | 1183 | { |
1184 | // Force has a limit | ||
1185 | force = force / magnitude * BSParam.MaxAddForceMagnitude; | ||
1186 | } | ||
1164 | 1187 | ||
1165 | OMV.Vector3 addForce = force; | 1188 | OMV.Vector3 addForce = force; |
1166 | // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); | 1189 | // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); |
1167 | 1190 | ||
1168 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() | 1191 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() |
1169 | { | ||
1170 | // Bullet adds this central force to the total force for this tick | ||
1171 | DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); | ||
1172 | if (PhysBody.HasPhysicalBody) | ||
1173 | { | 1192 | { |
1174 | PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); | 1193 | // Bullet adds this central force to the total force for this tick |
1175 | ActivateIfPhysical(false); | 1194 | DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); |
1176 | } | 1195 | if (PhysBody.HasPhysicalBody) |
1177 | }); | 1196 | { |
1197 | PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); | ||
1198 | ActivateIfPhysical(false); | ||
1199 | } | ||
1200 | }); | ||
1201 | } | ||
1202 | else | ||
1203 | { | ||
1204 | m_log.WarnFormat("{0}: AddForce: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); | ||
1205 | return; | ||
1206 | } | ||
1178 | } | 1207 | } |
1179 | else | 1208 | } |
1209 | |||
1210 | public void AddForceImpulse(OMV.Vector3 impulse, bool pushforce, bool inTaintTime) { | ||
1211 | // for an object, doesn't matter if force is a pushforce or not | ||
1212 | if (!IsStatic) | ||
1180 | { | 1213 | { |
1181 | m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); | 1214 | if (impulse.IsFinite()) |
1182 | return; | 1215 | { |
1216 | float magnitude = impulse.Length(); | ||
1217 | if (magnitude > BSParam.MaxAddForceMagnitude) | ||
1218 | { | ||
1219 | // Force has a limit | ||
1220 | impulse = impulse / magnitude * BSParam.MaxAddForceMagnitude; | ||
1221 | } | ||
1222 | |||
1223 | // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse); | ||
1224 | OMV.Vector3 addImpulse = impulse; | ||
1225 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate() | ||
1226 | { | ||
1227 | // Bullet adds this impulse immediately to the velocity | ||
1228 | DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse); | ||
1229 | if (PhysBody.HasPhysicalBody) | ||
1230 | { | ||
1231 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, addImpulse); | ||
1232 | ActivateIfPhysical(false); | ||
1233 | } | ||
1234 | }); | ||
1235 | } | ||
1236 | else | ||
1237 | { | ||
1238 | m_log.WarnFormat("{0}: AddForceImpulse: Got a NaN impulse applied to a prim. LocalID={1}", LogHeader, LocalID); | ||
1239 | return; | ||
1240 | } | ||
1183 | } | 1241 | } |
1184 | } | 1242 | } |
1185 | 1243 | ||
@@ -1561,21 +1619,6 @@ public sealed class BSPrim : BSPhysObject | |||
1561 | 1619 | ||
1562 | // The physics engine says that properties have updated. Update same and inform | 1620 | // The physics engine says that properties have updated. Update same and inform |
1563 | // the world that things have changed. | 1621 | // the world that things have changed. |
1564 | // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate() | ||
1565 | enum UpdatedProperties { | ||
1566 | Position = 1 << 0, | ||
1567 | Rotation = 1 << 1, | ||
1568 | Velocity = 1 << 2, | ||
1569 | Acceleration = 1 << 3, | ||
1570 | RotationalVel = 1 << 4 | ||
1571 | } | ||
1572 | |||
1573 | const float ROTATION_TOLERANCE = 0.01f; | ||
1574 | const float VELOCITY_TOLERANCE = 0.001f; | ||
1575 | const float POSITION_TOLERANCE = 0.05f; | ||
1576 | const float ACCELERATION_TOLERANCE = 0.01f; | ||
1577 | const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; | ||
1578 | |||
1579 | public override void UpdateProperties(EntityProperties entprop) | 1622 | public override void UpdateProperties(EntityProperties entprop) |
1580 | { | 1623 | { |
1581 | // Updates only for individual prims and for the root object of a linkset. | 1624 | // Updates only for individual prims and for the root object of a linkset. |
@@ -1588,7 +1631,8 @@ public sealed class BSPrim : BSPhysObject | |||
1588 | entprop.RotationalVelocity = OMV.Vector3.Zero; | 1631 | entprop.RotationalVelocity = OMV.Vector3.Zero; |
1589 | } | 1632 | } |
1590 | 1633 | ||
1591 | // Assign directly to the local variables so the normal set action does not happen | 1634 | // Assign directly to the local variables so the normal set actions do not happen |
1635 | entprop.Position -= PositionDisplacement; | ||
1592 | _position = entprop.Position; | 1636 | _position = entprop.Position; |
1593 | _orientation = entprop.Rotation; | 1637 | _orientation = entprop.Rotation; |
1594 | _velocity = entprop.Velocity; | 1638 | _velocity = entprop.Velocity; |