diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 645 |
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 | } |