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