aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs197
1 files changed, 153 insertions, 44 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 4ece1eb..3afd52e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -33,14 +33,6 @@ using OMV = OpenMetaverse;
33namespace OpenSim.Region.Physics.BulletSPlugin 33namespace OpenSim.Region.Physics.BulletSPlugin
34{ 34{
35 35
36// A BSPrim can get individual information about its linkedness attached
37// to it through an instance of a subclass of LinksetInfo.
38// Each type of linkset will define the information needed for its type.
39public abstract class BSLinksetInfo
40{
41 public virtual void Clear() { }
42}
43
44public abstract class BSLinkset 36public abstract class BSLinkset
45{ 37{
46 // private static string LogHeader = "[BULLETSIM LINKSET]"; 38 // private static string LogHeader = "[BULLETSIM LINKSET]";
@@ -56,15 +48,15 @@ public abstract class BSLinkset
56 { 48 {
57 BSLinkset ret = null; 49 BSLinkset ret = null;
58 50
59 switch ((int)BSParam.LinksetImplementation) 51 switch (parent.LinksetType)
60 { 52 {
61 case (int)LinksetImplementation.Constraint: 53 case LinksetImplementation.Constraint:
62 ret = new BSLinksetConstraints(physScene, parent); 54 ret = new BSLinksetConstraints(physScene, parent);
63 break; 55 break;
64 case (int)LinksetImplementation.Compound: 56 case LinksetImplementation.Compound:
65 ret = new BSLinksetCompound(physScene, parent); 57 ret = new BSLinksetCompound(physScene, parent);
66 break; 58 break;
67 case (int)LinksetImplementation.Manual: 59 case LinksetImplementation.Manual:
68 // ret = new BSLinksetManual(physScene, parent); 60 // ret = new BSLinksetManual(physScene, parent);
69 break; 61 break;
70 default: 62 default:
@@ -78,28 +70,33 @@ public abstract class BSLinkset
78 return ret; 70 return ret;
79 } 71 }
80 72
73 public class BSLinkInfo
74 {
75 public BSPrimLinkable member;
76 public BSLinkInfo(BSPrimLinkable pMember)
77 {
78 member = pMember;
79 }
80 }
81
82 public LinksetImplementation LinksetImpl { get; protected set; }
83
81 public BSPrimLinkable LinksetRoot { get; protected set; } 84 public BSPrimLinkable LinksetRoot { get; protected set; }
82 85
83 public BSScene PhysicsScene { get; private set; } 86 protected BSScene m_physicsScene { get; private set; }
84 87
85 static int m_nextLinksetID = 1; 88 static int m_nextLinksetID = 1;
86 public int LinksetID { get; private set; } 89 public int LinksetID { get; private set; }
87 90
88 // The children under the root in this linkset. 91 // The children under the root in this linkset.
89 protected HashSet<BSPrimLinkable> m_children; 92 // protected HashSet<BSPrimLinkable> m_children;
93 protected Dictionary<BSPrimLinkable, BSLinkInfo> m_children;
90 94
91 // We lock the diddling of linkset classes to prevent any badness. 95 // We lock the diddling of linkset classes to prevent any badness.
92 // This locks the modification of the instances of this class. Changes 96 // This locks the modification of the instances of this class. Changes
93 // to the physical representation is done via the tainting mechenism. 97 // to the physical representation is done via the tainting mechenism.
94 protected object m_linksetActivityLock = new Object(); 98 protected object m_linksetActivityLock = new Object();
95 99
96 // Some linksets have a preferred physical shape.
97 // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
98 public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
99 {
100 return BSPhysicsShapeType.SHAPE_UNKNOWN;
101 }
102
103 // We keep the prim's mass in the linkset structure since it could be dependent on other prims 100 // We keep the prim's mass in the linkset structure since it could be dependent on other prims
104 public float LinksetMass { get; protected set; } 101 public float LinksetMass { get; protected set; }
105 102
@@ -122,9 +119,9 @@ public abstract class BSLinkset
122 // We create LOTS of linksets. 119 // We create LOTS of linksets.
123 if (m_nextLinksetID <= 0) 120 if (m_nextLinksetID <= 0)
124 m_nextLinksetID = 1; 121 m_nextLinksetID = 1;
125 PhysicsScene = scene; 122 m_physicsScene = scene;
126 LinksetRoot = parent; 123 LinksetRoot = parent;
127 m_children = new HashSet<BSPrimLinkable>(); 124 m_children = new Dictionary<BSPrimLinkable, BSLinkInfo>();
128 LinksetMass = parent.RawMass; 125 LinksetMass = parent.RawMass;
129 Rebuilding = false; 126 Rebuilding = false;
130 127
@@ -165,7 +162,7 @@ public abstract class BSLinkset
165 } 162 }
166 163
167 // The child is down to a linkset of just itself 164 // The child is down to a linkset of just itself
168 return BSLinkset.Factory(PhysicsScene, child); 165 return BSLinkset.Factory(m_physicsScene, child);
169 } 166 }
170 167
171 // Return 'true' if the passed object is the root object of this linkset 168 // Return 'true' if the passed object is the root object of this linkset
@@ -185,17 +182,7 @@ public abstract class BSLinkset
185 bool ret = false; 182 bool ret = false;
186 lock (m_linksetActivityLock) 183 lock (m_linksetActivityLock)
187 { 184 {
188 ret = m_children.Contains(child); 185 ret = m_children.ContainsKey(child);
189 /* Safer version but the above should work
190 foreach (BSPrimLinkable bp in m_children)
191 {
192 if (child.LocalID == bp.LocalID)
193 {
194 ret = true;
195 break;
196 }
197 }
198 */
199 } 186 }
200 return ret; 187 return ret;
201 } 188 }
@@ -209,7 +196,24 @@ public abstract class BSLinkset
209 lock (m_linksetActivityLock) 196 lock (m_linksetActivityLock)
210 { 197 {
211 action(LinksetRoot); 198 action(LinksetRoot);
212 foreach (BSPrimLinkable po in m_children) 199 foreach (BSPrimLinkable po in m_children.Keys)
200 {
201 if (action(po))
202 break;
203 }
204 }
205 return ret;
206 }
207
208 // Perform an action on each member of the linkset including root prim.
209 // Depends on the action on whether this should be done at taint time.
210 public delegate bool ForEachLinkInfoAction(BSLinkInfo obj);
211 public virtual bool ForEachLinkInfo(ForEachLinkInfoAction action)
212 {
213 bool ret = false;
214 lock (m_linksetActivityLock)
215 {
216 foreach (BSLinkInfo po in m_children.Values)
213 { 217 {
214 if (action(po)) 218 if (action(po))
215 break; 219 break;
@@ -218,10 +222,37 @@ public abstract class BSLinkset
218 return ret; 222 return ret;
219 } 223 }
220 224
225 // Called after a simulation step to post a collision with this object.
226 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have
227 // anything to add for the collision and it should be passed through normal processing.
228 // Default processing for a linkset.
229 public virtual bool HandleCollide(uint collidingWith, BSPhysObject collidee,
230 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
231 {
232 bool ret = false;
233
234 // prims in the same linkset cannot collide with each other
235 BSPrimLinkable convCollidee = collidee as BSPrimLinkable;
236 if (convCollidee != null && (LinksetID == convCollidee.Linkset.LinksetID))
237 {
238 // By returning 'true', we tell the caller the collision has been 'handled' so it won't
239 // do anything about this collision and thus, effectivily, ignoring the collision.
240 ret = true;
241 }
242 else
243 {
244 // Not a collision between members of the linkset. Must be a real collision.
245 // So the linkset root can know if there is a collision anywhere in the linkset.
246 LinksetRoot.SomeCollisionSimulationStep = m_physicsScene.SimulationStep;
247 }
248
249 return ret;
250 }
251
221 // I am the root of a linkset and a new child is being added 252 // I am the root of a linkset and a new child is being added
222 // Called while LinkActivity is locked. 253 // Called while LinkActivity is locked.
223 protected abstract void AddChildToLinkset(BSPrimLinkable child); 254 protected abstract void AddChildToLinkset(BSPrimLinkable child);
224 255
225 // I am the root of a linkset and one of my children is being removed. 256 // I am the root of a linkset and one of my children is being removed.
226 // Safe to call even if the child is not really in my linkset. 257 // Safe to call even if the child is not really in my linkset.
227 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child); 258 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child);
@@ -263,8 +294,87 @@ public abstract class BSLinkset
263 // This is called when the root body is changing. 294 // This is called when the root body is changing.
264 // Returns 'true' of something was actually removed and would need restoring 295 // Returns 'true' of something was actually removed and would need restoring
265 // Called at taint-time!! 296 // Called at taint-time!!
266 public abstract bool RemoveBodyDependencies(BSPrimLinkable child); 297 public abstract bool RemoveDependencies(BSPrimLinkable child);
298
299 // ================================================================
300 // Some physical setting happen to all members of the linkset
301 public virtual void SetPhysicalFriction(float friction)
302 {
303 ForEachMember((member) =>
304 {
305 if (member.PhysBody.HasPhysicalBody)
306 m_physicsScene.PE.SetFriction(member.PhysBody, friction);
307 return false; // 'false' says to continue looping
308 }
309 );
310 }
311 public virtual void SetPhysicalRestitution(float restitution)
312 {
313 ForEachMember((member) =>
314 {
315 if (member.PhysBody.HasPhysicalBody)
316 m_physicsScene.PE.SetRestitution(member.PhysBody, restitution);
317 return false; // 'false' says to continue looping
318 }
319 );
320 }
321 public virtual void SetPhysicalGravity(OMV.Vector3 gravity)
322 {
323 ForEachMember((member) =>
324 {
325 if (member.PhysBody.HasPhysicalBody)
326 m_physicsScene.PE.SetGravity(member.PhysBody, gravity);
327 return false; // 'false' says to continue looping
328 }
329 );
330 }
331 public virtual void ComputeAndSetLocalInertia(OMV.Vector3 inertiaFactor, float linksetMass)
332 {
333 ForEachMember((member) =>
334 {
335 if (member.PhysBody.HasPhysicalBody)
336 {
337 OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(member.PhysShape.physShapeInfo, linksetMass);
338 member.Inertia = inertia * inertiaFactor;
339 m_physicsScene.PE.SetMassProps(member.PhysBody, linksetMass, member.Inertia);
340 m_physicsScene.PE.UpdateInertiaTensor(member.PhysBody);
341 DetailLog("{0},BSLinkset.ComputeAndSetLocalInertia,m.mass={1}, inertia={2}", member.LocalID, linksetMass, member.Inertia);
267 342
343 }
344 return false; // 'false' says to continue looping
345 }
346 );
347 }
348 public virtual void SetPhysicalCollisionFlags(CollisionFlags collFlags)
349 {
350 ForEachMember((member) =>
351 {
352 if (member.PhysBody.HasPhysicalBody)
353 m_physicsScene.PE.SetCollisionFlags(member.PhysBody, collFlags);
354 return false; // 'false' says to continue looping
355 }
356 );
357 }
358 public virtual void AddToPhysicalCollisionFlags(CollisionFlags collFlags)
359 {
360 ForEachMember((member) =>
361 {
362 if (member.PhysBody.HasPhysicalBody)
363 m_physicsScene.PE.AddToCollisionFlags(member.PhysBody, collFlags);
364 return false; // 'false' says to continue looping
365 }
366 );
367 }
368 public virtual void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags)
369 {
370 ForEachMember((member) =>
371 {
372 if (member.PhysBody.HasPhysicalBody)
373 m_physicsScene.PE.RemoveFromCollisionFlags(member.PhysBody, collFlags);
374 return false; // 'false' says to continue looping
375 }
376 );
377 }
268 // ================================================================ 378 // ================================================================
269 protected virtual float ComputeLinksetMass() 379 protected virtual float ComputeLinksetMass()
270 { 380 {
@@ -273,7 +383,7 @@ public abstract class BSLinkset
273 { 383 {
274 lock (m_linksetActivityLock) 384 lock (m_linksetActivityLock)
275 { 385 {
276 foreach (BSPrimLinkable bp in m_children) 386 foreach (BSPrimLinkable bp in m_children.Keys)
277 { 387 {
278 mass += bp.RawMass; 388 mass += bp.RawMass;
279 } 389 }
@@ -291,7 +401,7 @@ public abstract class BSLinkset
291 com = LinksetRoot.Position * LinksetRoot.RawMass; 401 com = LinksetRoot.Position * LinksetRoot.RawMass;
292 float totalMass = LinksetRoot.RawMass; 402 float totalMass = LinksetRoot.RawMass;
293 403
294 foreach (BSPrimLinkable bp in m_children) 404 foreach (BSPrimLinkable bp in m_children.Keys)
295 { 405 {
296 com += bp.Position * bp.RawMass; 406 com += bp.Position * bp.RawMass;
297 totalMass += bp.RawMass; 407 totalMass += bp.RawMass;
@@ -310,7 +420,7 @@ public abstract class BSLinkset
310 { 420 {
311 com = LinksetRoot.Position; 421 com = LinksetRoot.Position;
312 422
313 foreach (BSPrimLinkable bp in m_children) 423 foreach (BSPrimLinkable bp in m_children.Keys)
314 { 424 {
315 com += bp.Position; 425 com += bp.Position;
316 } 426 }
@@ -323,9 +433,8 @@ public abstract class BSLinkset
323 // Invoke the detailed logger and output something if it's enabled. 433 // Invoke the detailed logger and output something if it's enabled.
324 protected void DetailLog(string msg, params Object[] args) 434 protected void DetailLog(string msg, params Object[] args)
325 { 435 {
326 if (PhysicsScene.PhysicsLogging.Enabled) 436 if (m_physicsScene.PhysicsLogging.Enabled)
327 PhysicsScene.DetailLog(msg, args); 437 m_physicsScene.DetailLog(msg, args);
328 } 438 }
329
330} 439}
331} 440}