30 using System.Collections;
31 using System.Collections.Generic;
33 using System.Diagnostics;
34 using System.Reflection;
35 using System.Threading;
37 using OpenSim.Framework;
38 using OpenSim.Region.Framework.Interfaces;
39 using OpenSim.Region.PhysicsModules.SharedBase;
40 using OpenSim.Region.Framework.Scenes.Serialization;
41 using System.Runtime.Serialization.Formatters.Binary;
42 using System.Runtime.Serialization;
46 namespace OpenSim.
Region.Framework.Scenes
50 private static Dictionary<Scene, KeyframeTimer> m_timers =
51 new Dictionary<Scene, KeyframeTimer>();
53 private Timer m_timer;
54 private Dictionary<KeyframeMotion, object> m_motions =
new Dictionary<KeyframeMotion, object>();
55 private object m_lockObject =
new object();
56 private object m_timerLock =
new object();
57 private const double m_tickDuration = 50.0;
59 public double TickDuration
61 get {
return m_tickDuration; }
66 m_timer =
new Timer();
67 m_timer.Interval = TickDuration;
68 m_timer.AutoReset =
true;
69 m_timer.Elapsed += OnTimer;
81 private void OnTimer(
object sender, ElapsedEventArgs ea)
83 if (!Monitor.TryEnter(m_timerLock))
88 List<KeyframeMotion> motions;
92 motions =
new List<KeyframeMotion>(m_motions.Keys);
95 foreach (KeyframeMotion m
in motions)
99 m.OnTimer(TickDuration);
113 Monitor.Exit(m_timerLock);
121 if (motion.
Scene == null)
126 if (!m_timers.TryGetValue(motion.
Scene, out timer))
129 m_timers[motion.Scene] = timer;
137 SceneManager.Instance.OnRegionsReadyStatusChange += delegate(
SceneManager sm)
152 lock (timer.m_lockObject)
154 timer.m_motions[motion] = null;
162 if (motion.
Scene == null)
167 if (!m_timers.TryGetValue(motion.
Scene, out timer))
173 lock (timer.m_lockObject)
175 timer.m_motions.Remove(motion);
212 private Vector3 m_serializedPosition;
213 private Vector3 m_basePosition;
214 private Quaternion m_baseRotation;
218 private List<Keyframe> m_frames =
new List<Keyframe>();
225 private bool m_timerStopped;
228 private bool m_isCrossing;
231 private bool m_waitingCrossing;
235 private Vector3 m_nextPosition;
240 private PlayMode m_mode = PlayMode.Forward;
241 private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation;
243 private bool m_running =
false;
246 private bool m_selected =
false;
248 private int m_iterations = 0;
250 private int m_skipLoops = 0;
253 private Scene m_scene;
257 get {
return m_scene; }
260 public DataFormat Data
262 get {
return m_data; }
275 UpdateSceneObject(m_group);
283 m_serializedPosition = m_group.AbsolutePosition;
287 m_isCrossing =
false;
288 m_waitingCrossing =
false;
293 private void StartTimer()
297 KeyframeTimer.Add(
this);
298 m_timerStopped =
false;
302 private void StopTimer()
305 m_timerStopped = true;
314 using (MemoryStream ms =
new MemoryStream(data))
316 BinaryFormatter fmt =
new BinaryFormatter();
320 newMotion.m_group = grp;
324 newMotion.m_scene = grp.Scene;
326 newMotion.m_selected =
true;
329 newMotion.m_timerStopped =
false;
330 newMotion.m_running =
true;
331 newMotion.m_isCrossing =
false;
332 newMotion.m_waitingCrossing =
false;
344 m_isCrossing =
false;
345 m_waitingCrossing =
false;
357 Vector3 grppos = grp.AbsolutePosition;
358 Vector3 offset = grppos - m_serializedPosition;
361 m_serializedPosition = grppos;
363 m_basePosition += offset;
364 m_currentFrame.Position += offset;
366 m_nextPosition += offset;
368 for (
int i = 0; i < m_frames.Count; i++)
371 k.Position += offset;
388 m_basePosition = grp.AbsolutePosition;
389 m_baseRotation = grp.GroupRotation;
393 m_timerStopped =
true;
394 m_isCrossing =
false;
395 m_waitingCrossing =
false;
400 m_keyframes = frames;
409 newmotion.m_group = newgrp;
410 newmotion.m_scene = newgrp.Scene;
412 if (m_keyframes != null)
414 newmotion.m_keyframes =
new Keyframe[m_keyframes.Length];
415 m_keyframes.CopyTo(newmotion.m_keyframes, 0);
420 newmotion.m_frames =
new List<Keyframe>(m_frames);
422 newmotion.m_basePosition = m_basePosition;
423 newmotion.m_baseRotation = m_baseRotation;
426 newmotion.m_serializedPosition = m_serializedPosition;
430 newmotion.m_serializedPosition = m_group.AbsolutePosition;
432 newmotion.m_serializedPosition = m_serializedPosition;
435 newmotion.m_currentFrame = m_currentFrame;
437 newmotion.m_iterations = m_iterations;
438 newmotion.m_running = m_running;
441 if (m_running && !m_waitingCrossing)
451 m_isCrossing =
false;
452 m_waitingCrossing =
false;
459 m_isCrossing =
false;
460 m_waitingCrossing =
false;
461 if (m_keyframes != null && m_group != null && m_keyframes.Length > 0)
465 m_group.Scene.EventManager.TriggerMovingStartEvent(m_group.RootPart.LocalId);
478 m_isCrossing =
false;
479 m_waitingCrossing =
false;
481 m_basePosition = m_group.AbsolutePosition;
482 m_baseRotation = m_group.GroupRotation;
484 m_group.RootPart.Velocity = Vector3.Zero;
485 m_group.RootPart.AngularVelocity = Vector3.Zero;
486 m_group.SendGroupRootTerseUpdate();
496 m_group.RootPart.Velocity = Vector3.Zero;
497 m_group.RootPart.AngularVelocity = Vector3.Zero;
498 m_group.SendGroupRootTerseUpdate();
508 m_timerStopped =
true;
518 if (m_running && !m_waitingCrossing)
523 private void GetNextList()
526 Vector3 pos = m_basePosition;
527 Quaternion rot = m_baseRotation;
529 if (m_mode == PlayMode.Loop || m_mode == PlayMode.PingPong || m_iterations == 0)
532 if (m_mode == PlayMode.Reverse || ((m_mode == PlayMode.PingPong) && ((m_iterations & 1) != 0)))
536 int end = m_keyframes.Length;
540 start = m_keyframes.Length - 1;
544 for (
int i = start; i != end ; i += direction)
546 Keyframe k = m_keyframes[i];
548 k.StartPosition = pos;
549 if (k.Position.HasValue)
551 k.Position = (k.Position * direction);
561 k.StartRotation = rot;
562 if (k.Rotation.HasValue)
565 k.Rotation = Quaternion.Conjugate((Quaternion)k.Rotation);
566 k.Rotation = rot * k.Rotation;
605 k.TimeTotal = k.TimeMS;
609 pos = (Vector3)k.Position;
610 rot = (Quaternion)k.Rotation;
614 m_basePosition = pos;
615 m_baseRotation = rot;
623 if (!Monitor.TryEnter(m_frames))
626 KeyframeTimer.Remove(
this);
628 DoOnTimer(tickDuration);
629 Monitor.Exit(m_frames);
634 KeyframeTimer.Remove(
this);
635 m_timerStopped =
true;
637 m_isCrossing =
false;
638 m_waitingCrossing =
false;
640 m_basePosition = m_group.AbsolutePosition;
641 m_baseRotation = m_group.GroupRotation;
643 m_group.RootPart.Velocity = Vector3.Zero;
644 m_group.RootPart.AngularVelocity = Vector3.Zero;
645 m_group.SendGroupRootTerseUpdate();
650 private void DoOnTimer(
double tickDuration)
665 if (m_group.RootPart.Velocity != Vector3.Zero)
667 m_group.RootPart.Velocity = Vector3.Zero;
668 m_group.SendGroupRootTerseUpdate();
679 m_isCrossing =
false;
680 m_group.AbsolutePosition = m_nextPosition;
689 if (m_frames.Count == 0)
695 if (m_frames.Count == 0)
698 m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId);
702 m_currentFrame = m_frames[0];
703 m_currentFrame.TimeMS += (int)tickDuration;
706 m_nextPosition = m_group.AbsolutePosition;
710 m_currentFrame.TimeMS -= (int)tickDuration;
713 double remainingSteps = (double)m_currentFrame.TimeMS / tickDuration;
715 if (remainingSteps <= 0.0)
717 m_group.RootPart.Velocity = Vector3.Zero;
718 m_group.RootPart.AngularVelocity = Vector3.Zero;
720 m_nextPosition = (Vector3)m_currentFrame.Position;
721 m_group.AbsolutePosition = m_nextPosition;
726 m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation;
730 m_frames.RemoveAt(0);
731 if (m_frames.Count > 0)
732 m_currentFrame = m_frames[0];
739 float completed = ((float)m_currentFrame.TimeTotal - (
float)m_currentFrame.TimeMS) / (
float)m_currentFrame.TimeTotal;
740 bool lastStep = m_currentFrame.TimeMS <= tickDuration;
742 Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition;
743 Vector3 motionThisFrame = v / (
float)remainingSteps;
744 v = v * 1000 / m_currentFrame.TimeMS;
746 m_nextPosition = m_group.AbsolutePosition + motionThisFrame;
748 if (Vector3.Mag(motionThisFrame) >= 0.05f)
755 if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation)
757 Quaternion current = m_group.GroupRotation;
759 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed);
792 if (Math.Abs(step.X - current.X) > 0.001f
793 || Math.Abs(step.Y - current.Y) > 0.001f
794 || Math.Abs(step.Z - current.Z) > 0.001f)
798 m_group.RootPart.RotationOffset = step;
808 m_group.AbsolutePosition = m_nextPosition;
809 m_group.SendGroupRootTerseUpdate();
815 bool timerWasStopped;
818 timerWasStopped = m_timerStopped;
825 using (MemoryStream ms =
new MemoryStream())
827 BinaryFormatter fmt =
new BinaryFormatter();
828 if (!m_selected && tmp != null)
829 m_serializedPosition = tmp.AbsolutePosition;
830 fmt.Serialize(ms,
this);
832 if (!timerWasStopped && m_running && !m_waitingCrossing)
847 m_waitingCrossing =
true;
850 if (m_group.RootPart.Velocity != Vector3.Zero)
852 m_group.RootPart.Velocity = Vector3.Zero;
853 m_group.SendGroupRootTerseUpdate();
860 m_waitingCrossing =
false;
864 m_group.RootPart.Velocity = Vector3.Zero;
865 m_group.SendGroupRootTerseUpdate();
void SetKeyframes(Keyframe[] frames)
static void Remove(KeyframeMotion motion)
bool AllRegionsReady
Are all regions ready for use?
System.Timers.Timer Timer
static SceneManager Instance
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
System.Timers.Timer Timer
void UpdateSceneObject(SceneObjectGroup grp)
Manager for adding, closing and restarting scenes.
static void Add(KeyframeMotion motion)
KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data)
KeyframeTimer(Scene scene)
KeyframeMotion Copy(SceneObjectGroup newgrp)
void OnTimer(double tickDuration)
void StartCrossingCheck()