aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs386
1 files changed, 0 insertions, 386 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
deleted file mode 100755
index e7cb3e0..0000000
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ /dev/null
@@ -1,386 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30
31using OMV = OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34
35namespace OpenSim.Region.Physics.BulletSPlugin
36{
37/*
38 * Class to wrap all objects.
39 * The rest of BulletSim doesn't need to keep checking for avatars or prims
40 * unless the difference is significant.
41 *
42 * Variables in the physicsl objects are in three forms:
43 * VariableName: used by the simulator and performs taint operations, etc
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.
46 * The last two (and certainly the last one) should be referenced only in taint-time.
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
58public abstract class BSPhysObject : PhysicsActor
59{
60 protected BSPhysObject()
61 {
62 }
63 protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
64 {
65 PhysicsScene = parentScene;
66 LocalID = localID;
67 PhysObjectName = name;
68 TypeName = typeName;
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
75 Linkset = BSLinkset.Factory(PhysicsScene, this);
76 LastAssetBuildFailed = false;
77
78 // Default material type
79 Material = MaterialAttributes.Material.Wood;
80
81 CollisionCollection = new CollisionEventUpdate();
82 SubscribedEventsMs = 0;
83 CollidingStep = 0;
84 CollidingGroundStep = 0;
85 }
86
87 // Tell the object to clean up.
88 public virtual void Destroy()
89 {
90 UnRegisterAllPreStepActions();
91 }
92
93 public BSScene PhysicsScene { get; protected set; }
94 // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor
95 public string PhysObjectName { get; protected set; }
96 public string TypeName { get; protected set; }
97
98 public BSLinkset Linkset { get; set; }
99 public BSLinksetInfo LinksetInfo { get; set; }
100
101 // Return the object mass without calculating it or having side effects
102 public abstract float RawMass { get; }
103 // Set the raw mass but also update physical mass properties (inertia, ...)
104 // 'inWorld' true if the object has already been added to the dynamic world.
105 public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld);
106
107 // The last value calculated for the prim's inertia
108 public OMV.Vector3 Inertia { get; set; }
109
110 // Reference to the physical body (btCollisionObject) of this object
111 public BulletBody PhysBody;
112 // Reference to the physical shape (btCollisionShape) of this object
113 public BulletShape PhysShape;
114
115 // 'true' if the mesh's underlying asset failed to build.
116 // This will keep us from looping after the first time the build failed.
117 public bool LastAssetBuildFailed { get; set; }
118
119 // The objects base shape information. Null if not a prim type shape.
120 public PrimitiveBaseShape BaseShape { get; protected set; }
121 // Some types of objects have preferred physical representations.
122 // Returns SHAPE_UNKNOWN if there is no preference.
123 public virtual BSPhysicsShapeType PreferredPhysicalShape
124 {
125 get { return BSPhysicsShapeType.SHAPE_UNKNOWN; }
126 }
127
128 // When the physical properties are updated, an EntityProperty holds the update values.
129 // Keep the current and last EntityProperties to enable computation of differences
130 // between the current update and the previous values.
131 public EntityProperties CurrentEntityProperties { get; set; }
132 public EntityProperties LastEntityProperties { get; set; }
133
134 public virtual OMV.Vector3 Scale { get; set; }
135 public abstract bool IsSolid { get; }
136 public abstract bool IsStatic { get; }
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
145 // Stop all physical motion.
146 public abstract void ZeroMotion(bool inTaintTime);
147 public abstract void ZeroAngularMotion(bool inTaintTime);
148
149 // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured.
150 public virtual void StepVehicle(float timeStep) { }
151
152 // Update the physical location and motion of the object. Called with data from Bullet.
153 public abstract void UpdateProperties(EntityProperties entprop);
154
155 public abstract OMV.Vector3 RawPosition { get; set; }
156 public abstract OMV.Vector3 ForcePosition { get; set; }
157
158 public abstract OMV.Quaternion RawOrientation { get; set; }
159 public abstract OMV.Quaternion ForceOrientation { get; set; }
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 }
172 public abstract OMV.Vector3 ForceVelocity { get; set; }
173
174 public abstract OMV.Vector3 ForceRotationalVelocity { get; set; }
175
176 public abstract float ForceBuoyancy { get; set; }
177
178 public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
179
180 #region Collisions
181
182 // Requested number of milliseconds between collision events. Zero means disabled.
183 protected int SubscribedEventsMs { get; set; }
184 // Given subscription, the time that a collision may be passed up
185 protected int NextCollisionOkTime { get; set; }
186 // The simulation step that last had a collision
187 protected long CollidingStep { get; set; }
188 // The simulation step that last had a collision with the ground
189 protected long CollidingGroundStep { get; set; }
190 // The simulation step that last collided with an object
191 protected long CollidingObjectStep { get; set; }
192 // The collision flags we think are set in Bullet
193 protected CollisionFlags CurrentCollisionFlags { get; set; }
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
224 // The collisions that have been collected this tick
225 protected CollisionEventUpdate CollisionCollection;
226
227 // The simulation step is telling this object about a collision.
228 // Return 'true' if a collision was processed and should be sent up.
229 // Called at taint time from within the Step() function
230 public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
231 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
232 {
233 bool ret = false;
234
235 // The following lines make IsColliding(), CollidingGround() and CollidingObj work
236 CollidingStep = PhysicsScene.SimulationStep;
237 if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID)
238 {
239 CollidingGroundStep = PhysicsScene.SimulationStep;
240 }
241 else
242 {
243 CollidingObjectStep = PhysicsScene.SimulationStep;
244 }
245
246 // prims in the same linkset cannot collide with each other
247 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
248 {
249 return ret;
250 }
251
252 // if someone has subscribed for collision events....
253 if (SubscribedEvents()) {
254 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
255 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}",
256 LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth);
257
258 ret = true;
259 }
260 return ret;
261 }
262
263 // Send the collected collisions into the simulator.
264 // Called at taint time from within the Step() function thus no locking problems
265 // with CollisionCollection and ObjectsWithNoMoreCollisions.
266 // Return 'true' if there were some actual collisions passed up
267 public virtual bool SendCollisions()
268 {
269 bool ret = true;
270 // If the 'no collision' call, force it to happen right now so quick collision_end
271 bool force = (CollisionCollection.Count == 0);
272
273 // throttle the collisions to the number of milliseconds specified in the subscription
274 if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime))
275 {
276 NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs;
277
278 // We are called if we previously had collisions. If there are no collisions
279 // this time, send up one last empty event so OpenSim can sense collision end.
280 if (CollisionCollection.Count == 0)
281 {
282 // If I have no collisions this time, remove me from the list of objects with collisions.
283 ret = false;
284 }
285
286 // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
287 base.SendCollisionUpdate(CollisionCollection);
288
289 // The CollisionCollection instance is passed around in the simulator.
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.
293 CollisionCollection = new CollisionEventUpdate();
294 }
295 return ret;
296 }
297
298 // Subscribe for collision events.
299 // Parameter is the millisecond rate the caller wishes collision events to occur.
300 public override void SubscribeEvents(int ms) {
301 // DetailLog("{0},{1}.SubscribeEvents,subscribing,ms={2}", LocalID, TypeName, ms);
302 SubscribedEventsMs = ms;
303 if (ms > 0)
304 {
305 // make sure first collision happens
306 NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs);
307
308 PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
309 {
310 if (PhysBody.HasPhysicalBody)
311 CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
312 });
313 }
314 else
315 {
316 // Subscribing for zero or less is the same as unsubscribing
317 UnSubscribeEvents();
318 }
319 }
320 public override void UnSubscribeEvents() {
321 // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName);
322 SubscribedEventsMs = 0;
323 PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate()
324 {
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);
328 });
329 }
330 // Return 'true' if the simulator wants collision events
331 public override bool SubscribedEvents() {
332 return (SubscribedEventsMs > 0);
333 }
334
335 #endregion // Collisions
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 RegisteredActions[identifier] = actn;
347 PhysicsScene.BeforeStep += actn;
348 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
349 }
350
351 // Unregister a pre step action. Safe to call if the action has not been registered.
352 protected void UnRegisterPreStepAction(string op, uint id)
353 {
354 string identifier = op + "-" + id.ToString();
355 bool removed = false;
356 if (RegisteredActions.ContainsKey(identifier))
357 {
358 PhysicsScene.BeforeStep -= RegisteredActions[identifier];
359 RegisteredActions.Remove(identifier);
360 removed = true;
361 }
362 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
363 }
364
365 protected void UnRegisterAllPreStepActions()
366 {
367 foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions)
368 {
369 PhysicsScene.BeforeStep -= kvp.Value;
370 }
371 RegisteredActions.Clear();
372 DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
373 }
374
375
376 #endregion // Per Simulation Step actions
377
378 // High performance detailed logging routine used by the physical objects.
379 protected void DetailLog(string msg, params Object[] args)
380 {
381 if (PhysicsScene.PhysicsLogging.Enabled)
382 PhysicsScene.DetailLog(msg, args);
383 }
384
385}
386}