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.cs307
1 files changed, 52 insertions, 255 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index e56276a..71fea59 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -55,9 +55,6 @@ public class BSPrim : BSPhysObject
55 private OMV.Vector3 _position; 55 private OMV.Vector3 _position;
56 56
57 private float _mass; // the mass of this object 57 private float _mass; // the mass of this object
58 private OMV.Vector3 _force;
59 private OMV.Vector3 _velocity;
60 private OMV.Vector3 _torque;
61 private OMV.Vector3 _acceleration; 58 private OMV.Vector3 _acceleration;
62 private OMV.Quaternion _orientation; 59 private OMV.Quaternion _orientation;
63 private int _physicsActorType; 60 private int _physicsActorType;
@@ -73,16 +70,13 @@ public class BSPrim : BSPhysObject
73 private int CrossingFailures { get; set; } 70 private int CrossingFailures { get; set; }
74 71
75 public BSDynamics VehicleActor; 72 public BSDynamics VehicleActor;
76 public string VehicleActorName = "BasicVehicle"; 73 public const string VehicleActorName = "BasicVehicle";
77 74
78 private BSVMotor _targetMotor; 75 public const string HoverActorName = "HoverActor";
79 private OMV.Vector3 _PIDTarget; 76 public const String LockedAxisActorName = "BSPrim.LockedAxis";
80 private float _PIDTau; 77 public const string MoveToTargetActorName = "MoveToTargetActor";
81 78 public const string SetForceActorName = "SetForceActor";
82 private BSFMotor _hoverMotor; 79 public const string SetTorqueActorName = "SetTorqueActor";
83 private float _PIDHoverHeight;
84 private PIDHoverType _PIDHoverType;
85 private float _PIDHoverTau;
86 80
87 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, 81 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
88 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) 82 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
@@ -95,7 +89,7 @@ public class BSPrim : BSPhysObject
95 Scale = size; // prims are the size the user wants them to be (different for BSCharactes). 89 Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
96 _orientation = rotation; 90 _orientation = rotation;
97 _buoyancy = 0f; 91 _buoyancy = 0f;
98 _velocity = OMV.Vector3.Zero; 92 RawVelocity = OMV.Vector3.Zero;
99 _rotationalVelocity = OMV.Vector3.Zero; 93 _rotationalVelocity = OMV.Vector3.Zero;
100 BaseShape = pbs; 94 BaseShape = pbs;
101 _isPhysical = pisPhysical; 95 _isPhysical = pisPhysical;
@@ -233,7 +227,7 @@ public class BSPrim : BSPhysObject
233 // Called at taint time! 227 // Called at taint time!
234 public override void ZeroMotion(bool inTaintTime) 228 public override void ZeroMotion(bool inTaintTime)
235 { 229 {
236 _velocity = OMV.Vector3.Zero; 230 RawVelocity = OMV.Vector3.Zero;
237 _acceleration = OMV.Vector3.Zero; 231 _acceleration = OMV.Vector3.Zero;
238 _rotationalVelocity = OMV.Vector3.Zero; 232 _rotationalVelocity = OMV.Vector3.Zero;
239 233
@@ -270,19 +264,17 @@ public class BSPrim : BSPhysObject
270 if (axis.Z != 1) locking.Z = 0f; 264 if (axis.Z != 1) locking.Z = 0f;
271 LockedAxis = locking; 265 LockedAxis = locking;
272 266
273 if (LockedAxis != LockedAxisFree) 267 CreateRemoveActor(LockedAxis != LockedAxisFree /* creatActor */, LockedAxisActorName, false /* inTaintTime */, delegate()
274 { 268 {
275 PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate() 269 return new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName);
276 { 270 });
277 // If there is not already an axis locker, make one 271
278 if (!PhysicalActors.HasActor(LockedAxisActorName)) 272 // Update parameters so the new actor's Refresh() action is called at the right time.
279 { 273 PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
280 DetailLog("{0},BSPrim.LockAngularMotion,taint,registeringLockAxisActor", LocalID); 274 {
281 PhysicalActors.Add(LockedAxisActorName, new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName)); 275 UpdatePhysicalParameters();
282 } 276 });
283 UpdatePhysicalParameters(); 277
284 });
285 }
286 return; 278 return;
287 } 279 }
288 280
@@ -407,9 +399,9 @@ public class BSPrim : BSPhysObject
407 ZeroMotion(inTaintTime); 399 ZeroMotion(inTaintTime);
408 ret = true; 400 ret = true;
409 } 401 }
410 if (_velocity.LengthSquared() > BSParam.MaxLinearVelocity) 402 if (RawVelocity.LengthSquared() > BSParam.MaxLinearVelocity)
411 { 403 {
412 _velocity = Util.ClampV(_velocity, BSParam.MaxLinearVelocity); 404 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity);
413 ret = true; 405 ret = true;
414 } 406 }
415 if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared) 407 if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared)
@@ -506,35 +498,13 @@ public class BSPrim : BSPhysObject
506 } 498 }
507 499
508 public override OMV.Vector3 Force { 500 public override OMV.Vector3 Force {
509 get { return _force; } 501 get { return RawForce; }
510 set { 502 set {
511 _force = value; 503 RawForce = value;
512 if (_force != OMV.Vector3.Zero) 504 CreateRemoveActor(RawForce == OMV.Vector3.Zero, SetForceActorName, false /* inTaintTime */, delegate()
513 {
514 // If the force is non-zero, it must be reapplied each tick because
515 // Bullet clears the forces applied last frame.
516 RegisterPreStepAction("BSPrim.setForce", LocalID,
517 delegate(float timeStep)
518 {
519 if (!IsPhysicallyActive || _force == OMV.Vector3.Zero)
520 {
521 UnRegisterPreStepAction("BSPrim.setForce", LocalID);
522 return;
523 }
524
525 DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force);
526 if (PhysBody.HasPhysicalBody)
527 {
528 PhysicsScene.PE.ApplyCentralForce(PhysBody, _force);
529 ActivateIfPhysical(false);
530 }
531 }
532 );
533 }
534 else
535 { 505 {
536 UnRegisterPreStepAction("BSPrim.setForce", LocalID); 506 return new BSActorSetForce(PhysicsScene, this, SetForceActorName);
537 } 507 });
538 } 508 }
539 } 509 }
540 510
@@ -670,62 +640,39 @@ public class BSPrim : BSPhysObject
670 } 640 }
671 } 641 }
672 } 642 }
673 public override OMV.Vector3 RawVelocity
674 {
675 get { return _velocity; }
676 set { _velocity = value; }
677 }
678 public override OMV.Vector3 Velocity { 643 public override OMV.Vector3 Velocity {
679 get { return _velocity; } 644 get { return RawVelocity; }
680 set { 645 set {
681 _velocity = value; 646 RawVelocity = value;
682 PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() 647 PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate()
683 { 648 {
684 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 649 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
685 ForceVelocity = _velocity; 650 ForceVelocity = RawVelocity;
686 }); 651 });
687 } 652 }
688 } 653 }
689 public override OMV.Vector3 ForceVelocity { 654 public override OMV.Vector3 ForceVelocity {
690 get { return _velocity; } 655 get { return RawVelocity; }
691 set { 656 set {
692 PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity"); 657 PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity");
693 658
694 _velocity = Util.ClampV(value, BSParam.MaxLinearVelocity); 659 RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
695 if (PhysBody.HasPhysicalBody) 660 if (PhysBody.HasPhysicalBody)
696 { 661 {
697 DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity); 662 DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, RawVelocity);
698 PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); 663 PhysicsScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
699 ActivateIfPhysical(false); 664 ActivateIfPhysical(false);
700 } 665 }
701 } 666 }
702 } 667 }
703 public override OMV.Vector3 Torque { 668 public override OMV.Vector3 Torque {
704 get { return _torque; } 669 get { return RawTorque; }
705 set { 670 set {
706 _torque = value; 671 RawTorque = value;
707 if (_torque != OMV.Vector3.Zero) 672 CreateRemoveActor(RawTorque == OMV.Vector3.Zero, SetTorqueActorName, false /* inTaintTime */, delegate()
708 { 673 {
709 // If the torque is non-zero, it must be reapplied each tick because 674 return new BSActorSetTorque(PhysicsScene, this, SetTorqueActorName);
710 // Bullet clears the forces applied last frame. 675 });
711 RegisterPreStepAction("BSPrim.setTorque", LocalID,
712 delegate(float timeStep)
713 {
714 if (!IsPhysicallyActive || _torque == OMV.Vector3.Zero)
715 {
716 UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
717 return;
718 }
719
720 if (PhysBody.HasPhysicalBody)
721 AddAngularForce(_torque, false, true);
722 }
723 );
724 }
725 else
726 {
727 UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
728 }
729 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); 676 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
730 } 677 }
731 } 678 }
@@ -909,7 +856,7 @@ public class BSPrim : BSPhysObject
909 856
910 // For good measure, make sure the transform is set through to the motion state 857 // For good measure, make sure the transform is set through to the motion state
911 ForcePosition = _position; 858 ForcePosition = _position;
912 ForceVelocity = _velocity; 859 ForceVelocity = RawVelocity;
913 ForceRotationalVelocity = _rotationalVelocity; 860 ForceRotationalVelocity = _rotationalVelocity;
914 861
915 // A dynamic object has mass 862 // A dynamic object has mass
@@ -966,15 +913,6 @@ public class BSPrim : BSPhysObject
966 } 913 }
967 } 914 }
968 915
969 // Enable physical actions. Bullet will keep sleeping non-moving physical objects so
970 // they need waking up when parameters are changed.
971 // Called in taint-time!!
972 private void ActivateIfPhysical(bool forceIt)
973 {
974 if (IsPhysical && PhysBody.HasPhysicalBody)
975 PhysicsScene.PE.Activate(PhysBody, forceIt);
976 }
977
978 // Turn on or off the flag controlling whether collision events are returned to the simulator. 916 // Turn on or off the flag controlling whether collision events are returned to the simulator.
979 private void EnableCollisions(bool wantsCollisionEvents) 917 private void EnableCollisions(bool wantsCollisionEvents)
980 { 918 {
@@ -1096,78 +1034,13 @@ public class BSPrim : BSPhysObject
1096 } 1034 }
1097 } 1035 }
1098 1036
1099 // Used for MoveTo
1100 public override OMV.Vector3 PIDTarget {
1101 set
1102 {
1103 // TODO: add a sanity check -- don't move more than a region or something like that.
1104 _PIDTarget = value;
1105 }
1106 }
1107 public override float PIDTau {
1108 set { _PIDTau = value; }
1109 }
1110 public override bool PIDActive { 1037 public override bool PIDActive {
1111 set { 1038 set {
1112 if (value) 1039 base.MoveToTargetActive = value;
1113 { 1040 CreateRemoveActor(MoveToTargetActive, MoveToTargetActorName, false /* inTaintTime */, delegate()
1114 // We're taking over after this.
1115 ZeroMotion(true);
1116
1117 _targetMotor = new BSVMotor("BSPrim.PIDTarget",
1118 _PIDTau, // timeScale
1119 BSMotor.Infinite, // decay time scale
1120 BSMotor.InfiniteVector, // friction timescale
1121 1f // efficiency
1122 );
1123 _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
1124 _targetMotor.SetTarget(_PIDTarget);
1125 _targetMotor.SetCurrent(RawPosition);
1126 /*
1127 _targetMotor = new BSPIDVMotor("BSPrim.PIDTarget");
1128 _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
1129
1130 _targetMotor.SetTarget(_PIDTarget);
1131 _targetMotor.SetCurrent(RawPosition);
1132 _targetMotor.TimeScale = _PIDTau;
1133 _targetMotor.Efficiency = 1f;
1134 */
1135
1136 RegisterPreStepAction("BSPrim.PIDTarget", LocalID, delegate(float timeStep)
1137 {
1138 if (!IsPhysicallyActive)
1139 {
1140 UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID);
1141 return;
1142 }
1143
1144 OMV.Vector3 origPosition = RawPosition; // DEBUG DEBUG (for printout below)
1145
1146 // 'movePosition' is where we'd like the prim to be at this moment.
1147 OMV.Vector3 movePosition = RawPosition + _targetMotor.Step(timeStep);
1148
1149 // If we are very close to our target, turn off the movement motor.
1150 if (_targetMotor.ErrorIsZero())
1151 {
1152 DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}",
1153 LocalID, movePosition, RawPosition, Mass);
1154 ForcePosition = _targetMotor.TargetValue;
1155 _targetMotor.Enabled = false;
1156 }
1157 else
1158 {
1159 _position = movePosition;
1160 PositionSanityCheck(true /* intaintTime */);
1161 ForcePosition = _position;
1162 }
1163 DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", LocalID, origPosition, movePosition);
1164 });
1165 }
1166 else
1167 { 1041 {
1168 // Stop any targetting 1042 return new BSActorMoveToTarget(PhysicsScene, this, MoveToTargetActorName);
1169 UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID); 1043 });
1170 }
1171 } 1044 }
1172 } 1045 }
1173 1046
@@ -1175,88 +1048,14 @@ public class BSPrim : BSPhysObject
1175 // Hover Height will override MoveTo target's Z 1048 // Hover Height will override MoveTo target's Z
1176 public override bool PIDHoverActive { 1049 public override bool PIDHoverActive {
1177 set { 1050 set {
1178 if (value) 1051 base.HoverActive = value;
1179 { 1052 CreateRemoveActor(HoverActive /* creatActor */, HoverActorName, false /* inTaintTime */, delegate()
1180 // Turning the target on
1181 _hoverMotor = new BSFMotor("BSPrim.Hover",
1182 _PIDHoverTau, // timeScale
1183 BSMotor.Infinite, // decay time scale
1184 BSMotor.Infinite, // friction timescale
1185 1f // efficiency
1186 );
1187 _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
1188 _hoverMotor.SetCurrent(RawPosition.Z);
1189 _hoverMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
1190
1191 RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep)
1192 {
1193 // Don't do hovering while the object is selected.
1194 if (!IsPhysicallyActive)
1195 return;
1196
1197 _hoverMotor.SetCurrent(RawPosition.Z);
1198 _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
1199 float targetHeight = _hoverMotor.Step(timeStep);
1200
1201 // 'targetHeight' is where we'd like the Z of the prim to be at this moment.
1202 // Compute the amount of force to push us there.
1203 float moveForce = (targetHeight - RawPosition.Z) * Mass;
1204 // Undo anything the object thinks it's doing at the moment
1205 moveForce = -RawVelocity.Z * Mass;
1206
1207 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, new OMV.Vector3(0f, 0f, moveForce));
1208 DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}", LocalID, targetHeight, moveForce, Mass);
1209 });
1210 }
1211 else
1212 { 1053 {
1213 UnRegisterPreStepAction("BSPrim.Hover", LocalID); 1054 return new BSActorHover(PhysicsScene, this, HoverActorName);
1214 } 1055 });
1215 }
1216 }
1217 public override float PIDHoverHeight {
1218 set { _PIDHoverHeight = value; }
1219 }
1220 public override PIDHoverType PIDHoverType {
1221 set { _PIDHoverType = value; }
1222 }
1223 public override float PIDHoverTau {
1224 set { _PIDHoverTau = value; }
1225 }
1226 // Based on current position, determine what we should be hovering at now.
1227 // Must recompute often. What if we walked offa cliff>
1228 private float ComputeCurrentPIDHoverHeight()
1229 {
1230 float ret = _PIDHoverHeight;
1231 float groundHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
1232
1233 switch (_PIDHoverType)
1234 {
1235 case PIDHoverType.Ground:
1236 ret = groundHeight + _PIDHoverHeight;
1237 break;
1238 case PIDHoverType.GroundAndWater:
1239 float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition);
1240 if (groundHeight > waterHeight)
1241 {
1242 ret = groundHeight + _PIDHoverHeight;
1243 }
1244 else
1245 {
1246 ret = waterHeight + _PIDHoverHeight;
1247 }
1248 break;
1249 } 1056 }
1250 return ret;
1251 } 1057 }
1252 1058
1253
1254 // For RotLookAt
1255 public override OMV.Quaternion APIDTarget { set { return; } }
1256 public override bool APIDActive { set { return; } }
1257 public override float APIDStrength { set { return; } }
1258 public override float APIDDamping { set { return; } }
1259
1260 public override void AddForce(OMV.Vector3 force, bool pushforce) { 1059 public override void AddForce(OMV.Vector3 force, bool pushforce) {
1261 // Per documentation, max force is limited. 1060 // Per documentation, max force is limited.
1262 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); 1061 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
@@ -1324,10 +1123,8 @@ public class BSPrim : BSPhysObject
1324 } 1123 }
1325 } 1124 }
1326 1125
1327 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 1126 // BSPhysObject.AddAngularForce()
1328 AddAngularForce(force, pushforce, false); 1127 public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
1329 }
1330 public void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
1331 { 1128 {
1332 if (force.IsFinite()) 1129 if (force.IsFinite())
1333 { 1130 {
@@ -1694,8 +1491,8 @@ public class BSPrim : BSPhysObject
1694 _orientation = entprop.Rotation; 1491 _orientation = entprop.Rotation;
1695 // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be 1492 // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be
1696 // very sensitive to velocity changes. 1493 // very sensitive to velocity changes.
1697 if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(_velocity, BSParam.UpdateVelocityChangeThreshold)) 1494 if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
1698 _velocity = entprop.Velocity; 1495 RawVelocity = entprop.Velocity;
1699 _acceleration = entprop.Acceleration; 1496 _acceleration = entprop.Acceleration;
1700 _rotationalVelocity = entprop.RotationalVelocity; 1497 _rotationalVelocity = entprop.RotationalVelocity;
1701 1498
@@ -1705,7 +1502,7 @@ public class BSPrim : BSPhysObject
1705 if (PositionSanityCheck(true /* inTaintTime */ )) 1502 if (PositionSanityCheck(true /* inTaintTime */ ))
1706 { 1503 {
1707 entprop.Position = _position; 1504 entprop.Position = _position;
1708 entprop.Velocity = _velocity; 1505 entprop.Velocity = RawVelocity;
1709 entprop.RotationalVelocity = _rotationalVelocity; 1506 entprop.RotationalVelocity = _rotationalVelocity;
1710 entprop.Acceleration = _acceleration; 1507 entprop.Acceleration = _acceleration;
1711 } 1508 }