aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs388
-rw-r--r--OpenSim/Region/Framework/Scenes/AnimationSet.cs21
-rw-r--r--OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs460
5 files changed, 481 insertions, 392 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
new file mode 100644
index 0000000..d22e24a
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -0,0 +1,388 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenMetaverse;
30using OpenSim.Framework;
31using OpenSim.Region.Framework.Interfaces;
32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Region.Physics.Manager;
34
35namespace OpenSim.Region.Framework.Scenes.Animation
36{
37 /// <summary>
38 /// Handle all animation duties for a scene presence
39 /// </summary>
40 public class ScenePresenceAnimator
41 {
42 public AnimationSet Animations
43 {
44 get { return m_animations; }
45 }
46 protected AnimationSet m_animations = new AnimationSet();
47
48 /// <value>
49 /// The current movement animation
50 /// </value>
51 public string CurrentMovementAnimation
52 {
53 get { return m_movementAnimation; }
54 }
55 protected string m_movementAnimation = "DEFAULT";
56
57 private int m_animTickFall;
58 private int m_animTickJump;
59
60 /// <value>
61 /// The scene presence that this animator applies to
62 /// </value>
63 protected ScenePresence m_scenePresence;
64
65 public ScenePresenceAnimator(ScenePresence sp)
66 {
67 m_scenePresence = sp;
68 }
69
70 public void AddAnimation(UUID animID, UUID objectID)
71 {
72 if (m_scenePresence.IsChildAgent)
73 return;
74
75 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID))
76 SendAnimPack();
77 }
78
79 // Called from scripts
80 public void AddAnimation(string name, UUID objectID)
81 {
82 if (m_scenePresence.IsChildAgent)
83 return;
84
85 UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name);
86 if (animID == UUID.Zero)
87 return;
88
89 AddAnimation(animID, objectID);
90 }
91
92 public void RemoveAnimation(UUID animID)
93 {
94 if (m_scenePresence.IsChildAgent)
95 return;
96
97 if (m_animations.Remove(animID))
98 SendAnimPack();
99 }
100
101 // Called from scripts
102 public void RemoveAnimation(string name)
103 {
104 if (m_scenePresence.IsChildAgent)
105 return;
106
107 UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name);
108 if (animID == UUID.Zero)
109 return;
110
111 RemoveAnimation(animID);
112 }
113
114 public void ResetAnimations()
115 {
116 m_animations.Clear();
117 }
118
119 /// <summary>
120 /// The movement animation is reserved for "main" animations
121 /// that are mutually exclusive, e.g. flying and sitting.
122 /// </summary>
123 public void TrySetMovementAnimation(string anim)
124 {
125 //m_log.DebugFormat("Updating movement animation to {0}", anim);
126
127 if (!m_scenePresence.IsChildAgent)
128 {
129 if (m_animations.TrySetDefaultAnimation(
130 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero))
131 {
132 // 16384 is CHANGED_ANIMATION
133 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 });
134 SendAnimPack();
135 }
136 }
137 }
138
139 /// <summary>
140 /// This method determines the proper movement related animation
141 /// </summary>
142 public string GetMovementAnimation()
143 {
144 const float FALL_DELAY = 0.33f;
145 const float PREJUMP_DELAY = 0.25f;
146
147 #region Inputs
148
149 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
150 PhysicsActor actor = m_scenePresence.PhysicsActor;
151
152 // Create forward and left vectors from the current avatar rotation
153 Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation);
154 Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix);
155 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
156
157 // Check control flags
158 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
159 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG;
160 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
161 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
162 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
163 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
164 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
165 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
166 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
167 //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;
168
169 // Direction in which the avatar is trying to move
170 Vector3 move = Vector3.Zero;
171 if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
172 if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; }
173 if (heldLeft) { move.X += left.X; move.Y += left.Y; }
174 if (heldRight) { move.X -= left.X; move.Y -= left.Y; }
175 if (heldUp) { move.Z += 1; }
176 if (heldDown) { move.Z -= 1; }
177
178 // Is the avatar trying to move?
179// bool moving = (move != Vector3.Zero);
180 bool jumping = m_animTickJump != 0;
181
182 #endregion Inputs
183
184 #region Flying
185
186 if (actor != null && actor.Flying)
187 {
188 m_animTickFall = 0;
189 m_animTickJump = 0;
190
191 if (move.X != 0f || move.Y != 0f)
192 {
193 return (m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
194 }
195 else if (move.Z > 0f)
196 {
197 return "HOVER_UP";
198 }
199 else if (move.Z < 0f)
200 {
201 if (actor != null && actor.IsColliding)
202 return "LAND";
203 else
204 return "HOVER_DOWN";
205 }
206 else
207 {
208 return "HOVER";
209 }
210 }
211
212 #endregion Flying
213
214 #region Falling/Floating/Landing
215
216 if (actor == null || !actor.IsColliding)
217 {
218 float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
219 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;
220
221 if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f))
222 {
223 // Just started falling
224 m_animTickFall = Environment.TickCount;
225 }
226 else if (!jumping && fallElapsed > FALL_DELAY)
227 {
228 // Falling long enough to trigger the animation
229 return "FALLDOWN";
230 }
231
232 return m_movementAnimation;
233 }
234
235 #endregion Falling/Floating/Landing
236
237 #region Ground Movement
238
239 if (m_movementAnimation == "FALLDOWN")
240 {
241 m_animTickFall = Environment.TickCount;
242
243 // TODO: SOFT_LAND support
244 return "LAND";
245 }
246 else if (m_movementAnimation == "LAND")
247 {
248 float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
249
250 if (landElapsed <= FALL_DELAY)
251 return "LAND";
252 }
253
254 m_animTickFall = 0;
255
256 if (move.Z > 0f)
257 {
258 // Jumping
259 if (!jumping)
260 {
261 // Begin prejump
262 m_animTickJump = Environment.TickCount;
263 return "PREJUMP";
264 }
265 else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f)
266 {
267 // Start actual jump
268 if (m_animTickJump == -1)
269 {
270 // Already jumping! End the current jump
271 m_animTickJump = 0;
272 return "JUMP";
273 }
274
275 m_animTickJump = -1;
276 return "JUMP";
277 }
278 }
279 else
280 {
281 // Not jumping
282 m_animTickJump = 0;
283
284 if (move.X != 0f || move.Y != 0f)
285 {
286 // Walking / crouchwalking / running
287 if (move.Z < 0f)
288 return "CROUCHWALK";
289 else if (m_scenePresence.SetAlwaysRun)
290 return "RUN";
291 else
292 return "WALK";
293 }
294 else
295 {
296 // Not walking
297 if (move.Z < 0f)
298 return "CROUCH";
299 else
300 return "STAND";
301 }
302 }
303
304 #endregion Ground Movement
305
306 return m_movementAnimation;
307 }
308
309 /// <summary>
310 /// Update the movement animation of this avatar according to its current state
311 /// </summary>
312 public void UpdateMovementAnimations()
313 {
314 m_movementAnimation = GetMovementAnimation();
315
316 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
317 {
318 // This was the previous behavior before PREJUMP
319 TrySetMovementAnimation("JUMP");
320 }
321 else
322 {
323 TrySetMovementAnimation(m_movementAnimation);
324 }
325 }
326
327 public UUID[] GetAnimationArray()
328 {
329 UUID[] animIDs;
330 int[] sequenceNums;
331 UUID[] objectIDs;
332 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
333 return animIDs;
334 }
335
336 /// <summary>
337 ///
338 /// </summary>
339 /// <param name="animations"></param>
340 /// <param name="seqs"></param>
341 /// <param name="objectIDs"></param>
342 public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
343 {
344 if (m_scenePresence.IsChildAgent)
345 return;
346
347 m_scenePresence.Scene.ForEachClient(
348 delegate(IClientAPI client)
349 {
350 client.SendAnimations(animations, seqs, m_scenePresence.ControllingClient.AgentId, objectIDs);
351 });
352 }
353
354 public void SendAnimPackToClient(IClientAPI client)
355 {
356 if (m_scenePresence.IsChildAgent)
357 return;
358
359 UUID[] animIDs;
360 int[] sequenceNums;
361 UUID[] objectIDs;
362
363 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
364
365 m_scenePresence.ControllingClient.SendAnimations(
366 animIDs, sequenceNums, m_scenePresence.ControllingClient.AgentId, objectIDs);
367 }
368
369 /// <summary>
370 /// Send animation information about this avatar to all clients.
371 /// </summary>
372 public void SendAnimPack()
373 {
374 //m_log.Debug("Sending animation pack to all");
375
376 if (m_scenePresence.IsChildAgent)
377 return;
378
379 UUID[] animIDs;
380 int[] sequenceNums;
381 UUID[] objectIDs;
382
383 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
384
385 SendAnimPack(animIDs, sequenceNums, objectIDs);
386 }
387 }
388} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/AnimationSet.cs
index 740d168..3e6781e 100644
--- a/OpenSim/Region/Framework/Scenes/AnimationSet.cs
+++ b/OpenSim/Region/Framework/Scenes/AnimationSet.cs
@@ -39,13 +39,14 @@ namespace OpenSim.Region.Framework.Scenes
39 { 39 {
40 public static AvatarAnimations Animations = new AvatarAnimations(); 40 public static AvatarAnimations Animations = new AvatarAnimations();
41 41
42 private Animation m_defaultAnimation = new Animation(); 42 private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation();
43 private List<Animation> m_animations = new List<Animation>(); 43 private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>();
44 44
45 public Animation DefaultAnimation 45 public OpenSim.Framework.Animation DefaultAnimation
46 { 46 {
47 get { return m_defaultAnimation; } 47 get { return m_defaultAnimation; }
48 } 48 }
49
49 public AnimationSet() 50 public AnimationSet()
50 { 51 {
51 ResetDefaultAnimation(); 52 ResetDefaultAnimation();
@@ -71,7 +72,7 @@ namespace OpenSim.Region.Framework.Scenes
71 { 72 {
72 if (!HasAnimation(animID)) 73 if (!HasAnimation(animID))
73 { 74 {
74 m_animations.Add(new Animation(animID, sequenceNum, objectID)); 75 m_animations.Add(new OpenSim.Framework.Animation(animID, sequenceNum, objectID));
75 return true; 76 return true;
76 } 77 }
77 } 78 }
@@ -115,7 +116,7 @@ namespace OpenSim.Region.Framework.Scenes
115 { 116 {
116 if (m_defaultAnimation.AnimID != animID) 117 if (m_defaultAnimation.AnimID != animID)
117 { 118 {
118 m_defaultAnimation = new Animation(animID, sequenceNum, objectID); 119 m_defaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID);
119 return true; 120 return true;
120 } 121 }
121 return false; 122 return false;
@@ -159,13 +160,13 @@ namespace OpenSim.Region.Framework.Scenes
159 } 160 }
160 } 161 }
161 162
162 public Animation[] ToArray() 163 public OpenSim.Framework.Animation[] ToArray()
163 { 164 {
164 Animation[] theArray = new Animation[m_animations.Count]; 165 OpenSim.Framework.Animation[] theArray = new OpenSim.Framework.Animation[m_animations.Count];
165 uint i = 0; 166 uint i = 0;
166 try 167 try
167 { 168 {
168 foreach (Animation anim in m_animations) 169 foreach (OpenSim.Framework.Animation anim in m_animations)
169 theArray[i++] = anim; 170 theArray[i++] = anim;
170 } 171 }
171 catch 172 catch
@@ -175,9 +176,9 @@ namespace OpenSim.Region.Framework.Scenes
175 return theArray; 176 return theArray;
176 } 177 }
177 178
178 public void FromArray(Animation[] theArray) 179 public void FromArray(OpenSim.Framework.Animation[] theArray)
179 { 180 {
180 foreach (Animation anim in theArray) 181 foreach (OpenSim.Framework.Animation anim in theArray)
181 m_animations.Add(anim); 182 m_animations.Add(anim);
182 } 183 }
183 } 184 }
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
index d7e62a8..0f9c190 100644
--- a/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
@@ -82,7 +82,7 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid
82 IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>(); 82 IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>();
83 83
84 // Reset animations; the viewer does that in teleports. 84 // Reset animations; the viewer does that in teleports.
85 avatar.ResetAnimations(); 85 avatar.Animator.ResetAnimations();
86 86
87 if (regionHandle == m_regionInfo.RegionHandle) 87 if (regionHandle == m_regionInfo.RegionHandle)
88 { 88 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 4a2db5e..76c6cab 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -801,7 +801,7 @@ namespace OpenSim.Region.Framework.Scenes
801 IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>(); 801 IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>();
802 802
803 // Reset animations; the viewer does that in teleports. 803 // Reset animations; the viewer does that in teleports.
804 avatar.ResetAnimations(); 804 avatar.Animator.ResetAnimations();
805 805
806 if (regionHandle == m_regionInfo.RegionHandle) 806 if (regionHandle == m_regionInfo.RegionHandle)
807 { 807 {
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 08c144a..33c1932 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -35,6 +35,7 @@ using OpenSim.Framework;
35using OpenSim.Framework.Client; 35using OpenSim.Framework.Client;
36using OpenSim.Framework.Communications.Cache; 36using OpenSim.Framework.Communications.Cache;
37using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes.Animation;
38using OpenSim.Region.Framework.Scenes.Types; 39using OpenSim.Region.Framework.Scenes.Types;
39using OpenSim.Region.Physics.Manager; 40using OpenSim.Region.Physics.Manager;
40using GridRegion = OpenSim.Services.Interfaces.GridRegion; 41using GridRegion = OpenSim.Services.Interfaces.GridRegion;
@@ -79,6 +80,7 @@ namespace OpenSim.Region.Framework.Scenes
79// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 80// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
80 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 81 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
81 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); 82 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
83
82 /// <summary> 84 /// <summary>
83 /// Experimentally determined "fudge factor" to make sit-target positions 85 /// Experimentally determined "fudge factor" to make sit-target positions
84 /// the same as in SecondLife. Fudge factor was tested for 36 different 86 /// the same as in SecondLife. Fudge factor was tested for 36 different
@@ -93,7 +95,15 @@ namespace OpenSim.Region.Framework.Scenes
93 95
94 private ISceneViewer m_sceneViewer; 96 private ISceneViewer m_sceneViewer;
95 97
96 private AnimationSet m_animations = new AnimationSet(); 98 /// <value>
99 /// The animator for this avatar
100 /// </value>
101 public ScenePresenceAnimator Animator
102 {
103 get { return m_animator; }
104 }
105 protected ScenePresenceAnimator m_animator;
106
97 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); 107 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
98 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; 108 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
99 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; 109 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
@@ -134,12 +144,7 @@ namespace OpenSim.Region.Framework.Scenes
134 private int m_perfMonMS; 144 private int m_perfMonMS;
135 145
136 private bool m_setAlwaysRun; 146 private bool m_setAlwaysRun;
137 147
138 private string m_movementAnimation = "DEFAULT";
139 private int m_animTickFall;
140 private int m_animTickJump;
141 private bool m_useFlySlow;
142 private bool m_usePreJump;
143 private bool m_forceFly; 148 private bool m_forceFly;
144 private bool m_flyDisabled; 149 private bool m_flyDisabled;
145 150
@@ -227,7 +232,6 @@ namespace OpenSim.Region.Framework.Scenes
227 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 232 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
228 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 233 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
229 } 234 }
230
231 235
232 /// <summary> 236 /// <summary>
233 /// Position at which a significant movement was made 237 /// Position at which a significant movement was made
@@ -238,7 +242,10 @@ namespace OpenSim.Region.Framework.Scenes
238 string m_callbackURI; 242 string m_callbackURI;
239 ulong m_rootRegionHandle; 243 ulong m_rootRegionHandle;
240 244
241 private IScriptModule[] m_scriptEngines; 245 /// <value>
246 /// Script engines present in the scene
247 /// </value>
248 private IScriptModule[] m_scriptEngines;
242 249
243 #region Properties 250 #region Properties
244 251
@@ -586,11 +593,6 @@ namespace OpenSim.Region.Framework.Scenes
586 } 593 }
587 } 594 }
588 595
589 public AnimationSet Animations
590 {
591 get { return m_animations; }
592 }
593
594 private bool m_inTransit; 596 private bool m_inTransit;
595 private bool m_mouseLook; 597 private bool m_mouseLook;
596 private bool m_leftButtonDown; 598 private bool m_leftButtonDown;
@@ -625,6 +627,7 @@ namespace OpenSim.Region.Framework.Scenes
625 627
626 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) 628 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo)
627 { 629 {
630 m_animator = new ScenePresenceAnimator(this);
628 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 631 m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
629 CreateSceneViewer(); 632 CreateSceneViewer();
630 m_rootRegionHandle = reginfo.RegionHandle; 633 m_rootRegionHandle = reginfo.RegionHandle;
@@ -637,15 +640,12 @@ namespace OpenSim.Region.Framework.Scenes
637 m_regionInfo = reginfo; 640 m_regionInfo = reginfo;
638 m_localId = m_scene.AllocateLocalId(); 641 m_localId = m_scene.AllocateLocalId();
639 642
640 m_useFlySlow = m_scene.m_useFlySlow;
641 m_usePreJump = m_scene.m_usePreJump;
642
643 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); 643 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
644 if (gm != null) 644 if (gm != null)
645 m_grouptitle = gm.GetGroupTitle(m_uuid); 645 m_grouptitle = gm.GetGroupTitle(m_uuid);
646 646
647 m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); 647 m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>();
648 648
649 AbsolutePosition = posLastSignificantMove = m_CameraCenter = 649 AbsolutePosition = posLastSignificantMove = m_CameraCenter =
650 m_lastCameraCenter = m_controllingClient.StartPos; 650 m_lastCameraCenter = m_controllingClient.StartPos;
651 651
@@ -656,7 +656,8 @@ namespace OpenSim.Region.Framework.Scenes
656 656
657 AdjustKnownSeeds(); 657 AdjustKnownSeeds();
658 658
659 TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here... 659 // TODO: I think, this won't send anything, as we are still a child here...
660 Animator.TrySetMovementAnimation("STAND");
660 661
661 // we created a new ScenePresence (a new child agent) in a fresh region. 662 // we created a new ScenePresence (a new child agent) in a fresh region.
662 // Request info about all the (root) agents in this region 663 // Request info about all the (root) agents in this region
@@ -665,7 +666,6 @@ namespace OpenSim.Region.Framework.Scenes
665 666
666 RegisterToEvents(); 667 RegisterToEvents();
667 SetDirectionVectors(); 668 SetDirectionVectors();
668
669 } 669 }
670 670
671 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, 671 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams,
@@ -674,6 +674,7 @@ namespace OpenSim.Region.Framework.Scenes
674 { 674 {
675 CreateSceneViewer(); 675 CreateSceneViewer();
676 m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); 676 m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams);
677
677 } 678 }
678 679
679 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) 680 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
@@ -857,7 +858,7 @@ namespace OpenSim.Region.Framework.Scenes
857 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 858 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
858 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 859 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
859 // elsewhere anyway 860 // elsewhere anyway
860 //SendAnimPack(); 861 // Animator.SendAnimPack();
861 862
862 m_scene.SwapRootAgentCount(false); 863 m_scene.SwapRootAgentCount(false);
863 864
@@ -879,7 +880,7 @@ namespace OpenSim.Region.Framework.Scenes
879 ScenePresence presence = animAgents[i]; 880 ScenePresence presence = animAgents[i];
880 881
881 if (presence != this) 882 if (presence != this)
882 presence.SendAnimPackToClient(ControllingClient); 883 presence.Animator.SendAnimPackToClient(ControllingClient);
883 } 884 }
884 885
885 m_scene.EventManager.TriggerOnMakeRootAgent(this); 886 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -894,7 +895,7 @@ namespace OpenSim.Region.Framework.Scenes
894 /// </summary> 895 /// </summary>
895 public void MakeChildAgent() 896 public void MakeChildAgent()
896 { 897 {
897 m_animations.Clear(); 898 Animator.ResetAnimations();
898 899
899// m_log.DebugFormat( 900// m_log.DebugFormat(
900// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 901// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
@@ -995,7 +996,7 @@ namespace OpenSim.Region.Framework.Scenes
995 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 996 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
996 } 997 }
997 998
998 TrySetMovementAnimation("LAND"); 999 Animator.TrySetMovementAnimation("LAND");
999 SendFullUpdateToAllClients(); 1000 SendFullUpdateToAllClients();
1000 } 1001 }
1001 1002
@@ -1247,7 +1248,7 @@ namespace OpenSim.Region.Framework.Scenes
1247 // TODO: This doesn't prevent the user from walking yet. 1248 // TODO: This doesn't prevent the user from walking yet.
1248 // Setting parent ID would fix this, if we knew what value 1249 // Setting parent ID would fix this, if we knew what value
1249 // to use. Or we could add a m_isSitting variable. 1250 // to use. Or we could add a m_isSitting variable.
1250 TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 1251 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1251 } 1252 }
1252 1253
1253 // In the future, these values might need to go global. 1254 // In the future, these values might need to go global.
@@ -1453,7 +1454,7 @@ namespace OpenSim.Region.Framework.Scenes
1453 AddNewMovement(agent_control_v3, q); 1454 AddNewMovement(agent_control_v3, q);
1454 1455
1455 if (update_movementflag) 1456 if (update_movementflag)
1456 UpdateMovementAnimations(); 1457 Animator.UpdateMovementAnimations();
1457 } 1458 }
1458 } 1459 }
1459 1460
@@ -1561,7 +1562,7 @@ namespace OpenSim.Region.Framework.Scenes
1561 } 1562 }
1562 } 1563 }
1563 /// <summary> 1564 /// <summary>
1564 /// Perform the logic necessary to stand the client up. This method also executes 1565 /// Perform the logic necessary to stand the avatar up. This method also executes
1565 /// the stand animation. 1566 /// the stand animation.
1566 /// </summary> 1567 /// </summary>
1567 public void StandUp() 1568 public void StandUp()
@@ -1611,7 +1612,7 @@ namespace OpenSim.Region.Framework.Scenes
1611 } 1612 }
1612 } 1613 }
1613 1614
1614 TrySetMovementAnimation("STAND"); 1615 Animator.TrySetMovementAnimation("STAND");
1615 } 1616 }
1616 1617
1617 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 1618 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -1850,7 +1851,7 @@ namespace OpenSim.Region.Framework.Scenes
1850 Velocity = Vector3.Zero; 1851 Velocity = Vector3.Zero;
1851 RemoveFromPhysicalScene(); 1852 RemoveFromPhysicalScene();
1852 1853
1853 TrySetMovementAnimation(sitAnimation); 1854 Animator.TrySetMovementAnimation(sitAnimation);
1854 SendFullUpdateToAllClients(); 1855 SendFullUpdateToAllClients();
1855 // This may seem stupid, but Our Full updates don't send avatar rotation :P 1856 // This may seem stupid, but Our Full updates don't send avatar rotation :P
1856 // So we're also sending a terse update (which has avatar rotation) 1857 // So we're also sending a terse update (which has avatar rotation)
@@ -1870,6 +1871,7 @@ namespace OpenSim.Region.Framework.Scenes
1870 PhysicsActor.SetAlwaysRun = pSetAlwaysRun; 1871 PhysicsActor.SetAlwaysRun = pSetAlwaysRun;
1871 } 1872 }
1872 } 1873 }
1874
1873 public BinBVHAnimation GenerateRandomAnimation() 1875 public BinBVHAnimation GenerateRandomAnimation()
1874 { 1876 {
1875 int rnditerations = 3; 1877 int rnditerations = 3;
@@ -1917,7 +1919,6 @@ namespace OpenSim.Region.Framework.Scenes
1917 } 1919 }
1918 } 1920 }
1919 1921
1920
1921 AssetBase Animasset = new AssetBase(UUID.Random(), "Random Animation", (sbyte)AssetType.Animation); 1922 AssetBase Animasset = new AssetBase(UUID.Random(), "Random Animation", (sbyte)AssetType.Animation);
1922 Animasset.Data = anim.ToBytes(); 1923 Animasset.Data = anim.ToBytes();
1923 Animasset.Temporary = true; 1924 Animasset.Temporary = true;
@@ -1925,297 +1926,19 @@ namespace OpenSim.Region.Framework.Scenes
1925 Animasset.Description = "dance"; 1926 Animasset.Description = "dance";
1926 //BinBVHAnimation bbvhanim = new BinBVHAnimation(Animasset.Data); 1927 //BinBVHAnimation bbvhanim = new BinBVHAnimation(Animasset.Data);
1927 1928
1928
1929 m_scene.AssetService.Store(Animasset); 1929 m_scene.AssetService.Store(Animasset);
1930 AddAnimation(Animasset.FullID, UUID); 1930 Animator.AddAnimation(Animasset.FullID, UUID);
1931 return anim; 1931 return anim;
1932 } 1932 }
1933 public void AddAnimation(UUID animID, UUID objectID)
1934 {
1935 if (m_isChildAgent)
1936 return;
1937
1938 if (m_animations.Add(animID, m_controllingClient.NextAnimationSequenceNumber, objectID))
1939 SendAnimPack();
1940 }
1941
1942 // Called from scripts
1943 public void AddAnimation(string name, UUID objectID)
1944 {
1945 if (m_isChildAgent)
1946 return;
1947
1948 UUID animID = m_controllingClient.GetDefaultAnimation(name);
1949 if (animID == UUID.Zero)
1950 return;
1951
1952 AddAnimation(animID, objectID);
1953 }
1954
1955 public void RemoveAnimation(UUID animID)
1956 {
1957 if (m_isChildAgent)
1958 return;
1959
1960 if (m_animations.Remove(animID))
1961 SendAnimPack();
1962 }
1963
1964 // Called from scripts
1965 public void RemoveAnimation(string name)
1966 {
1967 if (m_isChildAgent)
1968 return;
1969
1970 UUID animID = m_controllingClient.GetDefaultAnimation(name);
1971 if (animID == UUID.Zero)
1972 return;
1973
1974 RemoveAnimation(animID);
1975 }
1976
1977 public UUID[] GetAnimationArray()
1978 {
1979 UUID[] animIDs;
1980 int[] sequenceNums;
1981 UUID[] objectIDs;
1982 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
1983 return animIDs;
1984 }
1985 1933
1986 public void HandleStartAnim(IClientAPI remoteClient, UUID animID) 1934 public void HandleStartAnim(IClientAPI remoteClient, UUID animID)
1987 { 1935 {
1988 AddAnimation(animID, UUID.Zero); 1936 Animator.AddAnimation(animID, UUID.Zero);
1989 } 1937 }
1990 1938
1991 public void HandleStopAnim(IClientAPI remoteClient, UUID animID) 1939 public void HandleStopAnim(IClientAPI remoteClient, UUID animID)
1992 { 1940 {
1993 RemoveAnimation(animID); 1941 Animator.RemoveAnimation(animID);
1994 }
1995
1996 /// <summary>
1997 /// The movement animation is reserved for "main" animations
1998 /// that are mutually exclusive, e.g. flying and sitting.
1999 /// </summary>
2000 protected void TrySetMovementAnimation(string anim)
2001 {
2002 //m_log.DebugFormat("Updating movement animation to {0}", anim);
2003
2004 if (!m_isChildAgent)
2005 {
2006 if (m_animations.TrySetDefaultAnimation(anim, m_controllingClient.NextAnimationSequenceNumber, UUID.Zero))
2007 {
2008 if (m_scriptEngines != null)
2009 {
2010 lock (m_attachments)
2011 {
2012 foreach (SceneObjectGroup grp in m_attachments)
2013 {
2014 // 16384 is CHANGED_ANIMATION
2015 //
2016 // Send this to all attachment root prims
2017 //
2018 foreach (IScriptModule m in m_scriptEngines)
2019 {
2020 if (m == null) // No script engine loaded
2021 continue;
2022
2023 m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { 16384 });
2024 }
2025 }
2026 }
2027 }
2028 SendAnimPack();
2029 }
2030 }
2031 }
2032
2033 /// <summary>
2034 /// This method determines the proper movement related animation
2035 /// </summary>
2036 public string GetMovementAnimation()
2037 {
2038 const float FALL_DELAY = 0.33f;
2039 const float PREJUMP_DELAY = 0.25f;
2040
2041 #region Inputs
2042
2043 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_AgentControlFlags;
2044 PhysicsActor actor = m_physicsActor;
2045
2046 // Create forward and left vectors from the current avatar rotation
2047 Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_bodyRot);
2048 Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix);
2049 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
2050
2051 // Check control flags
2052 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
2053 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG;
2054 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
2055 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
2056 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
2057 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
2058 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
2059 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
2060 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
2061 //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;
2062
2063 // Direction in which the avatar is trying to move
2064 Vector3 move = Vector3.Zero;
2065 if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
2066 if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; }
2067 if (heldLeft) { move.X += left.X; move.Y += left.Y; }
2068 if (heldRight) { move.X -= left.X; move.Y -= left.Y; }
2069 if (heldUp) { move.Z += 1; }
2070 if (heldDown) { move.Z -= 1; }
2071
2072 // Is the avatar trying to move?
2073// bool moving = (move != Vector3.Zero);
2074 bool jumping = m_animTickJump != 0;
2075
2076 #endregion Inputs
2077
2078 #region Flying
2079
2080 if (actor != null && actor.Flying)
2081 {
2082 m_animTickFall = 0;
2083 m_animTickJump = 0;
2084
2085 if (move.X != 0f || move.Y != 0f)
2086 {
2087 return (m_useFlySlow ? "FLYSLOW" : "FLY");
2088 }
2089 else if (move.Z > 0f)
2090 {
2091 return "HOVER_UP";
2092 }
2093 else if (move.Z < 0f)
2094 {
2095 if (actor != null && actor.IsColliding)
2096 return "LAND";
2097 else
2098 return "HOVER_DOWN";
2099 }
2100 else
2101 {
2102 return "HOVER";
2103 }
2104 }
2105
2106 #endregion Flying
2107
2108 #region Falling/Floating/Landing
2109
2110 if (actor == null || !actor.IsColliding)
2111 {
2112 float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
2113 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;
2114
2115 if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f))
2116 {
2117 // Just started falling
2118 m_animTickFall = Environment.TickCount;
2119 }
2120 else if (!jumping && fallElapsed > FALL_DELAY)
2121 {
2122 // Falling long enough to trigger the animation
2123 return "FALLDOWN";
2124 }
2125
2126 return m_movementAnimation;
2127 }
2128
2129 #endregion Falling/Floating/Landing
2130
2131 #region Ground Movement
2132
2133 if (m_movementAnimation == "FALLDOWN")
2134 {
2135 m_animTickFall = Environment.TickCount;
2136
2137 // TODO: SOFT_LAND support
2138 return "LAND";
2139 }
2140 else if (m_movementAnimation == "LAND")
2141 {
2142 float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
2143
2144 if (landElapsed <= FALL_DELAY)
2145 return "LAND";
2146 }
2147
2148 m_animTickFall = 0;
2149
2150 if (move.Z > 0f)
2151 {
2152 // Jumping
2153 if (!jumping)
2154 {
2155 // Begin prejump
2156 m_animTickJump = Environment.TickCount;
2157 return "PREJUMP";
2158 }
2159 else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f)
2160 {
2161 // Start actual jump
2162 if (m_animTickJump == -1)
2163 {
2164 // Already jumping! End the current jump
2165 m_animTickJump = 0;
2166 return "JUMP";
2167 }
2168
2169 m_animTickJump = -1;
2170 return "JUMP";
2171 }
2172 }
2173 else
2174 {
2175 // Not jumping
2176 m_animTickJump = 0;
2177
2178 if (move.X != 0f || move.Y != 0f)
2179 {
2180 // Walking / crouchwalking / running
2181 if (move.Z < 0f)
2182 return "CROUCHWALK";
2183 else if (m_setAlwaysRun)
2184 return "RUN";
2185 else
2186 return "WALK";
2187 }
2188 else
2189 {
2190 // Not walking
2191 if (move.Z < 0f)
2192 return "CROUCH";
2193 else
2194 return "STAND";
2195 }
2196 }
2197
2198 #endregion Ground Movement
2199
2200 return m_movementAnimation;
2201 }
2202
2203 /// <summary>
2204 /// Update the movement animation of this avatar according to its current state
2205 /// </summary>
2206 protected void UpdateMovementAnimations()
2207 {
2208 m_movementAnimation = GetMovementAnimation();
2209
2210 if (m_movementAnimation == "PREJUMP" && !m_usePreJump)
2211 {
2212 // This was the previous behavior before PREJUMP
2213 TrySetMovementAnimation("JUMP");
2214 }
2215 else
2216 {
2217 TrySetMovementAnimation(m_movementAnimation);
2218 }
2219 } 1942 }
2220 1943
2221 /// <summary> 1944 /// <summary>
@@ -2289,8 +2012,8 @@ namespace OpenSim.Region.Framework.Scenes
2289 direc.Z *= 3.0f; 2012 direc.Z *= 3.0f;
2290 2013
2291 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2014 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2292 TrySetMovementAnimation("PREJUMP"); 2015 Animator.TrySetMovementAnimation("PREJUMP");
2293 TrySetMovementAnimation("JUMP"); 2016 Animator.TrySetMovementAnimation("JUMP");
2294 } 2017 }
2295 } 2018 }
2296 } 2019 }
@@ -2504,7 +2227,7 @@ namespace OpenSim.Region.Framework.Scenes
2504 { 2227 {
2505 avatar.SendFullUpdateToOtherClient(this); 2228 avatar.SendFullUpdateToOtherClient(this);
2506 avatar.SendAppearanceToOtherAgent(this); 2229 avatar.SendAppearanceToOtherAgent(this);
2507 avatar.SendAnimPackToClient(ControllingClient); 2230 avatar.Animator.SendAnimPackToClient(ControllingClient);
2508 } 2231 }
2509 } 2232 }
2510 } 2233 }
@@ -2512,7 +2235,7 @@ namespace OpenSim.Region.Framework.Scenes
2512 m_scene.StatsReporter.AddAgentUpdates(avatars.Length); 2235 m_scene.StatsReporter.AddAgentUpdates(avatars.Length);
2513 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2236 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2514 2237
2515 //SendAnimPack(); 2238 //Animator.SendAnimPack();
2516 } 2239 }
2517 2240
2518 public void SendFullUpdateToAllClients() 2241 public void SendFullUpdateToAllClients()
@@ -2529,7 +2252,7 @@ namespace OpenSim.Region.Framework.Scenes
2529 m_scene.StatsReporter.AddAgentUpdates(avatars.Count); 2252 m_scene.StatsReporter.AddAgentUpdates(avatars.Count);
2530 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2253 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2531 2254
2532 SendAnimPack(); 2255 Animator.SendAnimPack();
2533 } 2256 }
2534 2257
2535 /// <summary> 2258 /// <summary>
@@ -2646,7 +2369,7 @@ namespace OpenSim.Region.Framework.Scenes
2646 SendAppearanceToAllOtherAgents(); 2369 SendAppearanceToAllOtherAgents();
2647 if (!m_startAnimationSet) 2370 if (!m_startAnimationSet)
2648 { 2371 {
2649 UpdateMovementAnimations(); 2372 Animator.UpdateMovementAnimations();
2650 m_startAnimationSet = true; 2373 m_startAnimationSet = true;
2651 } 2374 }
2652 2375
@@ -2674,54 +2397,6 @@ namespace OpenSim.Region.Framework.Scenes
2674 set { m_appearance = value; } 2397 set { m_appearance = value; }
2675 } 2398 }
2676 2399
2677 /// <summary>
2678 ///
2679 /// </summary>
2680 /// <param name="animations"></param>
2681 /// <param name="seqs"></param>
2682 /// <param name="objectIDs"></param>
2683 public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
2684 {
2685 if (m_isChildAgent)
2686 return;
2687
2688 m_scene.ForEachClient(
2689 delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); });
2690 }
2691
2692 public void SendAnimPackToClient(IClientAPI client)
2693 {
2694 if (m_isChildAgent)
2695 return;
2696 UUID[] animIDs;
2697 int[] sequenceNums;
2698 UUID[] objectIDs;
2699
2700 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
2701
2702 client.SendAnimations(animIDs, sequenceNums, m_controllingClient.AgentId, objectIDs);
2703 }
2704
2705 /// <summary>
2706 /// Send animation information about this avatar to all clients.
2707 /// </summary>
2708 public void SendAnimPack()
2709 {
2710 //m_log.Debug("Sending animation pack to all");
2711
2712 if (m_isChildAgent)
2713 return;
2714
2715 UUID[] animIDs;
2716 int[] sequenceNums;
2717 UUID[] objectIDs;
2718
2719 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
2720
2721 SendAnimPack(animIDs, sequenceNums, objectIDs);
2722 }
2723
2724
2725 #endregion 2400 #endregion
2726 2401
2727 #region Significant Movement Method 2402 #region Significant Movement Method
@@ -2919,13 +2594,9 @@ namespace OpenSim.Region.Framework.Scenes
2919 public void Reset() 2594 public void Reset()
2920 { 2595 {
2921 // Put the child agent back at the center 2596 // Put the child agent back at the center
2922 AbsolutePosition = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); 2597 AbsolutePosition
2923 ResetAnimations(); 2598 = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70);
2924 } 2599 Animator.ResetAnimations();
2925
2926 public void ResetAnimations()
2927 {
2928 m_animations.Clear();
2929 } 2600 }
2930 2601
2931 /// <summary> 2602 /// <summary>
@@ -3149,7 +2820,7 @@ namespace OpenSim.Region.Framework.Scenes
3149 // Animations 2820 // Animations
3150 try 2821 try
3151 { 2822 {
3152 cAgent.Anims = m_animations.ToArray(); 2823 cAgent.Anims = Animator.Animations.ToArray();
3153 } 2824 }
3154 catch { } 2825 catch { }
3155 2826
@@ -3228,15 +2899,13 @@ namespace OpenSim.Region.Framework.Scenes
3228 // Animations 2899 // Animations
3229 try 2900 try
3230 { 2901 {
3231 m_animations.Clear(); 2902 Animator.ResetAnimations();
3232 m_animations.FromArray(cAgent.Anims); 2903 Animator.Animations.FromArray(cAgent.Anims);
3233 } 2904 }
3234 catch { } 2905 catch { }
3235 2906
3236 //cAgent.GroupID = ?? 2907 //cAgent.GroupID = ??
3237 //Groups??? 2908 //Groups???
3238
3239
3240 } 2909 }
3241 2910
3242 public bool CopyAgent(out IAgentData agent) 2911 public bool CopyAgent(out IAgentData agent)
@@ -3318,7 +2987,7 @@ namespace OpenSim.Region.Framework.Scenes
3318 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 2987 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
3319 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( 2988 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3320 // as of this comment the interval is set in AddToPhysicalScene 2989 // as of this comment the interval is set in AddToPhysicalScene
3321 UpdateMovementAnimations(); 2990 Animator.UpdateMovementAnimations();
3322 2991
3323 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 2992 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3324 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 2993 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
@@ -3327,7 +2996,7 @@ namespace OpenSim.Region.Framework.Scenes
3327 2996
3328 if (coldata.Count != 0) 2997 if (coldata.Count != 0)
3329 { 2998 {
3330 switch (m_movementAnimation) 2999 switch (Animator.CurrentMovementAnimation)
3331 { 3000 {
3332 case "STAND": 3001 case "STAND":
3333 case "WALK": 3002 case "WALK":
@@ -3415,6 +3084,7 @@ namespace OpenSim.Region.Framework.Scenes
3415 } 3084 }
3416 m_attachments.Clear(); 3085 m_attachments.Clear();
3417 } 3086 }
3087
3418 lock (m_knownChildRegions) 3088 lock (m_knownChildRegions)
3419 { 3089 {
3420 m_knownChildRegions.Clear(); 3090 m_knownChildRegions.Clear();
@@ -3425,6 +3095,7 @@ namespace OpenSim.Region.Framework.Scenes
3425 m_reprioritization_timer.Enabled = false; 3095 m_reprioritization_timer.Enabled = false;
3426 m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); 3096 m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize);
3427 } 3097 }
3098
3428 // I don't get it but mono crashes when you try to dispose of this timer, 3099 // I don't get it but mono crashes when you try to dispose of this timer,
3429 // unsetting the elapsed callback should be enough to allow for cleanup however. 3100 // unsetting the elapsed callback should be enough to allow for cleanup however.
3430 //m_reprioritizationTimer.Dispose(); 3101 //m_reprioritizationTimer.Dispose();
@@ -3497,6 +3168,35 @@ namespace OpenSim.Region.Framework.Scenes
3497 return true; 3168 return true;
3498 } 3169 }
3499 3170
3171 /// <summary>
3172 /// Send a script event to this scene presence's attachments
3173 /// </summary>
3174 /// <param name="eventName">The name of the event</param>
3175 /// <param name="args">The arguments for the event</param>
3176 public void SendScriptEventToAttachments(string eventName, Object[] args)
3177 {
3178 if (m_scriptEngines != null)
3179 {
3180 lock (m_attachments)
3181 {
3182 foreach (SceneObjectGroup grp in m_attachments)
3183 {
3184 // 16384 is CHANGED_ANIMATION
3185 //
3186 // Send this to all attachment root prims
3187 //
3188 foreach (IScriptModule m in m_scriptEngines)
3189 {
3190 if (m == null) // No script engine loaded
3191 continue;
3192
3193 m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { 16384 });
3194 }
3195 }
3196 }
3197 }
3198 }
3199
3500 public bool CrossAttachmentsIntoNewRegion(ulong regionHandle, bool silent) 3200 public bool CrossAttachmentsIntoNewRegion(ulong regionHandle, bool silent)
3501 { 3201 {
3502 lock (m_attachments) 3202 lock (m_attachments)
@@ -3939,4 +3639,4 @@ namespace OpenSim.Region.Framework.Scenes
3939 } 3639 }
3940 } 3640 }
3941 } 3641 }
3942} 3642} \ No newline at end of file