aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs7
-rwxr-xr-xOpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs277
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs31
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs10
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs223
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs20
-rwxr-xr-xOpenSim/Region/Physics/Manager/IPhysicsParameters.cs73
7 files changed, 613 insertions, 28 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index 86ba2aa..97ee844 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -47,6 +47,12 @@ namespace OpenSim.Region.Framework.Scenes
47 47
48 public event RestartSim OnRestartSim; 48 public event RestartSim OnRestartSim;
49 49
50 private static SceneManager m_instance = null;
51 public static SceneManager Instance
52 {
53 get { return m_instance; }
54 }
55
50 private readonly List<Scene> m_localScenes; 56 private readonly List<Scene> m_localScenes;
51 private Scene m_currentScene = null; 57 private Scene m_currentScene = null;
52 58
@@ -84,6 +90,7 @@ namespace OpenSim.Region.Framework.Scenes
84 90
85 public SceneManager() 91 public SceneManager()
86 { 92 {
93 m_instance = this;
87 m_localScenes = new List<Scene>(); 94 m_localScenes = new List<Scene>();
88 } 95 }
89 96
diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
new file mode 100755
index 0000000..2a44360
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
@@ -0,0 +1,277 @@
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 copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections.Generic;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Console;
36using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Physics.Manager;
40
41namespace OpenSim.Region.OptionalModules.PhysicsParameters
42{
43 /// <summary>
44 /// </summary>
45 /// <remarks>
46 /// </remarks>
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PhysicsParameters")]
48 public class PhysicsParameters : ISharedRegionModule
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private static string LogHeader = "[PHYSICS PARAMETERS]";
52
53 private List<Scene> m_scenes = new List<Scene>();
54 private static bool m_commandsLoaded = false;
55
56 #region ISharedRegionModule
57 public string Name { get { return "Runtime Physics Parameter Module"; } }
58
59 public Type ReplaceableInterface { get { return null; } }
60
61 public void Initialise(IConfigSource source)
62 {
63 // m_log.DebugFormat("{0}: INITIALIZED MODULE", LogHeader);
64 }
65
66 public void PostInitialise()
67 {
68 // m_log.DebugFormat("[{0}: POST INITIALIZED MODULE", LogHeader);
69 InstallInterfaces();
70 }
71
72 public void Close()
73 {
74 // m_log.DebugFormat("{0}: CLOSED MODULE", LogHeader);
75 }
76
77 public void AddRegion(Scene scene)
78 {
79 // m_log.DebugFormat("{0}: REGION {1} ADDED", LogHeader, scene.RegionInfo.RegionName);
80 m_scenes.Add(scene);
81 }
82
83 public void RemoveRegion(Scene scene)
84 {
85 // m_log.DebugFormat("{0}: REGION {1} REMOVED", LogHeader, scene.RegionInfo.RegionName);
86 if (m_scenes.Contains(scene))
87 m_scenes.Remove(scene);
88 }
89
90 public void RegionLoaded(Scene scene)
91 {
92 // m_log.DebugFormat("{0}: REGION {1} LOADED", LogHeader, scene.RegionInfo.RegionName);
93 }
94 #endregion INonSharedRegionModule
95
96 private const string getInvocation = "physics get [<param>|ALL]";
97 private const string setInvocation = "physics set <param> [<value>|TRUE|FALSE] [localID|ALL]";
98 private const string listInvocation = "physics list";
99 private void InstallInterfaces()
100 {
101 if (!m_commandsLoaded)
102 {
103 MainConsole.Instance.Commands.AddCommand("Physics", false, "physics set",
104 "physics set",
105 "Set physics parameter from currently selected region" + Environment.NewLine
106 + "Invocation: " + setInvocation,
107 ProcessPhysicsSet);
108
109 MainConsole.Instance.Commands.AddCommand("Physics", false, "physics get",
110 "physics get",
111 "Get physics parameter from currently selected region" + Environment.NewLine
112 + "Invocation: " + getInvocation,
113 ProcessPhysicsGet);
114
115 MainConsole.Instance.Commands.AddCommand("Physics", false, "physics list",
116 "physics list",
117 "List settable physics parameters" + Environment.NewLine
118 + "Invocation: " + listInvocation,
119 ProcessPhysicsList);
120
121 m_commandsLoaded = true;
122 }
123 }
124
125 // TODO: extend get so you can get a value from an individual localID
126 private void ProcessPhysicsGet(string module, string[] cmdparms)
127 {
128 if (cmdparms.Length != 3)
129 {
130 WriteError("Parameter count error. Invocation: " + getInvocation);
131 return;
132 }
133 string parm = cmdparms[2];
134
135 if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null)
136 {
137 WriteError("Error: no region selected. Use 'change region' to select a region.");
138 return;
139 }
140
141 Scene scene = SceneManager.Instance.CurrentScene;
142 IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters;
143 if (physScene != null)
144 {
145 if (parm.ToLower() == "all")
146 {
147 foreach (PhysParameterEntry ppe in physScene.GetParameterList())
148 {
149 float val = 0.0f;
150 if (physScene.GetPhysicsParameter(ppe.name, out val))
151 {
152 WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, val);
153 }
154 else
155 {
156 WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, "unknown");
157 }
158 }
159 }
160 else
161 {
162 float val = 0.0f;
163 if (physScene.GetPhysicsParameter(parm, out val))
164 {
165 WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, parm, val);
166 }
167 else
168 {
169 WriteError("Failed fetch of parameter '{0}' from region '{1}'", parm, scene.RegionInfo.RegionName);
170 }
171 }
172 }
173 else
174 {
175 WriteError("Region '{0}' physics engine has no gettable physics parameters", scene.RegionInfo.RegionName);
176 }
177 return;
178 }
179
180 private void ProcessPhysicsSet(string module, string[] cmdparms)
181 {
182 if (cmdparms.Length < 4 || cmdparms.Length > 5)
183 {
184 WriteError("Parameter count error. Invocation: " + getInvocation);
185 return;
186 }
187 string parm = "xxx";
188 float val = 0f;
189 uint localID = (uint)PhysParameterEntry.APPLY_TO_NONE; // set default value
190 try
191 {
192 parm = cmdparms[2];
193 string valparm = cmdparms[3].ToLower();
194 if (valparm == "true")
195 val = PhysParameterEntry.NUMERIC_TRUE;
196 else
197 {
198 if (valparm == "false")
199 val = PhysParameterEntry.NUMERIC_FALSE;
200 else
201 val = float.Parse(valparm, Culture.NumberFormatInfo);
202 }
203 if (cmdparms.Length > 4)
204 {
205 if (cmdparms[4].ToLower() == "all")
206 localID = (uint)PhysParameterEntry.APPLY_TO_ALL;
207 else
208 localID = uint.Parse(cmdparms[2], Culture.NumberFormatInfo);
209 }
210 }
211 catch
212 {
213 WriteError(" Error parsing parameters. Invocation: " + setInvocation);
214 return;
215 }
216
217 if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null)
218 {
219 WriteError("Error: no region selected. Use 'change region' to select a region.");
220 return;
221 }
222
223 Scene scene = SceneManager.Instance.CurrentScene;
224 IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters;
225 if (physScene != null)
226 {
227 if (!physScene.SetPhysicsParameter(parm, val, localID))
228 {
229 WriteError("Failed set of parameter '{0}' for region '{1}'", parm, scene.RegionInfo.RegionName);
230 }
231 }
232 else
233 {
234 WriteOut("Region '{0}'s physics engine has no settable physics parameters", scene.RegionInfo.RegionName);
235 }
236 return;
237 }
238
239 private void ProcessPhysicsList(string module, string[] cmdparms)
240 {
241 if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null)
242 {
243 WriteError("Error: no region selected. Use 'change region' to select a region.");
244 return;
245 }
246 Scene scene = SceneManager.Instance.CurrentScene;
247
248 IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters;
249 if (physScene != null)
250 {
251 WriteOut("Available physics parameters:");
252 PhysParameterEntry[] parms = physScene.GetParameterList();
253 foreach (PhysParameterEntry ent in parms)
254 {
255 WriteOut(" {0}: {1}", ent.name, ent.desc);
256 }
257 }
258 else
259 {
260 WriteError("Current regions's physics engine has no settable physics parameters");
261 }
262 return;
263 }
264
265 private void WriteOut(string msg, params object[] args)
266 {
267 m_log.InfoFormat(msg, args);
268 // MainConsole.Instance.OutputFormat(msg, args);
269 }
270
271 private void WriteError(string msg, params object[] args)
272 {
273 m_log.ErrorFormat(msg, args);
274 // MainConsole.Instance.OutputFormat(msg, args);
275 }
276 }
277} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 9f9ebcc..682eb80 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -49,8 +49,9 @@ public class BSCharacter : PhysicsActor
49 private bool _grabbed; 49 private bool _grabbed;
50 private bool _selected; 50 private bool _selected;
51 private Vector3 _position; 51 private Vector3 _position;
52 private float _mass = 80f; 52 private float _mass;
53 public float _density = 60f; 53 public float _density;
54 public float _avatarVolume;
54 private Vector3 _force; 55 private Vector3 _force;
55 private Vector3 _velocity; 56 private Vector3 _velocity;
56 private Vector3 _torque; 57 private Vector3 _torque;
@@ -90,13 +91,13 @@ public class BSCharacter : PhysicsActor
90 _scene = parent_scene; 91 _scene = parent_scene;
91 _position = pos; 92 _position = pos;
92 _size = size; 93 _size = size;
94 _flying = isFlying;
93 _orientation = Quaternion.Identity; 95 _orientation = Quaternion.Identity;
94 _velocity = Vector3.Zero; 96 _velocity = Vector3.Zero;
95 _buoyancy = 0f; // characters return a buoyancy of zero 97 _buoyancy = isFlying ? 1f : 0f;
96 _scale = new Vector3(1f, 1f, 1f); 98 _scale = new Vector3(1f, 1f, 1f);
97 float AVvolume = (float) (Math.PI*Math.Pow(_scene.Params.avatarCapsuleRadius, 2)*_scene.Params.avatarCapsuleHeight);
98 _density = _scene.Params.avatarDensity; 99 _density = _scene.Params.avatarDensity;
99 _mass = _density*AVvolume; 100 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
100 101
101 ShapeData shapeData = new ShapeData(); 102 ShapeData shapeData = new ShapeData();
102 shapeData.ID = _localID; 103 shapeData.ID = _localID;
@@ -106,7 +107,7 @@ public class BSCharacter : PhysicsActor
106 shapeData.Velocity = _velocity; 107 shapeData.Velocity = _velocity;
107 shapeData.Scale = _scale; 108 shapeData.Scale = _scale;
108 shapeData.Mass = _mass; 109 shapeData.Mass = _mass;
109 shapeData.Buoyancy = isFlying ? 1f : 0f; 110 shapeData.Buoyancy = _buoyancy;
110 shapeData.Static = ShapeData.numericFalse; 111 shapeData.Static = ShapeData.numericFalse;
111 shapeData.Friction = _scene.Params.avatarFriction; 112 shapeData.Friction = _scene.Params.avatarFriction;
112 shapeData.Restitution = _scene.Params.defaultRestitution; 113 shapeData.Restitution = _scene.Params.defaultRestitution;
@@ -212,6 +213,7 @@ public class BSCharacter : PhysicsActor
212 get { return _velocity; } 213 get { return _velocity; }
213 set { 214 set {
214 _velocity = value; 215 _velocity = value;
216 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
215 _scene.TaintedObject(delegate() 217 _scene.TaintedObject(delegate()
216 { 218 {
217 BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); 219 BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity);
@@ -235,6 +237,7 @@ public class BSCharacter : PhysicsActor
235 get { return _orientation; } 237 get { return _orientation; }
236 set { 238 set {
237 _orientation = value; 239 _orientation = value;
240 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
238 _scene.TaintedObject(delegate() 241 _scene.TaintedObject(delegate()
239 { 242 {
240 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 243 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
@@ -300,7 +303,6 @@ public class BSCharacter : PhysicsActor
300 set { _buoyancy = value; 303 set { _buoyancy = value;
301 _scene.TaintedObject(delegate() 304 _scene.TaintedObject(delegate()
302 { 305 {
303 // simulate flying by changing the effect of gravity
304 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); 306 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
305 }); 307 });
306 } 308 }
@@ -344,6 +346,7 @@ public class BSCharacter : PhysicsActor
344 _force.X += force.X; 346 _force.X += force.X;
345 _force.Y += force.Y; 347 _force.Y += force.Y;
346 _force.Z += force.Z; 348 _force.Z += force.Z;
349 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
347 _scene.TaintedObject(delegate() 350 _scene.TaintedObject(delegate()
348 { 351 {
349 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); 352 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
@@ -370,6 +373,17 @@ public class BSCharacter : PhysicsActor
370 return (_subscribedEventsMs > 0); 373 return (_subscribedEventsMs > 0);
371 } 374 }
372 375
376 // set _avatarVolume and _mass based on capsule size, _density and _scale
377 private void ComputeAvatarVolumeAndMass()
378 {
379 _avatarVolume = (float)(
380 Math.PI
381 * _scene.Params.avatarCapsuleRadius * _scale.X
382 * _scene.Params.avatarCapsuleRadius * _scale.Y
383 * _scene.Params.avatarCapsuleHeight * _scale.Z);
384 _mass = _density * _avatarVolume;
385 }
386
373 // The physics engine says that properties have updated. Update same and inform 387 // The physics engine says that properties have updated. Update same and inform
374 // the world that things have changed. 388 // the world that things have changed.
375 public void UpdateProperties(EntityProperties entprop) 389 public void UpdateProperties(EntityProperties entprop)
@@ -403,6 +417,9 @@ public class BSCharacter : PhysicsActor
403 } 417 }
404 if (changed) 418 if (changed)
405 { 419 {
420 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
421 // Avatar movement is not done by generating this event. There is a system that
422 // checks for avatar updates each heartbeat loop.
406 // base.RequestPhysicsterseUpdate(); 423 // base.RequestPhysicsterseUpdate();
407 } 424 }
408 } 425 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index c4999f6..cc414e9 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -1013,8 +1013,8 @@ public sealed class BSPrim : PhysicsActor
1013 // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount); 1013 // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount);
1014 BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls); 1014 BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls);
1015 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; 1015 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1016 // Let the object be scaled by Bullet (the mesh was created as a unit mesh) 1016 // meshes are already scaled by the meshmerizer
1017 _scale = _size; 1017 _scale = new OMV.Vector3(1f, 1f, 1f);
1018 } 1018 }
1019 return; 1019 return;
1020 } 1020 }
@@ -1138,9 +1138,7 @@ public sealed class BSPrim : PhysicsActor
1138 if (_scene.NeedsMeshing(_pbs)) // linksets with constraints don't need a root mesh 1138 if (_scene.NeedsMeshing(_pbs)) // linksets with constraints don't need a root mesh
1139 { 1139 {
1140 // m_log.DebugFormat("{0}: RecreateGeomAndObject: creating mesh", LogHeader); 1140 // m_log.DebugFormat("{0}: RecreateGeomAndObject: creating mesh", LogHeader);
1141 // Make the mesh scaled to 1 and use Bullet's scaling feature to scale it in world 1141 _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, _scene.MeshLOD, _isPhysical);
1142 OMV.Vector3 scaleFactor = new OMV.Vector3(1.0f, 1.0f, 1.0f);
1143 _mesh = _scene.mesher.CreateMesh(_avName, _pbs, scaleFactor, _scene.MeshLOD, _isPhysical);
1144 } 1142 }
1145 else 1143 else
1146 { 1144 {
@@ -1225,6 +1223,8 @@ public sealed class BSPrim : PhysicsActor
1225 else 1223 else
1226 { 1224 {
1227 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. 1225 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1226
1227 // Only updates only for individual prims and for the root object of a linkset.
1228 if (this._parentPrim == null) 1228 if (this._parentPrim == null)
1229 { 1229 {
1230 // Assign to the local variables so the normal set action does not happen 1230 // Assign to the local variables so the normal set action does not happen
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index de86d59..518be09 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -58,11 +58,13 @@ using OpenSim.Region.Framework;
58// 58//
59namespace OpenSim.Region.Physics.BulletSPlugin 59namespace OpenSim.Region.Physics.BulletSPlugin
60{ 60{
61public class BSScene : PhysicsScene 61public class BSScene : PhysicsScene, IPhysicsParameters
62{ 62{
63 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 63 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
64 private static readonly string LogHeader = "[BULLETS SCENE]"; 64 private static readonly string LogHeader = "[BULLETS SCENE]";
65 65
66 public string BulletSimVersion = "?";
67
66 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); 68 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
67 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>(); 69 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
68 private List<BSPrim> m_vehicles = new List<BSPrim>(); 70 private List<BSPrim> m_vehicles = new List<BSPrim>();
@@ -127,7 +129,7 @@ public class BSScene : PhysicsScene
127 ConfigurationParameters[] m_params; 129 ConfigurationParameters[] m_params;
128 GCHandle m_paramsHandle; 130 GCHandle m_paramsHandle;
129 131
130 private BulletSimAPI.DebugLogCallback debugLogCallbackHandle; 132 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
131 133
132 public BSScene(string identifier) 134 public BSScene(string identifier)
133 { 135 {
@@ -149,12 +151,17 @@ public class BSScene : PhysicsScene
149 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; 151 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
150 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); 152 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
151 153
154 // Get the version of the DLL
155 // TODO: this doesn't work yet. Something wrong with marshaling the returned string.
156 // BulletSimVersion = BulletSimAPI.GetVersion();
157 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
158
152 // if Debug, enable logging from the unmanaged code 159 // if Debug, enable logging from the unmanaged code
153 if (m_log.IsDebugEnabled) 160 if (m_log.IsDebugEnabled)
154 { 161 {
155 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); 162 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
156 debugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); 163 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
157 BulletSimAPI.SetDebugLogCallback(debugLogCallbackHandle); 164 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
158 } 165 }
159 166
160 _taintedObjects = new List<TaintCallback>(); 167 _taintedObjects = new List<TaintCallback>();
@@ -188,7 +195,7 @@ public class BSScene : PhysicsScene
188 m_maxUpdatesPerFrame = 2048; 195 m_maxUpdatesPerFrame = 2048;
189 m_maximumObjectMass = 10000.01f; 196 m_maximumObjectMass = 10000.01f;
190 197
191 parms.defaultFriction = 0.70f; 198 parms.defaultFriction = 0.5f;
192 parms.defaultDensity = 10.000006836f; // Aluminum g/cm3 199 parms.defaultDensity = 10.000006836f; // Aluminum g/cm3
193 parms.defaultRestitution = 0f; 200 parms.defaultRestitution = 0f;
194 parms.collisionMargin = 0.0f; 201 parms.collisionMargin = 0.0f;
@@ -202,10 +209,10 @@ public class BSScene : PhysicsScene
202 parms.ccdMotionThreshold = 0.5f; // set to zero to disable 209 parms.ccdMotionThreshold = 0.5f; // set to zero to disable
203 parms.ccdSweptSphereRadius = 0.2f; 210 parms.ccdSweptSphereRadius = 0.2f;
204 211
205 parms.terrainFriction = 0.85f; 212 parms.terrainFriction = 0.5f;
206 parms.terrainHitFriction = 0.8f; 213 parms.terrainHitFraction = 0.8f;
207 parms.terrainRestitution = 0.2f; 214 parms.terrainRestitution = 0f;
208 parms.avatarFriction = 0.85f; 215 parms.avatarFriction = 0.0f;
209 parms.avatarDensity = 60f; 216 parms.avatarDensity = 60f;
210 parms.avatarCapsuleRadius = 0.37f; 217 parms.avatarCapsuleRadius = 0.37f;
211 parms.avatarCapsuleHeight = 1.5f; // 2.140599f 218 parms.avatarCapsuleHeight = 1.5f; // 2.140599f
@@ -213,7 +220,8 @@ public class BSScene : PhysicsScene
213 if (config != null) 220 if (config != null)
214 { 221 {
215 // If there are specifications in the ini file, use those values 222 // If there are specifications in the ini file, use those values
216 // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO ALSO UPDATE OpenSimDefaults.ini 223 // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO UPDATE OpenSimDefaults.ini
224 // ALSO REMEMBER TO UPDATE THE RUNTIME SETTING OF THE PARAMETERS.
217 IConfig pConfig = config.Configs["BulletSim"]; 225 IConfig pConfig = config.Configs["BulletSim"];
218 if (pConfig != null) 226 if (pConfig != null)
219 { 227 {
@@ -243,7 +251,7 @@ public class BSScene : PhysicsScene
243 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius); 251 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius);
244 252
245 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction); 253 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction);
246 parms.terrainHitFriction = pConfig.GetFloat("TerrainHitFriction", parms.terrainHitFriction); 254 parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction);
247 parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution); 255 parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution);
248 parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction); 256 parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction);
249 parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity); 257 parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity);
@@ -386,7 +394,7 @@ public class BSScene : PhysicsScene
386 } 394 }
387 } 395 }
388 396
389 // FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. 397 // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
390 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; 398 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
391 } 399 }
392 400
@@ -651,5 +659,196 @@ public class BSScene : PhysicsScene
651 } 659 }
652 } 660 }
653 #endregion Vehicles 661 #endregion Vehicles
662
663 #region Runtime settable parameters
664 public static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[]
665 {
666 new PhysParameterEntry("MeshLOD", "Level of detail to render meshes (Power of two. Default 32)"),
667 new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"),
668 new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"),
669 new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"),
670
671 new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"),
672 new PhysParameterEntry("DefaultDensity", "Density for new objects" ),
673 new PhysParameterEntry("DefaultRestitution", "Bouncyness of an object" ),
674 // new PhysParameterEntry("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!!)" ),
675 new PhysParameterEntry("Gravity", "Vertical force of gravity (negative means down)" ),
676
677 new PhysParameterEntry("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)" ),
678 new PhysParameterEntry("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)" ),
679 new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ),
680 new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ),
681 new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ),
682 // new PhysParameterEntry("CcdMotionThreshold", "" ),
683 // new PhysParameterEntry("CcdSweptSphereRadius", "" ),
684
685 new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ),
686 new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ),
687 new PhysParameterEntry("TerrainRestitution", "Bouncyness" ),
688 new PhysParameterEntry("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation." ),
689 new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ),
690 new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ),
691 new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ),
692 new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" )
693 };
694
695 #region IPhysicsParameters
696 // Get the list of parameters this physics engine supports
697 public PhysParameterEntry[] GetParameterList()
698 {
699 return SettableParameters;
700 }
701
702 // Set parameter on a specific or all instances.
703 // Return 'false' if not able to set the parameter.
704 // Setting the value in the m_params block will change the value the physics engine
705 // will use the next time since it's pinned and shared memory.
706 // Some of the values require calling into the physics engine to get the new
707 // value activated ('terrainFriction' for instance).
708 public bool SetPhysicsParameter(string parm, float val, uint localID)
709 {
710 bool ret = true;
711 string lparm = parm.ToLower();
712 switch (lparm)
713 {
714 case "meshlod": m_meshLOD = (int)val; break;
715 case "maxsubstep": m_maxSubSteps = (int)val; break;
716 case "fixedtimestep": m_fixedTimeStep = val; break;
717 case "maxobjectmass": m_maximumObjectMass = val; break;
718
719 case "defaultfriction": m_params[0].defaultFriction = val; break;
720 case "defaultdensity": m_params[0].defaultDensity = val; break;
721 case "defaultrestitution": m_params[0].defaultRestitution = val; break;
722 case "collisionmargin": m_params[0].collisionMargin = val; break;
723 case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break;
724
725 case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break;
726 case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
727 case "deactivationtime": UpdateParameterPrims(ref m_params[0].deactivationTime, lparm, localID, val); break;
728 case "linearsleepingthreshold": UpdateParameterPrims(ref m_params[0].linearSleepingThreshold, lparm, localID, val); break;
729 case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
730 case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break;
731 case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break;
732
733 // set a terrain physical feature and cause terrain to be recalculated
734 case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break;
735 case "terrainhitfraction": m_params[0].terrainHitFraction = val; TaintedUpdateParameter("terrain", 0, val); break;
736 case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break;
737 // set an avatar physical feature and cause avatar(s) to be recalculated
738 case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break;
739 case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break;
740 case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break;
741 case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break;
742 case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break;
743
744 default: ret = false; break;
745 }
746 return ret;
747 }
748
749 // check to see if we are updating a parameter for a particular or all of the prims
750 private void UpdateParameterPrims(ref float loc, string parm, uint localID, float val)
751 {
752 List<uint> operateOn;
753 lock (m_prims) operateOn = new List<uint>(m_prims.Keys);
754 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
755 }
756
757 // check to see if we are updating a parameter for a particular or all of the avatars
758 private void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
759 {
760 List<uint> operateOn;
761 lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys);
762 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
763 }
764
765 // update all the localIDs specified
766 // If the local ID is APPLY_TO_NONE, just change the default value
767 // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs
768 // If the localID is a specific object, apply the parameter change to only that object
769 private void UpdateParameterSet(List<uint> lIDs, ref float defaultLoc, string parm, uint localID, float val)
770 {
771 switch (localID)
772 {
773 case PhysParameterEntry.APPLY_TO_NONE:
774 defaultLoc = val; // setting only the default value
775 break;
776 case PhysParameterEntry.APPLY_TO_ALL:
777 defaultLoc = val; // setting ALL also sets the default value
778 List<uint> objectIDs = lIDs;
779 string xparm = parm.ToLower();
780 float xval = val;
781 TaintedObject(delegate() {
782 foreach (uint lID in objectIDs)
783 {
784 BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval);
785 }
786 });
787 break;
788 default:
789 // setting only one localID
790 TaintedUpdateParameter(parm, localID, val);
791 break;
792 }
793 }
794
795 // schedule the actual updating of the paramter to when the phys engine is not busy
796 private void TaintedUpdateParameter(string parm, uint localID, float val)
797 {
798 uint xlocalID = localID;
799 string xparm = parm.ToLower();
800 float xval = val;
801 TaintedObject(delegate() {
802 BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval);
803 });
804 }
805
806 // Get parameter.
807 // Return 'false' if not able to get the parameter.
808 public bool GetPhysicsParameter(string parm, out float value)
809 {
810 float val = 0f;
811 bool ret = true;
812 switch (parm.ToLower())
813 {
814 case "meshlod": val = (float)m_meshLOD; break;
815 case "maxsubstep": val = (float)m_maxSubSteps; break;
816 case "fixedtimestep": val = m_fixedTimeStep; break;
817 case "maxobjectmass": val = m_maximumObjectMass; break;
818
819 case "defaultfriction": val = m_params[0].defaultFriction; break;
820 case "defaultdensity": val = m_params[0].defaultDensity; break;
821 case "defaultrestitution": val = m_params[0].defaultRestitution; break;
822 case "collisionmargin": val = m_params[0].collisionMargin; break;
823 case "gravity": val = m_params[0].gravity; break;
824
825 case "lineardamping": val = m_params[0].linearDamping; break;
826 case "angulardamping": val = m_params[0].angularDamping; break;
827 case "deactivationtime": val = m_params[0].deactivationTime; break;
828 case "linearsleepingthreshold": val = m_params[0].linearSleepingThreshold; break;
829 case "angularsleepingthreshold": val = m_params[0].angularDamping; break;
830 case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break;
831 case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break;
832
833 case "terrainfriction": val = m_params[0].terrainFriction; break;
834 case "terrainhitfraction": val = m_params[0].terrainHitFraction; break;
835 case "terrainrestitution": val = m_params[0].terrainRestitution; break;
836
837 case "avatarfriction": val = m_params[0].avatarFriction; break;
838 case "avatardensity": val = m_params[0].avatarDensity; break;
839 case "avatarrestitution": val = m_params[0].avatarRestitution; break;
840 case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break;
841 case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break;
842 default: ret = false; break;
843
844 }
845 value = val;
846 return ret;
847 }
848
849 #endregion IPhysicsParameters
850
851 #endregion Runtime settable parameters
852
654} 853}
655} 854}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 819fce1..bf953df 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -51,9 +51,6 @@ public struct ShapeData
51 SHAPE_SPHERE = 4, 51 SHAPE_SPHERE = 4,
52 SHAPE_HULL = 5 52 SHAPE_HULL = 5
53 }; 53 };
54 // note that bools are passed as ints since bool size changes by language
55 public const int numericTrue = 1;
56 public const int numericFalse = 0;
57 public uint ID; 54 public uint ID;
58 public PhysicsShapeType Type; 55 public PhysicsShapeType Type;
59 public Vector3 Position; 56 public Vector3 Position;
@@ -67,6 +64,10 @@ public struct ShapeData
67 public float Restitution; 64 public float Restitution;
68 public int Collidable; 65 public int Collidable;
69 public int Static; // true if a static object. Otherwise gravity, etc. 66 public int Static; // true if a static object. Otherwise gravity, etc.
67
68 // note that bools are passed as ints since bool size changes by language and architecture
69 public const int numericTrue = 1;
70 public const int numericFalse = 0;
70} 71}
71[StructLayout(LayoutKind.Sequential)] 72[StructLayout(LayoutKind.Sequential)]
72public struct SweepHit 73public struct SweepHit
@@ -121,23 +122,34 @@ public struct ConfigurationParameters
121 public float ccdSweptSphereRadius; 122 public float ccdSweptSphereRadius;
122 123
123 public float terrainFriction; 124 public float terrainFriction;
124 public float terrainHitFriction; 125 public float terrainHitFraction;
125 public float terrainRestitution; 126 public float terrainRestitution;
126 public float avatarFriction; 127 public float avatarFriction;
127 public float avatarDensity; 128 public float avatarDensity;
128 public float avatarRestitution; 129 public float avatarRestitution;
129 public float avatarCapsuleRadius; 130 public float avatarCapsuleRadius;
130 public float avatarCapsuleHeight; 131 public float avatarCapsuleHeight;
132
133 public const float numericTrue = 1f;
134 public const float numericFalse = 0f;
131} 135}
132 136
133static class BulletSimAPI { 137static class BulletSimAPI {
134 138
135[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 139[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
140[return: MarshalAs(UnmanagedType.LPStr)]
141public static extern string GetVersion();
142
143[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
136public static extern uint Initialize(Vector3 maxPosition, IntPtr parms, 144public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
137 int maxCollisions, IntPtr collisionArray, 145 int maxCollisions, IntPtr collisionArray,
138 int maxUpdates, IntPtr updateArray); 146 int maxUpdates, IntPtr updateArray);
139 147
140[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 148[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
149public static extern bool UpdateParameter(uint worldID, uint localID,
150 [MarshalAs(UnmanagedType.LPStr)]string paramCode, float value);
151
152[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
141public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); 153public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
142 154
143[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 155[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
diff --git a/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs b/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs
new file mode 100755
index 0000000..b8676ba
--- /dev/null
+++ b/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs
@@ -0,0 +1,73 @@
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 copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenSim.Framework;
31using OpenMetaverse;
32
33namespace OpenSim.Region.Physics.Manager
34{
35 public struct PhysParameterEntry
36 {
37 // flags to say to apply to all or no instances (I wish one could put consts into interfaces)
38 public const uint APPLY_TO_ALL = 0xfffffff3;
39 public const uint APPLY_TO_NONE = 0xfffffff4;
40
41 // values that denote true and false values
42 public const float NUMERIC_TRUE = 1f;
43 public const float NUMERIC_FALSE = 0f;
44
45 public string name;
46 public string desc;
47
48 public PhysParameterEntry(string n, string d)
49 {
50 name = n;
51 desc = d;
52 }
53 }
54
55 // Interface for a physics scene that implements the runtime setting and getting of physics parameters
56 public interface IPhysicsParameters
57 {
58 // Get the list of parameters this physics engine supports
59 PhysParameterEntry[] GetParameterList();
60
61 // Set parameter on a specific or all instances.
62 // Return 'false' if not able to set the parameter.
63 bool SetPhysicsParameter(string parm, float value, uint localID);
64
65 // Get parameter.
66 // Return 'false' if not able to get the parameter.
67 bool GetPhysicsParameter(string parm, out float value);
68
69 // Get parameter from a particular object
70 // TODO:
71 // bool GetPhysicsParameter(string parm, out float value, uint localID);
72 }
73}