/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

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