BulletSim: add physChangeLinkSpring to change linkset link to be a spring constraint. Add implementation to create spring constraint. Send up property updates for linkset children at the end of flexible linkset links. The simulator probably doesn't do the right thing yet.

varregion
Robert Adams 2013-08-08 08:36:36 -07:00
parent dff0fb5690
commit 6aee08ac3c
5 changed files with 198 additions and 14 deletions

View File

@ -291,6 +291,10 @@ public class ExtendedPhysics : INonSharedRegionModule
return ret;
}
// physChangeLinkFixed(integer linkNum)
// Change the link between the root and the linkNum into a fixed, static physical connection.
// This needs to change 'linkNum' into the physical object because lower level code has
// no access to the link numbers.
[ScriptInvocation]
public int physChangeLinkFixed(UUID hostID, UUID scriptID, int linkNum)
{
@ -353,13 +357,76 @@ public class ExtendedPhysics : INonSharedRegionModule
[ScriptInvocation]
public int physChangeLinkHinge(UUID hostID, UUID scriptID, int linkNum)
{
return 0;
return -1;
}
[ScriptInvocation]
public int physChangeLinkSpring(UUID hostID, UUID scriptID, int linkNum)
public int physChangeLinkSpring(UUID hostID, UUID scriptID, int linkNum,
Vector3 frameInAloc, Quaternion frameInArot,
Vector3 frameInBloc, Quaternion frameInBrot,
Vector3 linearLimitLow, Vector3 linearLimitHigh,
Vector3 angularLimitLow, Vector3 angularLimitHigh
)
{
return 0;
int ret = -1;
if (!Enabled) return ret;
// The part that is requesting the change.
SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
if (requestingPart != null)
{
// The type is is always on the root of a linkset.
SceneObjectGroup containingGroup = requestingPart.ParentGroup;
SceneObjectPart rootPart = containingGroup.RootPart;
if (rootPart != null)
{
Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
if (rootPhysActor != null)
{
SceneObjectPart linkPart = containingGroup.GetLinkNumPart(linkNum);
if (linkPart != null)
{
Physics.Manager.PhysicsActor linkPhysActor = linkPart.PhysActor;
if (linkPhysActor != null)
{
ret = (int)rootPhysActor.Extension(PhysFunctChangeLinkSpring, linkNum, linkPhysActor,
frameInAloc, frameInArot,
frameInBloc, frameInBrot,
linearLimitLow, linearLimitHigh,
angularLimitLow, angularLimitHigh
);
}
else
{
m_log.WarnFormat("{0} physChangeLinkFixed: Link part has no physical actor. rootName={1}, hostID={2}, linknum={3}",
LogHeader, rootPart.Name, hostID, linkNum);
}
}
else
{
m_log.WarnFormat("{0} physChangeLinkFixed: Could not find linknum part. rootName={1}, hostID={2}, linknum={3}",
LogHeader, rootPart.Name, hostID, linkNum);
}
}
else
{
m_log.WarnFormat("{0} physChangeLinkFixed: Root part does not have a physics actor. rootName={1}, hostID={2}",
LogHeader, rootPart.Name, hostID);
}
}
else
{
m_log.WarnFormat("{0} physChangeLinkFixed: Root part does not exist. RequestingPartName={1}, hostID={2}",
LogHeader, requestingPart.Name, hostID);
}
}
else
{
m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
}
return ret;
}
[ScriptInvocation]

View File

@ -43,7 +43,9 @@ public enum ConstraintType : int
SLIDER_CONSTRAINT_TYPE,
CONTACT_CONSTRAINT_TYPE,
D6_SPRING_CONSTRAINT_TYPE,
MAX_CONSTRAINT_TYPE
MAX_CONSTRAINT_TYPE, // last type defined by Bullet
//
FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving
}
// ===============================================================================

View File

@ -79,6 +79,8 @@ public abstract class BSLinkset
}
public virtual void ResetLink() { }
public virtual void SetLinkParameters(BSConstraint constrain) { }
// Returns 'true' if physical property updates from the child should be reported to the simulator
public virtual bool ShouldUpdateChildProperties() { return false; }
}
public LinksetImplementation LinksetImpl { get; protected set; }
@ -224,6 +226,21 @@ public abstract class BSLinkset
return ret;
}
// Check the type of the link and return 'true' if the link is flexible and the
// updates from the child should be sent to the simulator so things change.
public virtual bool ShouldReportPropertyUpdates(BSPrimLinkable child)
{
bool ret = false;
BSLinkInfo linkInfo;
if (m_children.TryGetValue(child, out linkInfo))
{
ret = linkInfo.ShouldUpdateChildProperties();
}
return ret;
}
// Called after a simulation step to post a collision with this object.
// Return 'true' if linkset processed the collision. 'false' says the linkset didn't have
// anything to add for the collision and it should be passed through normal processing.
@ -432,6 +449,13 @@ public abstract class BSLinkset
return com;
}
#region Extension
public virtual object Extension(string pFunct, params object[] pParams)
{
return null;
}
#endregion // Extension
// Invoke the detailed logger and output something if it's enabled.
protected void DetailLog(string msg, params Object[] args)
{

View File

@ -60,8 +60,6 @@ public sealed class BSLinksetConstraints : BSLinkset
public float springDamping;
public float springStiffness;
public BSLinkInfoConstraint(BSPrimLinkable pMember)
: base(pMember)
{
@ -72,7 +70,8 @@ public sealed class BSLinksetConstraints : BSLinkset
// Set all the parameters for this constraint to a fixed, non-movable constraint.
public override void ResetLink()
{
constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
// constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
constraintType = ConstraintType.FIXED_CONSTRAINT_TYPE;
linearLimitLow = OMV.Vector3.Zero;
linearLimitHigh = OMV.Vector3.Zero;
angularLimitLow = OMV.Vector3.Zero;
@ -97,6 +96,7 @@ public sealed class BSLinksetConstraints : BSLinkset
{
switch (constraintType)
{
case ConstraintType.FIXED_CONSTRAINT_TYPE:
case ConstraintType.D6_CONSTRAINT_TYPE:
BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof;
if (constrain6dof != null)
@ -145,6 +145,20 @@ public sealed class BSLinksetConstraints : BSLinkset
break;
}
}
// Return 'true' if the property updates from the physics engine should be reported
// to the simulator.
// If the constraint is fixed, we don't need to report as the simulator and viewer will
// report the right things.
public override bool ShouldUpdateChildProperties()
{
bool ret = true;
if (constraintType == ConstraintType.FIXED_CONSTRAINT_TYPE)
ret = false;
return ret;
}
}
public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
@ -316,6 +330,7 @@ public sealed class BSLinksetConstraints : BSLinkset
switch (linkInfo.constraintType)
{
case ConstraintType.FIXED_CONSTRAINT_TYPE:
case ConstraintType.D6_CONSTRAINT_TYPE:
// Relative position normalized to the root prim
// Essentually a vector pointing from center of rootPrim to center of li.member
@ -466,5 +481,86 @@ public sealed class BSLinksetConstraints : BSLinkset
Rebuilding = false;
}
}
#region Extension
public override object Extension(string pFunct, params object[] pParams)
{
object ret = null;
switch (pFunct)
{
// pParams = (int linkNUm, PhysActor linkChild)
case BSScene.PhysFunctChangeLinkFixed:
if (pParams.Length > 1)
{
BSPrimLinkable child = pParams[1] as BSPrimLinkable;
if (child != null)
{
m_physicsScene.TaintedObject("BSLinksetConstraint.PhysFunctChangeLinkFixed", delegate()
{
// Pick up all the constraints currently created.
RemoveDependencies(child);
BSLinkInfo linkInfo = null;
if (m_children.TryGetValue(child, out linkInfo))
{
BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
if (linkInfoC != null)
{
// Setting to fixed is easy. The reset state is the fixed link configuration.
linkInfoC.ResetLink();
ret = (object)true;
}
}
// Cause the whole linkset to be rebuilt in post-taint time.
Refresh(child);
});
}
}
break;
case BSScene.PhysFunctChangeLinkSpring:
if (pParams.Length > 11)
{
BSPrimLinkable child = pParams[1] as BSPrimLinkable;
if (child != null)
{
m_physicsScene.TaintedObject("BSLinksetConstraint.PhysFunctChangeLinkFixed", delegate()
{
// Pick up all the constraints currently created.
RemoveDependencies(child);
BSLinkInfo linkInfo = null;
if (m_children.TryGetValue(child, out linkInfo))
{
BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
if (linkInfoC != null)
{
// Start with a reset link definition
linkInfoC.ResetLink();
linkInfoC.constraintType = ConstraintType.D6_SPRING_CONSTRAINT_TYPE;
linkInfoC.frameInAloc = (OMV.Vector3)pParams[2];
linkInfoC.frameInArot = (OMV.Quaternion)pParams[3];
linkInfoC.frameInBloc = (OMV.Vector3)pParams[4];
linkInfoC.frameInBrot = (OMV.Quaternion)pParams[5];
linkInfoC.linearLimitLow = (OMV.Vector3)pParams[6];
linkInfoC.linearLimitHigh = (OMV.Vector3)pParams[7];
linkInfoC.angularLimitLow = (OMV.Vector3)pParams[8];
linkInfoC.angularLimitHigh = (OMV.Vector3)pParams[9];
ret = (object)true;
}
}
// Cause the whole linkset to be rebuilt in post-taint time.
Refresh(child);
});
}
}
break;
default:
ret = base.Extension(pFunct, pParams);
break;
}
return ret;
}
#endregion // Extension
}
}

View File

@ -179,7 +179,7 @@ public class BSPrimLinkable : BSPrimDisplaced
// Do any filtering/modification needed for linksets.
public override void UpdateProperties(EntityProperties entprop)
{
if (Linkset.IsRoot(this))
if (Linkset.IsRoot(this) || Linkset.ShouldReportPropertyUpdates(this))
{
// Properties are only updated for the roots of a linkset.
// TODO: this will have to change when linksets are articulated.
@ -316,12 +316,7 @@ public class BSPrimLinkable : BSPrimDisplaced
// Params: int linkNum, PhysActor linkedPrim
case BSScene.PhysFunctChangeLinkFixed:
{
if (pParams.Length > 1)
{
int linkNum = (int)pParams[0];
Manager.PhysicsActor linkActor = (Manager.PhysicsActor)pParams[1];
Linkset.Refresh(this);
}
Linkset.Extension(pFunct, pParams);
break;
}
default: