diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 647 |
1 files changed, 399 insertions, 248 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 7cc3fe3..a1587a8 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -103,6 +103,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
103 | get { return m_sculptLOD; } | 103 | get { return m_sculptLOD; } |
104 | } | 104 | } |
105 | 105 | ||
106 | private BulletSim m_worldSim; | ||
107 | public BulletSim World | ||
108 | { | ||
109 | get { return m_worldSim; } | ||
110 | } | ||
111 | private BSConstraintCollection m_constraintCollection; | ||
112 | public BSConstraintCollection Constraints | ||
113 | { | ||
114 | get { return m_constraintCollection; } | ||
115 | } | ||
116 | |||
106 | private int m_maxSubSteps; | 117 | private int m_maxSubSteps; |
107 | private float m_fixedTimeStep; | 118 | private float m_fixedTimeStep; |
108 | private long m_simulationStep = 0; | 119 | private long m_simulationStep = 0; |
@@ -229,6 +240,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
229 | m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), | 240 | m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), |
230 | m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); | 241 | m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); |
231 | 242 | ||
243 | // Initialization to support the transition to a new API which puts most of the logic | ||
244 | // into the C# code so it is easier to modify and add to. | ||
245 | m_worldSim = new BulletSim(m_worldID, BulletSimAPI.GetSimHandle2(m_worldID)); | ||
246 | m_constraintCollection = new BSConstraintCollection(World); | ||
247 | |||
232 | m_initialized = true; | 248 | m_initialized = true; |
233 | } | 249 | } |
234 | 250 | ||
@@ -237,116 +253,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
237 | private void GetInitialParameterValues(IConfigSource config) | 253 | private void GetInitialParameterValues(IConfigSource config) |
238 | { | 254 | { |
239 | ConfigurationParameters parms = new ConfigurationParameters(); | 255 | ConfigurationParameters parms = new ConfigurationParameters(); |
256 | m_params[0] = parms; | ||
240 | 257 | ||
241 | _meshSculptedPrim = true; // mesh sculpted prims | 258 | SetParameterDefaultValues(); |
242 | _forceSimplePrimMeshing = false; // use complex meshing if called for | ||
243 | |||
244 | m_meshLOD = 8f; | ||
245 | m_sculptLOD = 32f; | ||
246 | |||
247 | shouldDebugLog = false; | ||
248 | m_detailedStatsStep = 0; // disabled | ||
249 | |||
250 | m_maxSubSteps = 10; | ||
251 | m_fixedTimeStep = 1f / 60f; | ||
252 | m_maxCollisionsPerFrame = 2048; | ||
253 | m_maxUpdatesPerFrame = 2048; | ||
254 | m_maximumObjectMass = 10000.01f; | ||
255 | |||
256 | PID_D = 2200f; | ||
257 | PID_P = 900f; | ||
258 | |||
259 | parms.defaultFriction = 0.5f; | ||
260 | parms.defaultDensity = 10.000006836f; // Aluminum g/cm3 | ||
261 | parms.defaultRestitution = 0f; | ||
262 | parms.collisionMargin = 0.0f; | ||
263 | parms.gravity = -9.80665f; | ||
264 | |||
265 | parms.linearDamping = 0.0f; | ||
266 | parms.angularDamping = 0.0f; | ||
267 | parms.deactivationTime = 0.2f; | ||
268 | parms.linearSleepingThreshold = 0.8f; | ||
269 | parms.angularSleepingThreshold = 1.0f; | ||
270 | parms.ccdMotionThreshold = 0.0f; // set to zero to disable | ||
271 | parms.ccdSweptSphereRadius = 0.0f; | ||
272 | parms.contactProcessingThreshold = 0.1f; | ||
273 | |||
274 | parms.terrainFriction = 0.5f; | ||
275 | parms.terrainHitFraction = 0.8f; | ||
276 | parms.terrainRestitution = 0f; | ||
277 | parms.avatarFriction = 0.5f; | ||
278 | parms.avatarRestitution = 0.0f; | ||
279 | parms.avatarDensity = 60f; | ||
280 | parms.avatarCapsuleRadius = 0.37f; | ||
281 | parms.avatarCapsuleHeight = 1.5f; // 2.140599f | ||
282 | parms.avatarContactProcessingThreshold = 0.1f; | ||
283 | |||
284 | parms.maxPersistantManifoldPoolSize = 0f; | ||
285 | parms.shouldDisableContactPoolDynamicAllocation = ConfigurationParameters.numericTrue; | ||
286 | parms.shouldForceUpdateAllAabbs = ConfigurationParameters.numericFalse; | ||
287 | parms.shouldRandomizeSolverOrder = ConfigurationParameters.numericFalse; | ||
288 | parms.shouldSplitSimulationIslands = ConfigurationParameters.numericFalse; | ||
289 | parms.shouldEnableFrictionCaching = ConfigurationParameters.numericFalse; | ||
290 | parms.numberOfSolverIterations = 0f; // means use default | ||
291 | 259 | ||
292 | if (config != null) | 260 | if (config != null) |
293 | { | 261 | { |
294 | // If there are specifications in the ini file, use those values | 262 | // If there are specifications in the ini file, use those values |
295 | // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO UPDATE OpenSimDefaults.ini | ||
296 | // ALSO REMEMBER TO UPDATE THE RUNTIME SETTING OF THE PARAMETERS. | ||
297 | IConfig pConfig = config.Configs["BulletSim"]; | 263 | IConfig pConfig = config.Configs["BulletSim"]; |
298 | if (pConfig != null) | 264 | if (pConfig != null) |
299 | { | 265 | { |
300 | _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim); | 266 | SetParameterConfigurationValues(pConfig); |
301 | _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing); | ||
302 | |||
303 | shouldDebugLog = pConfig.GetBoolean("ShouldDebugLog", shouldDebugLog); | ||
304 | m_detailedStatsStep = pConfig.GetInt("DetailedStatsStep", m_detailedStatsStep); | ||
305 | |||
306 | m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD); | ||
307 | m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD); | ||
308 | |||
309 | m_maxSubSteps = pConfig.GetInt("MaxSubSteps", m_maxSubSteps); | ||
310 | m_fixedTimeStep = pConfig.GetFloat("FixedTimeStep", m_fixedTimeStep); | ||
311 | m_maxCollisionsPerFrame = pConfig.GetInt("MaxCollisionsPerFrame", m_maxCollisionsPerFrame); | ||
312 | m_maxUpdatesPerFrame = pConfig.GetInt("MaxUpdatesPerFrame", m_maxUpdatesPerFrame); | ||
313 | m_maximumObjectMass = pConfig.GetFloat("MaxObjectMass", m_maximumObjectMass); | ||
314 | |||
315 | PID_D = pConfig.GetFloat("PIDDerivative", PID_D); | ||
316 | PID_P = pConfig.GetFloat("PIDProportional", PID_P); | ||
317 | |||
318 | parms.defaultFriction = pConfig.GetFloat("DefaultFriction", parms.defaultFriction); | ||
319 | parms.defaultDensity = pConfig.GetFloat("DefaultDensity", parms.defaultDensity); | ||
320 | parms.defaultRestitution = pConfig.GetFloat("DefaultRestitution", parms.defaultRestitution); | ||
321 | parms.collisionMargin = pConfig.GetFloat("CollisionMargin", parms.collisionMargin); | ||
322 | parms.gravity = pConfig.GetFloat("Gravity", parms.gravity); | ||
323 | |||
324 | parms.linearDamping = pConfig.GetFloat("LinearDamping", parms.linearDamping); | ||
325 | parms.angularDamping = pConfig.GetFloat("AngularDamping", parms.angularDamping); | ||
326 | parms.deactivationTime = pConfig.GetFloat("DeactivationTime", parms.deactivationTime); | ||
327 | parms.linearSleepingThreshold = pConfig.GetFloat("LinearSleepingThreshold", parms.linearSleepingThreshold); | ||
328 | parms.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", parms.angularSleepingThreshold); | ||
329 | parms.ccdMotionThreshold = pConfig.GetFloat("CcdMotionThreshold", parms.ccdMotionThreshold); | ||
330 | parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius); | ||
331 | parms.contactProcessingThreshold = pConfig.GetFloat("ContactProcessingThreshold", parms.contactProcessingThreshold); | ||
332 | |||
333 | parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction); | ||
334 | parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction); | ||
335 | parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution); | ||
336 | parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction); | ||
337 | parms.avatarRestitution = pConfig.GetFloat("AvatarRestitution", parms.avatarRestitution); | ||
338 | parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity); | ||
339 | parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius); | ||
340 | parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight); | ||
341 | parms.avatarContactProcessingThreshold = pConfig.GetFloat("AvatarContactProcessingThreshold", parms.avatarContactProcessingThreshold); | ||
342 | |||
343 | parms.maxPersistantManifoldPoolSize = pConfig.GetFloat("MaxPersistantManifoldPoolSize", parms.maxPersistantManifoldPoolSize); | ||
344 | parms.shouldDisableContactPoolDynamicAllocation = ParamBoolean(pConfig, "ShouldDisableContactPoolDynamicAllocation", parms.shouldDisableContactPoolDynamicAllocation); | ||
345 | parms.shouldForceUpdateAllAabbs = ParamBoolean(pConfig, "ShouldForceUpdateAllAabbs", parms.shouldForceUpdateAllAabbs); | ||
346 | parms.shouldRandomizeSolverOrder = ParamBoolean(pConfig, "ShouldRandomizeSolverOrder", parms.shouldRandomizeSolverOrder); | ||
347 | parms.shouldSplitSimulationIslands = ParamBoolean(pConfig, "ShouldSplitSimulationIslands", parms.shouldSplitSimulationIslands); | ||
348 | parms.shouldEnableFrictionCaching = ParamBoolean(pConfig, "ShouldEnableFrictionCaching", parms.shouldEnableFrictionCaching); | ||
349 | parms.numberOfSolverIterations = pConfig.GetFloat("NumberOfSolverIterations", parms.numberOfSolverIterations); | ||
350 | 267 | ||
351 | // Very detailed logging for physics debugging | 268 | // Very detailed logging for physics debugging |
352 | m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); | 269 | m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); |
@@ -357,7 +274,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
357 | m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); | 274 | m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); |
358 | } | 275 | } |
359 | } | 276 | } |
360 | m_params[0] = parms; | ||
361 | } | 277 | } |
362 | 278 | ||
363 | // A helper function that handles a true/false parameter and returns the proper float number encoding | 279 | // A helper function that handles a true/false parameter and returns the proper float number encoding |
@@ -634,6 +550,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
634 | // make sure no stepping happens while we're deleting stuff | 550 | // make sure no stepping happens while we're deleting stuff |
635 | m_initialized = false; | 551 | m_initialized = false; |
636 | 552 | ||
553 | if (m_constraintCollection != null) | ||
554 | { | ||
555 | m_constraintCollection.Dispose(); | ||
556 | m_constraintCollection = null; | ||
557 | } | ||
558 | |||
637 | foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) | 559 | foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) |
638 | { | 560 | { |
639 | kvp.Value.Destroy(); | 561 | kvp.Value.Destroy(); |
@@ -776,10 +698,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
776 | } | 698 | } |
777 | 699 | ||
778 | // The calls to the PhysicsActors can't directly call into the physics engine | 700 | // The calls to the PhysicsActors can't directly call into the physics engine |
779 | // because it might be busy. We we delay changes to a known time. | 701 | // because it might be busy. We delay changes to a known time. |
780 | // We rely on C#'s closure to save and restore the context for the delegate. | 702 | // We rely on C#'s closure to save and restore the context for the delegate. |
781 | public void TaintedObject(TaintCallback callback) | 703 | public void TaintedObject(TaintCallback callback) |
782 | { | 704 | { |
705 | if (!m_initialized) return; | ||
706 | |||
783 | lock (_taintLock) | 707 | lock (_taintLock) |
784 | _taintedObjects.Add(callback); | 708 | _taintedObjects.Add(callback); |
785 | return; | 709 | return; |
@@ -853,61 +777,371 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
853 | } | 777 | } |
854 | #endregion Vehicles | 778 | #endregion Vehicles |
855 | 779 | ||
856 | #region Runtime settable parameters | 780 | #region Parameters |
857 | public static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[] | 781 | |
782 | delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); | ||
783 | delegate float ParamGet(BSScene scene); | ||
784 | delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); | ||
785 | |||
786 | private struct ParameterDefn | ||
858 | { | 787 | { |
859 | new PhysParameterEntry("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)"), | 788 | public string name; |
860 | new PhysParameterEntry("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)"), | 789 | public string desc; |
861 | new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"), | 790 | public float defaultValue; |
862 | new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"), | 791 | public ParamUser userParam; |
863 | new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"), | 792 | public ParamGet getter; |
864 | new PhysParameterEntry("DetailedStats", "Frames between outputting detailed phys stats. Zero is off"), | 793 | public ParamSet setter; |
865 | 794 | public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) | |
866 | new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"), | 795 | { |
867 | new PhysParameterEntry("DefaultDensity", "Density for new objects" ), | 796 | name = n; |
868 | new PhysParameterEntry("DefaultRestitution", "Bouncyness of an object" ), | 797 | desc = d; |
869 | // new PhysParameterEntry("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!!)" ), | 798 | defaultValue = v; |
870 | new PhysParameterEntry("Gravity", "Vertical force of gravity (negative means down)" ), | 799 | userParam = u; |
871 | 800 | getter = g; | |
872 | new PhysParameterEntry("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)" ), | 801 | setter = s; |
873 | new PhysParameterEntry("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)" ), | 802 | } |
874 | new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ), | 803 | } |
875 | new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ), | 804 | |
876 | new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ), | 805 | // List of all of the externally visible parameters. |
877 | new PhysParameterEntry("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ), | 806 | // For each parameter, this table maps a text name to getter and setters. |
878 | new PhysParameterEntry("CcdSweptSphereRadius", "Continuious collision detection test radius" ), | 807 | // A ParameterDefn() takes the following parameters: |
879 | new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ), | 808 | // -- the text name of the parameter. This is used for console input and ini file. |
880 | // Can only change the following at initialization time. Change the INI file and reboot. | 809 | // -- a short text description of the parameter. This shows up in the console listing. |
881 | new PhysParameterEntry("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)"), | 810 | // -- a delegate for fetching the parameter from the ini file. |
882 | new PhysParameterEntry("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count"), | 811 | // Should handle fetching the right type from the ini file and converting it. |
883 | new PhysParameterEntry("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step"), | 812 | // -- a delegate for getting the value as a float |
884 | new PhysParameterEntry("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction"), | 813 | // -- a delegate for setting the value from a float |
885 | new PhysParameterEntry("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands"), | 814 | // |
886 | new PhysParameterEntry("ShouldEnableFrictionCaching", "Enable friction computation caching"), | 815 | // To add a new variable, it is best to find an existing definition and copy it. |
887 | new PhysParameterEntry("NumberOfSolverIterations", "Number of internal iterations (0 means default)"), | 816 | private ParameterDefn[] ParameterDefinitions = |
888 | 817 | { | |
889 | new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ), | 818 | new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", |
890 | new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ), | 819 | ConfigurationParameters.numericTrue, |
891 | 820 | (s,cf,p,v) => { s._meshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); }, | |
892 | new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ), | 821 | (s) => { return s.NumericBool(s._meshSculptedPrim); }, |
893 | new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ), | 822 | (s,p,l,v) => { s._meshSculptedPrim = s.BoolNumeric(v); } ), |
894 | 823 | new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", | |
895 | new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ), | 824 | ConfigurationParameters.numericFalse, |
896 | new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ), | 825 | (s,cf,p,v) => { s._forceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); }, |
897 | new PhysParameterEntry("TerrainRestitution", "Bouncyness" ), | 826 | (s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, |
898 | new PhysParameterEntry("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation." ), | 827 | (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ), |
899 | new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ), | 828 | |
900 | new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ), | 829 | new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", |
901 | new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ), | 830 | 8f, |
902 | new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ), | 831 | (s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); }, |
903 | new PhysParameterEntry("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions") | 832 | (s) => { return (float)s.m_meshLOD; }, |
833 | (s,p,l,v) => { s.m_meshLOD = (int)v; } ), | ||
834 | new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", | ||
835 | 32, | ||
836 | (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, | ||
837 | (s) => { return (float)s.m_sculptLOD; }, | ||
838 | (s,p,l,v) => { s.m_sculptLOD = (int)v; } ), | ||
839 | |||
840 | new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", | ||
841 | 10f, | ||
842 | (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); }, | ||
843 | (s) => { return (float)s.m_maxSubSteps; }, | ||
844 | (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ), | ||
845 | new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", | ||
846 | 1f / 60f, | ||
847 | (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); }, | ||
848 | (s) => { return (float)s.m_fixedTimeStep; }, | ||
849 | (s,p,l,v) => { s.m_fixedTimeStep = v; } ), | ||
850 | new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", | ||
851 | 2048f, | ||
852 | (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); }, | ||
853 | (s) => { return (float)s.m_maxCollisionsPerFrame; }, | ||
854 | (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), | ||
855 | new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame", | ||
856 | 8000f, | ||
857 | (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, | ||
858 | (s) => { return (float)s.m_maxUpdatesPerFrame; }, | ||
859 | (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), | ||
860 | new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", | ||
861 | 10000.01f, | ||
862 | (s,cf,p,v) => { s.m_maximumObjectMass = cf.GetFloat(p, v); }, | ||
863 | (s) => { return (float)s.m_maximumObjectMass; }, | ||
864 | (s,p,l,v) => { s.m_maximumObjectMass = v; } ), | ||
865 | |||
866 | new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", | ||
867 | 2200f, | ||
868 | (s,cf,p,v) => { s.PID_D = cf.GetFloat(p, v); }, | ||
869 | (s) => { return (float)s.PID_D; }, | ||
870 | (s,p,l,v) => { s.PID_D = v; } ), | ||
871 | new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", | ||
872 | 900f, | ||
873 | (s,cf,p,v) => { s.PID_P = cf.GetFloat(p, v); }, | ||
874 | (s) => { return (float)s.PID_P; }, | ||
875 | (s,p,l,v) => { s.PID_P = v; } ), | ||
876 | |||
877 | new ParameterDefn("DefaultFriction", "Friction factor used on new objects", | ||
878 | 0.5f, | ||
879 | (s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); }, | ||
880 | (s) => { return s.m_params[0].defaultFriction; }, | ||
881 | (s,p,l,v) => { s.m_params[0].defaultFriction = v; } ), | ||
882 | new ParameterDefn("DefaultDensity", "Density for new objects" , | ||
883 | 10.000006836f, // Aluminum g/cm3 | ||
884 | (s,cf,p,v) => { s.m_params[0].defaultDensity = cf.GetFloat(p, v); }, | ||
885 | (s) => { return s.m_params[0].defaultDensity; }, | ||
886 | (s,p,l,v) => { s.m_params[0].defaultDensity = v; } ), | ||
887 | new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , | ||
888 | 0f, | ||
889 | (s,cf,p,v) => { s.m_params[0].defaultRestitution = cf.GetFloat(p, v); }, | ||
890 | (s) => { return s.m_params[0].defaultRestitution; }, | ||
891 | (s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ), | ||
892 | new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", | ||
893 | 0f, | ||
894 | (s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); }, | ||
895 | (s) => { return s.m_params[0].collisionMargin; }, | ||
896 | (s,p,l,v) => { s.m_params[0].collisionMargin = v; } ), | ||
897 | new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", | ||
898 | -9.80665f, | ||
899 | (s,cf,p,v) => { s.m_params[0].gravity = cf.GetFloat(p, v); }, | ||
900 | (s) => { return s.m_params[0].gravity; }, | ||
901 | (s,p,l,v) => { s.m_params[0].gravity = v; s.TaintedUpdateParameter(p,l,v); } ), | ||
902 | |||
903 | |||
904 | new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", | ||
905 | 0f, | ||
906 | (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, | ||
907 | (s) => { return s.m_params[0].linearDamping; }, | ||
908 | (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearDamping, p, l, v); } ), | ||
909 | new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", | ||
910 | 0f, | ||
911 | (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, | ||
912 | (s) => { return s.m_params[0].angularDamping; }, | ||
913 | (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularDamping, p, l, v); } ), | ||
914 | new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", | ||
915 | 0.2f, | ||
916 | (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, | ||
917 | (s) => { return s.m_params[0].deactivationTime; }, | ||
918 | (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].deactivationTime, p, l, v); } ), | ||
919 | new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", | ||
920 | 0.8f, | ||
921 | (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, | ||
922 | (s) => { return s.m_params[0].linearSleepingThreshold; }, | ||
923 | (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ), | ||
924 | new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", | ||
925 | 1.0f, | ||
926 | (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, | ||
927 | (s) => { return s.m_params[0].angularSleepingThreshold; }, | ||
928 | (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ), | ||
929 | new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , | ||
930 | 0f, // set to zero to disable | ||
931 | (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, | ||
932 | (s) => { return s.m_params[0].ccdMotionThreshold; }, | ||
933 | (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ), | ||
934 | new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , | ||
935 | 0f, | ||
936 | (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, | ||
937 | (s) => { return s.m_params[0].ccdSweptSphereRadius; }, | ||
938 | (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ), | ||
939 | new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , | ||
940 | 0.1f, | ||
941 | (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, | ||
942 | (s) => { return s.m_params[0].contactProcessingThreshold; }, | ||
943 | (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ), | ||
944 | |||
945 | new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , | ||
946 | 0.5f, | ||
947 | (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); }, | ||
948 | (s) => { return s.m_params[0].terrainFriction; }, | ||
949 | (s,p,l,v) => { s.m_params[0].terrainFriction = v; s.TaintedUpdateParameter(p,l,v); } ), | ||
950 | new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , | ||
951 | 0.8f, | ||
952 | (s,cf,p,v) => { s.m_params[0].terrainHitFraction = cf.GetFloat(p, v); }, | ||
953 | (s) => { return s.m_params[0].terrainHitFraction; }, | ||
954 | (s,p,l,v) => { s.m_params[0].terrainHitFraction = v; s.TaintedUpdateParameter(p,l,v); } ), | ||
955 | new ParameterDefn("TerrainRestitution", "Bouncyness" , | ||
956 | 0f, | ||
957 | (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); }, | ||
958 | (s) => { return s.m_params[0].terrainRestitution; }, | ||
959 | (s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ), | ||
960 | new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", | ||
961 | 0.5f, | ||
962 | (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, | ||
963 | (s) => { return s.m_params[0].avatarFriction; }, | ||
964 | (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarFriction, p, l, v); } ), | ||
965 | new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", | ||
966 | 60f, | ||
967 | (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); }, | ||
968 | (s) => { return s.m_params[0].avatarDensity; }, | ||
969 | (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarDensity, p, l, v); } ), | ||
970 | new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", | ||
971 | 0f, | ||
972 | (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); }, | ||
973 | (s) => { return s.m_params[0].avatarRestitution; }, | ||
974 | (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarRestitution, p, l, v); } ), | ||
975 | new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar", | ||
976 | 0.37f, | ||
977 | (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); }, | ||
978 | (s) => { return s.m_params[0].avatarCapsuleRadius; }, | ||
979 | (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), | ||
980 | new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", | ||
981 | 1.5f, | ||
982 | (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, | ||
983 | (s) => { return s.m_params[0].avatarCapsuleHeight; }, | ||
984 | (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), | ||
985 | new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", | ||
986 | 0.1f, | ||
987 | (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); }, | ||
988 | (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, | ||
989 | (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), | ||
990 | |||
991 | |||
992 | new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)", | ||
993 | 0f, // zero to disable | ||
994 | (s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, | ||
995 | (s) => { return s.m_params[0].maxPersistantManifoldPoolSize; }, | ||
996 | (s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ), | ||
997 | new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", | ||
998 | ConfigurationParameters.numericTrue, | ||
999 | (s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, | ||
1000 | (s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; }, | ||
1001 | (s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ), | ||
1002 | new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", | ||
1003 | ConfigurationParameters.numericFalse, | ||
1004 | (s,cf,p,v) => { s.m_params[0].shouldForceUpdateAllAabbs = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, | ||
1005 | (s) => { return s.m_params[0].shouldForceUpdateAllAabbs; }, | ||
1006 | (s,p,l,v) => { s.m_params[0].shouldForceUpdateAllAabbs = v; } ), | ||
1007 | new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", | ||
1008 | ConfigurationParameters.numericFalse, | ||
1009 | (s,cf,p,v) => { s.m_params[0].shouldRandomizeSolverOrder = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, | ||
1010 | (s) => { return s.m_params[0].shouldRandomizeSolverOrder; }, | ||
1011 | (s,p,l,v) => { s.m_params[0].shouldRandomizeSolverOrder = v; } ), | ||
1012 | new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", | ||
1013 | ConfigurationParameters.numericFalse, | ||
1014 | (s,cf,p,v) => { s.m_params[0].shouldSplitSimulationIslands = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, | ||
1015 | (s) => { return s.m_params[0].shouldSplitSimulationIslands; }, | ||
1016 | (s,p,l,v) => { s.m_params[0].shouldSplitSimulationIslands = v; } ), | ||
1017 | new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", | ||
1018 | ConfigurationParameters.numericFalse, | ||
1019 | (s,cf,p,v) => { s.m_params[0].shouldEnableFrictionCaching = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, | ||
1020 | (s) => { return s.m_params[0].shouldEnableFrictionCaching; }, | ||
1021 | (s,p,l,v) => { s.m_params[0].shouldEnableFrictionCaching = v; } ), | ||
1022 | new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", | ||
1023 | 0f, // zero says use Bullet default | ||
1024 | (s,cf,p,v) => { s.m_params[0].numberOfSolverIterations = cf.GetFloat(p, v); }, | ||
1025 | (s) => { return s.m_params[0].numberOfSolverIterations; }, | ||
1026 | (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ), | ||
1027 | |||
1028 | new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", | ||
1029 | ConfigurationParameters.numericTrue, | ||
1030 | (s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, | ||
1031 | (s) => { return s.m_params[0].linkConstraintUseFrameOffset; }, | ||
1032 | (s,p,l,v) => { s.m_params[0].linkConstraintUseFrameOffset = v; } ), | ||
1033 | new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", | ||
1034 | ConfigurationParameters.numericTrue, | ||
1035 | (s,cf,p,v) => { s.m_params[0].linkConstraintEnableTransMotor = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, | ||
1036 | (s) => { return s.m_params[0].linkConstraintEnableTransMotor; }, | ||
1037 | (s,p,l,v) => { s.m_params[0].linkConstraintEnableTransMotor = v; } ), | ||
1038 | new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", | ||
1039 | 5.0f, | ||
1040 | (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = cf.GetFloat(p, v); }, | ||
1041 | (s) => { return s.m_params[0].linkConstraintTransMotorMaxVel; }, | ||
1042 | (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = v; } ), | ||
1043 | new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", | ||
1044 | 0.1f, | ||
1045 | (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, | ||
1046 | (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; }, | ||
1047 | (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ), | ||
1048 | |||
1049 | new ParameterDefn("DetailedStats", "Frames between outputting detailed phys stats. (0 is off)", | ||
1050 | 0f, | ||
1051 | (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, | ||
1052 | (s) => { return (float)s.m_detailedStatsStep; }, | ||
1053 | (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), | ||
1054 | new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements", | ||
1055 | ConfigurationParameters.numericFalse, | ||
1056 | (s,cf,p,v) => { s.shouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); }, | ||
1057 | (s) => { return s.NumericBool(s.shouldDebugLog); }, | ||
1058 | (s,p,l,v) => { s.shouldDebugLog = s.BoolNumeric(v); } ), | ||
904 | 1059 | ||
905 | }; | 1060 | }; |
906 | 1061 | ||
1062 | // Convert a boolean to our numeric true and false values | ||
1063 | public float NumericBool(bool b) | ||
1064 | { | ||
1065 | return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse); | ||
1066 | } | ||
1067 | |||
1068 | // Convert numeric true and false values to a boolean | ||
1069 | public bool BoolNumeric(float b) | ||
1070 | { | ||
1071 | return (b == ConfigurationParameters.numericTrue ? true : false); | ||
1072 | } | ||
1073 | |||
1074 | // Search through the parameter definitions and return the matching | ||
1075 | // ParameterDefn structure. | ||
1076 | // Case does not matter as names are compared after converting to lower case. | ||
1077 | // Returns 'false' if the parameter is not found. | ||
1078 | private bool TryGetParameter(string paramName, out ParameterDefn defn) | ||
1079 | { | ||
1080 | bool ret = false; | ||
1081 | ParameterDefn foundDefn = new ParameterDefn(); | ||
1082 | string pName = paramName.ToLower(); | ||
1083 | |||
1084 | foreach (ParameterDefn parm in ParameterDefinitions) | ||
1085 | { | ||
1086 | if (pName == parm.name.ToLower()) | ||
1087 | { | ||
1088 | foundDefn = parm; | ||
1089 | ret = true; | ||
1090 | break; | ||
1091 | } | ||
1092 | } | ||
1093 | defn = foundDefn; | ||
1094 | return ret; | ||
1095 | } | ||
1096 | |||
1097 | // Pass through the settable parameters and set the default values | ||
1098 | private void SetParameterDefaultValues() | ||
1099 | { | ||
1100 | foreach (ParameterDefn parm in ParameterDefinitions) | ||
1101 | { | ||
1102 | parm.setter(this, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue); | ||
1103 | } | ||
1104 | } | ||
1105 | |||
1106 | // Get user set values out of the ini file. | ||
1107 | private void SetParameterConfigurationValues(IConfig cfg) | ||
1108 | { | ||
1109 | foreach (ParameterDefn parm in ParameterDefinitions) | ||
1110 | { | ||
1111 | parm.userParam(this, cfg, parm.name, parm.defaultValue); | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; | ||
1116 | |||
1117 | private void BuildParameterTable() | ||
1118 | { | ||
1119 | if (SettableParameters.Length < ParameterDefinitions.Length) | ||
1120 | { | ||
1121 | |||
1122 | List<PhysParameterEntry> entries = new List<PhysParameterEntry>(); | ||
1123 | for (int ii = 0; ii < ParameterDefinitions.Length; ii++) | ||
1124 | { | ||
1125 | ParameterDefn pd = ParameterDefinitions[ii]; | ||
1126 | entries.Add(new PhysParameterEntry(pd.name, pd.desc)); | ||
1127 | } | ||
1128 | |||
1129 | // make the list in alphabetical order for estetic reasons | ||
1130 | entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2) | ||
1131 | { | ||
1132 | return ppe1.name.CompareTo(ppe2.name); | ||
1133 | }); | ||
1134 | |||
1135 | SettableParameters = entries.ToArray(); | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | |||
907 | #region IPhysicsParameters | 1140 | #region IPhysicsParameters |
908 | // Get the list of parameters this physics engine supports | 1141 | // Get the list of parameters this physics engine supports |
909 | public PhysParameterEntry[] GetParameterList() | 1142 | public PhysParameterEntry[] GetParameterList() |
910 | { | 1143 | { |
1144 | BuildParameterTable(); | ||
911 | return SettableParameters; | 1145 | return SettableParameters; |
912 | } | 1146 | } |
913 | 1147 | ||
@@ -919,63 +1153,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
919 | // value activated ('terrainFriction' for instance). | 1153 | // value activated ('terrainFriction' for instance). |
920 | public bool SetPhysicsParameter(string parm, float val, uint localID) | 1154 | public bool SetPhysicsParameter(string parm, float val, uint localID) |
921 | { | 1155 | { |
922 | bool ret = true; | 1156 | bool ret = false; |
923 | string lparm = parm.ToLower(); | 1157 | ParameterDefn theParam; |
924 | switch (lparm) | 1158 | if (TryGetParameter(parm, out theParam)) |
925 | { | 1159 | { |
926 | case "detailedstats": m_detailedStatsStep = (int)val; break; | 1160 | theParam.setter(this, parm, localID, val); |
927 | 1161 | ret = true; | |
928 | case "meshlod": m_meshLOD = (int)val; break; | ||
929 | case "sculptlod": m_sculptLOD = (int)val; break; | ||
930 | case "maxsubstep": m_maxSubSteps = (int)val; break; | ||
931 | case "fixedtimestep": m_fixedTimeStep = val; break; | ||
932 | case "maxobjectmass": m_maximumObjectMass = val; break; | ||
933 | |||
934 | case "defaultfriction": m_params[0].defaultFriction = val; break; | ||
935 | case "defaultdensity": m_params[0].defaultDensity = val; break; | ||
936 | case "defaultrestitution": m_params[0].defaultRestitution = val; break; | ||
937 | case "collisionmargin": m_params[0].collisionMargin = val; break; | ||
938 | case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, localID, val); break; | ||
939 | |||
940 | case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break; | ||
941 | case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; | ||
942 | case "deactivationtime": UpdateParameterPrims(ref m_params[0].deactivationTime, lparm, localID, val); break; | ||
943 | case "linearsleepingthreshold": UpdateParameterPrims(ref m_params[0].linearSleepingThreshold, lparm, localID, val); break; | ||
944 | case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; | ||
945 | case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break; | ||
946 | case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break; | ||
947 | case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break; | ||
948 | // the following are used only at initialization time so setting them makes no sense | ||
949 | // case "maxPersistantmanifoldpoolSize": m_params[0].maxPersistantManifoldPoolSize = val; break; | ||
950 | // case "shoulddisablecontactpooldynamicallocation": m_params[0].shouldDisableContactPoolDynamicAllocation = val; break; | ||
951 | // case "shouldforceupdateallaabbs": m_params[0].shouldForceUpdateAllAabbs = val; break; | ||
952 | // case "shouldrandomizesolverorder": m_params[0].shouldRandomizeSolverOrder = val; break; | ||
953 | // case "shouldsplitsimulationislands": m_params[0].shouldSplitSimulationIslands = val; break; | ||
954 | // case "shouldenablefrictioncaching": m_params[0].shouldEnableFrictionCaching = val; break; | ||
955 | // case "numberofsolveriterations": m_params[0].numberOfSolverIterations = val; break; | ||
956 | |||
957 | case "friction": TaintedUpdateParameter(lparm, localID, val); break; | ||
958 | case "restitution": TaintedUpdateParameter(lparm, localID, val); break; | ||
959 | |||
960 | // set a terrain physical feature and cause terrain to be recalculated | ||
961 | case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break; | ||
962 | case "terrainhitfraction": m_params[0].terrainHitFraction = val; TaintedUpdateParameter("terrain", 0, val); break; | ||
963 | case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break; | ||
964 | // set an avatar physical feature and cause avatar(s) to be recalculated | ||
965 | case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break; | ||
966 | case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break; | ||
967 | case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break; | ||
968 | case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break; | ||
969 | case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break; | ||
970 | case "avatarcontactprocessingthreshold": UpdateParameterAvatars(ref m_params[0].avatarContactProcessingThreshold, "avatar", localID, val); break; | ||
971 | |||
972 | default: ret = false; break; | ||
973 | } | 1162 | } |
974 | return ret; | 1163 | return ret; |
975 | } | 1164 | } |
976 | 1165 | ||
977 | // check to see if we are updating a parameter for a particular or all of the prims | 1166 | // check to see if we are updating a parameter for a particular or all of the prims |
978 | private void UpdateParameterPrims(ref float loc, string parm, uint localID, float val) | 1167 | protected void UpdateParameterPrims(ref float loc, string parm, uint localID, float val) |
979 | { | 1168 | { |
980 | List<uint> operateOn; | 1169 | List<uint> operateOn; |
981 | lock (m_prims) operateOn = new List<uint>(m_prims.Keys); | 1170 | lock (m_prims) operateOn = new List<uint>(m_prims.Keys); |
@@ -983,7 +1172,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
983 | } | 1172 | } |
984 | 1173 | ||
985 | // check to see if we are updating a parameter for a particular or all of the avatars | 1174 | // check to see if we are updating a parameter for a particular or all of the avatars |
986 | private void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val) | 1175 | protected void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val) |
987 | { | 1176 | { |
988 | List<uint> operateOn; | 1177 | List<uint> operateOn; |
989 | lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys); | 1178 | lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys); |
@@ -994,7 +1183,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
994 | // If the local ID is APPLY_TO_NONE, just change the default value | 1183 | // If the local ID is APPLY_TO_NONE, just change the default value |
995 | // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs | 1184 | // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs |
996 | // If the localID is a specific object, apply the parameter change to only that object | 1185 | // If the localID is a specific object, apply the parameter change to only that object |
997 | private void UpdateParameterSet(List<uint> lIDs, ref float defaultLoc, string parm, uint localID, float val) | 1186 | protected void UpdateParameterSet(List<uint> lIDs, ref float defaultLoc, string parm, uint localID, float val) |
998 | { | 1187 | { |
999 | switch (localID) | 1188 | switch (localID) |
1000 | { | 1189 | { |
@@ -1021,7 +1210,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
1021 | } | 1210 | } |
1022 | 1211 | ||
1023 | // schedule the actual updating of the paramter to when the phys engine is not busy | 1212 | // schedule the actual updating of the paramter to when the phys engine is not busy |
1024 | private void TaintedUpdateParameter(string parm, uint localID, float val) | 1213 | protected void TaintedUpdateParameter(string parm, uint localID, float val) |
1025 | { | 1214 | { |
1026 | uint xlocalID = localID; | 1215 | uint xlocalID = localID; |
1027 | string xparm = parm.ToLower(); | 1216 | string xparm = parm.ToLower(); |
@@ -1036,50 +1225,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
1036 | public bool GetPhysicsParameter(string parm, out float value) | 1225 | public bool GetPhysicsParameter(string parm, out float value) |
1037 | { | 1226 | { |
1038 | float val = 0f; | 1227 | float val = 0f; |
1039 | bool ret = true; | 1228 | bool ret = false; |
1040 | switch (parm.ToLower()) | 1229 | ParameterDefn theParam; |
1230 | if (TryGetParameter(parm, out theParam)) | ||
1041 | { | 1231 | { |
1042 | case "detailedstats": val = (int)m_detailedStatsStep; break; | 1232 | val = theParam.getter(this); |
1043 | case "meshlod": val = (float)m_meshLOD; break; | 1233 | ret = true; |
1044 | case "sculptlod": val = (float)m_sculptLOD; break; | ||
1045 | case "maxsubstep": val = (float)m_maxSubSteps; break; | ||
1046 | case "fixedtimestep": val = m_fixedTimeStep; break; | ||
1047 | case "maxobjectmass": val = m_maximumObjectMass; break; | ||
1048 | |||
1049 | case "defaultfriction": val = m_params[0].defaultFriction; break; | ||
1050 | case "defaultdensity": val = m_params[0].defaultDensity; break; | ||
1051 | case "defaultrestitution": val = m_params[0].defaultRestitution; break; | ||
1052 | case "collisionmargin": val = m_params[0].collisionMargin; break; | ||
1053 | case "gravity": val = m_params[0].gravity; break; | ||
1054 | |||
1055 | case "lineardamping": val = m_params[0].linearDamping; break; | ||
1056 | case "angulardamping": val = m_params[0].angularDamping; break; | ||
1057 | case "deactivationtime": val = m_params[0].deactivationTime; break; | ||
1058 | case "linearsleepingthreshold": val = m_params[0].linearSleepingThreshold; break; | ||
1059 | case "angularsleepingthreshold": val = m_params[0].angularDamping; break; | ||
1060 | case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break; | ||
1061 | case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break; | ||
1062 | case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break; | ||
1063 | case "maxPersistantmanifoldpoolSize": val = m_params[0].maxPersistantManifoldPoolSize; break; | ||
1064 | case "shoulddisablecontactpooldynamicallocation": val = m_params[0].shouldDisableContactPoolDynamicAllocation; break; | ||
1065 | case "shouldforceupdateallaabbs": val = m_params[0].shouldForceUpdateAllAabbs; break; | ||
1066 | case "shouldrandomizesolverorder": val = m_params[0].shouldRandomizeSolverOrder; break; | ||
1067 | case "shouldsplitsimulationislands": val = m_params[0].shouldSplitSimulationIslands; break; | ||
1068 | case "shouldenablefrictioncaching": val = m_params[0].shouldEnableFrictionCaching; break; | ||
1069 | case "numberofsolveriterations": val = m_params[0].numberOfSolverIterations; break; | ||
1070 | |||
1071 | case "terrainfriction": val = m_params[0].terrainFriction; break; | ||
1072 | case "terrainhitfraction": val = m_params[0].terrainHitFraction; break; | ||
1073 | case "terrainrestitution": val = m_params[0].terrainRestitution; break; | ||
1074 | |||
1075 | case "avatarfriction": val = m_params[0].avatarFriction; break; | ||
1076 | case "avatardensity": val = m_params[0].avatarDensity; break; | ||
1077 | case "avatarrestitution": val = m_params[0].avatarRestitution; break; | ||
1078 | case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break; | ||
1079 | case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break; | ||
1080 | case "avatarcontactprocessingthreshold": val = m_params[0].avatarContactProcessingThreshold; break; | ||
1081 | default: ret = false; break; | ||
1082 | |||
1083 | } | 1234 | } |
1084 | value = val; | 1235 | value = val; |
1085 | return ret; | 1236 | return ret; |