Porting the ScenePresenceAnimator from Avination. Jump and fall anims now work

properly.
remove-scene-viewer
Melanie 2011-11-05 22:41:00 +00:00
parent ac3254a5f5
commit 71388fc02a
2 changed files with 141 additions and 92 deletions

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using System.Threading;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using log4net; using log4net;
@ -42,7 +43,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// </summary> /// </summary>
public class ScenePresenceAnimator public class ScenePresenceAnimator
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public AnimationSet Animations public AnimationSet Animations
{ {
@ -57,10 +58,18 @@ namespace OpenSim.Region.Framework.Scenes.Animation
{ {
get { return m_movementAnimation; } get { return m_movementAnimation; }
} }
protected string m_movementAnimation = "DEFAULT"; protected string m_movementAnimation = "CROUCH";
private int m_animTickFall; private int m_animTickFall;
private int m_animTickJump; public int m_animTickJump; // ScenePresence has to see this to control +Z force
public bool m_jumping = false;
public float m_jumpVelocity = 0f;
private int m_landing = 0;
public bool Falling
{
get { return m_falling; }
}
private bool m_falling = false;
private float m_fallHeight;
/// <value> /// <value>
/// The scene presence that this animator applies to /// The scene presence that this animator applies to
@ -122,7 +131,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
public void ResetAnimations() public void ResetAnimations()
{ {
Console.WriteLine("ResetA.............");
m_animations.Clear(); m_animations.Clear();
TrySetMovementAnimation("STAND");
} }
/// <summary> /// <summary>
@ -152,15 +163,13 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// </summary> /// </summary>
public string GetMovementAnimation() public string GetMovementAnimation()
{ {
const float FALL_DELAY = 0.33f; const float FALL_DELAY = 800f;
const float PREJUMP_DELAY = 0.25f; const float PREJUMP_DELAY = 200f;
const float JUMP_PERIOD = 800f;
#region Inputs #region Inputs
if (m_scenePresence.SitGround)
{
return "SIT_GROUND_CONSTRAINED";
}
AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
// m_log.DebugFormat("[ANIM]: Control flags: {0}", controlFlags);
PhysicsActor actor = m_scenePresence.PhysicsActor; PhysicsActor actor = m_scenePresence.PhysicsActor;
// Create forward and left vectors from the current avatar rotation // Create forward and left vectors from the current avatar rotation
@ -169,13 +178,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
// Check control flags // Check control flags
bool heldForward = 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);
(((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)); 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);
bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 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);
bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 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);
bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
//bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
@ -183,17 +191,15 @@ namespace OpenSim.Region.Framework.Scenes.Animation
// Direction in which the avatar is trying to move // Direction in which the avatar is trying to move
Vector3 move = Vector3.Zero; Vector3 move = Vector3.Zero;
if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; } if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; }
if (heldLeft) { move.X += left.X; move.Y += left.Y; } if (heldLeft) { move.X += left.X; move.Y += left.Y; }
if (heldRight) { move.X -= left.X; move.Y -= left.Y; } if (heldRight) { move.X -= left.X; move.Y -= left.Y; }
if (heldUp) { move.Z += 1; } if (heldUp) { move.Z += 1; }
if (heldDown) { move.Z -= 1; } if (heldDown) { move.Z -= 1; }
if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
// Is the avatar trying to move? // Is the avatar trying to move?
// bool moving = (move != Vector3.Zero); // bool moving = (move != Vector3.Zero);
bool jumping = m_animTickJump != 0;
#endregion Inputs #endregion Inputs
#region Flying #region Flying
@ -202,6 +208,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation
{ {
m_animTickFall = 0; m_animTickFall = 0;
m_animTickJump = 0; m_animTickJump = 0;
m_jumping = false;
m_falling = true;
m_jumpVelocity = 0f;
actor.Selected = false;
m_fallHeight = actor.Position.Z; // save latest flying height
if (move.X != 0f || move.Y != 0f) if (move.X != 0f || move.Y != 0f)
{ {
@ -214,7 +225,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
else if (move.Z < 0f) else if (move.Z < 0f)
{ {
if (actor != null && actor.IsColliding) if (actor != null && actor.IsColliding)
{
return "LAND"; return "LAND";
}
else else
return "HOVER_DOWN"; return "HOVER_DOWN";
} }
@ -228,107 +241,141 @@ namespace OpenSim.Region.Framework.Scenes.Animation
#region Falling/Floating/Landing #region Falling/Floating/Landing
if (actor == null || !actor.IsColliding) if ((actor == null || !actor.IsColliding) && !m_jumping)
{ {
float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; float fallElapsed = (float)(Environment.TickCount - m_animTickFall);
float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;
if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f)) if (!m_jumping && (fallVelocity < -3.0f) ) m_falling = true;
if (m_animTickFall == 0 || (fallVelocity >= 0.0f))
{ {
// Just started falling // not falling yet, or going up
// reset start of fall time
m_animTickFall = Environment.TickCount; m_animTickFall = Environment.TickCount;
} }
else if (!jumping && fallElapsed > FALL_DELAY) else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) && (m_scenePresence.WasFlying))
{ {
// Falling long enough to trigger the animation // Falling long enough to trigger the animation
return "FALLDOWN"; return "FALLDOWN";
} }
else if (m_animTickJump == -1)
{
m_animTickJump = 0;
return "STAND";
}
return m_movementAnimation; return m_movementAnimation;
} }
#endregion Falling/Floating/Landing #endregion Falling/Floating/Landing
#region Jumping // section added for jumping...
int jumptime;
jumptime = Environment.TickCount - m_animTickJump;
if ((move.Z > 0f) && (!m_jumping))
{
// Start jumping, prejump
m_animTickFall = 0;
m_jumping = true;
m_falling = false;
actor.Selected = true; // borrowed for jumping flag
m_animTickJump = Environment.TickCount;
m_jumpVelocity = 0.35f;
return "PREJUMP";
}
if(m_jumping)
{
if ( (jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding)
{
// end jumping
m_jumping = false;
m_falling = false;
actor.Selected = false; // borrowed for jumping flag
m_jumpVelocity = 0f;
m_animTickFall = Environment.TickCount;
return "LAND";
}
else if (jumptime > JUMP_PERIOD)
{
// jump down
m_jumpVelocity = 0f;
return "JUMP";
}
else if (jumptime > PREJUMP_DELAY)
{
// jump up
m_jumping = true;
m_jumpVelocity = 10f;
return "JUMP";
}
}
#endregion Jumping
#region Ground Movement #region Ground Movement
if (m_movementAnimation == "FALLDOWN") if (m_movementAnimation == "FALLDOWN")
{ {
m_falling = false;
m_animTickFall = Environment.TickCount; m_animTickFall = Environment.TickCount;
// TODO: SOFT_LAND support // TODO: SOFT_LAND support
return "LAND"; float fallHeight = m_fallHeight - actor.Position.Z;
} if (fallHeight > 15.0f)
else if (m_movementAnimation == "LAND") return "STANDUP";
{ else if (fallHeight > 8.0f)
float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; return "SOFT_LAND";
if ((m_animTickFall != 0) && (landElapsed <= FALL_DELAY))
return "LAND";
}
m_animTickFall = 0;
if (move.Z > 0.2f)
{
// Jumping
if (!jumping)
{
// Begin prejump
m_animTickJump = Environment.TickCount;
return "PREJUMP";
}
else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f)
{
// Start actual jump
if (m_animTickJump == -1)
{
// Already jumping! End the current jump
m_animTickJump = 0;
return "JUMP";
}
m_animTickJump = -1;
return "JUMP";
}
else else
return "JUMP"; return "LAND";
}
else if ((m_movementAnimation == "LAND") || (m_movementAnimation == "SOFT_LAND") || (m_movementAnimation == "STANDUP"))
{
int landElapsed = Environment.TickCount - m_animTickFall;
int limit = 1000;
if(m_movementAnimation == "LAND") limit = 350;
// NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client
if ((m_animTickFall != 0) && (landElapsed <= limit))
{
return m_movementAnimation;
} }
else else
{ {
// Not jumping m_fallHeight = actor.Position.Z; // save latest flying height
m_animTickJump = 0; return "STAND";
}
}
// next section moved outside paren. and realigned for jumping
if (move.X != 0f || move.Y != 0f) if (move.X != 0f || move.Y != 0f)
{ {
m_fallHeight = actor.Position.Z; // save latest flying height
m_falling = false;
// Walking / crouchwalking / running // Walking / crouchwalking / running
if (move.Z < 0) if (move.Z < 0f)
return "CROUCHWALK"; return "CROUCHWALK";
else if (m_scenePresence.SetAlwaysRun) else if (m_scenePresence.SetAlwaysRun)
return "RUN"; return "RUN";
else else
return "WALK"; return "WALK";
} }
else else if (!m_jumping)
{ {
m_falling = false;
// Not walking // Not walking
if (move.Z < 0) if (move.Z < 0)
return "CROUCH"; return "CROUCH";
else if (heldTurnLeft) // else if (heldTurnLeft)
return "TURNLEFT"; // return "TURNLEFT";
else if (heldTurnRight) // else if (heldTurnRight)
return "TURNRIGHT"; // return "TURNRIGHT";
else else
return "STAND"; return "STAND";
} }
}
#endregion Ground Movement #endregion Ground Movement
//return m_movementAnimation; m_falling = false;
return m_movementAnimation;
} }
/// <summary> /// <summary>
@ -337,8 +384,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation
public void UpdateMovementAnimations() public void UpdateMovementAnimations()
{ {
m_movementAnimation = GetMovementAnimation(); m_movementAnimation = GetMovementAnimation();
// m_log.DebugFormat(
// "[SCENE PRESENCE ANIMATOR]: Got animation {0} for {1}", m_movementAnimation, m_scenePresence.Name);
TrySetMovementAnimation(m_movementAnimation); TrySetMovementAnimation(m_movementAnimation);
} }

View File

@ -2420,7 +2420,11 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.Info("[AGENT]: Stop Flying"); // m_log.Info("[AGENT]: Stop Flying");
//} //}
} }
if (!PhysicsActor.Flying && PhysicsActor.IsColliding) if (Animator.Falling && m_wasFlying) // if falling from flying, disable motion add
{
direc *= 0.0f;
}
else if (!PhysicsActor.Flying && PhysicsActor.IsColliding)
{ {
if (direc.Z > 2.0f) if (direc.Z > 2.0f)
{ {