aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs146
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;
35namespace OpenSim.Region.Physics.BulletSPlugin 35namespace 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
92public sealed class BSLinksetCompound : BSLinkset 94public 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