diff options
4 files changed, 96 insertions, 4 deletions
diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index 239f7ca..73db25b 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | using System; | 5 | using System; |
6 | using System.Timers; | 6 | using System.Timers; |
7 | using System.Collections; | ||
7 | using System.Collections.Generic; | 8 | using System.Collections.Generic; |
8 | using System.IO; | 9 | using System.IO; |
9 | using System.Diagnostics; | 10 | using System.Diagnostics; |
@@ -14,11 +15,14 @@ using OpenSim.Framework; | |||
14 | using OpenSim.Region.Framework.Interfaces; | 15 | using OpenSim.Region.Framework.Interfaces; |
15 | using OpenSim.Region.Physics.Manager; | 16 | using OpenSim.Region.Physics.Manager; |
16 | using OpenSim.Region.Framework.Scenes.Serialization; | 17 | using OpenSim.Region.Framework.Scenes.Serialization; |
18 | using System.Runtime.Serialization.Formatters.Binary; | ||
19 | using System.Runtime.Serialization; | ||
17 | using Timer = System.Timers.Timer; | 20 | using Timer = System.Timers.Timer; |
18 | using log4net; | 21 | using log4net; |
19 | 22 | ||
20 | namespace OpenSim.Region.Framework.Scenes | 23 | namespace OpenSim.Region.Framework.Scenes |
21 | { | 24 | { |
25 | [Serializable] | ||
22 | public class KeyframeMotion | 26 | public class KeyframeMotion |
23 | { | 27 | { |
24 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 28 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -38,6 +42,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
38 | Rotation = 2 | 42 | Rotation = 2 |
39 | } | 43 | } |
40 | 44 | ||
45 | [Serializable] | ||
41 | public struct Keyframe | 46 | public struct Keyframe |
42 | { | 47 | { |
43 | public Vector3? Position; | 48 | public Vector3? Position; |
@@ -50,19 +55,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
50 | 55 | ||
51 | private Vector3 m_basePosition; | 56 | private Vector3 m_basePosition; |
52 | private Quaternion m_baseRotation; | 57 | private Quaternion m_baseRotation; |
58 | private Vector3 m_serializedPosition; | ||
53 | 59 | ||
54 | private Keyframe m_currentFrame; | 60 | private Keyframe m_currentFrame; |
55 | private List<Keyframe> m_frames = new List<Keyframe>(); | 61 | private List<Keyframe> m_frames = new List<Keyframe>(); |
56 | 62 | ||
57 | private Keyframe[] m_keyframes; | 63 | private Keyframe[] m_keyframes; |
58 | 64 | ||
59 | private Timer m_timer = new Timer(); | 65 | [NonSerialized()] |
66 | protected Timer m_timer = new Timer(); | ||
60 | 67 | ||
61 | private readonly SceneObjectGroup m_group; | 68 | [NonSerialized()] |
69 | private SceneObjectGroup m_group; | ||
62 | 70 | ||
63 | private PlayMode m_mode = PlayMode.Forward; | 71 | private PlayMode m_mode = PlayMode.Forward; |
64 | private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation; | 72 | private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation; |
65 | 73 | ||
74 | private bool m_running = false; | ||
75 | |||
66 | private int m_iterations = 0; | 76 | private int m_iterations = 0; |
67 | 77 | ||
68 | private const double timerInterval = 50.0; | 78 | private const double timerInterval = 50.0; |
@@ -72,6 +82,41 @@ namespace OpenSim.Region.Framework.Scenes | |||
72 | get { return m_data; } | 82 | get { return m_data; } |
73 | } | 83 | } |
74 | 84 | ||
85 | public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) | ||
86 | { | ||
87 | MemoryStream ms = new MemoryStream(data); | ||
88 | |||
89 | BinaryFormatter fmt = new BinaryFormatter(); | ||
90 | |||
91 | KeyframeMotion newMotion = (KeyframeMotion)fmt.Deserialize(ms); | ||
92 | |||
93 | // This will be started when position is updated | ||
94 | newMotion.m_timer = new Timer(); | ||
95 | newMotion.m_timer.Interval = (int)timerInterval; | ||
96 | newMotion.m_timer.AutoReset = true; | ||
97 | newMotion.m_timer.Elapsed += newMotion.OnTimer; | ||
98 | |||
99 | return newMotion; | ||
100 | } | ||
101 | |||
102 | public void UpdateSceneObject(SceneObjectGroup grp) | ||
103 | { | ||
104 | m_group = grp; | ||
105 | Vector3 offset = grp.AbsolutePosition - m_serializedPosition; | ||
106 | |||
107 | m_basePosition += offset; | ||
108 | m_currentFrame.Position += offset; | ||
109 | for (int i = 0 ; i < m_frames.Count ; i++) | ||
110 | { | ||
111 | Keyframe k = m_frames[i]; | ||
112 | k.Position += offset; | ||
113 | m_frames[i] = k; | ||
114 | } | ||
115 | |||
116 | if (m_running) | ||
117 | Start(); | ||
118 | } | ||
119 | |||
75 | public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data) | 120 | public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data) |
76 | { | 121 | { |
77 | m_mode = mode; | 122 | m_mode = mode; |
@@ -95,10 +140,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
95 | { | 140 | { |
96 | if (m_keyframes.Length > 0) | 141 | if (m_keyframes.Length > 0) |
97 | m_timer.Start(); | 142 | m_timer.Start(); |
143 | m_running = true; | ||
98 | } | 144 | } |
99 | 145 | ||
100 | public void Stop() | 146 | public void Stop() |
101 | { | 147 | { |
148 | // Failed object creation | ||
149 | if (m_timer == null) | ||
150 | return; | ||
102 | m_timer.Stop(); | 151 | m_timer.Stop(); |
103 | 152 | ||
104 | m_basePosition = m_group.AbsolutePosition; | 153 | m_basePosition = m_group.AbsolutePosition; |
@@ -109,6 +158,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
109 | m_group.SendGroupRootTerseUpdate(); | 158 | m_group.SendGroupRootTerseUpdate(); |
110 | 159 | ||
111 | m_frames.Clear(); | 160 | m_frames.Clear(); |
161 | m_running = false; | ||
112 | } | 162 | } |
113 | 163 | ||
114 | public void Pause() | 164 | public void Pause() |
@@ -118,6 +168,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
118 | m_group.SendGroupRootTerseUpdate(); | 168 | m_group.SendGroupRootTerseUpdate(); |
119 | 169 | ||
120 | m_timer.Stop(); | 170 | m_timer.Stop(); |
171 | m_running = false; | ||
121 | } | 172 | } |
122 | 173 | ||
123 | private void GetNextList() | 174 | private void GetNextList() |
@@ -211,7 +262,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
211 | } | 262 | } |
212 | } | 263 | } |
213 | 264 | ||
214 | private void OnTimer(object sender, ElapsedEventArgs e) | 265 | protected void OnTimer(object sender, ElapsedEventArgs e) |
215 | { | 266 | { |
216 | if (m_frames.Count == 0) | 267 | if (m_frames.Count == 0) |
217 | { | 268 | { |
@@ -311,5 +362,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
311 | m_currentFrame = m_frames[0]; | 362 | m_currentFrame = m_frames[0]; |
312 | } | 363 | } |
313 | } | 364 | } |
365 | |||
366 | public Byte[] Serialize() | ||
367 | { | ||
368 | MemoryStream ms = new MemoryStream(); | ||
369 | m_timer.Stop(); | ||
370 | |||
371 | BinaryFormatter fmt = new BinaryFormatter(); | ||
372 | SceneObjectGroup tmp = m_group; | ||
373 | m_group = null; | ||
374 | m_serializedPosition = tmp.AbsolutePosition; | ||
375 | fmt.Serialize(ms, this); | ||
376 | m_group = tmp; | ||
377 | return ms.ToArray(); | ||
378 | } | ||
314 | } | 379 | } |
315 | } | 380 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index fcbed9f..c20da4b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2421,6 +2421,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2421 | 2421 | ||
2422 | if (newPosition != Vector3.Zero) | 2422 | if (newPosition != Vector3.Zero) |
2423 | newObject.RootPart.GroupPosition = newPosition; | 2423 | newObject.RootPart.GroupPosition = newPosition; |
2424 | if (newObject.KeyframeMotion != null) | ||
2425 | newObject.KeyframeMotion.UpdateSceneObject(newObject); | ||
2424 | 2426 | ||
2425 | if (!AddSceneObject(newObject)) | 2427 | if (!AddSceneObject(newObject)) |
2426 | { | 2428 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 9898681..d488189 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -1823,6 +1823,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1823 | // Name, UUID, m_scene.RegionInfo.RegionName); | 1823 | // Name, UUID, m_scene.RegionInfo.RegionName); |
1824 | 1824 | ||
1825 | SceneObjectGroup backup_group = Copy(false); | 1825 | SceneObjectGroup backup_group = Copy(false); |
1826 | if (KeyframeMotion != null) | ||
1827 | { | ||
1828 | backup_group.KeyframeMotion = KeyframeMotion.FromData(backup_group, KeyframeMotion.Serialize()); | ||
1829 | KeyframeMotion.UpdateSceneObject(this); | ||
1830 | } | ||
1826 | backup_group.RootPart.Velocity = RootPart.Velocity; | 1831 | backup_group.RootPart.Velocity = RootPart.Velocity; |
1827 | backup_group.RootPart.Acceleration = RootPart.Acceleration; | 1832 | backup_group.RootPart.Acceleration = RootPart.Acceleration; |
1828 | backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; | 1833 | backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; |
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index ed761da..a9f3e84 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | |||
@@ -244,6 +244,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
244 | sr.Close(); | 244 | sr.Close(); |
245 | } | 245 | } |
246 | 246 | ||
247 | XmlNodeList keymotion = doc.GetElementsByTagName("KeyframeMotion"); | ||
248 | if (keymotion.Count > 0) | ||
249 | { | ||
250 | m_log.DebugFormat("[SERIALIZER]: Deserialized KeyframeMotion"); | ||
251 | sceneObject.KeyframeMotion = KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(keymotion[0].InnerText)); | ||
252 | } | ||
253 | else | ||
254 | { | ||
255 | sceneObject.KeyframeMotion = null; | ||
256 | } | ||
257 | |||
247 | // Script state may, or may not, exist. Not having any, is NOT | 258 | // Script state may, or may not, exist. Not having any, is NOT |
248 | // ever a problem. | 259 | // ever a problem. |
249 | sceneObject.LoadScriptState(doc); | 260 | sceneObject.LoadScriptState(doc); |
@@ -597,7 +608,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
597 | obj.sopVehicle = _vehicle; | 608 | obj.sopVehicle = _vehicle; |
598 | } | 609 | } |
599 | 610 | ||
600 | |||
601 | private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) | 611 | private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) |
602 | { | 612 | { |
603 | List<string> errorNodeNames; | 613 | List<string> errorNodeNames; |
@@ -1168,6 +1178,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
1168 | }); | 1178 | }); |
1169 | 1179 | ||
1170 | writer.WriteEndElement(); | 1180 | writer.WriteEndElement(); |
1181 | |||
1182 | if (sog.KeyframeMotion != null) | ||
1183 | { | ||
1184 | Byte[] data = sog.KeyframeMotion.Serialize(); | ||
1185 | |||
1186 | writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty); | ||
1187 | writer.WriteBase64(data, 0, data.Length); | ||
1188 | writer.WriteEndElement(); | ||
1189 | } | ||
1190 | |||
1171 | writer.WriteEndElement(); | 1191 | writer.WriteEndElement(); |
1172 | } | 1192 | } |
1173 | 1193 | ||