diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/PhysicsModules/BulletS/BSScene.cs | 298 |
1 files changed, 226 insertions, 72 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs index 7ff0a07..163efaa 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs | |||
@@ -124,9 +124,10 @@ 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; } | 129 | // Flag that is true when the simulator is active and shouldn't be touched |
130 | public bool InSimulationTime { get; private set; } | ||
130 | 131 | ||
131 | // Pinned memory used to pass step information between managed and unmanaged | 132 | // Pinned memory used to pass step information between managed and unmanaged |
132 | internal int m_maxCollisionsPerFrame; | 133 | internal int m_maxCollisionsPerFrame; |
@@ -344,7 +345,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
344 | // Put some informational messages into the log file. | 345 | // Put some informational messages into the log file. |
345 | 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); |
346 | 347 | ||
347 | InTaintTime = false; | 348 | InSimulationTime = false; |
348 | m_initialized = true; | 349 | m_initialized = true; |
349 | 350 | ||
350 | // If the physics engine runs on its own thread, start same. | 351 | // If the physics engine runs on its own thread, start same. |
@@ -657,48 +658,57 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
657 | 658 | ||
658 | int beforeTime = Util.EnvironmentTickCount(); | 659 | int beforeTime = Util.EnvironmentTickCount(); |
659 | int simTime = 0; | 660 | int simTime = 0; |
661 | int numTaints = 0; | ||
662 | int numSubSteps = 0; | ||
660 | 663 | ||
661 | int numTaints = _taintOperations.Count; | 664 | lock (PhysicsEngineLock) |
662 | InTaintTime = true; // Only used for debugging so locking is not necessary. | 665 | { |
666 | InSimulationTime = true; | ||
667 | // update the prim states while we know the physics engine is not busy | ||
668 | numTaints += ProcessTaints(); | ||
663 | 669 | ||
664 | // update the prim states while we know the physics engine is not busy | 670 | // Some of the physical objects requre individual, pre-step calls |
665 | ProcessTaints(); | 671 | // (vehicles and avatar movement, in particular) |
672 | TriggerPreStepEvent(timeStep); | ||
666 | 673 | ||
667 | // Some of the physical objects requre individual, pre-step calls | 674 | // the prestep actions might have added taints |
668 | // (vehicles and avatar movement, in particular) | 675 | numTaints += ProcessTaints(); |
669 | TriggerPreStepEvent(timeStep); | ||
670 | 676 | ||
671 | // the prestep actions might have added taints | 677 | // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. |
672 | numTaints += _taintOperations.Count; | 678 | // Only enable this in a limited test world with few objects. |
673 | ProcessTaints(); | 679 | if (m_physicsPhysicalDumpEnabled) |
680 | PE.DumpAllInfo(World); | ||
674 | 681 | ||
675 | InTaintTime = false; // Only used for debugging so locking is not necessary. | 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 | } | ||
676 | 697 | ||
677 | // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. | 698 | // Make the physics engine dump useful statistics periodically |
678 | // Only enable this in a limited test world with few objects. | 699 | if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0)) |
679 | if (m_physicsPhysicalDumpEnabled) | 700 | PE.DumpPhysicsStatistics(World); |
680 | PE.DumpAllInfo(World); | ||
681 | 701 | ||
682 | // step the physical world one interval | 702 | InSimulationTime = false; |
683 | m_simulationStep++; | 703 | |
684 | int numSubSteps = 0; | 704 | // Some actors want to know when the simulation step is complete. |
685 | try | 705 | TriggerPostStepEvent(timeStep); |
686 | { | 706 | |
687 | numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount); | 707 | // In case there were any parameter updates that happened during the simulation step |
688 | } | 708 | numTaints += ProcessTaints(); |
689 | catch (Exception e) | ||
690 | { | ||
691 | m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}", | ||
692 | LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e); | ||
693 | DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}", | ||
694 | DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount); | ||
695 | updatedEntityCount = 0; | ||
696 | collidersCount = 0; | ||
697 | } | ||
698 | 709 | ||
699 | // Make the physics engine dump useful statistics periodically | 710 | InSimulationTime = false; |
700 | if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0)) | 711 | } |
701 | PE.DumpPhysicsStatistics(World); | ||
702 | 712 | ||
703 | // 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. |
704 | SimulationNowTime = Util.EnvironmentTickCount(); | 714 | SimulationNowTime = Util.EnvironmentTickCount(); |
@@ -748,9 +758,6 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
748 | } | 758 | } |
749 | } | 759 | } |
750 | 760 | ||
751 | // Some actors want to know when the simulation step is complete. | ||
752 | TriggerPostStepEvent(timeStep); | ||
753 | |||
754 | simTime = Util.EnvironmentTickCountSubtract(beforeTime); | 761 | simTime = Util.EnvironmentTickCountSubtract(beforeTime); |
755 | if (PhysicsLogging.Enabled) | 762 | if (PhysicsLogging.Enabled) |
756 | { | 763 | { |
@@ -956,6 +963,149 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
956 | 963 | ||
957 | #endregion // Terrain | 964 | #endregion // Terrain |
958 | 965 | ||
966 | #region Raycast | ||
967 | |||
968 | public override bool SupportsRayCast() | ||
969 | { | ||
970 | return BSParam.UseBulletRaycast; | ||
971 | } | ||
972 | |||
973 | public override bool SupportsRaycastWorldFiltered() | ||
974 | { | ||
975 | return BSParam.UseBulletRaycast; | ||
976 | } | ||
977 | |||
978 | |||
979 | /// <summary> | ||
980 | /// Queue a raycast against the physics scene. | ||
981 | /// The provided callback method will be called when the raycast is complete | ||
982 | /// | ||
983 | /// Many physics engines don't support collision testing at the same time as | ||
984 | /// manipulating the physics scene, so we queue the request up and callback | ||
985 | /// a custom method when the raycast is complete. | ||
986 | /// This allows physics engines that give an immediate result to callback immediately | ||
987 | /// and ones that don't, to callback when it gets a result back. | ||
988 | /// public delegate void RayCallback(List<ContactResult> list); | ||
989 | /// | ||
990 | /// ODE for example will not allow you to change the scene while collision testing or | ||
991 | /// it asserts, 'opteration not valid for locked space'. This includes adding a ray to the scene. | ||
992 | /// | ||
993 | /// This is named RayCastWorld to not conflict with modrex's Raycast method. | ||
994 | /// </summary> | ||
995 | /// <param name="position">Origin of the ray</param> | ||
996 | /// <param name="direction">Direction of the ray</param> | ||
997 | /// <param name="length">Length of ray in meters</param> | ||
998 | /// <param name="retMethod">Method to call when the raycast is complete</param> | ||
999 | public override void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) | ||
1000 | { | ||
1001 | if (retMethod != null) | ||
1002 | { | ||
1003 | if (BSParam.UseBulletRaycast) | ||
1004 | { | ||
1005 | Vector3 posFrom = position; | ||
1006 | Vector3 posTo = Vector3.Normalize(direction) * length + position; | ||
1007 | |||
1008 | TaintedObject(DetailLogZero, "BSScene.RaycastWorld1", delegate () | ||
1009 | { | ||
1010 | RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, 0xffff, 0xffff); | ||
1011 | retMethod(true, hitInfo.Point, hitInfo.ID, hitInfo.Fraction, hitInfo.Normal); | ||
1012 | }); | ||
1013 | } | ||
1014 | else | ||
1015 | { | ||
1016 | retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero); | ||
1017 | } | ||
1018 | } | ||
1019 | } | ||
1020 | |||
1021 | public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod) | ||
1022 | { | ||
1023 | if (retMethod != null) | ||
1024 | { | ||
1025 | if (BSParam.UseBulletRaycast) | ||
1026 | { | ||
1027 | List<ContactResult> hitInfo = RaycastWorld(position, direction, length, count); | ||
1028 | retMethod(hitInfo); | ||
1029 | } | ||
1030 | else | ||
1031 | { | ||
1032 | retMethod(new List<ContactResult>()); | ||
1033 | } | ||
1034 | } | ||
1035 | } | ||
1036 | |||
1037 | public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int count) | ||
1038 | { | ||
1039 | return (List<ContactResult>)RaycastWorld(position, direction, length, count, RayFilterFlags.All); | ||
1040 | } | ||
1041 | |||
1042 | public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayFilterFlags filter) | ||
1043 | { | ||
1044 | List<ContactResult> ret = new List<ContactResult>(); | ||
1045 | if (BSParam.UseBulletRaycast) | ||
1046 | { | ||
1047 | uint collisionFilter = 0; | ||
1048 | uint collisionMask = 0; | ||
1049 | if ((filter & RayFilterFlags.land) != 0) | ||
1050 | { | ||
1051 | collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Terrain].group; | ||
1052 | collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Terrain].mask; | ||
1053 | } | ||
1054 | if ((filter & RayFilterFlags.agent) != 0) | ||
1055 | { | ||
1056 | collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Avatar].group; | ||
1057 | collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Avatar].mask; | ||
1058 | } | ||
1059 | if ((filter & RayFilterFlags.nonphysical) != 0) | ||
1060 | { | ||
1061 | collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Static].group; | ||
1062 | collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Static].mask; | ||
1063 | } | ||
1064 | if ((filter & RayFilterFlags.physical) != 0) | ||
1065 | { | ||
1066 | collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Dynamic].group; | ||
1067 | collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Dynamic].mask; | ||
1068 | } | ||
1069 | // if ((filter & RayFilterFlags.phantom) != 0) | ||
1070 | // { | ||
1071 | // collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].group; | ||
1072 | // collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].mask; | ||
1073 | // } | ||
1074 | if ((filter & RayFilterFlags.volumedtc) != 0) | ||
1075 | { | ||
1076 | collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].group; | ||
1077 | collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].mask; | ||
1078 | } | ||
1079 | DetailLog("{0},RaycastWorld,pos={1},dir={2},len={3},count={4},filter={5},filter={6},mask={7}", | ||
1080 | DetailLogZero, position, direction, length, count, filter, collisionFilter, collisionMask); | ||
1081 | // NOTE: locking ensures the physics engine is not executing. | ||
1082 | // The caller might have to wait for the physics engine to finish. | ||
1083 | lock (PhysicsEngineLock) | ||
1084 | { | ||
1085 | Vector3 posFrom = position; | ||
1086 | Vector3 posTo = Vector3.Normalize(direction) * length + position; | ||
1087 | DetailLog("{0},RaycastWorld,RayTest2,from={1},to={2}", | ||
1088 | DetailLogZero, posFrom, posTo); | ||
1089 | RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, collisionFilter, collisionMask); | ||
1090 | if (hitInfo.hasHit()) | ||
1091 | { | ||
1092 | ContactResult result = new ContactResult(); | ||
1093 | result.Pos = hitInfo.Point; | ||
1094 | result.Normal = hitInfo.Normal; | ||
1095 | result.ConsumerID = hitInfo.ID; | ||
1096 | result.Depth = hitInfo.Fraction; | ||
1097 | ret.Add(result); | ||
1098 | DetailLog("{0},RaycastWorld,hit,pos={1},norm={2},depth={3},id={4}", | ||
1099 | DetailLogZero, result.Pos, result.Normal, result.Depth, result.ConsumerID); | ||
1100 | } | ||
1101 | } | ||
1102 | } | ||
1103 | return ret; | ||
1104 | } | ||
1105 | |||
1106 | #endregion Raycast | ||
1107 | |||
1108 | |||
959 | public override Dictionary<uint, float> GetTopColliders() | 1109 | public override Dictionary<uint, float> GetTopColliders() |
960 | { | 1110 | { |
961 | Dictionary<uint, float> topColliders; | 1111 | Dictionary<uint, float> topColliders; |
@@ -1068,32 +1218,35 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
1068 | // Calls to the PhysicsActors can't directly call into the physics engine | 1218 | // Calls to the PhysicsActors can't directly call into the physics engine |
1069 | // because it might be busy. We delay changes to a known time. | 1219 | // because it might be busy. We delay changes to a known time. |
1070 | // We rely on C#'s closure to save and restore the context for the delegate. | 1220 | // We rely on C#'s closure to save and restore the context for the delegate. |
1071 | public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback) | 1221 | // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed. |
1222 | // public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback) | ||
1223 | // { | ||
1224 | // TaintedObject(BSScene.DetailLogZero, pIdent, pCallback); | ||
1225 | // } | ||
1226 | // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed. | ||
1227 | public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback) | ||
1072 | { | 1228 | { |
1073 | TaintedObject(false /*inTaintTime*/, pOriginator, pIdent, pCallback); | 1229 | TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); |
1074 | } | 1230 | } |
1075 | public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback) | 1231 | public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback) |
1076 | { | 1232 | { |
1077 | TaintedObject(false /*inTaintTime*/, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); | 1233 | TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); |
1078 | } | ||
1079 | public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback) | ||
1080 | { | ||
1081 | TaintedObject(inTaintTime, BSScene.DetailLogZero, pIdent, pCallback); | ||
1082 | } | ||
1083 | public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback) | ||
1084 | { | ||
1085 | TaintedObject(inTaintTime, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); | ||
1086 | } | 1234 | } |
1087 | // Sometimes a potentially tainted operation can be used in and out of taint time. | 1235 | // Sometimes a potentially tainted operation can be used in and out of taint time. |
1088 | // This routine executes the command immediately if in taint-time otherwise it is queued. | 1236 | // This routine executes the command immediately if in taint-time otherwise it is queued. |
1089 | public void TaintedObject(bool inTaintTime, string pOriginator, string pIdent, TaintCallback pCallback) | 1237 | public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback) |
1090 | { | 1238 | { |
1091 | if (!m_initialized) return; | 1239 | if (!m_initialized) return; |
1092 | 1240 | ||
1093 | if (inTaintTime) | 1241 | if (Monitor.TryEnter(PhysicsEngineLock)) |
1242 | { | ||
1243 | // If we can get exclusive access to the physics engine, just do the operation | ||
1094 | pCallback(); | 1244 | pCallback(); |
1245 | Monitor.Exit(PhysicsEngineLock); | ||
1246 | } | ||
1095 | else | 1247 | else |
1096 | { | 1248 | { |
1249 | // The physics engine is busy, queue the operation | ||
1097 | lock (_taintLock) | 1250 | lock (_taintLock) |
1098 | { | 1251 | { |
1099 | _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback)); | 1252 | _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback)); |
@@ -1120,14 +1273,21 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
1120 | // When someone tries to change a property on a BSPrim or BSCharacter, the object queues | 1273 | // When someone tries to change a property on a BSPrim or BSCharacter, the object queues |
1121 | // a callback into itself to do the actual property change. That callback is called | 1274 | // a callback into itself to do the actual property change. That callback is called |
1122 | // here just before the physics engine is called to step the simulation. | 1275 | // here just before the physics engine is called to step the simulation. |
1123 | public void ProcessTaints() | 1276 | // Returns the number of taints processed |
1277 | // NOTE: Called while PhysicsEngineLock is locked | ||
1278 | public int ProcessTaints() | ||
1124 | { | 1279 | { |
1125 | ProcessRegularTaints(); | 1280 | int ret = 0; |
1126 | ProcessPostTaintTaints(); | 1281 | ret += ProcessRegularTaints(); |
1282 | ret += ProcessPostTaintTaints(); | ||
1283 | return ret; | ||
1127 | } | 1284 | } |
1128 | 1285 | ||
1129 | private void ProcessRegularTaints() | 1286 | // Returns the number of taints processed |
1287 | // NOTE: Called while PhysicsEngineLock is locked | ||
1288 | private int ProcessRegularTaints() | ||
1130 | { | 1289 | { |
1290 | int ret = 0; | ||
1131 | if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process | 1291 | if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process |
1132 | { | 1292 | { |
1133 | // swizzle a new list into the list location so we can process what's there | 1293 | // swizzle a new list into the list location so we can process what's there |
@@ -1144,6 +1304,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
1144 | { | 1304 | { |
1145 | DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG | 1305 | DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG |
1146 | tcbe.callback(); | 1306 | tcbe.callback(); |
1307 | ret++; | ||
1147 | } | 1308 | } |
1148 | catch (Exception e) | 1309 | catch (Exception e) |
1149 | { | 1310 | { |
@@ -1152,6 +1313,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
1152 | } | 1313 | } |
1153 | oldList.Clear(); | 1314 | oldList.Clear(); |
1154 | } | 1315 | } |
1316 | return ret; | ||
1155 | } | 1317 | } |
1156 | 1318 | ||
1157 | // Schedule an update to happen after all the regular taints are processed. | 1319 | // Schedule an update to happen after all the regular taints are processed. |
@@ -1170,8 +1332,11 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
1170 | } | 1332 | } |
1171 | 1333 | ||
1172 | // Taints that happen after the normal taint processing but before the simulation step. | 1334 | // Taints that happen after the normal taint processing but before the simulation step. |
1173 | private void ProcessPostTaintTaints() | 1335 | // Returns the number of taints processed |
1336 | // NOTE: Called while PhysicsEngineLock is locked | ||
1337 | private int ProcessPostTaintTaints() | ||
1174 | { | 1338 | { |
1339 | int ret = 0; | ||
1175 | if (m_initialized && _postTaintOperations.Count > 0) | 1340 | if (m_initialized && _postTaintOperations.Count > 0) |
1176 | { | 1341 | { |
1177 | Dictionary<string, TaintCallbackEntry> oldList; | 1342 | Dictionary<string, TaintCallbackEntry> oldList; |
@@ -1187,6 +1352,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
1187 | { | 1352 | { |
1188 | DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG | 1353 | DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG |
1189 | kvp.Value.callback(); | 1354 | kvp.Value.callback(); |
1355 | ret++; | ||
1190 | } | 1356 | } |
1191 | catch (Exception e) | 1357 | catch (Exception e) |
1192 | { | 1358 | { |
@@ -1195,20 +1361,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS | |||
1195 | } | 1361 | } |
1196 | oldList.Clear(); | 1362 | oldList.Clear(); |
1197 | } | 1363 | } |
1364 | return ret; | ||
1198 | } | 1365 | } |
1199 | |||
1200 | // Only used for debugging. Does not change state of anything so locking is not necessary. | ||
1201 | public bool AssertInTaintTime(string whereFrom) | ||
1202 | { | ||
1203 | if (!InTaintTime) | ||
1204 | { | ||
1205 | DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); | ||
1206 | m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); | ||
1207 | // Util.PrintCallStack(DetailLog); | ||
1208 | } | ||
1209 | return InTaintTime; | ||
1210 | } | ||
1211 | |||
1212 | #endregion // Taints | 1366 | #endregion // Taints |
1213 | 1367 | ||
1214 | #region IPhysicsParameters | 1368 | #region IPhysicsParameters |