BulletSim: Add axis locking enabled through the ExtendedPhysics module.

Allows locking of prim/linkset relative moving in each of the linear
and angular axis. Limits on movement or rotation can be set.
sedebug
Robert Adams 2014-12-31 12:43:26 -08:00
parent b40935837c
commit 291c7cdbcc
5 changed files with 474 additions and 97 deletions

View File

@ -66,6 +66,7 @@ public class ExtendedPhysics : INonSharedRegionModule
public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType"; public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType";
public const string PhysFunctGetLinkType = "BulletSim.GetLinkType"; public const string PhysFunctGetLinkType = "BulletSim.GetLinkType";
public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams"; public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams";
public const string PhysFunctAxisLockLimits = "BulletSim.AxisLockLimits";
// ============================================================= // =============================================================
@ -176,6 +177,71 @@ public class ExtendedPhysics : INonSharedRegionModule
return ret; return ret;
} }
// Code for specifying params.
// The choice if 14700 is arbitrary and only serves to catch parameter code misuse.
[ScriptConstant]
public const int PHYS_AXIS_LOCK_LINEAR = 14700;
[ScriptConstant]
public const int PHYS_AXIS_LOCK_LINEAR_X = 14701;
[ScriptConstant]
public const int PHYS_AXIS_LIMIT_LINEAR_X = 14702;
[ScriptConstant]
public const int PHYS_AXIS_LOCK_LINEAR_Y = 14703;
[ScriptConstant]
public const int PHYS_AXIS_LIMIT_LINEAR_Y = 14704;
[ScriptConstant]
public const int PHYS_AXIS_LOCK_LINEAR_Z = 14705;
[ScriptConstant]
public const int PHYS_AXIS_LIMIT_LINEAR_Z = 14706;
[ScriptConstant]
public const int PHYS_AXIS_LOCK_ANGULAR = 14707;
[ScriptConstant]
public const int PHYS_AXIS_LOCK_ANGULAR_X = 14708;
[ScriptConstant]
public const int PHYS_AXIS_LIMIT_ANGULAR_X = 14709;
[ScriptConstant]
public const int PHYS_AXIS_LOCK_ANGULAR_Y = 14710;
[ScriptConstant]
public const int PHYS_AXIS_LIMIT_ANGULAR_Y = 14711;
[ScriptConstant]
public const int PHYS_AXIS_LOCK_ANGULAR_Z = 14712;
[ScriptConstant]
public const int PHYS_AXIS_LIMIT_ANGULAR_Z = 14713;
[ScriptConstant]
public const int PHYS_AXIS_UNLOCK_LINEAR = 14714;
[ScriptConstant]
public const int PHYS_AXIS_UNLOCK_LINEAR_X = 14715;
[ScriptConstant]
public const int PHYS_AXIS_UNLOCK_LINEAR_Y = 14716;
[ScriptConstant]
public const int PHYS_AXIS_UNLOCK_LINEAR_Z = 14717;
[ScriptConstant]
public const int PHYS_AXIS_UNLOCK_ANGULAR = 14718;
[ScriptConstant]
public const int PHYS_AXIS_UNLOCK_ANGULAR_X = 14719;
[ScriptConstant]
public const int PHYS_AXIS_UNLOCK_ANGULAR_Y = 14720;
[ScriptConstant]
public const int PHYS_AXIS_UNLOCK_ANGULAR_Z = 14721;
[ScriptConstant]
public const int PHYS_AXIS_UNLOCK = 14722;
// physAxisLockLimits()
[ScriptInvocation]
public int physAxisLock(UUID hostID, UUID scriptID, object[] parms)
{
int ret = -1;
if (!Enabled) return ret;
PhysicsActor rootPhysActor;
if (GetRootPhysActor(hostID, out rootPhysActor))
{
object[] parms2 = AddToBeginningOfArray(rootPhysActor, null, parms);
ret = MakeIntError(rootPhysActor.Extension(PhysFunctAxisLockLimits, parms2));
}
return ret;
}
[ScriptConstant] [ScriptConstant]
public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0; public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0;
[ScriptConstant] [ScriptConstant]
@ -187,7 +253,6 @@ public class ExtendedPhysics : INonSharedRegionModule
public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
{ {
int ret = -1; int ret = -1;
if (!Enabled) return ret; if (!Enabled) return ret;
// The part that is requesting the change. // The part that is requesting the change.
@ -259,34 +324,11 @@ public class ExtendedPhysics : INonSharedRegionModule
int ret = -1; int ret = -1;
if (!Enabled) return ret; if (!Enabled) return ret;
// The part that is requesting the change. PhysicsActor rootPhysActor;
SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); if (GetRootPhysActor(hostID, out rootPhysActor))
if (requestingPart != null)
{ {
// The type is is always on the root of a linkset. object[] parms2 = { rootPhysActor, null };
SceneObjectGroup containingGroup = requestingPart.ParentGroup; ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2));
SceneObjectPart rootPart = containingGroup.RootPart;
if (rootPart != null)
{
PhysicsActor rootPhysActor = rootPart.PhysActor;
if (rootPhysActor != null)
{
object[] parms2 = { rootPhysActor, null };
ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2));
}
else
{
m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
LogHeader, rootPart.Name, hostID);
}
}
else
{
m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
LogHeader, requestingPart.Name, hostID);
}
} }
else else
{ {

View File

@ -37,12 +37,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin
public class BSActorLockAxis : BSActor public class BSActorLockAxis : BSActor
{ {
BSConstraint LockAxisConstraint = null; BSConstraint LockAxisConstraint = null;
// The lock access flags (which axises were locked) when the contraint was built.
// Used to see if locking has changed since when the constraint was built.
OMV.Vector3 LockAxisLinearFlags;
OMV.Vector3 LockAxisAngularFlags;
public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName) public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
: base(physicsScene, pObj, actorName) : base(physicsScene, pObj, actorName)
{ {
m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID); m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
LockAxisConstraint = null; LockAxisConstraint = null;
// we place our constraint just before the simulation step to make sure the linkset is complete
m_physicsScene.BeforeStep += PhysicsScene_BeforeStep;
} }
// BSActor.isActive // BSActor.isActive
@ -55,6 +62,7 @@ public class BSActorLockAxis : BSActor
// BSActor.Dispose() // BSActor.Dispose()
public override void Dispose() public override void Dispose()
{ {
m_physicsScene.BeforeStep -= PhysicsScene_BeforeStep;
RemoveAxisLockConstraint(); RemoveAxisLockConstraint();
} }
@ -63,10 +71,18 @@ public class BSActorLockAxis : BSActor
// BSActor.Refresh() // BSActor.Refresh()
public override void Refresh() public override void Refresh()
{ {
m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}", // Since the axis logging is done with a constraint, Refresh() time is good for
m_controllingPrim.LocalID, m_controllingPrim.LockedAngularAxis, Enabled, m_controllingPrim.IsPhysicallyActive); // changing parameters but this needs to wait until the prim/linkset is physically
// constructed. Therefore, the constraint itself is placed at pre-step time.
/*
m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedLinear={1},lockedAngular={2},enabled={3},pActive={4}",
m_controllingPrim.LocalID,
m_controllingPrim.LockedLinearAxis,
m_controllingPrim.LockedAngularAxis,
Enabled, m_controllingPrim.IsPhysicallyActive);
// If all the axis are free, we don't need to exist // If all the axis are free, we don't need to exist
if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree) if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree
&& m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree)
{ {
Enabled = false; Enabled = false;
} }
@ -74,12 +90,21 @@ public class BSActorLockAxis : BSActor
// If the object is physically active, add the axis locking constraint // If the object is physically active, add the axis locking constraint
if (isActive) if (isActive)
{ {
// Check to see if the locking parameters have changed
if (m_controllingPrim.LockedLinearAxis != this.LockAxisLinearFlags
|| m_controllingPrim.LockedAngularAxis != this.LockAxisAngularFlags)
{
// The locking has changed. Remove the old constraint and build a new one
RemoveAxisLockConstraint();
}
AddAxisLockConstraint(); AddAxisLockConstraint();
} }
else else
{ {
RemoveAxisLockConstraint(); RemoveAxisLockConstraint();
} }
*/
} }
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...). // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
@ -88,15 +113,35 @@ public class BSActorLockAxis : BSActor
// BSActor.RemoveDependencies() // BSActor.RemoveDependencies()
public override void RemoveDependencies() public override void RemoveDependencies()
{ {
if (LockAxisConstraint != null) RemoveAxisLockConstraint();
// The pre-step action will restore the constraint of needed
}
private void PhysicsScene_BeforeStep(float timestep)
{
// If all the axis are free, we don't need to exist
if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree
&& m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree)
{ {
// If a constraint is set up, remove it from the physical scene Enabled = false;
RemoveAxisLockConstraint(); }
// Schedule a call before the next simulation step to restore the constraint.
m_physicsScene.PostTaintObject("BSActorLockAxis:" + ActorName, m_controllingPrim.LocalID, delegate() // If the object is physically active, add the axis locking constraint
if (isActive)
{
// Check to see if the locking parameters have changed
if (m_controllingPrim.LockedLinearAxis != this.LockAxisLinearFlags
|| m_controllingPrim.LockedAngularAxis != this.LockAxisAngularFlags)
{ {
Refresh(); // The locking has changed. Remove the old constraint and build a new one
}); RemoveAxisLockConstraint();
}
AddAxisLockConstraint();
}
else
{
RemoveAxisLockConstraint();
} }
} }
@ -118,56 +163,30 @@ public class BSActorLockAxis : BSActor
LockAxisConstraint = axisConstrainer; LockAxisConstraint = axisConstrainer;
m_physicsScene.Constraints.AddConstraint(LockAxisConstraint); m_physicsScene.Constraints.AddConstraint(LockAxisConstraint);
// Remember the clocking being inforced so we can notice if they have changed
LockAxisLinearFlags = m_controllingPrim.LockedLinearAxis;
LockAxisAngularFlags = m_controllingPrim.LockedAngularAxis;
// The constraint is tied to the world and oriented to the prim. // The constraint is tied to the world and oriented to the prim.
// Free to move linearly in the region if (!axisConstrainer.SetLinearLimits(m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh))
// OMV.Vector3 linearLow = OMV.Vector3.Zero;
// OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize;
OMV.Vector3 linearLow = new OMV.Vector3(-10000f, -10000f, -10000f);
OMV.Vector3 linearHigh = new OMV.Vector3(10000f, 10000f, 10000f);
if (m_controllingPrim.LockedLinearAxis.X != BSPhysObject.FreeAxis)
{ {
linearLow.X = m_controllingPrim.RawPosition.X; m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetLinearLimits",
linearHigh.X = m_controllingPrim.RawPosition.X; m_controllingPrim.LocalID);
} }
if (m_controllingPrim.LockedLinearAxis.Y != BSPhysObject.FreeAxis)
{
linearLow.Y = m_controllingPrim.RawPosition.Y;
linearHigh.Y = m_controllingPrim.RawPosition.Y;
}
if (m_controllingPrim.LockedLinearAxis.Z != BSPhysObject.FreeAxis)
{
linearLow.Z = m_controllingPrim.RawPosition.Z;
linearHigh.Z = m_controllingPrim.RawPosition.Z;
}
axisConstrainer.SetLinearLimits(linearLow, linearHigh);
// Angular with some axis locked if (!axisConstrainer.SetAngularLimits(m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh))
float fPI = (float)Math.PI;
OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI);
OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI);
if (m_controllingPrim.LockedAngularAxis.X != BSPhysObject.FreeAxis)
{ {
angularLow.X = 0f; m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits",
angularHigh.X = 0f; m_controllingPrim.LocalID);
}
if (m_controllingPrim.LockedAngularAxis.Y != BSPhysObject.FreeAxis)
{
angularLow.Y = 0f;
angularHigh.Y = 0f;
}
if (m_controllingPrim.LockedAngularAxis.Z != BSPhysObject.FreeAxis)
{
angularLow.Z = 0f;
angularHigh.Z = 0f;
}
if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh))
{
m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID);
} }
m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}", m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}",
m_controllingPrim.LocalID, linearLow, linearHigh, angularLow, angularHigh); m_controllingPrim.LocalID,
m_controllingPrim.LockedLinearAxisLow,
m_controllingPrim.LockedLinearAxisHigh,
m_controllingPrim.LockedAngularAxisLow,
m_controllingPrim.LockedAngularAxisHigh);
// Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);

View File

@ -201,7 +201,10 @@ public sealed class BSLinksetCompound : BSLinkset
if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
{ {
// Find the physical instance of the child // Find the physical instance of the child
if (LinksetRoot.PhysShape.HasPhysicalShape && m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo)) if (!RebuildScheduled // if rebuilding, let the rebuild do it
&& !LinksetRoot.IsIncomplete // if waiting for assets or whatever, don't change
&& LinksetRoot.PhysShape.HasPhysicalShape // there must be a physical shape assigned
&& m_physicsScene.PE.IsCompound(LinksetRoot.PhysShape.physShapeInfo))
{ {
// It is possible that the linkset is still under construction and the child is not yet // It is possible that the linkset is still under construction and the child is not yet
// inserted into the compound shape. A rebuild of the linkset in a pre-step action will // inserted into the compound shape. A rebuild of the linkset in a pre-step action will

View File

@ -309,11 +309,20 @@ public abstract class BSPhysObject : PhysicsActor
// Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass. // Note this is a displacement from the root's coordinates. Zero means use the root prim as center-of-mass.
public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; } public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; }
public OMV.Vector3 LockedLinearAxis { get; set; } // zero means locked. one means free. public OMV.Vector3 LockedLinearAxis; // zero means locked. one means free.
public OMV.Vector3 LockedAngularAxis { get; set; } // zero means locked. one means free. public OMV.Vector3 LockedAngularAxis; // zero means locked. one means free.
public const float FreeAxis = 1f; public const float FreeAxis = 1f;
public const float LockedAxis = 0f;
public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free
// If an axis is locked (flagged above) then the limits of that axis are specified here.
// Linear axis limits are relative to the object's starting coordinates.
// Angular limits are limited to -PI to +PI
public OMV.Vector3 LockedLinearAxisLow;
public OMV.Vector3 LockedLinearAxisHigh;
public OMV.Vector3 LockedAngularAxisLow;
public OMV.Vector3 LockedAngularAxisHigh;
// Enable physical actions. Bullet will keep sleeping non-moving physical objects so // Enable physical actions. Bullet will keep sleeping non-moving physical objects so
// they need waking up when parameters are changed. // they need waking up when parameters are changed.
// Called in taint-time!! // Called in taint-time!!

View File

@ -34,6 +34,7 @@ using OMV = OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.Manager;
using OpenSim.Region.Physics.ConvexDecompositionDotNet; using OpenSim.Region.Physics.ConvexDecompositionDotNet;
using OpenSim.Region.OptionalModules.Scripting; // for ExtendedPhysics
namespace OpenSim.Region.Physics.BulletSPlugin namespace OpenSim.Region.Physics.BulletSPlugin
{ {
@ -285,23 +286,21 @@ public class BSPrim : BSPhysObject
{ {
DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
// "1" means free, "0" means locked ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
OMV.Vector3 locking = LockedAxisFree; if (axis.X != 1)
if (axis.X != 1) locking.X = 0f;
if (axis.Y != 1) locking.Y = 0f;
if (axis.Z != 1) locking.Z = 0f;
LockedAngularAxis = locking;
EnableActor(LockedAngularAxis != LockedAxisFree, LockedAxisActorName, delegate()
{ {
return new BSActorLockAxis(PhysScene, this, LockedAxisActorName); ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
}); }
if (axis.Y != 1)
// Update parameters so the new actor's Refresh() action is called at the right time.
PhysScene.TaintedObject(LocalID, "BSPrim.LockAngularMotion", delegate()
{ {
UpdatePhysicalParameters(); ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f);
}); }
if (axis.Z != 1)
{
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f);
}
InitializeAxisActor();
return; return;
} }
@ -533,6 +532,12 @@ public class BSPrim : BSPhysObject
{ {
return new BSActorSetForce(PhysScene, this, SetForceActorName); return new BSActorSetForce(PhysScene, this, SetForceActorName);
}); });
// Call update so actor Refresh() is called to start things off
PhysScene.TaintedObject(LocalID, "BSPrim.setForce", delegate()
{
UpdatePhysicalParameters();
});
} }
} }
@ -766,6 +771,12 @@ public class BSPrim : BSPhysObject
return new BSActorSetTorque(PhysScene, this, SetTorqueActorName); return new BSActorSetTorque(PhysScene, this, SetTorqueActorName);
}); });
DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque); DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque);
// Call update so actor Refresh() is called to start things off
PhysScene.TaintedObject(LocalID, "BSPrim.setTorque", delegate()
{
UpdatePhysicalParameters();
});
} }
} }
public override OMV.Vector3 Acceleration { public override OMV.Vector3 Acceleration {
@ -1138,6 +1149,12 @@ public class BSPrim : BSPhysObject
{ {
return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName); return new BSActorMoveToTarget(PhysScene, this, MoveToTargetActorName);
}); });
// Call update so actor Refresh() is called to start things off
PhysScene.TaintedObject(LocalID, "BSPrim.PIDActive", delegate()
{
UpdatePhysicalParameters();
});
} }
} }
@ -1164,6 +1181,12 @@ public class BSPrim : BSPhysObject
{ {
return new BSActorHover(PhysScene, this, HoverActorName); return new BSActorHover(PhysScene, this, HoverActorName);
}); });
// Call update so actor Refresh() is called to start things off
PhysScene.TaintedObject(LocalID, "BSPrim.PIDHoverActive", delegate()
{
UpdatePhysicalParameters();
});
} }
} }
@ -1601,12 +1624,293 @@ public class BSPrim : BSPhysObject
object ret = null; object ret = null;
switch (pFunct) switch (pFunct)
{ {
case ExtendedPhysics.PhysFunctAxisLockLimits:
ret = SetAxisLockLimitsExtension(pParams);
break;
default: default:
ret = base.Extension(pFunct, pParams); ret = base.Extension(pFunct, pParams);
break; break;
} }
return ret; return ret;
} }
private void InitializeAxisActor()
{
EnableActor(LockedAngularAxis != LockedAxisFree || LockedLinearAxis != LockedAxisFree,
LockedAxisActorName, delegate()
{
return new BSActorLockAxis(PhysScene, this, LockedAxisActorName);
});
// Update parameters so the new actor's Refresh() action is called at the right time.
PhysScene.TaintedObject(LocalID, "BSPrim.LockAxis", delegate()
{
UpdatePhysicalParameters();
});
}
// Passed an array of an array of parameters, set the axis locking.
// This expects an int (PHYS_AXIS_*) followed by none or two limit floats
// followed by another int and floats, etc.
private object SetAxisLockLimitsExtension(object[] pParams)
{
DetailLog("{0} SetAxisLockLimitsExtension. parmlen={1}", LocalID, pParams.GetLength(0));
object ret = null;
try
{
if (pParams.GetLength(0) > 1)
{
int index = 2;
while (index < pParams.GetLength(0))
{
var funct = pParams[index];
DetailLog("{0} SetAxisLockLimitsExtension. op={1}, index={2}", LocalID, funct, index);
if (funct is Int32 || funct is Int64)
{
switch ((int)funct)
{
case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X, (float)pParams[index + 1], (float)pParams[index + 2]);
index += 3;
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y, (float)pParams[index + 1], (float)pParams[index + 2]);
index += 3;
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z, (float)pParams[index + 1], (float)pParams[index + 2]);
index += 3;
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X, (float)pParams[index + 1], (float)pParams[index + 2]);
index += 3;
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y, (float)pParams[index + 1], (float)pParams[index + 2]);
index += 3;
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z, (float)pParams[index + 1], (float)pParams[index + 2]);
index += 3;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z, 0f, 0f);
index += 1;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK, 0f, 0f);
index += 1;
break;
default:
m_log.WarnFormat("{0} SetSxisLockLimitsExtension. Unknown op={1}", LogHeader, funct);
index += 1;
break;
}
}
}
InitializeAxisActor();
ret = (object)index;
}
}
catch (Exception e)
{
m_log.WarnFormat("{0} SetSxisLockLimitsExtension exception in object {1}: {2}", LogHeader, this.Name, e);
ret = null;
}
return ret; // not implemented yet
}
// Set the locking parameters.
// If an axis is locked, the limits for the axis are set to zero,
// If the axis is being constrained, the high and low value are passed and set.
// When done here, LockedXXXAxis flags are set and LockedXXXAxixLow/High are set to the range.
protected void ApplyAxisLimits(int funct, float low, float high)
{
DetailLog("{0} ApplyAxisLimits. op={1}, low={2}, high={3}", LocalID, funct, low, high);
float linearMax = 23000f;
float angularMax = (float)Math.PI;
switch ((int)funct)
{
case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR:
this.LockedLinearAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis);
this.LockedLinearAxisLow = OMV.Vector3.Zero;
this.LockedLinearAxisHigh = OMV.Vector3.Zero;
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X:
this.LockedLinearAxis.X = LockedAxis;
this.LockedLinearAxisLow.X = 0f;
this.LockedLinearAxisHigh.X = 0f;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X:
this.LockedLinearAxis.X = LockedAxis;
this.LockedLinearAxisLow.X = Util.Clip(low, -linearMax, linearMax);
this.LockedLinearAxisHigh.X = Util.Clip(high, -linearMax, linearMax);
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y:
this.LockedLinearAxis.Y = LockedAxis;
this.LockedLinearAxisLow.Y = 0f;
this.LockedLinearAxisHigh.Y = 0f;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y:
this.LockedLinearAxis.Y = LockedAxis;
this.LockedLinearAxisLow.Y = Util.Clip(low, -linearMax, linearMax);
this.LockedLinearAxisHigh.Y = Util.Clip(high, -linearMax, linearMax);
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z:
this.LockedLinearAxis.Z = LockedAxis;
this.LockedLinearAxisLow.Z = 0f;
this.LockedLinearAxisHigh.Z = 0f;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z:
this.LockedLinearAxis.Z = LockedAxis;
this.LockedLinearAxisLow.Z = Util.Clip(low, -linearMax, linearMax);
this.LockedLinearAxisHigh.Z = Util.Clip(high, -linearMax, linearMax);
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR:
this.LockedAngularAxis = new OMV.Vector3(LockedAxis, LockedAxis, LockedAxis);
this.LockedAngularAxisLow = OMV.Vector3.Zero;
this.LockedAngularAxisHigh = OMV.Vector3.Zero;
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X:
this.LockedAngularAxis.X = LockedAxis;
this.LockedAngularAxisLow.X = 0;
this.LockedAngularAxisHigh.X = 0;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X:
this.LockedAngularAxis.X = LockedAxis;
this.LockedAngularAxisLow.X = Util.Clip(low, -angularMax, angularMax);
this.LockedAngularAxisHigh.X = Util.Clip(high, -angularMax, angularMax);
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y:
this.LockedAngularAxis.Y = LockedAxis;
this.LockedAngularAxisLow.Y = 0;
this.LockedAngularAxisHigh.Y = 0;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y:
this.LockedAngularAxis.Y = LockedAxis;
this.LockedAngularAxisLow.Y = Util.Clip(low, -angularMax, angularMax);
this.LockedAngularAxisHigh.Y = Util.Clip(high, -angularMax, angularMax);
break;
case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z:
this.LockedAngularAxis.Z = LockedAxis;
this.LockedAngularAxisLow.Z = 0;
this.LockedAngularAxisHigh.Z = 0;
break;
case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z:
this.LockedAngularAxis.Z = LockedAxis;
this.LockedAngularAxisLow.Z = Util.Clip(low, -angularMax, angularMax);
this.LockedAngularAxisHigh.Z = Util.Clip(high, -angularMax, angularMax);
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR:
this.LockedLinearAxis = LockedAxisFree;
this.LockedLinearAxisLow = new OMV.Vector3(-linearMax, -linearMax, -linearMax);
this.LockedLinearAxisHigh = new OMV.Vector3(linearMax, linearMax, linearMax);
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X:
this.LockedLinearAxis.X = FreeAxis;
this.LockedLinearAxisLow.X = -linearMax;
this.LockedLinearAxisHigh.X = linearMax;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y:
this.LockedLinearAxis.Y = FreeAxis;
this.LockedLinearAxisLow.Y = -linearMax;
this.LockedLinearAxisHigh.Y = linearMax;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z:
this.LockedLinearAxis.Z = FreeAxis;
this.LockedLinearAxisLow.Z = -linearMax;
this.LockedLinearAxisHigh.Z = linearMax;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR:
this.LockedAngularAxis = LockedAxisFree;
this.LockedAngularAxisLow = new OMV.Vector3(-angularMax, -angularMax, -angularMax);
this.LockedAngularAxisHigh = new OMV.Vector3(angularMax, angularMax, angularMax);
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X:
this.LockedAngularAxis.X = FreeAxis;
this.LockedAngularAxisLow.X = -angularMax;
this.LockedAngularAxisHigh.X = angularMax;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y:
this.LockedAngularAxis.Y = FreeAxis;
this.LockedAngularAxisLow.Y = -angularMax;
this.LockedAngularAxisHigh.Y = angularMax;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z:
this.LockedAngularAxis.Z = FreeAxis;
this.LockedAngularAxisLow.Z = -angularMax;
this.LockedAngularAxisHigh.Z = angularMax;
break;
case ExtendedPhysics.PHYS_AXIS_UNLOCK:
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR, 0f, 0f);
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
break;
default:
break;
}
return;
}
#endregion // Extension #endregion // Extension
// The physics engine says that properties have updated. Update same and inform // The physics engine says that properties have updated. Update same and inform