aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs245
1 files changed, 137 insertions, 108 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index ce64b9b..f80304d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -39,8 +39,6 @@ using log4net;
39using OpenMetaverse; 39using OpenMetaverse;
40 40
41// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) 41// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
42// Debug linkset
43// Test with multiple regions in one simulator
44// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) 42// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight)
45// Test sculpties 43// Test sculpties
46// Compute physics FPS reasonably 44// Compute physics FPS reasonably
@@ -54,10 +52,8 @@ using OpenMetaverse;
54// Use collision masks for collision with terrain and phantom objects 52// Use collision masks for collision with terrain and phantom objects
55// Check out llVolumeDetect. Must do something for that. 53// Check out llVolumeDetect. Must do something for that.
56// Should prim.link() and prim.delink() membership checking happen at taint time? 54// Should prim.link() and prim.delink() membership checking happen at taint time?
57// changing the position and orientation of a linked prim must rebuild the constraint with the root.
58// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once 55// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
59// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect 56// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
60// Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions)
61// Implement LockAngularMotion 57// Implement LockAngularMotion
62// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) 58// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
63// Does NeedsMeshing() really need to exclude all the different shapes? 59// Does NeedsMeshing() really need to exclude all the different shapes?
@@ -85,18 +81,15 @@ public class BSScene : PhysicsScene, IPhysicsParameters
85 // moved to a better place. 81 // moved to a better place.
86 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); 82 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
87 83
88 private List<BSPrim> m_vehicles = new List<BSPrim>(); 84 // List of all the objects that have vehicle properties and should be called
89 85 // to update each physics step.
90 private float[] m_heightMap; 86 private List<BSPhysObject> m_vehicles = new List<BSPhysObject>();
91 private float m_waterLevel;
92 private uint m_worldID;
93 public uint WorldID { get { return m_worldID; } }
94 87
95 // let my minuions use my logger 88 // let my minuions use my logger
96 public ILog Logger { get { return m_log; } } 89 public ILog Logger { get { return m_log; } }
97 90
98 private bool m_initialized = false; 91 // If non-zero, the number of simulation steps between calls to the physics
99 92 // engine to output detailed physics stats. Debug logging level must be on also.
100 private int m_detailedStatsStep = 0; 93 private int m_detailedStatsStep = 0;
101 94
102 public IMesher mesher; 95 public IMesher mesher;
@@ -106,29 +99,31 @@ public class BSScene : PhysicsScene, IPhysicsParameters
106 public float MeshMegaPrimThreshold { get; private set; } 99 public float MeshMegaPrimThreshold { get; private set; }
107 public float SculptLOD { get; private set; } 100 public float SculptLOD { get; private set; }
108 101
109 private BulletSim m_worldSim; 102 public uint WorldID { get; private set; }
110 public BulletSim World 103 public BulletSim World { get; private set; }
111 { 104
112 get { return m_worldSim; } 105 // All the constraints that have been allocated in this instance.
113 } 106 public BSConstraintCollection Constraints { get; private set; }
114 private BSConstraintCollection m_constraintCollection;
115 public BSConstraintCollection Constraints
116 {
117 get { return m_constraintCollection; }
118 }
119 107
108 // Simulation parameters
120 private int m_maxSubSteps; 109 private int m_maxSubSteps;
121 private float m_fixedTimeStep; 110 private float m_fixedTimeStep;
122 private long m_simulationStep = 0; 111 private long m_simulationStep = 0;
123 public long SimulationStep { get { return m_simulationStep; } } 112 public long SimulationStep { get { return m_simulationStep; } }
124 113
114 // The length of the last timestep we were asked to simulate.
115 // This is used by the vehicle code. Since the vehicle code is called
116 // once per simulation step, its constants need to be scaled by this.
125 public float LastSimulatedTimestep { get; private set; } 117 public float LastSimulatedTimestep { get; private set; }
126 118
127 // A value of the time now so all the collision and update routines do not have to get their own 119 // A value of the time now so all the collision and update routines do not have to get their own
128 // Set to 'now' just before all the prims and actors are called for collisions and updates 120 // Set to 'now' just before all the prims and actors are called for collisions and updates
129 private int m_simulationNowTime; 121 public int SimulationNowTime { get; private set; }
130 public int SimulationNowTime { get { return m_simulationNowTime; } } 122
123 // True if initialized and ready to do simulation steps
124 private bool m_initialized = false;
131 125
126 // Pinned memory used to pass step information between managed and unmanaged
132 private int m_maxCollisionsPerFrame; 127 private int m_maxCollisionsPerFrame;
133 private CollisionDesc[] m_collisionArray; 128 private CollisionDesc[] m_collisionArray;
134 private GCHandle m_collisionArrayPinnedHandle; 129 private GCHandle m_collisionArrayPinnedHandle;
@@ -145,6 +140,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
145 140
146 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero 141 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
147 public const uint GROUNDPLANE_ID = 1; 142 public const uint GROUNDPLANE_ID = 1;
143 public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here
144
145 private float m_waterLevel;
146 public BSTerrainManager TerrainManager { get; private set; }
148 147
149 public ConfigurationParameters Params 148 public ConfigurationParameters Params
150 { 149 {
@@ -155,12 +154,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
155 get { return new Vector3(0f, 0f, Params.gravity); } 154 get { return new Vector3(0f, 0f, Params.gravity); }
156 } 155 }
157 156
158 private float m_maximumObjectMass; 157 public float MaximumObjectMass { get; private set; }
159 public float MaximumObjectMass
160 {
161 get { return m_maximumObjectMass; }
162 }
163 158
159 // When functions in the unmanaged code must be called, it is only
160 // done at a known time just before the simulation step. The taint
161 // system saves all these function calls and executes them in
162 // order before the simulation.
164 public delegate void TaintCallback(); 163 public delegate void TaintCallback();
165 private struct TaintCallbackEntry 164 private struct TaintCallbackEntry
166 { 165 {
@@ -176,6 +175,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
176 private Object _taintLock = new Object(); 175 private Object _taintLock = new Object();
177 176
178 // A pointer to an instance if this structure is passed to the C++ code 177 // A pointer to an instance if this structure is passed to the C++ code
178 // Used to pass basic configuration values to the unmanaged code.
179 ConfigurationParameters[] m_params; 179 ConfigurationParameters[] m_params;
180 GCHandle m_paramsHandle; 180 GCHandle m_paramsHandle;
181 181
@@ -189,11 +189,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
189 private bool m_physicsLoggingEnabled; 189 private bool m_physicsLoggingEnabled;
190 private string m_physicsLoggingDir; 190 private string m_physicsLoggingDir;
191 private string m_physicsLoggingPrefix; 191 private string m_physicsLoggingPrefix;
192 private int m_physicsLoggingFileMinutes; 192 private int m_physicsLoggingFileMinutes;
193 193 // 'true' of the vehicle code is to log lots of details
194 private bool m_vehicleLoggingEnabled; 194 public bool VehicleLoggingEnabled { get; private set; }
195 public bool VehicleLoggingEnabled { get { return m_vehicleLoggingEnabled; } }
196 195
196 #region Construction and Initialization
197 public BSScene(string identifier) 197 public BSScene(string identifier)
198 { 198 {
199 m_initialized = false; 199 m_initialized = false;
@@ -216,6 +216,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
216 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; 216 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
217 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); 217 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
218 218
219 mesher = meshmerizer;
220 _taintedObjects = new List<TaintCallbackEntry>();
221
219 // Enable very detailed logging. 222 // Enable very detailed logging.
220 // By creating an empty logger when not logging, the log message invocation code 223 // By creating an empty logger when not logging, the log message invocation code
221 // can be left in and every call doesn't have to check for null. 224 // can be left in and every call doesn't have to check for null.
@@ -228,11 +231,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
228 PhysicsLogging = new Logging.LogWriter(); 231 PhysicsLogging = new Logging.LogWriter();
229 } 232 }
230 233
231 // Get the version of the DLL
232 // TODO: this doesn't work yet. Something wrong with marshaling the returned string.
233 // BulletSimVersion = BulletSimAPI.GetVersion();
234 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
235
236 // If Debug logging level, enable logging from the unmanaged code 234 // If Debug logging level, enable logging from the unmanaged code
237 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) 235 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
238 { 236 {
@@ -245,22 +243,32 @@ public class BSScene : PhysicsScene, IPhysicsParameters
245 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); 243 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
246 } 244 }
247 245
248 _taintedObjects = new List<TaintCallbackEntry>(); 246 // Get the version of the DLL
249 247 // TODO: this doesn't work yet. Something wrong with marshaling the returned string.
250 mesher = meshmerizer; 248 // BulletSimVersion = BulletSimAPI.GetVersion();
249 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
251 250
252 // The bounding box for the simulated world 251 // The bounding box for the simulated world. The origin is 0,0,0 unless we're
252 // a child in a mega-region.
253 // Turns out that Bullet really doesn't care about the extents of the simulated
254 // area. It tracks active objects no matter where they are.
253 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f); 255 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f);
254 256
255 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); 257 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
256 m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), 258 WorldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
257 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), 259 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
258 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); 260 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject());
259 261
260 // Initialization to support the transition to a new API which puts most of the logic 262 // Initialization to support the transition to a new API which puts most of the logic
261 // into the C# code so it is easier to modify and add to. 263 // into the C# code so it is easier to modify and add to.
262 m_worldSim = new BulletSim(m_worldID, this, BulletSimAPI.GetSimHandle2(m_worldID)); 264 World = new BulletSim(WorldID, this, BulletSimAPI.GetSimHandle2(WorldID));
263 m_constraintCollection = new BSConstraintCollection(World); 265
266 Constraints = new BSConstraintCollection(World);
267
268 // Note: choose one of the two following lines
269 // BulletSimAPI.CreateInitialGroundPlaneAndTerrain(WorldID);
270 TerrainManager = new BSTerrainManager(this);
271 TerrainManager.CreateInitialGroundPlaneAndTerrain();
264 272
265 m_initialized = true; 273 m_initialized = true;
266 } 274 }
@@ -288,7 +296,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
288 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); 296 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
289 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); 297 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
290 // Very detailed logging for vehicle debugging 298 // Very detailed logging for vehicle debugging
291 m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); 299 VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
292 300
293 // Do any replacements in the parameters 301 // Do any replacements in the parameters
294 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); 302 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
@@ -323,6 +331,38 @@ public class BSScene : PhysicsScene, IPhysicsParameters
323 PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg); 331 PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg);
324 } 332 }
325 333
334 public override void Dispose()
335 {
336 // m_log.DebugFormat("{0}: Dispose()", LogHeader);
337
338 // make sure no stepping happens while we're deleting stuff
339 m_initialized = false;
340
341 TerrainManager.ReleaseGroundPlaneAndTerrain();
342
343 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
344 {
345 kvp.Value.Destroy();
346 }
347 PhysObjects.Clear();
348
349 // Now that the prims are all cleaned up, there should be no constraints left
350 if (Constraints != null)
351 {
352 Constraints.Dispose();
353 Constraints = null;
354 }
355
356 // Anything left in the unmanaged code should be cleaned out
357 BulletSimAPI.Shutdown(WorldID);
358
359 // Not logging any more
360 PhysicsLogging.Close();
361 }
362 #endregion // Construction and Initialization
363
364 #region Prim and Avatar addition and removal
365
326 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 366 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
327 { 367 {
328 m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader); 368 m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
@@ -413,6 +453,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
413 // information call is not needed. 453 // information call is not needed.
414 public override void AddPhysicsActorTaint(PhysicsActor prim) { } 454 public override void AddPhysicsActorTaint(PhysicsActor prim) { }
415 455
456 #endregion // Prim and Avatar addition and removal
457
458 #region Simulation
416 // Simulate one timestep 459 // Simulate one timestep
417 public override float Simulate(float timeStep) 460 public override float Simulate(float timeStep)
418 { 461 {
@@ -428,7 +471,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
428 471
429 int simulateStartTime = Util.EnvironmentTickCount(); 472 int simulateStartTime = Util.EnvironmentTickCount();
430 473
431 // update the prim states while we know the physics engine is not busy 474 // update the prim states while we know the physics engine is not busy
475 int numTaints = _taintedObjects.Count;
432 ProcessTaints(); 476 ProcessTaints();
433 477
434 // Some of the prims operate with special vehicle properties 478 // Some of the prims operate with special vehicle properties
@@ -440,14 +484,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
440 int numSubSteps = 0; 484 int numSubSteps = 0;
441 try 485 try
442 { 486 {
443 numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, 487 numSubSteps = BulletSimAPI.PhysicsStep(WorldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
444 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); 488 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
445 DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 489 DetailLog("{0},Simulate,call, nTaints= {1}, substeps={2}, updates={3}, colliders={4}",
490 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
446 } 491 }
447 catch (Exception e) 492 catch (Exception e)
448 { 493 {
449 m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e); 494 m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
450 // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 495 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
496 DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
497 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
451 updatedEntityCount = 0; 498 updatedEntityCount = 0;
452 collidersCount = 0; 499 collidersCount = 0;
453 } 500 }
@@ -456,7 +503,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
456 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in 503 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in
457 504
458 // Get a value for 'now' so all the collision and update routines don't have to get their own 505 // Get a value for 'now' so all the collision and update routines don't have to get their own
459 m_simulationNowTime = Util.EnvironmentTickCount(); 506 SimulationNowTime = Util.EnvironmentTickCount();
460 507
461 // If there were collisions, process them by sending the event to the prim. 508 // If there were collisions, process them by sending the event to the prim.
462 // Collisions must be processed before updates. 509 // Collisions must be processed before updates.
@@ -527,7 +574,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
527 // Something has collided 574 // Something has collided
528 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration) 575 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration)
529 { 576 {
530 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) 577 if (localID <= TerrainManager.HighestTerrainID)
531 { 578 {
532 return; // don't send collisions to the terrain 579 return; // don't send collisions to the terrain
533 } 580 }
@@ -539,7 +586,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
539 BSPhysObject collidee = null; 586 BSPhysObject collidee = null;
540 587
541 ActorTypes type = ActorTypes.Prim; 588 ActorTypes type = ActorTypes.Prim;
542 if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID) 589 if (collidingWith <= TerrainManager.HighestTerrainID)
543 { 590 {
544 type = ActorTypes.Ground; 591 type = ActorTypes.Ground;
545 } 592 }
@@ -558,28 +605,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
558 return; 605 return;
559 } 606 }
560 607
608 #endregion // Simulation
609
561 public override void GetResults() { } 610 public override void GetResults() { }
562 611
563 public override void SetTerrain(float[] heightMap) { 612 #region Terrain
564 m_heightMap = heightMap;
565 this.TaintedObject("BSScene.SetTerrain", delegate()
566 {
567 BulletSimAPI.SetHeightmap(m_worldID, m_heightMap);
568 });
569 }
570 613
571 // Someday we will have complex terrain with caves and tunnels 614 public override void SetTerrain(float[] heightMap) {
572 // For the moment, it's flat and convex 615 TerrainManager.SetTerrain(heightMap);
573 public float GetTerrainHeightAtXYZ(Vector3 loc)
574 {
575 return GetTerrainHeightAtXY(loc.X, loc.Y);
576 }
577
578 public float GetTerrainHeightAtXY(float tX, float tY)
579 {
580 if (tX < 0 || tX >= Constants.RegionSize || tY < 0 || tY >= Constants.RegionSize)
581 return 30;
582 return m_heightMap[((int)tX) * Constants.RegionSize + ((int)tY)];
583 } 616 }
584 617
585 public override void SetWaterLevel(float baseheight) 618 public override void SetWaterLevel(float baseheight)
@@ -595,35 +628,29 @@ public class BSScene : PhysicsScene, IPhysicsParameters
595 public override void DeleteTerrain() 628 public override void DeleteTerrain()
596 { 629 {
597 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); 630 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
631 }
632
633 // Although no one seems to check this, I do support combining.
634 public override bool SupportsCombining()
635 {
636 return TerrainManager.SupportsCombining();
598 } 637 }
599 638 // This call says I am a child to region zero in a mega-region. 'pScene' is that
600 public override void Dispose() 639 // of region zero, 'offset' is my offset from regions zero's origin, and
601 { 640 // 'extents' is the largest XY that is handled in my region.
602 // m_log.DebugFormat("{0}: Dispose()", LogHeader); 641 public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
603 642 {
604 // make sure no stepping happens while we're deleting stuff 643 TerrainManager.Combine(pScene, offset, extents);
605 m_initialized = false; 644 }
606 645
607 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects) 646 // Unhook all the combining that I know about.
608 { 647 public override void UnCombine(PhysicsScene pScene)
609 kvp.Value.Destroy(); 648 {
610 } 649 TerrainManager.UnCombine(pScene);
611 PhysObjects.Clear();
612
613 // Now that the prims are all cleaned up, there should be no constraints left
614 if (m_constraintCollection != null)
615 {
616 m_constraintCollection.Dispose();
617 m_constraintCollection = null;
618 }
619
620 // Anything left in the unmanaged code should be cleaned out
621 BulletSimAPI.Shutdown(WorldID);
622
623 // Not logging any more
624 PhysicsLogging.Close();
625 } 650 }
626 651
652 #endregion // Terrain
653
627 public override Dictionary<uint, float> GetTopColliders() 654 public override Dictionary<uint, float> GetTopColliders()
628 { 655 {
629 return new Dictionary<uint, float>(); 656 return new Dictionary<uint, float>();
@@ -833,14 +860,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
833 // no locking because only called when physics engine is not busy 860 // no locking because only called when physics engine is not busy
834 private void ProcessVehicles(float timeStep) 861 private void ProcessVehicles(float timeStep)
835 { 862 {
836 foreach (BSPrim prim in m_vehicles) 863 foreach (BSPhysObject pobj in m_vehicles)
837 { 864 {
838 prim.StepVehicle(timeStep); 865 pobj.StepVehicle(timeStep);
839 } 866 }
840 } 867 }
841 #endregion Vehicles 868 #endregion Vehicles
842 869
843 #region Parameters 870 #region INI and command line parameter processing
844 871
845 delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); 872 delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
846 delegate float ParamGet(BSScene scene); 873 delegate float ParamGet(BSScene scene);
@@ -943,9 +970,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
943 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), 970 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
944 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", 971 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
945 10000.01f, 972 10000.01f,
946 (s,cf,p,v) => { s.m_maximumObjectMass = cf.GetFloat(p, v); }, 973 (s,cf,p,v) => { s.MaximumObjectMass = cf.GetFloat(p, v); },
947 (s) => { return (float)s.m_maximumObjectMass; }, 974 (s) => { return (float)s.MaximumObjectMass; },
948 (s,p,l,v) => { s.m_maximumObjectMass = v; } ), 975 (s,p,l,v) => { s.MaximumObjectMass = v; } ),
949 976
950 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", 977 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
951 2200f, 978 2200f,
@@ -1207,6 +1234,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1207 1234
1208 private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; 1235 private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
1209 1236
1237 // This creates an array in the correct format for returning the list of
1238 // parameters. This is used by the 'list' option of the 'physics' command.
1210 private void BuildParameterTable() 1239 private void BuildParameterTable()
1211 { 1240 {
1212 if (SettableParameters.Length < ParameterDefinitions.Length) 1241 if (SettableParameters.Length < ParameterDefinitions.Length)
@@ -1283,7 +1312,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1283 TaintedObject("BSScene.UpdateParameterSet", delegate() { 1312 TaintedObject("BSScene.UpdateParameterSet", delegate() {
1284 foreach (uint lID in objectIDs) 1313 foreach (uint lID in objectIDs)
1285 { 1314 {
1286 BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval); 1315 BulletSimAPI.UpdateParameter(WorldID, lID, xparm, xval);
1287 } 1316 }
1288 }); 1317 });
1289 break; 1318 break;
@@ -1301,7 +1330,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1301 string xparm = parm.ToLower(); 1330 string xparm = parm.ToLower();
1302 float xval = val; 1331 float xval = val;
1303 TaintedObject("BSScene.TaintedUpdateParameter", delegate() { 1332 TaintedObject("BSScene.TaintedUpdateParameter", delegate() {
1304 BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval); 1333 BulletSimAPI.UpdateParameter(WorldID, xlocalID, xparm, xval);
1305 }); 1334 });
1306 } 1335 }
1307 1336