/// <summary> /// Next frame and next anim calculation function. /// </summary> public static void GetNextFrame(SSBoneFrame bf, float time, StateChange stc, out short frame, out TR_ANIMATION anim, AnimControlFlags animFlags) { var currAnim = bf.Animations.Model.Animations[(int) bf.Animations.CurrentAnimation]; frame = (short)((bf.Animations.FrameTime + time) / bf.Animations.Period); frame = Math.Max(frame, (short)0); // paranoid checking anim = bf.Animations.CurrentAnimation; // Flag has a highest priority if(animFlags == AnimControlFlags.LoopLastFrame) { if(frame >= currAnim.Frames.Count - 1) { frame = (short) (currAnim.Frames.Count - 1); anim = bf.Animations.CurrentAnimation; // paranoid duplicate } return; } else if(animFlags == AnimControlFlags.Lock) { frame = 0; anim = bf.Animations.CurrentAnimation; return; } // Check next anim if frame >= frames.Count if(frame >= currAnim.Frames.Count) { if(currAnim.NextAnim != null) { frame = (short)currAnim.NextFrame; anim = currAnim.NextAnim.ID; return; } frame = (short)(frame % currAnim.Frames.Count); anim = bf.Animations.CurrentAnimation; // paranoid duplicate return; } // State change check if(stc != null) { foreach (var disp in stc.AnimDispatch) { if(disp.FrameHigh >= disp.FrameLow && frame.IsBetween(disp.FrameLow, disp.FrameHigh)) { anim = disp.NextAnim; frame = (short) disp.NextFrame; return; } } } }
private void doAnimMove(ref TR_ANIMATION anim, ref short frame) { if(Bf.Animations.Model != null) { var currAf = Bf.Animations.Model.Animations[(int) Bf.Animations.CurrentAnimation]; var currBf = currAf.Frames[Bf.Animations.CurrentFrame]; if(currBf.Command.HasFlagUns(ANIM_CMD.Jump)) { Jump(-currBf.V_Vertical, currBf.V_Horizontal); } if(currBf.Command.HasFlagUns(ANIM_CMD.ChangeDirection)) { Angles.X += 180.0f; if(MoveType == MoveType.Underwater) { Angles.Y = -Angles.Y; // for underwater case } if(DirFlag == ENT_MOVE.MoveBackward) { DirFlag = ENT_MOVE.MoveForward; } else if(DirFlag == ENT_MOVE.MoveForward) { DirFlag = ENT_MOVE.MoveBackward; } UpdateTransform(); SetAnimation(currAf.NextAnim.ID, currAf.NextFrame); anim = Bf.Animations.CurrentAnimation; frame = Bf.Animations.CurrentFrame; } if(currBf.Command.HasFlagUns(ANIM_CMD.Move)) { Transform.Origin += Transform.Basis.MultiplyByVector(currBf.Move); } } }
public static StateChange Anim_FindStateChangeByAnim(AnimationFrame anim, TR_ANIMATION stateChangeAnim) { return stateChangeAnim >= 0 ? anim.StateChange.FirstOrDefault(x => x.AnimDispatch.Any(y => y.NextAnim == stateChangeAnim)) : null; }
public void SetAnimation(TR_ANIMATION animation, int frame = 0, int anotherModel = -1) { if(Bf.Animations.Model == null || (int)animation >= Bf.Animations.Model.Animations.Count) { return; } animation = animation < 0 ? 0 : animation; Bt.NoFixAll = false; if(anotherModel >= 0) { var model = EngineWorld.GetModelByID((uint) anotherModel); if (model == null || (int) animation >= model.Animations.Count) return; Bf.Animations.Model = model; } var anim = Bf.Animations.Model.Animations[(int) animation]; Bf.Animations.Lerp = 0.0f; frame %= anim.Frames.Count; frame = frame >= 0 ? frame : anim.Frames.Count - 1 + frame; Bf.Animations.Period = 1.0f / TR_FRAME_RATE; Bf.Animations.LastState = anim.StateID; Bf.Animations.NextState = anim.StateID; Bf.Animations.CurrentAnimation = animation; Bf.Animations.CurrentFrame = (short)frame; Bf.Animations.NextAnimation = animation; Bf.Animations.NextFrame = (short)frame; Bf.Animations.FrameTime = frame * Bf.Animations.Period; UpdateCurrentBoneFrame(Bf, Transform); UpdateRigidBody(false); }