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
parent
b40935837c
commit
291c7cdbcc
|
@ -66,6 +66,7 @@ public class ExtendedPhysics : INonSharedRegionModule
|
|||
public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType";
|
||||
public const string PhysFunctGetLinkType = "BulletSim.GetLinkType";
|
||||
public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams";
|
||||
public const string PhysFunctAxisLockLimits = "BulletSim.AxisLockLimits";
|
||||
|
||||
// =============================================================
|
||||
|
||||
|
@ -176,6 +177,71 @@ public class ExtendedPhysics : INonSharedRegionModule
|
|||
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]
|
||||
public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0;
|
||||
[ScriptConstant]
|
||||
|
@ -187,7 +253,6 @@ public class ExtendedPhysics : INonSharedRegionModule
|
|||
public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (!Enabled) return ret;
|
||||
|
||||
// The part that is requesting the change.
|
||||
|
@ -259,36 +324,13 @@ public class ExtendedPhysics : INonSharedRegionModule
|
|||
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)
|
||||
{
|
||||
PhysicsActor rootPhysActor = rootPart.PhysActor;
|
||||
if (rootPhysActor != null)
|
||||
PhysicsActor rootPhysActor;
|
||||
if (GetRootPhysActor(hostID, out rootPhysActor))
|
||||
{
|
||||
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
|
||||
{
|
||||
m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
|
||||
}
|
||||
|
|
|
@ -37,12 +37,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
public class BSActorLockAxis : BSActor
|
||||
{
|
||||
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)
|
||||
: base(physicsScene, pObj, actorName)
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
|
||||
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
|
||||
|
@ -55,6 +62,7 @@ public class BSActorLockAxis : BSActor
|
|||
// BSActor.Dispose()
|
||||
public override void Dispose()
|
||||
{
|
||||
m_physicsScene.BeforeStep -= PhysicsScene_BeforeStep;
|
||||
RemoveAxisLockConstraint();
|
||||
}
|
||||
|
||||
|
@ -63,10 +71,18 @@ public class BSActorLockAxis : BSActor
|
|||
// BSActor.Refresh()
|
||||
public override void Refresh()
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}",
|
||||
m_controllingPrim.LocalID, m_controllingPrim.LockedAngularAxis, Enabled, m_controllingPrim.IsPhysicallyActive);
|
||||
// Since the axis logging is done with a constraint, Refresh() time is good for
|
||||
// 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 (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree)
|
||||
if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree
|
||||
&& m_controllingPrim.LockedLinearAxis == m_controllingPrim.LockedAxisFree)
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
@ -74,12 +90,21 @@ public class BSActorLockAxis : BSActor
|
|||
// 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)
|
||||
{
|
||||
// The locking has changed. Remove the old constraint and build a new one
|
||||
RemoveAxisLockConstraint();
|
||||
}
|
||||
|
||||
AddAxisLockConstraint();
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveAxisLockConstraint();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// 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()
|
||||
public override void RemoveDependencies()
|
||||
{
|
||||
if (LockAxisConstraint != null)
|
||||
{
|
||||
// If a constraint is set up, remove it from the physical scene
|
||||
RemoveAxisLockConstraint();
|
||||
// Schedule a call before the next simulation step to restore the constraint.
|
||||
m_physicsScene.PostTaintObject("BSActorLockAxis:" + ActorName, m_controllingPrim.LocalID, delegate()
|
||||
// The pre-step action will restore the constraint of needed
|
||||
}
|
||||
|
||||
private void PhysicsScene_BeforeStep(float timestep)
|
||||
{
|
||||
Refresh();
|
||||
});
|
||||
// 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)
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// 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;
|
||||
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.
|
||||
|
||||
// Free to move linearly in the region
|
||||
// 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)
|
||||
if (!axisConstrainer.SetLinearLimits(m_controllingPrim.LockedLinearAxisLow, m_controllingPrim.LockedLinearAxisHigh))
|
||||
{
|
||||
linearLow.X = m_controllingPrim.RawPosition.X;
|
||||
linearHigh.X = m_controllingPrim.RawPosition.X;
|
||||
m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetLinearLimits",
|
||||
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
|
||||
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)
|
||||
if (!axisConstrainer.SetAngularLimits(m_controllingPrim.LockedAngularAxisLow, m_controllingPrim.LockedAngularAxisHigh))
|
||||
{
|
||||
angularLow.X = 0f;
|
||||
angularHigh.X = 0f;
|
||||
}
|
||||
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,failedSetAngularLimits",
|
||||
m_controllingPrim.LocalID);
|
||||
}
|
||||
|
||||
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.
|
||||
axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
|
||||
|
|
|
@ -201,7 +201,10 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
|
||||
{
|
||||
// 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
|
||||
// inserted into the compound shape. A rebuild of the linkset in a pre-step action will
|
||||
|
|
|
@ -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.
|
||||
public OMV.Vector3? UserSetCenterOfMassDisplacement { get; set; }
|
||||
|
||||
public OMV.Vector3 LockedLinearAxis { get; set; } // zero means locked. one means free.
|
||||
public OMV.Vector3 LockedAngularAxis { get; set; } // zero means locked. one means free.
|
||||
public OMV.Vector3 LockedLinearAxis; // zero means locked. one means free.
|
||||
public OMV.Vector3 LockedAngularAxis; // zero means locked. one means free.
|
||||
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
|
||||
|
||||
// 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
|
||||
// they need waking up when parameters are changed.
|
||||
// Called in taint-time!!
|
||||
|
|
|
@ -34,6 +34,7 @@ using OMV = OpenMetaverse;
|
|||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenSim.Region.Physics.ConvexDecompositionDotNet;
|
||||
using OpenSim.Region.OptionalModules.Scripting; // for ExtendedPhysics
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
|
@ -285,23 +286,21 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
|
||||
|
||||
// "1" means free, "0" means locked
|
||||
OMV.Vector3 locking = LockedAxisFree;
|
||||
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()
|
||||
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
|
||||
if (axis.X != 1)
|
||||
{
|
||||
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.LockAngularMotion", delegate()
|
||||
ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
|
||||
}
|
||||
if (axis.Y != 1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -533,6 +532,12 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
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);
|
||||
});
|
||||
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 {
|
||||
|
@ -1138,6 +1149,12 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
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);
|
||||
});
|
||||
|
||||
// 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;
|
||||
switch (pFunct)
|
||||
{
|
||||
case ExtendedPhysics.PhysFunctAxisLockLimits:
|
||||
ret = SetAxisLockLimitsExtension(pParams);
|
||||
break;
|
||||
default:
|
||||
ret = base.Extension(pFunct, pParams);
|
||||
break;
|
||||
}
|
||||
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
|
||||
|
||||
// The physics engine says that properties have updated. Update same and inform
|
||||
|
|
Loading…
Reference in New Issue