From cafbf1c977efdcd595076765fe10dda2ea827077 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 23 May 2023 16:41:22 +0000 Subject: [PATCH] Add physDisableDeactivation() LSL function to ExtendedPhysics. Add implementation of physDisableDeactivation to BulletSim. --- .../PhysicsModules/BulletS/BSPhysObject.cs | 5 + .../Region/PhysicsModules/BulletS/BSPrim.cs | 158 +++++++++++------- .../PhysicsModules/BulletS/ExtendedPhysics.cs | 25 +++ 3 files changed, 131 insertions(+), 57 deletions(-) diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs index ff0570be98..fbc853a071 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs @@ -114,6 +114,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS // All axis free. LockedLinearAxis = LockedAxisFree; LockedAngularAxis = LockedAxisFree; + + DisableDeactivation = false; // by default, objects can be deactivated (ie, not checked for collisions) } // Tell the object to clean up. @@ -371,6 +373,9 @@ namespace OpenSim.Region.PhysicsModule.BulletS // 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; } + // Set 'true' if physical object should never be deactivated + public bool DisableDeactivation; + 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; diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs index 2eb2ddcd23..8918a9e70b 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs @@ -1008,16 +1008,27 @@ namespace OpenSim.Region.PhysicsModule.BulletS // Various values for simulation limits PhysScene.PE.SetDamping(PhysBody, BSParam.LinearDamping, BSParam.AngularDamping); - PhysScene.PE.SetDeactivationTime(PhysBody, BSParam.DeactivationTime); + + // Whether to allow deactivation of this body when it is at rest. + if (this.DisableDeactivation) + { + // The user has asked that the physical object never be deactivated. + PhysScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION); + // DetailLog("{0},BSPrim.MakeDynamic,set ActivationState=DISABLE_DEACTIVATION", LocalID); + } + else + { + // Force activation of the object so Bullet will act on it. + // Must do the ForceActivationState() to overcome the DISABLE_SIMULATION from static objects. + PhysScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); + // DetailLog("{0},BSPrim.MakeDynamic,set ActivationState=ACTIVE_TAG", LocalID); + } + PhysScene.PE.SetSleepingThresholds(PhysBody, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold); PhysScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); // This collides like an object. PhysBody.collisionType = CollisionType.Dynamic; - - // Force activation of the object so Bullet will act on it. - // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. - PhysScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); } } @@ -1642,6 +1653,9 @@ namespace OpenSim.Region.PhysicsModule.BulletS case ExtendedPhysics.PhysFunctAxisLockLimits: ret = SetAxisLockLimitsExtension(pParams); break; + case ExtendedPhysics.PhysFunctDisableDeactivation: + ret = DisableDeactivationExtension(pParams); + break; default: ret = base.Extension(pFunct, pParams); break; @@ -1673,58 +1687,54 @@ namespace OpenSim.Region.PhysicsModule.BulletS object ret = null; try { - if (pParams.GetLength(0) > 1) + int index = 2; + while (index < pParams.GetLength(0)) { - int index = 2; - while (index < pParams.GetLength(0)) + var funct = PassedParam(pParams, index, 1); + DetailLog("{0} SetAxisLockLimitsExtension. op={1}, index={2}", LocalID, funct, index); + switch (funct) { - var funct = pParams[index]; - DetailLog("{0} SetAxisLockLimitsExtension. op={1}, index={2}", LocalID, funct, index); - if (funct is Int32 || funct is Int64) - { - switch ((int)funct) - { - // Those that take no parameters - case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR: - case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X: - case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y: - case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z: - case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR: - case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X: - case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y: - case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z: - case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR: - case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X: - case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y: - case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z: - case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR: - case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X: - case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y: - case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z: - case ExtendedPhysics.PHYS_AXIS_UNLOCK: - ApplyAxisLimits((int)funct, 0f, 0f); - index += 1; - break; - // Those that take two parameters (the limits) - case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X: - case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y: - case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z: - case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X: - case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y: - case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z: - ApplyAxisLimits((int)funct, (float)pParams[index + 1], (float)pParams[index + 2]); - index += 3; - break; - default: - m_log.WarnFormat("{0} SetSxisLockLimitsExtension. Unknown op={1}", LogHeader, funct); - index += 1; - break; - } - } + // Those that take no parameters + case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR: + case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_X: + case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Y: + case ExtendedPhysics.PHYS_AXIS_LOCK_LINEAR_Z: + case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR: + case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X: + case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y: + case ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z: + case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR: + case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_X: + case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Y: + case ExtendedPhysics.PHYS_AXIS_UNLOCK_LINEAR_Z: + case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR: + case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_X: + case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Y: + case ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR_Z: + case ExtendedPhysics.PHYS_AXIS_UNLOCK: + ApplyAxisLimits((int)funct, 0f, 0f); + index += 1; + break; + // Those that take two parameters (the limits) + case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_X: + case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Y: + case ExtendedPhysics.PHYS_AXIS_LIMIT_LINEAR_Z: + case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_X: + case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Y: + case ExtendedPhysics.PHYS_AXIS_LIMIT_ANGULAR_Z: + var low = PassedParam(pParams, index + 1, 0f); + var high = PassedParam(pParams, index + 2, 0f); + ApplyAxisLimits((int)funct, low, high); + index += 3; + break; + default: + m_log.WarnFormat("{0} SetSxisLockLimitsExtension. Unknown op={1}", LogHeader, funct); + index += 1; + break; } - InitializeAxisActor(); - ret = (object)index; } + InitializeAxisActor(); + ret = (object)index; } catch (Exception e) { @@ -1733,11 +1743,45 @@ namespace OpenSim.Region.PhysicsModule.BulletS } return ret; // not implemented yet } + private object DisableDeactivationExtension(object[] pParams) + { + object ret = null; + try + { + var disable = PassedParam(pParams, 2, 0); + DetailLog("{0} DisableDeactivationExtension. disable={1}", LocalID, disable); + this.DisableDeactivation = (disable != 0); + ret = (object)1; - // 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. + // Update parameters so the prim is rebuilt with the new settings + PhysScene.TaintedObject(LocalID, "BSPrim.DisableDeactivationExtension", () => { UpdatePhysicalParameters(); }); + } + catch (Exception e) + { + m_log.WarnFormat("{0} DisableDeactivationExtension exception in object {1}: {2}", LogHeader, this.Name, e); + ret = null; + } + return ret; // not implemented yet + } + + // Get the passed parameter if it exists and is of the right type. + // This returns the default value if the parameter is not present or is the wrong type. + private T PassedParam(object[] pParams, int index, T defaultValue) + { + if (pParams.GetLength(0) > index) + { + if (pParams[index] is T) + { + return (T)pParams[index]; + } + } + return defaultValue; + } + + // 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); diff --git a/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs b/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs index ab5d4849c5..8e382bdc8a 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs @@ -67,6 +67,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams"; public const string PhysFunctAxisLockLimits = "BulletSim.AxisLockLimits"; + public const string PhysFunctDisableDeactivation = "BulletSim.DisableDeactivation"; + // ============================================================= private IConfig Configuration { get; set; } @@ -138,6 +140,9 @@ namespace OpenSim.Region.PhysicsModule.BulletS } // Register as LSL functions all the [ScriptInvocation] marked methods. + // NOTE: YEngine keeps functions as region specific but constants are global static + // so if this is used in multiple regions on a simulator, the constants will + // show up as being redefined. Comms.RegisterScriptInvocations(this); Comms.RegisterConstants(this); @@ -176,6 +181,26 @@ namespace OpenSim.Region.PhysicsModule.BulletS return ret; } + [ScriptInvocation] + public float physDisableDeactivation(UUID hostId, UUID scriptId, int disable) + { + int ret = -1; + if (!Enabled) return ret; + + if (BaseScene.PhysicsScene != null) + { + if (GetRootPhysActor(hostId, out PhysicsActor rootPhysActor)) + { + m_log.DebugFormat("{0} physDisableDeactivation: hostId={1}, scriptId={2}, val={3}", LogHeader, hostId, scriptId, disable); + object[] parms2 = { rootPhysActor, null, disable }; + ret = MakeIntError(rootPhysActor.Extension(PhysFunctDisableDeactivation, parms2)); + } + } + + return ret; + + } + // Code for specifying params. // The choice if 14700 is arbitrary and only serves to catch parameter code misuse. [ScriptConstant]