diff options
Diffstat (limited to 'OpenSim')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 67979b3..086aa12 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | |||
@@ -43,23 +43,20 @@ public sealed 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 such a way that the |
47 | public override void Refresh(BSPhysObject requestor, bool inTaintTime) | 47 | // refresh will only 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 | // If there are no children, there are no constraints to recompute. |
50 | if (!HasAnyChildren || !IsRoot(requestor)) | 51 | if (!HasAnyChildren) |
51 | return; | 52 | return; |
52 | 53 | ||
53 | BSScene.TaintCallback refreshOperation = delegate() | 54 | // Queue to happen after all the other taint processing |
55 | PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() | ||
54 | { | 56 | { |
55 | RecomputeLinksetConstraintVariables(); | 57 | RecomputeLinksetConstraintVariables(); |
56 | DetailLog("{0},BSLinkset.Refresh,complete,rBody={1}", | 58 | }); |
57 | LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); | 59 | |
58 | }; | ||
59 | if (inTaintTime) | ||
60 | refreshOperation(); | ||
61 | else | ||
62 | PhysicsScene.TaintedObject("BSLinkSet.Refresh", refreshOperation); | ||
63 | } | 60 | } |
64 | 61 | ||
65 | // The object is going dynamic (physical). Do any setup necessary | 62 | // The object is going dynamic (physical). Do any setup necessary |
@@ -104,14 +101,14 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
104 | if (IsRoot(child)) | 101 | if (IsRoot(child)) |
105 | { | 102 | { |
106 | // If the one with the dependency is root, must undo all children | 103 | // If the one with the dependency is root, must undo all children |
107 | DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", | 104 | DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", |
108 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); | 105 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X")); |
109 | 106 | ||
110 | ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); | 107 | ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); |
111 | } | 108 | } |
112 | else | 109 | else |
113 | { | 110 | { |
114 | DetailLog("{0},BSLinkset.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}", | 111 | DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}", |
115 | child.LocalID, | 112 | child.LocalID, |
116 | LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), | 113 | LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), |
117 | child.LocalID, child.BSBody.ptr.ToString("X")); | 114 | child.LocalID, child.BSBody.ptr.ToString("X")); |
@@ -132,7 +129,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
132 | { | 129 | { |
133 | if (IsRoot(child)) | 130 | if (IsRoot(child)) |
134 | { | 131 | { |
135 | DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}", | 132 | DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}", |
136 | child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count); | 133 | child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count); |
137 | foreach (BSPhysObject bpo in m_taintChildren) | 134 | foreach (BSPhysObject bpo in m_taintChildren) |
138 | { | 135 | { |
@@ -141,7 +138,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
141 | } | 138 | } |
142 | else | 139 | else |
143 | { | 140 | { |
144 | DetailLog("{0},BSLinkset.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}", | 141 | DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}", |
145 | LinksetRoot.LocalID, | 142 | LinksetRoot.LocalID, |
146 | LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), | 143 | LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"), |
147 | child.LocalID, child.BSBody.ptr.ToString("X")); | 144 | child.LocalID, child.BSBody.ptr.ToString("X")); |
@@ -178,6 +175,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
178 | PhysicallyLinkAChildToRoot(rootx, childx); | 175 | PhysicallyLinkAChildToRoot(rootx, childx); |
179 | m_taintChildren.Add(child); | 176 | m_taintChildren.Add(child); |
180 | }); | 177 | }); |
178 | Refresh(LinksetRoot); | ||
181 | } | 179 | } |
182 | return; | 180 | return; |
183 | } | 181 | } |
@@ -211,9 +209,9 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
211 | { | 209 | { |
212 | m_taintChildren.Remove(child); | 210 | m_taintChildren.Remove(child); |
213 | PhysicallyUnlinkAChildFromRoot(rootx, childx); | 211 | PhysicallyUnlinkAChildFromRoot(rootx, childx); |
214 | RecomputeLinksetConstraintVariables(); | ||
215 | }); | 212 | }); |
216 | 213 | // See that the linkset parameters are recomputed at the end of the taint time. | |
214 | Refresh(LinksetRoot); | ||
217 | } | 215 | } |
218 | else | 216 | else |
219 | { | 217 | { |
@@ -237,7 +235,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
237 | // real world coordinate of midpoint between the two objects | 235 | // real world coordinate of midpoint between the two objects |
238 | OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); | 236 | OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); |
239 | 237 | ||
240 | DetailLog("{0},BSLinkset.PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", | 238 | DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", |
241 | rootPrim.LocalID, | 239 | rootPrim.LocalID, |
242 | rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), | 240 | rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), |
243 | childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"), | 241 | childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"), |
@@ -248,6 +246,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
248 | 246 | ||
249 | BSConstraint6Dof constrain = new BSConstraint6Dof( | 247 | BSConstraint6Dof constrain = new BSConstraint6Dof( |
250 | PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, midPoint, true, true ); | 248 | PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody, midPoint, true, true ); |
249 | // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); | ||
251 | 250 | ||
252 | /* NOTE: below is an attempt to build constraint with full frame computation, etc. | 251 | /* 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 | 252 | * Using the midpoint is easier since it lets the Bullet code manipulate the transforms |
@@ -264,7 +263,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
264 | 263 | ||
265 | // create a constraint that allows no freedom of movement between the two objects | 264 | // create a constraint that allows no freedom of movement between the two objects |
266 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | 265 | // 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); | 266 | DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); |
268 | BS6DofConstraint constrain = new BS6DofConstraint( | 267 | BS6DofConstraint constrain = new BS6DofConstraint( |
269 | PhysicsScene.World, rootPrim.Body, childPrim.Body, | 268 | PhysicsScene.World, rootPrim.Body, childPrim.Body, |
270 | OMV.Vector3.Zero, | 269 | OMV.Vector3.Zero, |
@@ -307,7 +306,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
307 | private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) | 306 | private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) |
308 | { | 307 | { |
309 | bool ret = false; | 308 | bool ret = false; |
310 | DetailLog("{0},BSLinkset.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", | 309 | DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", |
311 | rootPrim.LocalID, | 310 | rootPrim.LocalID, |
312 | rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), | 311 | rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), |
313 | childPrim.LocalID, childPrim.BSBody.ptr.ToString("X")); | 312 | childPrim.LocalID, childPrim.BSBody.ptr.ToString("X")); |
@@ -327,7 +326,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
327 | // Called at taint time! | 326 | // Called at taint time! |
328 | private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) | 327 | private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) |
329 | { | 328 | { |
330 | DetailLog("{0},BSLinkset.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); | 329 | DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); |
331 | bool ret = false; | 330 | bool ret = false; |
332 | 331 | ||
333 | if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody)) | 332 | if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody)) |
@@ -350,7 +349,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
350 | BSConstraint constrain; | 349 | BSConstraint constrain; |
351 | if (PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) | 350 | if (PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) |
352 | { | 351 | { |
353 | // DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}", | 352 | // DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}", |
354 | // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID); | 353 | // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID); |
355 | constrain.RecomputeConstraintVariables(linksetMass); | 354 | constrain.RecomputeConstraintVariables(linksetMass); |
356 | } | 355 | } |
@@ -367,15 +366,23 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
367 | { | 366 | { |
368 | // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass | 367 | // 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(); | 368 | OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); |
370 | BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, | 369 | BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); |
371 | centerOfMass, OMV.Quaternion.Identity); | 370 | // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, |
372 | DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,setCenterOfMass,COM={1},rBody={2}", | 371 | // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); |
373 | LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X")); | 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) | 374 | foreach (BSPhysObject child in m_taintChildren) |
375 | { | 375 | { |
376 | BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, | 376 | BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); |
377 | 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); | ||
378 | } | 383 | } |
384 | // Also update the root's physical mass to the whole linkset | ||
385 | LinksetRoot.UpdatePhysicalMassProperties(linksetMass); | ||
379 | 386 | ||
380 | // BulletSimAPI.DumpAllInfo2(PhysicsScene.World.ptr); // DEBUG DEBUG DEBUG | 387 | // BulletSimAPI.DumpAllInfo2(PhysicsScene.World.ptr); // DEBUG DEBUG DEBUG |
381 | } | 388 | } |