aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs
diff options
context:
space:
mode:
authorteravus2012-12-23 15:21:25 -0500
committerteravus2012-12-23 15:21:25 -0500
commit92e4f9f412046f8f7926c99c9e56c3a8b6b2edbf (patch)
treeeabcbb758a7512222e84cb51b51b6822cdbf561b /OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs
parentRevert "Whitespace change to trigger bot" (diff)
downloadopensim-SC_OLD-92e4f9f412046f8f7926c99c9e56c3a8b6b2edbf.zip
opensim-SC_OLD-92e4f9f412046f8f7926c99c9e56c3a8b6b2edbf.tar.gz
opensim-SC_OLD-92e4f9f412046f8f7926c99c9e56c3a8b6b2edbf.tar.bz2
opensim-SC_OLD-92e4f9f412046f8f7926c99c9e56c3a8b6b2edbf.tar.xz
* Initial commit of BulletSimN (BulletSNPlugin). Purely C# implementation of BulletSim. This is designed to be /as close as possible/ to the BulletSim plugin while still being entirely in the managed space to make keeping it up to date easy as possible (no thinking work). This implementation is /slower/ then the c++ version just because it's fully managed, so it's not appropriate for huge sims, but it will run small ones OK. At the moment, it supports all known features of BulletSim. Think of it like.. POS but everything works. To use this plugin, set the physics plugin to BulletSimN.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs559
1 files changed, 559 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs
new file mode 100644
index 0000000..0bb1674
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs
@@ -0,0 +1,559 @@
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.BulletSNPlugin
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
49 public static float LinearDamping { get; private set; }
50 public static float AngularDamping { get; private set; }
51 public static float DeactivationTime { get; private set; }
52 public static float LinearSleepingThreshold { get; private set; }
53 public static float AngularSleepingThreshold { get; private set; }
54 public static float CcdMotionThreshold { get; private set; }
55 public static float CcdSweptSphereRadius { get; private set; }
56 public static float ContactProcessingThreshold { get; private set; }
57
58 public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed
59 public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
60 public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects
61
62 public static float TerrainImplementation { get; private set; }
63 public static float TerrainFriction { get; private set; }
64 public static float TerrainHitFraction { get; private set; }
65 public static float TerrainRestitution { get; private set; }
66 public static float TerrainCollisionMargin { get; private set; }
67
68 // Avatar parameters
69 public static float AvatarFriction { get; private set; }
70 public static float AvatarStandingFriction { get; private set; }
71 public static float AvatarDensity { get; private set; }
72 public static float AvatarRestitution { get; private set; }
73 public static float AvatarCapsuleWidth { get; private set; }
74 public static float AvatarCapsuleDepth { get; private set; }
75 public static float AvatarCapsuleHeight { get; private set; }
76 public static float AvatarContactProcessingThreshold { get; private set; }
77
78 public static float VehicleAngularDamping { get; private set; }
79
80 public static float LinksetImplementation { get; private set; }
81 public static float LinkConstraintUseFrameOffset { get; private set; }
82 public static float LinkConstraintEnableTransMotor { get; private set; }
83 public static float LinkConstraintTransMotorMaxVel { get; private set; }
84 public static float LinkConstraintTransMotorMaxForce { get; private set; }
85 public static float LinkConstraintERP { get; private set; }
86 public static float LinkConstraintCFM { get; private set; }
87 public static float LinkConstraintSolverIterations { get; private set; }
88
89 public static float PID_D { get; private set; } // derivative
90 public static float PID_P { get; private set; } // proportional
91
92 public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
93 public delegate float ParamGet(BSScene scene);
94 public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val);
95 public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val);
96
97 public struct ParameterDefn
98 {
99 public string name; // string name of the parameter
100 public string desc; // a short description of what the parameter means
101 public float defaultValue; // default value if not specified anywhere else
102 public ParamUser userParam; // get the value from the configuration file
103 public ParamGet getter; // return the current value stored for this parameter
104 public ParamSet setter; // set the current value for this parameter
105 public SetOnObject onObject; // set the value on an object in the physical domain
106 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
107 {
108 name = n;
109 desc = d;
110 defaultValue = v;
111 userParam = u;
112 getter = g;
113 setter = s;
114 onObject = null;
115 }
116 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o)
117 {
118 name = n;
119 desc = d;
120 defaultValue = v;
121 userParam = u;
122 getter = g;
123 setter = s;
124 onObject = o;
125 }
126 }
127
128 // List of all of the externally visible parameters.
129 // For each parameter, this table maps a text name to getter and setters.
130 // To add a new externally referencable/settable parameter, add the paramter storage
131 // location somewhere in the program and make an entry in this table with the
132 // getters and setters.
133 // It is easiest to find an existing definition and copy it.
134 // Parameter values are floats. Booleans are converted to a floating value.
135 //
136 // A ParameterDefn() takes the following parameters:
137 // -- the text name of the parameter. This is used for console input and ini file.
138 // -- a short text description of the parameter. This shows up in the console listing.
139 // -- a default value (float)
140 // -- a delegate for fetching the parameter from the ini file.
141 // Should handle fetching the right type from the ini file and converting it.
142 // -- a delegate for getting the value as a float
143 // -- a delegate for setting the value from a float
144 // -- an optional delegate to update the value in the world. Most often used to
145 // push the new value to an in-world object.
146 //
147 // The single letter parameters for the delegates are:
148 // s = BSScene
149 // o = BSPhysObject
150 // p = string parameter name
151 // l = localID of referenced object
152 // v = value (float)
153 // cf = parameter configuration class (for fetching values from ini file)
154 private static ParameterDefn[] ParameterDefinitions =
155 {
156 new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties",
157 ConfigurationParameters.numericTrue,
158 (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
159 (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); },
160 (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ),
161 new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects",
162 ConfigurationParameters.numericFalse,
163 (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
164 (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); },
165 (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ),
166 new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects",
167 ConfigurationParameters.numericTrue,
168 (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
169 (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); },
170 (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ),
171
172 new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
173 8f,
174 (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); },
175 (s) => { return MeshLOD; },
176 (s,p,l,v) => { MeshLOD = v; } ),
177 new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
178 16f,
179 (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
180 (s) => { return MeshMegaPrimLOD; },
181 (s,p,l,v) => { MeshMegaPrimLOD = v; } ),
182 new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
183 10f,
184 (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
185 (s) => { return MeshMegaPrimThreshold; },
186 (s,p,l,v) => { MeshMegaPrimThreshold = v; } ),
187 new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
188 32f,
189 (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); },
190 (s) => { return SculptLOD; },
191 (s,p,l,v) => { SculptLOD = v; } ),
192
193 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
194 10f,
195 (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); },
196 (s) => { return (float)s.m_maxSubSteps; },
197 (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ),
198 new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)",
199 1f / 60f,
200 (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); },
201 (s) => { return (float)s.m_fixedTimeStep; },
202 (s,p,l,v) => { s.m_fixedTimeStep = v; } ),
203 new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame",
204 2048f,
205 (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); },
206 (s) => { return (float)s.m_maxCollisionsPerFrame; },
207 (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ),
208 new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame",
209 8000f,
210 (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); },
211 (s) => { return (float)s.m_maxUpdatesPerFrame; },
212 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
213 new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step",
214 500f,
215 (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); },
216 (s) => { return (float)s.m_taintsToProcessPerStep; },
217 (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ),
218 new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)",
219 0.0001f,
220 (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); },
221 (s) => { return (float)MinimumObjectMass; },
222 (s,p,l,v) => { MinimumObjectMass = v; } ),
223 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
224 10000.01f,
225 (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); },
226 (s) => { return (float)MaximumObjectMass; },
227 (s,p,l,v) => { MaximumObjectMass = v; } ),
228
229 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
230 2200f,
231 (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); },
232 (s) => { return (float)PID_D; },
233 (s,p,l,v) => { PID_D = v; } ),
234 new ParameterDefn("PID_P", "Parameteric factor for motion smoothing",
235 900f,
236 (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); },
237 (s) => { return (float)PID_P; },
238 (s,p,l,v) => { PID_P = v; } ),
239
240 new ParameterDefn("DefaultFriction", "Friction factor used on new objects",
241 0.2f,
242 (s,cf,p,v) => { s.UnmanagedParams[0].defaultFriction = cf.GetFloat(p, v); },
243 (s) => { return s.UnmanagedParams[0].defaultFriction; },
244 (s,p,l,v) => { s.UnmanagedParams[0].defaultFriction = v; } ),
245 new ParameterDefn("DefaultDensity", "Density for new objects" ,
246 10.000006836f, // Aluminum g/cm3
247 (s,cf,p,v) => { s.UnmanagedParams[0].defaultDensity = cf.GetFloat(p, v); },
248 (s) => { return s.UnmanagedParams[0].defaultDensity; },
249 (s,p,l,v) => { s.UnmanagedParams[0].defaultDensity = v; } ),
250 new ParameterDefn("DefaultRestitution", "Bouncyness of an object" ,
251 0f,
252 (s,cf,p,v) => { s.UnmanagedParams[0].defaultRestitution = cf.GetFloat(p, v); },
253 (s) => { return s.UnmanagedParams[0].defaultRestitution; },
254 (s,p,l,v) => { s.UnmanagedParams[0].defaultRestitution = v; } ),
255 new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)",
256 0.04f,
257 (s,cf,p,v) => { s.UnmanagedParams[0].collisionMargin = cf.GetFloat(p, v); },
258 (s) => { return s.UnmanagedParams[0].collisionMargin; },
259 (s,p,l,v) => { s.UnmanagedParams[0].collisionMargin = v; } ),
260 new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)",
261 -9.80665f,
262 (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); },
263 (s) => { return s.UnmanagedParams[0].gravity; },
264 (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); },
265 (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ),
266
267
268 new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)",
269 0f,
270 (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); },
271 (s) => { return LinearDamping; },
272 (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); },
273 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ),
274 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
275 0f,
276 (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); },
277 (s) => { return AngularDamping; },
278 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); },
279 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ),
280 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
281 0.2f,
282 (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); },
283 (s) => { return DeactivationTime; },
284 (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); },
285 (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ),
286 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
287 0.8f,
288 (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); },
289 (s) => { return LinearSleepingThreshold; },
290 (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); },
291 (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
292 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
293 1.0f,
294 (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); },
295 (s) => { return AngularSleepingThreshold; },
296 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); },
297 (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
298 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
299 0f, // set to zero to disable
300 (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); },
301 (s) => { return CcdMotionThreshold; },
302 (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); },
303 (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ),
304 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
305 0f,
306 (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); },
307 (s) => { return CcdSweptSphereRadius; },
308 (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); },
309 (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ),
310 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
311 0.1f,
312 (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); },
313 (s) => { return ContactProcessingThreshold; },
314 (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); },
315 (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ),
316
317 new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
318 (float)BSTerrainPhys.TerrainImplementation.Mesh,
319 (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); },
320 (s) => { return TerrainImplementation; },
321 (s,p,l,v) => { TerrainImplementation = v; } ),
322 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
323 0.3f,
324 (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); },
325 (s) => { return TerrainFriction; },
326 (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ),
327 new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" ,
328 0.8f,
329 (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); },
330 (s) => { return TerrainHitFraction; },
331 (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ),
332 new ParameterDefn("TerrainRestitution", "Bouncyness" ,
333 0f,
334 (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); },
335 (s) => { return TerrainRestitution; },
336 (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ),
337 new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" ,
338 0.04f,
339 (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); },
340 (s) => { return TerrainCollisionMargin; },
341 (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ),
342
343 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
344 0.2f,
345 (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); },
346 (s) => { return AvatarFriction; },
347 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarFriction=x;}, p, l, v); } ),
348 new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
349 10.0f,
350 (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); },
351 (s) => { return AvatarStandingFriction; },
352 (s,p,l,v) => { AvatarStandingFriction = v; } ),
353 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
354 60f,
355 (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); },
356 (s) => { return AvatarDensity; },
357 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ),
358 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
359 0f,
360 (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); },
361 (s) => { return AvatarRestitution; },
362 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarRestitution=x;}, p, l, v); } ),
363 new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule",
364 0.6f,
365 (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); },
366 (s) => { return AvatarCapsuleWidth; },
367 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleWidth=x;}, p, l, v); } ),
368 new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule",
369 0.45f,
370 (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); },
371 (s) => { return AvatarCapsuleDepth; },
372 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleDepth=x;}, p, l, v); } ),
373 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
374 1.5f,
375 (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); },
376 (s) => { return AvatarCapsuleHeight; },
377 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleHeight=x;}, p, l, v); } ),
378 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
379 0.1f,
380 (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); },
381 (s) => { return AvatarContactProcessingThreshold; },
382 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ),
383
384 new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
385 0.95f,
386 (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
387 (s) => { return VehicleAngularDamping; },
388 (s,p,l,v) => { VehicleAngularDamping = v; } ),
389
390 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
391 0f,
392 (s,cf,p,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
393 (s) => { return s.UnmanagedParams[0].maxPersistantManifoldPoolSize; },
394 (s,p,l,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ),
395 new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
396 0f,
397 (s,cf,p,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); },
398 (s) => { return s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize; },
399 (s,p,l,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ),
400 new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
401 ConfigurationParameters.numericFalse,
402 (s,cf,p,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
403 (s) => { return s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation; },
404 (s,p,l,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ),
405 new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
406 ConfigurationParameters.numericFalse,
407 (s,cf,p,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
408 (s) => { return s.UnmanagedParams[0].shouldForceUpdateAllAabbs; },
409 (s,p,l,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ),
410 new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction",
411 ConfigurationParameters.numericTrue,
412 (s,cf,p,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
413 (s) => { return s.UnmanagedParams[0].shouldRandomizeSolverOrder; },
414 (s,p,l,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ),
415 new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands",
416 ConfigurationParameters.numericTrue,
417 (s,cf,p,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
418 (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; },
419 (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ),
420 new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching",
421 ConfigurationParameters.numericFalse,
422 (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
423 (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; },
424 (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ),
425 new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)",
426 0f, // zero says use Bullet default
427 (s,cf,p,v) => { s.UnmanagedParams[0].numberOfSolverIterations = cf.GetFloat(p, v); },
428 (s) => { return s.UnmanagedParams[0].numberOfSolverIterations; },
429 (s,p,l,v) => { s.UnmanagedParams[0].numberOfSolverIterations = v; } ),
430
431 new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
432 (float)BSLinkset.LinksetImplementation.Compound,
433 (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); },
434 (s) => { return LinksetImplementation; },
435 (s,p,l,v) => { LinksetImplementation = v; } ),
436 new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
437 ConfigurationParameters.numericFalse,
438 (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
439 (s) => { return LinkConstraintUseFrameOffset; },
440 (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ),
441 new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
442 ConfigurationParameters.numericTrue,
443 (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
444 (s) => { return LinkConstraintEnableTransMotor; },
445 (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ),
446 new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints",
447 5.0f,
448 (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); },
449 (s) => { return LinkConstraintTransMotorMaxVel; },
450 (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ),
451 new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints",
452 0.1f,
453 (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
454 (s) => { return LinkConstraintTransMotorMaxForce; },
455 (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ),
456 new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
457 0.1f,
458 (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); },
459 (s) => { return LinkConstraintCFM; },
460 (s,p,l,v) => { LinkConstraintCFM = v; } ),
461 new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
462 0.1f,
463 (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); },
464 (s) => { return LinkConstraintERP; },
465 (s,p,l,v) => { LinkConstraintERP = v; } ),
466 new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
467 40,
468 (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); },
469 (s) => { return LinkConstraintSolverIterations; },
470 (s,p,l,v) => { LinkConstraintSolverIterations = v; } ),
471
472 new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)",
473 0f,
474 (s,cf,p,v) => { s.UnmanagedParams[0].physicsLoggingFrames = cf.GetInt(p, (int)v); },
475 (s) => { return (float)s.UnmanagedParams[0].physicsLoggingFrames; },
476 (s,p,l,v) => { s.UnmanagedParams[0].physicsLoggingFrames = (int)v; } ),
477 };
478
479 // Convert a boolean to our numeric true and false values
480 public static float NumericBool(bool b)
481 {
482 return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse);
483 }
484
485 // Convert numeric true and false values to a boolean
486 public static bool BoolNumeric(float b)
487 {
488 return (b == ConfigurationParameters.numericTrue ? true : false);
489 }
490
491 // Search through the parameter definitions and return the matching
492 // ParameterDefn structure.
493 // Case does not matter as names are compared after converting to lower case.
494 // Returns 'false' if the parameter is not found.
495 internal static bool TryGetParameter(string paramName, out ParameterDefn defn)
496 {
497 bool ret = false;
498 ParameterDefn foundDefn = new ParameterDefn();
499 string pName = paramName.ToLower();
500
501 foreach (ParameterDefn parm in ParameterDefinitions)
502 {
503 if (pName == parm.name.ToLower())
504 {
505 foundDefn = parm;
506 ret = true;
507 break;
508 }
509 }
510 defn = foundDefn;
511 return ret;
512 }
513
514 // Pass through the settable parameters and set the default values
515 internal static void SetParameterDefaultValues(BSScene physicsScene)
516 {
517 foreach (ParameterDefn parm in ParameterDefinitions)
518 {
519 parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue);
520 }
521 }
522
523 // Get user set values out of the ini file.
524 internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg)
525 {
526 foreach (ParameterDefn parm in ParameterDefinitions)
527 {
528 parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue);
529 }
530 }
531
532 internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
533
534 // This creates an array in the correct format for returning the list of
535 // parameters. This is used by the 'list' option of the 'physics' command.
536 internal static void BuildParameterTable()
537 {
538 if (SettableParameters.Length < ParameterDefinitions.Length)
539 {
540 List<PhysParameterEntry> entries = new List<PhysParameterEntry>();
541 for (int ii = 0; ii < ParameterDefinitions.Length; ii++)
542 {
543 ParameterDefn pd = ParameterDefinitions[ii];
544 entries.Add(new PhysParameterEntry(pd.name, pd.desc));
545 }
546
547 // make the list in alphabetical order for estetic reasons
548 entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2)
549 {
550 return ppe1.name.CompareTo(ppe2.name);
551 });
552
553 SettableParameters = entries.ToArray();
554 }
555 }
556
557
558}
559}