aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorRobert Adams2012-12-21 13:35:44 -0800
committerRobert Adams2012-12-21 13:35:44 -0800
commitae4d932e7f00e781db9c9cdd5c29efc51e2425fb (patch)
treeb03beb291cd35d4227fb82baf04ce14512b859eb /OpenSim/Region/Physics
parentBulletSim: small fix to avatar movement motor use which keeps avatar from fly... (diff)
downloadopensim-SC-ae4d932e7f00e781db9c9cdd5c29efc51e2425fb.zip
opensim-SC-ae4d932e7f00e781db9c9cdd5c29efc51e2425fb.tar.gz
opensim-SC-ae4d932e7f00e781db9c9cdd5c29efc51e2425fb.tar.bz2
opensim-SC-ae4d932e7f00e781db9c9cdd5c29efc51e2425fb.tar.xz
BulletSim: Move all the parameter variables, tables and get and fetch logic to a separate, static class for easier addition and to remove all that bulk from the BSScene class.
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs30
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs2
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs14
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs558
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs26
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs549
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs12
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs10
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs6
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs68
13 files changed, 681 insertions, 606 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 57c5898..7bde1c1 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -88,8 +88,8 @@ public sealed class BSCharacter : BSPhysObject
88 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 88 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
89 // replace with the default values. 89 // replace with the default values.
90 _size = size; 90 _size = size;
91 if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth; 91 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
92 if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth; 92 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
93 93
94 // A motor to control the acceleration and deceleration of the avatar movement. 94 // A motor to control the acceleration and deceleration of the avatar movement.
95 // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); 95 // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f);
@@ -108,8 +108,8 @@ public sealed class BSCharacter : BSPhysObject
108 _velocity = OMV.Vector3.Zero; 108 _velocity = OMV.Vector3.Zero;
109 _appliedVelocity = OMV.Vector3.Zero; 109 _appliedVelocity = OMV.Vector3.Zero;
110 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 110 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
111 _currentFriction = PhysicsScene.Params.avatarStandingFriction; 111 _currentFriction = BSParam.AvatarStandingFriction;
112 _avatarDensity = PhysicsScene.Params.avatarDensity; 112 _avatarDensity = BSParam.AvatarDensity;
113 113
114 // The dimensions of the avatar capsule are kept in the scale. 114 // The dimensions of the avatar capsule are kept in the scale.
115 // Physics creates a unit capsule which is scaled by the physics engine. 115 // Physics creates a unit capsule which is scaled by the physics engine.
@@ -161,14 +161,14 @@ public sealed class BSCharacter : BSPhysObject
161 // Needs to be reset especially when an avatar is recreated after crossing a region boundry. 161 // Needs to be reset especially when an avatar is recreated after crossing a region boundry.
162 Flying = _flying; 162 Flying = _flying;
163 163
164 BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.avatarRestitution); 164 BulletSimAPI.SetRestitution2(PhysBody.ptr, BSParam.AvatarRestitution);
165 BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin); 165 BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin);
166 BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); 166 BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale);
167 BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); 167 BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold);
168 if (PhysicsScene.Params.ccdMotionThreshold > 0f) 168 if (BSParam.CcdMotionThreshold > 0f)
169 { 169 {
170 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); 170 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold);
171 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); 171 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
172 } 172 }
173 173
174 UpdatePhysicalMassProperties(RawMass); 174 UpdatePhysicalMassProperties(RawMass);
@@ -208,8 +208,8 @@ public sealed class BSCharacter : BSPhysObject
208 _size = value; 208 _size = value;
209 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 209 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
210 // replace with the default values. 210 // replace with the default values.
211 if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth; 211 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
212 if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth; 212 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
213 213
214 ComputeAvatarScale(_size); 214 ComputeAvatarScale(_size);
215 ComputeAvatarVolumeAndMass(); 215 ComputeAvatarVolumeAndMass();
@@ -468,18 +468,18 @@ public sealed class BSCharacter : BSPhysObject
468 // to keep the avatar from slipping around 468 // to keep the avatar from slipping around
469 if (_velocity.Length() == 0) 469 if (_velocity.Length() == 0)
470 { 470 {
471 if (_currentFriction != PhysicsScene.Params.avatarStandingFriction) 471 if (_currentFriction != BSParam.AvatarStandingFriction)
472 { 472 {
473 _currentFriction = PhysicsScene.Params.avatarStandingFriction; 473 _currentFriction = BSParam.AvatarStandingFriction;
474 if (PhysBody.HasPhysicalBody) 474 if (PhysBody.HasPhysicalBody)
475 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); 475 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction);
476 } 476 }
477 } 477 }
478 else 478 else
479 { 479 {
480 if (_currentFriction != PhysicsScene.Params.avatarFriction) 480 if (_currentFriction != BSParam.AvatarFriction)
481 { 481 {
482 _currentFriction = PhysicsScene.Params.avatarFriction; 482 _currentFriction = BSParam.AvatarFriction;
483 if (PhysBody.HasPhysicalBody) 483 if (PhysBody.HasPhysicalBody)
484 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); 484 BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction);
485 } 485 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index 6b1e304..e77fb50 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -122,7 +122,7 @@ public abstract class BSConstraint : IDisposable
122 // Setting an object's mass to zero (making it static like when it's selected) 122 // Setting an object's mass to zero (making it static like when it's selected)
123 // automatically disables the constraints. 123 // automatically disables the constraints.
124 // If the link is enabled, be sure to set the constraint itself to enabled. 124 // If the link is enabled, be sure to set the constraint itself to enabled.
125 BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, m_world.physicsScene.NumericBool(true)); 125 BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, BSParam.NumericBool(true));
126 } 126 }
127 else 127 else
128 { 128 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index a5acd86..e59ed8d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -563,7 +563,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
563 // Moderate angular movement introduced by Bullet. 563 // Moderate angular movement introduced by Bullet.
564 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. 564 // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
565 // Maybe compute linear and angular factor and damping from params. 565 // Maybe compute linear and angular factor and damping from params.
566 float angularDamping = PhysicsScene.Params.vehicleAngularDamping; 566 float angularDamping = BSParam.VehicleAngularDamping;
567 BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); 567 BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping);
568 568
569 // Vehicles report collision events so we know when it's on the ground 569 // Vehicles report collision events so we know when it's on the ground
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 2017fa5..8580928 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -56,7 +56,7 @@ public abstract class BSLinkset
56 { 56 {
57 BSLinkset ret = null; 57 BSLinkset ret = null;
58 58
59 switch ((int)physScene.Params.linksetImplementation) 59 switch ((int)BSParam.LinksetImplementation)
60 { 60 {
61 case (int)LinksetImplementation.Constraint: 61 case (int)LinksetImplementation.Constraint:
62 ret = new BSLinksetConstraints(physScene, parent); 62 ret = new BSLinksetConstraints(physScene, parent);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index 8c36c31..d95f223 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -226,14 +226,14 @@ public sealed class BSLinksetConstraints : BSLinkset
226 constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); 226 constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
227 227
228 // tweek the constraint to increase stability 228 // tweek the constraint to increase stability
229 constrain.UseFrameOffset(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintUseFrameOffset)); 229 constrain.UseFrameOffset(BSParam.BoolNumeric(BSParam.LinkConstraintUseFrameOffset));
230 constrain.TranslationalLimitMotor(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintEnableTransMotor), 230 constrain.TranslationalLimitMotor(BSParam.BoolNumeric(BSParam.LinkConstraintEnableTransMotor),
231 PhysicsScene.Params.linkConstraintTransMotorMaxVel, 231 BSParam.LinkConstraintTransMotorMaxVel,
232 PhysicsScene.Params.linkConstraintTransMotorMaxForce); 232 BSParam.LinkConstraintTransMotorMaxForce);
233 constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP); 233 constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP);
234 if (PhysicsScene.Params.linkConstraintSolverIterations != 0f) 234 if (BSParam.LinkConstraintSolverIterations != 0f)
235 { 235 {
236 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations); 236 constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations);
237 } 237 }
238 return constrain; 238 return constrain;
239 } 239 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
new file mode 100755
index 0000000..1fb4c31
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -0,0 +1,558 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30
31using OpenSim.Region.Physics.Manager;
32
33using OpenMetaverse;
34using Nini.Config;
35
36namespace OpenSim.Region.Physics.BulletSPlugin
37{
38public static class BSParam
39{
40 // Level of Detail values kept as float because that's what the Meshmerizer wants
41 public static float MeshLOD { get; private set; }
42 public static float MeshMegaPrimLOD { get; private set; }
43 public static float MeshMegaPrimThreshold { get; private set; }
44 public static float SculptLOD { get; private set; }
45
46 public static float MinimumObjectMass { get; private set; }
47 public static float MaximumObjectMass { get; private set; }
48
49 public static float LinearDamping { get; private set; }
50 public static float AngularDamping { get; private set; }
51 public static float DeactivationTime { get; private set; }
52 public static float LinearSleepingThreshold { get; private set; }
53 public static float AngularSleepingThreshold { get; private set; }
54 public static float CcdMotionThreshold { get; private set; }
55 public static float CcdSweptSphereRadius { get; private set; }
56 public static float ContactProcessingThreshold { get; private set; }
57
58 public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed
59 public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
60 public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects
61
62 public static float TerrainImplementation { get; private set; }
63 public static float TerrainFriction { get; private set; }
64 public static float TerrainHitFraction { get; private set; }
65 public static float TerrainRestitution { get; private set; }
66 public static float TerrainCollisionMargin { get; private set; }
67
68 // Avatar parameters
69 public static float AvatarFriction { get; private set; }
70 public static float AvatarStandingFriction { get; private set; }
71 public static float AvatarDensity { get; private set; }
72 public static float AvatarRestitution { get; private set; }
73 public static float AvatarCapsuleWidth { get; private set; }
74 public static float AvatarCapsuleDepth { get; private set; }
75 public static float AvatarCapsuleHeight { get; private set; }
76 public static float AvatarContactProcessingThreshold { get; private set; }
77
78 public static float VehicleAngularDamping { get; private set; }
79
80 public static float LinksetImplementation { get; private set; }
81 public static float LinkConstraintUseFrameOffset { get; private set; }
82 public static float LinkConstraintEnableTransMotor { get; private set; }
83 public static float LinkConstraintTransMotorMaxVel { get; private set; }
84 public static float LinkConstraintTransMotorMaxForce { get; private set; }
85 public static float LinkConstraintERP { get; private set; }
86 public static float LinkConstraintCFM { get; private set; }
87 public static float LinkConstraintSolverIterations { get; private set; }
88
89 public static float PID_D { get; private set; } // derivative
90 public static float PID_P { get; private set; } // proportional
91
92 public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
93 public delegate float ParamGet(BSScene scene);
94 public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val);
95 public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val);
96
97 public struct ParameterDefn
98 {
99 public string name; // string name of the parameter
100 public string desc; // a short description of what the parameter means
101 public float defaultValue; // default value if not specified anywhere else
102 public ParamUser userParam; // get the value from the configuration file
103 public ParamGet getter; // return the current value stored for this parameter
104 public ParamSet setter; // set the current value for this parameter
105 public SetOnObject onObject; // set the value on an object in the physical domain
106 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
107 {
108 name = n;
109 desc = d;
110 defaultValue = v;
111 userParam = u;
112 getter = g;
113 setter = s;
114 onObject = null;
115 }
116 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o)
117 {
118 name = n;
119 desc = d;
120 defaultValue = v;
121 userParam = u;
122 getter = g;
123 setter = s;
124 onObject = o;
125 }
126 }
127
128 // List of all of the externally visible parameters.
129 // For each parameter, this table maps a text name to getter and setters.
130 // To add a new externally referencable/settable parameter, add the paramter storage
131 // location somewhere in the program and make an entry in this table with the
132 // getters and setters.
133 // It is easiest to find an existing definition and copy it.
134 // Parameter values are floats. Booleans are converted to a floating value.
135 //
136 // A ParameterDefn() takes the following parameters:
137 // -- the text name of the parameter. This is used for console input and ini file.
138 // -- a short text description of the parameter. This shows up in the console listing.
139 // -- a delegate for fetching the parameter from the ini file.
140 // Should handle fetching the right type from the ini file and converting it.
141 // -- a delegate for getting the value as a float
142 // -- a delegate for setting the value from a float
143 // -- an optional delegate to update the value in the world. Most often used to
144 // push the new value to an in-world object.
145 //
146 // The single letter parameters for the delegates are:
147 // s = BSScene
148 // o = BSPhysObject
149 // p = string parameter name
150 // l = localID of referenced object
151 // v = float value
152 // cf = parameter configuration class (for fetching values from ini file)
153 private static ParameterDefn[] ParameterDefinitions =
154 {
155 new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties",
156 ConfigurationParameters.numericTrue,
157 (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
158 (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); },
159 (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ),
160 new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects",
161 ConfigurationParameters.numericFalse,
162 (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
163 (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); },
164 (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ),
165 new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects",
166 ConfigurationParameters.numericTrue,
167 (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); },
168 (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); },
169 (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ),
170
171 new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
172 8f,
173 (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); },
174 (s) => { return MeshLOD; },
175 (s,p,l,v) => { MeshLOD = v; } ),
176 new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
177 16f,
178 (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
179 (s) => { return MeshMegaPrimLOD; },
180 (s,p,l,v) => { MeshMegaPrimLOD = v; } ),
181 new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
182 10f,
183 (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
184 (s) => { return MeshMegaPrimThreshold; },
185 (s,p,l,v) => { MeshMegaPrimThreshold = v; } ),
186 new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
187 32f,
188 (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); },
189 (s) => { return SculptLOD; },
190 (s,p,l,v) => { SculptLOD = v; } ),
191
192 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
193 10f,
194 (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); },
195 (s) => { return (float)s.m_maxSubSteps; },
196 (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ),
197 new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)",
198 1f / 60f,
199 (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); },
200 (s) => { return (float)s.m_fixedTimeStep; },
201 (s,p,l,v) => { s.m_fixedTimeStep = v; } ),
202 new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame",
203 2048f,
204 (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); },
205 (s) => { return (float)s.m_maxCollisionsPerFrame; },
206 (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ),
207 new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame",
208 8000f,
209 (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); },
210 (s) => { return (float)s.m_maxUpdatesPerFrame; },
211 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
212 new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step",
213 500f,
214 (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); },
215 (s) => { return (float)s.m_taintsToProcessPerStep; },
216 (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ),
217 new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)",
218 0.0001f,
219 (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); },
220 (s) => { return (float)MinimumObjectMass; },
221 (s,p,l,v) => { MinimumObjectMass = v; } ),
222 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
223 10000.01f,
224 (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); },
225 (s) => { return (float)MaximumObjectMass; },
226 (s,p,l,v) => { MaximumObjectMass = v; } ),
227
228 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
229 2200f,
230 (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); },
231 (s) => { return (float)PID_D; },
232 (s,p,l,v) => { PID_D = v; } ),
233 new ParameterDefn("PID_P", "Parameteric factor for motion smoothing",
234 900f,
235 (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); },
236 (s) => { return (float)PID_P; },
237 (s,p,l,v) => { PID_P = v; } ),
238
239 new ParameterDefn("DefaultFriction", "Friction factor used on new objects",
240 0.2f,
241 (s,cf,p,v) => { s.UnmanagedParams[0].defaultFriction = cf.GetFloat(p, v); },
242 (s) => { return s.UnmanagedParams[0].defaultFriction; },
243 (s,p,l,v) => { s.UnmanagedParams[0].defaultFriction = v; } ),
244 new ParameterDefn("DefaultDensity", "Density for new objects" ,
245 10.000006836f, // Aluminum g/cm3
246 (s,cf,p,v) => { s.UnmanagedParams[0].defaultDensity = cf.GetFloat(p, v); },
247 (s) => { return s.UnmanagedParams[0].defaultDensity; },
248 (s,p,l,v) => { s.UnmanagedParams[0].defaultDensity = v; } ),
249 new ParameterDefn("DefaultRestitution", "Bouncyness of an object" ,
250 0f,
251 (s,cf,p,v) => { s.UnmanagedParams[0].defaultRestitution = cf.GetFloat(p, v); },
252 (s) => { return s.UnmanagedParams[0].defaultRestitution; },
253 (s,p,l,v) => { s.UnmanagedParams[0].defaultRestitution = v; } ),
254 new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)",
255 0.04f,
256 (s,cf,p,v) => { s.UnmanagedParams[0].collisionMargin = cf.GetFloat(p, v); },
257 (s) => { return s.UnmanagedParams[0].collisionMargin; },
258 (s,p,l,v) => { s.UnmanagedParams[0].collisionMargin = v; } ),
259 new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)",
260 -9.80665f,
261 (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); },
262 (s) => { return s.UnmanagedParams[0].gravity; },
263 (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); },
264 (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ),
265
266
267 new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)",
268 0f,
269 (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); },
270 (s) => { return LinearDamping; },
271 (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); },
272 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ),
273 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
274 0f,
275 (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); },
276 (s) => { return AngularDamping; },
277 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); },
278 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ),
279 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
280 0.2f,
281 (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); },
282 (s) => { return DeactivationTime; },
283 (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); },
284 (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ),
285 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
286 0.8f,
287 (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); },
288 (s) => { return LinearSleepingThreshold; },
289 (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); },
290 (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
291 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
292 1.0f,
293 (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); },
294 (s) => { return AngularSleepingThreshold; },
295 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); },
296 (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
297 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
298 0f, // set to zero to disable
299 (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); },
300 (s) => { return CcdMotionThreshold; },
301 (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); },
302 (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ),
303 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
304 0f,
305 (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); },
306 (s) => { return CcdSweptSphereRadius; },
307 (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); },
308 (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ),
309 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
310 0.1f,
311 (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); },
312 (s) => { return ContactProcessingThreshold; },
313 (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); },
314 (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ),
315
316 new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
317 (float)BSTerrainPhys.TerrainImplementation.Mesh,
318 (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); },
319 (s) => { return TerrainImplementation; },
320 (s,p,l,v) => { TerrainImplementation = v; } ),
321 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
322 0.3f,
323 (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); },
324 (s) => { return TerrainFriction; },
325 (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ),
326 new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" ,
327 0.8f,
328 (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); },
329 (s) => { return TerrainHitFraction; },
330 (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ),
331 new ParameterDefn("TerrainRestitution", "Bouncyness" ,
332 0f,
333 (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); },
334 (s) => { return TerrainRestitution; },
335 (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ),
336 new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" ,
337 0.04f,
338 (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); },
339 (s) => { return TerrainCollisionMargin; },
340 (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ),
341
342 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
343 0.2f,
344 (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); },
345 (s) => { return AvatarFriction; },
346 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarFriction=x;}, p, l, v); } ),
347 new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
348 10.0f,
349 (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); },
350 (s) => { return AvatarStandingFriction; },
351 (s,p,l,v) => { AvatarStandingFriction = v; } ),
352 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
353 60f,
354 (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); },
355 (s) => { return AvatarDensity; },
356 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ),
357 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
358 0f,
359 (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); },
360 (s) => { return AvatarRestitution; },
361 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarRestitution=x;}, p, l, v); } ),
362 new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule",
363 0.6f,
364 (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); },
365 (s) => { return AvatarCapsuleWidth; },
366 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleWidth=x;}, p, l, v); } ),
367 new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule",
368 0.45f,
369 (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); },
370 (s) => { return AvatarCapsuleDepth; },
371 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleDepth=x;}, p, l, v); } ),
372 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
373 1.5f,
374 (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); },
375 (s) => { return AvatarCapsuleHeight; },
376 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleHeight=x;}, p, l, v); } ),
377 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
378 0.1f,
379 (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); },
380 (s) => { return AvatarContactProcessingThreshold; },
381 (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ),
382
383 new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
384 0.95f,
385 (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
386 (s) => { return VehicleAngularDamping; },
387 (s,p,l,v) => { VehicleAngularDamping = v; } ),
388
389 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
390 0f,
391 (s,cf,p,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
392 (s) => { return s.UnmanagedParams[0].maxPersistantManifoldPoolSize; },
393 (s,p,l,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ),
394 new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
395 0f,
396 (s,cf,p,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); },
397 (s) => { return s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize; },
398 (s,p,l,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ),
399 new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
400 ConfigurationParameters.numericFalse,
401 (s,cf,p,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
402 (s) => { return s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation; },
403 (s,p,l,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ),
404 new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
405 ConfigurationParameters.numericFalse,
406 (s,cf,p,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
407 (s) => { return s.UnmanagedParams[0].shouldForceUpdateAllAabbs; },
408 (s,p,l,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ),
409 new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction",
410 ConfigurationParameters.numericTrue,
411 (s,cf,p,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
412 (s) => { return s.UnmanagedParams[0].shouldRandomizeSolverOrder; },
413 (s,p,l,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ),
414 new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands",
415 ConfigurationParameters.numericTrue,
416 (s,cf,p,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
417 (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; },
418 (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ),
419 new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching",
420 ConfigurationParameters.numericFalse,
421 (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
422 (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; },
423 (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ),
424 new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)",
425 0f, // zero says use Bullet default
426 (s,cf,p,v) => { s.UnmanagedParams[0].numberOfSolverIterations = cf.GetFloat(p, v); },
427 (s) => { return s.UnmanagedParams[0].numberOfSolverIterations; },
428 (s,p,l,v) => { s.UnmanagedParams[0].numberOfSolverIterations = v; } ),
429
430 new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
431 (float)BSLinkset.LinksetImplementation.Compound,
432 (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); },
433 (s) => { return LinksetImplementation; },
434 (s,p,l,v) => { LinksetImplementation = v; } ),
435 new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
436 ConfigurationParameters.numericFalse,
437 (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
438 (s) => { return LinkConstraintUseFrameOffset; },
439 (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ),
440 new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
441 ConfigurationParameters.numericTrue,
442 (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
443 (s) => { return LinkConstraintEnableTransMotor; },
444 (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ),
445 new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints",
446 5.0f,
447 (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); },
448 (s) => { return LinkConstraintTransMotorMaxVel; },
449 (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ),
450 new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints",
451 0.1f,
452 (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
453 (s) => { return LinkConstraintTransMotorMaxForce; },
454 (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ),
455 new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
456 0.1f,
457 (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); },
458 (s) => { return LinkConstraintCFM; },
459 (s,p,l,v) => { LinkConstraintCFM = v; } ),
460 new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
461 0.1f,
462 (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); },
463 (s) => { return LinkConstraintERP; },
464 (s,p,l,v) => { LinkConstraintERP = v; } ),
465 new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
466 40,
467 (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); },
468 (s) => { return LinkConstraintSolverIterations; },
469 (s,p,l,v) => { LinkConstraintSolverIterations = v; } ),
470
471 new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)",
472 0f,
473 (s,cf,p,v) => { s.UnmanagedParams[0].physicsLoggingFrames = cf.GetInt(p, (int)v); },
474 (s) => { return (float)s.UnmanagedParams[0].physicsLoggingFrames; },
475 (s,p,l,v) => { s.UnmanagedParams[0].physicsLoggingFrames = (int)v; } ),
476 };
477
478 // Convert a boolean to our numeric true and false values
479 public static float NumericBool(bool b)
480 {
481 return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse);
482 }
483
484 // Convert numeric true and false values to a boolean
485 public static bool BoolNumeric(float b)
486 {
487 return (b == ConfigurationParameters.numericTrue ? true : false);
488 }
489
490 // Search through the parameter definitions and return the matching
491 // ParameterDefn structure.
492 // Case does not matter as names are compared after converting to lower case.
493 // Returns 'false' if the parameter is not found.
494 internal static bool TryGetParameter(string paramName, out ParameterDefn defn)
495 {
496 bool ret = false;
497 ParameterDefn foundDefn = new ParameterDefn();
498 string pName = paramName.ToLower();
499
500 foreach (ParameterDefn parm in ParameterDefinitions)
501 {
502 if (pName == parm.name.ToLower())
503 {
504 foundDefn = parm;
505 ret = true;
506 break;
507 }
508 }
509 defn = foundDefn;
510 return ret;
511 }
512
513 // Pass through the settable parameters and set the default values
514 internal static void SetParameterDefaultValues(BSScene physicsScene)
515 {
516 foreach (ParameterDefn parm in ParameterDefinitions)
517 {
518 parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue);
519 }
520 }
521
522 // Get user set values out of the ini file.
523 internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg)
524 {
525 foreach (ParameterDefn parm in ParameterDefinitions)
526 {
527 parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue);
528 }
529 }
530
531 internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
532
533 // This creates an array in the correct format for returning the list of
534 // parameters. This is used by the 'list' option of the 'physics' command.
535 internal static void BuildParameterTable()
536 {
537 if (SettableParameters.Length < ParameterDefinitions.Length)
538 {
539 List<PhysParameterEntry> entries = new List<PhysParameterEntry>();
540 for (int ii = 0; ii < ParameterDefinitions.Length; ii++)
541 {
542 ParameterDefn pd = ParameterDefinitions[ii];
543 entries.Add(new PhysParameterEntry(pd.name, pd.desc));
544 }
545
546 // make the list in alphabetical order for estetic reasons
547 entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2)
548 {
549 return ppe1.name.CompareTo(ppe2.name);
550 });
551
552 SettableParameters = entries.ToArray();
553 }
554 }
555
556
557}
558}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 68a0db6..e43bf8e 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -720,10 +720,10 @@ public sealed class BSPrim : BSPhysObject
720 // Mass is zero which disables a bunch of physics stuff in Bullet 720 // Mass is zero which disables a bunch of physics stuff in Bullet
721 UpdatePhysicalMassProperties(0f); 721 UpdatePhysicalMassProperties(0f);
722 // Set collision detection parameters 722 // Set collision detection parameters
723 if (PhysicsScene.Params.ccdMotionThreshold > 0f) 723 if (BSParam.CcdMotionThreshold > 0f)
724 { 724 {
725 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); 725 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold);
726 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); 726 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
727 } 727 }
728 728
729 // The activation state is 'disabled' so Bullet will not try to act on it. 729 // The activation state is 'disabled' so Bullet will not try to act on it.
@@ -761,17 +761,17 @@ public sealed class BSPrim : BSPhysObject
761 UpdatePhysicalMassProperties(RawMass); 761 UpdatePhysicalMassProperties(RawMass);
762 762
763 // Set collision detection parameters 763 // Set collision detection parameters
764 if (PhysicsScene.Params.ccdMotionThreshold > 0f) 764 if (BSParam.CcdMotionThreshold > 0f)
765 { 765 {
766 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); 766 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold);
767 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); 767 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
768 } 768 }
769 769
770 // Various values for simulation limits 770 // Various values for simulation limits
771 BulletSimAPI.SetDamping2(PhysBody.ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); 771 BulletSimAPI.SetDamping2(PhysBody.ptr, BSParam.LinearDamping, BSParam.AngularDamping);
772 BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, PhysicsScene.Params.deactivationTime); 772 BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, BSParam.DeactivationTime);
773 BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); 773 BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold);
774 BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); 774 BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold);
775 775
776 // This collides like an object. 776 // This collides like an object.
777 PhysBody.collisionType = CollisionType.Dynamic; 777 PhysBody.collisionType = CollisionType.Dynamic;
@@ -1361,11 +1361,7 @@ public sealed class BSPrim : BSPhysObject
1361 } 1361 }
1362 */ 1362 */
1363 1363
1364 if (returnMass <= 0) 1364 returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
1365 returnMass = 0.0001f;
1366
1367 if (returnMass > PhysicsScene.MaximumObjectMass)
1368 returnMass = PhysicsScene.MaximumObjectMass;
1369 1365
1370 return returnMass; 1366 return returnMass;
1371 }// end CalculateMass 1367 }// end CalculateMass
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 2ca4912..492a255 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -77,12 +77,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
77 public ILog Logger { get { return m_log; } } 77 public ILog Logger { get { return m_log; } }
78 78
79 public IMesher mesher; 79 public IMesher mesher;
80 // Level of Detail values kept as float because that's what the Meshmerizer wants
81 public float MeshLOD { get; private set; }
82 public float MeshMegaPrimLOD { get; private set; }
83 public float MeshMegaPrimThreshold { get; private set; }
84 public float SculptLOD { get; private set; }
85
86 public uint WorldID { get; private set; } 80 public uint WorldID { get; private set; }
87 public BulletSim World { get; private set; } 81 public BulletSim World { get; private set; }
88 82
@@ -90,21 +84,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
90 public BSConstraintCollection Constraints { get; private set; } 84 public BSConstraintCollection Constraints { get; private set; }
91 85
92 // Simulation parameters 86 // Simulation parameters
93 private int m_maxSubSteps; 87 internal int m_maxSubSteps;
94 private float m_fixedTimeStep; 88 internal float m_fixedTimeStep;
95 private long m_simulationStep = 0; 89 internal long m_simulationStep = 0;
96 public long SimulationStep { get { return m_simulationStep; } } 90 public long SimulationStep { get { return m_simulationStep; } }
97 private int m_taintsToProcessPerStep; 91 internal int m_taintsToProcessPerStep;
98
99 // Avatar parameters
100 public float ParamAvatarFriction { get; private set; }
101 public float ParamAvatarStandingFriction { get; private set; }
102 public float ParamAvatarDensity { get; private set; }
103 public float ParamAvatarRestitution { get; private set; }
104 public float ParamAvatarCapsuleWidth { get; private set; }
105 public float ParamAvatarCapsuleDepth { get; private set; }
106 public float ParamAvatarCapsuleHeight { get; private set; }
107 public float ParamAvatarContactProcessingThreshold { get; private set; }
108 92
109 public delegate void PreStepAction(float timeStep); 93 public delegate void PreStepAction(float timeStep);
110 public event PreStepAction BeforeStep; 94 public event PreStepAction BeforeStep;
@@ -121,20 +105,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
121 public bool InTaintTime { get; private set; } 105 public bool InTaintTime { get; private set; }
122 106
123 // Pinned memory used to pass step information between managed and unmanaged 107 // Pinned memory used to pass step information between managed and unmanaged
124 private int m_maxCollisionsPerFrame; 108 internal int m_maxCollisionsPerFrame;
125 private CollisionDesc[] m_collisionArray; 109 internal CollisionDesc[] m_collisionArray;
126 private GCHandle m_collisionArrayPinnedHandle; 110 internal GCHandle m_collisionArrayPinnedHandle;
127
128 private int m_maxUpdatesPerFrame;
129 private EntityProperties[] m_updateArray;
130 private GCHandle m_updateArrayPinnedHandle;
131 111
132 public bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed 112 internal int m_maxUpdatesPerFrame;
133 public bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes 113 internal EntityProperties[] m_updateArray;
134 public bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects 114 internal GCHandle m_updateArrayPinnedHandle;
135
136 public float PID_D { get; private set; } // derivative
137 public float PID_P { get; private set; } // proportional
138 115
139 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero 116 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
140 public const uint GROUNDPLANE_ID = 1; 117 public const uint GROUNDPLANE_ID = 1;
@@ -145,7 +122,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
145 122
146 public ConfigurationParameters Params 123 public ConfigurationParameters Params
147 { 124 {
148 get { return m_params[0]; } 125 get { return UnmanagedParams[0]; }
149 } 126 }
150 public Vector3 DefaultGravity 127 public Vector3 DefaultGravity
151 { 128 {
@@ -157,8 +134,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
157 get { return Params.gravity; } 134 get { return Params.gravity; }
158 } 135 }
159 136
160 public float MaximumObjectMass { get; private set; }
161
162 // When functions in the unmanaged code must be called, it is only 137 // When functions in the unmanaged code must be called, it is only
163 // done at a known time just before the simulation step. The taint 138 // done at a known time just before the simulation step. The taint
164 // system saves all these function calls and executes them in 139 // system saves all these function calls and executes them in
@@ -181,7 +156,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
181 156
182 // A pointer to an instance if this structure is passed to the C++ code 157 // A pointer to an instance if this structure is passed to the C++ code
183 // Used to pass basic configuration values to the unmanaged code. 158 // Used to pass basic configuration values to the unmanaged code.
184 ConfigurationParameters[] m_params; 159 internal ConfigurationParameters[] UnmanagedParams;
185 GCHandle m_paramsHandle; 160 GCHandle m_paramsHandle;
186 161
187 // Handle to the callback used by the unmanaged code to call into the managed code. 162 // Handle to the callback used by the unmanaged code to call into the managed code.
@@ -218,8 +193,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
218 Shapes = new BSShapeCollection(this); 193 Shapes = new BSShapeCollection(this);
219 194
220 // Allocate pinned memory to pass parameters. 195 // Allocate pinned memory to pass parameters.
221 m_params = new ConfigurationParameters[1]; 196 UnmanagedParams = new ConfigurationParameters[1];
222 m_paramsHandle = GCHandle.Alloc(m_params, GCHandleType.Pinned); 197 m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned);
223 198
224 // Set default values for physics parameters plus any overrides from the ini file 199 // Set default values for physics parameters plus any overrides from the ini file
225 GetInitialParameterValues(config); 200 GetInitialParameterValues(config);
@@ -277,7 +252,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
277 TerrainManager = new BSTerrainManager(this); 252 TerrainManager = new BSTerrainManager(this);
278 TerrainManager.CreateInitialGroundPlaneAndTerrain(); 253 TerrainManager.CreateInitialGroundPlaneAndTerrain();
279 254
280 m_log.WarnFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)Params.linksetImplementation); 255 m_log.WarnFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation);
281 256
282 InTaintTime = false; 257 InTaintTime = false;
283 m_initialized = true; 258 m_initialized = true;
@@ -288,9 +263,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
288 private void GetInitialParameterValues(IConfigSource config) 263 private void GetInitialParameterValues(IConfigSource config)
289 { 264 {
290 ConfigurationParameters parms = new ConfigurationParameters(); 265 ConfigurationParameters parms = new ConfigurationParameters();
291 m_params[0] = parms; 266 UnmanagedParams[0] = parms;
292 267
293 SetParameterDefaultValues(); 268 BSParam.SetParameterDefaultValues(this);
294 269
295 if (config != null) 270 if (config != null)
296 { 271 {
@@ -298,7 +273,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
298 IConfig pConfig = config.Configs["BulletSim"]; 273 IConfig pConfig = config.Configs["BulletSim"];
299 if (pConfig != null) 274 if (pConfig != null)
300 { 275 {
301 SetParameterConfigurationValues(pConfig); 276 BSParam.SetParameterConfigurationValues(this, pConfig);
302 277
303 // Very detailed logging for physics debugging 278 // Very detailed logging for physics debugging
304 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); 279 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
@@ -889,7 +864,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
889 { 864 {
890 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); 865 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
891 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); 866 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
892 Util.PrintCallStack(); // Prints the stack into the DEBUG log file. 867 Util.PrintCallStack(DetailLog); // Prints the stack into the DEBUG log file.
893 } 868 }
894 return InTaintTime; 869 return InTaintTime;
895 } 870 }
@@ -936,12 +911,15 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
936 911
937 private void DoPreStepActions(float timeStep) 912 private void DoPreStepActions(float timeStep)
938 { 913 {
914 InTaintTime = true; // Only used for debugging so locking is not necessary.
939 ProcessVehicles(timeStep); 915 ProcessVehicles(timeStep);
940 916
941 PreStepAction actions = BeforeStep; 917 PreStepAction actions = BeforeStep;
942 if (actions != null) 918 if (actions != null)
943 actions(timeStep); 919 actions(timeStep);
944 920
921 InTaintTime = false;
922
945 } 923 }
946 924
947 // Some prims have extra vehicle actions 925 // Some prims have extra vehicle actions
@@ -957,472 +935,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
957 935
958 #region INI and command line parameter processing 936 #region INI and command line parameter processing
959 937
960 delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
961 delegate float ParamGet(BSScene scene);
962 delegate void ParamSet(BSScene scene, string paramName, uint localID, float val);
963 delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val);
964
965 private struct ParameterDefn
966 {
967 public string name; // string name of the parameter
968 public string desc; // a short description of what the parameter means
969 public float defaultValue; // default value if not specified anywhere else
970 public ParamUser userParam; // get the value from the configuration file
971 public ParamGet getter; // return the current value stored for this parameter
972 public ParamSet setter; // set the current value for this parameter
973 public SetOnObject onObject; // set the value on an object in the physical domain
974 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
975 {
976 name = n;
977 desc = d;
978 defaultValue = v;
979 userParam = u;
980 getter = g;
981 setter = s;
982 onObject = null;
983 }
984 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o)
985 {
986 name = n;
987 desc = d;
988 defaultValue = v;
989 userParam = u;
990 getter = g;
991 setter = s;
992 onObject = o;
993 }
994 }
995
996 // List of all of the externally visible parameters.
997 // For each parameter, this table maps a text name to getter and setters.
998 // To add a new externally referencable/settable parameter, add the paramter storage
999 // location somewhere in the program and make an entry in this table with the
1000 // getters and setters.
1001 // It is easiest to find an existing definition and copy it.
1002 // Parameter values are floats. Booleans are converted to a floating value.
1003 //
1004 // A ParameterDefn() takes the following parameters:
1005 // -- the text name of the parameter. This is used for console input and ini file.
1006 // -- a short text description of the parameter. This shows up in the console listing.
1007 // -- a delegate for fetching the parameter from the ini file.
1008 // Should handle fetching the right type from the ini file and converting it.
1009 // -- a delegate for getting the value as a float
1010 // -- a delegate for setting the value from a float
1011 // -- an optional delegate to update the value in the world. Most often used to
1012 // push the new value to an in-world object.
1013 //
1014 // The single letter parameters for the delegates are:
1015 // s = BSScene
1016 // o = BSPhysObject
1017 // p = string parameter name
1018 // l = localID of referenced object
1019 // v = float value
1020 // cf = parameter configuration class (for fetching values from ini file)
1021 private ParameterDefn[] ParameterDefinitions =
1022 {
1023 new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties",
1024 ConfigurationParameters.numericTrue,
1025 (s,cf,p,v) => { s.ShouldMeshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); },
1026 (s) => { return s.NumericBool(s.ShouldMeshSculptedPrim); },
1027 (s,p,l,v) => { s.ShouldMeshSculptedPrim = s.BoolNumeric(v); } ),
1028 new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects",
1029 ConfigurationParameters.numericFalse,
1030 (s,cf,p,v) => { s.ShouldForceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); },
1031 (s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); },
1032 (s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ),
1033 new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects",
1034 ConfigurationParameters.numericTrue,
1035 (s,cf,p,v) => { s.ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, s.BoolNumeric(v)); },
1036 (s) => { return s.NumericBool(s.ShouldUseHullsForPhysicalObjects); },
1037 (s,p,l,v) => { s.ShouldUseHullsForPhysicalObjects = s.BoolNumeric(v); } ),
1038
1039 new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
1040 8f,
1041 (s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); },
1042 (s) => { return s.MeshLOD; },
1043 (s,p,l,v) => { s.MeshLOD = v; } ),
1044 new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
1045 16f,
1046 (s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
1047 (s) => { return s.MeshMegaPrimLOD; },
1048 (s,p,l,v) => { s.MeshMegaPrimLOD = v; } ),
1049 new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
1050 10f,
1051 (s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
1052 (s) => { return s.MeshMegaPrimThreshold; },
1053 (s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ),
1054 new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
1055 32f,
1056 (s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); },
1057 (s) => { return s.SculptLOD; },
1058 (s,p,l,v) => { s.SculptLOD = v; } ),
1059
1060 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
1061 10f,
1062 (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); },
1063 (s) => { return (float)s.m_maxSubSteps; },
1064 (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ),
1065 new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)",
1066 1f / 60f,
1067 (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); },
1068 (s) => { return (float)s.m_fixedTimeStep; },
1069 (s,p,l,v) => { s.m_fixedTimeStep = v; } ),
1070 new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame",
1071 2048f,
1072 (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); },
1073 (s) => { return (float)s.m_maxCollisionsPerFrame; },
1074 (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ),
1075 new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame",
1076 8000f,
1077 (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); },
1078 (s) => { return (float)s.m_maxUpdatesPerFrame; },
1079 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
1080 new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step",
1081 500f,
1082 (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); },
1083 (s) => { return (float)s.m_taintsToProcessPerStep; },
1084 (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ),
1085 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
1086 10000.01f,
1087 (s,cf,p,v) => { s.MaximumObjectMass = cf.GetFloat(p, v); },
1088 (s) => { return (float)s.MaximumObjectMass; },
1089 (s,p,l,v) => { s.MaximumObjectMass = v; } ),
1090
1091 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
1092 2200f,
1093 (s,cf,p,v) => { s.PID_D = cf.GetFloat(p, v); },
1094 (s) => { return (float)s.PID_D; },
1095 (s,p,l,v) => { s.PID_D = v; } ),
1096 new ParameterDefn("PID_P", "Parameteric factor for motion smoothing",
1097 900f,
1098 (s,cf,p,v) => { s.PID_P = cf.GetFloat(p, v); },
1099 (s) => { return (float)s.PID_P; },
1100 (s,p,l,v) => { s.PID_P = v; } ),
1101
1102 new ParameterDefn("DefaultFriction", "Friction factor used on new objects",
1103 0.2f,
1104 (s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); },
1105 (s) => { return s.m_params[0].defaultFriction; },
1106 (s,p,l,v) => { s.m_params[0].defaultFriction = v; } ),
1107 new ParameterDefn("DefaultDensity", "Density for new objects" ,
1108 10.000006836f, // Aluminum g/cm3
1109 (s,cf,p,v) => { s.m_params[0].defaultDensity = cf.GetFloat(p, v); },
1110 (s) => { return s.m_params[0].defaultDensity; },
1111 (s,p,l,v) => { s.m_params[0].defaultDensity = v; } ),
1112 new ParameterDefn("DefaultRestitution", "Bouncyness of an object" ,
1113 0f,
1114 (s,cf,p,v) => { s.m_params[0].defaultRestitution = cf.GetFloat(p, v); },
1115 (s) => { return s.m_params[0].defaultRestitution; },
1116 (s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ),
1117 new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)",
1118 0.04f,
1119 (s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); },
1120 (s) => { return s.m_params[0].collisionMargin; },
1121 (s,p,l,v) => { s.m_params[0].collisionMargin = v; } ),
1122 new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)",
1123 -9.80665f,
1124 (s,cf,p,v) => { s.m_params[0].gravity = cf.GetFloat(p, v); },
1125 (s) => { return s.m_params[0].gravity; },
1126 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].gravity, p, PhysParameterEntry.APPLY_TO_NONE, v); },
1127 (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ),
1128
1129
1130 new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)",
1131 0f,
1132 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
1133 (s) => { return s.m_params[0].linearDamping; },
1134 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); },
1135 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, s.m_params[0].angularDamping); } ),
1136 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
1137 0f,
1138 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
1139 (s) => { return s.m_params[0].angularDamping; },
1140 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); },
1141 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, s.m_params[0].linearDamping, v); } ),
1142 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
1143 0.2f,
1144 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
1145 (s) => { return s.m_params[0].deactivationTime; },
1146 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); },
1147 (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ),
1148 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
1149 0.8f,
1150 (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); },
1151 (s) => { return s.m_params[0].linearSleepingThreshold; },
1152 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); },
1153 (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
1154 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
1155 1.0f,
1156 (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); },
1157 (s) => { return s.m_params[0].angularSleepingThreshold; },
1158 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); },
1159 (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
1160 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
1161 0f, // set to zero to disable
1162 (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); },
1163 (s) => { return s.m_params[0].ccdMotionThreshold; },
1164 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); },
1165 (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ),
1166 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
1167 0f,
1168 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
1169 (s) => { return s.m_params[0].ccdSweptSphereRadius; },
1170 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); },
1171 (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ),
1172 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
1173 0.1f,
1174 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
1175 (s) => { return s.m_params[0].contactProcessingThreshold; },
1176 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); },
1177 (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ),
1178
1179 new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
1180 (float)BSTerrainPhys.TerrainImplementation.Mesh,
1181 (s,cf,p,v) => { s.m_params[0].terrainImplementation = cf.GetFloat(p,v); },
1182 (s) => { return s.m_params[0].terrainImplementation; },
1183 (s,p,l,v) => { s.m_params[0].terrainImplementation = v; } ),
1184 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
1185 0.3f,
1186 (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); },
1187 (s) => { return s.m_params[0].terrainFriction; },
1188 (s,p,l,v) => { s.m_params[0].terrainFriction = v; /* TODO: set on real terrain */} ),
1189 new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" ,
1190 0.8f,
1191 (s,cf,p,v) => { s.m_params[0].terrainHitFraction = cf.GetFloat(p, v); },
1192 (s) => { return s.m_params[0].terrainHitFraction; },
1193 (s,p,l,v) => { s.m_params[0].terrainHitFraction = v; /* TODO: set on real terrain */ } ),
1194 new ParameterDefn("TerrainRestitution", "Bouncyness" ,
1195 0f,
1196 (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); },
1197 (s) => { return s.m_params[0].terrainRestitution; },
1198 (s,p,l,v) => { s.m_params[0].terrainRestitution = v; /* TODO: set on real terrain */ } ),
1199 new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" ,
1200 0.04f,
1201 (s,cf,p,v) => { s.m_params[0].terrainCollisionMargin = cf.GetFloat(p, v); },
1202 (s) => { return s.m_params[0].terrainCollisionMargin; },
1203 (s,p,l,v) => { s.m_params[0].terrainCollisionMargin = v; /* TODO: set on real terrain */ } ),
1204
1205 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
1206 0.2f,
1207 (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
1208 (s) => { return s.m_params[0].avatarFriction; },
1209 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ),
1210 new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
1211 10.0f,
1212 (s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); },
1213 (s) => { return s.m_params[0].avatarStandingFriction; },
1214 (s,p,l,v) => { s.m_params[0].avatarStandingFriction = v; } ),
1215 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
1216 60f,
1217 (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); },
1218 (s) => { return s.m_params[0].avatarDensity; },
1219 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarDensity, p, l, v); } ),
1220 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
1221 0f,
1222 (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); },
1223 (s) => { return s.m_params[0].avatarRestitution; },
1224 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ),
1225 new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule",
1226 0.6f,
1227 (s,cf,p,v) => { s.m_params[0].avatarCapsuleWidth = cf.GetFloat(p, v); },
1228 (s) => { return s.m_params[0].avatarCapsuleWidth; },
1229 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleWidth, p, l, v); } ),
1230 new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule",
1231 0.45f,
1232 (s,cf,p,v) => { s.m_params[0].avatarCapsuleDepth = cf.GetFloat(p, v); },
1233 (s) => { return s.m_params[0].avatarCapsuleDepth; },
1234 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleDepth, p, l, v); } ),
1235 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
1236 1.5f,
1237 (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); },
1238 (s) => { return s.m_params[0].avatarCapsuleHeight; },
1239 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),
1240 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
1241 0.1f,
1242 (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); },
1243 (s) => { return s.m_params[0].avatarContactProcessingThreshold; },
1244 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
1245
1246 new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
1247 0.95f,
1248 (s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); },
1249 (s) => { return s.m_params[0].vehicleAngularDamping; },
1250 (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ),
1251
1252 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
1253 0f,
1254 (s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
1255 (s) => { return s.m_params[0].maxPersistantManifoldPoolSize; },
1256 (s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ),
1257 new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
1258 0f,
1259 (s,cf,p,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); },
1260 (s) => { return s.m_params[0].maxCollisionAlgorithmPoolSize; },
1261 (s,p,l,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = v; } ),
1262 new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
1263 ConfigurationParameters.numericFalse,
1264 (s,cf,p,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
1265 (s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; },
1266 (s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ),
1267 new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
1268 ConfigurationParameters.numericFalse,
1269 (s,cf,p,v) => { s.m_params[0].shouldForceUpdateAllAabbs = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
1270 (s) => { return s.m_params[0].shouldForceUpdateAllAabbs; },
1271 (s,p,l,v) => { s.m_params[0].shouldForceUpdateAllAabbs = v; } ),
1272 new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction",
1273 ConfigurationParameters.numericTrue,
1274 (s,cf,p,v) => { s.m_params[0].shouldRandomizeSolverOrder = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
1275 (s) => { return s.m_params[0].shouldRandomizeSolverOrder; },
1276 (s,p,l,v) => { s.m_params[0].shouldRandomizeSolverOrder = v; } ),
1277 new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands",
1278 ConfigurationParameters.numericTrue,
1279 (s,cf,p,v) => { s.m_params[0].shouldSplitSimulationIslands = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
1280 (s) => { return s.m_params[0].shouldSplitSimulationIslands; },
1281 (s,p,l,v) => { s.m_params[0].shouldSplitSimulationIslands = v; } ),
1282 new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching",
1283 ConfigurationParameters.numericFalse,
1284 (s,cf,p,v) => { s.m_params[0].shouldEnableFrictionCaching = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
1285 (s) => { return s.m_params[0].shouldEnableFrictionCaching; },
1286 (s,p,l,v) => { s.m_params[0].shouldEnableFrictionCaching = v; } ),
1287 new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)",
1288 0f, // zero says use Bullet default
1289 (s,cf,p,v) => { s.m_params[0].numberOfSolverIterations = cf.GetFloat(p, v); },
1290 (s) => { return s.m_params[0].numberOfSolverIterations; },
1291 (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ),
1292
1293 new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
1294 (float)BSLinkset.LinksetImplementation.Compound,
1295 (s,cf,p,v) => { s.m_params[0].linksetImplementation = cf.GetFloat(p,v); },
1296 (s) => { return s.m_params[0].linksetImplementation; },
1297 (s,p,l,v) => { s.m_params[0].linksetImplementation = v; } ),
1298 new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
1299 ConfigurationParameters.numericFalse,
1300 (s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
1301 (s) => { return s.m_params[0].linkConstraintUseFrameOffset; },
1302 (s,p,l,v) => { s.m_params[0].linkConstraintUseFrameOffset = v; } ),
1303 new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
1304 ConfigurationParameters.numericTrue,
1305 (s,cf,p,v) => { s.m_params[0].linkConstraintEnableTransMotor = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
1306 (s) => { return s.m_params[0].linkConstraintEnableTransMotor; },
1307 (s,p,l,v) => { s.m_params[0].linkConstraintEnableTransMotor = v; } ),
1308 new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints",
1309 5.0f,
1310 (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = cf.GetFloat(p, v); },
1311 (s) => { return s.m_params[0].linkConstraintTransMotorMaxVel; },
1312 (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = v; } ),
1313 new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints",
1314 0.1f,
1315 (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
1316 (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; },
1317 (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ),
1318 new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
1319 0.1f,
1320 (s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); },
1321 (s) => { return s.m_params[0].linkConstraintCFM; },
1322 (s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ),
1323 new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
1324 0.1f,
1325 (s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); },
1326 (s) => { return s.m_params[0].linkConstraintERP; },
1327 (s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ),
1328 new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
1329 40,
1330 (s,cf,p,v) => { s.m_params[0].linkConstraintSolverIterations = cf.GetFloat(p, v); },
1331 (s) => { return s.m_params[0].linkConstraintSolverIterations; },
1332 (s,p,l,v) => { s.m_params[0].linkConstraintSolverIterations = v; } ),
1333
1334 new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)",
1335 0f,
1336 (s,cf,p,v) => { s.m_params[0].physicsLoggingFrames = cf.GetInt(p, (int)v); },
1337 (s) => { return (float)s.m_params[0].physicsLoggingFrames; },
1338 (s,p,l,v) => { s.m_params[0].physicsLoggingFrames = (int)v; } ),
1339 };
1340
1341 // Convert a boolean to our numeric true and false values
1342 public float NumericBool(bool b)
1343 {
1344 return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse);
1345 }
1346
1347 // Convert numeric true and false values to a boolean
1348 public bool BoolNumeric(float b)
1349 {
1350 return (b == ConfigurationParameters.numericTrue ? true : false);
1351 }
1352
1353 // Search through the parameter definitions and return the matching
1354 // ParameterDefn structure.
1355 // Case does not matter as names are compared after converting to lower case.
1356 // Returns 'false' if the parameter is not found.
1357 private bool TryGetParameter(string paramName, out ParameterDefn defn)
1358 {
1359 bool ret = false;
1360 ParameterDefn foundDefn = new ParameterDefn();
1361 string pName = paramName.ToLower();
1362
1363 foreach (ParameterDefn parm in ParameterDefinitions)
1364 {
1365 if (pName == parm.name.ToLower())
1366 {
1367 foundDefn = parm;
1368 ret = true;
1369 break;
1370 }
1371 }
1372 defn = foundDefn;
1373 return ret;
1374 }
1375
1376 // Pass through the settable parameters and set the default values
1377 private void SetParameterDefaultValues()
1378 {
1379 foreach (ParameterDefn parm in ParameterDefinitions)
1380 {
1381 parm.setter(this, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue);
1382 }
1383 }
1384
1385 // Get user set values out of the ini file.
1386 private void SetParameterConfigurationValues(IConfig cfg)
1387 {
1388 foreach (ParameterDefn parm in ParameterDefinitions)
1389 {
1390 parm.userParam(this, cfg, parm.name, parm.defaultValue);
1391 }
1392 }
1393
1394 private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
1395
1396 // This creates an array in the correct format for returning the list of
1397 // parameters. This is used by the 'list' option of the 'physics' command.
1398 private void BuildParameterTable()
1399 {
1400 if (SettableParameters.Length < ParameterDefinitions.Length)
1401 {
1402 List<PhysParameterEntry> entries = new List<PhysParameterEntry>();
1403 for (int ii = 0; ii < ParameterDefinitions.Length; ii++)
1404 {
1405 ParameterDefn pd = ParameterDefinitions[ii];
1406 entries.Add(new PhysParameterEntry(pd.name, pd.desc));
1407 }
1408
1409 // make the list in alphabetical order for estetic reasons
1410 entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2)
1411 {
1412 return ppe1.name.CompareTo(ppe2.name);
1413 });
1414
1415 SettableParameters = entries.ToArray();
1416 }
1417 }
1418
1419
1420 #region IPhysicsParameters 938 #region IPhysicsParameters
1421 // Get the list of parameters this physics engine supports 939 // Get the list of parameters this physics engine supports
1422 public PhysParameterEntry[] GetParameterList() 940 public PhysParameterEntry[] GetParameterList()
1423 { 941 {
1424 BuildParameterTable(); 942 BSParam.BuildParameterTable();
1425 return SettableParameters; 943 return BSParam.SettableParameters;
1426 } 944 }
1427 945
1428 // Set parameter on a specific or all instances. 946 // Set parameter on a specific or all instances.
@@ -1434,8 +952,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1434 public bool SetPhysicsParameter(string parm, float val, uint localID) 952 public bool SetPhysicsParameter(string parm, float val, uint localID)
1435 { 953 {
1436 bool ret = false; 954 bool ret = false;
1437 ParameterDefn theParam; 955 BSParam.ParameterDefn theParam;
1438 if (TryGetParameter(parm, out theParam)) 956 if (BSParam.TryGetParameter(parm, out theParam))
1439 { 957 {
1440 theParam.setter(this, parm, localID, val); 958 theParam.setter(this, parm, localID, val);
1441 ret = true; 959 ret = true;
@@ -1447,19 +965,20 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1447 // If the local ID is APPLY_TO_NONE, just change the default value 965 // If the local ID is APPLY_TO_NONE, just change the default value
1448 // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs 966 // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs
1449 // If the localID is a specific object, apply the parameter change to only that object 967 // If the localID is a specific object, apply the parameter change to only that object
1450 private void UpdateParameterObject(ref float defaultLoc, string parm, uint localID, float val) 968 internal delegate void AssignVal(float x);
969 internal void UpdateParameterObject(AssignVal setDefault, string parm, uint localID, float val)
1451 { 970 {
1452 List<uint> objectIDs = new List<uint>(); 971 List<uint> objectIDs = new List<uint>();
1453 switch (localID) 972 switch (localID)
1454 { 973 {
1455 case PhysParameterEntry.APPLY_TO_NONE: 974 case PhysParameterEntry.APPLY_TO_NONE:
1456 defaultLoc = val; // setting only the default value 975 setDefault(val); // setting only the default value
1457 // This will cause a call into the physical world if some operation is specified (SetOnObject). 976 // This will cause a call into the physical world if some operation is specified (SetOnObject).
1458 objectIDs.Add(TERRAIN_ID); 977 objectIDs.Add(TERRAIN_ID);
1459 TaintedUpdateParameter(parm, objectIDs, val); 978 TaintedUpdateParameter(parm, objectIDs, val);
1460 break; 979 break;
1461 case PhysParameterEntry.APPLY_TO_ALL: 980 case PhysParameterEntry.APPLY_TO_ALL:
1462 defaultLoc = val; // setting ALL also sets the default value 981 setDefault(val); // setting ALL also sets the default value
1463 lock (PhysObjects) objectIDs = new List<uint>(PhysObjects.Keys); 982 lock (PhysObjects) objectIDs = new List<uint>(PhysObjects.Keys);
1464 TaintedUpdateParameter(parm, objectIDs, val); 983 TaintedUpdateParameter(parm, objectIDs, val);
1465 break; 984 break;
@@ -1478,8 +997,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1478 List<uint> xlIDs = lIDs; 997 List<uint> xlIDs = lIDs;
1479 string xparm = parm; 998 string xparm = parm;
1480 TaintedObject("BSScene.UpdateParameterSet", delegate() { 999 TaintedObject("BSScene.UpdateParameterSet", delegate() {
1481 ParameterDefn thisParam; 1000 BSParam.ParameterDefn thisParam;
1482 if (TryGetParameter(xparm, out thisParam)) 1001 if (BSParam.TryGetParameter(xparm, out thisParam))
1483 { 1002 {
1484 if (thisParam.onObject != null) 1003 if (thisParam.onObject != null)
1485 { 1004 {
@@ -1500,8 +1019,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1500 { 1019 {
1501 float val = 0f; 1020 float val = 0f;
1502 bool ret = false; 1021 bool ret = false;
1503 ParameterDefn theParam; 1022 BSParam.ParameterDefn theParam;
1504 if (TryGetParameter(parm, out theParam)) 1023 if (BSParam.TryGetParameter(parm, out theParam))
1505 { 1024 {
1506 val = theParam.getter(this); 1025 val = theParam.getter(this);
1507 ret = true; 1026 ret = true;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index ea996ae..939d5e9 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -456,7 +456,7 @@ public sealed class BSShapeCollection : IDisposable
456 if (!haveShape 456 if (!haveShape
457 && pbs != null 457 && pbs != null
458 && nativeShapePossible 458 && nativeShapePossible
459 && ((pbs.SculptEntry && !PhysicsScene.ShouldMeshSculptedPrim) 459 && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim)
460 || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 460 || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
461 && pbs.ProfileHollow == 0 461 && pbs.ProfileHollow == 0
462 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 462 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
@@ -520,7 +520,7 @@ public sealed class BSShapeCollection : IDisposable
520 bool ret = false; 520 bool ret = false;
521 // Note that if it's a native shape, the check for physical/non-physical is not 521 // Note that if it's a native shape, the check for physical/non-physical is not
522 // made. Native shapes work in either case. 522 // made. Native shapes work in either case.
523 if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) 523 if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects)
524 { 524 {
525 // Update prim.BSShape to reference a hull of this shape. 525 // Update prim.BSShape to reference a hull of this shape.
526 ret = GetReferenceToHull(prim,shapeCallback); 526 ret = GetReferenceToHull(prim,shapeCallback);
@@ -836,14 +836,14 @@ public sealed class BSShapeCollection : IDisposable
836 private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) 836 private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod)
837 { 837 {
838 // level of detail based on size and type of the object 838 // level of detail based on size and type of the object
839 float lod = PhysicsScene.MeshLOD; 839 float lod = BSParam.MeshLOD;
840 if (pbs.SculptEntry) 840 if (pbs.SculptEntry)
841 lod = PhysicsScene.SculptLOD; 841 lod = BSParam.SculptLOD;
842 842
843 // Mega prims usually get more detail because one can interact with shape approximations at this size. 843 // Mega prims usually get more detail because one can interact with shape approximations at this size.
844 float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); 844 float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z));
845 if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) 845 if (maxAxis > BSParam.MeshMegaPrimThreshold)
846 lod = PhysicsScene.MeshMegaPrimLOD; 846 lod = BSParam.MeshMegaPrimLOD;
847 847
848 retLod = lod; 848 retLod = lod;
849 return pbs.GetMeshKey(size, lod); 849 return pbs.GetMeshKey(size, lod);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
index 2b120d6..07a9fd8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
@@ -93,7 +93,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
93 { 93 {
94 m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, 94 m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
95 m_mapInfo.minCoords, m_mapInfo.maxCoords, 95 m_mapInfo.minCoords, m_mapInfo.maxCoords,
96 m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin); 96 m_mapInfo.heightMap, BSParam.TerrainCollisionMargin);
97 97
98 // Create the terrain shape from the mapInfo 98 // Create the terrain shape from the mapInfo
99 m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), 99 m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr),
@@ -110,9 +110,9 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
110 m_mapInfo.ID, centerPos, Quaternion.Identity)); 110 m_mapInfo.ID, centerPos, Quaternion.Identity));
111 111
112 // Set current terrain attributes 112 // Set current terrain attributes
113 BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); 113 BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction);
114 BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); 114 BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainHitFraction);
115 BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); 115 BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, BSParam.TerrainRestitution);
116 BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 116 BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
117 117
118 // Return the new terrain to the world of physical objects 118 // Return the new terrain to the world of physical objects
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 3428b9c..86ccfbb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -135,7 +135,7 @@ public sealed class BSTerrainManager : IDisposable
135 // The ground plane is here to catch things that are trying to drop to negative infinity 135 // The ground plane is here to catch things that are trying to drop to negative infinity
136 BulletShape groundPlaneShape = new BulletShape( 136 BulletShape groundPlaneShape = new BulletShape(
137 BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, 137 BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f,
138 PhysicsScene.Params.terrainCollisionMargin), 138 BSParam.TerrainCollisionMargin),
139 BSPhysicsShapeType.SHAPE_GROUNDPLANE); 139 BSPhysicsShapeType.SHAPE_GROUNDPLANE);
140 m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, 140 m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
141 BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, 141 BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
@@ -309,9 +309,9 @@ public sealed class BSTerrainManager : IDisposable
309 { 309 {
310 PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}", 310 PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}",
311 LogHeader, PhysicsScene.RegionName, terrainRegionBase, 311 LogHeader, PhysicsScene.RegionName, terrainRegionBase,
312 (BSTerrainPhys.TerrainImplementation)PhysicsScene.Params.terrainImplementation); 312 (BSTerrainPhys.TerrainImplementation)BSParam.TerrainImplementation);
313 BSTerrainPhys newTerrainPhys = null; 313 BSTerrainPhys newTerrainPhys = null;
314 switch ((int)PhysicsScene.Params.terrainImplementation) 314 switch ((int)BSParam.TerrainImplementation)
315 { 315 {
316 case (int)BSTerrainPhys.TerrainImplementation.Heightmap: 316 case (int)BSTerrainPhys.TerrainImplementation.Heightmap:
317 newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, 317 newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id,
@@ -324,8 +324,8 @@ public sealed class BSTerrainManager : IDisposable
324 default: 324 default:
325 PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}", 325 PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}",
326 LogHeader, 326 LogHeader,
327 (int)PhysicsScene.Params.terrainImplementation, 327 (int)BSParam.TerrainImplementation,
328 PhysicsScene.Params.terrainImplementation, 328 BSParam.TerrainImplementation,
329 PhysicsScene.RegionName, terrainRegionBase); 329 PhysicsScene.RegionName, terrainRegionBase);
330 break; 330 break;
331 } 331 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
index 6dc0d92..061e232 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
@@ -116,9 +116,9 @@ public sealed class BSTerrainMesh : BSTerrainPhys
116 } 116 }
117 117
118 // Set current terrain attributes 118 // Set current terrain attributes
119 BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction); 119 BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction);
120 BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); 120 BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction);
121 BulletSimAPI.SetRestitution2(m_terrainBody.ptr, PhysicsScene.Params.terrainRestitution); 121 BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution);
122 BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 122 BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
123 123
124 // Static objects are not very massive. 124 // Static objects are not very massive.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 962b540..7857eaa 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -141,6 +141,8 @@ public struct EntityProperties
141} 141}
142 142
143// Format of this structure must match the definition in the C++ code 143// Format of this structure must match the definition in the C++ code
144// NOTE: adding the X causes compile breaks if used. These are unused symbols
145// that can be removed from both here and the unmanaged definition of this structure.
144[StructLayout(LayoutKind.Sequential)] 146[StructLayout(LayoutKind.Sequential)]
145public struct ConfigurationParameters 147public struct ConfigurationParameters
146{ 148{
@@ -150,31 +152,31 @@ public struct ConfigurationParameters
150 public float collisionMargin; 152 public float collisionMargin;
151 public float gravity; 153 public float gravity;
152 154
153 public float linearDamping; 155 public float XlinearDamping;
154 public float angularDamping; 156 public float XangularDamping;
155 public float deactivationTime; 157 public float XdeactivationTime;
156 public float linearSleepingThreshold; 158 public float XlinearSleepingThreshold;
157 public float angularSleepingThreshold; 159 public float XangularSleepingThreshold;
158 public float ccdMotionThreshold; 160 public float XccdMotionThreshold;
159 public float ccdSweptSphereRadius; 161 public float XccdSweptSphereRadius;
160 public float contactProcessingThreshold; 162 public float XcontactProcessingThreshold;
161 163
162 public float terrainImplementation; 164 public float XterrainImplementation;
163 public float terrainFriction; 165 public float XterrainFriction;
164 public float terrainHitFraction; 166 public float XterrainHitFraction;
165 public float terrainRestitution; 167 public float XterrainRestitution;
166 public float terrainCollisionMargin; 168 public float XterrainCollisionMargin;
167 169
168 public float avatarFriction; 170 public float XavatarFriction;
169 public float avatarStandingFriction; 171 public float XavatarStandingFriction;
170 public float avatarDensity; 172 public float XavatarDensity;
171 public float avatarRestitution; 173 public float XavatarRestitution;
172 public float avatarCapsuleWidth; 174 public float XavatarCapsuleWidth;
173 public float avatarCapsuleDepth; 175 public float XavatarCapsuleDepth;
174 public float avatarCapsuleHeight; 176 public float XavatarCapsuleHeight;
175 public float avatarContactProcessingThreshold; 177 public float XavatarContactProcessingThreshold;
176 178
177 public float vehicleAngularDamping; 179 public float XvehicleAngularDamping;
178 180
179 public float maxPersistantManifoldPoolSize; 181 public float maxPersistantManifoldPoolSize;
180 public float maxCollisionAlgorithmPoolSize; 182 public float maxCollisionAlgorithmPoolSize;
@@ -185,14 +187,14 @@ public struct ConfigurationParameters
185 public float shouldEnableFrictionCaching; 187 public float shouldEnableFrictionCaching;
186 public float numberOfSolverIterations; 188 public float numberOfSolverIterations;
187 189
188 public float linksetImplementation; 190 public float XlinksetImplementation;
189 public float linkConstraintUseFrameOffset; 191 public float XlinkConstraintUseFrameOffset;
190 public float linkConstraintEnableTransMotor; 192 public float XlinkConstraintEnableTransMotor;
191 public float linkConstraintTransMotorMaxVel; 193 public float XlinkConstraintTransMotorMaxVel;
192 public float linkConstraintTransMotorMaxForce; 194 public float XlinkConstraintTransMotorMaxForce;
193 public float linkConstraintERP; 195 public float XlinkConstraintERP;
194 public float linkConstraintCFM; 196 public float XlinkConstraintCFM;
195 public float linkConstraintSolverIterations; 197 public float XlinkConstraintSolverIterations;
196 198
197 public float physicsLoggingFrames; 199 public float physicsLoggingFrames;
198 200