aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Animation
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Animation')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/MovementAnimationOverrides.cs101
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs382
2 files changed, 361 insertions, 122 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/MovementAnimationOverrides.cs b/OpenSim/Region/Framework/Scenes/Animation/MovementAnimationOverrides.cs
new file mode 100644
index 0000000..d59678b
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Animation/MovementAnimationOverrides.cs
@@ -0,0 +1,101 @@
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 System.Xml;
30using System.Collections.Generic;
31using System.Reflection;
32using System.Threading;
33using System.Timers;
34using Timer = System.Timers.Timer;
35using OpenMetaverse;
36using log4net;
37using Nini.Config;
38using OpenSim.Framework;
39using OpenSim.Framework.Client;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes.Animation;
42using OpenSim.Region.Framework.Scenes.Types;
43using OpenSim.Region.PhysicsModules.SharedBase;
44using GridRegion = OpenSim.Services.Interfaces.GridRegion;
45using OpenSim.Services.Interfaces;
46using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags;
47
48namespace OpenSim.Region.Framework.Scenes
49{
50 public class MovementAnimationOverrides
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private Dictionary<string, UUID> m_overrides = new Dictionary<string, UUID>();
56 public void SetOverride(string state, UUID animID)
57 {
58 if (animID == UUID.Zero)
59 {
60 if (state == "ALL")
61 m_overrides.Clear();
62 else
63 m_overrides.Remove(state);
64 return;
65 }
66
67 m_log.DebugFormat("Setting override for {0} to {1}", state, animID);
68
69 lock (m_overrides)
70 m_overrides[state] = animID;
71 }
72
73 public UUID GetOverriddenAnimation(string state)
74 {
75 lock (m_overrides)
76 {
77 if (m_overrides.ContainsKey(state))
78 return m_overrides[state];
79 }
80
81 return UUID.Zero;
82 }
83
84 public Dictionary<string, UUID> CloneAOPairs()
85 {
86 lock (m_overrides)
87 {
88 return new Dictionary<string, UUID>(m_overrides);
89 }
90 }
91
92 public void CopyAOPairsFrom(Dictionary<string, UUID> src)
93 {
94 lock (m_overrides)
95 {
96 m_overrides.Clear();
97 m_overrides = new Dictionary<string, UUID>(src);
98 }
99 }
100 }
101}
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 6d51029..13d4562 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -48,7 +48,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
48 48
49 public AnimationSet Animations 49 public AnimationSet Animations
50 { 50 {
51 get { return m_animations; } 51 get { return m_animations; }
52 } 52 }
53 protected AnimationSet m_animations = new AnimationSet(); 53 protected AnimationSet m_animations = new AnimationSet();
54 54
@@ -56,39 +56,42 @@ namespace OpenSim.Region.Framework.Scenes.Animation
56 /// The current movement animation 56 /// The current movement animation
57 /// </value> 57 /// </value>
58 public string CurrentMovementAnimation { get; private set; } 58 public string CurrentMovementAnimation { get; private set; }
59 59
60 private int m_animTickFall; 60 private int m_animTickFall;
61 public int m_animTickJump; // ScenePresence has to see this to control +Z force 61 private int m_animTickLand;
62 public bool m_jumping = false; 62 private int m_animTickJump;
63 public float m_jumpVelocity = 0f; 63
64// private int m_landing = 0; 64 public bool m_jumping = false;
65
66 // private int m_landing = 0;
65 67
66 /// <summary> 68 /// <summary>
67 /// Is the avatar falling? 69 /// Is the avatar falling?
68 /// </summary> 70 /// </summary>
69 public bool Falling { get; private set; } 71 public bool Falling { get; private set; }
70 72
71 private float m_fallHeight; 73 private float m_lastFallVelocity;
72 74
73 /// <value> 75 /// <value>
74 /// The scene presence that this animator applies to 76 /// The scene presence that this animator applies to
75 /// </value> 77 /// </value>
76 protected ScenePresence m_scenePresence; 78 protected ScenePresence m_scenePresence;
77 79
78 public ScenePresenceAnimator(ScenePresence sp) 80 public ScenePresenceAnimator(ScenePresence sp)
79 { 81 {
80 m_scenePresence = sp; 82 m_scenePresence = sp;
81 CurrentMovementAnimation = "CROUCH"; 83 CurrentMovementAnimation = "CROUCH";
82 } 84 }
83 85
84 public void AddAnimation(UUID animID, UUID objectID) 86 public void AddAnimation(UUID animID, UUID objectID)
85 { 87 {
86 if (m_scenePresence.IsChildAgent) 88 if (m_scenePresence.IsChildAgent)
87 return; 89 return;
88 90
91 // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name);
89 if (m_scenePresence.Scene.DebugAnimations) 92 if (m_scenePresence.Scene.DebugAnimations)
90 m_log.DebugFormat( 93 m_log.DebugFormat(
91 "[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", 94 "[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}",
92 GetAnimName(animID), animID, m_scenePresence.Name); 95 GetAnimName(animID), animID, m_scenePresence.Name);
93 96
94 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID)) 97 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID))
@@ -110,7 +113,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
110 if (animID == UUID.Zero) 113 if (animID == UUID.Zero)
111 return; 114 return;
112 115
113// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name); 116 // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name);
114 117
115 AddAnimation(animID, objectID); 118 AddAnimation(animID, objectID);
116 } 119 }
@@ -130,7 +133,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
130 133
131 if (m_scenePresence.Scene.DebugAnimations) 134 if (m_scenePresence.Scene.DebugAnimations)
132 m_log.DebugFormat( 135 m_log.DebugFormat(
133 "[SCENE PRESENCE ANIMATOR]: Removing animation {0} {1} for {2}", 136 "[SCENE PRESENCE ANIMATOR]: Removing animation {0} {1} for {2}",
134 GetAnimName(animID), animID, m_scenePresence.Name); 137 GetAnimName(animID), animID, m_scenePresence.Name);
135 138
136 if (m_animations.Remove(animID, allowNoDefault)) 139 if (m_animations.Remove(animID, allowNoDefault))
@@ -140,6 +143,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation
140 } 143 }
141 } 144 }
142 145
146 public void avnChangeAnim(UUID animID, bool addRemove, bool sendPack)
147 {
148 if (m_scenePresence.IsChildAgent)
149 return;
150
151 if (animID != UUID.Zero)
152 {
153 if (addRemove)
154 m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero);
155 else
156 m_animations.Remove(animID, false);
157 }
158 if (sendPack)
159 SendAnimPack();
160 }
161
143 // Called from scripts 162 // Called from scripts
144 public void RemoveAnimation(string name) 163 public void RemoveAnimation(string name)
145 { 164 {
@@ -164,12 +183,19 @@ namespace OpenSim.Region.Framework.Scenes.Animation
164 183
165 m_animations.Clear(); 184 m_animations.Clear();
166 } 185 }
167 186
187
188 UUID aoSitGndAnim = UUID.Zero;
189
168 /// <summary> 190 /// <summary>
169 /// The movement animation is reserved for "main" animations 191 /// The movement animation is reserved for "main" animations
170 /// that are mutually exclusive, e.g. flying and sitting. 192 /// that are mutually exclusive, e.g. flying and sitting.
171 /// </summary> 193 /// </summary>
172 /// <returns>'true' if the animation was updated</returns> 194 /// <returns>'true' if the animation was updated</returns>
195 ///
196
197
198
173 public bool TrySetMovementAnimation(string anim) 199 public bool TrySetMovementAnimation(string anim)
174 { 200 {
175 bool ret = false; 201 bool ret = false;
@@ -179,17 +205,50 @@ namespace OpenSim.Region.Framework.Scenes.Animation
179// "[SCENE PRESENCE ANIMATOR]: Setting movement animation {0} for {1}", 205// "[SCENE PRESENCE ANIMATOR]: Setting movement animation {0} for {1}",
180// anim, m_scenePresence.Name); 206// anim, m_scenePresence.Name);
181 207
182 if (m_animations.TrySetDefaultAnimation( 208 if (aoSitGndAnim != UUID.Zero)
183 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) 209 {
210 avnChangeAnim(aoSitGndAnim, false, true);
211 aoSitGndAnim = UUID.Zero;
212 }
213
214 UUID overridenAnim = m_scenePresence.Overrides.GetOverriddenAnimation(anim);
215 if (overridenAnim != UUID.Zero)
184 { 216 {
217 if (anim == "SITGROUND")
218 {
219 UUID defsit = DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"];
220 if (defsit == UUID.Zero)
221 return false;
222 m_animations.SetDefaultAnimation(defsit, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID);
223 aoSitGndAnim = overridenAnim;
224 avnChangeAnim(overridenAnim, true, false);
225 }
226 else
227 {
228 m_animations.SetDefaultAnimation(overridenAnim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID);
229 }
230 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION });
231 SendAnimPack();
232 ret = true;
233 }
234 else
235 {
236 // translate sit and sitground state animations
237 if (anim == "SIT" || anim == "SITGROUND")
238 anim = m_scenePresence.sitAnimation;
239
240 if (m_animations.TrySetDefaultAnimation(
241 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
242 {
185// m_log.DebugFormat( 243// m_log.DebugFormat(
186// "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}", 244// "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}",
187// anim, m_scenePresence.Name); 245// anim, m_scenePresence.Name);
188 246
189 // 16384 is CHANGED_ANIMATION 247 // 16384 is CHANGED_ANIMATION
190 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION}); 248 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION });
191 SendAnimPack(); 249 SendAnimPack();
192 ret = true; 250 ret = true;
251 }
193 } 252 }
194 } 253 }
195 else 254 else
@@ -201,78 +260,119 @@ namespace OpenSim.Region.Framework.Scenes.Animation
201 return ret; 260 return ret;
202 } 261 }
203 262
263 public enum motionControlStates : byte
264 {
265 sitted = 0,
266 flying,
267 falling,
268 jumping,
269 landing,
270 onsurface
271 }
272
273 public motionControlStates currentControlState = motionControlStates.onsurface;
274
204 /// <summary> 275 /// <summary>
205 /// This method determines the proper movement related animation 276 /// This method determines the proper movement related animation
206 /// </summary> 277 /// </summary>
207 private string DetermineMovementAnimation() 278 private string DetermineMovementAnimation()
208 { 279 {
209 const float FALL_DELAY = 800f; 280 const int FALL_DELAY = 800;
210 const float PREJUMP_DELAY = 200f; 281 const int PREJUMP_DELAY = 200;
211 const float JUMP_PERIOD = 800f; 282 const int JUMP_PERIOD = 800;
212 #region Inputs 283 #region Inputs
213 284
285 if (m_scenePresence.IsInTransit)
286 return CurrentMovementAnimation;
287
288 if (m_scenePresence.SitGround)
289 {
290 currentControlState = motionControlStates.sitted;
291 return "SITGROUND";
292 }
293 if (m_scenePresence.ParentID != 0 || m_scenePresence.ParentUUID != UUID.Zero)
294 {
295 currentControlState = motionControlStates.sitted;
296 return "SIT";
297 }
298
214 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; 299 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
215 PhysicsActor actor = m_scenePresence.PhysicsActor; 300 PhysicsActor actor = m_scenePresence.PhysicsActor;
216 301
217 // Create forward and left vectors from the current avatar rotation 302 const AgentManager.ControlFlags ANYXYMASK = (
218 Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation); 303 AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS |
219 Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix); 304 AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG |
220 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 305 AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS |
306 AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG
307 );
221 308
222 // Check control flags 309 // Check control flags
223 bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS); 310 /* not in use
224 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); 311 bool heldForward = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)) != 0);
225 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); 312 bool heldBack = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG)) != 0);
226 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG); 313 bool heldLeft = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS)) != 0);
314 bool heldRight = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG)) != 0);
315 */
227 bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 316 bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
228 bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; 317 bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
229 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 318 // bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS)) != 0);
230 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; 319 // excluded nudge up so it doesn't trigger jump state
320 bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS)) != 0);
321 bool heldDown = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG)) != 0);
231 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; 322 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
232 //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK; 323 //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;
233 if (heldForward || heldBack || heldLeft || heldRight || heldUp || heldDown) 324
325 bool heldOnXY = ((controlFlags & ANYXYMASK) != 0);
326 if (heldOnXY || heldUp || heldDown)
234 { 327 {
235 heldTurnLeft = false; 328 heldTurnLeft = false;
236 heldTurnRight = false; 329 heldTurnRight = false;
237 } 330 }
238 331
239 // Direction in which the avatar is trying to move
240 Vector3 move = Vector3.Zero;
241 if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
242 if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; }
243 if (heldLeft) { move.X += left.X; move.Y += left.Y; }
244 if (heldRight) { move.X -= left.X; move.Y -= left.Y; }
245 if (heldUp) { move.Z += 1; }
246 if (heldDown) { move.Z -= 1; }
247
248 // Is the avatar trying to move?
249// bool moving = (move != Vector3.Zero);
250 #endregion Inputs 332 #endregion Inputs
251 333
334 // no physics actor case
335 if (actor == null)
336 {
337 // well what to do?
338
339 currentControlState = motionControlStates.onsurface;
340 if (heldOnXY)
341 return "WALK";
342
343 return "STAND";
344 }
345
252 #region Flying 346 #region Flying
253 347
254 if (actor != null && actor.Flying) 348 bool isColliding = actor.IsColliding;
349
350 if (actor.Flying)
255 { 351 {
256 m_animTickFall = 0; 352 m_animTickFall = 0;
257 m_animTickJump = 0; 353 m_animTickJump = 0;
258 m_jumping = false; 354 m_jumping = false;
259 Falling = false; 355 Falling = false;
260 m_jumpVelocity = 0f;
261 actor.Selected = false;
262 m_fallHeight = actor.Position.Z; // save latest flying height
263 356
264 if (move.X != 0f || move.Y != 0f) 357 currentControlState = motionControlStates.flying;
358
359 if (heldOnXY)
265 { 360 {
266 return (m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY"); 361 return (m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
267 } 362 }
268 else if (move.Z > 0f) 363 else if (heldUp)
269 { 364 {
270 return "HOVER_UP"; 365 return "HOVER_UP";
271 } 366 }
272 else if (move.Z < 0f) 367 else if (heldDown)
273 { 368 {
274 if (actor != null && actor.IsColliding) 369 if (isColliding)
370 {
371 actor.Flying = false;
372 currentControlState = motionControlStates.landing;
373 m_animTickLand = Environment.TickCount;
275 return "LAND"; 374 return "LAND";
375 }
276 else 376 else
277 return "HOVER_DOWN"; 377 return "HOVER_DOWN";
278 } 378 }
@@ -281,128 +381,151 @@ namespace OpenSim.Region.Framework.Scenes.Animation
281 return "HOVER"; 381 return "HOVER";
282 } 382 }
283 } 383 }
384 else
385 {
386 if (isColliding && currentControlState == motionControlStates.flying)
387 {
388 currentControlState = motionControlStates.landing;
389 m_animTickLand = Environment.TickCount;
390 return "LAND";
391 }
392 }
284 393
285 #endregion Flying 394 #endregion Flying
286 395
287 #region Falling/Floating/Landing 396 #region Falling/Floating/Landing
288 397
289 if ((actor == null || !actor.IsColliding) && !m_jumping) 398 if (!isColliding && currentControlState != motionControlStates.jumping)
290 { 399 {
291 float fallElapsed = (float)(Environment.TickCount - m_animTickFall); 400 float fallVelocity = actor.Velocity.Z;
292 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;
293 401
294 if (!m_jumping && (fallVelocity < -3.0f)) 402 // if stable on Hover assume falling
403 if(actor.PIDHoverActive && fallVelocity < 0.05f)
404 {
405 Falling = true;
406 currentControlState = motionControlStates.falling;
407 m_lastFallVelocity = fallVelocity;
408 return "FALLDOWN";
409 }
410
411 if (fallVelocity < -2.5f)
295 Falling = true; 412 Falling = true;
296 413
297 if (m_animTickFall == 0 || (fallVelocity >= 0.0f)) 414 if (m_animTickFall == 0 || (fallVelocity >= -0.5f))
298 { 415 {
299 // not falling yet, or going up
300 // reset start of fall time
301 m_animTickFall = Environment.TickCount; 416 m_animTickFall = Environment.TickCount;
302 } 417 }
303 else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) && (m_scenePresence.WasFlying)) 418 else
304 { 419 {
305 // Falling long enough to trigger the animation 420 int fallElapsed = (Environment.TickCount - m_animTickFall);
306 return "FALLDOWN"; 421 if ((fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f))
422 {
423 currentControlState = motionControlStates.falling;
424 m_lastFallVelocity = fallVelocity;
425 // Falling long enough to trigger the animation
426 return "FALLDOWN";
427 }
307 } 428 }
308 429
309 // Check if the user has stopped walking just now 430 // Check if the user has stopped walking just now
310 if (CurrentMovementAnimation == "WALK" && (move == Vector3.Zero)) 431 if (CurrentMovementAnimation == "WALK" && !heldOnXY && !heldDown && !heldUp)
311 return "STAND"; 432 return "STAND";
312 433
313 return CurrentMovementAnimation; 434 return CurrentMovementAnimation;
314 } 435 }
315 436
316 #endregion Falling/Floating/Landing 437 m_animTickFall = 0;
317 438
439 #endregion Falling/Floating/Landing
318 440
319 #region Jumping // section added for jumping... 441 #region Jumping // section added for jumping...
320 442
321 int jumptime; 443 if (isColliding && heldUp && currentControlState != motionControlStates.jumping && !actor.PIDHoverActive)
322 jumptime = Environment.TickCount - m_animTickJump;
323
324 if ((move.Z > 0f) && (!m_jumping))
325 { 444 {
326 // Start jumping, prejump 445 // Start jumping, prejump
327 m_animTickFall = 0; 446 currentControlState = motionControlStates.jumping;
328 m_jumping = true; 447 m_jumping = true;
329 Falling = false; 448 Falling = false;
330 actor.Selected = true; // borrowed for jumping flag
331 m_animTickJump = Environment.TickCount; 449 m_animTickJump = Environment.TickCount;
332 m_jumpVelocity = 0.35f;
333 return "PREJUMP"; 450 return "PREJUMP";
334 } 451 }
335 452
336 if (m_jumping) 453 if (currentControlState == motionControlStates.jumping)
337 { 454 {
455 int jumptime = Environment.TickCount - m_animTickJump;
338 if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding) 456 if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding)
339 { 457 {
340 // end jumping 458 // end jumping
341 m_jumping = false; 459 m_jumping = false;
342 Falling = false; 460 Falling = false;
343 actor.Selected = false; // borrowed for jumping flag 461 actor.Selected = false; // borrowed for jumping flag
344 m_jumpVelocity = 0f; 462 m_animTickLand = Environment.TickCount;
345 m_animTickFall = Environment.TickCount; 463 currentControlState = motionControlStates.landing;
346 return "LAND"; 464 return "LAND";
347 } 465 }
348 else if (jumptime > JUMP_PERIOD) 466 else if (jumptime > JUMP_PERIOD)
349 { 467 {
350 // jump down 468 // jump down
351 m_jumpVelocity = 0f;
352 return "JUMP"; 469 return "JUMP";
353 } 470 }
354 else if (jumptime > PREJUMP_DELAY) 471 else if (jumptime > PREJUMP_DELAY)
355 { 472 {
356 // jump up 473 // jump up
357 m_jumping = true; 474 m_jumping = true;
358 m_jumpVelocity = 10f;
359 return "JUMP"; 475 return "JUMP";
360 } 476 }
477 return CurrentMovementAnimation;
361 } 478 }
362 479
363 #endregion Jumping 480 #endregion Jumping
364 481
365 #region Ground Movement 482 #region Ground Movement
366 483
367 if (CurrentMovementAnimation == "FALLDOWN") 484 if (currentControlState == motionControlStates.falling)
368 { 485 {
369 Falling = false; 486 Falling = false;
370 m_animTickFall = Environment.TickCount; 487 currentControlState = motionControlStates.landing;
488 m_animTickLand = Environment.TickCount;
371 // TODO: SOFT_LAND support 489 // TODO: SOFT_LAND support
372 float fallHeight = m_fallHeight - actor.Position.Z; 490 float fallVsq = m_lastFallVelocity * m_lastFallVelocity;
373 if (fallHeight > 15.0f) 491 if (fallVsq > 300f) // aprox 20*h
374 return "STANDUP"; 492 return "STANDUP";
375 else if (fallHeight > 8.0f) 493 else if (fallVsq > 160f)
376 return "SOFT_LAND"; 494 return "SOFT_LAND";
377 else 495 else
378 return "LAND"; 496 return "LAND";
379 } 497 }
380 else if ((CurrentMovementAnimation == "LAND") || (CurrentMovementAnimation == "SOFT_LAND") || (CurrentMovementAnimation == "STANDUP")) 498
499
500 if (currentControlState == motionControlStates.landing)
381 { 501 {
382 int landElapsed = Environment.TickCount - m_animTickFall; 502 Falling = false;
503 int landElapsed = Environment.TickCount - m_animTickLand;
383 int limit = 1000; 504 int limit = 1000;
384 if (CurrentMovementAnimation == "LAND") 505 if (CurrentMovementAnimation == "LAND")
385 limit = 350; 506 limit = 350;
386 // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client 507 // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client
387 508
388 if ((m_animTickFall != 0) && (landElapsed <= limit)) 509 if ((m_animTickLand != 0) && (landElapsed <= limit))
389 { 510 {
390 return CurrentMovementAnimation; 511 return CurrentMovementAnimation;
391 } 512 }
392 else 513 else
393 { 514 {
394 m_fallHeight = actor.Position.Z; // save latest flying height 515 currentControlState = motionControlStates.onsurface;
516 m_animTickLand = 0;
395 return "STAND"; 517 return "STAND";
396 } 518 }
397 } 519 }
398 520
399 // next section moved outside paren. and realigned for jumping 521 // next section moved outside paren. and realigned for jumping
400 if (move.X != 0f || move.Y != 0f) 522
523 if (heldOnXY)
401 { 524 {
402 m_fallHeight = actor.Position.Z; // save latest flying height 525 currentControlState = motionControlStates.onsurface;
403 Falling = false; 526 Falling = false;
404 // Walking / crouchwalking / running 527 // Walking / crouchwalking / running
405 if (move.Z < 0f) 528 if (heldDown)
406 { 529 {
407 return "CROUCHWALK"; 530 return "CROUCHWALK";
408 } 531 }
@@ -416,11 +539,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
416 return "WALK"; 539 return "WALK";
417 } 540 }
418 } 541 }
419 else if (!m_jumping) 542 else
420 { 543 {
544 currentControlState = motionControlStates.onsurface;
421 Falling = false; 545 Falling = false;
422 // Not walking 546 // Not walking
423 if (move.Z < 0) 547 if (heldDown)
424 return "CROUCH"; 548 return "CROUCH";
425 else if (heldTurnLeft) 549 else if (heldTurnLeft)
426 return "TURNLEFT"; 550 return "TURNLEFT";
@@ -431,8 +555,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation
431 } 555 }
432 #endregion Ground Movement 556 #endregion Ground Movement
433 557
434 Falling = false;
435
436 return CurrentMovementAnimation; 558 return CurrentMovementAnimation;
437 } 559 }
438 560
@@ -442,7 +564,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
442 /// <returns>'true' if the animation was changed</returns> 564 /// <returns>'true' if the animation was changed</returns>
443 public bool UpdateMovementAnimations() 565 public bool UpdateMovementAnimations()
444 { 566 {
445// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Updating movement animations for {0}", m_scenePresence.Name); 567 // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Updating movement animations for {0}", m_scenePresence.Name);
446 568
447 bool ret = false; 569 bool ret = false;
448 lock (m_animations) 570 lock (m_animations)
@@ -450,7 +572,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
450 string newMovementAnimation = DetermineMovementAnimation(); 572 string newMovementAnimation = DetermineMovementAnimation();
451 if (CurrentMovementAnimation != newMovementAnimation) 573 if (CurrentMovementAnimation != newMovementAnimation)
452 { 574 {
453 CurrentMovementAnimation = DetermineMovementAnimation(); 575 CurrentMovementAnimation = newMovementAnimation;
454 576
455// m_log.DebugFormat( 577// m_log.DebugFormat(
456// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()", 578// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()",
@@ -464,6 +586,24 @@ namespace OpenSim.Region.Framework.Scenes.Animation
464 return ret; 586 return ret;
465 } 587 }
466 588
589 public bool ForceUpdateMovementAnimations()
590 {
591 lock (m_animations)
592 {
593 CurrentMovementAnimation = DetermineMovementAnimation();
594 return TrySetMovementAnimation(CurrentMovementAnimation);
595 }
596 }
597
598 public bool SetMovementAnimations(string motionState)
599 {
600 lock (m_animations)
601 {
602 CurrentMovementAnimation = motionState;
603 return TrySetMovementAnimation(CurrentMovementAnimation);
604 }
605 }
606
467 public UUID[] GetAnimationArray() 607 public UUID[] GetAnimationArray()
468 { 608 {
469 UUID[] animIDs; 609 UUID[] animIDs;
@@ -472,19 +612,19 @@ namespace OpenSim.Region.Framework.Scenes.Animation
472 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs); 612 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
473 return animIDs; 613 return animIDs;
474 } 614 }
475 615
476 public BinBVHAnimation GenerateRandomAnimation() 616 public BinBVHAnimation GenerateRandomAnimation()
477 { 617 {
478 int rnditerations = 3; 618 int rnditerations = 3;
479 BinBVHAnimation anim = new BinBVHAnimation(); 619 BinBVHAnimation anim = new BinBVHAnimation();
480 List<string> parts = new List<string>(); 620 List<string> parts = new List<string>();
481 parts.Add("mPelvis");parts.Add("mHead");parts.Add("mTorso"); 621 parts.Add("mPelvis"); parts.Add("mHead"); parts.Add("mTorso");
482 parts.Add("mHipLeft");parts.Add("mHipRight");parts.Add("mHipLeft");parts.Add("mKneeLeft"); 622 parts.Add("mHipLeft"); parts.Add("mHipRight"); parts.Add("mHipLeft"); parts.Add("mKneeLeft");
483 parts.Add("mKneeRight");parts.Add("mCollarLeft");parts.Add("mCollarRight");parts.Add("mNeck"); 623 parts.Add("mKneeRight"); parts.Add("mCollarLeft"); parts.Add("mCollarRight"); parts.Add("mNeck");
484 parts.Add("mElbowLeft");parts.Add("mElbowRight");parts.Add("mWristLeft");parts.Add("mWristRight"); 624 parts.Add("mElbowLeft"); parts.Add("mElbowRight"); parts.Add("mWristLeft"); parts.Add("mWristRight");
485 parts.Add("mShoulderLeft");parts.Add("mShoulderRight");parts.Add("mAnkleLeft");parts.Add("mAnkleRight"); 625 parts.Add("mShoulderLeft"); parts.Add("mShoulderRight"); parts.Add("mAnkleLeft"); parts.Add("mAnkleRight");
486 parts.Add("mEyeRight");parts.Add("mChest");parts.Add("mToeLeft");parts.Add("mToeRight"); 626 parts.Add("mEyeRight"); parts.Add("mChest"); parts.Add("mToeLeft"); parts.Add("mToeRight");
487 parts.Add("mFootLeft");parts.Add("mFootRight");parts.Add("mEyeLeft"); 627 parts.Add("mFootLeft"); parts.Add("mFootRight"); parts.Add("mEyeLeft");
488 anim.HandPose = 1; 628 anim.HandPose = 1;
489 anim.InPoint = 0; 629 anim.InPoint = 0;
490 anim.OutPoint = (rnditerations * .10f); 630 anim.OutPoint = (rnditerations * .10f);
@@ -508,12 +648,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
508 for (int i = 0; i < rnditerations; i++) 648 for (int i = 0; i < rnditerations; i++)
509 { 649 {
510 anim.Joints[j].rotationkeys[i] = new binBVHJointKey(); 650 anim.Joints[j].rotationkeys[i] = new binBVHJointKey();
511 anim.Joints[j].rotationkeys[i].time = (i*.10f); 651 anim.Joints[j].rotationkeys[i].time = (i * .10f);
512 anim.Joints[j].rotationkeys[i].key_element.X = ((float) rnd.NextDouble()*2 - 1); 652 anim.Joints[j].rotationkeys[i].key_element.X = ((float)rnd.NextDouble() * 2 - 1);
513 anim.Joints[j].rotationkeys[i].key_element.Y = ((float) rnd.NextDouble()*2 - 1); 653 anim.Joints[j].rotationkeys[i].key_element.Y = ((float)rnd.NextDouble() * 2 - 1);
514 anim.Joints[j].rotationkeys[i].key_element.Z = ((float) rnd.NextDouble()*2 - 1); 654 anim.Joints[j].rotationkeys[i].key_element.Z = ((float)rnd.NextDouble() * 2 - 1);
515 anim.Joints[j].positionkeys[i] = new binBVHJointKey(); 655 anim.Joints[j].positionkeys[i] = new binBVHJointKey();
516 anim.Joints[j].positionkeys[i].time = (i*.10f); 656 anim.Joints[j].positionkeys[i].time = (i * .10f);
517 anim.Joints[j].positionkeys[i].key_element.X = 0; 657 anim.Joints[j].positionkeys[i].key_element.X = 0;
518 anim.Joints[j].positionkeys[i].key_element.Y = 0; 658 anim.Joints[j].positionkeys[i].key_element.Y = 0;
519 anim.Joints[j].positionkeys[i].key_element.Z = 0; 659 anim.Joints[j].positionkeys[i].key_element.Z = 0;
@@ -540,20 +680,17 @@ namespace OpenSim.Region.Framework.Scenes.Animation
540 /// <param name="objectIDs"></param> 680 /// <param name="objectIDs"></param>
541 public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs) 681 public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
542 { 682 {
543 if (m_scenePresence.IsChildAgent) 683 m_scenePresence.SendAnimPack(animations, seqs, objectIDs);
544 return; 684 }
545 685
546// m_log.DebugFormat( 686 public void GetArrays(out UUID[] animIDs, out int[] sequenceNums, out UUID[] objectIDs)
547// "[SCENE PRESENCE ANIMATOR]: Sending anim pack with animations '{0}', sequence '{1}', uuids '{2}'", 687 {
548// string.Join(",", Array.ConvertAll<UUID, string>(animations, a => a.ToString())), 688 animIDs = null;
549// string.Join(",", Array.ConvertAll<int, string>(seqs, s => s.ToString())), 689 sequenceNums = null;
550// string.Join(",", Array.ConvertAll<UUID, string>(objectIDs, o => o.ToString()))); 690 objectIDs = null;
551 691
552 m_scenePresence.Scene.ForEachClient( 692 if (m_animations != null)
553 delegate(IClientAPI client) 693 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
554 {
555 client.SendAnimations(animations, seqs, m_scenePresence.ControllingClient.AgentId, objectIDs);
556 });
557 } 694 }
558 695
559 public void SendAnimPackToClient(IClientAPI client) 696 public void SendAnimPackToClient(IClientAPI client)
@@ -575,7 +712,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
575 public void SendAnimPack() 712 public void SendAnimPack()
576 { 713 {
577 //m_log.Debug("Sending animation pack to all"); 714 //m_log.Debug("Sending animation pack to all");
578 715
579 if (m_scenePresence.IsChildAgent) 716 if (m_scenePresence.IsChildAgent)
580 return; 717 return;
581 718
@@ -585,7 +722,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
585 722
586 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs); 723 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
587 724
588 SendAnimPack(animIDs, sequenceNums, objectIDs); 725 // SendAnimPack(animIDs, sequenceNums, objectIDs);
726 m_scenePresence.SendAnimPack(animIDs, sequenceNums, objectIDs);
589 } 727 }
590 728
591 public string GetAnimName(UUID animId) 729 public string GetAnimName(UUID animId)