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.cs240
1 files changed, 193 insertions, 47 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 4ece1eb..77f69a5 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,37 @@ 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 public virtual void ResetLink() { }
81 public virtual void SetLinkParameters(BSConstraint constrain) { }
82 // Returns 'true' if physical property updates from the child should be reported to the simulator
83 public virtual bool ShouldUpdateChildProperties() { return false; }
84 }
85
86 public LinksetImplementation LinksetImpl { get; protected set; }
87
81 public BSPrimLinkable LinksetRoot { get; protected set; } 88 public BSPrimLinkable LinksetRoot { get; protected set; }
82 89
83 public BSScene PhysicsScene { get; private set; } 90 protected BSScene m_physicsScene { get; private set; }
84 91
85 static int m_nextLinksetID = 1; 92 static int m_nextLinksetID = 1;
86 public int LinksetID { get; private set; } 93 public int LinksetID { get; private set; }
87 94
88 // The children under the root in this linkset. 95 // The children under the root in this linkset.
89 protected HashSet<BSPrimLinkable> m_children; 96 // protected HashSet<BSPrimLinkable> m_children;
97 protected Dictionary<BSPrimLinkable, BSLinkInfo> m_children;
90 98
91 // We lock the diddling of linkset classes to prevent any badness. 99 // We lock the diddling of linkset classes to prevent any badness.
92 // This locks the modification of the instances of this class. Changes 100 // This locks the modification of the instances of this class. Changes
93 // to the physical representation is done via the tainting mechenism. 101 // to the physical representation is done via the tainting mechenism.
94 protected object m_linksetActivityLock = new Object(); 102 protected object m_linksetActivityLock = new Object();
95 103
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 104 // 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; } 105 public float LinksetMass { get; protected set; }
105 106
@@ -122,9 +123,9 @@ public abstract class BSLinkset
122 // We create LOTS of linksets. 123 // We create LOTS of linksets.
123 if (m_nextLinksetID <= 0) 124 if (m_nextLinksetID <= 0)
124 m_nextLinksetID = 1; 125 m_nextLinksetID = 1;
125 PhysicsScene = scene; 126 m_physicsScene = scene;
126 LinksetRoot = parent; 127 LinksetRoot = parent;
127 m_children = new HashSet<BSPrimLinkable>(); 128 m_children = new Dictionary<BSPrimLinkable, BSLinkInfo>();
128 LinksetMass = parent.RawMass; 129 LinksetMass = parent.RawMass;
129 Rebuilding = false; 130 Rebuilding = false;
130 131
@@ -151,7 +152,7 @@ public abstract class BSLinkset
151 // Returns a new linkset for the child which is a linkset of one (just the 152 // Returns a new linkset for the child which is a linkset of one (just the
152 // orphened child). 153 // orphened child).
153 // Called at runtime. 154 // Called at runtime.
154 public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child) 155 public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child, bool inTaintTime)
155 { 156 {
156 lock (m_linksetActivityLock) 157 lock (m_linksetActivityLock)
157 { 158 {
@@ -160,12 +161,12 @@ public abstract class BSLinkset
160 // Cannot remove the root from a linkset. 161 // Cannot remove the root from a linkset.
161 return this; 162 return this;
162 } 163 }
163 RemoveChildFromLinkset(child); 164 RemoveChildFromLinkset(child, inTaintTime);
164 LinksetMass = ComputeLinksetMass(); 165 LinksetMass = ComputeLinksetMass();
165 } 166 }
166 167
167 // The child is down to a linkset of just itself 168 // The child is down to a linkset of just itself
168 return BSLinkset.Factory(PhysicsScene, child); 169 return BSLinkset.Factory(m_physicsScene, child);
169 } 170 }
170 171
171 // Return 'true' if the passed object is the root object of this linkset 172 // Return 'true' if the passed object is the root object of this linkset
@@ -185,17 +186,7 @@ public abstract class BSLinkset
185 bool ret = false; 186 bool ret = false;
186 lock (m_linksetActivityLock) 187 lock (m_linksetActivityLock)
187 { 188 {
188 ret = m_children.Contains(child); 189 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 } 190 }
200 return ret; 191 return ret;
201 } 192 }
@@ -209,7 +200,35 @@ public abstract class BSLinkset
209 lock (m_linksetActivityLock) 200 lock (m_linksetActivityLock)
210 { 201 {
211 action(LinksetRoot); 202 action(LinksetRoot);
212 foreach (BSPrimLinkable po in m_children) 203 foreach (BSPrimLinkable po in m_children.Keys)
204 {
205 if (action(po))
206 break;
207 }
208 }
209 return ret;
210 }
211
212 public bool TryGetLinkInfo(BSPrimLinkable child, out BSLinkInfo foundInfo)
213 {
214 bool ret = false;
215 BSLinkInfo found = null;
216 lock (m_linksetActivityLock)
217 {
218 ret = m_children.TryGetValue(child, out found);
219 }
220 foundInfo = found;
221 return ret;
222 }
223 // Perform an action on each member of the linkset including root prim.
224 // Depends on the action on whether this should be done at taint time.
225 public delegate bool ForEachLinkInfoAction(BSLinkInfo obj);
226 public virtual bool ForEachLinkInfo(ForEachLinkInfoAction action)
227 {
228 bool ret = false;
229 lock (m_linksetActivityLock)
230 {
231 foreach (BSLinkInfo po in m_children.Values)
213 { 232 {
214 if (action(po)) 233 if (action(po))
215 break; 234 break;
@@ -218,13 +237,55 @@ public abstract class BSLinkset
218 return ret; 237 return ret;
219 } 238 }
220 239
240 // Check the type of the link and return 'true' if the link is flexible and the
241 // updates from the child should be sent to the simulator so things change.
242 public virtual bool ShouldReportPropertyUpdates(BSPrimLinkable child)
243 {
244 bool ret = false;
245
246 BSLinkInfo linkInfo;
247 if (m_children.TryGetValue(child, out linkInfo))
248 {
249 ret = linkInfo.ShouldUpdateChildProperties();
250 }
251
252 return ret;
253 }
254
255 // Called after a simulation step to post a collision with this object.
256 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have
257 // anything to add for the collision and it should be passed through normal processing.
258 // Default processing for a linkset.
259 public virtual bool HandleCollide(uint collidingWith, BSPhysObject collidee,
260 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
261 {
262 bool ret = false;
263
264 // prims in the same linkset cannot collide with each other
265 BSPrimLinkable convCollidee = collidee as BSPrimLinkable;
266 if (convCollidee != null && (LinksetID == convCollidee.Linkset.LinksetID))
267 {
268 // By returning 'true', we tell the caller the collision has been 'handled' so it won't
269 // do anything about this collision and thus, effectivily, ignoring the collision.
270 ret = true;
271 }
272 else
273 {
274 // Not a collision between members of the linkset. Must be a real collision.
275 // So the linkset root can know if there is a collision anywhere in the linkset.
276 LinksetRoot.SomeCollisionSimulationStep = m_physicsScene.SimulationStep;
277 }
278
279 return ret;
280 }
281
221 // I am the root of a linkset and a new child is being added 282 // I am the root of a linkset and a new child is being added
222 // Called while LinkActivity is locked. 283 // Called while LinkActivity is locked.
223 protected abstract void AddChildToLinkset(BSPrimLinkable child); 284 protected abstract void AddChildToLinkset(BSPrimLinkable child);
224 285
225 // I am the root of a linkset and one of my children is being removed. 286 // 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. 287 // Safe to call even if the child is not really in my linkset.
227 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child); 288 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime);
228 289
229 // When physical properties are changed the linkset needs to recalculate 290 // When physical properties are changed the linkset needs to recalculate
230 // its internal properties. 291 // its internal properties.
@@ -263,9 +324,88 @@ public abstract class BSLinkset
263 // This is called when the root body is changing. 324 // This is called when the root body is changing.
264 // Returns 'true' of something was actually removed and would need restoring 325 // Returns 'true' of something was actually removed and would need restoring
265 // Called at taint-time!! 326 // Called at taint-time!!
266 public abstract bool RemoveBodyDependencies(BSPrimLinkable child); 327 public abstract bool RemoveDependencies(BSPrimLinkable child);
267 328
268 // ================================================================ 329 // ================================================================
330 // Some physical setting happen to all members of the linkset
331 public virtual void SetPhysicalFriction(float friction)
332 {
333 ForEachMember((member) =>
334 {
335 if (member.PhysBody.HasPhysicalBody)
336 m_physicsScene.PE.SetFriction(member.PhysBody, friction);
337 return false; // 'false' says to continue looping
338 }
339 );
340 }
341 public virtual void SetPhysicalRestitution(float restitution)
342 {
343 ForEachMember((member) =>
344 {
345 if (member.PhysBody.HasPhysicalBody)
346 m_physicsScene.PE.SetRestitution(member.PhysBody, restitution);
347 return false; // 'false' says to continue looping
348 }
349 );
350 }
351 public virtual void SetPhysicalGravity(OMV.Vector3 gravity)
352 {
353 ForEachMember((member) =>
354 {
355 if (member.PhysBody.HasPhysicalBody)
356 m_physicsScene.PE.SetGravity(member.PhysBody, gravity);
357 return false; // 'false' says to continue looping
358 }
359 );
360 }
361 public virtual void ComputeAndSetLocalInertia(OMV.Vector3 inertiaFactor, float linksetMass)
362 {
363 ForEachMember((member) =>
364 {
365 if (member.PhysBody.HasPhysicalBody)
366 {
367 OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(member.PhysShape.physShapeInfo, linksetMass);
368 member.Inertia = inertia * inertiaFactor;
369 m_physicsScene.PE.SetMassProps(member.PhysBody, linksetMass, member.Inertia);
370 m_physicsScene.PE.UpdateInertiaTensor(member.PhysBody);
371 DetailLog("{0},BSLinkset.ComputeAndSetLocalInertia,m.mass={1}, inertia={2}", member.LocalID, linksetMass, member.Inertia);
372
373 }
374 return false; // 'false' says to continue looping
375 }
376 );
377 }
378 public virtual void SetPhysicalCollisionFlags(CollisionFlags collFlags)
379 {
380 ForEachMember((member) =>
381 {
382 if (member.PhysBody.HasPhysicalBody)
383 m_physicsScene.PE.SetCollisionFlags(member.PhysBody, collFlags);
384 return false; // 'false' says to continue looping
385 }
386 );
387 }
388 public virtual void AddToPhysicalCollisionFlags(CollisionFlags collFlags)
389 {
390 ForEachMember((member) =>
391 {
392 if (member.PhysBody.HasPhysicalBody)
393 m_physicsScene.PE.AddToCollisionFlags(member.PhysBody, collFlags);
394 return false; // 'false' says to continue looping
395 }
396 );
397 }
398 public virtual void RemoveFromPhysicalCollisionFlags(CollisionFlags collFlags)
399 {
400 ForEachMember((member) =>
401 {
402 if (member.PhysBody.HasPhysicalBody)
403 m_physicsScene.PE.RemoveFromCollisionFlags(member.PhysBody, collFlags);
404 return false; // 'false' says to continue looping
405 }
406 );
407 }
408 // ================================================================
269 protected virtual float ComputeLinksetMass() 409 protected virtual float ComputeLinksetMass()
270 { 410 {
271 float mass = LinksetRoot.RawMass; 411 float mass = LinksetRoot.RawMass;
@@ -273,7 +413,7 @@ public abstract class BSLinkset
273 { 413 {
274 lock (m_linksetActivityLock) 414 lock (m_linksetActivityLock)
275 { 415 {
276 foreach (BSPrimLinkable bp in m_children) 416 foreach (BSPrimLinkable bp in m_children.Keys)
277 { 417 {
278 mass += bp.RawMass; 418 mass += bp.RawMass;
279 } 419 }
@@ -291,7 +431,7 @@ public abstract class BSLinkset
291 com = LinksetRoot.Position * LinksetRoot.RawMass; 431 com = LinksetRoot.Position * LinksetRoot.RawMass;
292 float totalMass = LinksetRoot.RawMass; 432 float totalMass = LinksetRoot.RawMass;
293 433
294 foreach (BSPrimLinkable bp in m_children) 434 foreach (BSPrimLinkable bp in m_children.Keys)
295 { 435 {
296 com += bp.Position * bp.RawMass; 436 com += bp.Position * bp.RawMass;
297 totalMass += bp.RawMass; 437 totalMass += bp.RawMass;
@@ -310,7 +450,7 @@ public abstract class BSLinkset
310 { 450 {
311 com = LinksetRoot.Position; 451 com = LinksetRoot.Position;
312 452
313 foreach (BSPrimLinkable bp in m_children) 453 foreach (BSPrimLinkable bp in m_children.Keys)
314 { 454 {
315 com += bp.Position; 455 com += bp.Position;
316 } 456 }
@@ -320,12 +460,18 @@ public abstract class BSLinkset
320 return com; 460 return com;
321 } 461 }
322 462
463 #region Extension
464 public virtual object Extension(string pFunct, params object[] pParams)
465 {
466 return null;
467 }
468 #endregion // Extension
469
323 // Invoke the detailed logger and output something if it's enabled. 470 // Invoke the detailed logger and output something if it's enabled.
324 protected void DetailLog(string msg, params Object[] args) 471 protected void DetailLog(string msg, params Object[] args)
325 { 472 {
326 if (PhysicsScene.PhysicsLogging.Enabled) 473 if (m_physicsScene.PhysicsLogging.Enabled)
327 PhysicsScene.DetailLog(msg, args); 474 m_physicsScene.DetailLog(msg, args);
328 } 475 }
329
330} 476}
331} 477}