aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Animation
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs388
-rw-r--r--OpenSim/Region/Framework/Scenes/AnimationSet.cs21
2 files changed, 399 insertions, 10 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 }