aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSParam.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs738
1 files changed, 738 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
new file mode 100755
index 0000000..329169f
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -0,0 +1,738 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30
31using OpenSim.Region.Physics.Manager;
32
33using OpenMetaverse;
34using Nini.Config;
35
36namespace OpenSim.Region.Physics.BulletSPlugin
37{
38public static class BSParam
39{
40 // Level of Detail values kept as float because that's what the Meshmerizer wants
41 public static float MeshLOD { get; private set; }
42 public static float MeshCircularLOD { get; private set; }
43 public static float MeshMegaPrimLOD { get; private set; }
44 public static float MeshMegaPrimThreshold { get; private set; }
45 public static float SculptLOD { get; private set; }
46
47 public static float MinimumObjectMass { get; private set; }
48 public static float MaximumObjectMass { get; private set; }
49 public static float MaxLinearVelocity { get; private set; }
50 public static float MaxAngularVelocity { get; private set; }
51 public static float MaxAddForceMagnitude { get; private set; }
52 public static float DensityScaleFactor { get; private set; }
53
54 public static float LinearDamping { get; private set; }
55 public static float AngularDamping { get; private set; }
56 public static float DeactivationTime { get; private set; }
57 public static float LinearSleepingThreshold { get; private set; }
58 public static float AngularSleepingThreshold { get; private set; }
59 public static float CcdMotionThreshold { get; private set; }
60 public static float CcdSweptSphereRadius { get; private set; }
61 public static float ContactProcessingThreshold { get; private set; }
62
63 public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed
64 public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
65 public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects
66 public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
67
68 public static float TerrainImplementation { get; private set; }
69 public static float TerrainFriction { get; private set; }
70 public static float TerrainHitFraction { get; private set; }
71 public static float TerrainRestitution { get; private set; }
72 public static float TerrainCollisionMargin { get; private set; }
73
74 public static float DefaultFriction;
75 public static float DefaultDensity;
76 public static float DefaultRestitution;
77 public static float CollisionMargin;
78 public static float Gravity;
79
80 // Physics Engine operation
81 public static float MaxPersistantManifoldPoolSize;
82 public static float MaxCollisionAlgorithmPoolSize;
83 public static float ShouldDisableContactPoolDynamicAllocation;
84 public static float ShouldForceUpdateAllAabbs;
85 public static float ShouldRandomizeSolverOrder;
86 public static float ShouldSplitSimulationIslands;
87 public static float ShouldEnableFrictionCaching;
88 public static float NumberOfSolverIterations;
89 public static bool UseSingleSidedMeshes { get { return UseSingleSidedMeshesF != ConfigurationParameters.numericFalse; } }
90 public static float UseSingleSidedMeshesF;
91 public static float GlobalContactBreakingThreshold;
92
93 // Avatar parameters
94 public static float AvatarFriction { get; private set; }
95 public static float AvatarStandingFriction { get; private set; }
96 public static float AvatarAlwaysRunFactor { get; private set; }
97 public static float AvatarDensity { get; private set; }
98 public static float AvatarRestitution { get; private set; }
99 public static float AvatarCapsuleWidth { get; private set; }
100 public static float AvatarCapsuleDepth { get; private set; }
101 public static float AvatarCapsuleHeight { get; private set; }
102 public static float AvatarContactProcessingThreshold { get; private set; }
103 public static float AvatarStepHeight { get; private set; }
104 public static float AvatarStepApproachFactor { get; private set; }
105 public static float AvatarStepForceFactor { get; private set; }
106
107 // Vehicle parameters
108 public static float VehicleMaxLinearVelocity { get; private set; }
109 public static float VehicleMaxLinearVelocitySq { get; private set; }
110 public static float VehicleMaxAngularVelocity { get; private set; }
111 public static float VehicleMaxAngularVelocitySq { get; private set; }
112 public static float VehicleAngularDamping { get; private set; }
113 public static float VehicleFriction { get; private set; }
114 public static float VehicleRestitution { get; private set; }
115 public static float VehicleLinearFactor { get; private set; }
116 public static Vector3 VehicleLinearFactorV { get; private set; }
117 public static float VehicleAngularFactor { get; private set; }
118 public static Vector3 VehicleAngularFactorV { get; private set; }
119 public static float VehicleGroundGravityFudge { get; private set; }
120 public static float VehicleDebuggingEnabled { get; private set; }
121
122 public static float LinksetImplementation { get; private set; }
123 public static float LinkConstraintUseFrameOffset { get; private set; }
124 public static float LinkConstraintEnableTransMotor { get; private set; }
125 public static float LinkConstraintTransMotorMaxVel { get; private set; }
126 public static float LinkConstraintTransMotorMaxForce { get; private set; }
127 public static float LinkConstraintERP { get; private set; }
128 public static float LinkConstraintCFM { get; private set; }
129 public static float LinkConstraintSolverIterations { get; private set; }
130
131 public static float PID_D { get; private set; } // derivative
132 public static float PID_P { get; private set; } // proportional
133
134 // Various constants that come from that other virtual world that shall not be named.
135 public const float MinGravityZ = -1f;
136 public const float MaxGravityZ = 28f;
137 public const float MinFriction = 0f;
138 public const float MaxFriction = 255f;
139 public const float MinDensity = 0.01f;
140 public const float MaxDensity = 22587f;
141 public const float MinRestitution = 0f;
142 public const float MaxRestitution = 1f;
143
144 // ===========================================================================
145 public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
146 public delegate float ParamGet(BSScene scene);
147 public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val);
148 public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val);
149
150 public struct ParameterDefn
151 {
152 public string name; // string name of the parameter
153 public string desc; // a short description of what the parameter means
154 public float defaultValue; // default value if not specified anywhere else
155 public ParamUser userParam; // get the value from the configuration file
156 public ParamGet getter; // return the current value stored for this parameter
157 public ParamSet setter; // set the current value for this parameter
158 public SetOnObject onObject; // set the value on an object in the physical domain
159 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
160 {
161 name = n;
162 desc = d;
163 defaultValue = v;
164 userParam = u;
165 getter = g;
166 setter = s;
167 onObject = null;
168 }
169 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o)
170 {
171 name = n;
172 desc = d;
173 defaultValue = v;
174 userParam = u;
175 getter = g;
176 setter = s;
177 onObject = o;
178 }
179 }
180
181 // List of all of the externally visible parameters.
182 // For each parameter, this table maps a text name to getter and setters.
183 // To add a new externally referencable/settable parameter, add the paramter storage
184 // location somewhere in the program and make an entry in this table with the
185 // getters and setters.
186 // It is easiest to find an existing definition and copy it.
187 // Parameter values are floats. Booleans are converted to a floating value.
188 //
189 // A ParameterDefn() takes the following parameters:
190 // -- the text name of the parameter. This is used for console input and ini file.
191 // -- a short text description of the parameter. This shows up in the console listing.
192 // -- a default value (float)
193 // -- a delegate for fetching the parameter from the ini file.
194 // Should handle fetching the right type from the ini file and converting it.
195 // -- a delegate for getting the value as a float
196 // -- a delegate for setting the value from a float
197 // -- an optional delegate to update the value in the world. Most often used to
198 // push the new value to an in-world object.
199 //
200 // The single letter parameters for the delegates are:
201 // s = BSScene
202 // o = BSPhysObject
203 // p = string parameter name
204 // l = localID of referenced object
205 // v = value (float)
206 // cf = parameter configuration class (for fetching values from ini file)
207 private static ParameterDefn[] ParameterDefinitions =
208 {
209 new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties",
210 ConfigurationParameters.numericTrue,
211 (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
212 (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); },
213 (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ),
214 new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects",
215 ConfigurationParameters.numericFalse,
216 (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
217 (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); },
218 (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ),
219 new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects",
220 ConfigurationParameters.numericTrue,
221 (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
222 (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); },
223 (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ),
224 new ParameterDefn("ShouldRemoveZeroWidthTriangles", "If true, remove degenerate triangles from meshes",
225 ConfigurationParameters.numericTrue,
226 (s,cf,p,v) => { ShouldRemoveZeroWidthTriangles = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
227 (s) => { return BSParam.NumericBool(ShouldRemoveZeroWidthTriangles); },
228 (s,p,l,v) => { ShouldRemoveZeroWidthTriangles = BSParam.BoolNumeric(v); } ),
229
230 new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
231 32f,
232 (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); },
233 (s) => { return MeshLOD; },
234 (s,p,l,v) => { MeshLOD = v; } ),
235 new ParameterDefn("MeshLevelOfDetailCircular", "Level of detail for prims with circular cuts or shapes",
236 32f,
237 (s,cf,p,v) => { MeshCircularLOD = (float)cf.GetInt(p, (int)v); },
238 (s) => { return MeshCircularLOD; },
239 (s,p,l,v) => { MeshCircularLOD = v; } ),
240 new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
241 10f,
242 (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
243 (s) => { return MeshMegaPrimThreshold; },
244 (s,p,l,v) => { MeshMegaPrimThreshold = v; } ),
245 new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
246 32f,
247 (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
248 (s) => { return MeshMegaPrimLOD; },
249 (s,p,l,v) => { MeshMegaPrimLOD = v; } ),
250 new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
251 32f,
252 (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); },
253 (s) => { return SculptLOD; },
254 (s,p,l,v) => { SculptLOD = v; } ),
255
256 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
257 10f,
258 (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); },
259 (s) => { return (float)s.m_maxSubSteps; },
260 (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ),
261 new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)",
262 1f / 60f,
263 (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); },
264 (s) => { return (float)s.m_fixedTimeStep; },
265 (s,p,l,v) => { s.m_fixedTimeStep = v; } ),
266 new ParameterDefn("NominalFrameRate", "The base frame rate we claim",
267 55f,
268 (s,cf,p,v) => { s.NominalFrameRate = cf.GetInt(p, (int)v); },
269 (s) => { return (float)s.NominalFrameRate; },
270 (s,p,l,v) => { s.NominalFrameRate = (int)v; } ),
271 new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame",
272 2048f,
273 (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); },
274 (s) => { return (float)s.m_maxCollisionsPerFrame; },
275 (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ),
276 new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame",
277 8000f,
278 (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); },
279 (s) => { return (float)s.m_maxUpdatesPerFrame; },
280 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
281
282 new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)",
283 0.0001f,
284 (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); },
285 (s) => { return MinimumObjectMass; },
286 (s,p,l,v) => { MinimumObjectMass = v; } ),
287 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
288 10000.01f,
289 (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); },
290 (s) => { return MaximumObjectMass; },
291 (s,p,l,v) => { MaximumObjectMass = v; } ),
292 new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object",
293 1000.0f,
294 (s,cf,p,v) => { MaxLinearVelocity = cf.GetFloat(p, v); },
295 (s) => { return MaxLinearVelocity; },
296 (s,p,l,v) => { MaxLinearVelocity = v; } ),
297 new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object",
298 1000.0f,
299 (s,cf,p,v) => { MaxAngularVelocity = cf.GetFloat(p, v); },
300 (s) => { return MaxAngularVelocity; },
301 (s,p,l,v) => { MaxAngularVelocity = v; } ),
302 // LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject
303 new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)",
304 20000.0f,
305 (s,cf,p,v) => { MaxAddForceMagnitude = cf.GetFloat(p, v); },
306 (s) => { return MaxAddForceMagnitude; },
307 (s,p,l,v) => { MaxAddForceMagnitude = v; } ),
308 // Density is passed around as 100kg/m3. This scales that to 1kg/m3.
309 new ParameterDefn("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)",
310 0.01f,
311 (s,cf,p,v) => { DensityScaleFactor = cf.GetFloat(p, v); },
312 (s) => { return DensityScaleFactor; },
313 (s,p,l,v) => { DensityScaleFactor = v; } ),
314
315 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
316 2200f,
317 (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); },
318 (s) => { return (float)PID_D; },
319 (s,p,l,v) => { PID_D = v; } ),
320 new ParameterDefn("PID_P", "Parameteric factor for motion smoothing",
321 900f,
322 (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); },
323 (s) => { return (float)PID_P; },
324 (s,p,l,v) => { PID_P = v; } ),
325
326 new ParameterDefn("DefaultFriction", "Friction factor used on new objects",
327 0.2f,
328 (s,cf,p,v) => { DefaultFriction = cf.GetFloat(p, v); },
329 (s) => { return DefaultFriction; },
330 (s,p,l,v) => { DefaultFriction = v; s.UnmanagedParams[0].defaultFriction = v; } ),
331 new ParameterDefn("DefaultDensity", "Density for new objects" ,
332 10.000006836f, // Aluminum g/cm3
333 (s,cf,p,v) => { DefaultDensity = cf.GetFloat(p, v); },
334 (s) => { return DefaultDensity; },
335 (s,p,l,v) => { DefaultDensity = v; s.UnmanagedParams[0].defaultDensity = v; } ),
336 new ParameterDefn("DefaultRestitution", "Bouncyness of an object" ,
337 0f,
338 (s,cf,p,v) => { DefaultRestitution = cf.GetFloat(p, v); },
339 (s) => { return DefaultRestitution; },
340 (s,p,l,v) => { DefaultRestitution = v; s.UnmanagedParams[0].defaultRestitution = v; } ),
341 new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)",
342 0.04f,
343 (s,cf,p,v) => { CollisionMargin = cf.GetFloat(p, v); },
344 (s) => { return CollisionMargin; },
345 (s,p,l,v) => { CollisionMargin = v; s.UnmanagedParams[0].collisionMargin = v; } ),
346 new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)",
347 -9.80665f,
348 (s,cf,p,v) => { Gravity = cf.GetFloat(p, v); },
349 (s) => { return Gravity; },
350 (s,p,l,v) => { Gravity = v; s.UnmanagedParams[0].gravity = v; },
351 (s,o,v) => { s.PE.SetGravity(o.PhysBody, new Vector3(0f,0f,v)); } ),
352
353
354 new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)",
355 0f,
356 (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); },
357 (s) => { return LinearDamping; },
358 (s,p,l,v) => { LinearDamping = v; },
359 (s,o,v) => { s.PE.SetDamping(o.PhysBody, v, AngularDamping); } ),
360 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
361 0f,
362 (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); },
363 (s) => { return AngularDamping; },
364 (s,p,l,v) => { AngularDamping = v; },
365 (s,o,v) => { s.PE.SetDamping(o.PhysBody, LinearDamping, v); } ),
366 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
367 0.2f,
368 (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); },
369 (s) => { return DeactivationTime; },
370 (s,p,l,v) => { DeactivationTime = v; },
371 (s,o,v) => { s.PE.SetDeactivationTime(o.PhysBody, v); } ),
372 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
373 0.8f,
374 (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); },
375 (s) => { return LinearSleepingThreshold; },
376 (s,p,l,v) => { LinearSleepingThreshold = v;},
377 (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ),
378 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
379 1.0f,
380 (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); },
381 (s) => { return AngularSleepingThreshold; },
382 (s,p,l,v) => { AngularSleepingThreshold = v;},
383 (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ),
384 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
385 0.0f, // set to zero to disable
386 (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); },
387 (s) => { return CcdMotionThreshold; },
388 (s,p,l,v) => { CcdMotionThreshold = v;},
389 (s,o,v) => { s.PE.SetCcdMotionThreshold(o.PhysBody, v); } ),
390 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
391 0.2f,
392 (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); },
393 (s) => { return CcdSweptSphereRadius; },
394 (s,p,l,v) => { CcdSweptSphereRadius = v;},
395 (s,o,v) => { s.PE.SetCcdSweptSphereRadius(o.PhysBody, v); } ),
396 new ParameterDefn("ContactProcessingThreshold", "Distance above which contacts can be discarded (0 means no discard)" ,
397 0.0f,
398 (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); },
399 (s) => { return ContactProcessingThreshold; },
400 (s,p,l,v) => { ContactProcessingThreshold = v;},
401 (s,o,v) => { s.PE.SetContactProcessingThreshold(o.PhysBody, v); } ),
402
403 new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
404 (float)BSTerrainPhys.TerrainImplementation.Mesh,
405 (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); },
406 (s) => { return TerrainImplementation; },
407 (s,p,l,v) => { TerrainImplementation = v; } ),
408 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
409 0.3f,
410 (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); },
411 (s) => { return TerrainFriction; },
412 (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ),
413 new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" ,
414 0.8f,
415 (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); },
416 (s) => { return TerrainHitFraction; },
417 (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ),
418 new ParameterDefn("TerrainRestitution", "Bouncyness" ,
419 0f,
420 (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); },
421 (s) => { return TerrainRestitution; },
422 (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ),
423 new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" ,
424 0.08f,
425 (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); },
426 (s) => { return TerrainCollisionMargin; },
427 (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ),
428
429 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
430 0.2f,
431 (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); },
432 (s) => { return AvatarFriction; },
433 (s,p,l,v) => { AvatarFriction = v; } ),
434 new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
435 0.95f,
436 (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); },
437 (s) => { return AvatarStandingFriction; },
438 (s,p,l,v) => { AvatarStandingFriction = v; } ),
439 new ParameterDefn("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run",
440 1.3f,
441 (s,cf,p,v) => { AvatarAlwaysRunFactor = cf.GetFloat(p, v); },
442 (s) => { return AvatarAlwaysRunFactor; },
443 (s,p,l,v) => { AvatarAlwaysRunFactor = v; } ),
444 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
445 3.5f,
446 (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); },
447 (s) => { return AvatarDensity; },
448 (s,p,l,v) => { AvatarDensity = v; } ),
449 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
450 0f,
451 (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); },
452 (s) => { return AvatarRestitution; },
453 (s,p,l,v) => { AvatarRestitution = v; } ),
454 new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule",
455 0.6f,
456 (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); },
457 (s) => { return AvatarCapsuleWidth; },
458 (s,p,l,v) => { AvatarCapsuleWidth = v; } ),
459 new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule",
460 0.45f,
461 (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); },
462 (s) => { return AvatarCapsuleDepth; },
463 (s,p,l,v) => { AvatarCapsuleDepth = v; } ),
464 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
465 1.5f,
466 (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); },
467 (s) => { return AvatarCapsuleHeight; },
468 (s,p,l,v) => { AvatarCapsuleHeight = v; } ),
469 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
470 0.1f,
471 (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); },
472 (s) => { return AvatarContactProcessingThreshold; },
473 (s,p,l,v) => { AvatarContactProcessingThreshold = v; } ),
474 new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction",
475 0.3f,
476 (s,cf,p,v) => { AvatarStepHeight = cf.GetFloat(p, v); },
477 (s) => { return AvatarStepHeight; },
478 (s,p,l,v) => { AvatarStepHeight = v; } ),
479 new ParameterDefn("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)",
480 0.6f,
481 (s,cf,p,v) => { AvatarStepApproachFactor = cf.GetFloat(p, v); },
482 (s) => { return AvatarStepApproachFactor; },
483 (s,p,l,v) => { AvatarStepApproachFactor = v; } ),
484 new ParameterDefn("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step",
485 2.0f,
486 (s,cf,p,v) => { AvatarStepForceFactor = cf.GetFloat(p, v); },
487 (s) => { return AvatarStepForceFactor; },
488 (s,p,l,v) => { AvatarStepForceFactor = v; } ),
489
490 new ParameterDefn("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle",
491 1000.0f,
492 (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); },
493 (s) => { return (float)VehicleMaxLinearVelocity; },
494 (s,p,l,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySq = v * v; } ),
495 new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle",
496 12.0f,
497 (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); },
498 (s) => { return (float)VehicleMaxAngularVelocity; },
499 (s,p,l,v) => { VehicleMaxAngularVelocity = v; VehicleMaxAngularVelocitySq = v * v; } ),
500 new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
501 0.0f,
502 (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
503 (s) => { return VehicleAngularDamping; },
504 (s,p,l,v) => { VehicleAngularDamping = v; } ),
505 new ParameterDefn("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (0.0 - 1.0)",
506 1.0f,
507 (s,cf,p,v) => { VehicleLinearFactor = cf.GetFloat(p, v); },
508 (s) => { return VehicleLinearFactor; },
509 (s,p,l,v) => { VehicleLinearFactor = v; VehicleLinearFactorV = new Vector3(v, v, v); } ),
510 new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (0.0 - 1.0)",
511 1.0f,
512 (s,cf,p,v) => { VehicleAngularFactor = cf.GetFloat(p, v); },
513 (s) => { return VehicleAngularFactor; },
514 (s,p,l,v) => { VehicleAngularFactor = v; VehicleAngularFactorV = new Vector3(v, v, v); } ),
515 new ParameterDefn("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)",
516 0.0f,
517 (s,cf,p,v) => { VehicleFriction = cf.GetFloat(p, v); },
518 (s) => { return VehicleFriction; },
519 (s,p,l,v) => { VehicleFriction = v; } ),
520 new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)",
521 0.0f,
522 (s,cf,p,v) => { VehicleRestitution = cf.GetFloat(p, v); },
523 (s) => { return VehicleRestitution; },
524 (s,p,l,v) => { VehicleRestitution = v; } ),
525 new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)",
526 0.2f,
527 (s,cf,p,v) => { VehicleGroundGravityFudge = cf.GetFloat(p, v); },
528 (s) => { return VehicleGroundGravityFudge; },
529 (s,p,l,v) => { VehicleGroundGravityFudge = v; } ),
530 new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging",
531 ConfigurationParameters.numericFalse,
532 (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
533 (s) => { return VehicleDebuggingEnabled; },
534 (s,p,l,v) => { VehicleDebuggingEnabled = v; } ),
535
536 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
537 0f,
538 (s,cf,p,v) => { MaxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
539 (s) => { return MaxPersistantManifoldPoolSize; },
540 (s,p,l,v) => { MaxPersistantManifoldPoolSize = v; s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ),
541 new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
542 0f,
543 (s,cf,p,v) => { MaxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); },
544 (s) => { return MaxCollisionAlgorithmPoolSize; },
545 (s,p,l,v) => { MaxCollisionAlgorithmPoolSize = v; s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ),
546 new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
547 ConfigurationParameters.numericFalse,
548 (s,cf,p,v) => { ShouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
549 (s) => { return ShouldDisableContactPoolDynamicAllocation; },
550 (s,p,l,v) => { ShouldDisableContactPoolDynamicAllocation = v; s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ),
551 new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
552 ConfigurationParameters.numericFalse,
553 (s,cf,p,v) => { ShouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
554 (s) => { return ShouldForceUpdateAllAabbs; },
555 (s,p,l,v) => { ShouldForceUpdateAllAabbs = v; s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ),
556 new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction",
557 ConfigurationParameters.numericTrue,
558 (s,cf,p,v) => { ShouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
559 (s) => { return ShouldRandomizeSolverOrder; },
560 (s,p,l,v) => { ShouldRandomizeSolverOrder = v; s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ),
561 new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands",
562 ConfigurationParameters.numericTrue,
563 (s,cf,p,v) => { ShouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
564 (s) => { return ShouldSplitSimulationIslands; },
565 (s,p,l,v) => { ShouldSplitSimulationIslands = v; s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ),
566 new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching",
567 ConfigurationParameters.numericTrue,
568 (s,cf,p,v) => { ShouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
569 (s) => { return ShouldEnableFrictionCaching; },
570 (s,p,l,v) => { ShouldEnableFrictionCaching = v; s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ),
571 new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)",
572 0f, // zero says use Bullet default
573 (s,cf,p,v) => { NumberOfSolverIterations = cf.GetFloat(p, v); },
574 (s) => { return NumberOfSolverIterations; },
575 (s,p,l,v) => { NumberOfSolverIterations = v; s.UnmanagedParams[0].numberOfSolverIterations = v; } ),
576 new ParameterDefn("UseSingleSidedMeshes", "Whether to compute collisions based on single sided meshes.",
577 ConfigurationParameters.numericTrue,
578 (s,cf,p,v) => { UseSingleSidedMeshesF = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
579 (s) => { return UseSingleSidedMeshesF; },
580 (s,p,l,v) => { UseSingleSidedMeshesF = v; s.UnmanagedParams[0].useSingleSidedMeshes = v; } ),
581 new ParameterDefn("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))",
582 0f,
583 (s,cf,p,v) => { GlobalContactBreakingThreshold = cf.GetFloat(p, v); },
584 (s) => { return GlobalContactBreakingThreshold; },
585 (s,p,l,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ),
586
587 new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
588 (float)BSLinkset.LinksetImplementation.Compound,
589 (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); },
590 (s) => { return LinksetImplementation; },
591 (s,p,l,v) => { LinksetImplementation = v; } ),
592 new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
593 ConfigurationParameters.numericFalse,
594 (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
595 (s) => { return LinkConstraintUseFrameOffset; },
596 (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ),
597 new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
598 ConfigurationParameters.numericTrue,
599 (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
600 (s) => { return LinkConstraintEnableTransMotor; },
601 (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ),
602 new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints",
603 5.0f,
604 (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); },
605 (s) => { return LinkConstraintTransMotorMaxVel; },
606 (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ),
607 new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints",
608 0.1f,
609 (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
610 (s) => { return LinkConstraintTransMotorMaxForce; },
611 (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ),
612 new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
613 0.1f,
614 (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); },
615 (s) => { return LinkConstraintCFM; },
616 (s,p,l,v) => { LinkConstraintCFM = v; } ),
617 new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
618 0.1f,
619 (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); },
620 (s) => { return LinkConstraintERP; },
621 (s,p,l,v) => { LinkConstraintERP = v; } ),
622 new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
623 40,
624 (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); },
625 (s) => { return LinkConstraintSolverIterations; },
626 (s,p,l,v) => { LinkConstraintSolverIterations = v; } ),
627
628 new ParameterDefn("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)",
629 0f,
630 (s,cf,p,v) => { s.PhysicsMetricDumpFrames = cf.GetFloat(p, (int)v); },
631 (s) => { return (float)s.PhysicsMetricDumpFrames; },
632 (s,p,l,v) => { s.PhysicsMetricDumpFrames = (int)v; } ),
633 new ParameterDefn("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool",
634 0f,
635 (s,cf,p,v) => { ; },
636 (s) => { return 0f; },
637 (s,p,l,v) => { BSParam.ResetBroadphasePoolTainted(s, v); } ),
638 new ParameterDefn("ResetConstraintSolver", "Setting this is any value resets the constraint solver",
639 0f,
640 (s,cf,p,v) => { ; },
641 (s) => { return 0f; },
642 (s,p,l,v) => { BSParam.ResetConstraintSolverTainted(s, v); } ),
643 };
644
645 // Convert a boolean to our numeric true and false values
646 public static float NumericBool(bool b)
647 {
648 return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse);
649 }
650
651 // Convert numeric true and false values to a boolean
652 public static bool BoolNumeric(float b)
653 {
654 return (b == ConfigurationParameters.numericTrue ? true : false);
655 }
656
657 // Search through the parameter definitions and return the matching
658 // ParameterDefn structure.
659 // Case does not matter as names are compared after converting to lower case.
660 // Returns 'false' if the parameter is not found.
661 internal static bool TryGetParameter(string paramName, out ParameterDefn defn)
662 {
663 bool ret = false;
664 ParameterDefn foundDefn = new ParameterDefn();
665 string pName = paramName.ToLower();
666
667 foreach (ParameterDefn parm in ParameterDefinitions)
668 {
669 if (pName == parm.name.ToLower())
670 {
671 foundDefn = parm;
672 ret = true;
673 break;
674 }
675 }
676 defn = foundDefn;
677 return ret;
678 }
679
680 // Pass through the settable parameters and set the default values
681 internal static void SetParameterDefaultValues(BSScene physicsScene)
682 {
683 foreach (ParameterDefn parm in ParameterDefinitions)
684 {
685 parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue);
686 }
687 }
688
689 // Get user set values out of the ini file.
690 internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg)
691 {
692 foreach (ParameterDefn parm in ParameterDefinitions)
693 {
694 parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue);
695 }
696 }
697
698 internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
699
700 // This creates an array in the correct format for returning the list of
701 // parameters. This is used by the 'list' option of the 'physics' command.
702 internal static void BuildParameterTable()
703 {
704 if (SettableParameters.Length < ParameterDefinitions.Length)
705 {
706 List<PhysParameterEntry> entries = new List<PhysParameterEntry>();
707 for (int ii = 0; ii < ParameterDefinitions.Length; ii++)
708 {
709 ParameterDefn pd = ParameterDefinitions[ii];
710 entries.Add(new PhysParameterEntry(pd.name, pd.desc));
711 }
712
713 // make the list alphabetical for estetic reasons
714 entries.Sort((ppe1, ppe2) => { return ppe1.name.CompareTo(ppe2.name); });
715
716 SettableParameters = entries.ToArray();
717 }
718 }
719
720 private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v)
721 {
722 BSScene physScene = pPhysScene;
723 physScene.TaintedObject("BSParam.ResetBroadphasePoolTainted", delegate()
724 {
725 physScene.PE.ResetBroadphasePool(physScene.World);
726 });
727 }
728
729 private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v)
730 {
731 BSScene physScene = pPhysScene;
732 physScene.TaintedObject("BSParam.ResetConstraintSolver", delegate()
733 {
734 physScene.PE.ResetConstraintSolver(physScene.World);
735 });
736 }
737}
738}