PageRenderTime 194ms CodeModel.GetById 169ms app.highlight 11ms RepoModel.GetById 11ms app.codeStats 0ms

/Aurora/Modules/World/PhysicsState/PhysicsStateModule.cs

https://bitbucket.org/VirtualReality/software-testing
C# | 235 lines | 203 code | 31 blank | 1 comment | 14 complexity | e7c8efcad713dd99b282c122fe792d50 MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Timers;
  5using Aurora.Framework.Modules;
  6using Aurora.Framework.Physics;
  7using Aurora.Framework.PresenceInfo;
  8using Aurora.Framework.SceneInfo;
  9using Nini.Config;
 10using OpenMetaverse;
 11using Aurora.Framework;
 12
 13namespace Aurora.Modules.PhysicsState
 14{
 15    public class PhysicsStateModule : INonSharedRegionModule, IPhysicsStateModule
 16    {
 17        private readonly List<WorldPhysicsState> m_timeReversal = new List<WorldPhysicsState>();
 18        private bool m_isReversing;
 19        private bool m_isSavingRevertStates;
 20        private int m_lastRevertedTo = -100;
 21        private WorldPhysicsState m_lastWorldPhysicsState;
 22        private IScene m_scene;
 23
 24        #region INonSharedRegionModule Members
 25
 26        public void Initialise(IConfigSource source)
 27        {
 28        }
 29
 30        public void AddRegion(IScene scene)
 31        {
 32            scene.RegisterModuleInterface<IPhysicsStateModule>(this);
 33            m_scene = scene;
 34            Timer timeReversal = new Timer(250);
 35            timeReversal.Elapsed += timeReversal_Elapsed;
 36            timeReversal.Start();
 37        }
 38
 39        public void RegionLoaded(IScene scene)
 40        {
 41        }
 42
 43        public void RemoveRegion(IScene scene)
 44        {
 45        }
 46
 47        public void Close()
 48        {
 49        }
 50
 51        public string Name
 52        {
 53            get { return "PhysicsState"; }
 54        }
 55
 56        public Type ReplaceableInterface
 57        {
 58            get { return null; }
 59        }
 60
 61        #endregion
 62
 63        #region IPhysicsStateModule Members
 64
 65        public void SavePhysicsState()
 66        {
 67            m_lastWorldPhysicsState = m_isReversing ? null : MakePhysicsState();
 68        }
 69
 70        public void ResetToLastSavedState()
 71        {
 72            if (m_lastWorldPhysicsState != null)
 73                m_lastWorldPhysicsState.Reload(m_scene, 1);
 74            m_lastWorldPhysicsState = null;
 75        }
 76
 77        public void StartSavingPhysicsTimeReversalStates()
 78        {
 79            m_isSavingRevertStates = true;
 80        }
 81
 82        public void StopSavingPhysicsTimeReversalStates()
 83        {
 84            m_isSavingRevertStates = false;
 85            m_timeReversal.Clear();
 86        }
 87
 88        public void StartPhysicsTimeReversal()
 89        {
 90            m_lastRevertedTo = -100;
 91            m_isReversing = true;
 92            m_scene.RegionInfo.RegionSettings.DisablePhysics = true;
 93        }
 94
 95        public void StopPhysicsTimeReversal()
 96        {
 97            m_lastRevertedTo = -100;
 98            m_scene.RegionInfo.RegionSettings.DisablePhysics = false;
 99            m_isReversing = false;
100        }
101
102        #endregion
103
104        private WorldPhysicsState MakePhysicsState()
105        {
106            WorldPhysicsState state = new WorldPhysicsState();
107            //Add all active objects in the scene
108            foreach (PhysicsObject prm in m_scene.PhysicsScene.ActiveObjects)
109            {
110                state.AddPrim(prm);
111            }
112#if (!ISWIN)
113            foreach (IScenePresence sp in m_scene.GetScenePresences())
114            {
115                if (!sp.IsChildAgent)
116                {
117                    state.AddAvatar(sp.PhysicsActor);
118                }
119            }
120#else
121            foreach (IScenePresence sp in m_scene.GetScenePresences().Where(sp => !sp.IsChildAgent))
122            {
123                state.AddAvatar(sp.PhysicsActor);
124            }
125#endif
126            return state;
127        }
128
129        private void timeReversal_Elapsed(object sender, ElapsedEventArgs e)
130        {
131            if (!m_isSavingRevertStates)
132                return; //Only save if we are running this
133            if (!m_isReversing) //Only save new states if we are going forward
134                m_timeReversal.Add(MakePhysicsState());
135            else
136            {
137                if (m_lastRevertedTo == -100)
138                    m_lastRevertedTo = m_timeReversal.Count - 1;
139                m_timeReversal[m_lastRevertedTo].Reload(m_scene, -1f); //Do the velocity in reverse with -1
140                m_lastRevertedTo--;
141                if (m_lastRevertedTo < 0)
142                {
143                    m_isSavingRevertStates = false;
144                    m_lastRevertedTo = -100;
145                    m_isReversing = false;
146                    m_scene.StopPhysicsScene(); //Stop physics from moving too
147                    m_scene.RegionInfo.RegionSettings.DisablePhysics = true; //Freeze the scene
148                    m_timeReversal.Clear(); //Remove the states we have as well, we've played them
149                }
150            }
151        }
152
153        #region Nested type: WorldPhysicsState
154
155        public class WorldPhysicsState
156        {
157            private readonly Dictionary<UUID, PhysicsState> m_activePrims = new Dictionary<UUID, PhysicsState>();
158
159            public void AddPrim(PhysicsObject prm)
160            {
161                PhysicsState state = new PhysicsState
162                                         {
163                                             Position = prm.Position,
164                                             AngularVelocity = prm.RotationalVelocity,
165                                             LinearVelocity = prm.Velocity,
166                                             Rotation = prm.Orientation
167                                         };
168                m_activePrims[prm.UUID] = state;
169            }
170
171            public void AddAvatar(PhysicsCharacter prm)
172            {
173                PhysicsState state = new PhysicsState
174                                         {
175                                             Position = prm.Position,
176                                             AngularVelocity = prm.RotationalVelocity,
177                                             LinearVelocity = prm.Velocity,
178                                             Rotation = prm.Orientation
179                                         };
180                m_activePrims[prm.UUID] = state;
181            }
182
183            public void Reload(IScene scene, float direction)
184            {
185                foreach (KeyValuePair<UUID, PhysicsState> kvp in m_activePrims)
186                {
187                    ISceneChildEntity childPrim = scene.GetSceneObjectPart(kvp.Key);
188                    if (childPrim != null && childPrim.PhysActor != null)
189                        ResetPrim(childPrim.PhysActor, kvp.Value, direction);
190                    else
191                    {
192                        IScenePresence sp = scene.GetScenePresence(kvp.Key);
193                        if (sp != null)
194                            ResetAvatar(sp.PhysicsActor, kvp.Value, direction);
195                    }
196                }
197            }
198
199            private void ResetPrim(PhysicsObject physicsObject, PhysicsState physicsState, float direction)
200            {
201                physicsObject.Position = physicsState.Position;
202                physicsObject.Orientation = physicsState.Rotation;
203                physicsObject.RotationalVelocity = physicsState.AngularVelocity*direction;
204                physicsObject.Velocity = physicsState.LinearVelocity*direction;
205                physicsObject.ForceSetVelocity(physicsState.LinearVelocity*direction);
206                physicsObject.RequestPhysicsterseUpdate();
207            }
208
209            private void ResetAvatar(PhysicsCharacter physicsObject, PhysicsState physicsState, float direction)
210            {
211                physicsObject.Position = physicsState.Position;
212                physicsObject.ForceSetPosition(physicsState.Position);
213                physicsObject.Orientation = physicsState.Rotation;
214                physicsObject.RotationalVelocity = physicsState.AngularVelocity*direction;
215                physicsObject.Velocity = physicsState.LinearVelocity*direction;
216                physicsObject.ForceSetVelocity(physicsState.LinearVelocity*direction);
217                physicsObject.RequestPhysicsterseUpdate();
218            }
219
220            #region Nested type: PhysicsState
221
222            public class PhysicsState
223            {
224                public Vector3 AngularVelocity;
225                public Vector3 LinearVelocity;
226                public Vector3 Position;
227                public Quaternion Rotation;
228            }
229
230            #endregion
231        }
232
233        #endregion
234    }
235}