aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/PhysicsModules/BulletS/BSScene.cs')
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSScene.cs182
1 files changed, 89 insertions, 93 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
index 52aea87..ca54721 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
@@ -124,10 +124,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS
124 // True if initialized and ready to do simulation steps 124 // True if initialized and ready to do simulation steps
125 private bool m_initialized = false; 125 private bool m_initialized = false;
126 126
127 // Flag which is true when processing taints. 127 // Object locked whenever execution is inside the physics engine
128 // Not guaranteed to be correct all the time (don't depend on this) but good for debugging. 128 public Object PhysicsEngineLock = new object();
129 public bool InTaintTime { get; private set; }
130
131 // Flag that is true when the simulator is active and shouldn't be touched 129 // Flag that is true when the simulator is active and shouldn't be touched
132 public bool InSimulationTime { get; private set; } 130 public bool InSimulationTime { get; private set; }
133 131
@@ -348,7 +346,6 @@ namespace OpenSim.Region.PhysicsModule.BulletS
348 m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation); 346 m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation);
349 347
350 InSimulationTime = false; 348 InSimulationTime = false;
351 InTaintTime = false;
352 m_initialized = true; 349 m_initialized = true;
353 350
354 // If the physics engine runs on its own thread, start same. 351 // If the physics engine runs on its own thread, start same.
@@ -661,60 +658,57 @@ namespace OpenSim.Region.PhysicsModule.BulletS
661 658
662 int beforeTime = Util.EnvironmentTickCount(); 659 int beforeTime = Util.EnvironmentTickCount();
663 int simTime = 0; 660 int simTime = 0;
661 int numTaints = 0;
662 int numSubSteps = 0;
664 663
665 InTaintTime = true; 664 lock (PhysicsEngineLock)
666 // update the prim states while we know the physics engine is not busy
667 int numTaints = ProcessTaints();
668
669 // Some of the physical objects requre individual, pre-step calls
670 // (vehicles and avatar movement, in particular)
671 TriggerPreStepEvent(timeStep);
672
673 // the prestep actions might have added taints
674 numTaints += ProcessTaints();
675
676 lock (_taintLock)
677 { 665 {
678 InSimulationTime = true; 666 InSimulationTime = true;
679 } 667 // update the prim states while we know the physics engine is not busy
668 numTaints += ProcessTaints();
680 669
681 // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. 670 // Some of the physical objects requre individual, pre-step calls
682 // Only enable this in a limited test world with few objects. 671 // (vehicles and avatar movement, in particular)
683 if (m_physicsPhysicalDumpEnabled) 672 TriggerPreStepEvent(timeStep);
684 PE.DumpAllInfo(World);
685 673
686 // step the physical world one interval 674 // the prestep actions might have added taints
687 m_simulationStep++; 675 numTaints += ProcessTaints();
688 int numSubSteps = 0;
689 try
690 {
691 numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
692 }
693 catch (Exception e)
694 {
695 m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
696 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
697 DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
698 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
699 updatedEntityCount = 0;
700 collidersCount = 0;
701 }
702 676
703 // Make the physics engine dump useful statistics periodically 677 // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
704 if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0)) 678 // Only enable this in a limited test world with few objects.
705 PE.DumpPhysicsStatistics(World); 679 if (m_physicsPhysicalDumpEnabled)
680 PE.DumpAllInfo(World);
681
682 // step the physical world one interval
683 m_simulationStep++;
684 try
685 {
686 numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
687 }
688 catch (Exception e)
689 {
690 m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
691 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
692 DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
693 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
694 updatedEntityCount = 0;
695 collidersCount = 0;
696 }
697
698 // Make the physics engine dump useful statistics periodically
699 if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0))
700 PE.DumpPhysicsStatistics(World);
706 701
707 lock (_taintLock)
708 {
709 InTaintTime = false;
710 InSimulationTime = false; 702 InSimulationTime = false;
711 }
712 703
713 // Some actors want to know when the simulation step is complete. 704 // Some actors want to know when the simulation step is complete.
714 TriggerPostStepEvent(timeStep); 705 TriggerPostStepEvent(timeStep);
715 706
716 // In case there were any parameter updates that happened during the simulation step 707 // In case there were any parameter updates that happened during the simulation step
717 numTaints += ProcessTaints(); 708 numTaints += ProcessTaints();
709
710 InSimulationTime = false;
711 }
718 712
719 // Get a value for 'now' so all the collision and update routines don't have to get their own. 713 // Get a value for 'now' so all the collision and update routines don't have to get their own.
720 SimulationNowTime = Util.EnvironmentTickCount(); 714 SimulationNowTime = Util.EnvironmentTickCount();
@@ -1040,20 +1034,39 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1040 } 1034 }
1041 } 1035 }
1042 1036
1043 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) 1037 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int count)
1044 { 1038 {
1045 List<ContactResult> ret = new List<ContactResult>(); 1039 return (List<ContactResult>)RaycastWorld(position, direction, length, count, RayFilterFlags.All);
1046 if (BSParam.UseBulletRaycast)
1047 {
1048 }
1049 return ret;
1050 } 1040 }
1051 1041
1052 public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) 1042 public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayFilterFlags filter)
1053 { 1043 {
1054 object ret = null; 1044 List<ContactResult> ret = new List<ContactResult>();
1055 if (BSParam.UseBulletRaycast) 1045 if (BSParam.UseBulletRaycast)
1056 { 1046 {
1047 DetailLog("{0},RaycastWorld,pos={1},dir={2},len={3},count={4},filter={5}",
1048 DetailLogZero, position, direction, length, count, filter);
1049 // NOTE: locking ensures the physics engine is not executing.
1050 // The caller might have to wait for the physics engine to finish.
1051 lock (PhysicsEngineLock)
1052 {
1053 Vector3 posFrom = position;
1054 Vector3 posTo = Vector3.Normalize(direction) * length + position;
1055 DetailLog("{0},RaycastWorld,RayTest2,from={1},to={2}",
1056 DetailLogZero, posFrom, posTo);
1057 RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, 0xffff, 0xffff);
1058 if (hitInfo.hasHit())
1059 {
1060 ContactResult result = new ContactResult();
1061 result.Pos = hitInfo.Point;
1062 result.Normal = hitInfo.Normal;
1063 result.ConsumerID = hitInfo.ID;
1064 result.Depth = hitInfo.Fraction;
1065 ret.Add(result);
1066 DetailLog("{0},RaycastWorld,hit,pos={1},norm={2},depth={3},id={4}",
1067 DetailLogZero, result.Pos, result.Normal, result.Depth, result.ConsumerID);
1068 }
1069 }
1057 } 1070 }
1058 return ret; 1071 return ret;
1059 } 1072 }
@@ -1173,47 +1186,40 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1173 // Calls to the PhysicsActors can't directly call into the physics engine 1186 // Calls to the PhysicsActors can't directly call into the physics engine
1174 // because it might be busy. We delay changes to a known time. 1187 // because it might be busy. We delay changes to a known time.
1175 // We rely on C#'s closure to save and restore the context for the delegate. 1188 // We rely on C#'s closure to save and restore the context for the delegate.
1176 public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback) 1189 // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed.
1190 // public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
1191 // {
1192 // TaintedObject(BSScene.DetailLogZero, pIdent, pCallback);
1193 // }
1194 // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed.
1195 public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
1177 { 1196 {
1178 TaintedObject(false /*inTaintTime*/, pOriginator, pIdent, pCallback); 1197 TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1179 } 1198 }
1180 public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback) 1199 public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback)
1181 { 1200 {
1182 TaintedObject(false /*inTaintTime*/, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); 1201 TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1183 }
1184 public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
1185 {
1186 TaintedObject(inTaintTime, BSScene.DetailLogZero, pIdent, pCallback);
1187 }
1188 public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
1189 {
1190 TaintedObject(inTaintTime, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1191 } 1202 }
1192 // Sometimes a potentially tainted operation can be used in and out of taint time. 1203 // Sometimes a potentially tainted operation can be used in and out of taint time.
1193 // This routine executes the command immediately if in taint-time otherwise it is queued. 1204 // This routine executes the command immediately if in taint-time otherwise it is queued.
1194 public void TaintedObject(bool inTaintTime, string pOriginator, string pIdent, TaintCallback pCallback) 1205 public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback)
1195 { 1206 {
1196 if (!m_initialized) return; 1207 if (!m_initialized) return;
1197 1208
1198 lock (_taintLock) { 1209 if (Monitor.TryEnter(PhysicsEngineLock))
1199 if (inTaintTime || !InSimulationTime) { 1210 {
1200 pCallback(); 1211 // If we can get exclusive access to the physics engine, just do the operation
1201 }
1202 else {
1203 _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
1204 }
1205 }
1206 /*
1207 if (inTaintTime)
1208 pCallback(); 1212 pCallback();
1213 Monitor.Exit(PhysicsEngineLock);
1214 }
1209 else 1215 else
1210 { 1216 {
1217 // The physics engine is busy, queue the operation
1211 lock (_taintLock) 1218 lock (_taintLock)
1212 { 1219 {
1213 _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback)); 1220 _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
1214 } 1221 }
1215 } 1222 }
1216 */
1217 } 1223 }
1218 1224
1219 private void TriggerPreStepEvent(float timeStep) 1225 private void TriggerPreStepEvent(float timeStep)
@@ -1236,6 +1242,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1236 // a callback into itself to do the actual property change. That callback is called 1242 // a callback into itself to do the actual property change. That callback is called
1237 // here just before the physics engine is called to step the simulation. 1243 // here just before the physics engine is called to step the simulation.
1238 // Returns the number of taints processed 1244 // Returns the number of taints processed
1245 // NOTE: Called while PhysicsEngineLock is locked
1239 public int ProcessTaints() 1246 public int ProcessTaints()
1240 { 1247 {
1241 int ret = 0; 1248 int ret = 0;
@@ -1245,6 +1252,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1245 } 1252 }
1246 1253
1247 // Returns the number of taints processed 1254 // Returns the number of taints processed
1255 // NOTE: Called while PhysicsEngineLock is locked
1248 private int ProcessRegularTaints() 1256 private int ProcessRegularTaints()
1249 { 1257 {
1250 int ret = 0; 1258 int ret = 0;
@@ -1293,6 +1301,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1293 1301
1294 // Taints that happen after the normal taint processing but before the simulation step. 1302 // Taints that happen after the normal taint processing but before the simulation step.
1295 // Returns the number of taints processed 1303 // Returns the number of taints processed
1304 // NOTE: Called while PhysicsEngineLock is locked
1296 private int ProcessPostTaintTaints() 1305 private int ProcessPostTaintTaints()
1297 { 1306 {
1298 int ret = 0; 1307 int ret = 0;
@@ -1322,19 +1331,6 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1322 } 1331 }
1323 return ret; 1332 return ret;
1324 } 1333 }
1325
1326 // Verify that things are being diddled when the physics engine is not running.
1327 public bool AssertNotInSimulationTime(string whereFrom)
1328 {
1329 if (InSimulationTime)
1330 {
1331 DetailLog("{0},BSScene.AssertInTaintTime,IN SIMULATION TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
1332 m_log.ErrorFormat("{0} IN SIMULATION TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
1333 // Util.PrintCallStack(DetailLog);
1334 }
1335 return InSimulationTime;
1336 }
1337
1338 #endregion // Taints 1334 #endregion // Taints
1339 1335
1340 #region IPhysicsParameters 1336 #region IPhysicsParameters