BulletSim: disable center-of-mass computation for linksets until debugged. Move physical prim above ground if it is underground. Previously tried to correct by applying and up force but the prim would never go through the ground.

user_profiles
Robert Adams 2013-01-13 22:32:31 -08:00
parent 459fcd81c9
commit 8bf0a9f85d
2 changed files with 36 additions and 25 deletions

View File

@ -319,6 +319,7 @@ public sealed class BSLinksetCompound : BSLinkset
// Constraint linksets are rebuilt every time. // Constraint linksets are rebuilt every time.
// Note that this works for rebuilding just the root after a linkset is taken apart. // Note that this works for rebuilding just the root after a linkset is taken apart.
// Called at taint time!! // Called at taint time!!
private bool disableCOM = true; // disable until we get this debugged
private void RecomputeLinksetCompound() private void RecomputeLinksetCompound()
{ {
try try
@ -331,15 +332,26 @@ public sealed class BSLinksetCompound : BSLinkset
// The center of mass for the linkset is the geometric center of the group. // The center of mass for the linkset is the geometric center of the group.
// Compute a displacement for each component so it is relative to the center-of-mass. // Compute a displacement for each component so it is relative to the center-of-mass.
OMV.Vector3 centerOfMass = ComputeLinksetGeometricCenter(); // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
OMV.Vector3 centerDisplacement = centerOfMass - LinksetRoot.RawPosition; OMV.Vector3 centerOfMass;
OMV.Vector3 centerDisplacement = OMV.Vector3.Zero;
if (disableCOM) // DEBUG DEBUG
{ // DEBUG DEBUG
centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
} // DEBUG DEBUG
else
{
centerOfMass = ComputeLinksetGeometricCenter();
centerDisplacement = centerOfMass - LinksetRoot.RawPosition;
// Since we're displacing the center of the shape, we need to move the body in the world // Since we're displacing the center of the shape, we need to move the body in the world
LinksetRoot.PositionDisplacement = centerDisplacement * LinksetRoot.RawOrientation; LinksetRoot.PositionDisplacement = centerDisplacement;
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false);
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement);
}
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
@ -357,14 +369,15 @@ public sealed class BSLinksetCompound : BSLinkset
BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
if (lci == null) if (lci == null)
{ {
// Each child position and rotation is given relative to the root. // Each child position and rotation is given relative to the center-of-mass.
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
// Save relative position for recomputing child's world position after moving linkset. // Save relative position for recomputing child's world position after moving linkset.
lci = new BSLinksetCompoundInfo(memberIndex, displacementPos, displacementRot); lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot);
lci.OffsetFromCenterOfMass = displacementPos - centerDisplacement; lci.OffsetFromRoot = displacementFromRoot;
cPrim.LinksetInfo = lci; cPrim.LinksetInfo = lci;
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
} }

View File

@ -297,7 +297,7 @@ public sealed class BSPrim : BSPhysObject
*/ */
// don't do the GetObjectPosition for root elements because this function is called a zillion times. // don't do the GetObjectPosition for root elements because this function is called a zillion times.
// _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody); // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement;
return _position; return _position;
} }
set { set {
@ -362,7 +362,7 @@ public sealed class BSPrim : BSPhysObject
{ {
bool ret = false; bool ret = false;
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
{ {
// The physical object is out of the known/simulated area. // The physical object is out of the known/simulated area.
// Upper levels of code will handle the transition to other areas so, for // Upper levels of code will handle the transition to other areas so, for
@ -376,8 +376,11 @@ public sealed class BSPrim : BSPhysObject
{ {
DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
float targetHeight = terrainHeight + (Size.Z / 2f); float targetHeight = terrainHeight + (Size.Z / 2f);
// Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. // If the object is below ground it just has to be moved up because pushing will
upForce.Z = (terrainHeight - RawPosition.Z) * 1f; // not get it through the terrain
_position.Z = targetHeight;
if (!inTaintTime)
ForcePosition = _position;
ret = true; ret = true;
} }
@ -389,20 +392,15 @@ public sealed class BSPrim : BSPhysObject
{ {
// Upforce proportional to the distance away from the water. Correct the error in 1 sec. // Upforce proportional to the distance away from the water. Correct the error in 1 sec.
upForce.Z = (waterHeight - RawPosition.Z) * 1f; upForce.Z = (waterHeight - RawPosition.Z) * 1f;
ret = true;
}
}
// The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
// TODO: This should be intergrated with a geneal physics action mechanism.
// TODO: This should be moderated with PID'ness.
if (ret)
{
// Apply upforce and overcome gravity. // Apply upforce and overcome gravity.
OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
AddForce(correctionForce, false, inTaintTime); AddForce(correctionForce, false, inTaintTime);
ret = true;
} }
}
return ret; return ret;
} }