aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs138
1 files changed, 122 insertions, 16 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 9e95ce5..cb52937 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -171,7 +171,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
171 } 171 }
172 } 172 }
173 private Object _taintLock = new Object(); // lock for using the next object 173 private Object _taintLock = new Object(); // lock for using the next object
174 private List<TaintCallbackEntry> _taintedObjects; 174 private List<TaintCallbackEntry> _taintOperations;
175 private Dictionary<string, TaintCallbackEntry> _postTaintOperations;
176 private List<TaintCallbackEntry> _postStepOperations;
175 177
176 // 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
177 // Used to pass basic configuration values to the unmanaged code. 179 // Used to pass basic configuration values to the unmanaged code.
@@ -203,7 +205,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
203 public override void Initialise(IMesher meshmerizer, IConfigSource config) 205 public override void Initialise(IMesher meshmerizer, IConfigSource config)
204 { 206 {
205 mesher = meshmerizer; 207 mesher = meshmerizer;
206 _taintedObjects = new List<TaintCallbackEntry>(); 208 _taintOperations = new List<TaintCallbackEntry>();
209 _postTaintOperations = new Dictionary<string, TaintCallbackEntry>();
210 _postStepOperations = new List<TaintCallbackEntry>();
207 PhysObjects = new Dictionary<uint, BSPhysObject>(); 211 PhysObjects = new Dictionary<uint, BSPhysObject>();
208 Shapes = new BSShapeCollection(this); 212 Shapes = new BSShapeCollection(this);
209 213
@@ -475,23 +479,21 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
475 if (!m_initialized) return 5.0f; 479 if (!m_initialized) return 5.0f;
476 480
477 // update the prim states while we know the physics engine is not busy 481 // update the prim states while we know the physics engine is not busy
478 int numTaints = _taintedObjects.Count; 482 int numTaints = _taintOperations.Count;
479 ProcessTaints(); 483 ProcessTaints();
480 484
481 // Some of the prims operate with special vehicle properties 485 // Some of the prims operate with special vehicle properties
482 ProcessVehicles(timeStep); 486 ProcessVehicles(timeStep);
483 numTaints += _taintedObjects.Count; 487 numTaints += _taintOperations.Count;
484 ProcessTaints(); // the vehicles might have added taints 488 ProcessTaints(); // the vehicles might have added taints
485 489
486 // step the physical world one interval 490 // step the physical world one interval
487 m_simulationStep++; 491 m_simulationStep++;
488 int numSubSteps = 0; 492 int numSubSteps = 0;
489 493
490 // DEBUG
491 // DetailLog("{0},BSScene.Simulate,beforeStep,ntaimts={1},step={2}", DetailLogZero, numTaints, m_simulationStep);
492
493 try 494 try
494 { 495 {
496 // DumpVehicles(); // DEBUG
495 if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); 497 if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
496 498
497 numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, 499 numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
@@ -500,6 +502,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
500 if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); 502 if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
501 DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", 503 DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}",
502 DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); 504 DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
505 // DumpVehicles(); // DEBUG
503 } 506 }
504 catch (Exception e) 507 catch (Exception e)
505 { 508 {
@@ -579,6 +582,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
579 // Only enable this in a limited test world with few objects. 582 // Only enable this in a limited test world with few objects.
580 // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG 583 // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG
581 584
585 ProcessPostStepTaints();
586
582 // The physics engine returns the number of milliseconds it simulated this call. 587 // The physics engine returns the number of milliseconds it simulated this call.
583 // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. 588 // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
584 // We multiply by 55 to give a recognizable running rate (55 or less). 589 // We multiply by 55 to give a recognizable running rate (55 or less).
@@ -670,6 +675,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
670 675
671 public override bool IsThreaded { get { return false; } } 676 public override bool IsThreaded { get { return false; } }
672 677
678 #region Taints
679
673 // Calls to the PhysicsActors can't directly call into the physics engine 680 // Calls to the PhysicsActors can't directly call into the physics engine
674 // because it might be busy. We delay changes to a known time. 681 // because it might be busy. We delay changes to a known time.
675 // We rely on C#'s closure to save and restore the context for the delegate. 682 // We rely on C#'s closure to save and restore the context for the delegate.
@@ -679,7 +686,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
679 686
680 lock (_taintLock) 687 lock (_taintLock)
681 { 688 {
682 _taintedObjects.Add(new TaintCallbackEntry(ident, callback)); 689 _taintOperations.Add(new TaintCallbackEntry(ident, callback));
683 } 690 }
684 691
685 return; 692 return;
@@ -690,19 +697,25 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
690 // here just before the physics engine is called to step the simulation. 697 // here just before the physics engine is called to step the simulation.
691 public void ProcessTaints() 698 public void ProcessTaints()
692 { 699 {
693 if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process 700 ProcessRegularTaints();
701 ProcessPostTaintTaints();
702 }
703
704 private void ProcessRegularTaints()
705 {
706 if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process
694 { 707 {
695 int taintCount = m_taintsToProcessPerStep; 708 int taintCount = m_taintsToProcessPerStep;
696 TaintCallbackEntry oneCallback = new TaintCallbackEntry(); 709 TaintCallbackEntry oneCallback = new TaintCallbackEntry();
697 while (_taintedObjects.Count > 0 && taintCount-- > 0) 710 while (_taintOperations.Count > 0 && taintCount-- > 0)
698 { 711 {
699 bool gotOne = false; 712 bool gotOne = false;
700 lock (_taintLock) 713 lock (_taintLock)
701 { 714 {
702 if (_taintedObjects.Count > 0) 715 if (_taintOperations.Count > 0)
703 { 716 {
704 oneCallback = _taintedObjects[0]; 717 oneCallback = _taintOperations[0];
705 _taintedObjects.RemoveAt(0); 718 _taintOperations.RemoveAt(0);
706 gotOne = true; 719 gotOne = true;
707 } 720 }
708 } 721 }
@@ -746,6 +759,89 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
746 } 759 }
747 } 760 }
748 761
762 // Schedule an update to happen after all the regular taints are processed.
763 // Note that new requests for the same operation ("ident") for the same object ("ID")
764 // will replace any previous operation by the same object.
765 public void PostTaintObject(String ident, uint ID, TaintCallback callback)
766 {
767 if (!m_initialized) return;
768
769 lock (_taintLock)
770 {
771 _postTaintOperations[ident] = new TaintCallbackEntry(ident + "-" + ID.ToString(), callback);
772 }
773
774 return;
775 }
776
777 private void ProcessPostTaintTaints()
778 {
779 if (_postTaintOperations.Count > 0)
780 {
781 Dictionary<string, TaintCallbackEntry> oldList;
782 lock (_taintLock)
783 {
784 oldList = _postTaintOperations;
785 _postTaintOperations = new Dictionary<string, TaintCallbackEntry>();
786 }
787
788 foreach (KeyValuePair<string,TaintCallbackEntry> kvp in oldList)
789 {
790 try
791 {
792 DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG
793 kvp.Value.callback();
794 }
795 catch (Exception e)
796 {
797 m_log.ErrorFormat("{0}: ProcessPostTaintTaints: {1}: Exception: {2}", LogHeader, kvp.Key, e);
798 }
799 }
800 oldList.Clear();
801 }
802 }
803
804 public void PostStepTaintObject(String ident, TaintCallback callback)
805 {
806 if (!m_initialized) return;
807
808 lock (_taintLock)
809 {
810 _postStepOperations.Add(new TaintCallbackEntry(ident, callback));
811 }
812
813 return;
814 }
815
816 private void ProcessPostStepTaints()
817 {
818 if (_postStepOperations.Count > 0)
819 {
820 List<TaintCallbackEntry> oldList;
821 lock (_taintLock)
822 {
823 oldList = _postStepOperations;
824 _postStepOperations = new List<TaintCallbackEntry>();
825 }
826
827 foreach (TaintCallbackEntry tcbe in oldList)
828 {
829 try
830 {
831 DetailLog("{0},BSScene.ProcessPostStepTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG
832 tcbe.callback();
833 }
834 catch (Exception e)
835 {
836 m_log.ErrorFormat("{0}: ProcessPostStepTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e);
837 }
838 }
839 oldList.Clear();
840 }
841 }
842
843 #endregion // Taints
844
749 #region Vehicles 845 #region Vehicles
750 846
751 public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType) 847 public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType)
@@ -1006,7 +1102,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1006 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, 1102 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
1007 (s) => { return s.m_params[0].ccdSweptSphereRadius; }, 1103 (s) => { return s.m_params[0].ccdSweptSphereRadius; },
1008 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); }, 1104 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); },
1009 (s,o,v) => { BulletSimAPI.SetCcdSweepSphereRadius2(o.BSBody.ptr, v); } ), 1105 (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.BSBody.ptr, v); } ),
1010 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 1106 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
1011 0.1f, 1107 0.1f,
1012 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, 1108 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
@@ -1128,12 +1224,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1128 (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; }, 1224 (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; },
1129 (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ), 1225 (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ),
1130 new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", 1226 new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
1131 0.001f, 1227 0.1f,
1132 (s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); }, 1228 (s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); },
1133 (s) => { return s.m_params[0].linkConstraintCFM; }, 1229 (s) => { return s.m_params[0].linkConstraintCFM; },
1134 (s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ), 1230 (s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ),
1135 new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", 1231 new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
1136 0.8f, 1232 0.1f,
1137 (s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); }, 1233 (s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); },
1138 (s) => { return s.m_params[0].linkConstraintERP; }, 1234 (s) => { return s.m_params[0].linkConstraintERP; },
1139 (s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ), 1235 (s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ),
@@ -1326,6 +1422,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1326 1422
1327 #endregion Runtime settable parameters 1423 #endregion Runtime settable parameters
1328 1424
1425 // Debugging routine for dumping detailed physical information for vehicle prims
1426 private void DumpVehicles()
1427 {
1428 foreach (BSPrim prim in m_vehicles)
1429 {
1430 BulletSimAPI.DumpRigidBody2(World.ptr, prim.BSBody.ptr);
1431 BulletSimAPI.DumpCollisionShape2(World.ptr, prim.BSShape.ptr);
1432 }
1433 }
1434
1329 // Invoke the detailed logger and output something if it's enabled. 1435 // Invoke the detailed logger and output something if it's enabled.
1330 public void DetailLog(string msg, params Object[] args) 1436 public void DetailLog(string msg, params Object[] args)
1331 { 1437 {