diff options
Diffstat (limited to 'OpenSim/Region/PhysicsModules')
8 files changed, 137 insertions, 128 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs index afb0ba2..a288048 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs | |||
@@ -121,6 +121,14 @@ public struct SweepHit | |||
121 | public float Fraction; | 121 | public float Fraction; |
122 | public Vector3 Normal; | 122 | public Vector3 Normal; |
123 | public Vector3 Point; | 123 | public Vector3 Point; |
124 | |||
125 | public bool hasHit() | ||
126 | { | ||
127 | float sum = Fraction | ||
128 | + Normal.X + Normal.Y + Normal.Z | ||
129 | + Point.X + Point.Y + Point.Z; | ||
130 | return (sum != 0) || (ID != 0); | ||
131 | } | ||
124 | } | 132 | } |
125 | [StructLayout(LayoutKind.Sequential)] | 133 | [StructLayout(LayoutKind.Sequential)] |
126 | public struct RaycastHit | 134 | public struct RaycastHit |
@@ -129,6 +137,12 @@ public struct RaycastHit | |||
129 | public float Fraction; | 137 | public float Fraction; |
130 | public Vector3 Normal; | 138 | public Vector3 Normal; |
131 | public Vector3 Point; | 139 | public Vector3 Point; |
140 | |||
141 | public bool hasHit() | ||
142 | { | ||
143 | float sum = Normal.X + Normal.Y + Normal.Z + Point.X + Point.Y + Point.Z; | ||
144 | return (sum != 0); | ||
145 | } | ||
132 | } | 146 | } |
133 | [StructLayout(LayoutKind.Sequential)] | 147 | [StructLayout(LayoutKind.Sequential)] |
134 | public struct CollisionDesc | 148 | public struct CollisionDesc |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs index 04ac659..7faee70 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs | |||
@@ -496,7 +496,6 @@ public sealed class BSCharacter : BSPhysObject | |||
496 | public override OMV.Vector3 ForceVelocity { | 496 | public override OMV.Vector3 ForceVelocity { |
497 | get { return RawVelocity; } | 497 | get { return RawVelocity; } |
498 | set { | 498 | set { |
499 | PhysScene.AssertNotInSimulationTime("BSCharacter.ForceVelocity"); | ||
500 | DetailLog("{0},BSCharacter.ForceVelocity.set={1}", LocalID, value); | 499 | DetailLog("{0},BSCharacter.ForceVelocity.set={1}", LocalID, value); |
501 | 500 | ||
502 | RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); | 501 | RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); |
@@ -638,8 +637,6 @@ public sealed class BSCharacter : BSPhysObject | |||
638 | public override float ForceBuoyancy { | 637 | public override float ForceBuoyancy { |
639 | get { return _buoyancy; } | 638 | get { return _buoyancy; } |
640 | set { | 639 | set { |
641 | PhysScene.AssertNotInSimulationTime("BSCharacter.ForceBuoyancy"); | ||
642 | |||
643 | _buoyancy = value; | 640 | _buoyancy = value; |
644 | DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 641 | DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
645 | // Buoyancy is faked by changing the gravity applied to the object | 642 | // Buoyancy is faked by changing the gravity applied to the object |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs index 0792f5d..fcda92c 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs | |||
@@ -838,7 +838,7 @@ public static class BSParam | |||
838 | new ParameterDefn<float>("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool", | 838 | new ParameterDefn<float>("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool", |
839 | 0f, | 839 | 0f, |
840 | (s) => { return 0f; }, | 840 | (s) => { return 0f; }, |
841 | (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v, false /* inTaintTime */); } ), | 841 | (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v); } ), |
842 | new ParameterDefn<float>("ResetConstraintSolver", "Setting this is any value resets the constraint solver", | 842 | new ParameterDefn<float>("ResetConstraintSolver", "Setting this is any value resets the constraint solver", |
843 | 0f, | 843 | 0f, |
844 | (s) => { return 0f; }, | 844 | (s) => { return 0f; }, |
@@ -924,10 +924,10 @@ public static class BSParam | |||
924 | // ===================================================================== | 924 | // ===================================================================== |
925 | // There are parameters that, when set, cause things to happen in the physics engine. | 925 | // There are parameters that, when set, cause things to happen in the physics engine. |
926 | // This causes the broadphase collision cache to be cleared. | 926 | // This causes the broadphase collision cache to be cleared. |
927 | private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v, bool inTaintTime) | 927 | private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v) |
928 | { | 928 | { |
929 | BSScene physScene = pPhysScene; | 929 | BSScene physScene = pPhysScene; |
930 | physScene.TaintedObject(inTaintTime, "BSParam.ResetBroadphasePoolTainted", delegate() | 930 | physScene.TaintedObject(BSScene.DetailLogZero, "BSParam.ResetBroadphasePoolTainted", delegate() |
931 | { | 931 | { |
932 | physScene.PE.ResetBroadphasePool(physScene.World); | 932 | physScene.PE.ResetBroadphasePool(physScene.World); |
933 | }); | 933 | }); |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs index e1990ee..f085d70 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs | |||
@@ -790,8 +790,6 @@ public class BSPrim : BSPhysObject | |||
790 | public override OMV.Vector3 ForceVelocity { | 790 | public override OMV.Vector3 ForceVelocity { |
791 | get { return RawVelocity; } | 791 | get { return RawVelocity; } |
792 | set { | 792 | set { |
793 | PhysScene.AssertNotInSimulationTime("BSPrim.ForceVelocity"); | ||
794 | |||
795 | RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); | 793 | RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); |
796 | if (PhysBody.HasPhysicalBody) | 794 | if (PhysBody.HasPhysicalBody) |
797 | { | 795 | { |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs index d8ed56b..3f90fc5 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs | |||
@@ -81,7 +81,6 @@ public class BSPrimDisplaced : BSPrim | |||
81 | // Called at taint time. | 81 | // Called at taint time. |
82 | public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) | 82 | public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) |
83 | { | 83 | { |
84 | PhysScene.AssertInTaintTime("BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement"); | ||
85 | Vector3 comDisp; | 84 | Vector3 comDisp; |
86 | if (UserSetCenterOfMassDisplacement.HasValue) | 85 | if (UserSetCenterOfMassDisplacement.HasValue) |
87 | comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; | 86 | comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; |
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 |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs index cda33e4..86bf23f 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs | |||
@@ -75,8 +75,6 @@ public sealed class BSShapeCollection : IDisposable | |||
75 | // Called at taint-time. | 75 | // Called at taint-time. |
76 | public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback) | 76 | public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback) |
77 | { | 77 | { |
78 | m_physicsScene.AssertNotInSimulationTime("BSShapeCollection.GetBodyAndShape"); | ||
79 | |||
80 | bool ret = false; | 78 | bool ret = false; |
81 | 79 | ||
82 | // This lock could probably be pushed down lower but building shouldn't take long | 80 | // This lock could probably be pushed down lower but building shouldn't take long |
@@ -346,8 +344,6 @@ public sealed class BSShapeCollection : IDisposable | |||
346 | if (!body.HasPhysicalBody) | 344 | if (!body.HasPhysicalBody) |
347 | return; | 345 | return; |
348 | 346 | ||
349 | m_physicsScene.AssertNotInSimulationTime("BSShapeCollection.DereferenceBody"); | ||
350 | |||
351 | lock (m_collectionActivityLock) | 347 | lock (m_collectionActivityLock) |
352 | { | 348 | { |
353 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.ID, body); | 349 | if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.ID, body); |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs index 046df56..bfa95c1 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs | |||
@@ -48,67 +48,76 @@ namespace OpenSim.Region.PhysicsModule.BulletS.Tests | |||
48 | // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 | 48 | // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 |
49 | // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 | 49 | // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 |
50 | 50 | ||
51 | BSScene PhysicsScene { get; set; } | 51 | BSScene _physicsScene { get; set; } |
52 | BSPrim TargetSphere { get; set; } | 52 | BSPrim _targetSphere { get; set; } |
53 | Vector3 TargetSpherePosition { get; set; } | 53 | Vector3 _targetSpherePosition { get; set; } |
54 | float simulationTimeStep = 0.089f; | 54 | float _simulationTimeStep = 0.089f; |
55 | |||
56 | uint _targetLocalID = 123; | ||
55 | 57 | ||
56 | [TestFixtureSetUp] | 58 | [TestFixtureSetUp] |
57 | public void Init() | 59 | public void Init() |
58 | { | 60 | { |
59 | Dictionary<string, string> engineParams = new Dictionary<string, string>(); | 61 | Dictionary<string, string> engineParams = new Dictionary<string, string>(); |
60 | engineParams.Add("UseBulletRaycast", "true"); | 62 | engineParams.Add("UseBulletRaycast", "true"); |
61 | PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams); | 63 | _physicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams); |
62 | 64 | ||
63 | PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere(); | 65 | PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere(); |
64 | Vector3 pos = new Vector3(100.0f, 100.0f, 50f); | 66 | Vector3 pos = new Vector3(100.0f, 100.0f, 50f); |
65 | pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2f; | 67 | _targetSpherePosition = pos; |
66 | TargetSpherePosition = pos; | ||
67 | Vector3 size = new Vector3(10f, 10f, 10f); | 68 | Vector3 size = new Vector3(10f, 10f, 10f); |
68 | pbs.Scale = size; | 69 | pbs.Scale = size; |
69 | Quaternion rot = Quaternion.Identity; | 70 | Quaternion rot = Quaternion.Identity; |
70 | bool isPhys = false; | 71 | bool isPhys = false; |
71 | uint localID = 123; | ||
72 | 72 | ||
73 | PhysicsScene.AddPrimShape("TargetSphere", pbs, pos, size, rot, isPhys, localID); | 73 | _physicsScene.AddPrimShape("TargetSphere", pbs, pos, size, rot, isPhys, _targetLocalID); |
74 | TargetSphere = (BSPrim)PhysicsScene.PhysObjects[localID]; | 74 | _targetSphere = (BSPrim)_physicsScene.PhysObjects[_targetLocalID]; |
75 | // The actual prim shape creation happens at taint time | 75 | // The actual prim shape creation happens at taint time |
76 | PhysicsScene.ProcessTaints(); | 76 | _physicsScene.ProcessTaints(); |
77 | 77 | ||
78 | } | 78 | } |
79 | 79 | ||
80 | [TestFixtureTearDown] | 80 | [TestFixtureTearDown] |
81 | public void TearDown() | 81 | public void TearDown() |
82 | { | 82 | { |
83 | if (PhysicsScene != null) | 83 | if (_physicsScene != null) |
84 | { | 84 | { |
85 | // The Dispose() will also free any physical objects in the scene | 85 | // The Dispose() will also free any physical objects in the scene |
86 | PhysicsScene.Dispose(); | 86 | _physicsScene.Dispose(); |
87 | PhysicsScene = null; | 87 | _physicsScene = null; |
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | // There is a 10x10x10 sphere at <100,100,50> | 91 | // There is a 10x10x10 sphere at <100,100,50> |
92 | // Shoot rays around the sphere and verify it hits and doesn't hit | 92 | // Shoot rays around the sphere and verify it hits and doesn't hit |
93 | // TestCase parameters are <x,y,z> of start and <x,y,z> of end and expected result | 93 | // TestCase parameters are <x,y,z> of start and <x,y,z> of end and expected result |
94 | [TestCase(20f, 20f, 50f, 50f, 50f, 50f, true)] // in front to sphere | 94 | [TestCase(100f, 50f, 50f, 100f, 150f, 50f, true, "Pass through sphere from front")] |
95 | [TestCase(20f, 20f, 100f, 50f, 50f, 50f, true)] // from above to sphere | 95 | [TestCase(50f, 100f, 50f, 150f, 100f, 50f, true, "Pass through sphere from side")] |
96 | [TestCase(50f, 50f, 50f, 150f, 150f, 50f, true)] // through sphere | 96 | [TestCase(50f, 50f, 50f, 150f, 150f, 50f, true, "Pass through sphere diaginally")] |
97 | [TestCase(50f, 50f, 65f, 150f, 150f, 65f, false)] // pass over sphere | 97 | [TestCase(100f, 100f, 100f, 100f, 100f, 20f, true, "Pass through sphere from above")] |
98 | public void RaycastAroundObject(float fromX, float fromY, float fromZ, float toX, float toY, float toZ, bool expected) { | 98 | [TestCase(20f, 20f, 50f, 80f, 80f, 50f, false, "Not reach sphere")] |
99 | [TestCase(50f, 50f, 65f, 150f, 150f, 65f, false, "Passed over sphere")] | ||
100 | public void RaycastAroundObject(float fromX, float fromY, float fromZ, float toX, float toY, float toZ, bool expected, string msg) { | ||
99 | Vector3 fromPos = new Vector3(fromX, fromY, fromZ); | 101 | Vector3 fromPos = new Vector3(fromX, fromY, fromZ); |
100 | Vector3 toPos = new Vector3(toX, toY, toZ); | 102 | Vector3 toPos = new Vector3(toX, toY, toZ); |
101 | Vector3 direction = toPos - fromPos; | 103 | Vector3 direction = toPos - fromPos; |
102 | float len = Vector3.Distance(fromPos, toPos); | 104 | float len = Vector3.Distance(fromPos, toPos); |
103 | 105 | ||
104 | List<ContactResult> results = PhysicsScene.RaycastWorld(fromPos, direction, len, 1); | 106 | List<ContactResult> results = _physicsScene.RaycastWorld(fromPos, direction, len, 1); |
105 | 107 | ||
106 | if (expected) { | 108 | if (expected) { |
107 | Assert.True(results.Count > 0); | 109 | // The test coordinates should generate a hit |
110 | Assert.True(results.Count != 0, msg + ": Did not return a hit but expected to."); | ||
111 | Assert.True(results.Count == 1, msg + ": Raycast returned not just one hit result."); | ||
112 | Assert.True(results[0].ConsumerID == _targetLocalID, msg + ": Raycast returned a collision object other than the target"); | ||
108 | } | 113 | } |
109 | else | 114 | else |
110 | { | 115 | { |
111 | Assert.False(results.Count > 0); | 116 | // The test coordinates should not generate a hit |
117 | if (results.Count > 0) | ||
118 | { | ||
119 | Assert.False(results.Count > 0, msg + ": Returned a hit at " + results[0].Pos.ToString()); | ||
120 | } | ||
112 | } | 121 | } |
113 | } | 122 | } |
114 | } | 123 | } |