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.cs645
1 files changed, 176 insertions, 469 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 6a5461a..95bdc7b 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;
@@ -72,16 +69,19 @@ public class BSPrim : BSPhysObject
72 69
73 private int CrossingFailures { get; set; } 70 private int CrossingFailures { get; set; }
74 71
75 public BSDynamics VehicleController { get; private set; } 72 // Keep a handle to the vehicle actor so it is easy to set parameters on same.
73 public BSDynamics VehicleActor;
74 public const string VehicleActorName = "BasicVehicle";
76 75
77 private BSVMotor _targetMotor; 76 // Parameters for the hover actor
78 private OMV.Vector3 _PIDTarget; 77 public const string HoverActorName = "HoverActor";
79 private float _PIDTau; 78 // Parameters for the axis lock actor
80 79 public const String LockedAxisActorName = "BSPrim.LockedAxis";
81 private BSFMotor _hoverMotor; 80 // Parameters for the move to target actor
82 private float _PIDHoverHeight; 81 public const string MoveToTargetActorName = "MoveToTargetActor";
83 private PIDHoverType _PIDHoverType; 82 // Parameters for the setForce and setTorque actors
84 private float _PIDHoverTau; 83 public const string SetForceActorName = "SetForceActor";
84 public const string SetTorqueActorName = "SetTorqueActor";
85 85
86 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, 86 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
87 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) 87 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
@@ -94,26 +94,28 @@ public class BSPrim : BSPhysObject
94 Scale = size; // prims are the size the user wants them to be (different for BSCharactes). 94 Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
95 _orientation = rotation; 95 _orientation = rotation;
96 _buoyancy = 0f; 96 _buoyancy = 0f;
97 _velocity = OMV.Vector3.Zero; 97 RawVelocity = OMV.Vector3.Zero;
98 _rotationalVelocity = OMV.Vector3.Zero; 98 _rotationalVelocity = OMV.Vector3.Zero;
99 BaseShape = pbs; 99 BaseShape = pbs;
100 _isPhysical = pisPhysical; 100 _isPhysical = pisPhysical;
101 _isVolumeDetect = false; 101 _isVolumeDetect = false;
102 102
103 VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness 103 // We keep a handle to the vehicle actor so we can set vehicle parameters later.
104 VehicleActor = new BSDynamics(PhysScene, this, VehicleActorName);
105 PhysicalActors.Add(VehicleActorName, VehicleActor);
104 106
105 _mass = CalculateMass(); 107 _mass = CalculateMass();
106 108
107 DetailLog("{0},BSPrim.constructor,call", LocalID); 109 // DetailLog("{0},BSPrim.constructor,call", LocalID);
108 // do the actual object creation at taint time 110 // do the actual object creation at taint time
109 PhysicsScene.TaintedObject("BSPrim.create", delegate() 111 PhysScene.TaintedObject("BSPrim.create", delegate()
110 { 112 {
111 // Make sure the object is being created with some sanity. 113 // Make sure the object is being created with some sanity.
112 ExtremeSanityCheck(true /* inTaintTime */); 114 ExtremeSanityCheck(true /* inTaintTime */);
113 115
114 CreateGeomAndObject(true); 116 CreateGeomAndObject(true);
115 117
116 CurrentCollisionFlags = PhysicsScene.PE.GetCollisionFlags(PhysBody); 118 CurrentCollisionFlags = PhysScene.PE.GetCollisionFlags(PhysBody);
117 }); 119 });
118 } 120 }
119 121
@@ -126,14 +128,14 @@ public class BSPrim : BSPhysObject
126 // Undo any vehicle properties 128 // Undo any vehicle properties
127 this.VehicleType = (int)Vehicle.TYPE_NONE; 129 this.VehicleType = (int)Vehicle.TYPE_NONE;
128 130
129 PhysicsScene.TaintedObject("BSPrim.destroy", delegate() 131 PhysScene.TaintedObject("BSPrim.Destroy", delegate()
130 { 132 {
131 DetailLog("{0},BSPrim.Destroy,taint,", LocalID); 133 DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
132 // If there are physical body and shape, release my use of same. 134 // If there are physical body and shape, release my use of same.
133 PhysicsScene.Shapes.DereferenceBody(PhysBody, null); 135 PhysScene.Shapes.DereferenceBody(PhysBody, null);
134 PhysBody.Clear(); 136 PhysBody.Clear();
135 PhysicsScene.Shapes.DereferenceShape(PhysShape, null); 137 PhysShape.Dereference(PhysScene);
136 PhysShape.Clear(); 138 PhysShape = new BSShapeNull();
137 }); 139 });
138 } 140 }
139 141
@@ -159,25 +161,13 @@ public class BSPrim : BSPhysObject
159 ForceBodyShapeRebuild(false); 161 ForceBodyShapeRebuild(false);
160 } 162 }
161 } 163 }
162 // 'unknown' says to choose the best type
163 public override BSPhysicsShapeType PreferredPhysicalShape
164 { get { return BSPhysicsShapeType.SHAPE_UNKNOWN; } }
165
166 public override bool ForceBodyShapeRebuild(bool inTaintTime) 164 public override bool ForceBodyShapeRebuild(bool inTaintTime)
167 { 165 {
168 if (inTaintTime) 166 PhysScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate()
169 { 167 {
170 _mass = CalculateMass(); // changing the shape changes the mass 168 _mass = CalculateMass(); // changing the shape changes the mass
171 CreateGeomAndObject(true); 169 CreateGeomAndObject(true);
172 } 170 });
173 else
174 {
175 PhysicsScene.TaintedObject("BSPrim.ForceBodyShapeRebuild", delegate()
176 {
177 _mass = CalculateMass(); // changing the shape changes the mass
178 CreateGeomAndObject(true);
179 });
180 }
181 return true; 171 return true;
182 } 172 }
183 public override bool Grabbed { 173 public override bool Grabbed {
@@ -190,7 +180,7 @@ public class BSPrim : BSPhysObject
190 if (value != _isSelected) 180 if (value != _isSelected)
191 { 181 {
192 _isSelected = value; 182 _isSelected = value;
193 PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() 183 PhysScene.TaintedObject("BSPrim.setSelected", delegate()
194 { 184 {
195 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); 185 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
196 SetObjectDynamic(false); 186 SetObjectDynamic(false);
@@ -231,124 +221,56 @@ public class BSPrim : BSPhysObject
231 // Called at taint time! 221 // Called at taint time!
232 public override void ZeroMotion(bool inTaintTime) 222 public override void ZeroMotion(bool inTaintTime)
233 { 223 {
234 _velocity = OMV.Vector3.Zero; 224 RawVelocity = OMV.Vector3.Zero;
235 _acceleration = OMV.Vector3.Zero; 225 _acceleration = OMV.Vector3.Zero;
236 _rotationalVelocity = OMV.Vector3.Zero; 226 _rotationalVelocity = OMV.Vector3.Zero;
237 227
238 // Zero some other properties in the physics engine 228 // Zero some other properties in the physics engine
239 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 229 PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
240 { 230 {
241 if (PhysBody.HasPhysicalBody) 231 if (PhysBody.HasPhysicalBody)
242 PhysicsScene.PE.ClearAllForces(PhysBody); 232 PhysScene.PE.ClearAllForces(PhysBody);
243 }); 233 });
244 } 234 }
245 public override void ZeroAngularMotion(bool inTaintTime) 235 public override void ZeroAngularMotion(bool inTaintTime)
246 { 236 {
247 _rotationalVelocity = OMV.Vector3.Zero; 237 _rotationalVelocity = OMV.Vector3.Zero;
248 // Zero some other properties in the physics engine 238 // Zero some other properties in the physics engine
249 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 239 PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
250 { 240 {
251 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); 241 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
252 if (PhysBody.HasPhysicalBody) 242 if (PhysBody.HasPhysicalBody)
253 { 243 {
254 PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); 244 PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
255 PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); 245 PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
256 } 246 }
257 }); 247 });
258 } 248 }
259 249
260 bool TryExperimentalLockAxisCode = false;
261 BSConstraint LockAxisConstraint = null;
262 public override void LockAngularMotion(OMV.Vector3 axis) 250 public override void LockAngularMotion(OMV.Vector3 axis)
263 { 251 {
264 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 252 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
265 253
266 // "1" means free, "0" means locked 254 // "1" means free, "0" means locked
267 OMV.Vector3 locking = new OMV.Vector3(1f, 1f, 1f); 255 OMV.Vector3 locking = LockedAxisFree;
268 if (axis.X != 1) locking.X = 0f; 256 if (axis.X != 1) locking.X = 0f;
269 if (axis.Y != 1) locking.Y = 0f; 257 if (axis.Y != 1) locking.Y = 0f;
270 if (axis.Z != 1) locking.Z = 0f; 258 if (axis.Z != 1) locking.Z = 0f;
271 LockedAxis = locking; 259 LockedAngularAxis = locking;
272 260
273 if (TryExperimentalLockAxisCode && LockedAxis != LockedAxisFree) 261 EnableActor(LockedAngularAxis != LockedAxisFree, LockedAxisActorName, delegate()
274 { 262 {
275 // Lock that axis by creating a 6DOF constraint that has one end in the world and 263 return new BSActorLockAxis(PhysScene, this, LockedAxisActorName);
276 // the other in the object. 264 });
277 // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817
278 // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380
279
280 PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
281 {
282 CleanUpLockAxisPhysicals(true /* inTaintTime */);
283
284 BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(PhysicsScene.World, PhysBody,
285 OMV.Vector3.Zero, OMV.Quaternion.Inverse(RawOrientation),
286 true /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */);
287 LockAxisConstraint = axisConstrainer;
288 PhysicsScene.Constraints.AddConstraint(LockAxisConstraint);
289
290 // The constraint is tied to the world and oriented to the prim.
291
292 // Free to move linearly
293 OMV.Vector3 linearLow = OMV.Vector3.Zero;
294 OMV.Vector3 linearHigh = PhysicsScene.TerrainManager.DefaultRegionSize;
295 axisConstrainer.SetLinearLimits(linearLow, linearHigh);
296
297 // Angular with some axis locked
298 float f2PI = (float)Math.PI * 2f;
299 OMV.Vector3 angularLow = new OMV.Vector3(-f2PI, -f2PI, -f2PI);
300 OMV.Vector3 angularHigh = new OMV.Vector3(f2PI, f2PI, f2PI);
301 if (LockedAxis.X != 1f)
302 {
303 angularLow.X = 0f;
304 angularHigh.X = 0f;
305 }
306 if (LockedAxis.Y != 1f)
307 {
308 angularLow.Y = 0f;
309 angularHigh.Y = 0f;
310 }
311 if (LockedAxis.Z != 1f)
312 {
313 angularLow.Z = 0f;
314 angularHigh.Z = 0f;
315 }
316 axisConstrainer.SetAngularLimits(angularLow, angularHigh);
317
318 DetailLog("{0},BSPrim.LockAngularMotion,create,linLow={1},linHi={2},angLow={3},angHi={4}",
319 LocalID, linearLow, linearHigh, angularLow, angularHigh);
320
321 // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
322 axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
323 265
324 axisConstrainer.RecomputeConstraintVariables(RawMass); 266 // Update parameters so the new actor's Refresh() action is called at the right time.
325 }); 267 PhysScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
326 }
327 else
328 { 268 {
329 // Everything seems unlocked 269 UpdatePhysicalParameters();
330 CleanUpLockAxisPhysicals(false /* inTaintTime */); 270 });
331 }
332 271
333 return; 272 return;
334 } 273 }
335 // Get rid of any constraint built for LockAxis
336 // Most often the constraint is removed when the constraint collection is cleaned for this prim.
337 private void CleanUpLockAxisPhysicals(bool inTaintTime)
338 {
339 if (LockAxisConstraint != null)
340 {
341 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.CleanUpLockAxisPhysicals", delegate()
342 {
343 if (LockAxisConstraint != null)
344 {
345 PhysicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint);
346 LockAxisConstraint = null;
347 DetailLog("{0},BSPrim.CleanUpLockAxisPhysicals,destroyingConstraint", LocalID);
348 }
349 });
350 }
351 }
352 274
353 public override OMV.Vector3 RawPosition 275 public override OMV.Vector3 RawPosition
354 { 276 {
@@ -372,7 +294,7 @@ public class BSPrim : BSPhysObject
372 _position = value; 294 _position = value;
373 PositionSanityCheck(false); 295 PositionSanityCheck(false);
374 296
375 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() 297 PhysScene.TaintedObject("BSPrim.setPosition", delegate()
376 { 298 {
377 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 299 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
378 ForcePosition = _position; 300 ForcePosition = _position;
@@ -382,14 +304,14 @@ public class BSPrim : BSPhysObject
382 304
383 public override OMV.Vector3 ForcePosition { 305 public override OMV.Vector3 ForcePosition {
384 get { 306 get {
385 _position = PhysicsScene.PE.GetPosition(PhysBody); 307 _position = PhysScene.PE.GetPosition(PhysBody);
386 return _position; 308 return _position;
387 } 309 }
388 set { 310 set {
389 _position = value; 311 _position = value;
390 if (PhysBody.HasPhysicalBody) 312 if (PhysBody.HasPhysicalBody)
391 { 313 {
392 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); 314 PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
393 ActivateIfPhysical(false); 315 ActivateIfPhysical(false);
394 } 316 }
395 } 317 }
@@ -406,7 +328,7 @@ public class BSPrim : BSPhysObject
406 if (!IsPhysicallyActive) 328 if (!IsPhysicallyActive)
407 return ret; 329 return ret;
408 330
409 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) 331 if (!PhysScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
410 { 332 {
411 // The physical object is out of the known/simulated area. 333 // The physical object is out of the known/simulated area.
412 // Upper levels of code will handle the transition to other areas so, for 334 // Upper levels of code will handle the transition to other areas so, for
@@ -414,7 +336,7 @@ public class BSPrim : BSPhysObject
414 return ret; 336 return ret;
415 } 337 }
416 338
417 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); 339 float terrainHeight = PhysScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
418 OMV.Vector3 upForce = OMV.Vector3.Zero; 340 OMV.Vector3 upForce = OMV.Vector3.Zero;
419 float approxSize = Math.Max(Size.X, Math.Max(Size.Y, Size.Z)); 341 float approxSize = Math.Max(Size.X, Math.Max(Size.Y, Size.Z));
420 if ((RawPosition.Z + approxSize / 2f) < terrainHeight) 342 if ((RawPosition.Z + approxSize / 2f) < terrainHeight)
@@ -435,7 +357,7 @@ public class BSPrim : BSPhysObject
435 357
436 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) 358 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
437 { 359 {
438 float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); 360 float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position);
439 // TODO: a floating motor so object will bob in the water 361 // TODO: a floating motor so object will bob in the water
440 if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f) 362 if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f)
441 { 363 {
@@ -443,7 +365,7 @@ public class BSPrim : BSPhysObject
443 upForce.Z = (waterHeight - RawPosition.Z) * 1f; 365 upForce.Z = (waterHeight - RawPosition.Z) * 1f;
444 366
445 // Apply upforce and overcome gravity. 367 // Apply upforce and overcome gravity.
446 OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; 368 OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity;
447 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); 369 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
448 AddForce(correctionForce, false, inTaintTime); 370 AddForce(correctionForce, false, inTaintTime);
449 ret = true; 371 ret = true;
@@ -471,9 +393,9 @@ public class BSPrim : BSPhysObject
471 ZeroMotion(inTaintTime); 393 ZeroMotion(inTaintTime);
472 ret = true; 394 ret = true;
473 } 395 }
474 if (_velocity.LengthSquared() > BSParam.MaxLinearVelocity) 396 if (RawVelocity.LengthSquared() > BSParam.MaxLinearVelocity)
475 { 397 {
476 _velocity = Util.ClampV(_velocity, BSParam.MaxLinearVelocity); 398 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity);
477 ret = true; 399 ret = true;
478 } 400 }
479 if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared) 401 if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared)
@@ -498,7 +420,7 @@ public class BSPrim : BSPhysObject
498 get { return _mass; } 420 get { return _mass; }
499 } 421 }
500 // used when we only want this prim's mass and not the linkset thing 422 // used when we only want this prim's mass and not the linkset thing
501 public override float RawMass { 423 public override float RawMass {
502 get { return _mass; } 424 get { return _mass; }
503 } 425 }
504 // Set the physical mass to the passed mass. 426 // Set the physical mass to the passed mass.
@@ -509,10 +431,10 @@ public class BSPrim : BSPhysObject
509 { 431 {
510 if (IsStatic) 432 if (IsStatic)
511 { 433 {
512 PhysicsScene.PE.SetGravity(PhysBody, PhysicsScene.DefaultGravity); 434 PhysScene.PE.SetGravity(PhysBody, PhysScene.DefaultGravity);
513 Inertia = OMV.Vector3.Zero; 435 Inertia = OMV.Vector3.Zero;
514 PhysicsScene.PE.SetMassProps(PhysBody, 0f, Inertia); 436 PhysScene.PE.SetMassProps(PhysBody, 0f, Inertia);
515 PhysicsScene.PE.UpdateInertiaTensor(PhysBody); 437 PhysScene.PE.UpdateInertiaTensor(PhysBody);
516 } 438 }
517 else 439 else
518 { 440 {
@@ -521,16 +443,16 @@ public class BSPrim : BSPhysObject
521 // Changing interesting properties doesn't change proxy and collision cache 443 // Changing interesting properties doesn't change proxy and collision cache
522 // information. The Bullet solution is to re-add the object to the world 444 // information. The Bullet solution is to re-add the object to the world
523 // after parameters are changed. 445 // after parameters are changed.
524 PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody); 446 PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody);
525 } 447 }
526 448
527 // The computation of mass props requires gravity to be set on the object. 449 // The computation of mass props requires gravity to be set on the object.
528 Gravity = ComputeGravity(Buoyancy); 450 Gravity = ComputeGravity(Buoyancy);
529 PhysicsScene.PE.SetGravity(PhysBody, Gravity); 451 PhysScene.PE.SetGravity(PhysBody, Gravity);
530 452
531 Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass); 453 Inertia = PhysScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass);
532 PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia); 454 PhysScene.PE.SetMassProps(PhysBody, physMass, Inertia);
533 PhysicsScene.PE.UpdateInertiaTensor(PhysBody); 455 PhysScene.PE.UpdateInertiaTensor(PhysBody);
534 456
535 DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", 457 DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}",
536 LocalID, physMass, Inertia, Gravity, inWorld); 458 LocalID, physMass, Inertia, Gravity, inWorld);
@@ -546,7 +468,7 @@ public class BSPrim : BSPhysObject
546 // Return what gravity should be set to this very moment 468 // Return what gravity should be set to this very moment
547 public OMV.Vector3 ComputeGravity(float buoyancy) 469 public OMV.Vector3 ComputeGravity(float buoyancy)
548 { 470 {
549 OMV.Vector3 ret = PhysicsScene.DefaultGravity; 471 OMV.Vector3 ret = PhysScene.DefaultGravity;
550 472
551 if (!IsStatic) 473 if (!IsStatic)
552 { 474 {
@@ -570,95 +492,63 @@ public class BSPrim : BSPhysObject
570 } 492 }
571 493
572 public override OMV.Vector3 Force { 494 public override OMV.Vector3 Force {
573 get { return _force; } 495 get { return RawForce; }
574 set { 496 set {
575 _force = value; 497 RawForce = value;
576 if (_force != OMV.Vector3.Zero) 498 EnableActor(RawForce != OMV.Vector3.Zero, SetForceActorName, delegate()
577 { 499 {
578 // If the force is non-zero, it must be reapplied each tick because 500 return new BSActorSetForce(PhysScene, this, SetForceActorName);
579 // Bullet clears the forces applied last frame. 501 });
580 RegisterPreStepAction("BSPrim.setForce", LocalID,
581 delegate(float timeStep)
582 {
583 if (!IsPhysicallyActive || _force == OMV.Vector3.Zero)
584 {
585 UnRegisterPreStepAction("BSPrim.setForce", LocalID);
586 return;
587 }
588
589 DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force);
590 if (PhysBody.HasPhysicalBody)
591 {
592 PhysicsScene.PE.ApplyCentralForce(PhysBody, _force);
593 ActivateIfPhysical(false);
594 }
595 }
596 );
597 }
598 else
599 {
600 UnRegisterPreStepAction("BSPrim.setForce", LocalID);
601 }
602 } 502 }
603 } 503 }
604 504
605 public override int VehicleType { 505 public override int VehicleType {
606 get { 506 get {
607 return (int)VehicleController.Type; // if we are a vehicle, return that type 507 return (int)VehicleActor.Type;
608 } 508 }
609 set { 509 set {
610 Vehicle type = (Vehicle)value; 510 Vehicle type = (Vehicle)value;
611 511
612 PhysicsScene.TaintedObject("setVehicleType", delegate() 512 PhysScene.TaintedObject("setVehicleType", delegate()
613 { 513 {
614 // Done at taint time so we're sure the physics engine is not using the variables 514 // Some vehicle scripts change vehicle type on the fly as an easy way to
615 // Vehicle code changes the parameters for this vehicle type. 515 // change all the parameters. Like a plane changing to CAR when on the
616 VehicleController.ProcessTypeChange(type); 516 // ground. In this case, don't want to zero motion.
517 // ZeroMotion(true /* inTaintTime */);
518 VehicleActor.ProcessTypeChange(type);
617 ActivateIfPhysical(false); 519 ActivateIfPhysical(false);
618
619 // If an active vehicle, register the vehicle code to be called before each step
620 if (VehicleController.Type == Vehicle.TYPE_NONE)
621 {
622 UnRegisterPreStepAction("BSPrim.Vehicle", LocalID);
623 UnRegisterPostStepAction("BSPrim.Vehicle", LocalID);
624 }
625 else
626 {
627 RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step);
628 RegisterPostStepAction("BSPrim.Vehicle", LocalID, VehicleController.PostStep);
629 }
630 }); 520 });
631 } 521 }
632 } 522 }
633 public override void VehicleFloatParam(int param, float value) 523 public override void VehicleFloatParam(int param, float value)
634 { 524 {
635 PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() 525 PhysScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
636 { 526 {
637 VehicleController.ProcessFloatVehicleParam((Vehicle)param, value); 527 VehicleActor.ProcessFloatVehicleParam((Vehicle)param, value);
638 ActivateIfPhysical(false); 528 ActivateIfPhysical(false);
639 }); 529 });
640 } 530 }
641 public override void VehicleVectorParam(int param, OMV.Vector3 value) 531 public override void VehicleVectorParam(int param, OMV.Vector3 value)
642 { 532 {
643 PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() 533 PhysScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
644 { 534 {
645 VehicleController.ProcessVectorVehicleParam((Vehicle)param, value); 535 VehicleActor.ProcessVectorVehicleParam((Vehicle)param, value);
646 ActivateIfPhysical(false); 536 ActivateIfPhysical(false);
647 }); 537 });
648 } 538 }
649 public override void VehicleRotationParam(int param, OMV.Quaternion rotation) 539 public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
650 { 540 {
651 PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() 541 PhysScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
652 { 542 {
653 VehicleController.ProcessRotationVehicleParam((Vehicle)param, rotation); 543 VehicleActor.ProcessRotationVehicleParam((Vehicle)param, rotation);
654 ActivateIfPhysical(false); 544 ActivateIfPhysical(false);
655 }); 545 });
656 } 546 }
657 public override void VehicleFlags(int param, bool remove) 547 public override void VehicleFlags(int param, bool remove)
658 { 548 {
659 PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate() 549 PhysScene.TaintedObject("BSPrim.VehicleFlags", delegate()
660 { 550 {
661 VehicleController.ProcessVehicleFlags(param, remove); 551 VehicleActor.ProcessVehicleFlags(param, remove);
662 }); 552 });
663 } 553 }
664 554
@@ -668,7 +558,7 @@ public class BSPrim : BSPhysObject
668 if (_isVolumeDetect != newValue) 558 if (_isVolumeDetect != newValue)
669 { 559 {
670 _isVolumeDetect = newValue; 560 _isVolumeDetect = newValue;
671 PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() 561 PhysScene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
672 { 562 {
673 // DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); 563 // DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect);
674 SetObjectDynamic(true); 564 SetObjectDynamic(true);
@@ -679,7 +569,7 @@ public class BSPrim : BSPhysObject
679 public override void SetMaterial(int material) 569 public override void SetMaterial(int material)
680 { 570 {
681 base.SetMaterial(material); 571 base.SetMaterial(material);
682 PhysicsScene.TaintedObject("BSPrim.SetMaterial", delegate() 572 PhysScene.TaintedObject("BSPrim.SetMaterial", delegate()
683 { 573 {
684 UpdatePhysicalParameters(); 574 UpdatePhysicalParameters();
685 }); 575 });
@@ -692,7 +582,7 @@ public class BSPrim : BSPhysObject
692 if (base.Friction != value) 582 if (base.Friction != value)
693 { 583 {
694 base.Friction = value; 584 base.Friction = value;
695 PhysicsScene.TaintedObject("BSPrim.setFriction", delegate() 585 PhysScene.TaintedObject("BSPrim.setFriction", delegate()
696 { 586 {
697 UpdatePhysicalParameters(); 587 UpdatePhysicalParameters();
698 }); 588 });
@@ -707,7 +597,7 @@ public class BSPrim : BSPhysObject
707 if (base.Restitution != value) 597 if (base.Restitution != value)
708 { 598 {
709 base.Restitution = value; 599 base.Restitution = value;
710 PhysicsScene.TaintedObject("BSPrim.setRestitution", delegate() 600 PhysScene.TaintedObject("BSPrim.setRestitution", delegate()
711 { 601 {
712 UpdatePhysicalParameters(); 602 UpdatePhysicalParameters();
713 }); 603 });
@@ -724,7 +614,7 @@ public class BSPrim : BSPhysObject
724 if (base.Density != value) 614 if (base.Density != value)
725 { 615 {
726 base.Density = value; 616 base.Density = value;
727 PhysicsScene.TaintedObject("BSPrim.setDensity", delegate() 617 PhysScene.TaintedObject("BSPrim.setDensity", delegate()
728 { 618 {
729 UpdatePhysicalParameters(); 619 UpdatePhysicalParameters();
730 }); 620 });
@@ -739,70 +629,47 @@ public class BSPrim : BSPhysObject
739 if (base.GravModifier != value) 629 if (base.GravModifier != value)
740 { 630 {
741 base.GravModifier = value; 631 base.GravModifier = value;
742 PhysicsScene.TaintedObject("BSPrim.setGravityModifier", delegate() 632 PhysScene.TaintedObject("BSPrim.setGravityModifier", delegate()
743 { 633 {
744 UpdatePhysicalParameters(); 634 UpdatePhysicalParameters();
745 }); 635 });
746 } 636 }
747 } 637 }
748 } 638 }
749 public override OMV.Vector3 RawVelocity
750 {
751 get { return _velocity; }
752 set { _velocity = value; }
753 }
754 public override OMV.Vector3 Velocity { 639 public override OMV.Vector3 Velocity {
755 get { return _velocity; } 640 get { return RawVelocity; }
756 set { 641 set {
757 _velocity = value; 642 RawVelocity = value;
758 PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() 643 PhysScene.TaintedObject("BSPrim.setVelocity", delegate()
759 { 644 {
760 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 645 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
761 ForceVelocity = _velocity; 646 ForceVelocity = RawVelocity;
762 }); 647 });
763 } 648 }
764 } 649 }
765 public override OMV.Vector3 ForceVelocity { 650 public override OMV.Vector3 ForceVelocity {
766 get { return _velocity; } 651 get { return RawVelocity; }
767 set { 652 set {
768 PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity"); 653 PhysScene.AssertInTaintTime("BSPrim.ForceVelocity");
769 654
770 _velocity = Util.ClampV(value, BSParam.MaxLinearVelocity); 655 RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
771 if (PhysBody.HasPhysicalBody) 656 if (PhysBody.HasPhysicalBody)
772 { 657 {
773 DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity); 658 DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, RawVelocity);
774 PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); 659 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
775 ActivateIfPhysical(false); 660 ActivateIfPhysical(false);
776 } 661 }
777 } 662 }
778 } 663 }
779 public override OMV.Vector3 Torque { 664 public override OMV.Vector3 Torque {
780 get { return _torque; } 665 get { return RawTorque; }
781 set { 666 set {
782 _torque = value; 667 RawTorque = value;
783 if (_torque != OMV.Vector3.Zero) 668 EnableActor(RawTorque != OMV.Vector3.Zero, SetTorqueActorName, delegate()
784 {
785 // If the torque is non-zero, it must be reapplied each tick because
786 // Bullet clears the forces applied last frame.
787 RegisterPreStepAction("BSPrim.setTorque", LocalID,
788 delegate(float timeStep)
789 {
790 if (!IsPhysicallyActive || _torque == OMV.Vector3.Zero)
791 {
792 UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
793 return;
794 }
795
796 if (PhysBody.HasPhysicalBody)
797 AddAngularForce(_torque, false, true);
798 }
799 );
800 }
801 else
802 { 669 {
803 UnRegisterPreStepAction("BSPrim.setTorque", LocalID); 670 return new BSActorSetTorque(PhysScene, this, SetTorqueActorName);
804 } 671 });
805 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); 672 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque);
806 } 673 }
807 } 674 }
808 public override OMV.Vector3 Acceleration { 675 public override OMV.Vector3 Acceleration {
@@ -823,7 +690,7 @@ public class BSPrim : BSPhysObject
823 return; 690 return;
824 _orientation = value; 691 _orientation = value;
825 692
826 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() 693 PhysScene.TaintedObject("BSPrim.setOrientation", delegate()
827 { 694 {
828 ForceOrientation = _orientation; 695 ForceOrientation = _orientation;
829 }); 696 });
@@ -834,14 +701,14 @@ public class BSPrim : BSPhysObject
834 { 701 {
835 get 702 get
836 { 703 {
837 _orientation = PhysicsScene.PE.GetOrientation(PhysBody); 704 _orientation = PhysScene.PE.GetOrientation(PhysBody);
838 return _orientation; 705 return _orientation;
839 } 706 }
840 set 707 set
841 { 708 {
842 _orientation = value; 709 _orientation = value;
843 if (PhysBody.HasPhysicalBody) 710 if (PhysBody.HasPhysicalBody)
844 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); 711 PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
845 } 712 }
846 } 713 }
847 public override int PhysicsActorType { 714 public override int PhysicsActorType {
@@ -854,7 +721,7 @@ public class BSPrim : BSPhysObject
854 if (_isPhysical != value) 721 if (_isPhysical != value)
855 { 722 {
856 _isPhysical = value; 723 _isPhysical = value;
857 PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() 724 PhysScene.TaintedObject("BSPrim.setIsPhysical", delegate()
858 { 725 {
859 DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); 726 DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
860 SetObjectDynamic(true); 727 SetObjectDynamic(true);
@@ -903,19 +770,19 @@ public class BSPrim : BSPhysObject
903 if (!PhysBody.HasPhysicalBody) 770 if (!PhysBody.HasPhysicalBody)
904 { 771 {
905 // This would only happen if updates are called for during initialization when the body is not set up yet. 772 // This would only happen if updates are called for during initialization when the body is not set up yet.
906 DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID); 773 // DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID);
907 return; 774 return;
908 } 775 }
909 776
910 // Mangling all the physical properties requires the object not be in the physical world. 777 // Mangling all the physical properties requires the object not be in the physical world.
911 // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found). 778 // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found).
912 PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody); 779 PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody);
913 780
914 // Set up the object physicalness (does gravity and collisions move this object) 781 // Set up the object physicalness (does gravity and collisions move this object)
915 MakeDynamic(IsStatic); 782 MakeDynamic(IsStatic);
916 783
917 // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters) 784 // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
918 VehicleController.Refresh(); 785 PhysicalActors.Refresh();
919 786
920 // Arrange for collision events if the simulator wants them 787 // Arrange for collision events if the simulator wants them
921 EnableCollisions(SubscribedEvents()); 788 EnableCollisions(SubscribedEvents());
@@ -926,10 +793,11 @@ public class BSPrim : BSPhysObject
926 AddObjectToPhysicalWorld(); 793 AddObjectToPhysicalWorld();
927 794
928 // Rebuild its shape 795 // Rebuild its shape
929 PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody); 796 PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody);
930 797
931 DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}", 798 DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}",
932 LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape); 799 LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(),
800 CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
933 } 801 }
934 802
935 // "Making dynamic" means changing to and from static. 803 // "Making dynamic" means changing to and from static.
@@ -942,28 +810,28 @@ public class BSPrim : BSPhysObject
942 if (makeStatic) 810 if (makeStatic)
943 { 811 {
944 // Become a Bullet 'static' object type 812 // Become a Bullet 'static' object type
945 CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT); 813 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
946 // Stop all movement 814 // Stop all movement
947 ZeroMotion(true); 815 ZeroMotion(true);
948 816
949 // Set various physical properties so other object interact properly 817 // Set various physical properties so other object interact properly
950 PhysicsScene.PE.SetFriction(PhysBody, Friction); 818 PhysScene.PE.SetFriction(PhysBody, Friction);
951 PhysicsScene.PE.SetRestitution(PhysBody, Restitution); 819 PhysScene.PE.SetRestitution(PhysBody, Restitution);
952 PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); 820 PhysScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
953 821
954 // Mass is zero which disables a bunch of physics stuff in Bullet 822 // Mass is zero which disables a bunch of physics stuff in Bullet
955 UpdatePhysicalMassProperties(0f, false); 823 UpdatePhysicalMassProperties(0f, false);
956 // Set collision detection parameters 824 // Set collision detection parameters
957 if (BSParam.CcdMotionThreshold > 0f) 825 if (BSParam.CcdMotionThreshold > 0f)
958 { 826 {
959 PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold); 827 PhysScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
960 PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius); 828 PhysScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
961 } 829 }
962 830
963 // The activation state is 'disabled' so Bullet will not try to act on it. 831 // The activation state is 'disabled' so Bullet will not try to act on it.
964 // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_SIMULATION); 832 // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_SIMULATION);
965 // Start it out sleeping and physical actions could wake it up. 833 // Start it out sleeping and physical actions could wake it up.
966 PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ISLAND_SLEEPING); 834 PhysScene.PE.ForceActivationState(PhysBody, ActivationState.ISLAND_SLEEPING);
967 835
968 // This collides like a static object 836 // This collides like a static object
969 PhysBody.collisionType = CollisionType.Static; 837 PhysBody.collisionType = CollisionType.Static;
@@ -971,11 +839,11 @@ public class BSPrim : BSPhysObject
971 else 839 else
972 { 840 {
973 // Not a Bullet static object 841 // Not a Bullet static object
974 CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT); 842 CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
975 843
976 // Set various physical properties so other object interact properly 844 // Set various physical properties so other object interact properly
977 PhysicsScene.PE.SetFriction(PhysBody, Friction); 845 PhysScene.PE.SetFriction(PhysBody, Friction);
978 PhysicsScene.PE.SetRestitution(PhysBody, Restitution); 846 PhysScene.PE.SetRestitution(PhysBody, Restitution);
979 // DetailLog("{0},BSPrim.MakeDynamic,frict={1},rest={2}", LocalID, Friction, Restitution); 847 // DetailLog("{0},BSPrim.MakeDynamic,frict={1},rest={2}", LocalID, Friction, Restitution);
980 848
981 // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 849 // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
@@ -984,7 +852,7 @@ public class BSPrim : BSPhysObject
984 852
985 // For good measure, make sure the transform is set through to the motion state 853 // For good measure, make sure the transform is set through to the motion state
986 ForcePosition = _position; 854 ForcePosition = _position;
987 ForceVelocity = _velocity; 855 ForceVelocity = RawVelocity;
988 ForceRotationalVelocity = _rotationalVelocity; 856 ForceRotationalVelocity = _rotationalVelocity;
989 857
990 // A dynamic object has mass 858 // A dynamic object has mass
@@ -993,22 +861,22 @@ public class BSPrim : BSPhysObject
993 // Set collision detection parameters 861 // Set collision detection parameters
994 if (BSParam.CcdMotionThreshold > 0f) 862 if (BSParam.CcdMotionThreshold > 0f)
995 { 863 {
996 PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold); 864 PhysScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
997 PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius); 865 PhysScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
998 } 866 }
999 867
1000 // Various values for simulation limits 868 // Various values for simulation limits
1001 PhysicsScene.PE.SetDamping(PhysBody, BSParam.LinearDamping, BSParam.AngularDamping); 869 PhysScene.PE.SetDamping(PhysBody, BSParam.LinearDamping, BSParam.AngularDamping);
1002 PhysicsScene.PE.SetDeactivationTime(PhysBody, BSParam.DeactivationTime); 870 PhysScene.PE.SetDeactivationTime(PhysBody, BSParam.DeactivationTime);
1003 PhysicsScene.PE.SetSleepingThresholds(PhysBody, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold); 871 PhysScene.PE.SetSleepingThresholds(PhysBody, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold);
1004 PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); 872 PhysScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
1005 873
1006 // This collides like an object. 874 // This collides like an object.
1007 PhysBody.collisionType = CollisionType.Dynamic; 875 PhysBody.collisionType = CollisionType.Dynamic;
1008 876
1009 // Force activation of the object so Bullet will act on it. 877 // Force activation of the object so Bullet will act on it.
1010 // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. 878 // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
1011 PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); 879 PhysScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
1012 } 880 }
1013 } 881 }
1014 882
@@ -1018,7 +886,7 @@ public class BSPrim : BSPhysObject
1018 // the functions after this one set up the state of a possibly newly created collision body. 886 // the functions after this one set up the state of a possibly newly created collision body.
1019 private void MakeSolid(bool makeSolid) 887 private void MakeSolid(bool makeSolid)
1020 { 888 {
1021 CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(PhysBody); 889 CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysScene.PE.GetBodyType(PhysBody);
1022 if (makeSolid) 890 if (makeSolid)
1023 { 891 {
1024 // Verify the previous code created the correct shape for this type of thing. 892 // Verify the previous code created the correct shape for this type of thing.
@@ -1026,7 +894,7 @@ public class BSPrim : BSPhysObject
1026 { 894 {
1027 m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType); 895 m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType);
1028 } 896 }
1029 CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); 897 CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
1030 } 898 }
1031 else 899 else
1032 { 900 {
@@ -1034,32 +902,23 @@ public class BSPrim : BSPhysObject
1034 { 902 {
1035 m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); 903 m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType);
1036 } 904 }
1037 CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); 905 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
1038 906
1039 // Change collision info from a static object to a ghosty collision object 907 // Change collision info from a static object to a ghosty collision object
1040 PhysBody.collisionType = CollisionType.VolumeDetect; 908 PhysBody.collisionType = CollisionType.VolumeDetect;
1041 } 909 }
1042 } 910 }
1043 911
1044 // Enable physical actions. Bullet will keep sleeping non-moving physical objects so
1045 // they need waking up when parameters are changed.
1046 // Called in taint-time!!
1047 private void ActivateIfPhysical(bool forceIt)
1048 {
1049 if (IsPhysical && PhysBody.HasPhysicalBody)
1050 PhysicsScene.PE.Activate(PhysBody, forceIt);
1051 }
1052
1053 // Turn on or off the flag controlling whether collision events are returned to the simulator. 912 // Turn on or off the flag controlling whether collision events are returned to the simulator.
1054 private void EnableCollisions(bool wantsCollisionEvents) 913 private void EnableCollisions(bool wantsCollisionEvents)
1055 { 914 {
1056 if (wantsCollisionEvents) 915 if (wantsCollisionEvents)
1057 { 916 {
1058 CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 917 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
1059 } 918 }
1060 else 919 else
1061 { 920 {
1062 CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 921 CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
1063 } 922 }
1064 } 923 }
1065 924
@@ -1070,7 +929,7 @@ public class BSPrim : BSPhysObject
1070 { 929 {
1071 if (PhysBody.HasPhysicalBody) 930 if (PhysBody.HasPhysicalBody)
1072 { 931 {
1073 PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); 932 PhysScene.PE.AddObjectToWorld(PhysScene.World, PhysBody);
1074 } 933 }
1075 else 934 else
1076 { 935 {
@@ -1105,12 +964,12 @@ public class BSPrim : BSPhysObject
1105 public override bool FloatOnWater { 964 public override bool FloatOnWater {
1106 set { 965 set {
1107 _floatOnWater = value; 966 _floatOnWater = value;
1108 PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate() 967 PhysScene.TaintedObject("BSPrim.setFloatOnWater", delegate()
1109 { 968 {
1110 if (_floatOnWater) 969 if (_floatOnWater)
1111 CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); 970 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
1112 else 971 else
1113 CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); 972 CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
1114 }); 973 });
1115 } 974 }
1116 } 975 }
@@ -1122,7 +981,7 @@ public class BSPrim : BSPhysObject
1122 _rotationalVelocity = value; 981 _rotationalVelocity = value;
1123 Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); 982 Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity);
1124 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 983 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
1125 PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 984 PhysScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
1126 { 985 {
1127 ForceRotationalVelocity = _rotationalVelocity; 986 ForceRotationalVelocity = _rotationalVelocity;
1128 }); 987 });
@@ -1137,7 +996,7 @@ public class BSPrim : BSPhysObject
1137 if (PhysBody.HasPhysicalBody) 996 if (PhysBody.HasPhysicalBody)
1138 { 997 {
1139 DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 998 DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
1140 PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); 999 PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
1141 // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); 1000 // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
1142 ActivateIfPhysical(false); 1001 ActivateIfPhysical(false);
1143 } 1002 }
@@ -1153,7 +1012,7 @@ public class BSPrim : BSPhysObject
1153 get { return _buoyancy; } 1012 get { return _buoyancy; }
1154 set { 1013 set {
1155 _buoyancy = value; 1014 _buoyancy = value;
1156 PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate() 1015 PhysScene.TaintedObject("BSPrim.setBuoyancy", delegate()
1157 { 1016 {
1158 ForceBuoyancy = _buoyancy; 1017 ForceBuoyancy = _buoyancy;
1159 }); 1018 });
@@ -1171,78 +1030,13 @@ public class BSPrim : BSPhysObject
1171 } 1030 }
1172 } 1031 }
1173 1032
1174 // Used for MoveTo
1175 public override OMV.Vector3 PIDTarget {
1176 set
1177 {
1178 // TODO: add a sanity check -- don't move more than a region or something like that.
1179 _PIDTarget = value;
1180 }
1181 }
1182 public override float PIDTau {
1183 set { _PIDTau = value; }
1184 }
1185 public override bool PIDActive { 1033 public override bool PIDActive {
1186 set { 1034 set {
1187 if (value) 1035 base.MoveToTargetActive = value;
1188 { 1036 EnableActor(MoveToTargetActive, MoveToTargetActorName, delegate()
1189 // We're taking over after this.
1190 ZeroMotion(true);
1191
1192 _targetMotor = new BSVMotor("BSPrim.PIDTarget",
1193 _PIDTau, // timeScale
1194 BSMotor.Infinite, // decay time scale
1195 BSMotor.InfiniteVector, // friction timescale
1196 1f // efficiency
1197 );
1198 _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
1199 _targetMotor.SetTarget(_PIDTarget);
1200 _targetMotor.SetCurrent(RawPosition);
1201 /*
1202 _targetMotor = new BSPIDVMotor("BSPrim.PIDTarget");
1203 _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
1204
1205 _targetMotor.SetTarget(_PIDTarget);
1206 _targetMotor.SetCurrent(RawPosition);
1207 _targetMotor.TimeScale = _PIDTau;
1208 _targetMotor.Efficiency = 1f;
1209 */
1210
1211 RegisterPreStepAction("BSPrim.PIDTarget", LocalID, delegate(float timeStep)
1212 {
1213 if (!IsPhysicallyActive)
1214 {
1215 UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID);
1216 return;
1217 }
1218
1219 OMV.Vector3 origPosition = RawPosition; // DEBUG DEBUG (for printout below)
1220
1221 // 'movePosition' is where we'd like the prim to be at this moment.
1222 OMV.Vector3 movePosition = RawPosition + _targetMotor.Step(timeStep);
1223
1224 // If we are very close to our target, turn off the movement motor.
1225 if (_targetMotor.ErrorIsZero())
1226 {
1227 DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}",
1228 LocalID, movePosition, RawPosition, Mass);
1229 ForcePosition = _targetMotor.TargetValue;
1230 _targetMotor.Enabled = false;
1231 }
1232 else
1233 {
1234 _position = movePosition;
1235 PositionSanityCheck(true /* intaintTime */);
1236 ForcePosition = _position;
1237 }
1238 DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", LocalID, origPosition, movePosition);
1239 });
1240 }
1241 else
1242 { 1037 {
1243 // Stop any targetting 1038 return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName);
1244 UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID); 1039 });
1245 }
1246 } 1040 }
1247 } 1041 }
1248 1042
@@ -1250,94 +1044,20 @@ public class BSPrim : BSPhysObject
1250 // Hover Height will override MoveTo target's Z 1044 // Hover Height will override MoveTo target's Z
1251 public override bool PIDHoverActive { 1045 public override bool PIDHoverActive {
1252 set { 1046 set {
1253 if (value) 1047 base.HoverActive = value;
1254 { 1048 EnableActor(HoverActive, HoverActorName, delegate()
1255 // Turning the target on
1256 _hoverMotor = new BSFMotor("BSPrim.Hover",
1257 _PIDHoverTau, // timeScale
1258 BSMotor.Infinite, // decay time scale
1259 BSMotor.Infinite, // friction timescale
1260 1f // efficiency
1261 );
1262 _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
1263 _hoverMotor.SetCurrent(RawPosition.Z);
1264 _hoverMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
1265
1266 RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep)
1267 {
1268 // Don't do hovering while the object is selected.
1269 if (!IsPhysicallyActive)
1270 return;
1271
1272 _hoverMotor.SetCurrent(RawPosition.Z);
1273 _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
1274 float targetHeight = _hoverMotor.Step(timeStep);
1275
1276 // 'targetHeight' is where we'd like the Z of the prim to be at this moment.
1277 // Compute the amount of force to push us there.
1278 float moveForce = (targetHeight - RawPosition.Z) * Mass;
1279 // Undo anything the object thinks it's doing at the moment
1280 moveForce = -RawVelocity.Z * Mass;
1281
1282 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, new OMV.Vector3(0f, 0f, moveForce));
1283 DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}", LocalID, targetHeight, moveForce, Mass);
1284 });
1285 }
1286 else
1287 { 1049 {
1288 UnRegisterPreStepAction("BSPrim.Hover", LocalID); 1050 return new BSActorHover(PhysScene, this, HoverActorName);
1289 } 1051 });
1290 }
1291 }
1292 public override float PIDHoverHeight {
1293 set { _PIDHoverHeight = value; }
1294 }
1295 public override PIDHoverType PIDHoverType {
1296 set { _PIDHoverType = value; }
1297 }
1298 public override float PIDHoverTau {
1299 set { _PIDHoverTau = value; }
1300 }
1301 // Based on current position, determine what we should be hovering at now.
1302 // Must recompute often. What if we walked offa cliff>
1303 private float ComputeCurrentPIDHoverHeight()
1304 {
1305 float ret = _PIDHoverHeight;
1306 float groundHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
1307
1308 switch (_PIDHoverType)
1309 {
1310 case PIDHoverType.Ground:
1311 ret = groundHeight + _PIDHoverHeight;
1312 break;
1313 case PIDHoverType.GroundAndWater:
1314 float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition);
1315 if (groundHeight > waterHeight)
1316 {
1317 ret = groundHeight + _PIDHoverHeight;
1318 }
1319 else
1320 {
1321 ret = waterHeight + _PIDHoverHeight;
1322 }
1323 break;
1324 } 1052 }
1325 return ret;
1326 } 1053 }
1327 1054
1328
1329 // For RotLookAt
1330 public override OMV.Quaternion APIDTarget { set { return; } }
1331 public override bool APIDActive { set { return; } }
1332 public override float APIDStrength { set { return; } }
1333 public override float APIDDamping { set { return; } }
1334
1335 public override void AddForce(OMV.Vector3 force, bool pushforce) { 1055 public override void AddForce(OMV.Vector3 force, bool pushforce) {
1336 // Per documentation, max force is limited. 1056 // Per documentation, max force is limited.
1337 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); 1057 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
1338 1058
1339 // Since this force is being applied in only one step, make this a force per second. 1059 // Since this force is being applied in only one step, make this a force per second.
1340 addForce /= PhysicsScene.LastTimeStep; 1060 addForce /= PhysScene.LastTimeStep;
1341 AddForce(addForce, pushforce, false /* inTaintTime */); 1061 AddForce(addForce, pushforce, false /* inTaintTime */);
1342 } 1062 }
1343 1063
@@ -1352,13 +1072,13 @@ public class BSPrim : BSPhysObject
1352 // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); 1072 // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
1353 1073
1354 OMV.Vector3 addForce = force; 1074 OMV.Vector3 addForce = force;
1355 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() 1075 PhysScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
1356 { 1076 {
1357 // Bullet adds this central force to the total force for this tick 1077 // Bullet adds this central force to the total force for this tick
1358 DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); 1078 DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
1359 if (PhysBody.HasPhysicalBody) 1079 if (PhysBody.HasPhysicalBody)
1360 { 1080 {
1361 PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); 1081 PhysScene.PE.ApplyCentralForce(PhysBody, addForce);
1362 ActivateIfPhysical(false); 1082 ActivateIfPhysical(false);
1363 } 1083 }
1364 }); 1084 });
@@ -1380,13 +1100,13 @@ public class BSPrim : BSPhysObject
1380 OMV.Vector3 addImpulse = Util.ClampV(impulse, BSParam.MaxAddForceMagnitude); 1100 OMV.Vector3 addImpulse = Util.ClampV(impulse, BSParam.MaxAddForceMagnitude);
1381 // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse); 1101 // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse);
1382 1102
1383 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate() 1103 PhysScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate()
1384 { 1104 {
1385 // Bullet adds this impulse immediately to the velocity 1105 // Bullet adds this impulse immediately to the velocity
1386 DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse); 1106 DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse);
1387 if (PhysBody.HasPhysicalBody) 1107 if (PhysBody.HasPhysicalBody)
1388 { 1108 {
1389 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, addImpulse); 1109 PhysScene.PE.ApplyCentralImpulse(PhysBody, addImpulse);
1390 ActivateIfPhysical(false); 1110 ActivateIfPhysical(false);
1391 } 1111 }
1392 }); 1112 });
@@ -1399,20 +1119,18 @@ public class BSPrim : BSPhysObject
1399 } 1119 }
1400 } 1120 }
1401 1121
1402 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 1122 // BSPhysObject.AddAngularForce()
1403 AddAngularForce(force, pushforce, false); 1123 public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
1404 }
1405 public void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
1406 { 1124 {
1407 if (force.IsFinite()) 1125 if (force.IsFinite())
1408 { 1126 {
1409 OMV.Vector3 angForce = force; 1127 OMV.Vector3 angForce = force;
1410 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate() 1128 PhysScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate()
1411 { 1129 {
1412 if (PhysBody.HasPhysicalBody) 1130 if (PhysBody.HasPhysicalBody)
1413 { 1131 {
1414 DetailLog("{0},BSPrim.AddAngularForce,taint,angForce={1}", LocalID, angForce); 1132 DetailLog("{0},BSPrim.AddAngularForce,taint,angForce={1}", LocalID, angForce);
1415 PhysicsScene.PE.ApplyTorque(PhysBody, angForce); 1133 PhysScene.PE.ApplyTorque(PhysBody, angForce);
1416 ActivateIfPhysical(false); 1134 ActivateIfPhysical(false);
1417 } 1135 }
1418 }); 1136 });
@@ -1431,11 +1149,11 @@ public class BSPrim : BSPhysObject
1431 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) 1149 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
1432 { 1150 {
1433 OMV.Vector3 applyImpulse = impulse; 1151 OMV.Vector3 applyImpulse = impulse;
1434 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() 1152 PhysScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate()
1435 { 1153 {
1436 if (PhysBody.HasPhysicalBody) 1154 if (PhysBody.HasPhysicalBody)
1437 { 1155 {
1438 PhysicsScene.PE.ApplyTorqueImpulse(PhysBody, applyImpulse); 1156 PhysScene.PE.ApplyTorqueImpulse(PhysBody, applyImpulse);
1439 ActivateIfPhysical(false); 1157 ActivateIfPhysical(false);
1440 } 1158 }
1441 }); 1159 });
@@ -1721,9 +1439,9 @@ public class BSPrim : BSPhysObject
1721 volume *= (profileEnd - profileBegin); 1439 volume *= (profileEnd - profileBegin);
1722 1440
1723 returnMass = Density * BSParam.DensityScaleFactor * volume; 1441 returnMass = Density * BSParam.DensityScaleFactor * volume;
1724 DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass);
1725 1442
1726 returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); 1443 returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
1444 // DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass);
1727 1445
1728 return returnMass; 1446 return returnMass;
1729 }// end CalculateMass 1447 }// end CalculateMass
@@ -1736,13 +1454,14 @@ public class BSPrim : BSPhysObject
1736 { 1454 {
1737 // Create the correct physical representation for this type of object. 1455 // Create the correct physical representation for this type of object.
1738 // Updates base.PhysBody and base.PhysShape with the new information. 1456 // Updates base.PhysBody and base.PhysShape with the new information.
1739 // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. 1457 // Ignore 'forceRebuild'. 'GetBodyAndShape' makes the right choices and changes of necessary.
1740 PhysicsScene.Shapes.GetBodyAndShape(false /*forceRebuild */, PhysicsScene.World, this, null, delegate(BulletBody dBody) 1458 PhysScene.Shapes.GetBodyAndShape(false /*forceRebuild */, PhysScene.World, this, delegate(BulletBody pBody, BulletShape pShape)
1741 { 1459 {
1742 // Called if the current prim body is about to be destroyed. 1460 // Called if the current prim body is about to be destroyed.
1743 // Remove all the physical dependencies on the old body. 1461 // Remove all the physical dependencies on the old body.
1744 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) 1462 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
1745 RemoveBodyDependencies(); 1463 // Note: this virtual function is overloaded by BSPrimLinkable to remove linkset constraints.
1464 RemoveDependencies();
1746 }); 1465 });
1747 1466
1748 // Make sure the properties are set on the new object 1467 // Make sure the properties are set on the new object
@@ -1750,24 +1469,19 @@ public class BSPrim : BSPhysObject
1750 return; 1469 return;
1751 } 1470 }
1752 1471
1753 protected virtual void RemoveBodyDependencies() 1472 // Called at taint-time
1473 protected virtual void RemoveDependencies()
1754 { 1474 {
1755 VehicleController.RemoveBodyDependencies(this); 1475 PhysicalActors.RemoveDependencies();
1756 } 1476 }
1757 1477
1758 // The physics engine says that properties have updated. Update same and inform 1478 // The physics engine says that properties have updated. Update same and inform
1759 // the world that things have changed. 1479 // the world that things have changed.
1760 public override void UpdateProperties(EntityProperties entprop) 1480 public override void UpdateProperties(EntityProperties entprop)
1761 { 1481 {
1482 // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator.
1762 TriggerPreUpdatePropertyAction(ref entprop); 1483 TriggerPreUpdatePropertyAction(ref entprop);
1763 1484
1764 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
1765 // TODO: handle physics introduced by Bullet with computed vehicle physics.
1766 if (VehicleController.IsActive)
1767 {
1768 entprop.RotationalVelocity = OMV.Vector3.Zero;
1769 }
1770
1771 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG 1485 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1772 1486
1773 // Assign directly to the local variables so the normal set actions do not happen 1487 // Assign directly to the local variables so the normal set actions do not happen
@@ -1775,8 +1489,8 @@ public class BSPrim : BSPhysObject
1775 _orientation = entprop.Rotation; 1489 _orientation = entprop.Rotation;
1776 // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be 1490 // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be
1777 // very sensitive to velocity changes. 1491 // very sensitive to velocity changes.
1778 if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(_velocity, BSParam.UpdateVelocityChangeThreshold)) 1492 if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
1779 _velocity = entprop.Velocity; 1493 RawVelocity = entprop.Velocity;
1780 _acceleration = entprop.Acceleration; 1494 _acceleration = entprop.Acceleration;
1781 _rotationalVelocity = entprop.RotationalVelocity; 1495 _rotationalVelocity = entprop.RotationalVelocity;
1782 1496
@@ -1786,7 +1500,7 @@ public class BSPrim : BSPhysObject
1786 if (PositionSanityCheck(true /* inTaintTime */ )) 1500 if (PositionSanityCheck(true /* inTaintTime */ ))
1787 { 1501 {
1788 entprop.Position = _position; 1502 entprop.Position = _position;
1789 entprop.Velocity = _velocity; 1503 entprop.Velocity = RawVelocity;
1790 entprop.RotationalVelocity = _rotationalVelocity; 1504 entprop.RotationalVelocity = _rotationalVelocity;
1791 entprop.Acceleration = _acceleration; 1505 entprop.Acceleration = _acceleration;
1792 } 1506 }
@@ -1798,16 +1512,9 @@ public class BSPrim : BSPhysObject
1798 LastEntityProperties = CurrentEntityProperties; 1512 LastEntityProperties = CurrentEntityProperties;
1799 CurrentEntityProperties = entprop; 1513 CurrentEntityProperties = entprop;
1800 1514
1801 base.RequestPhysicsterseUpdate(); 1515 // Note that BSPrim can be overloaded by BSPrimLinkable which controls updates from root and children prims.
1802 /* 1516
1803 else 1517 PhysScene.PostUpdate(this);
1804 {
1805 // For debugging, report the movement of children
1806 DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1807 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
1808 entprop.Acceleration, entprop.RotationalVelocity);
1809 }
1810 */
1811 } 1518 }
1812} 1519}
1813} 1520}