aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs172
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;