From 5bb85a14d46ad280b045e945edcc9e9bc6045612 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 1 Feb 2013 11:52:27 -0800 Subject: [PATCH] BulletSim: fix problem where editting a physical linkset caused the child prim physical positions to get out of sync with the view. More reliably compute the offset of children in a physical linkset. --- .../BulletSPlugin/BSLinksetCompound.cs | 51 ++++++++++++------- .../Physics/BulletSPlugin/BulletSimTODO.txt | 1 + 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 6c6ca09d3f..0c4db4063c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -219,30 +219,31 @@ public sealed class BSLinksetCompound : BSLinkset { // Gather the child info. It might not be there if the linkset is in transition. BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo; - - // The linksetInfo will need to be rebuilt either here or when the linkset is rebuilt - if (LinksetRoot.PhysShape.HasPhysicalShape && lsi != null) + if (lsi != null) { - if (PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) + // Since the child moved or rotationed, it needs a new relative position within the linkset + BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); + updated.LinksetInfo = newLsi; + + // Find the physical instance of the child + if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) { + // It is possible that the linkset is still under construction and the child is not yet + // inserted into the compound shape. A rebuild of the linkset in a pre-step action will + // build the whole thing with the new position or rotation. + // The index must be checked because Bullet references the child array but does no validity + // checking of the child index passed. int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape); if (lsi.Index < numLinksetChildren) { - // It is possible that the linkset is still under construction and the child is not yet - // inserted into the compound shape. A rebuild of the linkset in a pre-step action will - // build the whole thing with the new position or rotation. - // This must be checked for because Bullet references the child array but does no validity - // checking of the child index passed. BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); if (linksetChildShape.HasPhysicalShape) { - // Compute the offset from the center-of-gravity - BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); + // Found the child shape within the compound shape PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, newLsi.OffsetFromCenterOfMass, newLsi.OffsetRot, true /* shouldRecalculateLocalAabb */); - updated.LinksetInfo = newLsi; updatedChild = true; DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}", updated.LocalID, whichUpdated, newLsi); @@ -262,19 +263,20 @@ public sealed class BSLinksetCompound : BSLinkset } else // DEBUG DEBUG { // DEBUG DEBUG - DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,notCompound", updated.LocalID); + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID); } // DEBUG DEBUG } else // DEBUG DEBUG { // DEBUG DEBUG - DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,rootPhysShape={1},lsi={2}", - updated.LocalID, LinksetRoot.PhysShape, lsi == null ? "NULL" : lsi.ToString()); + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noLinkSetInfo,rootPhysShape={1}", + updated.LocalID, LinksetRoot.PhysShape); } // DEBUG DEBUG + if (!updatedChild) { // If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info. - // Note that there are several ways through this code that will not update the child that can - // occur if the linkset is being rebuilt. In this case, scheduling a rebuild is a NOOP since + // Note: there are several ways through this code that will not update the child if + // the linkset is being rebuilt. In this case, scheduling a rebuild is a NOOP since // there will already be a rebuild scheduled. DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}", updated.LocalID, whichUpdated); @@ -300,7 +302,8 @@ public sealed class BSLinksetCompound : BSLinkset { // Because it is a convenient time, recompute child world position and rotation based on // its position in the linkset. - RecomputeChildWorldPosition(child, true); + RecomputeChildWorldPosition(child, true /* inTaintTime */); + child.LinksetInfo = null; } // Cannot schedule a refresh/rebuild here because this routine is called when @@ -315,6 +318,14 @@ public sealed class BSLinksetCompound : BSLinkset // prim. The child prim's location must be recomputed based on the location of the root shape. private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) { + // For the moment (20130201), disable this computation (converting the child physical addr back to + // a region address) until we have a good handle on center-of-mass offsets and what the physics + // engine moving a child actually means. + // The simulator keeps track of where children should be as the linkset moves. Setting + // the pos/rot here does not effect that knowledge as there is no good way for the + // physics engine to send the simulator an update for a child. + + /* BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; if (lci != null) { @@ -343,6 +354,7 @@ public sealed class BSLinksetCompound : BSLinkset // LogHeader, child.LocalID); DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID); } + */ } // ================================================================ @@ -376,6 +388,7 @@ public sealed class BSLinksetCompound : BSLinkset // Cause the child's body to be rebuilt and thus restored to normal operation RecomputeChildWorldPosition(child, false); + child.LinksetInfo = null; child.ForceBodyShapeRebuild(false); if (!HasAnyChildren) @@ -397,7 +410,7 @@ public sealed class BSLinksetCompound : BSLinkset // Constraint linksets are rebuilt every time. // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! - private bool disableCOM = true; // disable until we get this debugged + private bool disableCOM = true; // DEBUG DEBUG: disable until we get this debugged private void RecomputeLinksetCompound() { try diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 7dfdec1db9..a3b355656d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -127,6 +127,7 @@ Physical and phantom will drop through the terrain LINKSETS ====================================================== +Child prims do not report collisions Editing a child of a linkset causes the child to go phantom Move a child prim once when it is physical and can never move it again without it going phantom Offset the center of the linkset to be the geometric center of all the prims