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