diff options
Diffstat (limited to '')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | 100 |
1 files changed, 70 insertions, 30 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 6d252ca..f17d698 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | |||
@@ -48,12 +48,22 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
48 | { | 48 | { |
49 | base.Refresh(requestor); | 49 | base.Refresh(requestor); |
50 | 50 | ||
51 | if (HasAnyChildren && IsRoot(requestor)) | 51 | } |
52 | |||
53 | private void ScheduleRebuild(BSPrimLinkable requestor) | ||
54 | { | ||
55 | DetailLog("{0},BSLinksetConstraint.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}", | ||
56 | requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren)); | ||
57 | |||
58 | // When rebuilding, it is possible to set properties that would normally require a rebuild. | ||
59 | // If already rebuilding, don't request another rebuild. | ||
60 | // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding. | ||
61 | if (!Rebuilding && HasAnyChildren) | ||
52 | { | 62 | { |
53 | // Queue to happen after all the other taint processing | 63 | // Queue to happen after all the other taint processing |
54 | PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() | 64 | m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() |
55 | { | 65 | { |
56 | if (HasAnyChildren && IsRoot(requestor)) | 66 | if (HasAnyChildren) |
57 | RecomputeLinksetConstraints(); | 67 | RecomputeLinksetConstraints(); |
58 | }); | 68 | }); |
59 | } | 69 | } |
@@ -67,8 +77,14 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
67 | // Called at taint-time! | 77 | // Called at taint-time! |
68 | public override bool MakeDynamic(BSPrimLinkable child) | 78 | public override bool MakeDynamic(BSPrimLinkable child) |
69 | { | 79 | { |
70 | // What is done for each object in BSPrim is what we want. | 80 | bool ret = false; |
71 | return false; | 81 | DetailLog("{0},BSLinksetConstraints.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); |
82 | if (IsRoot(child)) | ||
83 | { | ||
84 | // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly. | ||
85 | ScheduleRebuild(LinksetRoot); | ||
86 | } | ||
87 | return ret; | ||
72 | } | 88 | } |
73 | 89 | ||
74 | // The object is going static (non-physical). Do any setup necessary for a static linkset. | 90 | // The object is going static (non-physical). Do any setup necessary for a static linkset. |
@@ -78,8 +94,16 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
78 | // Called at taint-time! | 94 | // Called at taint-time! |
79 | public override bool MakeStatic(BSPrimLinkable child) | 95 | public override bool MakeStatic(BSPrimLinkable child) |
80 | { | 96 | { |
81 | // What is done for each object in BSPrim is what we want. | 97 | bool ret = false; |
82 | return false; | 98 | |
99 | DetailLog("{0},BSLinksetConstraint.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); | ||
100 | child.ClearDisplacement(); | ||
101 | if (IsRoot(child)) | ||
102 | { | ||
103 | // Schedule a rebuild to verify that the root shape is set to the real shape. | ||
104 | ScheduleRebuild(LinksetRoot); | ||
105 | } | ||
106 | return ret; | ||
83 | } | 107 | } |
84 | 108 | ||
85 | // Called at taint-time!! | 109 | // Called at taint-time!! |
@@ -93,11 +117,11 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
93 | // up to rebuild the constraints before the next simulation step. | 117 | // up to rebuild the constraints before the next simulation step. |
94 | // Returns 'true' of something was actually removed and would need restoring | 118 | // Returns 'true' of something was actually removed and would need restoring |
95 | // Called at taint-time!! | 119 | // Called at taint-time!! |
96 | public override bool RemoveBodyDependencies(BSPrimLinkable child) | 120 | public override bool RemoveDependencies(BSPrimLinkable child) |
97 | { | 121 | { |
98 | bool ret = false; | 122 | bool ret = false; |
99 | 123 | ||
100 | DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", | 124 | DetailLog("{0},BSLinksetConstraint.RemoveDependencies,removeChildrenForRoot,rID={1},rBody={2}", |
101 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString); | 125 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString); |
102 | 126 | ||
103 | lock (m_linksetActivityLock) | 127 | lock (m_linksetActivityLock) |
@@ -105,7 +129,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
105 | // Just undo all the constraints for this linkset. Rebuild at the end of the step. | 129 | // Just undo all the constraints for this linkset. Rebuild at the end of the step. |
106 | ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); | 130 | ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); |
107 | // Cause the constraints, et al to be rebuilt before the next simulation step. | 131 | // Cause the constraints, et al to be rebuilt before the next simulation step. |
108 | Refresh(LinksetRoot); | 132 | ScheduleRebuild(LinksetRoot); |
109 | } | 133 | } |
110 | return ret; | 134 | return ret; |
111 | } | 135 | } |
@@ -123,7 +147,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
123 | DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); | 147 | DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); |
124 | 148 | ||
125 | // Cause constraints and assorted properties to be recomputed before the next simulation step. | 149 | // Cause constraints and assorted properties to be recomputed before the next simulation step. |
126 | Refresh(LinksetRoot); | 150 | ScheduleRebuild(LinksetRoot); |
127 | } | 151 | } |
128 | return; | 152 | return; |
129 | } | 153 | } |
@@ -142,12 +166,12 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
142 | rootx.LocalID, rootx.PhysBody.AddrString, | 166 | rootx.LocalID, rootx.PhysBody.AddrString, |
143 | childx.LocalID, childx.PhysBody.AddrString); | 167 | childx.LocalID, childx.PhysBody.AddrString); |
144 | 168 | ||
145 | PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() | 169 | m_physicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() |
146 | { | 170 | { |
147 | PhysicallyUnlinkAChildFromRoot(rootx, childx); | 171 | PhysicallyUnlinkAChildFromRoot(rootx, childx); |
148 | }); | 172 | }); |
149 | // See that the linkset parameters are recomputed at the end of the taint time. | 173 | // See that the linkset parameters are recomputed at the end of the taint time. |
150 | Refresh(LinksetRoot); | 174 | ScheduleRebuild(LinksetRoot); |
151 | } | 175 | } |
152 | else | 176 | else |
153 | { | 177 | { |
@@ -165,6 +189,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
165 | Refresh(rootPrim); | 189 | Refresh(rootPrim); |
166 | } | 190 | } |
167 | 191 | ||
192 | // Create a static constraint between the two passed objects | ||
168 | private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) | 193 | private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) |
169 | { | 194 | { |
170 | // Zero motion for children so they don't interpolate | 195 | // Zero motion for children so they don't interpolate |
@@ -187,7 +212,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
187 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | 212 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 |
188 | 213 | ||
189 | BSConstraint6Dof constrain = new BSConstraint6Dof( | 214 | BSConstraint6Dof constrain = new BSConstraint6Dof( |
190 | PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true ); | 215 | m_physicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true ); |
191 | // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); | 216 | // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); |
192 | 217 | ||
193 | /* NOTE: below is an attempt to build constraint with full frame computation, etc. | 218 | /* NOTE: below is an attempt to build constraint with full frame computation, etc. |
@@ -216,7 +241,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
216 | // ================================================================================== | 241 | // ================================================================================== |
217 | */ | 242 | */ |
218 | 243 | ||
219 | PhysicsScene.Constraints.AddConstraint(constrain); | 244 | m_physicsScene.Constraints.AddConstraint(constrain); |
220 | 245 | ||
221 | // zero linear and angular limits makes the objects unable to move in relation to each other | 246 | // zero linear and angular limits makes the objects unable to move in relation to each other |
222 | constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | 247 | constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); |
@@ -248,10 +273,10 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
248 | childPrim.LocalID, childPrim.PhysBody.AddrString); | 273 | childPrim.LocalID, childPrim.PhysBody.AddrString); |
249 | 274 | ||
250 | // Find the constraint for this link and get rid of it from the overall collection and from my list | 275 | // Find the constraint for this link and get rid of it from the overall collection and from my list |
251 | if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) | 276 | if (m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) |
252 | { | 277 | { |
253 | // Make the child refresh its location | 278 | // Make the child refresh its location |
254 | PhysicsScene.PE.PushUpdate(childPrim.PhysBody); | 279 | m_physicsScene.PE.PushUpdate(childPrim.PhysBody); |
255 | ret = true; | 280 | ret = true; |
256 | } | 281 | } |
257 | 282 | ||
@@ -265,7 +290,7 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
265 | { | 290 | { |
266 | DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); | 291 | DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); |
267 | 292 | ||
268 | return PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody); | 293 | return m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody); |
269 | } | 294 | } |
270 | 295 | ||
271 | // Call each of the constraints that make up this linkset and recompute the | 296 | // Call each of the constraints that make up this linkset and recompute the |
@@ -281,24 +306,39 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
281 | DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", | 306 | DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", |
282 | LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass); | 307 | LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass); |
283 | 308 | ||
284 | foreach (BSPrimLinkable child in m_children) | 309 | try |
285 | { | 310 | { |
286 | // A child in the linkset physically shows the mass of the whole linkset. | 311 | Rebuilding = true; |
287 | // This allows Bullet to apply enough force on the child to move the whole linkset. | ||
288 | // (Also do the mass stuff before recomputing the constraint so mass is not zero.) | ||
289 | child.UpdatePhysicalMassProperties(linksetMass, true); | ||
290 | 312 | ||
291 | BSConstraint constrain; | 313 | // There is no reason to build all this physical stuff for a non-physical linkset. |
292 | if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) | 314 | if (!LinksetRoot.IsPhysicallyActive) |
293 | { | 315 | { |
294 | // If constraint doesn't exist yet, create it. | 316 | DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); |
295 | constrain = BuildConstraint(LinksetRoot, child); | 317 | return; // Note the 'finally' clause at the botton which will get executed. |
296 | } | 318 | } |
297 | constrain.RecomputeConstraintVariables(linksetMass); | ||
298 | 319 | ||
299 | // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG | 320 | foreach (BSPrimLinkable child in m_children) |
300 | } | 321 | { |
322 | // A child in the linkset physically shows the mass of the whole linkset. | ||
323 | // This allows Bullet to apply enough force on the child to move the whole linkset. | ||
324 | // (Also do the mass stuff before recomputing the constraint so mass is not zero.) | ||
325 | child.UpdatePhysicalMassProperties(linksetMass, true); | ||
326 | |||
327 | BSConstraint constrain; | ||
328 | if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) | ||
329 | { | ||
330 | // If constraint doesn't exist yet, create it. | ||
331 | constrain = BuildConstraint(LinksetRoot, child); | ||
332 | } | ||
333 | constrain.RecomputeConstraintVariables(linksetMass); | ||
301 | 334 | ||
335 | // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG | ||
336 | } | ||
337 | } | ||
338 | finally | ||
339 | { | ||
340 | Rebuilding = false; | ||
341 | } | ||
302 | } | 342 | } |
303 | } | 343 | } |
304 | } | 344 | } |