BulletSim: allow changing position and rotation of a child of a linkset

without rebuilding the whole compound shape. Should make vehicles move
smoother.
user_profiles
Robert Adams 2013-01-21 15:58:22 -08:00
parent 95c53ecae7
commit 471c477863
8 changed files with 112 additions and 46 deletions

View File

@ -899,7 +899,7 @@ public sealed class BSCharacter : BSPhysObject
CurrentEntityProperties = entprop;
// Tell the linkset about value changes
Linkset.UpdateProperties(this, true);
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
// base.RequestPhysicsterseUpdate();

View File

@ -252,7 +252,7 @@ public abstract class BSLinkset
// of the linkset is received.
// Passed flag is update came from physics engine (true) or the user (false).
// Called at taint-time!!
public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate);
public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject physObject);
// Routine used when rebuilding the body of the root of the linkset
// Destroy all the constraints have have been made to root.

View File

@ -51,6 +51,21 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo
OffsetFromCenterOfMass = p;
OffsetRot = r;
}
// 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
public BSLinksetCompoundInfo(int indx, BSPhysObject root, BSPhysObject child, OMV.Vector3 centerDisplacement)
{
// Each child position and rotation is given relative to the center-of-mass.
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation);
OMV.Vector3 displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation;
OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
OMV.Quaternion displacementRot = child.RawOrientation * invRootOrientation;
// Save relative position for recomputing child's world position after moving linkset.
Index = indx;
OffsetFromRoot = displacementFromRoot;
OffsetFromCenterOfMass = displacementFromCOM;
OffsetRot = displacementRot;
}
public override void Clear()
{
Index = 0;
@ -182,24 +197,71 @@ public sealed class BSLinksetCompound : BSLinkset
// 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
// Called at taint-time.
public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate)
public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject updated)
{
// The user moving a child around requires the rebuilding of the linkset compound shape
// One problem is this happens when a border is crossed -- the simulator implementation
// is to store the position into the group which causes the move of the object
// stores the position into the group which causes the move of the object
// but it also means all the child positions get updated.
// What would cause an unnecessary rebuild so we make sure the linkset is in a
// region before bothering to do a rebuild.
if (!IsRoot(updated)
&& !physicalUpdate
&& PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
if (!IsRoot(updated) && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
{
// TODO: replace this with are calculation of the child prim's orientation and pos.
// TODO: for the moment, don't rebuild the compound shape.
// This is often just the car turning its wheels. When we can just reorient the one
// member shape of the compound shape, the overhead of rebuilding won't be a problem.
// updated.LinksetInfo = null;
// ScheduleRebuild(updated);
// If a child of the linkset is updating only the position or rotation, that can be done
// without rebuilding the linkset.
// If a handle for the child can be fetch, we update the child here. If a rebuild was
// scheduled by someone else, the rebuild will just replace this setting.
bool updatedChild = false;
// Anything other than updating position or orientation usually means a physical update
// and that is caused by us updating the object.
if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
{
// Gather the child info. It might not be there if the linkset is in transition.
BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo;
if (LinksetRoot.PhysShape.HasPhysicalShape && lsi != null)
{
if (PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape))
{
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);
PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index,
newLsi.OffsetFromCenterOfMass,
newLsi.OffsetRot,
true /* shouldRecalculateLocalAabb */);
DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1}newLsi={2}",
updated.LocalID, whichUpdated, newLsi);
updated.LinksetInfo = newLsi;
updatedChild = true;
}
else // DEBUG DEBUG
{ // DEBUG DEBUG
DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}",
updated.LocalID, linksetChildShape);
} // DEBUG DEBUG
}
else // DEBUG DEBUG
{ // DEBUG DEBUG
DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,notCompound", 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());
} // DEBUG DEBUG
if (!updatedChild)
{
// If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info.
DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}",
updated.LocalID, whichUpdated);
updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed.
ScheduleRebuild(updated);
}
}
}
}
@ -372,15 +434,7 @@ public sealed class BSLinksetCompound : BSLinkset
BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
if (lci == null)
{
// Each child position and rotation is given relative to the center-of-mass.
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
// Save relative position for recomputing child's world position after moving linkset.
lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot);
lci.OffsetFromRoot = displacementFromRoot;
lci = new BSLinksetCompoundInfo(memberIndex, LinksetRoot, cPrim, centerDisplacement);
cPrim.LinksetInfo = lci;
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
}

View File

@ -83,7 +83,7 @@ public sealed class BSLinksetConstraints : BSLinkset
}
// Called at taint-time!!
public override void UpdateProperties(BSPhysObject updated, bool inTaintTime)
public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject pObj)
{
// Nothing to do for constraints on property updates
}

View File

@ -55,6 +55,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
* BS.ApplyCentralForce BS.ApplyTorque
*/
// Flags used to denote which properties updates when making UpdateProperties calls to linksets, etc.
public enum UpdatedProperties : uint
{
Position = 1 << 0,
Orientation = 1 << 1,
Velocity = 1 << 2,
Acceleration = 1 << 3,
RotationalVelocity = 1 << 4,
EntPropUpdates = Position | Orientation | Velocity | Acceleration | RotationalVelocity,
}
public abstract class BSPhysObject : PhysicsActor
{
protected BSPhysObject()

View File

@ -311,13 +311,14 @@ public sealed class BSPrim : BSPhysObject
_position = value;
PositionSanityCheck(false);
// A linkset might need to know if a component information changed.
Linkset.UpdateProperties(this, false);
PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
{
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
ForcePosition = _position;
// A linkset might need to know if a component information changed.
Linkset.UpdateProperties(UpdatedProperties.Position, this);
});
}
}
@ -682,12 +683,13 @@ public sealed class BSPrim : BSPhysObject
return;
_orientation = value;
// A linkset might need to know if a component information changed.
Linkset.UpdateProperties(this, false);
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
{
ForceOrientation = _orientation;
// A linkset might need to know if a component information changed.
Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
});
}
}
@ -1686,7 +1688,7 @@ public sealed class BSPrim : BSPhysObject
*/
// The linkset implimentation might want to know about this.
Linkset.UpdateProperties(this, true);
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
}
}
}

View File

@ -846,8 +846,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
#endregion // Taints
#region INI and command line parameter processing
#region IPhysicsParameters
// Get the list of parameters this physics engine supports
public PhysParameterEntry[] GetParameterList()
@ -944,8 +942,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
#endregion IPhysicsParameters
#endregion Runtime settable parameters
// Invoke the detailed logger and output something if it's enabled.
public void DetailLog(string msg, params Object[] args)
{

View File

@ -1,25 +1,20 @@
CURRENT PRIORITIES
=================================================
Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040
Msg Kayaker on OSGrid when working
Child movement in linkset (don't rebuild linkset)
Vehicle angular vertical attraction
vehicle angular banking
Center-of-gravity
Vehicle angular deflection
Preferred orientation angular correction fix
when should angular and linear motor targets be zeroed? when selected?
Need a vehicle.clear()? Or an 'else' in prestep if not physical.
Teravus llMoveToTarget script debug
Mixing of hover, buoyancy/gravity, moveToTarget, into one force
Boats floating at proper level
Nebadon vehicles turning funny in arena
limitMotorUp calibration (more down?)
llRotLookAt
llLookAt
Vehicle angular vertical attraction
Vehicle angular deflection
Preferred orientation angular correction fix
vehicle angular banking
Avatars walking up stairs (HALF DONE)
Radius of the capsule affects ability to climb edges.
Vehicle movement on terrain smoothness
When is force introduced by SetForce removed? The prestep action could go forever.
Boats float low in the water (DONE)
Avatar movement
flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE)
walking up stairs is not calibrated correctly (stairs out of Kepler cabin)
@ -75,6 +70,7 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl
GENERAL TODO LIST:
=================================================
llMoveToTarget objects are not effected by gravity until target is removed.
Implement llSetPhysicalMaterial.
extend it with Center-of-mass, rolling friction, density
Implement llSetForceAndTorque.
@ -315,4 +311,12 @@ Remove HeightmapInfo from terrain specification (DONE)
Since C++ code does not need terrain height, this structure et al are not needed.
Surfboard go wonky when turning (DONE)
Angular motor direction is global coordinates rather than local coordinates?
(Resolution: made angular motor direction correct coordinate system)
(Resolution: made angular motor direction correct coordinate system)
Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 (DONE)
Msg Kayaker on OSGrid when working
(Resolution: LINEAR_DIRECTION is in vehicle coords. Test script does the
same in SL as in OS/BulletSim)
Boats float low in the water (DONE)
Boats floating at proper level (DONE)
When is force introduced by SetForce removed? The prestep action could go forever. (DONE)
(Resolution: setForce registers a prestep action which keeps applying the force)