aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
authorMelanie2012-03-04 16:23:46 +0000
committerMelanie2012-03-04 16:23:46 +0000
commit182f5efbe94881c22af82bc71566c49dd02ed8f8 (patch)
tree2b26c2657cfb91464008d8e305566500bc3cdd9e /OpenSim/Region/Framework
parentMerge branch 'master' into careminster (diff)
parentZero velocity when drag-copying (diff)
downloadopensim-SC_OLD-182f5efbe94881c22af82bc71566c49dd02ed8f8.zip
opensim-SC_OLD-182f5efbe94881c22af82bc71566c49dd02ed8f8.tar.gz
opensim-SC_OLD-182f5efbe94881c22af82bc71566c49dd02ed8f8.tar.bz2
opensim-SC_OLD-182f5efbe94881c22af82bc71566c49dd02ed8f8.tar.xz
Merge branch 'master' of ssh://melanie@3dhosting.de/var/git/careminster into careminster
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/KeyframeMotion.cs422
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs44
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs115
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs34
7 files changed, 592 insertions, 42 deletions
diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
new file mode 100644
index 0000000..b7b0d27
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
@@ -0,0 +1,422 @@
1// Proprietary code of Avination Virtual Limited
2// (c) 2012 Melanie Thielker
3//
4
5using System;
6using System.Timers;
7using System.Collections;
8using System.Collections.Generic;
9using System.IO;
10using System.Diagnostics;
11using System.Reflection;
12using System.Threading;
13using OpenMetaverse;
14using OpenSim.Framework;
15using OpenSim.Region.Framework.Interfaces;
16using OpenSim.Region.Physics.Manager;
17using OpenSim.Region.Framework.Scenes.Serialization;
18using System.Runtime.Serialization.Formatters.Binary;
19using System.Runtime.Serialization;
20using Timer = System.Timers.Timer;
21using log4net;
22
23namespace OpenSim.Region.Framework.Scenes
24{
25 [Serializable]
26 public class KeyframeMotion
27 {
28 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
29
30 public enum PlayMode : int
31 {
32 Forward = 0,
33 Reverse = 1,
34 Loop = 2,
35 PingPong = 3
36 };
37
38 [Flags]
39 public enum DataFormat : int
40 {
41 Translation = 1,
42 Rotation = 2
43 }
44
45 [Serializable]
46 public struct Keyframe
47 {
48 public Vector3? Position;
49 public Quaternion? Rotation;
50 public Quaternion StartRotation;
51 public int TimeMS;
52 public int TimeTotal;
53 public Vector3 AngularVelocity;
54 };
55
56 private Vector3 m_basePosition;
57 private Quaternion m_baseRotation;
58 private Vector3 m_serializedPosition;
59
60 private Keyframe m_currentFrame;
61 private List<Keyframe> m_frames = new List<Keyframe>();
62
63 private Keyframe[] m_keyframes;
64
65 [NonSerialized()]
66 protected Timer m_timer = new Timer();
67
68 [NonSerialized()]
69 private SceneObjectGroup m_group;
70
71 private PlayMode m_mode = PlayMode.Forward;
72 private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation;
73
74 private bool m_running = false;
75 [NonSerialized()]
76 private bool m_selected = false;
77
78 private int m_iterations = 0;
79
80 private const double timerInterval = 50.0;
81
82 public DataFormat Data
83 {
84 get { return m_data; }
85 }
86
87 public bool Selected
88 {
89 set
90 {
91 if (value)
92 {
93 // Once we're let go, recompute positions
94 if (m_selected)
95 UpdateSceneObject(m_group);
96 }
97 else
98 {
99 // Save selection position in case we get moved
100 if (!m_selected)
101 m_serializedPosition = m_group.AbsolutePosition;
102 }
103 m_selected = value; }
104 }
105
106 public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data)
107 {
108 MemoryStream ms = new MemoryStream(data);
109
110 BinaryFormatter fmt = new BinaryFormatter();
111
112 KeyframeMotion newMotion = (KeyframeMotion)fmt.Deserialize(ms);
113
114 // This will be started when position is updated
115 newMotion.m_timer = new Timer();
116 newMotion.m_timer.Interval = (int)timerInterval;
117 newMotion.m_timer.AutoReset = true;
118 newMotion.m_timer.Elapsed += newMotion.OnTimer;
119
120 return newMotion;
121 }
122
123 public void UpdateSceneObject(SceneObjectGroup grp)
124 {
125 m_group = grp;
126 Vector3 offset = grp.AbsolutePosition - m_serializedPosition;
127
128 m_basePosition += offset;
129 m_currentFrame.Position += offset;
130 for (int i = 0 ; i < m_frames.Count ; i++)
131 {
132 Keyframe k = m_frames[i];
133 k.Position += offset;
134 m_frames[i] = k;
135 }
136
137 if (m_running)
138 Start();
139 }
140
141 public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data)
142 {
143 m_mode = mode;
144 m_data = data;
145
146 m_group = grp;
147 m_basePosition = grp.AbsolutePosition;
148 m_baseRotation = grp.GroupRotation;
149
150 m_timer.Interval = (int)timerInterval;
151 m_timer.AutoReset = true;
152 m_timer.Elapsed += OnTimer;
153 }
154
155 public void SetKeyframes(Keyframe[] frames)
156 {
157 m_keyframes = frames;
158 }
159
160 public void Start()
161 {
162 if (m_keyframes.Length > 0)
163 m_timer.Start();
164 m_running = true;
165 }
166
167 public void Stop()
168 {
169 // Failed object creation
170 if (m_timer == null)
171 return;
172 m_timer.Stop();
173
174 m_basePosition = m_group.AbsolutePosition;
175 m_baseRotation = m_group.GroupRotation;
176
177 m_group.RootPart.Velocity = Vector3.Zero;
178 m_group.RootPart.UpdateAngularVelocity(Vector3.Zero);
179 m_group.SendGroupRootTerseUpdate();
180
181 m_frames.Clear();
182 m_running = false;
183 }
184
185 public void Pause()
186 {
187 m_group.RootPart.Velocity = Vector3.Zero;
188 m_group.RootPart.UpdateAngularVelocity(Vector3.Zero);
189 m_group.SendGroupRootTerseUpdate();
190
191 m_timer.Stop();
192 m_running = false;
193 }
194
195 private void GetNextList()
196 {
197 m_frames.Clear();
198 Vector3 pos = m_basePosition;
199 Quaternion rot = m_baseRotation;
200
201 if (m_mode == PlayMode.Loop || m_mode == PlayMode.PingPong || m_iterations == 0)
202 {
203 int direction = 1;
204 if (m_mode == PlayMode.Reverse || ((m_mode == PlayMode.PingPong) && ((m_iterations & 1) != 0)))
205 direction = -1;
206
207 int start = 0;
208 int end = m_keyframes.Length;
209// if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1)
210// end = m_keyframes.Length - 1;
211
212 if (direction < 0)
213 {
214 start = m_keyframes.Length - 1;
215 end = -1;
216// if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1)
217// end = 0;
218 }
219
220 for (int i = start; i != end ; i += direction)
221 {
222 Keyframe k = m_keyframes[i];
223
224 if (k.Position.HasValue)
225 k.Position = (k.Position * direction) + pos;
226 else
227 k.Position = pos;
228
229 k.StartRotation = rot;
230 if (k.Rotation.HasValue)
231 {
232 if (direction == -1)
233 k.Rotation = Quaternion.Conjugate((Quaternion)k.Rotation);
234 k.Rotation = rot * k.Rotation;
235 }
236 else
237 {
238 k.Rotation = rot;
239 }
240
241 float angle = 0;
242
243 float aa = k.StartRotation.X * k.StartRotation.X + k.StartRotation.Y * k.StartRotation.Y + k.StartRotation.Z * k.StartRotation.Z + k.StartRotation.W * k.StartRotation.W;
244 float bb = ((Quaternion)k.Rotation).X * ((Quaternion)k.Rotation).X + ((Quaternion)k.Rotation).Y * ((Quaternion)k.Rotation).Y + ((Quaternion)k.Rotation).Z * ((Quaternion)k.Rotation).Z + ((Quaternion)k.Rotation).W * ((Quaternion)k.Rotation).W;
245 float aa_bb = aa * bb;
246
247 if (aa_bb == 0)
248 {
249 angle = 0;
250 }
251 else
252 {
253 float ab = k.StartRotation.X * ((Quaternion)k.Rotation).X +
254 k.StartRotation.Y * ((Quaternion)k.Rotation).Y +
255 k.StartRotation.Z * ((Quaternion)k.Rotation).Z +
256 k.StartRotation.W * ((Quaternion)k.Rotation).W;
257 float q = (ab * ab) / aa_bb;
258
259 if (q > 1.0f)
260 {
261 angle = 0;
262 }
263 else
264 {
265 angle = (float)Math.Acos(2 * q - 1);
266 }
267 }
268
269 k.AngularVelocity = (new Vector3(0, 0, 1) * (Quaternion)k.Rotation) * (angle / (k.TimeMS / 1000));
270 k.TimeTotal = k.TimeMS;
271
272 m_frames.Add(k);
273
274 pos = (Vector3)k.Position;
275 rot = (Quaternion)k.Rotation;
276 }
277
278 m_basePosition = pos;
279 m_baseRotation = rot;
280
281 m_iterations++;
282 }
283 }
284
285 protected void OnTimer(object sender, ElapsedEventArgs e)
286 {
287 if (m_frames.Count == 0)
288 {
289 GetNextList();
290
291 if (m_frames.Count == 0)
292 {
293 Stop();
294 return;
295 }
296
297 m_currentFrame = m_frames[0];
298 }
299
300 if (m_selected)
301 {
302 if (m_group.RootPart.Velocity != Vector3.Zero)
303 {
304 m_group.RootPart.Velocity = Vector3.Zero;
305 m_group.SendGroupRootTerseUpdate();
306 }
307 return;
308 }
309
310 // Do the frame processing
311 double steps = (double)m_currentFrame.TimeMS / timerInterval;
312 float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal;
313
314 if (steps <= 1.0)
315 {
316 m_currentFrame.TimeMS = 0;
317
318 m_group.AbsolutePosition = (Vector3)m_currentFrame.Position;
319 m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation);
320 }
321 else
322 {
323 Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition;
324 Vector3 motionThisFrame = v / (float)steps;
325 v = v * 1000 / m_currentFrame.TimeMS;
326
327 bool update = false;
328
329 if (Vector3.Mag(motionThisFrame) >= 0.05f)
330 {
331 m_group.AbsolutePosition += motionThisFrame;
332 m_group.RootPart.Velocity = v;
333 update = true;
334 }
335
336 if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation)
337 {
338 Quaternion current = m_group.GroupRotation;
339
340 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete);
341
342 float angle = 0;
343
344 float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W;
345 float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W;
346 float aa_bb = aa * bb;
347
348 if (aa_bb == 0)
349 {
350 angle = 0;
351 }
352 else
353 {
354 float ab = current.X * step.X +
355 current.Y * step.Y +
356 current.Z * step.Z +
357 current.W * step.W;
358 float q = (ab * ab) / aa_bb;
359
360 if (q > 1.0f)
361 {
362 angle = 0;
363 }
364 else
365 {
366 angle = (float)Math.Acos(2 * q - 1);
367 }
368 }
369
370 if (angle > 0.01f)
371 {
372 m_group.UpdateGroupRotationR(step);
373 //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2);
374 update = true;
375 }
376 }
377
378 if (update)
379 m_group.SendGroupRootTerseUpdate();
380 }
381
382 m_currentFrame.TimeMS -= (int)timerInterval;
383
384 if (m_currentFrame.TimeMS <= 0)
385 {
386 m_group.RootPart.Velocity = Vector3.Zero;
387 m_group.RootPart.UpdateAngularVelocity(Vector3.Zero);
388 m_group.SendGroupRootTerseUpdate();
389
390 m_frames.RemoveAt(0);
391 if (m_frames.Count > 0)
392 m_currentFrame = m_frames[0];
393 }
394 }
395
396 public Byte[] Serialize()
397 {
398 MemoryStream ms = new MemoryStream();
399 m_timer.Stop();
400
401 BinaryFormatter fmt = new BinaryFormatter();
402 SceneObjectGroup tmp = m_group;
403 m_group = null;
404 m_serializedPosition = tmp.AbsolutePosition;
405 fmt.Serialize(ms, this);
406 m_group = tmp;
407 return ms.ToArray();
408 }
409
410 public void CrossingFailure()
411 {
412 // The serialization has stopped the timer, so let's wait a moment
413 // then retry the crossing. We'll get back here if it fails.
414 Util.FireAndForget(delegate (object x)
415 {
416 Thread.Sleep(60000);
417 if (m_running)
418 m_timer.Start();
419 });
420 }
421 }
422}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index bf2e775..b006045 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -138,12 +138,12 @@ namespace OpenSim.Region.Framework.Scenes
138 { 138 {
139 SceneObjectGroup sog = part.ParentGroup; 139 SceneObjectGroup sog = part.ParentGroup;
140 sog.SendPropertiesToClient(remoteClient); 140 sog.SendPropertiesToClient(remoteClient);
141 sog.IsSelected = true;
142 141
143 // A prim is only tainted if it's allowed to be edited by the person clicking it. 142 // A prim is only tainted if it's allowed to be edited by the person clicking it.
144 if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) 143 if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)
145 || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) 144 || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId))
146 { 145 {
146 sog.IsSelected = true;
147 EventManager.TriggerParcelPrimCountTainted(); 147 EventManager.TriggerParcelPrimCountTainted();
148 } 148 }
149 } 149 }
@@ -215,7 +215,9 @@ namespace OpenSim.Region.Framework.Scenes
215 // handled by group, but by prim. Legacy cruft. 215 // handled by group, but by prim. Legacy cruft.
216 // TODO: Make selection flagging per prim! 216 // TODO: Make selection flagging per prim!
217 // 217 //
218 part.ParentGroup.IsSelected = false; 218 if (Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)
219 || Permissions.CanMoveObject(part.ParentGroup.UUID, remoteClient.AgentId))
220 part.ParentGroup.IsSelected = false;
219 221
220 if (part.ParentGroup.IsAttachment) 222 if (part.ParentGroup.IsAttachment)
221 isAttachment = true; 223 isAttachment = true;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 4324cc0..e675c73 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2411,6 +2411,8 @@ namespace OpenSim.Region.Framework.Scenes
2411 2411
2412 if (newPosition != Vector3.Zero) 2412 if (newPosition != Vector3.Zero)
2413 newObject.RootPart.GroupPosition = newPosition; 2413 newObject.RootPart.GroupPosition = newPosition;
2414 if (newObject.RootPart.KeyframeMotion != null)
2415 newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
2414 2416
2415 if (!AddSceneObject(newObject)) 2417 if (!AddSceneObject(newObject))
2416 { 2418 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 5a7f124..a320601 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -1731,6 +1731,12 @@ namespace OpenSim.Region.Framework.Scenes
1731 /// <param name="childPrims"></param> 1731 /// <param name="childPrims"></param>
1732 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1732 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1733 { 1733 {
1734 if (root.KeyframeMotion != null)
1735 {
1736 root.KeyframeMotion.Stop();
1737 root.KeyframeMotion = null;
1738 }
1739
1734 SceneObjectGroup parentGroup = root.ParentGroup; 1740 SceneObjectGroup parentGroup = root.ParentGroup;
1735 if (parentGroup == null) return; 1741 if (parentGroup == null) return;
1736 1742
@@ -1823,6 +1829,11 @@ namespace OpenSim.Region.Framework.Scenes
1823 { 1829 {
1824 if (part != null) 1830 if (part != null)
1825 { 1831 {
1832 if (part.KeyframeMotion != null)
1833 {
1834 part.KeyframeMotion.Stop();
1835 part.KeyframeMotion = null;
1836 }
1826 if (part.ParentGroup.PrimCount != 1) // Skip single 1837 if (part.ParentGroup.PrimCount != 1) // Skip single
1827 { 1838 {
1828 if (part.LinkNum < 2) // Root 1839 if (part.LinkNum < 2) // Root
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index cf8637f..c9ea8e4 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -582,7 +582,7 @@ namespace OpenSim.Region.Framework.Scenes
582 foreach (ScenePresence av in m_linkedAvatars) 582 foreach (ScenePresence av in m_linkedAvatars)
583 { 583 {
584 SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID); 584 SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID);
585 if (m_parts.TryGetValue(p.UUID, out p)) 585 if (p != null && m_parts.TryGetValue(p.UUID, out p))
586 { 586 {
587 Vector3 offset = p.GetWorldPosition() - av.ParentPosition; 587 Vector3 offset = p.GetWorldPosition() - av.ParentPosition;
588 av.AbsolutePosition += offset; 588 av.AbsolutePosition += offset;
@@ -720,6 +720,8 @@ namespace OpenSim.Region.Framework.Scenes
720 child.PhysActor.Selected = value; 720 child.PhysActor.Selected = value;
721 } 721 }
722 } 722 }
723 if (RootPart.KeyframeMotion != null)
724 RootPart.KeyframeMotion.Selected = value;
723 } 725 }
724 } 726 }
725 727
@@ -890,6 +892,10 @@ namespace OpenSim.Region.Framework.Scenes
890 ApplyPhysics(); 892 ApplyPhysics();
891 893
892 if (RootPart.PhysActor != null) 894 if (RootPart.PhysActor != null)
895 RootPart.Force = RootPart.Force;
896 if (RootPart.PhysActor != null)
897 RootPart.Torque = RootPart.Torque;
898 if (RootPart.PhysActor != null)
893 RootPart.Buoyancy = RootPart.Buoyancy; 899 RootPart.Buoyancy = RootPart.Buoyancy;
894 900
895 // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled 901 // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
@@ -1829,6 +1835,11 @@ namespace OpenSim.Region.Framework.Scenes
1829 1835
1830 backup_group.ForEachPart(delegate(SceneObjectPart part) 1836 backup_group.ForEachPart(delegate(SceneObjectPart part)
1831 { 1837 {
1838 if (part.KeyframeMotion != null)
1839 {
1840 part.KeyframeMotion = KeyframeMotion.FromData(backup_group, part.KeyframeMotion.Serialize());
1841 part.KeyframeMotion.UpdateSceneObject(this);
1842 }
1832 part.Inventory.ProcessInventoryBackup(datastore); 1843 part.Inventory.ProcessInventoryBackup(datastore);
1833 }); 1844 });
1834 1845
@@ -1978,10 +1989,18 @@ namespace OpenSim.Region.Framework.Scenes
1978 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 1989 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
1979 { 1990 {
1980 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); 1991 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
1992 if (userExposed)
1993 RootPart.Velocity = Vector3.Zero; // In case source is moving
1981 } 1994 }
1982 1995
1983 public void ScriptSetPhysicsStatus(bool usePhysics) 1996 public void ScriptSetPhysicsStatus(bool usePhysics)
1984 { 1997 {
1998 if (usePhysics)
1999 {
2000 if (RootPart.KeyframeMotion != null)
2001 RootPart.KeyframeMotion.Stop();
2002 RootPart.KeyframeMotion = null;
2003 }
1985 UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2004 UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
1986 } 2005 }
1987 2006
@@ -2045,30 +2064,9 @@ namespace OpenSim.Region.Framework.Scenes
2045 } 2064 }
2046 } 2065 }
2047 2066
2048 public void setAngularImpulse(Vector3 impulse)
2049 {
2050 if (RootPart.PhysActor != null)
2051 {
2052 if (!IsAttachment)
2053 {
2054 RootPart.PhysActor.Torque = impulse;
2055 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
2056 }
2057 }
2058 }
2059
2060 public Vector3 GetTorque() 2067 public Vector3 GetTorque()
2061 { 2068 {
2062 if (RootPart.PhysActor != null) 2069 return RootPart.Torque;
2063 {
2064 if (!IsAttachment)
2065 {
2066 Vector3 torque = RootPart.PhysActor.Torque;
2067 return torque;
2068 }
2069 }
2070
2071 return Vector3.Zero;
2072 } 2070 }
2073 2071
2074 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object 2072 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index dd9431b..1c72b10 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -294,6 +294,8 @@ namespace OpenSim.Region.Framework.Scenes
294 protected Vector3 m_lastAngularVelocity; 294 protected Vector3 m_lastAngularVelocity;
295 protected int m_lastTerseSent; 295 protected int m_lastTerseSent;
296 protected float m_buoyancy = 0.0f; 296 protected float m_buoyancy = 0.0f;
297 protected Vector3 m_force;
298 protected Vector3 m_torque;
297 299
298 /// <summary> 300 /// <summary>
299 /// Stores media texture data 301 /// Stores media texture data
@@ -313,6 +315,14 @@ namespace OpenSim.Region.Framework.Scenes
313 315
314 private SOPVehicle m_vehicle = null; 316 private SOPVehicle m_vehicle = null;
315 317
318 private KeyframeMotion m_keyframeMotion = null;
319
320 public KeyframeMotion KeyframeMotion
321 {
322 get; set;
323 }
324
325
316 #endregion Fields 326 #endregion Fields
317 327
318// ~SceneObjectPart() 328// ~SceneObjectPart()
@@ -906,7 +916,7 @@ namespace OpenSim.Region.Framework.Scenes
906 get 916 get
907 { 917 {
908 PhysicsActor actor = PhysActor; 918 PhysicsActor actor = PhysActor;
909 if ((actor != null) && actor.IsPhysical) 919 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
910 { 920 {
911 m_angularVelocity = actor.RotationalVelocity; 921 m_angularVelocity = actor.RotationalVelocity;
912 } 922 }
@@ -1302,14 +1312,69 @@ namespace OpenSim.Region.Framework.Scenes
1302 1312
1303 public float Buoyancy 1313 public float Buoyancy
1304 { 1314 {
1305 get { return m_buoyancy; } 1315 get
1316 {
1317 if (ParentGroup.RootPart == this)
1318 return m_buoyancy;
1319
1320 return ParentGroup.RootPart.Buoyancy;
1321 }
1306 set 1322 set
1307 { 1323 {
1324 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1325 {
1326 ParentGroup.RootPart.Buoyancy = value;
1327 return;
1328 }
1308 m_buoyancy = value; 1329 m_buoyancy = value;
1309 if (PhysActor != null) 1330 if (PhysActor != null)
1310 {
1311 PhysActor.Buoyancy = value; 1331 PhysActor.Buoyancy = value;
1332 }
1333 }
1334
1335 public Vector3 Force
1336 {
1337 get
1338 {
1339 if (ParentGroup.RootPart == this)
1340 return m_force;
1341
1342 return ParentGroup.RootPart.Force;
1343 }
1344
1345 set
1346 {
1347 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1348 {
1349 ParentGroup.RootPart.Force = value;
1350 return;
1351 }
1352 m_force = value;
1353 if (PhysActor != null)
1354 PhysActor.Force = value;
1355 }
1356 }
1357
1358 public Vector3 Torque
1359 {
1360 get
1361 {
1362 if (ParentGroup.RootPart == this)
1363 return m_torque;
1364
1365 return ParentGroup.RootPart.Torque;
1366 }
1367
1368 set
1369 {
1370 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1371 {
1372 ParentGroup.RootPart.Torque = value;
1373 return;
1312 } 1374 }
1375 m_torque = value;
1376 if (PhysActor != null)
1377 PhysActor.Torque = value;
1313 } 1378 }
1314 } 1379 }
1315 1380
@@ -1488,20 +1553,24 @@ namespace OpenSim.Region.Framework.Scenes
1488 /// </summary> 1553 /// </summary>
1489 /// <param name="impulsei">Vector force</param> 1554 /// <param name="impulsei">Vector force</param>
1490 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1555 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1491 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1556
1557 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
1558 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1492 { 1559 {
1493 Vector3 impulse = impulsei; 1560 Vector3 torque = torquei;
1494 1561
1495 if (localGlobalTF) 1562 if (localGlobalTF)
1496 { 1563 {
1564/*
1497 Quaternion grot = GetWorldRotation(); 1565 Quaternion grot = GetWorldRotation();
1498 Quaternion AXgrot = grot; 1566 Quaternion AXgrot = grot;
1499 Vector3 AXimpulsei = impulsei; 1567 Vector3 AXimpulsei = impulsei;
1500 Vector3 newimpulse = AXimpulsei * AXgrot; 1568 Vector3 newimpulse = AXimpulsei * AXgrot;
1501 impulse = newimpulse; 1569 */
1570 torque *= GetWorldRotation();
1502 } 1571 }
1503 1572
1504 ParentGroup.setAngularImpulse(impulse); 1573 Torque = torque;
1505 } 1574 }
1506 1575
1507 /// <summary> 1576 /// <summary>
@@ -1571,14 +1640,22 @@ namespace OpenSim.Region.Framework.Scenes
1571 1640
1572 DoPhysicsPropertyUpdate(RigidBody, true); 1641 DoPhysicsPropertyUpdate(RigidBody, true);
1573 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1642 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
1643
1644 if (!building)
1645 PhysActor.Building = false;
1574 1646
1575 Velocity = velocity; 1647 Velocity = velocity;
1576 AngularVelocity = rotationalVelocity; 1648 AngularVelocity = rotationalVelocity;
1577 PhysActor.Velocity = velocity; 1649 PhysActor.Velocity = velocity;
1578 PhysActor.RotationalVelocity = rotationalVelocity; 1650 PhysActor.RotationalVelocity = rotationalVelocity;
1579 1651
1580 if (!building) 1652 // if not vehicle and root part apply force and torque
1581 PhysActor.Building = false; 1653 if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
1654 && LocalId == ParentGroup.RootPart.LocalId)
1655 {
1656 PhysActor.Force = Force;
1657 PhysActor.Torque = Torque;
1658 }
1582 } 1659 }
1583 } 1660 }
1584 } 1661 }
@@ -1816,7 +1893,8 @@ namespace OpenSim.Region.Framework.Scenes
1816 1893
1817 Velocity = new Vector3(0, 0, 0); 1894 Velocity = new Vector3(0, 0, 0);
1818 Acceleration = new Vector3(0, 0, 0); 1895 Acceleration = new Vector3(0, 0, 0);
1819 AngularVelocity = new Vector3(0, 0, 0); 1896 if (ParentGroup.RootPart == this)
1897 AngularVelocity = new Vector3(0, 0, 0);
1820 1898
1821 PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 1899 PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1822 PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; 1900 PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
@@ -1840,7 +1918,8 @@ namespace OpenSim.Region.Framework.Scenes
1840 // velocity-vector. 1918 // velocity-vector.
1841 Velocity = new Vector3(0, 0, 0); 1919 Velocity = new Vector3(0, 0, 0);
1842 Acceleration = new Vector3(0, 0, 0); 1920 Acceleration = new Vector3(0, 0, 0);
1843 AngularVelocity = new Vector3(0, 0, 0); 1921 if (ParentGroup.RootPart == this)
1922 AngularVelocity = new Vector3(0, 0, 0);
1844 //RotationalVelocity = new Vector3(0, 0, 0); 1923 //RotationalVelocity = new Vector3(0, 0, 0);
1845 } 1924 }
1846 1925
@@ -1855,6 +1934,9 @@ namespace OpenSim.Region.Framework.Scenes
1855 { 1934 {
1856 if (UsePhysics) 1935 if (UsePhysics)
1857 { 1936 {
1937 if (ParentGroup.RootPart.KeyframeMotion != null)
1938 ParentGroup.RootPart.KeyframeMotion.Stop();
1939 ParentGroup.RootPart.KeyframeMotion = null;
1858 ParentGroup.Scene.AddPhysicalPrim(1); 1940 ParentGroup.Scene.AddPhysicalPrim(1);
1859 1941
1860 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 1942 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -2002,10 +2084,7 @@ namespace OpenSim.Region.Framework.Scenes
2002 2084
2003 public Vector3 GetForce() 2085 public Vector3 GetForce()
2004 { 2086 {
2005 if (PhysActor != null) 2087 return Force;
2006 return PhysActor.Force;
2007 else
2008 return Vector3.Zero;
2009 } 2088 }
2010 2089
2011 /// <summary> 2090 /// <summary>
@@ -3150,10 +3229,13 @@ namespace OpenSim.Region.Framework.Scenes
3150 3229
3151 public void SetBuoyancy(float fvalue) 3230 public void SetBuoyancy(float fvalue)
3152 { 3231 {
3232 Buoyancy = fvalue;
3233/*
3153 if (PhysActor != null) 3234 if (PhysActor != null)
3154 { 3235 {
3155 PhysActor.Buoyancy = fvalue; 3236 PhysActor.Buoyancy = fvalue;
3156 } 3237 }
3238 */
3157 } 3239 }
3158 3240
3159 public void SetDieAtEdge(bool p) 3241 public void SetDieAtEdge(bool p)
@@ -3181,10 +3263,13 @@ namespace OpenSim.Region.Framework.Scenes
3181 3263
3182 public void SetForce(Vector3 force) 3264 public void SetForce(Vector3 force)
3183 { 3265 {
3266 Force = force;
3267/*
3184 if (PhysActor != null) 3268 if (PhysActor != null)
3185 { 3269 {
3186 PhysActor.Force = force; 3270 PhysActor.Force = force;
3187 } 3271 }
3272 */
3188 } 3273 }
3189 3274
3190 public SOPVehicle sopVehicle 3275 public SOPVehicle sopVehicle
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 72a0ec3..51a3320 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -244,6 +244,12 @@ 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 sceneObject.RootPart.KeyframeMotion = KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(keymotion[0].InnerText));
250 else
251 sceneObject.RootPart.KeyframeMotion = null;
252
247 // Script state may, or may not, exist. Not having any, is NOT 253 // Script state may, or may not, exist. Not having any, is NOT
248 // ever a problem. 254 // ever a problem.
249 sceneObject.LoadScriptState(doc); 255 sceneObject.LoadScriptState(doc);
@@ -349,6 +355,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
349 m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4); 355 m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4);
350 356
351 m_SOPXmlProcessors.Add("Buoyancy", ProcessBuoyancy); 357 m_SOPXmlProcessors.Add("Buoyancy", ProcessBuoyancy);
358 m_SOPXmlProcessors.Add("Force", ProcessForce);
359 m_SOPXmlProcessors.Add("Torque", ProcessTorque);
352 m_SOPXmlProcessors.Add("VolumeDetectActive", ProcessVolumeDetectActive); 360 m_SOPXmlProcessors.Add("VolumeDetectActive", ProcessVolumeDetectActive);
353 361
354 //Ubit comented until proper testing 362 //Ubit comented until proper testing
@@ -595,7 +603,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
595 obj.sopVehicle = _vehicle; 603 obj.sopVehicle = _vehicle;
596 } 604 }
597 605
598
599 private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) 606 private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
600 { 607 {
601 List<string> errorNodeNames; 608 List<string> errorNodeNames;
@@ -762,7 +769,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
762 769
763 private static void ProcessBuoyancy(SceneObjectPart obj, XmlTextReader reader) 770 private static void ProcessBuoyancy(SceneObjectPart obj, XmlTextReader reader)
764 { 771 {
765 obj.Buoyancy = (int)reader.ReadElementContentAsFloat("Buoyancy", String.Empty); 772 obj.Buoyancy = (float)reader.ReadElementContentAsFloat("Buoyancy", String.Empty);
773 }
774
775 private static void ProcessForce(SceneObjectPart obj, XmlTextReader reader)
776 {
777 obj.Force = Util.ReadVector(reader, "Force");
778 }
779 private static void ProcessTorque(SceneObjectPart obj, XmlTextReader reader)
780 {
781 obj.Torque = Util.ReadVector(reader, "Torque");
766 } 782 }
767 783
768 private static void ProcessVolumeDetectActive(SceneObjectPart obj, XmlTextReader reader) 784 private static void ProcessVolumeDetectActive(SceneObjectPart obj, XmlTextReader reader)
@@ -1157,6 +1173,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1157 }); 1173 });
1158 1174
1159 writer.WriteEndElement(); 1175 writer.WriteEndElement();
1176
1177 if (sog.RootPart.KeyframeMotion != null)
1178 {
1179 Byte[] data = sog.RootPart.KeyframeMotion.Serialize();
1180
1181 writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty);
1182 writer.WriteBase64(data, 0, data.Length);
1183 writer.WriteEndElement();
1184 }
1185
1160 writer.WriteEndElement(); 1186 writer.WriteEndElement();
1161 } 1187 }
1162 1188
@@ -1256,6 +1282,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1256 writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString()); 1282 writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString());
1257 1283
1258 writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString()); 1284 writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString());
1285
1286 WriteVector(writer, "Force", sop.Force);
1287 WriteVector(writer, "Torque", sop.Torque);
1288
1259 writer.WriteElementString("VolumeDetectActive", sop.VolumeDetectActive.ToString().ToLower()); 1289 writer.WriteElementString("VolumeDetectActive", sop.VolumeDetectActive.ToString().ToLower());
1260 1290
1261 //Ubit comented until proper testing 1291 //Ubit comented until proper testing