aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs260
1 files changed, 101 insertions, 159 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index 8a750b5..d2387fb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -32,7 +32,7 @@ using OMV = OpenMetaverse;
32 32
33namespace OpenSim.Region.Physics.BulletSPlugin 33namespace OpenSim.Region.Physics.BulletSPlugin
34{ 34{
35public class BSLinksetConstraints : BSLinkset 35public sealed class BSLinksetConstraints : BSLinkset
36{ 36{
37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; 37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
38 38
@@ -43,23 +43,16 @@ public class BSLinksetConstraints : BSLinkset
43 43
44 // When physical properties are changed the linkset needs to recalculate 44 // When physical properties are changed the linkset needs to recalculate
45 // its internal properties. 45 // its internal properties.
46 // May be called at runtime or taint-time (just pass the appropriate flag). 46 // This is queued in the 'post taint' queue so the
47 public override void Refresh(BSPhysObject requestor, bool inTaintTime) 47 // refresh will happen once after all the other taints are applied.
48 public override void Refresh(BSPhysObject requestor)
48 { 49 {
49 // If there are no children or not root, I am not the one that recomputes the constraints 50 // Queue to happen after all the other taint processing
50 if (!HasAnyChildren || !IsRoot(requestor)) 51 PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
51 return;
52
53 BSScene.TaintCallback refreshOperation = delegate()
54 { 52 {
55 RecomputeLinksetConstraintVariables(); 53 if (HasAnyChildren && IsRoot(requestor))
56 DetailLog("{0},BSLinkset.Refresh,complete,rBody={1}", 54 RecomputeLinksetConstraints();
57 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); 55 });
58 };
59 if (inTaintTime)
60 refreshOperation();
61 else
62 PhysicsScene.TaintedObject("BSLinkSet.Refresh", refreshOperation);
63 } 56 }
64 57
65 // The object is going dynamic (physical). Do any setup necessary 58 // The object is going dynamic (physical). Do any setup necessary
@@ -74,9 +67,10 @@ public class BSLinksetConstraints : BSLinkset
74 return false; 67 return false;
75 } 68 }
76 69
77 // The object is going static (non-physical). Do any setup necessary 70 // The object is going static (non-physical). Do any setup necessary for a static linkset.
78 // for a static linkset.
79 // Return 'true' if any properties updated on the passed object. 71 // Return 'true' if any properties updated on the passed object.
72 // This doesn't normally happen -- OpenSim removes the objects from the physical
73 // world if it is a static linkset.
80 // Called at taint-time! 74 // Called at taint-time!
81 public override bool MakeStatic(BSPhysObject child) 75 public override bool MakeStatic(BSPhysObject child)
82 { 76 {
@@ -90,35 +84,36 @@ public class BSLinksetConstraints : BSLinkset
90 // Nothing to do for constraints on property updates 84 // Nothing to do for constraints on property updates
91 } 85 }
92 86
93 // Routine used when rebuilding the body of the root of the linkset 87 // The children of the linkset are moved around by the constraints.
94 // Destroy all the constraints have have been made to root. 88 // Just grab the current values of wherever it is right now.
95 // This is called when the root body is changing. 89 public override OMV.Vector3 Position(BSPhysObject member)
96 // Returns 'true' of something eas actually removed and would need restoring 90 {
91 return BulletSimAPI.GetPosition2(member.PhysBody.ptr);
92 }
93
94 public override OMV.Quaternion Orientation(BSPhysObject member)
95 {
96 return BulletSimAPI.GetOrientation2(member.PhysBody.ptr);
97 }
98
99 // Routine called when rebuilding the body of some member of the linkset.
100 // Destroy all the constraints have have been made to root and set
101 // up to rebuild the constraints before the next simulation step.
102 // Returns 'true' of something was actually removed and would need restoring
97 // Called at taint-time!! 103 // Called at taint-time!!
98 public override bool RemoveBodyDependencies(BSPrim child) 104 public override bool RemoveBodyDependencies(BSPrim child)
99 { 105 {
100 bool ret = false; 106 bool ret = false;
101 107
108 DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
109 child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"));
110
102 lock (m_linksetActivityLock) 111 lock (m_linksetActivityLock)
103 { 112 {
104 if (IsRoot(child)) 113 // Just undo all the constraints for this linkset. Rebuild at the end of the step.
105 { 114 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
106 // If the one with the dependency is root, must undo all children 115 // Cause the constraints, et al to be rebuilt before the next simulation step.
107 DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", 116 Refresh(LinksetRoot);
108 child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"));
109
110 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
111 }
112 else
113 {
114 DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
115 child.LocalID,
116 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
117 child.LocalID, child.BSBody.ptr.ToString("X"));
118 // ret = PhysicallyUnlinkAChildFromRoot(LinksetRoot, child);
119 // Despite the function name, this removes any link to the specified object.
120 ret = PhysicallyUnlinkAllChildrenFromRoot(child);
121 }
122 } 117 }
123 return ret; 118 return ret;
124 } 119 }
@@ -128,32 +123,12 @@ public class BSLinksetConstraints : BSLinkset
128 // Called at taint-time!! 123 // Called at taint-time!!
129 public override void RestoreBodyDependencies(BSPrim child) 124 public override void RestoreBodyDependencies(BSPrim child)
130 { 125 {
131 lock (m_linksetActivityLock) 126 // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints.
132 {
133 if (IsRoot(child))
134 {
135 DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}",
136 child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count);
137 foreach (BSPhysObject bpo in m_taintChildren)
138 {
139 PhysicallyLinkAChildToRoot(LinksetRoot, bpo);
140 }
141 }
142 else
143 {
144 DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
145 LinksetRoot.LocalID,
146 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
147 child.LocalID, child.BSBody.ptr.ToString("X"));
148 PhysicallyLinkAChildToRoot(LinksetRoot, child);
149 }
150 }
151 } 127 }
152 128
153 // ================================================================ 129 // ================================================================
154 // Below this point is internal magic
155 130
156 // I am the root of a linkset and a new child is being added 131 // Add a new child to the linkset.
157 // Called while LinkActivity is locked. 132 // Called while LinkActivity is locked.
158 protected override void AddChildToLinkset(BSPhysObject child) 133 protected override void AddChildToLinkset(BSPhysObject child)
159 { 134 {
@@ -161,39 +136,15 @@ public class BSLinksetConstraints : BSLinkset
161 { 136 {
162 m_children.Add(child); 137 m_children.Add(child);
163 138
164 BSPhysObject rootx = LinksetRoot; // capture the root as of now 139 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
165 BSPhysObject childx = child;
166
167 DetailLog("{0},AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
168 140
169 PhysicsScene.TaintedObject("AddChildToLinkset", delegate() 141 // Cause constraints and assorted properties to be recomputed before the next simulation step.
170 { 142 Refresh(LinksetRoot);
171 DetailLog("{0},AddChildToLinkset,taint,rID={1},rBody={2},cID={3},cBody={4}",
172 rootx.LocalID,
173 rootx.LocalID, rootx.BSBody.ptr.ToString("X"),
174 childx.LocalID, childx.BSBody.ptr.ToString("X"));
175 // Since this is taint-time, the body and shape could have changed for the child
176 rootx.ForcePosition = rootx.Position; // DEBUG
177 childx.ForcePosition = childx.Position; // DEBUG
178 PhysicallyLinkAChildToRoot(rootx, childx);
179 m_taintChildren.Add(child);
180 });
181 } 143 }
182 return; 144 return;
183 } 145 }
184 146
185 // Forcefully removing a child from a linkset. 147 // Remove the specified child from the linkset.
186 // This is not being called by the child so we have to make sure the child doesn't think
187 // it's still connected to the linkset.
188 // Normal OpenSimulator operation will never do this because other SceneObjectPart information
189 // also has to be updated (like pointer to prim's parent).
190 protected override void RemoveChildFromOtherLinkset(BSPhysObject pchild)
191 {
192 pchild.Linkset = BSLinkset.Factory(PhysicsScene, pchild);
193 RemoveChildFromLinkset(pchild);
194 }
195
196 // I am the root of a linkset and one of my children is being removed.
197 // Safe to call even if the child is not really in my linkset. 148 // Safe to call even if the child is not really in my linkset.
198 protected override void RemoveChildFromLinkset(BSPhysObject child) 149 protected override void RemoveChildFromLinkset(BSPhysObject child)
199 { 150 {
@@ -202,22 +153,21 @@ public class BSLinksetConstraints : BSLinkset
202 BSPhysObject rootx = LinksetRoot; // capture the root and body as of now 153 BSPhysObject rootx = LinksetRoot; // capture the root and body as of now
203 BSPhysObject childx = child; 154 BSPhysObject childx = child;
204 155
205 DetailLog("{0},RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", 156 DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
206 childx.LocalID, 157 childx.LocalID,
207 rootx.LocalID, rootx.BSBody.ptr.ToString("X"), 158 rootx.LocalID, rootx.PhysBody.ptr.ToString("X"),
208 childx.LocalID, childx.BSBody.ptr.ToString("X")); 159 childx.LocalID, childx.PhysBody.ptr.ToString("X"));
209 160
210 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 161 PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate()
211 { 162 {
212 m_taintChildren.Remove(child);
213 PhysicallyUnlinkAChildFromRoot(rootx, childx); 163 PhysicallyUnlinkAChildFromRoot(rootx, childx);
214 RecomputeLinksetConstraintVariables();
215 }); 164 });
216 165 // See that the linkset parameters are recomputed at the end of the taint time.
166 Refresh(LinksetRoot);
217 } 167 }
218 else 168 else
219 { 169 {
220 // This will happen if we remove the root of the linkset first. Non-fatal occurance. 170 // Non-fatal occurance.
221 // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); 171 // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
222 } 172 }
223 return; 173 return;
@@ -227,6 +177,12 @@ public class BSLinksetConstraints : BSLinkset
227 // Called at taint time! 177 // Called at taint time!
228 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 178 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
229 { 179 {
180 // Don't build the constraint when asked. Put it off until just before the simulation step.
181 Refresh(rootPrim);
182 }
183
184 private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim)
185 {
230 // Zero motion for children so they don't interpolate 186 // Zero motion for children so they don't interpolate
231 childPrim.ZeroMotion(); 187 childPrim.ZeroMotion();
232 188
@@ -237,22 +193,23 @@ public class BSLinksetConstraints : BSLinkset
237 // real world coordinate of midpoint between the two objects 193 // real world coordinate of midpoint between the two objects
238 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); 194 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
239 195
240 DetailLog("{0},BSLinkset.PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", 196 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
241 rootPrim.LocalID, 197 rootPrim.LocalID,
242 rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), 198 rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"),
243 childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"), 199 childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X"),
244 rootPrim.Position, childPrim.Position, midPoint); 200 rootPrim.Position, childPrim.Position, midPoint);
245 201
246 // create a constraint that allows no freedom of movement between the two objects 202 // create a constraint that allows no freedom of movement between the two objects
247 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 203 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
248 204
249 BS6DofConstraint constrain = new BS6DofConstraint( 205 BSConstraint6Dof constrain = new BSConstraint6Dof(
250 PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, midPoint, true, true ); 206 PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true );
207 // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true );
251 208
252 /* NOTE: below is an attempt to build constraint with full frame computation, etc. 209 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
253 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms 210 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
254 * of the objects. 211 * of the objects.
255 * Code left as a warning to future programmers. 212 * Code left for future programmers.
256 // ================================================================================== 213 // ==================================================================================
257 // relative position normalized to the root prim 214 // relative position normalized to the root prim
258 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); 215 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
@@ -262,20 +219,13 @@ public class BSLinksetConstraints : BSLinkset
262 OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; 219 OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
263 OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); 220 OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation);
264 221
265 // create a constraint that allows no freedom of movement between the two objects 222 DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
266 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
267 DetailLog("{0},BSLinkset.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
268 BS6DofConstraint constrain = new BS6DofConstraint( 223 BS6DofConstraint constrain = new BS6DofConstraint(
269 PhysicsScene.World, rootPrim.Body, childPrim.Body, 224 PhysicsScene.World, rootPrim.Body, childPrim.Body,
270 OMV.Vector3.Zero, 225 OMV.Vector3.Zero,
271 OMV.Quaternion.Inverse(rootPrim.Orientation), 226 OMV.Quaternion.Inverse(rootPrim.Orientation),
272 OMV.Vector3.Zero, 227 OMV.Vector3.Zero,
273 OMV.Quaternion.Inverse(childPrim.Orientation), 228 OMV.Quaternion.Inverse(childPrim.Orientation),
274 // A point half way between the parent and child
275 // childRelativePosition/2,
276 // childRelativeRotation,
277 // childRelativePosition/2,
278 // inverseChildRelativeRotation,
279 true, 229 true,
280 true 230 true
281 ); 231 );
@@ -298,25 +248,26 @@ public class BSLinksetConstraints : BSLinkset
298 { 248 {
299 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations); 249 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations);
300 } 250 }
251 return constrain;
301 } 252 }
302 253
303 // Remove linkage between myself and a particular child 254 // Remove linkage between the linkset root and a particular child
304 // The root and child bodies are passed in because we need to remove the constraint between 255 // The root and child bodies are passed in because we need to remove the constraint between
305 // the bodies that were at unlink time. 256 // the bodies that were present at unlink time.
306 // Called at taint time! 257 // Called at taint time!
307 private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 258 private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
308 { 259 {
309 bool ret = false; 260 bool ret = false;
310 DetailLog("{0},BSLinkset.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", 261 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
311 rootPrim.LocalID, 262 rootPrim.LocalID,
312 rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), 263 rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"),
313 childPrim.LocalID, childPrim.BSBody.ptr.ToString("X")); 264 childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X"));
314 265
315 // Find the constraint for this link and get rid of it from the overall collection and from my list 266 // Find the constraint for this link and get rid of it from the overall collection and from my list
316 if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody)) 267 if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
317 { 268 {
318 // Make the child refresh its location 269 // Make the child refresh its location
319 BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr); 270 BulletSimAPI.PushUpdate2(childPrim.PhysBody.ptr);
320 ret = true; 271 ret = true;
321 } 272 }
322 273
@@ -324,62 +275,53 @@ public class BSLinksetConstraints : BSLinkset
324 } 275 }
325 276
326 // Remove linkage between myself and any possible children I might have. 277 // Remove linkage between myself and any possible children I might have.
278 // Returns 'true' of any constraints were destroyed.
327 // Called at taint time! 279 // Called at taint time!
328 private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) 280 private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
329 { 281 {
330 DetailLog("{0},BSLinkset.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); 282 DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
331 bool ret = false;
332 283
333 if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody)) 284 return PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody);
334 {
335 ret = true;
336 }
337 return ret;
338 } 285 }
339 286
340 // Call each of the constraints that make up this linkset and recompute the 287 // Call each of the constraints that make up this linkset and recompute the
341 // various transforms and variables. Used when objects are added or removed 288 // various transforms and variables. Create constraints of not created yet.
342 // from a linkset to make sure the constraints know about the new mass and 289 // Called before the simulation step to make sure the constraint based linkset
343 // geometry. 290 // is all initialized.
344 // Must only be called at taint time!! 291 // Called at taint time!!
345 private void RecomputeLinksetConstraintVariables() 292 private void RecomputeLinksetConstraints()
346 { 293 {
347 float linksetMass = LinksetMass; 294 float linksetMass = LinksetMass;
348 foreach (BSPhysObject child in m_taintChildren) 295 LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
296
297 // DEBUG: see of inter-linkset collisions are causing problems
298 // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
299 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
300 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
301 LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass);
302
303 foreach (BSPhysObject child in m_children)
349 { 304 {
305 // A child in the linkset physically shows the mass of the whole linkset.
306 // This allows Bullet to apply enough force on the child to move the whole linkset.
307 // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
308 child.UpdatePhysicalMassProperties(linksetMass);
309
350 BSConstraint constrain; 310 BSConstraint constrain;
351 if (PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) 311 if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain))
352 {
353 // DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",
354 // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID);
355 constrain.RecomputeConstraintVariables(linksetMass);
356 }
357 else
358 { 312 {
359 // Non-fatal error that happens when children are being added to the linkset but 313 // If constraint doesn't exist yet, create it.
360 // their constraints have not been created yet. 314 constrain = BuildConstraint(LinksetRoot, child);
361 break;
362 } 315 }
363 } 316 constrain.RecomputeConstraintVariables(linksetMass);
364 317
365 // If the whole linkset is not here, doesn't make sense to recompute linkset wide values 318 // DEBUG: see of inter-linkset collisions are causing problems
366 if (m_children.Count == m_taintChildren.Count) 319 // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr,
367 { 320 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
368 // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass
369 OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
370 BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr,
371 centerOfMass, OMV.Quaternion.Identity);
372 DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,setCenterOfMass,COM={1},rBody={2}",
373 LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"));
374 foreach (BSPhysObject child in m_taintChildren)
375 {
376 BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr,
377 centerOfMass, OMV.Quaternion.Identity);
378 }
379 321
380 // BulletSimAPI.DumpAllInfo2(PhysicsScene.World.ptr); // DEBUG DEBUG DEBUG 322 // BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG
381 } 323 }
382 return; 324
383 } 325 }
384} 326}
385} 327}