public static AnimationStatus RenderFrame(Avatar avatar, Animation animation, int frame, float fraction) { if (frame < 0 || frame > animation.NumFrames) { return(AnimationStatus.COMPLETED); } var numDone = 0; foreach (var motion in animation.Motions) { var bone = avatar.Skeleton.GetBone(motion.BoneName); if (bone == null) { continue; //fixes bugs with missing bones.. need to find out what R_FINGERPOLY0 is though. } var motionFrame = frame; if (frame >= motion.FrameCount) { numDone++; motionFrame = (int)motion.FrameCount - 1; } if (motion.HasTranslation) { if (fraction >= 0) { var trans1 = animation.Translations[motion.FirstTranslationIndex + motionFrame]; var trans2 = (frame + 1 >= motion.FrameCount) ? trans1 : animation.Translations[motion.FirstTranslationIndex + motionFrame + 1]; bone.Translation = Vector3.Lerp(trans1, trans2, fraction); } else { bone.Translation = animation.Translations[motion.FirstTranslationIndex + motionFrame]; } } if (motion.HasRotation) { if (fraction >= 0) { var quat1 = animation.Rotations[motion.FirstRotationIndex + motionFrame]; var quat2 = (frame + 1 >= motion.FrameCount) ? quat1 : animation.Rotations[motion.FirstRotationIndex + motionFrame + 1]; bone.Rotation = Quaternion.Slerp(quat1, quat2, fraction); } else { bone.Rotation = animation.Rotations[motion.FirstRotationIndex + motionFrame]; } } } avatar.ReloadSkeleton(); return(AnimationStatus.IN_PROGRESS); }
public void Update(GameTime time) { var now = time.ElapsedGameTime.Milliseconds; if (this.Status == AnimationStatus.WAITING_TO_START) { StartTime = now; this.Status = AnimationStatus.IN_PROGRESS; } var fps = 30.0f * Speed; var fpms = fps / 1000; var runTime = now - StartTime; uint frame = (uint)(runTime * fpms); var fraction = (runTime * fpms) - frame; int numDone = 0; /** Speed is 30fps by default **/ foreach (var motion in Animation.Motions) { var bone = Avatar.Skeleton.GetBone(motion.BoneName); var motionFrame = frame; if (frame >= motion.FrameCount) { numDone++; motionFrame = motion.FrameCount - 1; } if (motion.HasTranslation) { bone.Translation = Animation.Translations[motion.FirstTranslationIndex + motionFrame]; } if (motion.HasRotation) { bone.Rotation = Animation.Rotations[motion.FirstRotationIndex + motionFrame]; } } if (numDone == Animation.Motions.Length) { /** Completed! **/ this.Status = AnimationStatus.COMPLETED; } else { Avatar.ReloadSkeleton(); } }
/// <summary> /// Renders an animation's frame. /// </summary> /// <param name="avatar">The avatar which the animation is run for.</param> /// <param name="animation">The animation.</param> /// <param name="frame">Frame number in animation.</param> /// <param name="fraction"></param> /// <returns>Status of animation.</returns> public static AnimationStatus RenderFrame(Avatar avatar, Animation animation, int frame, float fraction) { if (frame < 0 || frame > animation.NumFrames) return AnimationStatus.COMPLETED; var numDone = 0; foreach (var motion in animation.Motions) { var bone = avatar.Skeleton.GetBone(motion.BoneName); if (bone == null) continue; //fixes bugs with missing bones.. need to find out what R_FINGERPOLY0 is though. var motionFrame = frame; if (frame >= motion.FrameCount) { numDone++; motionFrame = (int)motion.FrameCount - 1; } if (motion.HasTranslation) { if (fraction >= 0) { var trans1 = animation.Translations[motion.FirstTranslationIndex + motionFrame]; var trans2 = (frame + 1 >= motion.FrameCount) ? trans1 : animation.Translations[motion.FirstTranslationIndex + motionFrame+1]; bone.Translation = Vector3.Lerp(trans1, trans2, fraction); } else { bone.Translation = animation.Translations[motion.FirstTranslationIndex + motionFrame]; } } if (motion.HasRotation) { if (fraction >= 0) { var quat1 = animation.Rotations[motion.FirstRotationIndex + motionFrame]; var quat2 = (frame + 1 >= motion.FrameCount) ? quat1 : animation.Rotations[motion.FirstRotationIndex + motionFrame + 1]; bone.Rotation = Quaternion.Slerp(quat1, quat2, fraction); } else { bone.Rotation = animation.Rotations[motion.FirstRotationIndex + motionFrame]; } } } avatar.ReloadSkeleton(); return AnimationStatus.IN_PROGRESS; }