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.

0.7.6-extended
Robert Adams 2013-08-08 08:36:36 -07:00 committed by Justin Clark-Casey (justincc)
parent 05ff4379f0
commit 826f8ce791
5 changed files with 198 additions and 14 deletions

View File

@ -291,6 +291,10 @@ public class ExtendedPhysics : INonSharedRegionModule
return ret; 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] [ScriptInvocation]
public int physChangeLinkFixed(UUID hostID, UUID scriptID, int linkNum) public int physChangeLinkFixed(UUID hostID, UUID scriptID, int linkNum)
{ {
@ -353,13 +357,76 @@ public class ExtendedPhysics : INonSharedRegionModule
[ScriptInvocation] [ScriptInvocation]
public int physChangeLinkHinge(UUID hostID, UUID scriptID, int linkNum) public int physChangeLinkHinge(UUID hostID, UUID scriptID, int linkNum)
{ {
return 0; return -1;
} }
[ScriptInvocation] [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] [ScriptInvocation]

View File

@ -43,7 +43,9 @@ public enum ConstraintType : int
SLIDER_CONSTRAINT_TYPE, SLIDER_CONSTRAINT_TYPE,
CONTACT_CONSTRAINT_TYPE, CONTACT_CONSTRAINT_TYPE,
D6_SPRING_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 ResetLink() { }
public virtual void SetLinkParameters(BSConstraint constrain) { } 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; } public LinksetImplementation LinksetImpl { get; protected set; }
@ -224,6 +226,21 @@ public abstract class BSLinkset
return ret; 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. // 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 // 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. // anything to add for the collision and it should be passed through normal processing.
@ -432,6 +449,13 @@ public abstract class BSLinkset
return com; 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. // Invoke the detailed logger and output something if it's enabled.
protected void DetailLog(string msg, params Object[] args) protected void DetailLog(string msg, params Object[] args)
{ {

View File

@ -60,8 +60,6 @@ public sealed class BSLinksetConstraints : BSLinkset
public float springDamping; public float springDamping;
public float springStiffness; public float springStiffness;
public BSLinkInfoConstraint(BSPrimLinkable pMember) public BSLinkInfoConstraint(BSPrimLinkable pMember)
: base(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. // Set all the parameters for this constraint to a fixed, non-movable constraint.
public override void ResetLink() public override void ResetLink()
{ {
constraintType = ConstraintType.D6_CONSTRAINT_TYPE; // constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
constraintType = ConstraintType.FIXED_CONSTRAINT_TYPE;
linearLimitLow = OMV.Vector3.Zero; linearLimitLow = OMV.Vector3.Zero;
linearLimitHigh = OMV.Vector3.Zero; linearLimitHigh = OMV.Vector3.Zero;
angularLimitLow = OMV.Vector3.Zero; angularLimitLow = OMV.Vector3.Zero;
@ -97,6 +96,7 @@ public sealed class BSLinksetConstraints : BSLinkset
{ {
switch (constraintType) switch (constraintType)
{ {
case ConstraintType.FIXED_CONSTRAINT_TYPE:
case ConstraintType.D6_CONSTRAINT_TYPE: case ConstraintType.D6_CONSTRAINT_TYPE:
BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof;
if (constrain6dof != null) if (constrain6dof != null)
@ -145,6 +145,20 @@ public sealed class BSLinksetConstraints : BSLinkset
break; 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) public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
@ -316,6 +330,7 @@ public sealed class BSLinksetConstraints : BSLinkset
switch (linkInfo.constraintType) switch (linkInfo.constraintType)
{ {
case ConstraintType.FIXED_CONSTRAINT_TYPE:
case ConstraintType.D6_CONSTRAINT_TYPE: case ConstraintType.D6_CONSTRAINT_TYPE:
// Relative position normalized to the root prim // Relative position normalized to the root prim
// Essentually a vector pointing from center of rootPrim to center of li.member // Essentually a vector pointing from center of rootPrim to center of li.member
@ -466,5 +481,86 @@ public sealed class BSLinksetConstraints : BSLinkset
Rebuilding = false; 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. // Do any filtering/modification needed for linksets.
public override void UpdateProperties(EntityProperties entprop) 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. // Properties are only updated for the roots of a linkset.
// TODO: this will have to change when linksets are articulated. // TODO: this will have to change when linksets are articulated.
@ -316,12 +316,7 @@ public class BSPrimLinkable : BSPrimDisplaced
// Params: int linkNum, PhysActor linkedPrim // Params: int linkNum, PhysActor linkedPrim
case BSScene.PhysFunctChangeLinkFixed: case BSScene.PhysFunctChangeLinkFixed:
{ {
if (pParams.Length > 1) Linkset.Extension(pFunct, pParams);
{
int linkNum = (int)pParams[0];
Manager.PhysicsActor linkActor = (Manager.PhysicsActor)pParams[1];
Linkset.Refresh(this);
}
break; break;
} }
default: default: