From 291c7cdbcc80dc270418a4959ccfa0ed8cc0c190 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 31 Dec 2014 12:43:26 -0800 Subject: [PATCH] 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. --- .../ExtendedPhysics/ExtendedPhysics.cs | 98 +++-- .../Physics/BulletSPlugin/BSActorLockAxis.cs | 121 ++++--- .../BulletSPlugin/BSLinksetCompound.cs | 5 +- .../Physics/BulletSPlugin/BSPhysObject.cs | 13 +- .../Region/Physics/BulletSPlugin/BSPrim.cs | 334 +++++++++++++++++- 5 files changed, 474 insertions(+), 97 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs index 9daf9d75ad..ff4afbf90e 100755 --- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs @@ -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,34 +324,11 @@ 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) + PhysicsActor rootPhysActor; + if (GetRootPhysActor(hostID, out rootPhysActor)) { - // 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) - { - 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); - } + object[] parms2 = { rootPhysActor, null }; + ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2)); } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs index 7e610075ee..48cab64b15 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs @@ -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) + 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 - RemoveAxisLockConstraint(); - // Schedule a call before the next simulation step to restore the constraint. - m_physicsScene.PostTaintObject("BSActorLockAxis:" + ActorName, m_controllingPrim.LocalID, delegate() + 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) { - 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; 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); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index b444446010..22b3f3f066 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -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 diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 2b744a0899..d20d094cab 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -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!! diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index c88a5c2a5e..9695fcff69 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -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