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.cs136
1 files changed, 80 insertions, 56 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index c984824..3a92f93 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -36,20 +36,29 @@ public abstract class BSLinkset
36{ 36{
37 // private static string LogHeader = "[BULLETSIM LINKSET]"; 37 // private static string LogHeader = "[BULLETSIM LINKSET]";
38 38
39 public enum LinksetImplementation
40 {
41 Constraint = 0, // linkset tied together with constraints
42 Compound = 1, // linkset tied together as a compound object
43 Manual = 2 // linkset tied together manually (code moves all the pieces)
44 }
39 // Create the correct type of linkset for this child 45 // Create the correct type of linkset for this child
40 public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) 46 public static BSLinkset Factory(BSScene physScene, BSPhysObject parent)
41 { 47 {
42 BSLinkset ret = null; 48 BSLinkset ret = null;
43 /*
44 if (parent.IsPhysical)
45 ret = new BSLinksetConstraints(physScene, parent);
46 else
47 ret = new BSLinksetManual(physScene, parent);
48 */
49
50 // at the moment, there is only one
51 ret = new BSLinksetConstraints(physScene, parent);
52 49
50 switch ((int)physScene.Params.linksetImplementation)
51 {
52 case (int)LinksetImplementation.Compound:
53 ret = new BSLinksetCompound(physScene, parent);
54 break;
55 case (int)LinksetImplementation.Manual:
56 // ret = new BSLinksetManual(physScene, parent);
57 break;
58 default:
59 ret = new BSLinksetConstraints(physScene, parent);
60 break;
61 }
53 return ret; 62 return ret;
54 } 63 }
55 64
@@ -61,22 +70,27 @@ public abstract class BSLinkset
61 public int LinksetID { get; private set; } 70 public int LinksetID { get; private set; }
62 71
63 // The children under the root in this linkset. 72 // The children under the root in this linkset.
64 // There are two lists of children: the current children at runtime
65 // and the children at taint-time. For instance, if you delink a
66 // child from the linkset, the child is removed from m_children
67 // but the constraint won't be removed until taint time.
68 // Two lists lets this track the 'current' children and
69 // the physical 'taint' children separately.
70 // After taint processing and before the simulation step, these
71 // two lists must be the same.
72 protected HashSet<BSPhysObject> m_children; 73 protected HashSet<BSPhysObject> m_children;
73 protected HashSet<BSPhysObject> m_taintChildren;
74 74
75 // We lock the diddling of linkset classes to prevent any badness. 75 // We lock the diddling of linkset classes to prevent any badness.
76 // This locks the modification of the instances of this class. Changes 76 // This locks the modification of the instances of this class. Changes
77 // to the physical representation is done via the tainting mechenism. 77 // to the physical representation is done via the tainting mechenism.
78 protected object m_linksetActivityLock = new Object(); 78 protected object m_linksetActivityLock = new Object();
79 79
80 // Some linksets have a preferred physical shape.
81 // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
82 public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor)
83 {
84 return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN;
85 }
86
87 // Linksets move around the children so the linkset might need to compute the child position
88 public virtual OMV.Vector3 Position(BSPhysObject member)
89 { return member.RawPosition; }
90 public virtual OMV.Quaternion Orientation(BSPhysObject member)
91 { return member.RawOrientation; }
92 // TODO: does this need to be done for Velocity and RotationalVelocityy?
93
80 // We keep the prim's mass in the linkset structure since it could be dependent on other prims 94 // We keep the prim's mass in the linkset structure since it could be dependent on other prims
81 protected float m_mass; 95 protected float m_mass;
82 public float LinksetMass 96 public float LinksetMass
@@ -88,6 +102,8 @@ public abstract class BSLinkset
88 } 102 }
89 } 103 }
90 104
105 public virtual bool LinksetIsColliding { get { return false; } }
106
91 public OMV.Vector3 CenterOfMass 107 public OMV.Vector3 CenterOfMass
92 { 108 {
93 get { return ComputeLinksetCenterOfMass(); } 109 get { return ComputeLinksetCenterOfMass(); }
@@ -108,8 +124,7 @@ public abstract class BSLinkset
108 PhysicsScene = scene; 124 PhysicsScene = scene;
109 LinksetRoot = parent; 125 LinksetRoot = parent;
110 m_children = new HashSet<BSPhysObject>(); 126 m_children = new HashSet<BSPhysObject>();
111 m_taintChildren = new HashSet<BSPhysObject>(); 127 m_mass = parent.RawMass;
112 m_mass = parent.MassRaw;
113 } 128 }
114 129
115 // Link to a linkset where the child knows the parent. 130 // Link to a linkset where the child knows the parent.
@@ -140,7 +155,6 @@ public abstract class BSLinkset
140 // Cannot remove the root from a linkset. 155 // Cannot remove the root from a linkset.
141 return this; 156 return this;
142 } 157 }
143
144 RemoveChildFromLinkset(child); 158 RemoveChildFromLinkset(child);
145 } 159 }
146 160
@@ -165,9 +179,8 @@ public abstract class BSLinkset
165 bool ret = false; 179 bool ret = false;
166 lock (m_linksetActivityLock) 180 lock (m_linksetActivityLock)
167 { 181 {
168 if (m_children.Contains(child)) 182 ret = m_children.Contains(child);
169 ret = true; 183 /* Safer version but the above should work
170 /*
171 foreach (BSPhysObject bp in m_children) 184 foreach (BSPhysObject bp in m_children)
172 { 185 {
173 if (child.LocalID == bp.LocalID) 186 if (child.LocalID == bp.LocalID)
@@ -181,10 +194,36 @@ public abstract class BSLinkset
181 return ret; 194 return ret;
182 } 195 }
183 196
197 // Perform an action on each member of the linkset including root prim.
198 // Depends on the action on whether this should be done at taint time.
199 public delegate bool ForEachMemberAction(BSPhysObject obj);
200 public virtual bool ForEachMember(ForEachMemberAction action)
201 {
202 bool ret = false;
203 lock (m_linksetActivityLock)
204 {
205 action(LinksetRoot);
206 foreach (BSPhysObject po in m_children)
207 {
208 if (action(po))
209 break;
210 }
211 }
212 return ret;
213 }
214
215 // I am the root of a linkset and a new child is being added
216 // Called while LinkActivity is locked.
217 protected abstract void AddChildToLinkset(BSPhysObject child);
218
219 // I am the root of a linkset and one of my children is being removed.
220 // Safe to call even if the child is not really in my linkset.
221 protected abstract void RemoveChildFromLinkset(BSPhysObject child);
222
184 // When physical properties are changed the linkset needs to recalculate 223 // When physical properties are changed the linkset needs to recalculate
185 // its internal properties. 224 // its internal properties.
186 // May be called at runtime or taint-time (just pass the appropriate flag). 225 // May be called at runtime or taint-time.
187 public abstract void Refresh(BSPhysObject requestor, bool inTaintTime); 226 public abstract void Refresh(BSPhysObject requestor);
188 227
189 // The object is going dynamic (physical). Do any setup necessary 228 // The object is going dynamic (physical). Do any setup necessary
190 // for a dynamic linkset. 229 // for a dynamic linkset.
@@ -218,17 +257,17 @@ public abstract class BSLinkset
218 public abstract void RestoreBodyDependencies(BSPrim child); 257 public abstract void RestoreBodyDependencies(BSPrim child);
219 258
220 // ================================================================ 259 // ================================================================
221 // Below this point is internal magic
222
223 protected virtual float ComputeLinksetMass() 260 protected virtual float ComputeLinksetMass()
224 { 261 {
225 float mass; 262 float mass = LinksetRoot.RawMass;
226 lock (m_linksetActivityLock) 263 if (HasAnyChildren)
227 { 264 {
228 mass = LinksetRoot.MassRaw; 265 lock (m_linksetActivityLock)
229 foreach (BSPhysObject bp in m_taintChildren)
230 { 266 {
231 mass += bp.MassRaw; 267 foreach (BSPhysObject bp in m_children)
268 {
269 mass += bp.RawMass;
270 }
232 } 271 }
233 } 272 }
234 return mass; 273 return mass;
@@ -239,13 +278,13 @@ public abstract class BSLinkset
239 OMV.Vector3 com; 278 OMV.Vector3 com;
240 lock (m_linksetActivityLock) 279 lock (m_linksetActivityLock)
241 { 280 {
242 com = LinksetRoot.Position * LinksetRoot.MassRaw; 281 com = LinksetRoot.Position * LinksetRoot.RawMass;
243 float totalMass = LinksetRoot.MassRaw; 282 float totalMass = LinksetRoot.RawMass;
244 283
245 foreach (BSPhysObject bp in m_taintChildren) 284 foreach (BSPhysObject bp in m_children)
246 { 285 {
247 com += bp.Position * bp.MassRaw; 286 com += bp.Position * bp.RawMass;
248 totalMass += bp.MassRaw; 287 totalMass += bp.RawMass;
249 } 288 }
250 if (totalMass != 0f) 289 if (totalMass != 0f)
251 com /= totalMass; 290 com /= totalMass;
@@ -261,31 +300,16 @@ public abstract class BSLinkset
261 { 300 {
262 com = LinksetRoot.Position; 301 com = LinksetRoot.Position;
263 302
264 foreach (BSPhysObject bp in m_taintChildren) 303 foreach (BSPhysObject bp in m_children)
265 { 304 {
266 com += bp.Position * bp.MassRaw; 305 com += bp.Position * bp.RawMass;
267 } 306 }
268 com /= (m_taintChildren.Count + 1); 307 com /= (m_children.Count + 1);
269 } 308 }
270 309
271 return com; 310 return com;
272 } 311 }
273 312
274 // I am the root of a linkset and a new child is being added
275 // Called while LinkActivity is locked.
276 protected abstract void AddChildToLinkset(BSPhysObject child);
277
278 // Forcefully removing a child from a linkset.
279 // This is not being called by the child so we have to make sure the child doesn't think
280 // it's still connected to the linkset.
281 // Normal OpenSimulator operation will never do this because other SceneObjectPart information
282 // also has to be updated (like pointer to prim's parent).
283 protected abstract void RemoveChildFromOtherLinkset(BSPhysObject pchild);
284
285 // I am the root of a linkset and one of my children is being removed.
286 // Safe to call even if the child is not really in my linkset.
287 protected abstract void RemoveChildFromLinkset(BSPhysObject child);
288
289 // Invoke the detailed logger and output something if it's enabled. 313 // Invoke the detailed logger and output something if it's enabled.
290 protected void DetailLog(string msg, params Object[] args) 314 protected void DetailLog(string msg, params Object[] args)
291 { 315 {