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