diff options
Diffstat (limited to 'OpenSim/Region/PhysicsModules/BulletS/BSScene.cs')
-rw-r--r-- | OpenSim/Region/PhysicsModules/BulletS/BSScene.cs | 182 |
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 |