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