/// <summary> /// Gets a SkeletonSet for the standing Skeleton. /// </summary> /// <returns>A SkeletonSet for the standing Skeleton.</returns> public static SkeletonSet GetStandingSkeletonSet() { var newSkeleton = new Skeleton(StandingSkeletonName, ContentPaths.Dev); var nFrame0 = new SkeletonFrame(StandingSkeletonName, newSkeleton); var newSet = new SkeletonSet(new[] { nFrame0 }); return newSet; }
/// <summary> /// Handles the Click event of the btnInterpolate control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> void btnInterpolate_Click(object sender, EventArgs e) { var result = GetLoadSkeletonDialogResult(_filterFrame); if (result == null || result.Length <= 1) return; var frame1Skeleton = SkeletonLoader.LoadSkeleton(result); var frame1 = new SkeletonFrame(result, frame1Skeleton, 10); result = GetLoadSkeletonDialogResult(_filterFrame); if (result == null || result.Length <= 1) return; var frame2Skeleton = SkeletonLoader.LoadSkeleton(result); var frame2 = new SkeletonFrame(result, frame2Skeleton, 10); var frames = new[] { frame1, frame2 }; var ss = new SkeletonSet(frames); var sa = new SkeletonAnimation(GetTime(), ss); sa.Update(5); LoadFrame(sa.Skeleton); }
/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Form.Load"/> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (DesignMode) return; // Create the engine objects _drawingManager = new DrawingManager(GameScreen.RenderWindow); _camera = new Camera2D(new Vector2(GameScreen.Width, GameScreen.Height)) { KeepInMap = false }; _content = ContentManager.Create(); _font = _content.LoadFont("Font/Arial", 14, ContentLevel.GameScreen); GrhInfo.Load(ContentPaths.Dev, _content); // Create the skeleton-related objects _skeleton = new Skeleton(); var frameSkeleton = new Skeleton(SkeletonLoader.StandingSkeletonName, ContentPaths.Dev); var frame = new SkeletonFrame(SkeletonLoader.StandingSkeletonName, frameSkeleton); _skeletonAnim = new SkeletonAnimation(GetTime(), frame); LoadFrame(Skeleton.GetFilePath(SkeletonLoader.StandingSkeletonName, ContentPaths.Dev)); LoadAnim(SkeletonSet.GetFilePath(SkeletonLoader.WalkingSkeletonSetName, ContentPaths.Dev)); LoadBody(SkeletonBodyInfo.GetFilePath(SkeletonLoader.BasicSkeletonBodyName, ContentPaths.Dev)); LoadSkelSets(ContentPaths.Build.Grhs + "\\Character\\Skeletons"); _watch.Start(); ResetCamera(); GameScreen.MouseWheel += GameScreen_MouseWheel; }
/// <summary> /// Initializes a new instance of the <see cref="SkeletonAnimation"/> class. /// </summary> /// <param name="currentTime">Current time.</param> /// <param name="frame">Single frame to use for the keyframe.</param> public SkeletonAnimation(TickCount currentTime, SkeletonFrame frame) : this(currentTime, new SkeletonSet(new[] { frame })) { }
/// <summary> /// Loads a SkeletonSet from a string array. /// </summary> /// <param name="framesTxt">Array containing the text for each frame in the format name/time, where /// name is the name of the skeleton model and time is the delay time of the frame.</param> /// <returns> /// The loaded SkeletonSet. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="framesTxt"/> is null or empty.</exception> /// <exception cref="ArgumentException">framesTxt is null or empty.</exception> public static SkeletonSet LoadSkeletonSetFromString(string[] framesTxt) { if (framesTxt == null || framesTxt.Length == 0) { const string errmsg = "framesTxt cannot be null or empty."; throw new ArgumentException(errmsg, "framesTxt"); } var sep = new[] { "/" }; var frames = new SkeletonFrame[framesTxt.Length]; for (var i = 0; i < frames.Length; i++) { // Split up the time and frame name var frameInfo = framesTxt[i].Split(sep, StringSplitOptions.RemoveEmptyEntries); // If there is a defined time, use it float frameTime; if (frameInfo.Length == 1 || !Parser.Invariant.TryParse(frameInfo[1], out frameTime)) frameTime = 200f; if (frameTime <= 0) return null; // Create the keyframe var newSkeleton = new Skeleton(frameInfo[0], ContentPaths.Dev); frames[i] = new SkeletonFrame(frameInfo[0], newSkeleton, frameTime); } return new SkeletonSet(frames); }
/// <summary> /// Updates the skeleton animation. /// </summary> /// <param name="currentTime">Current time.</param> public void Update(TickCount currentTime) { // If theres no frames and no modifier, don't update if (_mod == null && (_skelSet.KeyFrames.Length == 1) && (CurrentFrame.Skeleton == _skelSet.KeyFrames[0].Skeleton)) _lastTime = currentTime; else { // Find the time that has elapsed since the last update float elapsedTime = currentTime - _lastTime; _lastTime = currentTime; // Calculate the new frame float delay; if (CurrentFrame.Delay == 0f) delay = NextFrame.Delay; else delay = CurrentFrame.Delay; var newFrame = _frame + ((elapsedTime * _speed) / delay); if (_skelSet.KeyFrames.Length != 1) newFrame %= _skelSet.KeyFrames.Length; // Set the new keyframe references if the frame changed if ((int)newFrame != (int)_frame) { if (_skelSet.KeyFrames.Length == 1) { _nextFrame = _skelSet.KeyFrames[0]; _currFrame = _nextFrame; } else { // If we have reached the first frame, raise the OnLoop event if ((int)newFrame == 0) { if (Looped != null) Looped.Raise(this, EventArgs.Empty); } // Store the new frame references _currFrame = _skelSet.KeyFrames[(int)newFrame]; _nextFrame = _skelSet.KeyFrames[((int)newFrame + 1) % _skelSet.KeyFrames.Length]; } } // Set the new frame _frame = newFrame; // Update the nodes of the working skeleton var framePercent = _frame - (int)_frame; SkeletonNode parentNode; if (_parent == null) parentNode = null; else parentNode = _parent.Skeleton.RootNode; RecursiveUpdate(CurrentFrame.Skeleton.RootNode, NextFrame.Skeleton.RootNode, parentNode, _skel.RootNode, framePercent); } // Update the body if (_skelBody != null) _skelBody.Update(currentTime); foreach (var bodyLayer in BodyLayers) { bodyLayer.Update(currentTime); } // If there is a parent, apply the changes to it if (_parent != null) RecursiveUpdateParent(_skel.RootNode, _parent.Skeleton.RootNode); // Apply the modifiers if (_mod != null) _mod.Update(currentTime); }
/// <summary> /// Initializes a new instance of the <see cref="SkeletonAnimation"/> class. /// </summary> /// <param name="currentTime">The current time.</param> /// <param name="skeletonSet"><see cref="SkeletonSet"/> to use for the keyframes.</param> /// <exception cref="ArgumentNullException"><paramref name="skeletonSet" /> is <c>null</c>.</exception> /// <exception cref="ArgumentException">skeletonSet contains no KeyFrames.</exception> public SkeletonAnimation(TickCount currentTime, SkeletonSet skeletonSet) { if (skeletonSet == null) throw new ArgumentNullException("skeletonSet"); if (skeletonSet.KeyFrames.Length == 0) throw new ArgumentException("skeletonSet contains no KeyFrames.", "skeletonSet"); _lastTime = currentTime; _skelSet = skeletonSet; _currFrame = _skelSet.KeyFrames[0]; _nextFrame = _skelSet.KeyFrames.Length > 1 ? _skelSet.KeyFrames[1] : _skelSet.KeyFrames[0]; _skel = CurrentFrame.Skeleton.DeepCopy(); }
/// <exception cref="ArgumentNullException"><paramref name="set" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="skel" /> is <c>null</c>.</exception> /// <exception cref="ArgumentException"><paramref name="set"/> contians no KeyFrames.</exception> public static SkeletonSet CreateSmoothedSet(SkeletonSet set, Skeleton skel) { if (set == null) throw new ArgumentNullException("set"); if (skel == null) throw new ArgumentNullException("skel"); if (set.KeyFrames.Length == 0) throw new ArgumentException("Parameter `set` contians no KeyFrames.", "set"); // Create the new frames var frames = new SkeletonFrame[set.KeyFrames.Length + 2]; // Move the old frames into the new frames array for (var i = 0; i < set.KeyFrames.Length; i++) { frames[i + 1] = set.KeyFrames[i]; } // Set the first and last frame to the skeleton var lastFrame = frames.Length - 1; frames[0] = new SkeletonFrame(string.Empty, skel, frames[1].Delay); frames[lastFrame] = new SkeletonFrame(string.Empty, skel, frames[lastFrame - 1].Delay); // Copy over the IsModifier properties from the last frame from the old set // This is required to properly animate the new skeleton set // The last frame is used instead of the first since it is more important that // we transist out of the animation smoother than translating in, under the rare // and undesirable case that all IsModifier properties are not equal frames[0].Skeleton.CopyIsModifier(frames[lastFrame - 1].Skeleton); return new SkeletonSet(frames); }
/// <summary> /// Changes the SkeletonSet used to animate. /// </summary> /// <param name="newSet">New SkeletonSet to use.</param> public void ChangeSet(SkeletonSet newSet) { if (newSet == null) { Debug.Fail("newSet is null."); return; } if (newSet.KeyFrames.Length == 0) { Debug.Fail("newSet contains no KeyFrames."); return; } // Set the new animation and clear the frame count _frame = 0; _nextFrame = newSet.KeyFrames[0]; _skelSet = newSet; // Create a temporary new current keyframe by duplicating the current state and making // that our new current keyframe, resulting in a smooth translation to the next animation float delay; if (CurrentFrame.Delay == 0) delay = _nextFrame.Delay; else delay = CurrentFrame.Delay; _currFrame = new SkeletonFrame("_worker_", _skel.DeepCopy(), delay); }
/// <summary> /// Initializes a new instance of the <see cref="SkeletonSet"/> class. /// </summary> /// <param name="keyFrames">Array of frames to use for the keyframes.</param> public SkeletonSet(SkeletonFrame[] keyFrames) { _keyFrames = keyFrames; }
/// <summary> /// Updates the skeleton animation. /// </summary> /// <param name="currentTime">Current time.</param> public void Update(TickCount currentTime) { // If theres no frames and no modifier, don't update if (_mod == null && (_skelSet.KeyFrames.Length == 1) && (CurrentFrame.Skeleton == _skelSet.KeyFrames[0].Skeleton)) { _lastTime = currentTime; } else { // Find the time that has elapsed since the last update float elapsedTime = currentTime - _lastTime; _lastTime = currentTime; // Calculate the new frame float delay; if (CurrentFrame.Delay == 0f) { delay = NextFrame.Delay; } else { delay = CurrentFrame.Delay; } var newFrame = _frame + ((elapsedTime * _speed) / delay); if (_skelSet.KeyFrames.Length != 1) { newFrame %= _skelSet.KeyFrames.Length; } // Set the new keyframe references if the frame changed if ((int)newFrame != (int)_frame) { if (_skelSet.KeyFrames.Length == 1) { _nextFrame = _skelSet.KeyFrames[0]; _currFrame = _nextFrame; } else { // If we have reached the first frame, raise the OnLoop event if ((int)newFrame == 0) { if (Looped != null) { Looped.Raise(this, EventArgs.Empty); } } // Store the new frame references _currFrame = _skelSet.KeyFrames[(int)newFrame]; _nextFrame = _skelSet.KeyFrames[((int)newFrame + 1) % _skelSet.KeyFrames.Length]; } } // Set the new frame _frame = newFrame; // Update the nodes of the working skeleton var framePercent = _frame - (int)_frame; SkeletonNode parentNode; if (_parent == null) { parentNode = null; } else { parentNode = _parent.Skeleton.RootNode; } RecursiveUpdate(CurrentFrame.Skeleton.RootNode, NextFrame.Skeleton.RootNode, parentNode, _skel.RootNode, framePercent); } // Update the body if (_skelBody != null) { _skelBody.Update(currentTime); } foreach (var bodyLayer in BodyLayers) { bodyLayer.Update(currentTime); } // If there is a parent, apply the changes to it if (_parent != null) { RecursiveUpdateParent(_skel.RootNode, _parent.Skeleton.RootNode); } // Apply the modifiers if (_mod != null) { _mod.Update(currentTime); } }