aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs124
1 files changed, 82 insertions, 42 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 011033c..a31c578 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -73,7 +73,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
73 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 73 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
74 private static readonly string LogHeader = "[BULLETS SCENE]"; 74 private static readonly string LogHeader = "[BULLETS SCENE]";
75 75
76 public void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); } 76 public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); }
77 77
78 public string BulletSimVersion = "?"; 78 public string BulletSimVersion = "?";
79 79
@@ -162,14 +162,24 @@ public class BSScene : PhysicsScene, IPhysicsParameters
162 } 162 }
163 163
164 public delegate void TaintCallback(); 164 public delegate void TaintCallback();
165 private List<TaintCallback> _taintedObjects; 165 private struct TaintCallbackEntry
166 {
167 public String ident;
168 public TaintCallback callback;
169 public TaintCallbackEntry(string i, TaintCallback c)
170 {
171 ident = i;
172 callback = c;
173 }
174 }
175 private List<TaintCallbackEntry> _taintedObjects;
166 private Object _taintLock = new Object(); 176 private Object _taintLock = new Object();
167 177
168 // A pointer to an instance if this structure is passed to the C++ code 178 // A pointer to an instance if this structure is passed to the C++ code
169 ConfigurationParameters[] m_params; 179 ConfigurationParameters[] m_params;
170 GCHandle m_paramsHandle; 180 GCHandle m_paramsHandle;
171 181
172 public bool shouldDebugLog { get; private set; } 182 public bool ShouldDebugLog { get; private set; }
173 183
174 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; 184 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
175 185
@@ -232,7 +242,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
232 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); 242 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
233 } 243 }
234 244
235 _taintedObjects = new List<TaintCallback>(); 245 _taintedObjects = new List<TaintCallbackEntry>();
236 246
237 mesher = meshmerizer; 247 mesher = meshmerizer;
238 // The bounding box for the simulated world 248 // The bounding box for the simulated world
@@ -245,7 +255,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
245 255
246 // Initialization to support the transition to a new API which puts most of the logic 256 // Initialization to support the transition to a new API which puts most of the logic
247 // into the C# code so it is easier to modify and add to. 257 // into the C# code so it is easier to modify and add to.
248 m_worldSim = new BulletSim(m_worldID, BulletSimAPI.GetSimHandle2(m_worldID)); 258 m_worldSim = new BulletSim(m_worldID, this, BulletSimAPI.GetSimHandle2(m_worldID));
249 m_constraintCollection = new BSConstraintCollection(World); 259 m_constraintCollection = new BSConstraintCollection(World);
250 260
251 m_initialized = true; 261 m_initialized = true;
@@ -352,7 +362,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
352 BSPrim bsprim = prim as BSPrim; 362 BSPrim bsprim = prim as BSPrim;
353 if (bsprim != null) 363 if (bsprim != null)
354 { 364 {
355 m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); 365 // DetailLog("{0},RemovePrim,call", bsprim.LocalID);
366 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
356 try 367 try
357 { 368 {
358 lock (m_prims) m_prims.Remove(bsprim.LocalID); 369 lock (m_prims) m_prims.Remove(bsprim.LocalID);
@@ -377,6 +388,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
377 388
378 if (!m_initialized) return null; 389 if (!m_initialized) return null;
379 390
391 // DetailLog("{0},AddPrimShape,call", localID);
392
380 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); 393 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
381 lock (m_prims) m_prims.Add(localID, prim); 394 lock (m_prims) m_prims.Add(localID, prim);
382 return prim; 395 return prim;
@@ -400,7 +413,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
400 // prevent simulation until we've been initialized 413 // prevent simulation until we've been initialized
401 if (!m_initialized) return 10.0f; 414 if (!m_initialized) return 10.0f;
402 415
403 long simulateStartTime = Util.EnvironmentTickCount(); 416 int simulateStartTime = Util.EnvironmentTickCount();
404 417
405 // update the prim states while we know the physics engine is not busy 418 // update the prim states while we know the physics engine is not busy
406 ProcessTaints(); 419 ProcessTaints();
@@ -416,12 +429,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
416 { 429 {
417 numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, 430 numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
418 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); 431 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
419 DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount); 432 // DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
420 } 433 }
421 catch (Exception e) 434 catch (Exception e)
422 { 435 {
423 m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e); 436 m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
424 DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount); 437 // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
425 // updatedEntityCount = 0; 438 // updatedEntityCount = 0;
426 collidersCount = 0; 439 collidersCount = 0;
427 } 440 }
@@ -498,8 +511,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
498 // long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime); 511 // long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
499 // return (timeStep * (float)simulateTotalTime); 512 // return (timeStep * (float)simulateTotalTime);
500 513
501 // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. 514 // TODO: FIX THIS: fps calculation possibly wrong.
502 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; 515 // This calculation says 1/timeStep is the ideal frame rate. Any time added to
516 // that by the physics simulation gives a slower frame rate.
517 long totalSimulationTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
518 if (totalSimulationTime >= timeStep)
519 return 0;
520 return 1f / (timeStep + totalSimulationTime);
503 } 521 }
504 522
505 // Something has collided 523 // Something has collided
@@ -535,7 +553,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
535 553
536 public override void SetTerrain(float[] heightMap) { 554 public override void SetTerrain(float[] heightMap) {
537 m_heightMap = heightMap; 555 m_heightMap = heightMap;
538 this.TaintedObject(delegate() 556 this.TaintedObject("BSScene.SetTerrain", delegate()
539 { 557 {
540 BulletSimAPI.SetHeightmap(m_worldID, m_heightMap); 558 BulletSimAPI.SetHeightmap(m_worldID, m_heightMap);
541 }); 559 });
@@ -577,12 +595,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
577 // make sure no stepping happens while we're deleting stuff 595 // make sure no stepping happens while we're deleting stuff
578 m_initialized = false; 596 m_initialized = false;
579 597
580 if (m_constraintCollection != null)
581 {
582 m_constraintCollection.Dispose();
583 m_constraintCollection = null;
584 }
585
586 foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) 598 foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
587 { 599 {
588 kvp.Value.Destroy(); 600 kvp.Value.Destroy();
@@ -595,6 +607,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
595 } 607 }
596 m_prims.Clear(); 608 m_prims.Clear();
597 609
610 // Now that the prims are all cleaned up, there should be no constraints left
611 if (m_constraintCollection != null)
612 {
613 m_constraintCollection.Dispose();
614 m_constraintCollection = null;
615 }
616
598 // Anything left in the unmanaged code should be cleaned out 617 // Anything left in the unmanaged code should be cleaned out
599 BulletSimAPI.Shutdown(WorldID); 618 BulletSimAPI.Shutdown(WorldID);
600 619
@@ -727,12 +746,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
727 // Calls to the PhysicsActors can't directly call into the physics engine 746 // Calls to the PhysicsActors can't directly call into the physics engine
728 // because it might be busy. We delay changes to a known time. 747 // because it might be busy. We delay changes to a known time.
729 // We rely on C#'s closure to save and restore the context for the delegate. 748 // We rely on C#'s closure to save and restore the context for the delegate.
730 public void TaintedObject(TaintCallback callback) 749 public void TaintedObject(String ident, TaintCallback callback)
731 { 750 {
732 if (!m_initialized) return; 751 if (!m_initialized) return;
733 752
734 lock (_taintLock) 753 lock (_taintLock)
735 _taintedObjects.Add(callback); 754 _taintedObjects.Add(new TaintCallbackEntry(ident, callback));
736 return; 755 return;
737 } 756 }
738 757
@@ -744,22 +763,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters
744 if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process 763 if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process
745 { 764 {
746 // swizzle a new list into the list location so we can process what's there 765 // swizzle a new list into the list location so we can process what's there
747 List<TaintCallback> oldList; 766 List<TaintCallbackEntry> oldList;
748 lock (_taintLock) 767 lock (_taintLock)
749 { 768 {
750 oldList = _taintedObjects; 769 oldList = _taintedObjects;
751 _taintedObjects = new List<TaintCallback>(); 770 _taintedObjects = new List<TaintCallbackEntry>();
752 } 771 }
753 772
754 foreach (TaintCallback callback in oldList) 773 foreach (TaintCallbackEntry tcbe in oldList)
755 { 774 {
756 try 775 try
757 { 776 {
758 callback(); 777 tcbe.callback();
759 } 778 }
760 catch (Exception e) 779 catch (Exception e)
761 { 780 {
762 m_log.ErrorFormat("{0}: ProcessTaints: Exception: {1}", LogHeader, e); 781 m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e);
763 } 782 }
764 } 783 }
765 oldList.Clear(); 784 oldList.Clear();
@@ -767,6 +786,20 @@ public class BSScene : PhysicsScene, IPhysicsParameters
767 } 786 }
768 787
769 #region Vehicles 788 #region Vehicles
789
790 public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType)
791 {
792 if (newType == Vehicle.TYPE_NONE)
793 {
794 RemoveVehiclePrim(vehic);
795 }
796 else
797 {
798 // make it so the scene will call us each tick to do vehicle things
799 AddVehiclePrim(vehic);
800 }
801 }
802
770 // Make so the scene will call this prim for vehicle actions each tick. 803 // Make so the scene will call this prim for vehicle actions each tick.
771 // Safe to call if prim is already in the vehicle list. 804 // Safe to call if prim is already in the vehicle list.
772 public void AddVehiclePrim(BSPrim vehicle) 805 public void AddVehiclePrim(BSPrim vehicle)
@@ -812,12 +845,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
812 845
813 private struct ParameterDefn 846 private struct ParameterDefn
814 { 847 {
815 public string name; 848 public string name; // string name of the parameter
816 public string desc; 849 public string desc; // a short description of what the parameter means
817 public float defaultValue; 850 public float defaultValue; // default value if not specified anywhere else
818 public ParamUser userParam; 851 public ParamUser userParam; // get the value from the configuration file
819 public ParamGet getter; 852 public ParamGet getter; // return the current value stored for this parameter
820 public ParamSet setter; 853 public ParamSet setter; // set the current value for this parameter
821 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) 854 public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
822 { 855 {
823 name = n; 856 name = n;
@@ -834,7 +867,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
834 // To add a new externally referencable/settable parameter, add the paramter storage 867 // To add a new externally referencable/settable parameter, add the paramter storage
835 // location somewhere in the program and make an entry in this table with the 868 // location somewhere in the program and make an entry in this table with the
836 // getters and setters. 869 // getters and setters.
837 // To add a new variable, it is easiest to find an existing definition and copy it. 870 // It is easiest to find an existing definition and copy it.
838 // Parameter values are floats. Booleans are converted to a floating value. 871 // Parameter values are floats. Booleans are converted to a floating value.
839 // 872 //
840 // A ParameterDefn() takes the following parameters: 873 // A ParameterDefn() takes the following parameters:
@@ -870,7 +903,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
870 (s) => { return (float)s.m_meshLOD; }, 903 (s) => { return (float)s.m_meshLOD; },
871 (s,p,l,v) => { s.m_meshLOD = (int)v; } ), 904 (s,p,l,v) => { s.m_meshLOD = (int)v; } ),
872 new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", 905 new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
873 32, 906 32f,
874 (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, 907 (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); },
875 (s) => { return (float)s.m_sculptLOD; }, 908 (s) => { return (float)s.m_sculptLOD; },
876 (s,p,l,v) => { s.m_sculptLOD = (int)v; } ), 909 (s,p,l,v) => { s.m_sculptLOD = (int)v; } ),
@@ -1027,14 +1060,19 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1027 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), 1060 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
1028 1061
1029 1062
1030 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)", 1063 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
1031 0f, // zero to disable 1064 0f, // zero to disable
1032 (s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, 1065 (s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
1033 (s) => { return s.m_params[0].maxPersistantManifoldPoolSize; }, 1066 (s) => { return s.m_params[0].maxPersistantManifoldPoolSize; },
1034 (s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ), 1067 (s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ),
1068 new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
1069 0f, // zero to disable
1070 (s,cf,p,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); },
1071 (s) => { return s.m_params[0].maxCollisionAlgorithmPoolSize; },
1072 (s,p,l,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = v; } ),
1035 new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", 1073 new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
1036 ConfigurationParameters.numericTrue, 1074 ConfigurationParameters.numericFalse,
1037 (s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, 1075 (s,cf,p,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
1038 (s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; }, 1076 (s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; },
1039 (s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ), 1077 (s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ),
1040 new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", 1078 new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
@@ -1101,9 +1139,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1101 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), 1139 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
1102 new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements", 1140 new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
1103 ConfigurationParameters.numericFalse, 1141 ConfigurationParameters.numericFalse,
1104 (s,cf,p,v) => { s.shouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); }, 1142 (s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
1105 (s) => { return s.NumericBool(s.shouldDebugLog); }, 1143 (s) => { return s.NumericBool(s.ShouldDebugLog); },
1106 (s,p,l,v) => { s.shouldDebugLog = s.BoolNumeric(v); } ), 1144 (s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ),
1107 1145
1108 }; 1146 };
1109 1147
@@ -1243,7 +1281,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1243 List<uint> objectIDs = lIDs; 1281 List<uint> objectIDs = lIDs;
1244 string xparm = parm.ToLower(); 1282 string xparm = parm.ToLower();
1245 float xval = val; 1283 float xval = val;
1246 TaintedObject(delegate() { 1284 TaintedObject("BSScene.UpdateParameterSet", delegate() {
1247 foreach (uint lID in objectIDs) 1285 foreach (uint lID in objectIDs)
1248 { 1286 {
1249 BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval); 1287 BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval);
@@ -1263,7 +1301,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1263 uint xlocalID = localID; 1301 uint xlocalID = localID;
1264 string xparm = parm.ToLower(); 1302 string xparm = parm.ToLower();
1265 float xval = val; 1303 float xval = val;
1266 TaintedObject(delegate() { 1304 TaintedObject("BSScene.TaintedUpdateParameter", delegate() {
1267 BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval); 1305 BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval);
1268 }); 1306 });
1269 } 1307 }
@@ -1289,10 +1327,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1289 #endregion Runtime settable parameters 1327 #endregion Runtime settable parameters
1290 1328
1291 // Invoke the detailed logger and output something if it's enabled. 1329 // Invoke the detailed logger and output something if it's enabled.
1292 private void DetailLog(string msg, params Object[] args) 1330 public void DetailLog(string msg, params Object[] args)
1293 { 1331 {
1294 PhysicsLogging.Write(msg, args); 1332 PhysicsLogging.Write(msg, args);
1295 } 1333 }
1334 // used to fill in the LocalID when there isn't one
1335 public const string DetailLogZero = "0000000000";
1296 1336
1297} 1337}
1298} 1338}