From 90f03ccd42a045bb30f33ed866feb38677ed7780 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 6 May 2013 11:47:55 -0700 Subject: [PATCH 1/4] Added new method to Remote Admin for reloading the estate settings. This is meant to be called when some other program has changed the data on the backend. --- .../RemoteController/RemoteAdminPlugin.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 355f7b3078..ad683b8ff1 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -157,6 +157,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController availableMethods["admin_acl_add"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListAdd); availableMethods["admin_acl_remove"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListRemove); availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList); + availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload); // Either enable full remote functionality or just selected features string enabledMethods = m_config.GetString("enabled_methods", "all"); @@ -1762,6 +1763,22 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Access List List Request complete"); } + private void XmlRpcEstateReload(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Estate Reload Request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + m_application.SceneManager.ForEachScene(s => + s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false) + ); + + responseData["success"] = true; + + m_log.Info("[RADMIN]: Estate Reload Request complete"); + } + private void XmlRpcGetAgentsMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { Hashtable responseData = (Hashtable)response.Value; From f9fb1484aa00f8bfadead06ce71d004502fb564e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 3 May 2013 15:46:35 -0700 Subject: [PATCH 2/4] BulletSim: extend BSActorLockAxis to allow locking linear movement in addition to angular movement. Not enabled by anything yet. --- .../Physics/BulletSPlugin/BSActorLockAxis.cs | 25 +++++++++++++++---- .../Physics/BulletSPlugin/BSPhysObject.cs | 9 ++++--- .../Region/Physics/BulletSPlugin/BSPrim.cs | 4 +-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs index 7801d8e47f..8b0fdeb7f2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs @@ -64,9 +64,9 @@ public class BSActorLockAxis : BSActor public override void Refresh() { m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,lockedAxis={1},enabled={2},pActive={3}", - m_controllingPrim.LocalID, m_controllingPrim.LockedAxis, Enabled, m_controllingPrim.IsPhysicallyActive); + m_controllingPrim.LocalID, m_controllingPrim.LockedAngularAxis, Enabled, m_controllingPrim.IsPhysicallyActive); // If all the axis are free, we don't need to exist - if (m_controllingPrim.LockedAxis == m_controllingPrim.LockedAxisFree) + if (m_controllingPrim.LockedAngularAxis == m_controllingPrim.LockedAxisFree) { Enabled = false; } @@ -123,23 +123,38 @@ public class BSActorLockAxis : BSActor // Free to move linearly in the region OMV.Vector3 linearLow = OMV.Vector3.Zero; OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize; + if (m_controllingPrim.LockedLinearAxis.X != BSPhysObject.FreeAxis) + { + linearLow.X = m_controllingPrim.RawPosition.X; + linearHigh.X = m_controllingPrim.RawPosition.X; + } + 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.LockedAxis.X != 1f) + if (m_controllingPrim.LockedAngularAxis.X != BSPhysObject.FreeAxis) { angularLow.X = 0f; angularHigh.X = 0f; } - if (m_controllingPrim.LockedAxis.Y != 1f) + if (m_controllingPrim.LockedAngularAxis.Y != BSPhysObject.FreeAxis) { angularLow.Y = 0f; angularHigh.Y = 0f; } - if (m_controllingPrim.LockedAxis.Z != 1f) + if (m_controllingPrim.LockedAngularAxis.Z != BSPhysObject.FreeAxis) { angularLow.Z = 0f; angularHigh.Z = 0f; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index e796804df4..cca887afa0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -108,7 +108,8 @@ public abstract class BSPhysObject : PhysicsActor CollisionScore = 0; // All axis free. - LockedAxis = LockedAxisFree; + LockedLinearAxis = LockedAxisFree; + LockedAngularAxis = LockedAxisFree; } // Tell the object to clean up. @@ -265,8 +266,10 @@ 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 LockedAxis { get; set; } // zero means locked. one means free. - public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free + 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 const float FreeAxis = 1f; + public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(FreeAxis, FreeAxis, FreeAxis); // All axis are free // Enable physical actions. Bullet will keep sleeping non-moving physical objects so // they need waking up when parameters are changed. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index d3f34759d1..f5b03611dd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -256,9 +256,9 @@ public class BSPrim : BSPhysObject if (axis.X != 1) locking.X = 0f; if (axis.Y != 1) locking.Y = 0f; if (axis.Z != 1) locking.Z = 0f; - LockedAxis = locking; + LockedAngularAxis = locking; - EnableActor(LockedAxis != LockedAxisFree, LockedAxisActorName, delegate() + EnableActor(LockedAngularAxis != LockedAxisFree, LockedAxisActorName, delegate() { return new BSActorLockAxis(PhysScene, this, LockedAxisActorName); }); From bf318969836bf38dbd0325f24fa3d1bd12f34d77 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 3 May 2013 17:14:31 -0700 Subject: [PATCH 3/4] BulletSim: simplify parameter specification by reducing the number of specifications required for simple properties with defaults. --- .../Physics/BulletSPlugin/BSDynamics.cs | 2 +- .../Region/Physics/BulletSPlugin/BSParam.cs | 283 ++++++------------ 2 files changed, 94 insertions(+), 191 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index c5bee6d705..0dd2aa5d1a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin enableAngularVerticalAttraction = true; enableAngularDeflection = false; enableAngularBanking = true; - if (BSParam.VehicleDebuggingEnabled) + if (BSParam.VehicleDebuggingEnable) { enableAngularVerticalAttraction = true; enableAngularDeflection = false; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 2ac68e3e43..3ca7e160ce 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -26,6 +26,7 @@ */ using System; using System.Collections.Generic; +using System.Reflection; using System.Text; using OpenSim.Region.Physics.Manager; @@ -144,7 +145,7 @@ public static class BSParam public static Vector3 VehicleAngularFactor { get; private set; } public static float VehicleGroundGravityFudge { get; private set; } public static float VehicleAngularBankingTimescaleFudge { get; private set; } - public static bool VehicleDebuggingEnabled { get; private set; } + public static bool VehicleDebuggingEnable { get; private set; } // Convex Hulls public static int CSHullMaxDepthSplit { get; private set; } @@ -236,17 +237,41 @@ public static class BSParam getter = pGetter; objectSet = pObjSetter; } - /* Wish I could simplify using this definition but CLR doesn't store references so closure around delegates of references won't work - * TODO: Maybe use reflection and the name of the variable to create a reference for the getter/setter. - public ParameterDefn(string pName, string pDesc, T pDefault, ref T loc) + // Simple parameter variable where property name is the same as the INI file name + // and the value is only a simple get and set. + public ParameterDefn(string pName, string pDesc, T pDefault) : base(pName, pDesc) { defaultValue = pDefault; - setter = (s, v) => { loc = v; }; - getter = (s) => { return loc; }; + setter = (s, v) => { SetValueByName(s, name, v); }; + getter = (s) => { return GetValueByName(s, name); }; objectSet = null; } - */ + // Use reflection to find the property named 'pName' in BSParam and assign 'val' to same. + private void SetValueByName(BSScene s, string pName, T val) + { + PropertyInfo prop = typeof(BSParam).GetProperty(pName, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); + if (prop == null) + { + // This should only be output when someone adds a new INI parameter and misspells the name. + s.Logger.ErrorFormat("{0} SetValueByName: did not find '{1}'. Verify specified property name is the same as the given INI parameters name.", LogHeader, pName); + } + else + { + prop.SetValue(null, val, null); + } + } + // Use reflection to find the property named 'pName' in BSParam and return the value in same. + private T GetValueByName(BSScene s, string pName) + { + PropertyInfo prop = typeof(BSParam).GetProperty(pName, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); + if (prop == null) + { + // This should only be output when someone adds a new INI parameter and misspells the name. + s.Logger.ErrorFormat("{0} GetValueByName: did not find '{1}'. Verify specified property name is the same as the given INI parameter name.", LogHeader, pName); + } + return (T)prop.GetValue(null, null); + } public override void AssignDefault(BSScene s) { setter(s, defaultValue); @@ -336,26 +361,16 @@ public static class BSParam (s) => { return ShouldUseHullsForPhysicalObjects; }, (s,v) => { ShouldUseHullsForPhysicalObjects = v; } ), new ParameterDefn("ShouldRemoveZeroWidthTriangles", "If true, remove degenerate triangles from meshes", - true, - (s) => { return ShouldRemoveZeroWidthTriangles; }, - (s,v) => { ShouldRemoveZeroWidthTriangles = v; } ), + true ), new ParameterDefn("ShouldUseBulletHACD", "If true, use the Bullet version of HACD", - false, - (s) => { return ShouldUseBulletHACD; }, - (s,v) => { ShouldUseBulletHACD = v; } ), + false ), new ParameterDefn("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", - true, - (s) => { return ShouldUseSingleConvexHullForPrims; }, - (s,v) => { ShouldUseSingleConvexHullForPrims = v; } ), + true ), new ParameterDefn("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", - 5, - (s) => { return CrossingFailuresBeforeOutOfBounds; }, - (s,v) => { CrossingFailuresBeforeOutOfBounds = v; } ), + 5 ), new ParameterDefn("UpdateVelocityChangeThreshold", "Change in updated velocity required before reporting change to simulator", - 0.1f, - (s) => { return UpdateVelocityChangeThreshold; }, - (s,v) => { UpdateVelocityChangeThreshold = v; } ), + 0.1f ), new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 32f, @@ -422,18 +437,12 @@ public static class BSParam (s,v) => { MaxAddForceMagnitude = v; MaxAddForceMagnitudeSquared = v * v; } ), // Density is passed around as 100kg/m3. This scales that to 1kg/m3. new ParameterDefn("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)", - 0.01f, - (s) => { return DensityScaleFactor; }, - (s,v) => { DensityScaleFactor = v; } ), + 0.01f ), new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", - 2200f, - (s) => { return (float)PID_D; }, - (s,v) => { PID_D = v; } ), + 2200f ), new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", - 900f, - (s) => { return (float)PID_P; }, - (s,v) => { PID_P = v; } ), + 900f ), new ParameterDefn("DefaultFriction", "Friction factor used on new objects", 0.2f, @@ -500,94 +509,50 @@ public static class BSParam (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ), new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", - (float)BSTerrainPhys.TerrainImplementation.Mesh, - (s) => { return TerrainImplementation; }, - (s,v) => { TerrainImplementation = v; } ), + (float)BSTerrainPhys.TerrainImplementation.Mesh ), new ParameterDefn("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , - 2, - (s) => { return TerrainMeshMagnification; }, - (s,v) => { TerrainMeshMagnification = v; } ), + 2 ), new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , - 0.3f, - (s) => { return TerrainFriction; }, - (s,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ), + 0.3f ), new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , - 0.8f, - (s) => { return TerrainHitFraction; }, - (s,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ), + 0.8f ), new ParameterDefn("TerrainRestitution", "Bouncyness" , - 0f, - (s) => { return TerrainRestitution; }, - (s,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), + 0f ), new ParameterDefn("TerrainContactProcessingThreshold", "Distance from terrain to stop processing collisions" , - 0.0f, - (s) => { return TerrainContactProcessingThreshold; }, - (s,v) => { TerrainContactProcessingThreshold = v; /* TODO: set on real terrain */ } ), + 0.0f ), new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , - 0.08f, - (s) => { return TerrainCollisionMargin; }, - (s,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), + 0.08f ), new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", - 0.2f, - (s) => { return AvatarFriction; }, - (s,v) => { AvatarFriction = v; } ), + 0.2f ), new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", - 0.95f, - (s) => { return AvatarStandingFriction; }, - (s,v) => { AvatarStandingFriction = v; } ), + 0.95f ), new ParameterDefn("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run", - 1.3f, - (s) => { return AvatarAlwaysRunFactor; }, - (s,v) => { AvatarAlwaysRunFactor = v; } ), + 1.3f ), new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", - 3.5f, - (s) => { return AvatarDensity; }, - (s,v) => { AvatarDensity = v; } ), + 3.5f) , new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", - 0f, - (s) => { return AvatarRestitution; }, - (s,v) => { AvatarRestitution = v; } ), + 0f ), new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", - 0.6f, - (s) => { return AvatarCapsuleWidth; }, - (s,v) => { AvatarCapsuleWidth = v; } ), + 0.6f ) , new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", - 0.45f, - (s) => { return AvatarCapsuleDepth; }, - (s,v) => { AvatarCapsuleDepth = v; } ), + 0.45f ), new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", - 1.5f, - (s) => { return AvatarCapsuleHeight; }, - (s,v) => { AvatarCapsuleHeight = v; } ), + 1.5f ), new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", - 0.1f, - (s) => { return AvatarContactProcessingThreshold; }, - (s,v) => { AvatarContactProcessingThreshold = v; } ), + 0.1f ), new ParameterDefn("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", - 1.0f, - (s) => { return AvatarBelowGroundUpCorrectionMeters; }, - (s,v) => { AvatarBelowGroundUpCorrectionMeters = v; } ), + 1.0f ), new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction", - 0.6f, - (s) => { return AvatarStepHeight; }, - (s,v) => { AvatarStepHeight = v; } ), + 0.6f ) , new ParameterDefn("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", - 0.6f, - (s) => { return AvatarStepApproachFactor; }, - (s,v) => { AvatarStepApproachFactor = v; } ), + 0.6f ), new ParameterDefn("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", - 1.0f, - (s) => { return AvatarStepForceFactor; }, - (s,v) => { AvatarStepForceFactor = v; } ), + 1.0f ), new ParameterDefn("AvatarStepUpCorrectionFactor", "Multiplied by height of step collision to create up movement at step", - 1.0f, - (s) => { return AvatarStepUpCorrectionFactor; }, - (s,v) => { AvatarStepUpCorrectionFactor = v; } ), + 1.0f ), new ParameterDefn("AvatarStepSmoothingSteps", "Number of frames after a step collision that we continue walking up stairs", - 2, - (s) => { return AvatarStepSmoothingSteps; }, - (s,v) => { AvatarStepSmoothingSteps = v; } ), + 2 ), new ParameterDefn("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", 1000.0f, @@ -598,37 +563,21 @@ public static class BSParam (s) => { return (float)VehicleMaxAngularVelocity; }, (s,v) => { VehicleMaxAngularVelocity = v; VehicleMaxAngularVelocitySq = v * v; } ), new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", - 0.0f, - (s) => { return VehicleAngularDamping; }, - (s,v) => { VehicleAngularDamping = v; } ), + 0.0f ), new ParameterDefn("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (<0,0,0> to <1,1,1>)", - new Vector3(1f, 1f, 1f), - (s) => { return VehicleLinearFactor; }, - (s,v) => { VehicleLinearFactor = v; } ), + new Vector3(1f, 1f, 1f) ), new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (<0,0,0> to <1,1,1>)", - new Vector3(1f, 1f, 1f), - (s) => { return VehicleAngularFactor; }, - (s,v) => { VehicleAngularFactor = v; } ), + new Vector3(1f, 1f, 1f) ), new ParameterDefn("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)", - 0.0f, - (s) => { return VehicleFriction; }, - (s,v) => { VehicleFriction = v; } ), + 0.0f ), new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", - 0.0f, - (s) => { return VehicleRestitution; }, - (s,v) => { VehicleRestitution = v; } ), + 0.0f ), new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiply gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", - 0.2f, - (s) => { return VehicleGroundGravityFudge; }, - (s,v) => { VehicleGroundGravityFudge = v; } ), + 0.2f ), new ParameterDefn("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.", - 60.0f, - (s) => { return VehicleAngularBankingTimescaleFudge; }, - (s,v) => { VehicleAngularBankingTimescaleFudge = v; } ), + 60.0f ), new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", - false, - (s) => { return VehicleDebuggingEnabled; }, - (s,v) => { VehicleDebuggingEnabled = v; } ), + false ), new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 0f, @@ -673,99 +622,53 @@ public static class BSParam (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), new ParameterDefn("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy", - 7, - (s) => { return CSHullMaxDepthSplit; }, - (s,v) => { CSHullMaxDepthSplit = v; } ), + 7 ), new ParameterDefn("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes", - 2, - (s) => { return CSHullMaxDepthSplitForSimpleShapes; }, - (s,v) => { CSHullMaxDepthSplitForSimpleShapes = v; } ), + 2 ), new ParameterDefn("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)", - 5f, - (s) => { return CSHullConcavityThresholdPercent; }, - (s,v) => { CSHullConcavityThresholdPercent = v; } ), + 5f ), new ParameterDefn("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)", - 5f, - (s) => { return CSHullVolumeConservationThresholdPercent; }, - (s,v) => { CSHullVolumeConservationThresholdPercent = v; } ), + 5f ), new ParameterDefn("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.", - 32, - (s) => { return CSHullMaxVertices; }, - (s,v) => { CSHullMaxVertices = v; } ), + 32 ), new ParameterDefn("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.", - 0f, - (s) => { return CSHullMaxSkinWidth; }, - (s,v) => { CSHullMaxSkinWidth = v; } ), + 0f ), new ParameterDefn("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull", - 100f, - (s) => { return BHullMaxVerticesPerHull; }, - (s,v) => { BHullMaxVerticesPerHull = v; } ), + 100f ), new ParameterDefn("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh", - 2f, - (s) => { return BHullMinClusters; }, - (s,v) => { BHullMinClusters = v; } ), + 2f ), new ParameterDefn("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls", - 2f, - (s) => { return BHullCompacityWeight; }, - (s,v) => { BHullCompacityWeight = v; } ), + 0.1f ), new ParameterDefn("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull", - 0.1f, - (s) => { return BHullVolumeWeight; }, - (s,v) => { BHullVolumeWeight = v; } ), + 0f ), new ParameterDefn("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be", - 100f, - (s) => { return BHullConcavity; }, - (s,v) => { BHullConcavity = v; } ), + 100f ), new ParameterDefn("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors", - false, - (s) => { return BHullAddExtraDistPoints; }, - (s,v) => { BHullAddExtraDistPoints = v; } ), + false ), new ParameterDefn("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls", - false, - (s) => { return BHullAddNeighboursDistPoints; }, - (s,v) => { BHullAddNeighboursDistPoints = v; } ), + false ), new ParameterDefn("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces", - false, - (s) => { return BHullAddFacesPoints; }, - (s,v) => { BHullAddFacesPoints = v; } ), + false ), new ParameterDefn("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin", - false, - (s) => { return BHullShouldAdjustCollisionMargin; }, - (s,v) => { BHullShouldAdjustCollisionMargin = v; } ), + false ), new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", - (float)BSLinkset.LinksetImplementation.Compound, - (s) => { return LinksetImplementation; }, - (s,v) => { LinksetImplementation = v; } ), + (float)BSLinkset.LinksetImplementation.Compound ), new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", - false, - (s) => { return LinkConstraintUseFrameOffset; }, - (s,v) => { LinkConstraintUseFrameOffset = v; } ), + false ), new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", - true, - (s) => { return LinkConstraintEnableTransMotor; }, - (s,v) => { LinkConstraintEnableTransMotor = v; } ), + true ), new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", - 5.0f, - (s) => { return LinkConstraintTransMotorMaxVel; }, - (s,v) => { LinkConstraintTransMotorMaxVel = v; } ), + 5.0f ), new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", - 0.1f, - (s) => { return LinkConstraintTransMotorMaxForce; }, - (s,v) => { LinkConstraintTransMotorMaxForce = v; } ), + 0.1f ), new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", - 0.1f, - (s) => { return LinkConstraintCFM; }, - (s,v) => { LinkConstraintCFM = v; } ), + 0.1f ), new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", - 0.1f, - (s) => { return LinkConstraintERP; }, - (s,v) => { LinkConstraintERP = v; } ), + 0.1f ), new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", - 40, - (s) => { return LinkConstraintSolverIterations; }, - (s,v) => { LinkConstraintSolverIterations = v; } ), + 40 ), new ParameterDefn("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)", 0, From 045aaa838ac0a6e129ff1d8ec65053508df1d51a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 6 May 2013 13:29:19 -0700 Subject: [PATCH 4/4] BulletSim: remove friction calcuation from BSMotor and move linear and angular friction computation into linear and angular movement code. The friction wasn't being applied properly. This will make it so vehicles don't drift as much and the drift is tunable by changing the friction timescales. --- .../BulletSPlugin/BSActorAvatarMove.cs | 1 - .../Physics/BulletSPlugin/BSActorHover.cs | 1 - .../BulletSPlugin/BSActorMoveToTarget.cs | 1 - .../Physics/BulletSPlugin/BSActorSetForce.cs | 2 +- .../Physics/BulletSPlugin/BSActorSetTorque.cs | 2 +- .../Physics/BulletSPlugin/BSDynamics.cs | 44 +++++++++---- .../Region/Physics/BulletSPlugin/BSMotors.cs | 63 +++++-------------- 7 files changed, 47 insertions(+), 67 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs index 4e067b5f53..ac8c30c9cd 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs @@ -118,7 +118,6 @@ public class BSActorAvatarMove : BSActor m_velocityMotor = new BSVMotor("BSCharacter.Velocity", 0.2f, // time scale BSMotor.Infinite, // decay time scale - BSMotor.InfiniteVector, // friction timescale 1f // efficiency ); // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs index 3630ca8e67..8a79809fa5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs @@ -102,7 +102,6 @@ public class BSActorHover : BSActor m_hoverMotor = new BSFMotor("BSActorHover", m_controllingPrim.HoverTau, // timeScale BSMotor.Infinite, // decay time scale - BSMotor.Infinite, // friction timescale 1f // efficiency ); m_hoverMotor.SetTarget(ComputeCurrentHoverHeight()); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs index 1b598fdfba..75ff24ed0b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs @@ -105,7 +105,6 @@ public class BSActorMoveToTarget : BSActor m_targetMotor = new BSVMotor("BSActorMoveToTargget.Activate", m_controllingPrim.MoveToTargetTau, // timeScale BSMotor.Infinite, // decay time scale - BSMotor.InfiniteVector, // friction timescale 1f // efficiency ); m_targetMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG so motor will output detail log messages. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs index c0f40fdd0a..96fa0b6ce9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs @@ -101,7 +101,7 @@ public class BSActorSetForce : BSActor if (m_forceMotor == null) { // A fake motor that might be used someday - m_forceMotor = new BSFMotor("setForce", 1f, 1f, 1f, 1f); + m_forceMotor = new BSFMotor("setForce", 1f, 1f, 1f); m_physicsScene.BeforeStep += Mover; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs index b3806e17ad..65098e1641 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs @@ -101,7 +101,7 @@ public class BSActorSetTorque : BSActor if (m_torqueMotor == null) { // A fake motor that might be used someday - m_torqueMotor = new BSFMotor("setTorque", 1f, 1f, 1f, 1f); + m_torqueMotor = new BSFMotor("setTorque", 1f, 1f, 1f); m_physicsScene.BeforeStep += Mover; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 0dd2aa5d1a..272a162411 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -235,7 +235,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // set all of the components to the same value case Vehicle.ANGULAR_FRICTION_TIMESCALE: m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); - m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; break; case Vehicle.ANGULAR_MOTOR_DIRECTION: m_angularMotorDirection = new Vector3(pValue, pValue, pValue); @@ -244,7 +243,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); - m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; break; case Vehicle.LINEAR_MOTOR_DIRECTION: m_linearMotorDirection = new Vector3(pValue, pValue, pValue); @@ -265,7 +263,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin { case Vehicle.ANGULAR_FRICTION_TIMESCALE: m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; break; case Vehicle.ANGULAR_MOTOR_DIRECTION: // Limit requested angular speed to 2 rps= 4 pi rads/sec @@ -278,7 +275,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; break; case Vehicle.LINEAR_MOTOR_DIRECTION: m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); @@ -559,14 +555,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; } - m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, - m_linearMotorDecayTimescale, m_linearFrictionTimescale, - 1f); + m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f); m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) - m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, - m_angularMotorDecayTimescale, m_angularFrictionTimescale, - 1f); + m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f); m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) /* Not implemented @@ -574,7 +566,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin BSMotor.Infinite, BSMotor.InfiniteVector, m_verticalAttractionEfficiency); // Z goes away and we keep X and Y - m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) */ @@ -1050,8 +1041,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Add this correction to the velocity to make it faster/slower. VehicleVelocity += linearMotorVelocityW; - VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}", - ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity); + // Friction reduces vehicle motion + Vector3 frictionFactor = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep); + VehicleVelocity -= (VehicleVelocity * frictionFactor); + + VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5},fricFact={6}", + ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, + linearMotorVelocityW, VehicleVelocity, frictionFactor); } public void ComputeLinearTerrainHeightCorrection(float pTimestep) @@ -1342,6 +1338,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // } VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation; + + // Reduce any velocity by friction. + Vector3 frictionFactor = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep); + VehicleRotationalVelocity -= (VehicleRotationalVelocity * frictionFactor); + VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", ControllingPrim.LocalID, angularMotorContributionV); } @@ -1629,6 +1630,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin } + // Given a friction vector (reduction in seconds) and a timestep, return the factor to reduce + // some value by to apply this friction. + private Vector3 ComputeFrictionFactor(Vector3 friction, float pTimestep) + { + Vector3 frictionFactor = Vector3.Zero; + if (friction != BSMotor.InfiniteVector) + { + // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; + // Individual friction components can be 'infinite' so compute each separately. + frictionFactor.X = (friction.X == BSMotor.Infinite) ? 0f : (1f / friction.X); + frictionFactor.Y = (friction.Y == BSMotor.Infinite) ? 0f : (1f / friction.Y); + frictionFactor.Z = (friction.Z == BSMotor.Infinite) ? 0f : (1f / friction.Z); + frictionFactor *= pTimestep; + } + return frictionFactor; + } + private float ClampInRange(float low, float val, float high) { return Math.Max(low, Math.Min(val, high)); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 0128d8dbdd..ef662b5919 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -65,13 +65,11 @@ public abstract class BSMotor } // Motor which moves CurrentValue to TargetValue over TimeScale seconds. -// The TargetValue decays in TargetValueDecayTimeScale and -// the CurrentValue will be held back by FrictionTimeScale. +// The TargetValue decays in TargetValueDecayTimeScale. // This motor will "zero itself" over time in that the targetValue will // decay to zero and the currentValue will follow it to that zero. // The overall effect is for the returned correction value to go from large -// values (the total difference between current and target minus friction) -// to small and eventually zero values. +// values to small and eventually zero values. // TimeScale and TargetDelayTimeScale may be 'infinite' which means no decay. // For instance, if something is moving at speed X and the desired speed is Y, @@ -88,7 +86,6 @@ public class BSVMotor : BSMotor public virtual float TimeScale { get; set; } public virtual float TargetValueDecayTimeScale { get; set; } - public virtual Vector3 FrictionTimescale { get; set; } public virtual float Efficiency { get; set; } public virtual float ErrorZeroThreshold { get; set; } @@ -111,16 +108,14 @@ public class BSVMotor : BSMotor { TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; Efficiency = 1f; - FrictionTimescale = BSMotor.InfiniteVector; CurrentValue = TargetValue = Vector3.Zero; ErrorZeroThreshold = 0.001f; } - public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) + public BSVMotor(string useName, float timeScale, float decayTimeScale, float efficiency) : this(useName) { TimeScale = timeScale; TargetValueDecayTimeScale = decayTimeScale; - FrictionTimescale = frictionTimeScale; Efficiency = efficiency; CurrentValue = TargetValue = Vector3.Zero; } @@ -165,26 +160,11 @@ public class BSVMotor : BSMotor TargetValue *= (1f - decayFactor); } - // The amount we can correct the error is reduced by the friction - Vector3 frictionFactor = Vector3.Zero; - if (FrictionTimescale != BSMotor.InfiniteVector) - { - // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; - // Individual friction components can be 'infinite' so compute each separately. - frictionFactor.X = (FrictionTimescale.X == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.X); - frictionFactor.Y = (FrictionTimescale.Y == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Y); - frictionFactor.Z = (FrictionTimescale.Z == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Z); - frictionFactor *= timeStep; - CurrentValue *= (Vector3.One - frictionFactor); - } - MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, timeStep, error, correction); - MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}", - BSScene.DetailLogZero, UseName, - TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor, - TargetValue, CurrentValue); + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},tgt={4},curr={5}", + BSScene.DetailLogZero, UseName, TargetValueDecayTimeScale, decayFactor, TargetValue, CurrentValue); } else { @@ -235,9 +215,9 @@ public class BSVMotor : BSMotor // maximum number of outputs to generate. int maxOutput = 50; MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName); - MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},frictTS={4},eff={5},curr={6},tgt={7}", + MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},eff={4},curr={5},tgt={6}", BSScene.DetailLogZero, UseName, - TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency, + TimeScale, TargetValueDecayTimeScale, Efficiency, CurrentValue, TargetValue); LastError = BSMotor.InfiniteVector; @@ -254,8 +234,8 @@ public class BSVMotor : BSMotor public override string ToString() { - return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4},frictTS={5}>", - UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale, FrictionTimescale); + return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4}>", + UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale); } } @@ -265,7 +245,6 @@ public class BSFMotor : BSMotor { public virtual float TimeScale { get; set; } public virtual float TargetValueDecayTimeScale { get; set; } - public virtual float FrictionTimescale { get; set; } public virtual float Efficiency { get; set; } public virtual float ErrorZeroThreshold { get; set; } @@ -283,12 +262,11 @@ public class BSFMotor : BSMotor return (err >= -ErrorZeroThreshold && err <= ErrorZeroThreshold); } - public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency) + public BSFMotor(string useName, float timeScale, float decayTimescale, float efficiency) : base(useName) { TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; Efficiency = 1f; - FrictionTimescale = BSMotor.Infinite; CurrentValue = TargetValue = 0f; ErrorZeroThreshold = 0.01f; } @@ -331,24 +309,11 @@ public class BSFMotor : BSMotor TargetValue *= (1f - decayFactor); } - // The amount we can correct the error is reduced by the friction - float frictionFactor = 0f; - if (FrictionTimescale != BSMotor.Infinite) - { - // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; - // Individual friction components can be 'infinite' so compute each separately. - frictionFactor = 1f / FrictionTimescale; - frictionFactor *= timeStep; - CurrentValue *= (1f - frictionFactor); - } - MDetailLog("{0}, BSFMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, timeStep, error, correction); - MDetailLog("{0}, BSFMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}", - BSScene.DetailLogZero, UseName, - TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor, - TargetValue, CurrentValue); + MDetailLog("{0}, BSFMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},tgt={4},curr={5}", + BSScene.DetailLogZero, UseName, TargetValueDecayTimeScale, decayFactor, TargetValue, CurrentValue); } else { @@ -390,8 +355,8 @@ public class BSFMotor : BSMotor public override string ToString() { - return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4},frictTS={5}>", - UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale, FrictionTimescale); + return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4}>", + UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale); } }