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
parent
95c53ecae7
commit
471c477863
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue