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.cs147
1 files changed, 137 insertions, 10 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index f6a890e..534f929 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -45,6 +45,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
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 two (and certainly the last one) should be referenced only in taint-time.
47 */ 47 */
48
49/*
50 * As of 20121221, the following are the call sequences (going down) for different script physical functions:
51 * llApplyImpulse llApplyRotImpulse llSetTorque llSetForce
52 * SOP.ApplyImpulse SOP.ApplyAngularImpulse SOP.SetAngularImpulse SOP.SetForce
53 * SOG.ApplyImpulse SOG.ApplyAngularImpulse SOG.SetAngularImpulse
54 * PA.AddForce PA.AddAngularForce PA.Torque = v PA.Force = v
55 * BS.ApplyCentralForce BS.ApplyTorque
56 */
57
48public abstract class BSPhysObject : PhysicsActor 58public abstract class BSPhysObject : PhysicsActor
49{ 59{
50 protected BSPhysObject() 60 protected BSPhysObject()
@@ -57,26 +67,42 @@ public abstract class BSPhysObject : PhysicsActor
57 PhysObjectName = name; 67 PhysObjectName = name;
58 TypeName = typeName; 68 TypeName = typeName;
59 69
70 // We don't have any physical representation yet.
71 PhysBody = new BulletBody(localID);
72 PhysShape = new BulletShape();
73
74 // A linkset of just me
60 Linkset = BSLinkset.Factory(PhysicsScene, this); 75 Linkset = BSLinkset.Factory(PhysicsScene, this);
61 LastAssetBuildFailed = false; 76 LastAssetBuildFailed = false;
62 77
78 // Default material type
79 Material = MaterialAttributes.Material.Wood;
80
63 CollisionCollection = new CollisionEventUpdate(); 81 CollisionCollection = new CollisionEventUpdate();
64 SubscribedEventsMs = 0; 82 SubscribedEventsMs = 0;
65 CollidingStep = 0; 83 CollidingStep = 0;
66 CollidingGroundStep = 0; 84 CollidingGroundStep = 0;
67 } 85 }
68 86
87 // Tell the object to clean up.
88 public virtual void Destroy()
89 {
90 UnRegisterAllPreStepActions();
91 }
92
69 public BSScene PhysicsScene { get; protected set; } 93 public BSScene PhysicsScene { get; protected set; }
70 // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor 94 // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor
71 public string PhysObjectName { get; protected set; } 95 public string PhysObjectName { get; protected set; }
72 public string TypeName { get; protected set; } 96 public string TypeName { get; protected set; }
73 97
74 public BSLinkset Linkset { get; set; } 98 public BSLinkset Linkset { get; set; }
99 public BSLinksetInfo LinksetInfo { get; set; }
75 100
76 // Return the object mass without calculating it or having side effects 101 // Return the object mass without calculating it or having side effects
77 public abstract float RawMass { get; } 102 public abstract float RawMass { get; }
78 // Set the raw mass but also update physical mass properties (inertia, ...) 103 // Set the raw mass but also update physical mass properties (inertia, ...)
79 public abstract void UpdatePhysicalMassProperties(float mass); 104 // 'inWorld' true if the object has already been added to the dynamic world.
105 public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld);
80 106
81 // The last value calculated for the prim's inertia 107 // The last value calculated for the prim's inertia
82 public OMV.Vector3 Inertia { get; set; } 108 public OMV.Vector3 Inertia { get; set; }
@@ -105,10 +131,17 @@ public abstract class BSPhysObject : PhysicsActor
105 public EntityProperties CurrentEntityProperties { get; set; } 131 public EntityProperties CurrentEntityProperties { get; set; }
106 public EntityProperties LastEntityProperties { get; set; } 132 public EntityProperties LastEntityProperties { get; set; }
107 133
108 public abstract OMV.Vector3 Scale { get; set; } 134 public virtual OMV.Vector3 Scale { get; set; }
109 public abstract bool IsSolid { get; } 135 public abstract bool IsSolid { get; }
110 public abstract bool IsStatic { get; } 136 public abstract bool IsStatic { get; }
111 137
138 // Materialness
139 public MaterialAttributes.Material Material { get; private set; }
140 public override void SetMaterial(int material)
141 {
142 Material = (MaterialAttributes.Material)material;
143 }
144
112 // Stop all physical motion. 145 // Stop all physical motion.
113 public abstract void ZeroMotion(bool inTaintTime); 146 public abstract void ZeroMotion(bool inTaintTime);
114 public abstract void ZeroAngularMotion(bool inTaintTime); 147 public abstract void ZeroAngularMotion(bool inTaintTime);
@@ -119,15 +152,23 @@ public abstract class BSPhysObject : PhysicsActor
119 // Update the physical location and motion of the object. Called with data from Bullet. 152 // Update the physical location and motion of the object. Called with data from Bullet.
120 public abstract void UpdateProperties(EntityProperties entprop); 153 public abstract void UpdateProperties(EntityProperties entprop);
121 154
122 // Tell the object to clean up.
123 public abstract void Destroy();
124
125 public abstract OMV.Vector3 RawPosition { get; set; } 155 public abstract OMV.Vector3 RawPosition { get; set; }
126 public abstract OMV.Vector3 ForcePosition { get; set; } 156 public abstract OMV.Vector3 ForcePosition { get; set; }
127 157
128 public abstract OMV.Quaternion RawOrientation { get; set; } 158 public abstract OMV.Quaternion RawOrientation { get; set; }
129 public abstract OMV.Quaternion ForceOrientation { get; set; } 159 public abstract OMV.Quaternion ForceOrientation { get; set; }
130 160
161 // The system is telling us the velocity it wants to move at.
162 // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor
163 public override OMV.Vector3 TargetVelocity
164 {
165 get { return m_targetVelocity; }
166 set
167 {
168 m_targetVelocity = value;
169 Velocity = value;
170 }
171 }
131 public abstract OMV.Vector3 ForceVelocity { get; set; } 172 public abstract OMV.Vector3 ForceVelocity { get; set; }
132 173
133 public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } 174 public abstract OMV.Vector3 ForceRotationalVelocity { get; set; }
@@ -146,9 +187,40 @@ public abstract class BSPhysObject : PhysicsActor
146 protected long CollidingStep { get; set; } 187 protected long CollidingStep { get; set; }
147 // The simulation step that last had a collision with the ground 188 // The simulation step that last had a collision with the ground
148 protected long CollidingGroundStep { get; set; } 189 protected long CollidingGroundStep { get; set; }
190 // The simulation step that last collided with an object
191 protected long CollidingObjectStep { get; set; }
149 // The collision flags we think are set in Bullet 192 // The collision flags we think are set in Bullet
150 protected CollisionFlags CurrentCollisionFlags { get; set; } 193 protected CollisionFlags CurrentCollisionFlags { get; set; }
151 194
195 public override bool IsColliding {
196 get { return (CollidingStep == PhysicsScene.SimulationStep); }
197 set {
198 if (value)
199 CollidingStep = PhysicsScene.SimulationStep;
200 else
201 CollidingStep = 0;
202 }
203 }
204 public override bool CollidingGround {
205 get { return (CollidingGroundStep == PhysicsScene.SimulationStep); }
206 set
207 {
208 if (value)
209 CollidingGroundStep = PhysicsScene.SimulationStep;
210 else
211 CollidingGroundStep = 0;
212 }
213 }
214 public override bool CollidingObj {
215 get { return (CollidingObjectStep == PhysicsScene.SimulationStep); }
216 set {
217 if (value)
218 CollidingObjectStep = PhysicsScene.SimulationStep;
219 else
220 CollidingObjectStep = 0;
221 }
222 }
223
152 // The collisions that have been collected this tick 224 // The collisions that have been collected this tick
153 protected CollisionEventUpdate CollisionCollection; 225 protected CollisionEventUpdate CollisionCollection;
154 226
@@ -160,12 +232,16 @@ public abstract class BSPhysObject : PhysicsActor
160 { 232 {
161 bool ret = false; 233 bool ret = false;
162 234
163 // The following lines make IsColliding() and IsCollidingGround() work 235 // The following lines make IsColliding(), CollidingGround() and CollidingObj work
164 CollidingStep = PhysicsScene.SimulationStep; 236 CollidingStep = PhysicsScene.SimulationStep;
165 if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID) 237 if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID)
166 { 238 {
167 CollidingGroundStep = PhysicsScene.SimulationStep; 239 CollidingGroundStep = PhysicsScene.SimulationStep;
168 } 240 }
241 else
242 {
243 CollidingObjectStep = PhysicsScene.SimulationStep;
244 }
169 245
170 // prims in the same linkset cannot collide with each other 246 // prims in the same linkset cannot collide with each other
171 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) 247 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
@@ -192,7 +268,7 @@ public abstract class BSPhysObject : PhysicsActor
192 { 268 {
193 bool ret = true; 269 bool ret = true;
194 // If the 'no collision' call, force it to happen right now so quick collision_end 270 // If the 'no collision' call, force it to happen right now so quick collision_end
195 bool force = CollisionCollection.Count == 0; 271 bool force = (CollisionCollection.Count == 0);
196 272
197 // throttle the collisions to the number of milliseconds specified in the subscription 273 // throttle the collisions to the number of milliseconds specified in the subscription
198 if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) 274 if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime))
@@ -210,8 +286,10 @@ public abstract class BSPhysObject : PhysicsActor
210 // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); 286 // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
211 base.SendCollisionUpdate(CollisionCollection); 287 base.SendCollisionUpdate(CollisionCollection);
212 288
213 // The collisionCollection structure is passed around in the simulator. 289 // The CollisionCollection instance is passed around in the simulator.
214 // Make sure we don't have a handle to that one and that a new one is used for next time. 290 // Make sure we don't have a handle to that one and that a new one is used for next time.
291 // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here,
292 // a race condition is created for the other users of this instance.
215 CollisionCollection = new CollisionEventUpdate(); 293 CollisionCollection = new CollisionEventUpdate();
216 } 294 }
217 return ret; 295 return ret;
@@ -229,7 +307,8 @@ public abstract class BSPhysObject : PhysicsActor
229 307
230 PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() 308 PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
231 { 309 {
232 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 310 if (PhysBody.HasPhysicalBody)
311 CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
233 }); 312 });
234 } 313 }
235 else 314 else
@@ -243,7 +322,9 @@ public abstract class BSPhysObject : PhysicsActor
243 SubscribedEventsMs = 0; 322 SubscribedEventsMs = 0;
244 PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() 323 PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate()
245 { 324 {
246 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 325 // Make sure there is a body there because sometimes destruction happens in an un-ideal order.
326 if (PhysBody.HasPhysicalBody)
327 CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
247 }); 328 });
248 } 329 }
249 // Return 'true' if the simulator wants collision events 330 // Return 'true' if the simulator wants collision events
@@ -253,11 +334,57 @@ public abstract class BSPhysObject : PhysicsActor
253 334
254 #endregion // Collisions 335 #endregion // Collisions
255 336
337 #region Per Simulation Step actions
338 // There are some actions that must be performed for a physical object before each simulation step.
339 // These actions are optional so, rather than scanning all the physical objects and asking them
340 // if they have anything to do, a physical object registers for an event call before the step is performed.
341 // This bookkeeping makes it easy to add, remove and clean up after all these registrations.
342 private Dictionary<string, BSScene.PreStepAction> RegisteredActions = new Dictionary<string, BSScene.PreStepAction>();
343 protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn)
344 {
345 string identifier = op + "-" + id.ToString();
346
347 // Clean out any existing action
348 UnRegisterPreStepAction(op, id);
349
350 RegisteredActions[identifier] = actn;
351 PhysicsScene.BeforeStep += actn;
352 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
353 }
354
355 // Unregister a pre step action. Safe to call if the action has not been registered.
356 protected void UnRegisterPreStepAction(string op, uint id)
357 {
358 string identifier = op + "-" + id.ToString();
359 bool removed = false;
360 if (RegisteredActions.ContainsKey(identifier))
361 {
362 PhysicsScene.BeforeStep -= RegisteredActions[identifier];
363 RegisteredActions.Remove(identifier);
364 removed = true;
365 }
366 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
367 }
368
369 protected void UnRegisterAllPreStepActions()
370 {
371 foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions)
372 {
373 PhysicsScene.BeforeStep -= kvp.Value;
374 }
375 RegisteredActions.Clear();
376 DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
377 }
378
379
380 #endregion // Per Simulation Step actions
381
256 // High performance detailed logging routine used by the physical objects. 382 // High performance detailed logging routine used by the physical objects.
257 protected void DetailLog(string msg, params Object[] args) 383 protected void DetailLog(string msg, params Object[] args)
258 { 384 {
259 if (PhysicsScene.PhysicsLogging.Enabled) 385 if (PhysicsScene.PhysicsLogging.Enabled)
260 PhysicsScene.DetailLog(msg, args); 386 PhysicsScene.DetailLog(msg, args);
261 } 387 }
388
262} 389}
263} 390}