opensim-development – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | eva | 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 | */ |
||
27 | using System; |
||
28 | using System.Collections.Generic; |
||
29 | using System.Reflection; |
||
30 | using System.Text; |
||
31 | |||
32 | using OpenSim.Region.Physics.Manager; |
||
33 | |||
34 | using OpenMetaverse; |
||
35 | using Nini.Config; |
||
36 | |||
37 | namespace OpenSim.Region.Physics.BulletSPlugin |
||
38 | { |
||
39 | public static class BSParam |
||
40 | { |
||
41 | private static string LogHeader = "[BULLETSIM PARAMETERS]"; |
||
42 | |||
43 | // Tuning notes: |
||
44 | // From: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=6575 |
||
45 | // Contact points can be added even if the distance is positive. The constraint solver can deal with |
||
46 | // contacts with positive distances as well as negative (penetration). Contact points are discarded |
||
47 | // if the distance exceeds a certain threshold. |
||
48 | // Bullet has a contact processing threshold and a contact breaking threshold. |
||
49 | // If the distance is larger than the contact breaking threshold, it will be removed after one frame. |
||
50 | // If the distance is larger than the contact processing threshold, the constraint solver will ignore it. |
||
51 | |||
52 | // This is separate/independent from the collision margin. The collision margin increases the object a bit |
||
53 | // to improve collision detection performance and accuracy. |
||
54 | // =================== |
||
55 | // From: |
||
56 | |||
57 | public static bool UseSeparatePhysicsThread { get; private set; } |
||
58 | public static float PhysicsTimeStep { get; private set; } |
||
59 | |||
60 | // Level of Detail values kept as float because that's what the Meshmerizer wants |
||
61 | public static float MeshLOD { get; private set; } |
||
62 | public static float MeshCircularLOD { get; private set; } |
||
63 | public static float MeshMegaPrimLOD { get; private set; } |
||
64 | public static float MeshMegaPrimThreshold { get; private set; } |
||
65 | public static float SculptLOD { get; private set; } |
||
66 | |||
67 | public static int CrossingFailuresBeforeOutOfBounds { get; private set; } |
||
68 | public static float UpdateVelocityChangeThreshold { get; private set; } |
||
69 | |||
70 | public static float MinimumObjectMass { get; private set; } |
||
71 | public static float MaximumObjectMass { get; private set; } |
||
72 | public static float MaxLinearVelocity { get; private set; } |
||
73 | public static float MaxLinearVelocitySquared { get; private set; } |
||
74 | public static float MaxAngularVelocity { get; private set; } |
||
75 | public static float MaxAngularVelocitySquared { get; private set; } |
||
76 | public static float MaxAddForceMagnitude { get; private set; } |
||
77 | public static float MaxAddForceMagnitudeSquared { get; private set; } |
||
78 | public static float DensityScaleFactor { get; private set; } |
||
79 | |||
80 | public static float LinearDamping { get; private set; } |
||
81 | public static float AngularDamping { get; private set; } |
||
82 | public static float DeactivationTime { get; private set; } |
||
83 | public static float LinearSleepingThreshold { get; private set; } |
||
84 | public static float AngularSleepingThreshold { get; private set; } |
||
85 | public static float CcdMotionThreshold { get; private set; } |
||
86 | public static float CcdSweptSphereRadius { get; private set; } |
||
87 | public static float ContactProcessingThreshold { get; private set; } |
||
88 | |||
89 | public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed |
||
90 | public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes |
||
91 | public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects |
||
92 | public static bool ShouldRemoveZeroWidthTriangles { get; private set; } |
||
93 | public static bool ShouldUseBulletHACD { get; set; } |
||
94 | public static bool ShouldUseSingleConvexHullForPrims { get; set; } |
||
95 | public static bool ShouldUseGImpactShapeForPrims { get; set; } |
||
96 | public static bool ShouldUseAssetHulls { get; set; } |
||
97 | |||
98 | public static float TerrainImplementation { get; set; } |
||
99 | public static int TerrainMeshMagnification { get; private set; } |
||
100 | public static float TerrainFriction { get; private set; } |
||
101 | public static float TerrainHitFraction { get; private set; } |
||
102 | public static float TerrainRestitution { get; private set; } |
||
103 | public static float TerrainContactProcessingThreshold { get; private set; } |
||
104 | public static float TerrainCollisionMargin { get; private set; } |
||
105 | |||
106 | public static float DefaultFriction { get; private set; } |
||
107 | public static float DefaultDensity { get; private set; } |
||
108 | public static float DefaultRestitution { get; private set; } |
||
109 | public static float CollisionMargin { get; private set; } |
||
110 | public static float Gravity { get; private set; } |
||
111 | |||
112 | // Physics Engine operation |
||
113 | public static float MaxPersistantManifoldPoolSize { get; private set; } |
||
114 | public static float MaxCollisionAlgorithmPoolSize { get; private set; } |
||
115 | public static bool ShouldDisableContactPoolDynamicAllocation { get; private set; } |
||
116 | public static bool ShouldForceUpdateAllAabbs { get; private set; } |
||
117 | public static bool ShouldRandomizeSolverOrder { get; private set; } |
||
118 | public static bool ShouldSplitSimulationIslands { get; private set; } |
||
119 | public static bool ShouldEnableFrictionCaching { get; private set; } |
||
120 | public static float NumberOfSolverIterations { get; private set; } |
||
121 | public static bool UseSingleSidedMeshes { get; private set; } |
||
122 | public static float GlobalContactBreakingThreshold { get; private set; } |
||
123 | public static float PhysicsUnmanLoggingFrames { get; private set; } |
||
124 | |||
125 | // Avatar parameters |
||
126 | public static float AvatarFriction { get; private set; } |
||
127 | public static float AvatarStandingFriction { get; private set; } |
||
128 | public static float AvatarAlwaysRunFactor { get; private set; } |
||
129 | public static float AvatarDensity { get; private set; } |
||
130 | public static float AvatarRestitution { get; private set; } |
||
131 | public static float AvatarCapsuleWidth { get; private set; } |
||
132 | public static float AvatarCapsuleDepth { get; private set; } |
||
133 | public static float AvatarCapsuleHeight { get; private set; } |
||
134 | public static float AvatarHeightLowFudge { get; private set; } |
||
135 | public static float AvatarHeightMidFudge { get; private set; } |
||
136 | public static float AvatarHeightHighFudge { get; private set; } |
||
137 | public static float AvatarContactProcessingThreshold { get; private set; } |
||
138 | public static float AvatarStopZeroThreshold { get; private set; } |
||
139 | public static int AvatarJumpFrames { get; private set; } |
||
140 | public static float AvatarBelowGroundUpCorrectionMeters { get; private set; } |
||
141 | public static float AvatarStepHeight { get; private set; } |
||
142 | public static float AvatarStepApproachFactor { get; private set; } |
||
143 | public static float AvatarStepForceFactor { get; private set; } |
||
144 | public static float AvatarStepUpCorrectionFactor { get; private set; } |
||
145 | public static int AvatarStepSmoothingSteps { get; private set; } |
||
146 | |||
147 | // Vehicle parameters |
||
148 | public static float VehicleMaxLinearVelocity { get; private set; } |
||
149 | public static float VehicleMaxLinearVelocitySquared { get; private set; } |
||
150 | public static float VehicleMaxAngularVelocity { get; private set; } |
||
151 | public static float VehicleMaxAngularVelocitySq { get; private set; } |
||
152 | public static float VehicleAngularDamping { get; private set; } |
||
153 | public static float VehicleFriction { get; private set; } |
||
154 | public static float VehicleRestitution { get; private set; } |
||
155 | public static Vector3 VehicleLinearFactor { get; private set; } |
||
156 | public static Vector3 VehicleAngularFactor { get; private set; } |
||
157 | public static Vector3 VehicleInertiaFactor { get; private set; } |
||
158 | public static float VehicleGroundGravityFudge { get; private set; } |
||
159 | public static float VehicleAngularBankingTimescaleFudge { get; private set; } |
||
160 | public static bool VehicleEnableLinearDeflection { get; private set; } |
||
161 | public static bool VehicleLinearDeflectionNotCollidingNoZ { get; private set; } |
||
162 | public static bool VehicleEnableAngularVerticalAttraction { get; private set; } |
||
163 | public static int VehicleAngularVerticalAttractionAlgorithm { get; private set; } |
||
164 | public static bool VehicleEnableAngularDeflection { get; private set; } |
||
165 | public static bool VehicleEnableAngularBanking { get; private set; } |
||
166 | |||
167 | // Convex Hulls |
||
168 | public static int CSHullMaxDepthSplit { get; private set; } |
||
169 | public static int CSHullMaxDepthSplitForSimpleShapes { get; private set; } |
||
170 | public static float CSHullConcavityThresholdPercent { get; private set; } |
||
171 | public static float CSHullVolumeConservationThresholdPercent { get; private set; } |
||
172 | public static int CSHullMaxVertices { get; private set; } |
||
173 | public static float CSHullMaxSkinWidth { get; private set; } |
||
174 | public static float BHullMaxVerticesPerHull { get; private set; } // 100 |
||
175 | public static float BHullMinClusters { get; private set; } // 2 |
||
176 | public static float BHullCompacityWeight { get; private set; } // 0.1 |
||
177 | public static float BHullVolumeWeight { get; private set; } // 0.0 |
||
178 | public static float BHullConcavity { get; private set; } // 100 |
||
179 | public static bool BHullAddExtraDistPoints { get; private set; } // false |
||
180 | public static bool BHullAddNeighboursDistPoints { get; private set; } // false |
||
181 | public static bool BHullAddFacesPoints { get; private set; } // false |
||
182 | public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false |
||
183 | |||
184 | // Linkset implementation parameters |
||
185 | public static float LinksetImplementation { get; private set; } |
||
186 | public static bool LinksetOffsetCenterOfMass { get; private set; } |
||
187 | public static bool LinkConstraintUseFrameOffset { get; private set; } |
||
188 | public static bool LinkConstraintEnableTransMotor { get; private set; } |
||
189 | public static float LinkConstraintTransMotorMaxVel { get; private set; } |
||
190 | public static float LinkConstraintTransMotorMaxForce { get; private set; } |
||
191 | public static float LinkConstraintERP { get; private set; } |
||
192 | public static float LinkConstraintCFM { get; private set; } |
||
193 | public static float LinkConstraintSolverIterations { get; private set; } |
||
194 | |||
195 | public static float PID_D { get; private set; } // derivative |
||
196 | public static float PID_P { get; private set; } // proportional |
||
197 | |||
198 | // Various constants that come from that other virtual world that shall not be named. |
||
199 | public const float MinGravityZ = -1f; |
||
200 | public const float MaxGravityZ = 28f; |
||
201 | public const float MinFriction = 0f; |
||
202 | public const float MaxFriction = 255f; |
||
203 | public const float MinDensity = 0.01f; |
||
204 | public const float MaxDensity = 22587f; |
||
205 | public const float MinRestitution = 0f; |
||
206 | public const float MaxRestitution = 1f; |
||
207 | |||
208 | // ===================================================================================== |
||
209 | // ===================================================================================== |
||
210 | |||
211 | // Base parameter definition that gets and sets parameter values via a string |
||
212 | public abstract class ParameterDefnBase |
||
213 | { |
||
214 | public string name; // string name of the parameter |
||
215 | public string desc; // a short description of what the parameter means |
||
216 | public ParameterDefnBase(string pName, string pDesc) |
||
217 | { |
||
218 | name = pName; |
||
219 | desc = pDesc; |
||
220 | } |
||
221 | // Set the parameter value to the default |
||
222 | public abstract void AssignDefault(BSScene s); |
||
223 | // Get the value as a string |
||
224 | public abstract string GetValue(BSScene s); |
||
225 | // Set the value to this string value |
||
226 | public abstract void SetValue(BSScene s, string valAsString); |
||
227 | // set the value on a particular object (usually sets in physics engine) |
||
228 | public abstract void SetOnObject(BSScene s, BSPhysObject obj); |
||
229 | public abstract bool HasSetOnObject { get; } |
||
230 | } |
||
231 | |||
232 | // Specific parameter definition for a parameter of a specific type. |
||
233 | public delegate T PGetValue<T>(BSScene s); |
||
234 | public delegate void PSetValue<T>(BSScene s, T val); |
||
235 | public delegate void PSetOnObject<T>(BSScene scene, BSPhysObject obj); |
||
236 | public sealed class ParameterDefn<T> : ParameterDefnBase |
||
237 | { |
||
238 | private T defaultValue; |
||
239 | private PSetValue<T> setter; |
||
240 | private PGetValue<T> getter; |
||
241 | private PSetOnObject<T> objectSet; |
||
242 | public ParameterDefn(string pName, string pDesc, T pDefault, PGetValue<T> pGetter, PSetValue<T> pSetter) |
||
243 | : base(pName, pDesc) |
||
244 | { |
||
245 | defaultValue = pDefault; |
||
246 | setter = pSetter; |
||
247 | getter = pGetter; |
||
248 | objectSet = null; |
||
249 | } |
||
250 | public ParameterDefn(string pName, string pDesc, T pDefault, PGetValue<T> pGetter, PSetValue<T> pSetter, PSetOnObject<T> pObjSetter) |
||
251 | : base(pName, pDesc) |
||
252 | { |
||
253 | defaultValue = pDefault; |
||
254 | setter = pSetter; |
||
255 | getter = pGetter; |
||
256 | objectSet = pObjSetter; |
||
257 | } |
||
258 | // Simple parameter variable where property name is the same as the INI file name |
||
259 | // and the value is only a simple get and set. |
||
260 | public ParameterDefn(string pName, string pDesc, T pDefault) |
||
261 | : base(pName, pDesc) |
||
262 | { |
||
263 | defaultValue = pDefault; |
||
264 | setter = (s, v) => { SetValueByName(s, name, v); }; |
||
265 | getter = (s) => { return GetValueByName(s, name); }; |
||
266 | objectSet = null; |
||
267 | } |
||
268 | // Use reflection to find the property named 'pName' in BSParam and assign 'val' to same. |
||
269 | private void SetValueByName(BSScene s, string pName, T val) |
||
270 | { |
||
271 | PropertyInfo prop = typeof(BSParam).GetProperty(pName, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); |
||
272 | if (prop == null) |
||
273 | { |
||
274 | // This should only be output when someone adds a new INI parameter and misspells the name. |
||
275 | s.Logger.ErrorFormat("{0} SetValueByName: did not find '{1}'. Verify specified property name is the same as the given INI parameters name.", LogHeader, pName); |
||
276 | } |
||
277 | else |
||
278 | { |
||
279 | prop.SetValue(null, val, null); |
||
280 | } |
||
281 | } |
||
282 | // Use reflection to find the property named 'pName' in BSParam and return the value in same. |
||
283 | private T GetValueByName(BSScene s, string pName) |
||
284 | { |
||
285 | PropertyInfo prop = typeof(BSParam).GetProperty(pName, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); |
||
286 | if (prop == null) |
||
287 | { |
||
288 | // This should only be output when someone adds a new INI parameter and misspells the name. |
||
289 | s.Logger.ErrorFormat("{0} GetValueByName: did not find '{1}'. Verify specified property name is the same as the given INI parameter name.", LogHeader, pName); |
||
290 | } |
||
291 | return (T)prop.GetValue(null, null); |
||
292 | } |
||
293 | public override void AssignDefault(BSScene s) |
||
294 | { |
||
295 | setter(s, defaultValue); |
||
296 | } |
||
297 | public override string GetValue(BSScene s) |
||
298 | { |
||
299 | return getter(s).ToString(); |
||
300 | } |
||
301 | public override void SetValue(BSScene s, string valAsString) |
||
302 | { |
||
303 | // Get the generic type of the setter |
||
304 | Type genericType = setter.GetType().GetGenericArguments()[0]; |
||
305 | // Find the 'Parse' method on that type |
||
306 | System.Reflection.MethodInfo parser = null; |
||
307 | try |
||
308 | { |
||
309 | parser = genericType.GetMethod("Parse", new Type[] { typeof(String) } ); |
||
310 | } |
||
311 | catch (Exception e) |
||
312 | { |
||
313 | s.Logger.ErrorFormat("{0} Exception getting parser for type '{1}': {2}", LogHeader, genericType, e); |
||
314 | parser = null; |
||
315 | } |
||
316 | if (parser != null) |
||
317 | { |
||
318 | // Parse the input string |
||
319 | try |
||
320 | { |
||
321 | T setValue = (T)parser.Invoke(genericType, new Object[] { valAsString }); |
||
322 | // Store the parsed value |
||
323 | setter(s, setValue); |
||
324 | // s.Logger.DebugFormat("{0} Parameter {1} = {2}", LogHeader, name, setValue); |
||
325 | } |
||
326 | catch |
||
327 | { |
||
328 | s.Logger.ErrorFormat("{0} Failed parsing parameter value '{1}' as type '{2}'", LogHeader, valAsString, genericType); |
||
329 | } |
||
330 | } |
||
331 | else |
||
332 | { |
||
333 | s.Logger.ErrorFormat("{0} Could not find parameter parser for type '{1}'", LogHeader, genericType); |
||
334 | } |
||
335 | } |
||
336 | public override bool HasSetOnObject |
||
337 | { |
||
338 | get { return objectSet != null; } |
||
339 | } |
||
340 | public override void SetOnObject(BSScene s, BSPhysObject obj) |
||
341 | { |
||
342 | if (objectSet != null) |
||
343 | objectSet(s, obj); |
||
344 | } |
||
345 | } |
||
346 | |||
347 | // List of all of the externally visible parameters. |
||
348 | // For each parameter, this table maps a text name to getter and setters. |
||
349 | // To add a new externally referencable/settable parameter, add the paramter storage |
||
350 | // location somewhere in the program and make an entry in this table with the |
||
351 | // getters and setters. |
||
352 | // It is easiest to find an existing definition and copy it. |
||
353 | // |
||
354 | // A ParameterDefn<T>() takes the following parameters: |
||
355 | // -- the text name of the parameter. This is used for console input and ini file. |
||
356 | // -- a short text description of the parameter. This shows up in the console listing. |
||
357 | // -- a default value |
||
358 | // -- a delegate for getting the value |
||
359 | // -- a delegate for setting the value |
||
360 | // -- an optional delegate to update the value in the world. Most often used to |
||
361 | // push the new value to an in-world object. |
||
362 | // |
||
363 | // The single letter parameters for the delegates are: |
||
364 | // s = BSScene |
||
365 | // o = BSPhysObject |
||
366 | // v = value (appropriate type) |
||
367 | private static ParameterDefnBase[] ParameterDefinitions = |
||
368 | { |
||
369 | new ParameterDefn<bool>("UseSeparatePhysicsThread", "If 'true', the physics engine runs independent from the simulator heartbeat", |
||
370 | false ), |
||
371 | new ParameterDefn<float>("PhysicsTimeStep", "If separate thread, seconds to simulate each interval", |
||
372 | 0.089f ), |
||
373 | |||
374 | new ParameterDefn<bool>("MeshSculptedPrim", "Whether to create meshes for sculpties", |
||
375 | true, |
||
376 | (s) => { return ShouldMeshSculptedPrim; }, |
||
377 | (s,v) => { ShouldMeshSculptedPrim = v; } ), |
||
378 | new ParameterDefn<bool>("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", |
||
379 | false, |
||
380 | (s) => { return ShouldForceSimplePrimMeshing; }, |
||
381 | (s,v) => { ShouldForceSimplePrimMeshing = v; } ), |
||
382 | new ParameterDefn<bool>("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", |
||
383 | true, |
||
384 | (s) => { return ShouldUseHullsForPhysicalObjects; }, |
||
385 | (s,v) => { ShouldUseHullsForPhysicalObjects = v; } ), |
||
386 | new ParameterDefn<bool>("ShouldRemoveZeroWidthTriangles", "If true, remove degenerate triangles from meshes", |
||
387 | true ), |
||
388 | new ParameterDefn<bool>("ShouldUseBulletHACD", "If true, use the Bullet version of HACD", |
||
389 | false ), |
||
390 | new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", |
||
391 | true ), |
||
392 | new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists", |
||
393 | false ), |
||
394 | new ParameterDefn<bool>("ShouldUseAssetHulls", "If true, use hull if specified in the mesh asset info", |
||
395 | true ), |
||
396 | |||
397 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", |
||
398 | 5 ), |
||
399 | new ParameterDefn<float>("UpdateVelocityChangeThreshold", "Change in updated velocity required before reporting change to simulator", |
||
400 | 0.1f ), |
||
401 | |||
402 | new ParameterDefn<float>("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", |
||
403 | 32f, |
||
404 | (s) => { return MeshLOD; }, |
||
405 | (s,v) => { MeshLOD = v; } ), |
||
406 | new ParameterDefn<float>("MeshLevelOfDetailCircular", "Level of detail for prims with circular cuts or shapes", |
||
407 | 32f, |
||
408 | (s) => { return MeshCircularLOD; }, |
||
409 | (s,v) => { MeshCircularLOD = v; } ), |
||
410 | new ParameterDefn<float>("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", |
||
411 | 10f, |
||
412 | (s) => { return MeshMegaPrimThreshold; }, |
||
413 | (s,v) => { MeshMegaPrimThreshold = v; } ), |
||
414 | new ParameterDefn<float>("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", |
||
415 | 32f, |
||
416 | (s) => { return MeshMegaPrimLOD; }, |
||
417 | (s,v) => { MeshMegaPrimLOD = v; } ), |
||
418 | new ParameterDefn<float>("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", |
||
419 | 32f, |
||
420 | (s) => { return SculptLOD; }, |
||
421 | (s,v) => { SculptLOD = v; } ), |
||
422 | |||
423 | new ParameterDefn<int>("MaxSubStep", "In simulation step, maximum number of substeps", |
||
424 | 10, |
||
425 | (s) => { return s.m_maxSubSteps; }, |
||
426 | (s,v) => { s.m_maxSubSteps = (int)v; } ), |
||
427 | new ParameterDefn<float>("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", |
||
428 | 1f / 60f, |
||
429 | (s) => { return s.m_fixedTimeStep; }, |
||
430 | (s,v) => { s.m_fixedTimeStep = v; } ), |
||
431 | new ParameterDefn<float>("NominalFrameRate", "The base frame rate we claim", |
||
432 | 55f, |
||
433 | (s) => { return s.NominalFrameRate; }, |
||
434 | (s,v) => { s.NominalFrameRate = (int)v; } ), |
||
435 | new ParameterDefn<int>("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", |
||
436 | 2048, |
||
437 | (s) => { return s.m_maxCollisionsPerFrame; }, |
||
438 | (s,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), |
||
439 | new ParameterDefn<int>("MaxUpdatesPerFrame", "Max updates returned at end of each frame", |
||
440 | 8000, |
||
441 | (s) => { return s.m_maxUpdatesPerFrame; }, |
||
442 | (s,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), |
||
443 | |||
444 | new ParameterDefn<float>("MinObjectMass", "Minimum object mass (0.0001)", |
||
445 | 0.0001f, |
||
446 | (s) => { return MinimumObjectMass; }, |
||
447 | (s,v) => { MinimumObjectMass = v; } ), |
||
448 | new ParameterDefn<float>("MaxObjectMass", "Maximum object mass (10000.01)", |
||
449 | 10000.01f, |
||
450 | (s) => { return MaximumObjectMass; }, |
||
451 | (s,v) => { MaximumObjectMass = v; } ), |
||
452 | new ParameterDefn<float>("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object", |
||
453 | 1000.0f, |
||
454 | (s) => { return MaxLinearVelocity; }, |
||
455 | (s,v) => { MaxLinearVelocity = v; MaxLinearVelocitySquared = v * v; } ), |
||
456 | new ParameterDefn<float>("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object", |
||
457 | 1000.0f, |
||
458 | (s) => { return MaxAngularVelocity; }, |
||
459 | (s,v) => { MaxAngularVelocity = v; MaxAngularVelocitySquared = v * v; } ), |
||
460 | // LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject |
||
461 | new ParameterDefn<float>("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)", |
||
462 | 20000.0f, |
||
463 | (s) => { return MaxAddForceMagnitude; }, |
||
464 | (s,v) => { MaxAddForceMagnitude = v; MaxAddForceMagnitudeSquared = v * v; } ), |
||
465 | // Density is passed around as 100kg/m3. This scales that to 1kg/m3. |
||
466 | // Reduce by power of 100 because Bullet doesn't seem to handle objects with large mass very well |
||
467 | new ParameterDefn<float>("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)", |
||
468 | 0.01f ), |
||
469 | |||
470 | new ParameterDefn<float>("PID_D", "Derivitive factor for motion smoothing", |
||
471 | 2200f ), |
||
472 | new ParameterDefn<float>("PID_P", "Parameteric factor for motion smoothing", |
||
473 | 900f ), |
||
474 | |||
475 | new ParameterDefn<float>("DefaultFriction", "Friction factor used on new objects", |
||
476 | 0.2f, |
||
477 | (s) => { return DefaultFriction; }, |
||
478 | (s,v) => { DefaultFriction = v; s.UnmanagedParams[0].defaultFriction = v; } ), |
||
479 | // For historical reasons, the viewer and simulator multiply the density by 100 |
||
480 | new ParameterDefn<float>("DefaultDensity", "Density for new objects" , |
||
481 | 1000.0006836f, // Aluminum g/cm3 * 100 |
||
482 | (s) => { return DefaultDensity; }, |
||
483 | (s,v) => { DefaultDensity = v; s.UnmanagedParams[0].defaultDensity = v; } ), |
||
484 | new ParameterDefn<float>("DefaultRestitution", "Bouncyness of an object" , |
||
485 | 0f, |
||
486 | (s) => { return DefaultRestitution; }, |
||
487 | (s,v) => { DefaultRestitution = v; s.UnmanagedParams[0].defaultRestitution = v; } ), |
||
488 | new ParameterDefn<float>("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", |
||
489 | 0.04f, |
||
490 | (s) => { return CollisionMargin; }, |
||
491 | (s,v) => { CollisionMargin = v; s.UnmanagedParams[0].collisionMargin = v; } ), |
||
492 | new ParameterDefn<float>("Gravity", "Vertical force of gravity (negative means down)", |
||
493 | -9.80665f, |
||
494 | (s) => { return Gravity; }, |
||
495 | (s,v) => { Gravity = v; s.UnmanagedParams[0].gravity = v; }, |
||
496 | (s,o) => { s.PE.SetGravity(o.PhysBody, new Vector3(0f,0f,Gravity)); } ), |
||
497 | |||
498 | |||
499 | new ParameterDefn<float>("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", |
||
500 | 0f, |
||
501 | (s) => { return LinearDamping; }, |
||
502 | (s,v) => { LinearDamping = v; }, |
||
503 | (s,o) => { s.PE.SetDamping(o.PhysBody, LinearDamping, AngularDamping); } ), |
||
504 | new ParameterDefn<float>("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", |
||
505 | 0f, |
||
506 | (s) => { return AngularDamping; }, |
||
507 | (s,v) => { AngularDamping = v; }, |
||
508 | (s,o) => { s.PE.SetDamping(o.PhysBody, LinearDamping, AngularDamping); } ), |
||
509 | new ParameterDefn<float>("DeactivationTime", "Seconds before considering an object potentially static", |
||
510 | 0.2f, |
||
511 | (s) => { return DeactivationTime; }, |
||
512 | (s,v) => { DeactivationTime = v; }, |
||
513 | (s,o) => { s.PE.SetDeactivationTime(o.PhysBody, DeactivationTime); } ), |
||
514 | new ParameterDefn<float>("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", |
||
515 | 0.8f, |
||
516 | (s) => { return LinearSleepingThreshold; }, |
||
517 | (s,v) => { LinearSleepingThreshold = v;}, |
||
518 | (s,o) => { s.PE.SetSleepingThresholds(o.PhysBody, LinearSleepingThreshold, AngularSleepingThreshold); } ), |
||
519 | new ParameterDefn<float>("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", |
||
520 | 1.0f, |
||
521 | (s) => { return AngularSleepingThreshold; }, |
||
522 | (s,v) => { AngularSleepingThreshold = v;}, |
||
523 | (s,o) => { s.PE.SetSleepingThresholds(o.PhysBody, LinearSleepingThreshold, AngularSleepingThreshold); } ), |
||
524 | new ParameterDefn<float>("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , |
||
525 | 0.0f, // set to zero to disable |
||
526 | (s) => { return CcdMotionThreshold; }, |
||
527 | (s,v) => { CcdMotionThreshold = v;}, |
||
528 | (s,o) => { s.PE.SetCcdMotionThreshold(o.PhysBody, CcdMotionThreshold); } ), |
||
529 | new ParameterDefn<float>("CcdSweptSphereRadius", "Continuious collision detection test radius" , |
||
530 | 0.2f, |
||
531 | (s) => { return CcdSweptSphereRadius; }, |
||
532 | (s,v) => { CcdSweptSphereRadius = v;}, |
||
533 | (s,o) => { s.PE.SetCcdSweptSphereRadius(o.PhysBody, CcdSweptSphereRadius); } ), |
||
534 | new ParameterDefn<float>("ContactProcessingThreshold", "Distance above which contacts can be discarded (0 means no discard)" , |
||
535 | 0.0f, |
||
536 | (s) => { return ContactProcessingThreshold; }, |
||
537 | (s,v) => { ContactProcessingThreshold = v;}, |
||
538 | (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ), |
||
539 | |||
540 | new ParameterDefn<float>("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", |
||
541 | (float)BSTerrainPhys.TerrainImplementation.Heightmap ), |
||
542 | new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , |
||
543 | 2 ), |
||
544 | new ParameterDefn<float>("TerrainFriction", "Factor to reduce movement against terrain surface" , |
||
545 | 0.3f ), |
||
546 | new ParameterDefn<float>("TerrainHitFraction", "Distance to measure hit collisions" , |
||
547 | 0.8f ), |
||
548 | new ParameterDefn<float>("TerrainRestitution", "Bouncyness" , |
||
549 | 0f ), |
||
550 | new ParameterDefn<float>("TerrainContactProcessingThreshold", "Distance from terrain to stop processing collisions" , |
||
551 | 0.0f ), |
||
552 | new ParameterDefn<float>("TerrainCollisionMargin", "Margin where collision checking starts" , |
||
553 | 0.08f ), |
||
554 | |||
555 | new ParameterDefn<float>("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", |
||
556 | 0.2f ), |
||
557 | new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", |
||
558 | 0.95f ), |
||
559 | new ParameterDefn<float>("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run", |
||
560 | 1.3f ), |
||
561 | // For historical reasons, density is reported * 100 |
||
562 | new ParameterDefn<float>("AvatarDensity", "Density of an avatar. Changed on avatar recreation. Scaled times 100.", |
||
563 | 3500f) , // 3.5 * 100 |
||
564 | new ParameterDefn<float>("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", |
||
565 | 0f ), |
||
566 | new ParameterDefn<float>("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", |
||
567 | 0.6f ) , |
||
568 | new ParameterDefn<float>("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", |
||
569 | 0.45f ), |
||
570 | new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar", |
||
571 | 1.5f ), |
||
572 | new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", |
||
573 | -0.2f ), |
||
574 | new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", |
||
575 | 0.1f ), |
||
576 | new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground", |
||
577 | 0.1f ), |
||
578 | new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", |
||
579 | 0.1f ), |
||
580 | new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped", |
||
581 | 0.1f ), |
||
582 | new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", |
||
583 | 1.0f ), |
||
584 | new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.", |
||
585 | 4 ), |
||
586 | new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction", |
||
587 | 0.6f ) , |
||
588 | new ParameterDefn<float>("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", |
||
589 | 0.6f ), |
||
590 | new ParameterDefn<float>("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", |
||
591 | 1.0f ), |
||
592 | new ParameterDefn<float>("AvatarStepUpCorrectionFactor", "Multiplied by height of step collision to create up movement at step", |
||
593 | 1.0f ), |
||
594 | new ParameterDefn<int>("AvatarStepSmoothingSteps", "Number of frames after a step collision that we continue walking up stairs", |
||
595 | 2 ), |
||
596 | |||
597 | new ParameterDefn<float>("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", |
||
598 | 1000.0f, |
||
599 | (s) => { return (float)VehicleMaxLinearVelocity; }, |
||
600 | (s,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySquared = v * v; } ), |
||
601 | new ParameterDefn<float>("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", |
||
602 | 12.0f, |
||
603 | (s) => { return (float)VehicleMaxAngularVelocity; }, |
||
604 | (s,v) => { VehicleMaxAngularVelocity = v; VehicleMaxAngularVelocitySq = v * v; } ), |
||
605 | new ParameterDefn<float>("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", |
||
606 | 0.0f ), |
||
607 | new ParameterDefn<Vector3>("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (<0,0,0> to <1,1,1>)", |
||
608 | new Vector3(1f, 1f, 1f) ), |
||
609 | new ParameterDefn<Vector3>("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (<0,0,0> to <1,1,1>)", |
||
610 | new Vector3(1f, 1f, 1f) ), |
||
611 | new ParameterDefn<Vector3>("VehicleInertiaFactor", "Fraction of physical inertia applied (<0,0,0> to <1,1,1>)", |
||
612 | new Vector3(1f, 1f, 1f) ), |
||
613 | new ParameterDefn<float>("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)", |
||
614 | 0.0f ), |
||
615 | new ParameterDefn<float>("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", |
||
616 | 0.0f ), |
||
617 | new ParameterDefn<float>("VehicleGroundGravityFudge", "Factor to multiply gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", |
||
618 | 0.2f ), |
||
619 | new ParameterDefn<float>("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.", |
||
620 | 60.0f ), |
||
621 | new ParameterDefn<bool>("VehicleEnableLinearDeflection", "Turn on/off vehicle linear deflection effect", |
||
622 | true ), |
||
623 | new ParameterDefn<bool>("VehicleLinearDeflectionNotCollidingNoZ", "Turn on/off linear deflection Z effect on non-colliding vehicles", |
||
624 | true ), |
||
625 | new ParameterDefn<bool>("VehicleEnableAngularVerticalAttraction", "Turn on/off vehicle angular vertical attraction effect", |
||
626 | true ), |
||
627 | new ParameterDefn<int>("VehicleAngularVerticalAttractionAlgorithm", "Select vertical attraction algo. You need to look at the source.", |
||
628 | |||
629 | new ParameterDefn<bool>("VehicleEnableAngularDeflection", "Turn on/off vehicle angular deflection effect", |
||
630 | true ), |
||
631 | new ParameterDefn<bool>("VehicleEnableAngularBanking", "Turn on/off vehicle angular banking effect", |
||
632 | true ), |
||
633 | |||
634 | new ParameterDefn<float>("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", |
||
635 | 0f, |
||
636 | (s) => { return MaxPersistantManifoldPoolSize; }, |
||
637 | (s,v) => { MaxPersistantManifoldPoolSize = v; s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), |
||
638 | new ParameterDefn<float>("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", |
||
639 | 0f, |
||
640 | (s) => { return MaxCollisionAlgorithmPoolSize; }, |
||
641 | (s,v) => { MaxCollisionAlgorithmPoolSize = v; s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), |
||
642 | new ParameterDefn<bool>("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", |
||
643 | false, |
||
644 | (s) => { return ShouldDisableContactPoolDynamicAllocation; }, |
||
645 | (s,v) => { ShouldDisableContactPoolDynamicAllocation = v; |
||
646 | s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = NumericBool(v); } ), |
||
647 | new ParameterDefn<bool>("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", |
||
648 | false, |
||
649 | (s) => { return ShouldForceUpdateAllAabbs; }, |
||
650 | (s,v) => { ShouldForceUpdateAllAabbs = v; s.UnmanagedParams[0].shouldForceUpdateAllAabbs = NumericBool(v); } ), |
||
651 | new ParameterDefn<bool>("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", |
||
652 | true, |
||
653 | (s) => { return ShouldRandomizeSolverOrder; }, |
||
654 | (s,v) => { ShouldRandomizeSolverOrder = v; s.UnmanagedParams[0].shouldRandomizeSolverOrder = NumericBool(v); } ), |
||
655 | new ParameterDefn<bool>("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", |
||
656 | true, |
||
657 | (s) => { return ShouldSplitSimulationIslands; }, |
||
658 | (s,v) => { ShouldSplitSimulationIslands = v; s.UnmanagedParams[0].shouldSplitSimulationIslands = NumericBool(v); } ), |
||
659 | new ParameterDefn<bool>("ShouldEnableFrictionCaching", "Enable friction computation caching", |
||
660 | true, |
||
661 | (s) => { return ShouldEnableFrictionCaching; }, |
||
662 | (s,v) => { ShouldEnableFrictionCaching = v; s.UnmanagedParams[0].shouldEnableFrictionCaching = NumericBool(v); } ), |
||
663 | new ParameterDefn<float>("NumberOfSolverIterations", "Number of internal iterations (0 means default)", |
||
664 | 0f, // zero says use Bullet default |
||
665 | (s) => { return NumberOfSolverIterations; }, |
||
666 | (s,v) => { NumberOfSolverIterations = v; s.UnmanagedParams[0].numberOfSolverIterations = v; } ), |
||
667 | new ParameterDefn<bool>("UseSingleSidedMeshes", "Whether to compute collisions based on single sided meshes.", |
||
668 | true, |
||
669 | (s) => { return UseSingleSidedMeshes; }, |
||
670 | (s,v) => { UseSingleSidedMeshes = v; s.UnmanagedParams[0].useSingleSidedMeshes = NumericBool(v); } ), |
||
671 | new ParameterDefn<float>("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))", |
||
672 | 0f, |
||
673 | (s) => { return GlobalContactBreakingThreshold; }, |
||
674 | (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), |
||
675 | new ParameterDefn<float>("PhysicsUnmanLoggingFrames", "If non-zero, frames between output of detailed unmanaged physics statistics", |
||
676 | 0f, |
||
677 | (s) => { return PhysicsUnmanLoggingFrames; }, |
||
678 | (s,v) => { PhysicsUnmanLoggingFrames = v; s.UnmanagedParams[0].physicsLoggingFrames = v; } ), |
||
679 | |||
680 | new ParameterDefn<int>("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy", |
||
681 | 7 ), |
||
682 | new ParameterDefn<int>("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes", |
||
683 | 2 ), |
||
684 | new ParameterDefn<float>("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)", |
||
685 | 5f ), |
||
686 | new ParameterDefn<float>("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)", |
||
687 | 5f ), |
||
688 | new ParameterDefn<int>("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.", |
||
689 | 32 ), |
||
690 | new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.", |
||
691 | 0f ), |
||
692 | |||
693 | new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull", |
||
694 | 200f ), |
||
695 | new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh", |
||
696 | 10f ), |
||
697 | new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls", |
||
698 | 20f ), |
||
699 | new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull", |
||
700 | 0.1f ), |
||
701 | new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be", |
||
702 | 10f ), |
||
703 | new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors", |
||
704 | true ), |
||
705 | new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls", |
||
706 | true ), |
||
707 | new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces", |
||
708 | true ), |
||
709 | new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin", |
||
710 | false ), |
||
711 | |||
712 | new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", |
||
713 | (float)BSLinkset.LinksetImplementation.Compound ), |
||
714 | new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same", |
||
715 | true ), |
||
716 | new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", |
||
717 | false ), |
||
718 | new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", |
||
719 | true ), |
||
720 | new ParameterDefn<float>("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", |
||
721 | 5.0f ), |
||
722 | new ParameterDefn<float>("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", |
||
723 | 0.1f ), |
||
724 | new ParameterDefn<float>("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", |
||
725 | 0.1f ), |
||
726 | new ParameterDefn<float>("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", |
||
727 | 0.1f ), |
||
728 | new ParameterDefn<float>("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", |
||
729 | 40 ), |
||
730 | |||
731 | new ParameterDefn<int>("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)", |
||
732 | 0, |
||
733 | (s) => { return s.PhysicsMetricDumpFrames; }, |
||
734 | (s,v) => { s.PhysicsMetricDumpFrames = v; } ), |
||
735 | new ParameterDefn<float>("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool", |
||
736 | 0f, |
||
737 | (s) => { return 0f; }, |
||
738 | (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v, false /* inTaintTime */); } ), |
||
739 | new ParameterDefn<float>("ResetConstraintSolver", "Setting this is any value resets the constraint solver", |
||
740 | 0f, |
||
741 | (s) => { return 0f; }, |
||
742 | (s,v) => { BSParam.ResetConstraintSolverTainted(s, v); } ), |
||
743 | }; |
||
744 | |||
745 | // Convert a boolean to our numeric true and false values |
||
746 | public static float NumericBool(bool b) |
||
747 | { |
||
748 | return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse); |
||
749 | } |
||
750 | |||
751 | // Convert numeric true and false values to a boolean |
||
752 | public static bool BoolNumeric(float b) |
||
753 | { |
||
754 | return (b == ConfigurationParameters.numericTrue ? true : false); |
||
755 | } |
||
756 | |||
757 | // Search through the parameter definitions and return the matching |
||
758 | // ParameterDefn structure. |
||
759 | // Case does not matter as names are compared after converting to lower case. |
||
760 | // Returns 'false' if the parameter is not found. |
||
761 | internal static bool TryGetParameter(string paramName, out ParameterDefnBase defn) |
||
762 | { |
||
763 | bool ret = false; |
||
764 | ParameterDefnBase foundDefn = null; |
||
765 | string pName = paramName.ToLower(); |
||
766 | |||
767 | foreach (ParameterDefnBase parm in ParameterDefinitions) |
||
768 | { |
||
769 | if (pName == parm.name.ToLower()) |
||
770 | { |
||
771 | foundDefn = parm; |
||
772 | ret = true; |
||
773 | break; |
||
774 | } |
||
775 | } |
||
776 | defn = foundDefn; |
||
777 | return ret; |
||
778 | } |
||
779 | |||
780 | // Pass through the settable parameters and set the default values |
||
781 | internal static void SetParameterDefaultValues(BSScene physicsScene) |
||
782 | { |
||
783 | foreach (ParameterDefnBase parm in ParameterDefinitions) |
||
784 | { |
||
785 | parm.AssignDefault(physicsScene); |
||
786 | } |
||
787 | } |
||
788 | |||
789 | // Get user set values out of the ini file. |
||
790 | internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg) |
||
791 | { |
||
792 | foreach (ParameterDefnBase parm in ParameterDefinitions) |
||
793 | { |
||
794 | parm.SetValue(physicsScene, cfg.GetString(parm.name, parm.GetValue(physicsScene))); |
||
795 | } |
||
796 | } |
||
797 | |||
798 | internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; |
||
799 | |||
800 | // This creates an array in the correct format for returning the list of |
||
801 | // parameters. This is used by the 'list' option of the 'physics' command. |
||
802 | internal static void BuildParameterTable() |
||
803 | { |
||
804 | if (SettableParameters.Length < ParameterDefinitions.Length) |
||
805 | { |
||
806 | List<PhysParameterEntry> entries = new List<PhysParameterEntry>(); |
||
807 | for (int ii = 0; ii < ParameterDefinitions.Length; ii++) |
||
808 | { |
||
809 | ParameterDefnBase pd = ParameterDefinitions[ii]; |
||
810 | entries.Add(new PhysParameterEntry(pd.name, pd.desc)); |
||
811 | } |
||
812 | |||
813 | // make the list alphabetical for ease of finding anything |
||
814 | entries.Sort((ppe1, ppe2) => { return ppe1.name.CompareTo(ppe2.name); }); |
||
815 | |||
816 | SettableParameters = entries.ToArray(); |
||
817 | } |
||
818 | } |
||
819 | |||
820 | // ===================================================================== |
||
821 | // ===================================================================== |
||
822 | // There are parameters that, when set, cause things to happen in the physics engine. |
||
823 | // This causes the broadphase collision cache to be cleared. |
||
824 | private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v, bool inTaintTime) |
||
825 | { |
||
826 | BSScene physScene = pPhysScene; |
||
827 | physScene.TaintedObject(inTaintTime, "BSParam.ResetBroadphasePoolTainted", delegate() |
||
828 | { |
||
829 | physScene.PE.ResetBroadphasePool(physScene.World); |
||
830 | }); |
||
831 | } |
||
832 | |||
833 | // This causes the constraint solver cache to be cleared and reset. |
||
834 | private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v) |
||
835 | { |
||
836 | BSScene physScene = pPhysScene; |
||
837 | physScene.TaintedObject(BSScene.DetailLogZero, "BSParam.ResetConstraintSolver", delegate() |
||
838 | { |
||
839 | physScene.PE.ResetConstraintSolver(physScene.World); |
||
840 | }); |
||
841 | } |
||
842 | } |
||
843 | } |