aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs140
1 files changed, 48 insertions, 92 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index 086aa12..6c1fa2a 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -54,7 +54,7 @@ public sealed class BSLinksetConstraints : BSLinkset
54 // Queue to happen after all the other taint processing 54 // Queue to happen after all the other taint processing
55 PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() 55 PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
56 { 56 {
57 RecomputeLinksetConstraintVariables(); 57 RecomputeLinksetConstraints();
58 }); 58 });
59 59
60 } 60 }
@@ -98,24 +98,13 @@ public sealed class BSLinksetConstraints : BSLinkset
98 98
99 lock (m_linksetActivityLock) 99 lock (m_linksetActivityLock)
100 { 100 {
101 if (IsRoot(child)) 101 // Just undo all the constraints for this linkset. Rebuild at the end of the step.
102 { 102 DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
103 // If the one with the dependency is root, must undo all children 103 child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"));
104 DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
105 child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"));
106 104
107 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); 105 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
108 } 106 // Cause the constraints, et al to be rebuilt before the next simulation step.
109 else 107 Refresh(LinksetRoot);
110 {
111 DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
112 child.LocalID,
113 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
114 child.LocalID, child.BSBody.ptr.ToString("X"));
115 // ret = PhysicallyUnlinkAChildFromRoot(LinksetRoot, child);
116 // Despite the function name, this removes any link to the specified object.
117 ret = PhysicallyUnlinkAllChildrenFromRoot(child);
118 }
119 } 108 }
120 return ret; 109 return ret;
121 } 110 }
@@ -125,26 +114,7 @@ public sealed class BSLinksetConstraints : BSLinkset
125 // Called at taint-time!! 114 // Called at taint-time!!
126 public override void RestoreBodyDependencies(BSPrim child) 115 public override void RestoreBodyDependencies(BSPrim child)
127 { 116 {
128 lock (m_linksetActivityLock) 117 // The Refresh operation will build any missing constraints.
129 {
130 if (IsRoot(child))
131 {
132 DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}",
133 child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count);
134 foreach (BSPhysObject bpo in m_taintChildren)
135 {
136 PhysicallyLinkAChildToRoot(LinksetRoot, bpo);
137 }
138 }
139 else
140 {
141 DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
142 LinksetRoot.LocalID,
143 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
144 child.LocalID, child.BSBody.ptr.ToString("X"));
145 PhysicallyLinkAChildToRoot(LinksetRoot, child);
146 }
147 }
148 } 118 }
149 119
150 // ================================================================ 120 // ================================================================
@@ -163,18 +133,7 @@ public sealed class BSLinksetConstraints : BSLinkset
163 133
164 DetailLog("{0},AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 134 DetailLog("{0},AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
165 135
166 PhysicsScene.TaintedObject("AddChildToLinkset", delegate() 136 // Cause constraints and assorted properties to be recomputed before the next simulation step.
167 {
168 DetailLog("{0},AddChildToLinkset,taint,rID={1},rBody={2},cID={3},cBody={4}",
169 rootx.LocalID,
170 rootx.LocalID, rootx.BSBody.ptr.ToString("X"),
171 childx.LocalID, childx.BSBody.ptr.ToString("X"));
172 // Since this is taint-time, the body and shape could have changed for the child
173 rootx.ForcePosition = rootx.Position; // DEBUG
174 childx.ForcePosition = childx.Position; // DEBUG
175 PhysicallyLinkAChildToRoot(rootx, childx);
176 m_taintChildren.Add(child);
177 });
178 Refresh(LinksetRoot); 137 Refresh(LinksetRoot);
179 } 138 }
180 return; 139 return;
@@ -207,7 +166,6 @@ public sealed class BSLinksetConstraints : BSLinkset
207 166
208 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 167 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
209 { 168 {
210 m_taintChildren.Remove(child);
211 PhysicallyUnlinkAChildFromRoot(rootx, childx); 169 PhysicallyUnlinkAChildFromRoot(rootx, childx);
212 }); 170 });
213 // See that the linkset parameters are recomputed at the end of the taint time. 171 // See that the linkset parameters are recomputed at the end of the taint time.
@@ -225,6 +183,12 @@ public sealed class BSLinksetConstraints : BSLinkset
225 // Called at taint time! 183 // Called at taint time!
226 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 184 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
227 { 185 {
186 // Don't build the constraint when asked. Put it off until just before the simulation step.
187 Refresh(rootPrim);
188 }
189
190 private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim)
191 {
228 // Zero motion for children so they don't interpolate 192 // Zero motion for children so they don't interpolate
229 childPrim.ZeroMotion(); 193 childPrim.ZeroMotion();
230 194
@@ -235,7 +199,7 @@ public sealed class BSLinksetConstraints : BSLinkset
235 // real world coordinate of midpoint between the two objects 199 // real world coordinate of midpoint between the two objects
236 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); 200 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
237 201
238 DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", 202 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
239 rootPrim.LocalID, 203 rootPrim.LocalID,
240 rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), 204 rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"),
241 childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"), 205 childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"),
@@ -297,6 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset
297 { 261 {
298 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations); 262 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations);
299 } 263 }
264 return constrain;
300 } 265 }
301 266
302 // Remove linkage between myself and a particular child 267 // Remove linkage between myself and a particular child
@@ -337,56 +302,47 @@ public sealed class BSLinksetConstraints : BSLinkset
337 } 302 }
338 303
339 // Call each of the constraints that make up this linkset and recompute the 304 // Call each of the constraints that make up this linkset and recompute the
340 // various transforms and variables. Used when objects are added or removed 305 // various transforms and variables. Create constraints of not created yet.
341 // from a linkset to make sure the constraints know about the new mass and 306 // Called before the simulation step to make sure the constraint based linkset
342 // geometry. 307 // is all initialized.
343 // Must only be called at taint time!! 308 // Must only be called at taint time!!
344 private void RecomputeLinksetConstraintVariables() 309 private void RecomputeLinksetConstraints()
345 { 310 {
346 float linksetMass = LinksetMass; 311 float linksetMass = LinksetMass;
347 foreach (BSPhysObject child in m_taintChildren) 312 LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
313
314 // For a multiple object linkset, set everybody's center of mass to the set's center of mass
315 OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
316 BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity);
317
318 // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
319 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
320 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,setCenterOfMass,COM={1},rBody={2},linksetMass={3}",
321 LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass);
322
323 foreach (BSPhysObject child in m_children)
348 { 324 {
325 // A child in the linkset physically shows the mass of the whole linkset.
326 // This allows Bullet to apply enough force on the child to move the whole linkset.
327 // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
328 BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity);
329 child.UpdatePhysicalMassProperties(linksetMass);
330
349 BSConstraint constrain; 331 BSConstraint constrain;
350 if (PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) 332 if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain))
351 {
352 // DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",
353 // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID);
354 constrain.RecomputeConstraintVariables(linksetMass);
355 }
356 else
357 { 333 {
358 // Non-fatal error that happens when children are being added to the linkset but 334 // If constraint doesn't exist yet, create it.
359 // their constraints have not been created yet. 335 constrain = BuildConstraint(LinksetRoot, child);
360 break;
361 } 336 }
362 } 337 constrain.RecomputeConstraintVariables(linksetMass);
363 338
364 // If the whole linkset is not here, doesn't make sense to recompute linkset wide values 339 // DEBUG: see of inter-linkset collisions are causing problems
365 if (m_children.Count == m_taintChildren.Count) 340 // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr,
366 { 341 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
367 // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass
368 OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
369 BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity);
370 // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
371 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
372 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraintVariables,setCenterOfMass,COM={1},rBody={2},linksetMass={3}",
373 LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass);
374 foreach (BSPhysObject child in m_taintChildren)
375 {
376 BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity);
377 // A child in the linkset physically shows the mass of the whole linkset.
378 // This allows Bullet to apply enough force on the child to move the whole linkset.
379 child.UpdatePhysicalMassProperties(linksetMass);
380 // DEBUG: see of inter-linkset collisions are causing problems
381 // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr,
382 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
383 }
384 // Also update the root's physical mass to the whole linkset
385 LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
386 342
387 // BulletSimAPI.DumpAllInfo2(PhysicsScene.World.ptr); // DEBUG DEBUG DEBUG 343 // BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG
388 } 344 }
389 return; 345
390 } 346 }
391} 347}
392} 348}