diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 112 |
1 files changed, 30 insertions, 82 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 3a129a4..e8e0d50 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -85,9 +85,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
85 | internal long m_simulationStep = 0; | 85 | internal long m_simulationStep = 0; |
86 | public long SimulationStep { get { return m_simulationStep; } } | 86 | public long SimulationStep { get { return m_simulationStep; } } |
87 | internal int m_taintsToProcessPerStep; | 87 | internal int m_taintsToProcessPerStep; |
88 | internal float LastTimeStep { get; private set; } | ||
88 | 89 | ||
90 | // Physical objects can register for prestep or poststep events | ||
89 | public delegate void PreStepAction(float timeStep); | 91 | public delegate void PreStepAction(float timeStep); |
92 | public delegate void PostStepAction(float timeStep); | ||
90 | public event PreStepAction BeforeStep; | 93 | public event PreStepAction BeforeStep; |
94 | public event PreStepAction AfterStep; | ||
91 | 95 | ||
92 | // A value of the time now so all the collision and update routines do not have to get their own | 96 | // A value of the time now so all the collision and update routines do not have to get their own |
93 | // Set to 'now' just before all the prims and actors are called for collisions and updates | 97 | // Set to 'now' just before all the prims and actors are called for collisions and updates |
@@ -463,6 +467,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
463 | // Simulate one timestep | 467 | // Simulate one timestep |
464 | public override float Simulate(float timeStep) | 468 | public override float Simulate(float timeStep) |
465 | { | 469 | { |
470 | // prevent simulation until we've been initialized | ||
471 | if (!m_initialized) return 5.0f; | ||
472 | |||
473 | LastTimeStep = timeStep; | ||
474 | |||
466 | int updatedEntityCount = 0; | 475 | int updatedEntityCount = 0; |
467 | IntPtr updatedEntitiesPtr; | 476 | IntPtr updatedEntitiesPtr; |
468 | int collidersCount = 0; | 477 | int collidersCount = 0; |
@@ -471,9 +480,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
471 | int beforeTime = 0; | 480 | int beforeTime = 0; |
472 | int simTime = 0; | 481 | int simTime = 0; |
473 | 482 | ||
474 | // prevent simulation until we've been initialized | ||
475 | if (!m_initialized) return 5.0f; | ||
476 | |||
477 | // update the prim states while we know the physics engine is not busy | 483 | // update the prim states while we know the physics engine is not busy |
478 | int numTaints = _taintOperations.Count; | 484 | int numTaints = _taintOperations.Count; |
479 | 485 | ||
@@ -482,7 +488,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
482 | ProcessTaints(); | 488 | ProcessTaints(); |
483 | 489 | ||
484 | // Some of the physical objects requre individual, pre-step calls | 490 | // Some of the physical objects requre individual, pre-step calls |
485 | DoPreStepActions(timeStep); | 491 | TriggerPreStepEvent(timeStep); |
486 | 492 | ||
487 | // the prestep actions might have added taints | 493 | // the prestep actions might have added taints |
488 | ProcessTaints(); | 494 | ProcessTaints(); |
@@ -582,7 +588,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
582 | } | 588 | } |
583 | } | 589 | } |
584 | 590 | ||
585 | ProcessPostStepTaints(); | 591 | TriggerPostStepEvent(timeStep); |
586 | 592 | ||
587 | // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. | 593 | // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. |
588 | // Only enable this in a limited test world with few objects. | 594 | // Only enable this in a limited test world with few objects. |
@@ -674,6 +680,15 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
674 | public override bool IsThreaded { get { return false; } } | 680 | public override bool IsThreaded { get { return false; } } |
675 | 681 | ||
676 | #region Taints | 682 | #region Taints |
683 | // The simulation execution order is: | ||
684 | // Simulate() | ||
685 | // DoOneTimeTaints | ||
686 | // TriggerPreStepEvent | ||
687 | // DoOneTimeTaints | ||
688 | // Step() | ||
689 | // ProcessAndForwardCollisions | ||
690 | // ProcessAndForwardPropertyUpdates | ||
691 | // TriggerPostStepEvent | ||
677 | 692 | ||
678 | // Calls to the PhysicsActors can't directly call into the physics engine | 693 | // Calls to the PhysicsActors can't directly call into the physics engine |
679 | // because it might be busy. We delay changes to a known time. | 694 | // because it might be busy. We delay changes to a known time. |
@@ -700,7 +715,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
700 | TaintedObject(ident, callback); | 715 | TaintedObject(ident, callback); |
701 | } | 716 | } |
702 | 717 | ||
703 | private void DoPreStepActions(float timeStep) | 718 | private void TriggerPreStepEvent(float timeStep) |
704 | { | 719 | { |
705 | PreStepAction actions = BeforeStep; | 720 | PreStepAction actions = BeforeStep; |
706 | if (actions != null) | 721 | if (actions != null) |
@@ -708,6 +723,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
708 | 723 | ||
709 | } | 724 | } |
710 | 725 | ||
726 | private void TriggerPostStepEvent(float timeStep) | ||
727 | { | ||
728 | PreStepAction actions = AfterStep; | ||
729 | if (actions != null) | ||
730 | actions(timeStep); | ||
731 | |||
732 | } | ||
733 | |||
711 | // When someone tries to change a property on a BSPrim or BSCharacter, the object queues | 734 | // When someone tries to change a property on a BSPrim or BSCharacter, the object queues |
712 | // a callback into itself to do the actual property change. That callback is called | 735 | // a callback into itself to do the actual property change. That callback is called |
713 | // here just before the physics engine is called to step the simulation. | 736 | // here just before the physics engine is called to step the simulation. |
@@ -721,43 +744,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
721 | { | 744 | { |
722 | if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process | 745 | if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process |
723 | { | 746 | { |
724 | /* | ||
725 | // Code to limit the number of taints processed per step. Meant to limit step time. | ||
726 | // Unsure if a good idea as code assumes that taints are done before the step. | ||
727 | int taintCount = m_taintsToProcessPerStep; | ||
728 | TaintCallbackEntry oneCallback = new TaintCallbackEntry(); | ||
729 | while (_taintOperations.Count > 0 && taintCount-- > 0) | ||
730 | { | ||
731 | bool gotOne = false; | ||
732 | lock (_taintLock) | ||
733 | { | ||
734 | if (_taintOperations.Count > 0) | ||
735 | { | ||
736 | oneCallback = _taintOperations[0]; | ||
737 | _taintOperations.RemoveAt(0); | ||
738 | gotOne = true; | ||
739 | } | ||
740 | } | ||
741 | if (gotOne) | ||
742 | { | ||
743 | try | ||
744 | { | ||
745 | DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, oneCallback.ident); | ||
746 | oneCallback.callback(); | ||
747 | } | ||
748 | catch (Exception e) | ||
749 | { | ||
750 | DetailLog("{0},BSScene.ProcessTaints,doTaintException,id={1}", DetailLogZero, oneCallback.ident); // DEBUG DEBUG DEBUG | ||
751 | m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, oneCallback.ident, e); | ||
752 | } | ||
753 | } | ||
754 | } | ||
755 | if (_taintOperations.Count > 0) | ||
756 | { | ||
757 | DetailLog("{0},BSScene.ProcessTaints,leftTaintsOnList,numNotProcessed={1}", DetailLogZero, _taintOperations.Count); | ||
758 | } | ||
759 | */ | ||
760 | |||
761 | // swizzle a new list into the list location so we can process what's there | 747 | // swizzle a new list into the list location so we can process what's there |
762 | List<TaintCallbackEntry> oldList; | 748 | List<TaintCallbackEntry> oldList; |
763 | lock (_taintLock) | 749 | lock (_taintLock) |
@@ -796,6 +782,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
796 | return; | 782 | return; |
797 | } | 783 | } |
798 | 784 | ||
785 | // Taints that happen after the normal taint processing but before the simulation step. | ||
799 | private void ProcessPostTaintTaints() | 786 | private void ProcessPostTaintTaints() |
800 | { | 787 | { |
801 | if (_postTaintOperations.Count > 0) | 788 | if (_postTaintOperations.Count > 0) |
@@ -823,45 +810,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
823 | } | 810 | } |
824 | } | 811 | } |
825 | 812 | ||
826 | public void PostStepTaintObject(String ident, TaintCallback callback) | ||
827 | { | ||
828 | if (!m_initialized) return; | ||
829 | |||
830 | lock (_taintLock) | ||
831 | { | ||
832 | _postStepOperations.Add(new TaintCallbackEntry(ident, callback)); | ||
833 | } | ||
834 | |||
835 | return; | ||
836 | } | ||
837 | |||
838 | private void ProcessPostStepTaints() | ||
839 | { | ||
840 | if (_postStepOperations.Count > 0) | ||
841 | { | ||
842 | List<TaintCallbackEntry> oldList; | ||
843 | lock (_taintLock) | ||
844 | { | ||
845 | oldList = _postStepOperations; | ||
846 | _postStepOperations = new List<TaintCallbackEntry>(); | ||
847 | } | ||
848 | |||
849 | foreach (TaintCallbackEntry tcbe in oldList) | ||
850 | { | ||
851 | try | ||
852 | { | ||
853 | DetailLog("{0},BSScene.ProcessPostStepTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG | ||
854 | tcbe.callback(); | ||
855 | } | ||
856 | catch (Exception e) | ||
857 | { | ||
858 | m_log.ErrorFormat("{0}: ProcessPostStepTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e); | ||
859 | } | ||
860 | } | ||
861 | oldList.Clear(); | ||
862 | } | ||
863 | } | ||
864 | |||
865 | // Only used for debugging. Does not change state of anything so locking is not necessary. | 813 | // Only used for debugging. Does not change state of anything so locking is not necessary. |
866 | public bool AssertInTaintTime(string whereFrom) | 814 | public bool AssertInTaintTime(string whereFrom) |
867 | { | 815 | { |