aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs647
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;