diff options
Diffstat (limited to 'OpenSim/Region/Physics')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 146 |
1 files changed, 40 insertions, 106 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index e3ce7fb..20eb871 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -35,6 +35,7 @@ using OMV = OpenMetaverse; | |||
35 | namespace OpenSim.Region.Physics.BulletSPlugin | 35 | namespace OpenSim.Region.Physics.BulletSPlugin |
36 | { | 36 | { |
37 | 37 | ||
38 | /* | ||
38 | // When a child is linked, the relationship position of the child to the parent | 39 | // When a child is linked, the relationship position of the child to the parent |
39 | // is remembered so the child's world position can be recomputed when it is | 40 | // is remembered so the child's world position can be recomputed when it is |
40 | // removed from the linkset. | 41 | // removed from the linkset. |
@@ -88,17 +89,15 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo | |||
88 | return buff.ToString(); | 89 | return buff.ToString(); |
89 | } | 90 | } |
90 | }; | 91 | }; |
92 | */ | ||
91 | 93 | ||
92 | public sealed class BSLinksetCompound : BSLinkset | 94 | public sealed class BSLinksetCompound : BSLinkset |
93 | { | 95 | { |
94 | private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; | 96 | private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; |
95 | 97 | ||
96 | private BSShape LinksetShape; | ||
97 | |||
98 | public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) | 98 | public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) |
99 | : base(scene, parent) | 99 | : base(scene, parent) |
100 | { | 100 | { |
101 | LinksetShape = new BSShapeNull(); | ||
102 | } | 101 | } |
103 | 102 | ||
104 | // When physical properties are changed the linkset needs to recalculate | 103 | // When physical properties are changed the linkset needs to recalculate |
@@ -143,25 +142,11 @@ public sealed class BSLinksetCompound : BSLinkset | |||
143 | // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly. | 142 | // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly. |
144 | ScheduleRebuild(LinksetRoot); | 143 | ScheduleRebuild(LinksetRoot); |
145 | } | 144 | } |
146 | |||
147 | // The origional prims are removed from the world as the shape of the root compound | ||
148 | // shape takes over. | ||
149 | m_physicsScene.PE.AddToCollisionFlags(child.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); | ||
150 | m_physicsScene.PE.ForceActivationState(child.PhysBody, ActivationState.DISABLE_SIMULATION); | ||
151 | // We don't want collisions from the old linkset children. | ||
152 | m_physicsScene.PE.RemoveFromCollisionFlags(child.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
153 | |||
154 | child.PhysBody.collisionType = CollisionType.LinksetChild; | ||
155 | |||
156 | ret = true; | ||
157 | |||
158 | return ret; | 145 | return ret; |
159 | } | 146 | } |
160 | 147 | ||
161 | // The object is going static (non-physical). Do any setup necessary for a static linkset. | 148 | // The object is going static (non-physical). We do not do anything for static linksets. |
162 | // Return 'true' if any properties updated on the passed object. | 149 | // Return 'true' if any properties updated on the passed object. |
163 | // This doesn't normally happen -- OpenSim removes the objects from the physical | ||
164 | // world if it is a static linkset. | ||
165 | // Called at taint-time! | 150 | // Called at taint-time! |
166 | public override bool MakeStatic(BSPrimLinkable child) | 151 | public override bool MakeStatic(BSPrimLinkable child) |
167 | { | 152 | { |
@@ -169,19 +154,9 @@ public sealed class BSLinksetCompound : BSLinkset | |||
169 | DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); | 154 | DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); |
170 | if (IsRoot(child)) | 155 | if (IsRoot(child)) |
171 | { | 156 | { |
157 | // Schedule a rebuild to verify that the root shape is set to the real shape. | ||
172 | ScheduleRebuild(LinksetRoot); | 158 | ScheduleRebuild(LinksetRoot); |
173 | } | 159 | } |
174 | else | ||
175 | { | ||
176 | // The non-physical children can come back to life. | ||
177 | m_physicsScene.PE.RemoveFromCollisionFlags(child.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); | ||
178 | |||
179 | child.PhysBody.collisionType = CollisionType.LinksetChild; | ||
180 | |||
181 | // Don't force activation so setting of DISABLE_SIMULATION can stay if used. | ||
182 | m_physicsScene.PE.Activate(child.PhysBody, false); | ||
183 | ret = true; | ||
184 | } | ||
185 | return ret; | 160 | return ret; |
186 | } | 161 | } |
187 | 162 | ||
@@ -283,9 +258,6 @@ public sealed class BSLinksetCompound : BSLinkset | |||
283 | 258 | ||
284 | if (!IsRoot(child)) | 259 | if (!IsRoot(child)) |
285 | { | 260 | { |
286 | // Because it is a convenient time, recompute child world position and rotation based on | ||
287 | // its position in the linkset. | ||
288 | RecomputeChildWorldPosition(child, true /* inTaintTime */); | ||
289 | child.LinksetInfo = null; | 261 | child.LinksetInfo = null; |
290 | } | 262 | } |
291 | 263 | ||
@@ -296,50 +268,6 @@ public sealed class BSLinksetCompound : BSLinkset | |||
296 | return ret; | 268 | return ret; |
297 | } | 269 | } |
298 | 270 | ||
299 | // When the linkset is built, the child shape is added to the compound shape relative to the | ||
300 | // root shape. The linkset then moves around but this does not move the actual child | ||
301 | // prim. The child prim's location must be recomputed based on the location of the root shape. | ||
302 | private void RecomputeChildWorldPosition(BSPrimLinkable child, bool inTaintTime) | ||
303 | { | ||
304 | // For the moment (20130201), disable this computation (converting the child physical addr back to | ||
305 | // a region address) until we have a good handle on center-of-mass offsets and what the physics | ||
306 | // engine moving a child actually means. | ||
307 | // The simulator keeps track of where children should be as the linkset moves. Setting | ||
308 | // the pos/rot here does not effect that knowledge as there is no good way for the | ||
309 | // physics engine to send the simulator an update for a child. | ||
310 | |||
311 | /* | ||
312 | BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; | ||
313 | if (lci != null) | ||
314 | { | ||
315 | if (inTaintTime) | ||
316 | { | ||
317 | OMV.Vector3 oldPos = child.RawPosition; | ||
318 | child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot; | ||
319 | child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; | ||
320 | DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", | ||
321 | child.LocalID, oldPos, lci, child.RawPosition); | ||
322 | } | ||
323 | else | ||
324 | { | ||
325 | // TaintedObject is not used here so the raw position is set now and not at taint-time. | ||
326 | child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot; | ||
327 | child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; | ||
328 | } | ||
329 | } | ||
330 | else | ||
331 | { | ||
332 | // This happens when children have been added to the linkset but the linkset | ||
333 | // has not been constructed yet. So like, at taint time, adding children to a linkset | ||
334 | // and then changing properties of the children (makePhysical, for instance) | ||
335 | // but the post-print action of actually rebuilding the linkset has not yet happened. | ||
336 | // PhysicsScene.Logger.WarnFormat("{0} Restoring linkset child position failed because of no relative position computed. ID={1}", | ||
337 | // LogHeader, child.LocalID); | ||
338 | DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID); | ||
339 | } | ||
340 | */ | ||
341 | } | ||
342 | |||
343 | // ================================================================ | 271 | // ================================================================ |
344 | 272 | ||
345 | // Add a new child to the linkset. | 273 | // Add a new child to the linkset. |
@@ -372,7 +300,6 @@ public sealed class BSLinksetCompound : BSLinkset | |||
372 | child.LocalID, child.PhysBody.AddrString); | 300 | child.LocalID, child.PhysBody.AddrString); |
373 | 301 | ||
374 | // Cause the child's body to be rebuilt and thus restored to normal operation | 302 | // Cause the child's body to be rebuilt and thus restored to normal operation |
375 | RecomputeChildWorldPosition(child, false); | ||
376 | child.LinksetInfo = null; | 303 | child.LinksetInfo = null; |
377 | child.ForceBodyShapeRebuild(false); | 304 | child.ForceBodyShapeRebuild(false); |
378 | 305 | ||
@@ -399,26 +326,27 @@ public sealed class BSLinksetCompound : BSLinkset | |||
399 | private bool disableCOM = true; // For basic linkset debugging, turn off the center-of-mass setting | 326 | private bool disableCOM = true; // For basic linkset debugging, turn off the center-of-mass setting |
400 | private void RecomputeLinksetCompound() | 327 | private void RecomputeLinksetCompound() |
401 | { | 328 | { |
402 | if (!LinksetRoot.IsPhysicallyActive) | ||
403 | { | ||
404 | // There is no reason to build all this physical stuff for a non-physical linkset | ||
405 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); | ||
406 | return; | ||
407 | } | ||
408 | |||
409 | try | 329 | try |
410 | { | 330 | { |
411 | // This replaces the physical shape of the root prim with a compound shape made up of the root | 331 | Rebuilding = true; |
412 | // shape and all the children. | 332 | |
333 | // No matter what is being done, force the root prim's PhysBody and PhysShape to get set | ||
334 | // to what they should be as if the root was not in a linkset. | ||
335 | // Not that bad since we only get into this routine if there are children in the linkset and | ||
336 | // something has been updated/changed. | ||
337 | LinksetRoot.ForceBodyShapeRebuild(true); | ||
413 | 338 | ||
414 | // RootPrim.PhysShape is the shape of the root prim. | 339 | // There is no reason to build all this physical stuff for a non-physical linkset. |
415 | // Here we build the compound shape made up of all the children. | 340 | if (!LinksetRoot.IsPhysicallyActive) |
341 | { | ||
342 | // Clean up any old linkset shape and make sure the root shape is set to the root object. | ||
343 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); | ||
416 | 344 | ||
417 | // Free up any shape we'd previously built. | 345 | return; // Note the 'finally' clause at the botton which will get executed. |
418 | LinksetShape.Dereference(m_physicsScene); | 346 | } |
419 | 347 | ||
420 | // Get a new compound shape to build the linkset shape in. | 348 | // Get a new compound shape to build the linkset shape in. |
421 | LinksetShape = BSShapeCompound.GetReference(m_physicsScene); | 349 | BSShape linksetShape = BSShapeCompound.GetReference(m_physicsScene); |
422 | 350 | ||
423 | // The center of mass for the linkset is the geometric center of the group. | 351 | // The center of mass for the linkset is the geometric center of the group. |
424 | // Compute a displacement for each component so it is relative to the center-of-mass. | 352 | // Compute a displacement for each component so it is relative to the center-of-mass. |
@@ -445,35 +373,41 @@ public sealed class BSLinksetCompound : BSLinkset | |||
445 | int memberIndex = 1; | 373 | int memberIndex = 1; |
446 | ForEachMember(delegate(BSPrimLinkable cPrim) | 374 | ForEachMember(delegate(BSPrimLinkable cPrim) |
447 | { | 375 | { |
448 | if (IsRoot(cPrim)) | 376 | // Root shape is always index zero. |
449 | { | 377 | cPrim.LinksetChildIndex = IsRoot(cPrim) ? 0 : memberIndex; |
450 | cPrim.LinksetChildIndex = 0; | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | cPrim.LinksetChildIndex = memberIndex; | ||
455 | } | ||
456 | 378 | ||
379 | // Get a reference to the shape of the child and add that shape to the linkset compound shape | ||
457 | BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim); | 380 | BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim); |
458 | OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; | 381 | OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; |
459 | OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; | 382 | OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; |
460 | m_physicsScene.PE.AddChildShapeToCompoundShape(LinksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot); | 383 | m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot); |
461 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1}cShape={2},offPos={3},offRot={4}", | 384 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}", |
462 | LinksetRoot.LocalID, memberIndex, cPrim.PhysShape, offsetPos, offsetRot); | 385 | LinksetRoot.LocalID, memberIndex, cPrim.PhysShape, offsetPos, offsetRot); |
463 | 386 | ||
387 | // Since we are borrowing the shape of the child, disable the origional child body | ||
388 | if (!IsRoot(cPrim)) | ||
389 | { | ||
390 | m_physicsScene.PE.AddToCollisionFlags(cPrim.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); | ||
391 | m_physicsScene.PE.ForceActivationState(cPrim.PhysBody, ActivationState.DISABLE_SIMULATION); | ||
392 | // We don't want collisions from the old linkset children. | ||
393 | m_physicsScene.PE.RemoveFromCollisionFlags(cPrim.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
394 | cPrim.PhysBody.collisionType = CollisionType.LinksetChild; | ||
395 | } | ||
396 | |||
464 | memberIndex++; | 397 | memberIndex++; |
465 | 398 | ||
466 | return false; // 'false' says to move onto the next child in the list | 399 | return false; // 'false' says to move onto the next child in the list |
467 | }); | 400 | }); |
468 | 401 | ||
469 | // Sneak the built compound shape in as the shape of the root prim. | 402 | // Replace the root shape with the built compound shape. |
470 | // Note this doesn't touch the root prim's PhysShape so be sure the manage the difference. | ||
471 | // Object removed and added to world to get collision cache rebuilt for new shape. | 403 | // Object removed and added to world to get collision cache rebuilt for new shape. |
404 | LinksetRoot.PhysShape.Dereference(m_physicsScene); | ||
405 | LinksetRoot.PhysShape = linksetShape; | ||
472 | m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, LinksetRoot.PhysBody); | 406 | m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, LinksetRoot.PhysBody); |
473 | m_physicsScene.PE.SetCollisionShape(m_physicsScene.World, LinksetRoot.PhysBody, LinksetShape.physShapeInfo); | 407 | m_physicsScene.PE.SetCollisionShape(m_physicsScene.World, LinksetRoot.PhysBody, linksetShape.physShapeInfo); |
474 | m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody); | 408 | m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody); |
475 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}", | 409 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}", |
476 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetShape); | 410 | LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape); |
477 | 411 | ||
478 | // With all of the linkset packed into the root prim, it has the mass of everyone. | 412 | // With all of the linkset packed into the root prim, it has the mass of everyone. |
479 | LinksetMass = ComputeLinksetMass(); | 413 | LinksetMass = ComputeLinksetMass(); |
@@ -494,7 +428,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
494 | } | 428 | } |
495 | 429 | ||
496 | // See that the Aabb surrounds the new shape | 430 | // See that the Aabb surrounds the new shape |
497 | m_physicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetShape.physShapeInfo); | 431 | m_physicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape.physShapeInfo); |
498 | } | 432 | } |
499 | } | 433 | } |
500 | } \ No newline at end of file | 434 | } \ No newline at end of file |