aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs336
1 files changed, 150 insertions, 186 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 6bb88c7..cca887a 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -38,12 +38,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
38 * Class to wrap all objects. 38 * Class to wrap all objects.
39 * The rest of BulletSim doesn't need to keep checking for avatars or prims 39 * The rest of BulletSim doesn't need to keep checking for avatars or prims
40 * unless the difference is significant. 40 * unless the difference is significant.
41 * 41 *
42 * Variables in the physicsl objects are in three forms: 42 * Variables in the physicsl objects are in three forms:
43 * VariableName: used by the simulator and performs taint operations, etc 43 * VariableName: used by the simulator and performs taint operations, etc
44 * RawVariableName: direct reference to the BulletSim storage for the variable value 44 * RawVariableName: direct reference to the BulletSim storage for the variable value
45 * ForceVariableName: direct reference (store and fetch) to the value in the physics engine. 45 * ForceVariableName: direct reference (store and fetch) to the value in the physics engine.
46 * The last two (and certainly the last one) should be referenced only in taint-time. 46 * The last one should only be referenced in taint-time.
47 */ 47 */
48 48
49/* 49/*
@@ -52,7 +52,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
52 * SOP.ApplyImpulse SOP.ApplyAngularImpulse SOP.SetAngularImpulse SOP.SetForce 52 * SOP.ApplyImpulse SOP.ApplyAngularImpulse SOP.SetAngularImpulse SOP.SetForce
53 * SOG.ApplyImpulse SOG.ApplyAngularImpulse SOG.SetAngularImpulse 53 * SOG.ApplyImpulse SOG.ApplyAngularImpulse SOG.SetAngularImpulse
54 * PA.AddForce PA.AddAngularForce PA.Torque = v PA.Force = v 54 * PA.AddForce PA.AddAngularForce PA.Torque = v PA.Force = v
55 * BS.ApplyCentralForce BS.ApplyTorque 55 * BS.ApplyCentralForce BS.ApplyTorque
56 */ 56 */
57 57
58// Flags used to denote which properties updates when making UpdateProperties calls to linksets, etc. 58// Flags used to denote which properties updates when making UpdateProperties calls to linksets, etc.
@@ -72,19 +72,23 @@ public abstract class BSPhysObject : PhysicsActor
72 } 72 }
73 protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) 73 protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
74 { 74 {
75 PhysicsScene = parentScene; 75 PhysScene = parentScene;
76 LocalID = localID; 76 LocalID = localID;
77 PhysObjectName = name; 77 PhysObjectName = name;
78 Name = name; // PhysicsActor also has the name of the object. Someday consolidate. 78 Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
79 TypeName = typeName; 79 TypeName = typeName;
80 80
81 // The collection of things that push me around
82 PhysicalActors = new BSActorCollection(PhysScene);
83
81 // Initialize variables kept in base. 84 // Initialize variables kept in base.
82 GravModifier = 1.0f; 85 GravModifier = 1.0f;
83 Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); 86 Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
87 HoverActive = false;
84 88
85 // We don't have any physical representation yet. 89 // We don't have any physical representation yet.
86 PhysBody = new BulletBody(localID); 90 PhysBody = new BulletBody(localID);
87 PhysShape = new BulletShape(); 91 PhysShape = new BSShapeNull();
88 92
89 PrimAssetState = PrimAssetCondition.Unknown; 93 PrimAssetState = PrimAssetCondition.Unknown;
90 94
@@ -92,7 +96,10 @@ public abstract class BSPhysObject : PhysicsActor
92 SetMaterial((int)MaterialAttributes.Material.Wood); 96 SetMaterial((int)MaterialAttributes.Material.Wood);
93 97
94 CollisionCollection = new CollisionEventUpdate(); 98 CollisionCollection = new CollisionEventUpdate();
95 CollisionsLastTick = CollisionCollection; 99 CollisionsLastReported = CollisionCollection;
100 CollisionsLastTick = new CollisionEventUpdate();
101 CollisionsLastTickStep = -1;
102
96 SubscribedEventsMs = 0; 103 SubscribedEventsMs = 0;
97 CollidingStep = 0; 104 CollidingStep = 0;
98 CollidingGroundStep = 0; 105 CollidingGroundStep = 0;
@@ -101,17 +108,21 @@ public abstract class BSPhysObject : PhysicsActor
101 CollisionScore = 0; 108 CollisionScore = 0;
102 109
103 // All axis free. 110 // All axis free.
104 LockedAxis = LockedAxisFree; 111 LockedLinearAxis = LockedAxisFree;
112 LockedAngularAxis = LockedAxisFree;
105 } 113 }
106 114
107 // Tell the object to clean up. 115 // Tell the object to clean up.
108 public virtual void Destroy() 116 public virtual void Destroy()
109 { 117 {
110 UnRegisterAllPreStepActions(); 118 PhysicalActors.Enable(false);
111 UnRegisterAllPostStepActions(); 119 PhysScene.TaintedObject("BSPhysObject.Destroy", delegate()
120 {
121 PhysicalActors.Dispose();
122 });
112 } 123 }
113 124
114 public BSScene PhysicsScene { get; protected set; } 125 public BSScene PhysScene { get; protected set; }
115 // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor 126 // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor
116 public string PhysObjectName { get; protected set; } 127 public string PhysObjectName { get; protected set; }
117 public string TypeName { get; protected set; } 128 public string TypeName { get; protected set; }
@@ -131,7 +142,7 @@ public abstract class BSPhysObject : PhysicsActor
131 // Reference to the physical body (btCollisionObject) of this object 142 // Reference to the physical body (btCollisionObject) of this object
132 public BulletBody PhysBody; 143 public BulletBody PhysBody;
133 // Reference to the physical shape (btCollisionShape) of this object 144 // Reference to the physical shape (btCollisionShape) of this object
134 public BulletShape PhysShape; 145 public BSShape PhysShape;
135 146
136 // The physical representation of the prim might require an asset fetch. 147 // The physical representation of the prim might require an asset fetch.
137 // The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'. 148 // The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'.
@@ -144,13 +155,6 @@ public abstract class BSPhysObject : PhysicsActor
144 // The objects base shape information. Null if not a prim type shape. 155 // The objects base shape information. Null if not a prim type shape.
145 public PrimitiveBaseShape BaseShape { get; protected set; } 156 public PrimitiveBaseShape BaseShape { get; protected set; }
146 157
147 // Some types of objects have preferred physical representations.
148 // Returns SHAPE_UNKNOWN if there is no preference.
149 public virtual BSPhysicsShapeType PreferredPhysicalShape
150 {
151 get { return BSPhysicsShapeType.SHAPE_UNKNOWN; }
152 }
153
154 // When the physical properties are updated, an EntityProperty holds the update values. 158 // When the physical properties are updated, an EntityProperty holds the update values.
155 // Keep the current and last EntityProperties to enable computation of differences 159 // Keep the current and last EntityProperties to enable computation of differences
156 // between the current update and the previous values. 160 // between the current update and the previous values.
@@ -180,7 +184,7 @@ public abstract class BSPhysObject : PhysicsActor
180 Friction = matAttrib.friction; 184 Friction = matAttrib.friction;
181 Restitution = matAttrib.restitution; 185 Restitution = matAttrib.restitution;
182 Density = matAttrib.density / BSParam.DensityScaleFactor; 186 Density = matAttrib.density / BSParam.DensityScaleFactor;
183 DetailLog("{0},{1}.SetMaterial,Mat={2},frict={3},rest={4},den={5}", LocalID, TypeName, Material, Friction, Restitution, Density); 187 // DetailLog("{0},{1}.SetMaterial,Mat={2},frict={3},rest={4},den={5}", LocalID, TypeName, Material, Friction, Restitution, Density);
184 } 188 }
185 189
186 // Stop all physical motion. 190 // Stop all physical motion.
@@ -196,15 +200,48 @@ public abstract class BSPhysObject : PhysicsActor
196 public abstract OMV.Quaternion RawOrientation { get; set; } 200 public abstract OMV.Quaternion RawOrientation { get; set; }
197 public abstract OMV.Quaternion ForceOrientation { get; set; } 201 public abstract OMV.Quaternion ForceOrientation { get; set; }
198 202
199 public abstract OMV.Vector3 RawVelocity { get; set; } 203 public OMV.Vector3 RawVelocity { get; set; }
200 public abstract OMV.Vector3 ForceVelocity { get; set; } 204 public abstract OMV.Vector3 ForceVelocity { get; set; }
201 205
206 public OMV.Vector3 RawForce { get; set; }
207 public OMV.Vector3 RawTorque { get; set; }
208 public override void AddAngularForce(OMV.Vector3 force, bool pushforce)
209 {
210 AddAngularForce(force, pushforce, false);
211 }
212 public abstract void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime);
213
202 public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } 214 public abstract OMV.Vector3 ForceRotationalVelocity { get; set; }
203 215
204 public abstract float ForceBuoyancy { get; set; } 216 public abstract float ForceBuoyancy { get; set; }
205 217
206 public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } 218 public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
207 219
220 public override bool PIDActive { set { MoveToTargetActive = value; } }
221 public override OMV.Vector3 PIDTarget { set { MoveToTargetTarget = value; } }
222 public override float PIDTau { set { MoveToTargetTau = value; } }
223
224 public bool MoveToTargetActive { get; set; }
225 public OMV.Vector3 MoveToTargetTarget { get; set; }
226 public float MoveToTargetTau { get; set; }
227
228 // Used for llSetHoverHeight and maybe vehicle height. Hover Height will override MoveTo target's Z
229 public override bool PIDHoverActive { set { HoverActive = value; } }
230 public override float PIDHoverHeight { set { HoverHeight = value; } }
231 public override PIDHoverType PIDHoverType { set { HoverType = value; } }
232 public override float PIDHoverTau { set { HoverTau = value; } }
233
234 public bool HoverActive { get; set; }
235 public float HoverHeight { get; set; }
236 public PIDHoverType HoverType { get; set; }
237 public float HoverTau { get; set; }
238
239 // For RotLookAt
240 public override OMV.Quaternion APIDTarget { set { return; } }
241 public override bool APIDActive { set { return; } }
242 public override float APIDStrength { set { return; } }
243 public override float APIDDamping { set { return; } }
244
208 // The current velocity forward 245 // The current velocity forward
209 public virtual float ForwardSpeed 246 public virtual float ForwardSpeed
210 { 247 {
@@ -226,10 +263,58 @@ public abstract class BSPhysObject : PhysicsActor
226 263
227 // The user can optionally set the center of mass. The user's setting will override any 264 // The user can optionally set the center of mass. The user's setting will override any
228 // computed center-of-mass (like in linksets). 265 // computed center-of-mass (like in linksets).
229 public OMV.Vector3? UserSetCenterOfMass { get; set; } 266 // Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass.
267 public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; }
268
269 public OMV.Vector3 LockedLinearAxis { get; set; } // zero means locked. one means free.
270 public OMV.Vector3 LockedAngularAxis { get; set; } // zero means locked. one means free.
271 public const float FreeAxis = 1f;
272 public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free
273
274 // Enable physical actions. Bullet will keep sleeping non-moving physical objects so
275 // they need waking up when parameters are changed.
276 // Called in taint-time!!
277 public void ActivateIfPhysical(bool forceIt)
278 {
279 if (IsPhysical && PhysBody.HasPhysicalBody)
280 PhysScene.PE.Activate(PhysBody, forceIt);
281 }
230 282
231 public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free. 283 // 'actors' act on the physical object to change or constrain its motion. These can range from
232 public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free 284 // hovering to complex vehicle motion.
285 // May be called at non-taint time as this just adds the actor to the action list and the real
286 // work is done during the simulation step.
287 // Note that, if the actor is already in the list and we are disabling same, the actor is just left
288 // in the list disabled.
289 public delegate BSActor CreateActor();
290 public void EnableActor(bool enableActor, string actorName, CreateActor creator)
291 {
292 lock (PhysicalActors)
293 {
294 BSActor theActor;
295 if (PhysicalActors.TryGetActor(actorName, out theActor))
296 {
297 // The actor already exists so just turn it on or off
298 DetailLog("{0},BSPhysObject.EnableActor,enablingExistingActor,name={1},enable={2}", LocalID, actorName, enableActor);
299 theActor.Enabled = enableActor;
300 }
301 else
302 {
303 // The actor does not exist. If it should, create it.
304 if (enableActor)
305 {
306 DetailLog("{0},BSPhysObject.EnableActor,creatingActor,name={1}", LocalID, actorName);
307 theActor = creator();
308 PhysicalActors.Add(actorName, theActor);
309 theActor.Enabled = true;
310 }
311 else
312 {
313 DetailLog("{0},BSPhysObject.EnableActor,notCreatingActorSinceNotEnabled,name={1}", LocalID, actorName);
314 }
315 }
316 }
317 }
233 318
234 #region Collisions 319 #region Collisions
235 320
@@ -247,45 +332,50 @@ public abstract class BSPhysObject : PhysicsActor
247 protected CollisionFlags CurrentCollisionFlags { get; set; } 332 protected CollisionFlags CurrentCollisionFlags { get; set; }
248 // On a collision, check the collider and remember if the last collider was moving 333 // On a collision, check the collider and remember if the last collider was moving
249 // Used to modify the standing of avatars (avatars on stationary things stand still) 334 // Used to modify the standing of avatars (avatars on stationary things stand still)
250 protected bool ColliderIsMoving; 335 public bool ColliderIsMoving;
336 // Used by BSCharacter to manage standing (and not slipping)
337 public bool IsStationary;
251 338
252 // Count of collisions for this object 339 // Count of collisions for this object
253 protected long CollisionAccumulation { get; set; } 340 protected long CollisionAccumulation { get; set; }
254 341
255 public override bool IsColliding { 342 public override bool IsColliding {
256 get { return (CollidingStep == PhysicsScene.SimulationStep); } 343 get { return (CollidingStep == PhysScene.SimulationStep); }
257 set { 344 set {
258 if (value) 345 if (value)
259 CollidingStep = PhysicsScene.SimulationStep; 346 CollidingStep = PhysScene.SimulationStep;
260 else 347 else
261 CollidingStep = 0; 348 CollidingStep = 0;
262 } 349 }
263 } 350 }
264 public override bool CollidingGround { 351 public override bool CollidingGround {
265 get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } 352 get { return (CollidingGroundStep == PhysScene.SimulationStep); }
266 set 353 set
267 { 354 {
268 if (value) 355 if (value)
269 CollidingGroundStep = PhysicsScene.SimulationStep; 356 CollidingGroundStep = PhysScene.SimulationStep;
270 else 357 else
271 CollidingGroundStep = 0; 358 CollidingGroundStep = 0;
272 } 359 }
273 } 360 }
274 public override bool CollidingObj { 361 public override bool CollidingObj {
275 get { return (CollidingObjectStep == PhysicsScene.SimulationStep); } 362 get { return (CollidingObjectStep == PhysScene.SimulationStep); }
276 set { 363 set {
277 if (value) 364 if (value)
278 CollidingObjectStep = PhysicsScene.SimulationStep; 365 CollidingObjectStep = PhysScene.SimulationStep;
279 else 366 else
280 CollidingObjectStep = 0; 367 CollidingObjectStep = 0;
281 } 368 }
282 } 369 }
283 370
284 // The collisions that have been collected this tick 371 // The collisions that have been collected for the next collision reporting (throttled by subscription)
285 protected CollisionEventUpdate CollisionCollection; 372 protected CollisionEventUpdate CollisionCollection;
286 // Remember collisions from last tick for fancy collision based actions 373 // This is the collision collection last reported to the Simulator.
374 public CollisionEventUpdate CollisionsLastReported;
375 // Remember the collisions recorded in the last tick for fancy collision checking
287 // (like a BSCharacter walking up stairs). 376 // (like a BSCharacter walking up stairs).
288 protected CollisionEventUpdate CollisionsLastTick; 377 public CollisionEventUpdate CollisionsLastTick;
378 private long CollisionsLastTickStep = -1;
289 379
290 // The simulation step is telling this object about a collision. 380 // The simulation step is telling this object about a collision.
291 // Return 'true' if a collision was processed and should be sent up. 381 // Return 'true' if a collision was processed and should be sent up.
@@ -297,14 +387,14 @@ public abstract class BSPhysObject : PhysicsActor
297 bool ret = false; 387 bool ret = false;
298 388
299 // The following lines make IsColliding(), CollidingGround() and CollidingObj work 389 // The following lines make IsColliding(), CollidingGround() and CollidingObj work
300 CollidingStep = PhysicsScene.SimulationStep; 390 CollidingStep = PhysScene.SimulationStep;
301 if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID) 391 if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID)
302 { 392 {
303 CollidingGroundStep = PhysicsScene.SimulationStep; 393 CollidingGroundStep = PhysScene.SimulationStep;
304 } 394 }
305 else 395 else
306 { 396 {
307 CollidingObjectStep = PhysicsScene.SimulationStep; 397 CollidingObjectStep = PhysScene.SimulationStep;
308 } 398 }
309 399
310 CollisionAccumulation++; 400 CollisionAccumulation++;
@@ -312,6 +402,15 @@ public abstract class BSPhysObject : PhysicsActor
312 // For movement tests, remember if we are colliding with an object that is moving. 402 // For movement tests, remember if we are colliding with an object that is moving.
313 ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; 403 ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false;
314 404
405 // Make a collection of the collisions that happened the last simulation tick.
406 // This is different than the collection created for sending up to the simulator as it is cleared every tick.
407 if (CollisionsLastTickStep != PhysScene.SimulationStep)
408 {
409 CollisionsLastTick = new CollisionEventUpdate();
410 CollisionsLastTickStep = PhysScene.SimulationStep;
411 }
412 CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
413
315 // If someone has subscribed for collision events log the collision so it will be reported up 414 // If someone has subscribed for collision events log the collision so it will be reported up
316 if (SubscribedEvents()) { 415 if (SubscribedEvents()) {
317 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 416 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
@@ -332,12 +431,12 @@ public abstract class BSPhysObject : PhysicsActor
332 bool ret = true; 431 bool ret = true;
333 432
334 // If the 'no collision' call, force it to happen right now so quick collision_end 433 // If the 'no collision' call, force it to happen right now so quick collision_end
335 bool force = (CollisionCollection.Count == 0 && CollisionsLastTick.Count != 0); 434 bool force = (CollisionCollection.Count == 0 && CollisionsLastReported.Count != 0);
336 435
337 // throttle the collisions to the number of milliseconds specified in the subscription 436 // throttle the collisions to the number of milliseconds specified in the subscription
338 if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) 437 if (force || (PhysScene.SimulationNowTime >= NextCollisionOkTime))
339 { 438 {
340 NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs; 439 NextCollisionOkTime = PhysScene.SimulationNowTime + SubscribedEventsMs;
341 440
342 // We are called if we previously had collisions. If there are no collisions 441 // We are called if we previously had collisions. If there are no collisions
343 // this time, send up one last empty event so OpenSim can sense collision end. 442 // this time, send up one last empty event so OpenSim can sense collision end.
@@ -351,11 +450,11 @@ public abstract class BSPhysObject : PhysicsActor
351 base.SendCollisionUpdate(CollisionCollection); 450 base.SendCollisionUpdate(CollisionCollection);
352 451
353 // Remember the collisions from this tick for some collision specific processing. 452 // Remember the collisions from this tick for some collision specific processing.
354 CollisionsLastTick = CollisionCollection; 453 CollisionsLastReported = CollisionCollection;
355 454
356 // The CollisionCollection instance is passed around in the simulator. 455 // The CollisionCollection instance is passed around in the simulator.
357 // Make sure we don't have a handle to that one and that a new one is used for next time. 456 // Make sure we don't have a handle to that one and that a new one is used for next time.
358 // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, 457 // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here,
359 // a race condition is created for the other users of this instance. 458 // a race condition is created for the other users of this instance.
360 CollisionCollection = new CollisionEventUpdate(); 459 CollisionCollection = new CollisionEventUpdate();
361 } 460 }
@@ -372,10 +471,10 @@ public abstract class BSPhysObject : PhysicsActor
372 // make sure first collision happens 471 // make sure first collision happens
373 NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs); 472 NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs);
374 473
375 PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() 474 PhysScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
376 { 475 {
377 if (PhysBody.HasPhysicalBody) 476 if (PhysBody.HasPhysicalBody)
378 CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 477 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
379 }); 478 });
380 } 479 }
381 else 480 else
@@ -387,11 +486,11 @@ public abstract class BSPhysObject : PhysicsActor
387 public override void UnSubscribeEvents() { 486 public override void UnSubscribeEvents() {
388 // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName); 487 // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName);
389 SubscribedEventsMs = 0; 488 SubscribedEventsMs = 0;
390 PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() 489 PhysScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate()
391 { 490 {
392 // Make sure there is a body there because sometimes destruction happens in an un-ideal order. 491 // Make sure there is a body there because sometimes destruction happens in an un-ideal order.
393 if (PhysBody.HasPhysicalBody) 492 if (PhysBody.HasPhysicalBody)
394 CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 493 CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
395 }); 494 });
396 } 495 }
397 // Return 'true' if the simulator wants collision events 496 // Return 'true' if the simulator wants collision events
@@ -405,7 +504,7 @@ public abstract class BSPhysObject : PhysicsActor
405 { 504 {
406 // Scale the collision count by the time since the last collision. 505 // Scale the collision count by the time since the last collision.
407 // The "+1" prevents dividing by zero. 506 // The "+1" prevents dividing by zero.
408 long timeAgo = PhysicsScene.SimulationStep - CollidingStep + 1; 507 long timeAgo = PhysScene.SimulationStep - CollidingStep + 1;
409 CollisionScore = CollisionAccumulation / timeAgo; 508 CollisionScore = CollisionAccumulation / timeAgo;
410 } 509 }
411 public override float CollisionScore { get; set; } 510 public override float CollisionScore { get; set; }
@@ -413,103 +512,8 @@ public abstract class BSPhysObject : PhysicsActor
413 #endregion // Collisions 512 #endregion // Collisions
414 513
415 #region Per Simulation Step actions 514 #region Per Simulation Step actions
416 // There are some actions that must be performed for a physical object before each simulation step.
417 // These actions are optional so, rather than scanning all the physical objects and asking them
418 // if they have anything to do, a physical object registers for an event call before the step is performed.
419 // This bookkeeping makes it easy to add, remove and clean up after all these registrations.
420 private Dictionary<string, BSScene.PreStepAction> RegisteredPrestepActions = new Dictionary<string, BSScene.PreStepAction>();
421 private Dictionary<string, BSScene.PostStepAction> RegisteredPoststepActions = new Dictionary<string, BSScene.PostStepAction>();
422 protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn)
423 {
424 string identifier = op + "-" + id.ToString();
425 515
426 lock (RegisteredPrestepActions) 516 public BSActorCollection PhysicalActors;
427 {
428 // Clean out any existing action
429 UnRegisterPreStepAction(op, id);
430 RegisteredPrestepActions[identifier] = actn;
431 PhysicsScene.BeforeStep += actn;
432 }
433 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
434 }
435
436 // Unregister a pre step action. Safe to call if the action has not been registered.
437 // Returns 'true' if an action was actually removed
438 protected bool UnRegisterPreStepAction(string op, uint id)
439 {
440 string identifier = op + "-" + id.ToString();
441 bool removed = false;
442 lock (RegisteredPrestepActions)
443 {
444 if (RegisteredPrestepActions.ContainsKey(identifier))
445 {
446 PhysicsScene.BeforeStep -= RegisteredPrestepActions[identifier];
447 RegisteredPrestepActions.Remove(identifier);
448 removed = true;
449 }
450 }
451 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
452 return removed;
453 }
454
455 protected void UnRegisterAllPreStepActions()
456 {
457 lock (RegisteredPrestepActions)
458 {
459 foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredPrestepActions)
460 {
461 PhysicsScene.BeforeStep -= kvp.Value;
462 }
463 RegisteredPrestepActions.Clear();
464 }
465 DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
466 }
467
468 protected void RegisterPostStepAction(string op, uint id, BSScene.PostStepAction actn)
469 {
470 string identifier = op + "-" + id.ToString();
471
472 lock (RegisteredPoststepActions)
473 {
474 // Clean out any existing action
475 UnRegisterPostStepAction(op, id);
476 RegisteredPoststepActions[identifier] = actn;
477 PhysicsScene.AfterStep += actn;
478 }
479 DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier);
480 }
481
482 // Unregister a pre step action. Safe to call if the action has not been registered.
483 // Returns 'true' if an action was actually removed.
484 protected bool UnRegisterPostStepAction(string op, uint id)
485 {
486 string identifier = op + "-" + id.ToString();
487 bool removed = false;
488 lock (RegisteredPoststepActions)
489 {
490 if (RegisteredPoststepActions.ContainsKey(identifier))
491 {
492 PhysicsScene.AfterStep -= RegisteredPoststepActions[identifier];
493 RegisteredPoststepActions.Remove(identifier);
494 removed = true;
495 }
496 }
497 DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed);
498 return removed;
499 }
500
501 protected void UnRegisterAllPostStepActions()
502 {
503 lock (RegisteredPoststepActions)
504 {
505 foreach (KeyValuePair<string, BSScene.PostStepAction> kvp in RegisteredPoststepActions)
506 {
507 PhysicsScene.AfterStep -= kvp.Value;
508 }
509 RegisteredPoststepActions.Clear();
510 }
511 DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID);
512 }
513 517
514 // When an update to the physical properties happens, this event is fired to let 518 // When an update to the physical properties happens, this event is fired to let
515 // different actors to modify the update before it is passed around 519 // different actors to modify the update before it is passed around
@@ -522,53 +526,13 @@ public abstract class BSPhysObject : PhysicsActor
522 actions(ref entprop); 526 actions(ref entprop);
523 } 527 }
524 528
525 private Dictionary<string, PreUpdatePropertyAction> RegisteredPreUpdatePropertyActions = new Dictionary<string, PreUpdatePropertyAction>();
526 public void RegisterPreUpdatePropertyAction(string identifier, PreUpdatePropertyAction actn)
527 {
528 lock (RegisteredPreUpdatePropertyActions)
529 {
530 // Clean out any existing action
531 UnRegisterPreUpdatePropertyAction(identifier);
532 RegisteredPreUpdatePropertyActions[identifier] = actn;
533 OnPreUpdateProperty += actn;
534 }
535 DetailLog("{0},BSPhysObject.RegisterPreUpdatePropertyAction,id={1}", LocalID, identifier);
536 }
537 public bool UnRegisterPreUpdatePropertyAction(string identifier)
538 {
539 bool removed = false;
540 lock (RegisteredPreUpdatePropertyActions)
541 {
542 if (RegisteredPreUpdatePropertyActions.ContainsKey(identifier))
543 {
544 OnPreUpdateProperty -= RegisteredPreUpdatePropertyActions[identifier];
545 RegisteredPreUpdatePropertyActions.Remove(identifier);
546 removed = true;
547 }
548 }
549 DetailLog("{0},BSPhysObject.UnRegisterPreUpdatePropertyAction,id={1},removed={2}", LocalID, identifier, removed);
550 return removed;
551 }
552 public void UnRegisterAllPreUpdatePropertyActions()
553 {
554 lock (RegisteredPreUpdatePropertyActions)
555 {
556 foreach (KeyValuePair<string, PreUpdatePropertyAction> kvp in RegisteredPreUpdatePropertyActions)
557 {
558 OnPreUpdateProperty -= kvp.Value;
559 }
560 RegisteredPreUpdatePropertyActions.Clear();
561 }
562 DetailLog("{0},BSPhysObject.UnRegisterAllPreUpdatePropertyAction,", LocalID);
563 }
564
565 #endregion // Per Simulation Step actions 529 #endregion // Per Simulation Step actions
566 530
567 // High performance detailed logging routine used by the physical objects. 531 // High performance detailed logging routine used by the physical objects.
568 protected void DetailLog(string msg, params Object[] args) 532 protected void DetailLog(string msg, params Object[] args)
569 { 533 {
570 if (PhysicsScene.PhysicsLogging.Enabled) 534 if (PhysScene.PhysicsLogging.Enabled)
571 PhysicsScene.DetailLog(msg, args); 535 PhysScene.DetailLog(msg, args);
572 } 536 }
573 537
574} 538}