예제 #1
0
        /// <summary>
        /// Recursively draws the joints and bones of a skeleton.
        /// </summary>
        /// <param name="camera">Camera to use.</param>
        /// <param name="sb"><see cref="ISpriteBatch"/> to draw to.</param>
        /// <param name="selectedNode">SpriteBatch to draw to.</param>
        /// <param name="node">Current node being drawn.</param>
        /// <param name="colorIndex">Index of the color to use from the ColorList.</param>
        static void RecursiveDraw(ICamera2D camera, ISpriteBatch sb, SkeletonNode selectedNode, SkeletonNode node, int colorIndex)
        {
            // Find the color of the joint
            var color = _colorList[colorIndex];
            if (node == selectedNode)
                color = _nodeColorSelected;
            else if (node.Parent == null)
                color = _nodeColorRoot;

            // Draw the joint
            var scale = 1f / camera.Scale;
            var origin = SkeletonNode.HalfJointVector;
            _joint.Draw(sb, node.Position, color, SpriteEffects.None, 0f, origin, scale);

            // Iterate through the children
            foreach (var child in node.Nodes)
            {
                colorIndex++;
                if (colorIndex == _colorList.Length)
                    colorIndex = 0;

                // Draw the bone to the child
                RenderLine.Draw(sb, node.Position, child.Position, _colorList[colorIndex], (1f / camera.Scale) * 2f);

                // Draw the child
                RecursiveDraw(camera, sb, selectedNode, child, colorIndex);
            }
        }
예제 #2
0
        /// <summary>
        /// Draws a <see cref="Skeleton"/>.
        /// </summary>
        /// <param name="skeleton">The <see cref="Skeleton"/> to draw.</param>
        /// <param name="camera">Camera to use.</param>
        /// <param name="sb">The <see cref="ISpriteBatch"/> to draw with.</param>
        /// <param name="selectedNode">The <see cref="SkeletonNode"/> to draw as selected.</param>
        public static void Draw(Skeleton skeleton, ICamera2D camera, ISpriteBatch sb, SkeletonNode selectedNode = null)
        {
            if (skeleton == null)
            {
                Debug.Fail("skeleton is null.");
                return;
            }
            if (skeleton.RootNode == null)
            {
                Debug.Fail("skeleton contains no root node.");
                return;
            }
            if (sb == null)
            {
                Debug.Fail("sb is null.");
                return;
            }
            if (sb.IsDisposed)
            {
                Debug.Fail("sb is disposed.");
                return;
            }
            if (camera == null)
            {
                Debug.Fail("camera is null.");
                return;
            }

            RecursiveDraw(camera, sb, selectedNode, skeleton.RootNode, 0);
        }
예제 #3
0
        /// <summary>
        /// Attaches the <see cref="SkeletonBodyItem"/> to a <see cref="Skeleton"/> using the name of the joints.
        /// </summary>
        /// <param name="skeleton"><see cref="Skeleton"/> to attach to.</param>
        internal void Attach(Skeleton skeleton)
        {
            // Source node
            if (skeleton == null)
                Source = null;
            else
                Source = skeleton.FindNode(ItemInfo.SourceName);

            // Destination node
            if (skeleton == null || ItemInfo.DestName.Length == 0)
                Dest = null;
            else
                Dest = skeleton.FindNode(ItemInfo.DestName);
        }
예제 #4
0
        /// <summary>
        /// Draws the <see cref="SkeletonBodyItem"/>.
        /// </summary>
        /// <param name="sb"><see cref="ISpriteBatch"/> to draw to.</param>
        /// <param name="position">Position to draw at.</param>
        /// <param name="scale">Amount to scale the Grh in percent (1.0f for no scaling).</param>
        /// <param name="color">The color.</param>
        /// <param name="effect">SpriteEffects to use when drawing.</param>
        internal void Draw(ISpriteBatch sb, Vector2 position, float scale, Color color, SpriteEffects effect)
        {
            // Validate
            if (Source == null)
            {
                return;
            }

            // Find the effect
            Vector2 m;

            switch (effect)
            {
            case SpriteEffects.FlipHorizontally:
                m = new Vector2(-1, 1);
                break;

            case SpriteEffects.FlipVertically:
                m = new Vector2(1, -1);
                break;

            default:
                m = new Vector2(1, 1);
                break;
            }

            // Calculate the angle
            float angle;

            if (Dest == null)
            {
                angle = 0.0f;
            }
            else
            {
                angle = SkeletonNode.GetAngle(Source.Position * m, Dest.Position * m) - MathHelper.PiOver2;
            }

            // Draw
            var v = Source.Position + ItemInfo.Offset;

            Grh.Draw(sb, (v * m) + position, color, effect, angle, ItemInfo.Origin, scale);
        }
예제 #5
0
        /// <summary>
        /// Checks if a given point hits the node
        /// </summary>
        /// <param name="camera">World camera (determines node size)</param>
        /// <param name="position">World position</param>
        /// <param name="node">Node to test against</param>
        /// <returns>True if the node was hit, else false</returns>
        public static bool HitTest(ICamera2D camera, Vector2 position, SkeletonNode node)
        {
            if (node == null)
            {
                Debug.Fail("node is null.");
                return(false);
            }
            if (camera == null)
            {
                Debug.Fail("camera is null.");
                return(false);
            }

            var size = Vector2.Divide(HalfJointVector, camera.Scale);
            var min  = node.Position - size;
            var max  = node.Position + size;

            return(position.X >= min.X && position.X <= max.X && position.Y >= min.Y && position.Y <= max.Y);
        }
예제 #6
0
        /// <summary>
        /// Recursively copies the length of one set of nodes to another set of nodes
        /// </summary>
        /// <param name="src">Source root SkeletonNode to copy from</param>
        /// <param name="dest">Destination root SkeletonNode to copy to</param>
        public static void CopyLength(SkeletonNode src, SkeletonNode dest)
        {
            if (src == null)
            {
                Debug.Fail("src is null.");
                return;
            }
            if (dest == null)
            {
                Debug.Fail("dest is null.");
                return;
            }

            dest.SetLength(src.GetLength());
            for (var i = 0; i < src.Nodes.Count(); i++)
            {
                CopyLength(src.Nodes.ElementAt(i), dest.Nodes.ElementAt(i));
            }
        }
예제 #7
0
        /// <summary>
        /// Recursively copies the IsModifier property of one set of nodes to another set of nodes
        /// </summary>
        /// <param name="src">Source root SkeletonNode to copy from</param>
        /// <param name="dest">Destination root SkeletonNode to copy to</param>
        static void CopyIsModifier(SkeletonNode src, SkeletonNode dest)
        {
            if (src == null)
            {
                Debug.Fail("src is null.");
                return;
            }

            if (dest == null)
            {
                Debug.Fail("dest is null.");
                return;
            }

            dest.IsModifier = src.IsModifier;
            for (var i = 0; i < src.Nodes.Count(); i++)
            {
                CopyIsModifier(src.Nodes.ElementAt(i), dest.Nodes.ElementAt(i));
            }
        }
예제 #8
0
        /// <summary>
        /// Used to assist the recursive node acquisition
        /// </summary>
        /// <param name="root">Root node to work from</param>
        /// <returns>Children of the root</returns>
        static List <SkeletonNode> GetNodes(SkeletonNode root)
        {
            if (root == null)
            {
                Debug.Fail("root is null.");
                return(new List <SkeletonNode>());
            }

            var ret = new List <SkeletonNode>();

            foreach (var node in root.Nodes)
            {
                ret.Add(node);
                foreach (var subNode in GetNodes(node))
                {
                    ret.Add(subNode);
                }
            }
            return(ret);
        }
예제 #9
0
        /// <summary>
        /// Recursively updates all the children of a node.
        /// </summary>
        /// <param name="srcA">Source skeleton node for the current frame.</param>
        /// <param name="srcB">Source skeleton node for the next frame.</param>
        /// <param name="srcP">Parent skeleton node (use null if theres no parent).</param>
        /// <param name="dest">Destination skeleton node to have the two sources applied to.</param>
        /// <param name="framePercent">A value between 0.0 and 1.0 stating how far along the animation is
        /// from the current frame.</param>
        void RecursiveUpdate(SkeletonNode srcA, SkeletonNode srcB, SkeletonNode srcP, SkeletonNode dest, float framePercent)
        {
            // Set the position
            Vector2 vA;
            Vector2 vB;

            if (_scale == 1.0f)
            {
                vA = srcA.Position;
                vB = srcB.Position;
            }
            else
            {
                vA = srcA.Position * _scale;
                vB = srcB.Position * _scale;
            }
            dest.Position = Vector2.Lerp(vA, vB, framePercent);

            // Check if the node is part of a modifier animation
            if (srcP == null)
            {
                // Set the length
                dest.SetLength(srcA.GetLength() * _scale);
            }
            else
            {
                // This is a modifier so check for inheriting node values
                dest.SetLength(srcP.GetLength());
                if (!srcP.IsModifier && srcP.Parent != null)
                {
                    dest.SetAngle(srcP.GetAngle());
                }
            }

            // Update the child nodes (if there is any)
            for (var i = 0; i < srcA.internalNodes.Count; i++)
            {
                var nextSrcP = (srcP == null ? null : srcP.internalNodes[i]);
                RecursiveUpdate(srcA.internalNodes[i], srcB.internalNodes[i], nextSrcP, dest.internalNodes[i], framePercent);
            }
        }
예제 #10
0
        /// <summary>
        /// Reads a <see cref="Skeleton"/> from an <see cref="IValueReader"/>.
        /// </summary>
        /// <param name="reader">The <see cref="IValueReader"/> to read from.</param>
        /// <exception cref="ArgumentNullException"><paramref name="reader" /> is <c>null</c>.</exception>
        /// <exception cref="InvalidOperationException">The loaded <see cref="Skeleton"/> was not properly structured.</exception>
        public void Read(IValueReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            var nodesWithParents = new List <KeyValuePair <SkeletonNode, string> >();

            var loadedNodes = reader.ReadManyNodes(_nodesNodeName, x => SkeletonNodeReadHandler(x, nodesWithParents));

            // Add the root node (which should be the only one without a parent)
            var nodesWithoutParents = loadedNodes.Except(nodesWithParents.Select(x => x.Key));

            if (nodesWithoutParents.Count() != 1)
            {
                throw new InvalidOperationException("Invalid number of parentless nodes. Was only expected one!");
            }

            _rootNode = nodesWithoutParents.First();

            // Set up the parents
            foreach (var nodeWithParent in nodesWithParents)
            {
                var node       = nodeWithParent.Key;
                var parentName = nodeWithParent.Value;

                var parentNode = loadedNodes.FirstOrDefault(x => parentName.Equals(x.Name, StringComparison.OrdinalIgnoreCase));

                if (parentNode == null)
                {
                    const string errmsg = "Unable to find parent node `{0}` for node `{1}`.";
                    var          err    = string.Format(errmsg, parentName, node.Name);
                    throw new InvalidOperationException(err);
                }

                node.Parent = parentNode;
                parentNode.internalNodes.Add(node);
            }
        }
예제 #11
0
        /// <summary>
        /// Attaches the <see cref="SkeletonBodyItem"/> to a <see cref="Skeleton"/> using the name of the joints.
        /// </summary>
        /// <param name="skeleton"><see cref="Skeleton"/> to attach to.</param>
        internal void Attach(Skeleton skeleton)
        {
            // Source node
            if (skeleton == null)
            {
                Source = null;
            }
            else
            {
                Source = skeleton.FindNode(ItemInfo.SourceName);
            }

            // Destination node
            if (skeleton == null || ItemInfo.DestName.Length == 0)
            {
                Dest = null;
            }
            else
            {
                Dest = skeleton.FindNode(ItemInfo.DestName);
            }
        }
예제 #12
0
        /// <summary>
        /// Recursively creates a deep-copy of the node and all its child nodes
        /// </summary>
        /// <param name="root">Node to duplicate</param>
        /// <returns>Duplicate copy of the node</returns>
        static SkeletonNode Duplicate(SkeletonNode root)
        {
            if (root == null)
            {
                Debug.Fail("root is null.");
                return(null);
            }

            var ret = new SkeletonNode(new Vector2(root.Position.X, root.Position.Y))
            {
                Name = root.Name
            };

            foreach (var node in root.Nodes)
            {
                var newChild = Duplicate(node);
                newChild.Parent     = ret;
                newChild.Name       = node.Name;
                newChild.IsModifier = node.IsModifier;
                ret._nodes.Add(newChild);
            }
            return(ret);
        }
예제 #13
0
        /// <summary>
        /// Recursively draws the joints and bones of a skeleton.
        /// </summary>
        /// <param name="camera">Camera to use.</param>
        /// <param name="sb"><see cref="ISpriteBatch"/> to draw to.</param>
        /// <param name="selectedNode">SpriteBatch to draw to.</param>
        /// <param name="node">Current node being drawn.</param>
        /// <param name="colorIndex">Index of the color to use from the ColorList.</param>
        static void RecursiveDraw(ICamera2D camera, ISpriteBatch sb, SkeletonNode selectedNode, SkeletonNode node, int colorIndex)
        {
            // Find the color of the joint
            var color = _colorList[colorIndex];

            if (node == selectedNode)
            {
                color = _nodeColorSelected;
            }
            else if (node.Parent == null)
            {
                color = _nodeColorRoot;
            }

            // Draw the joint
            var scale  = 1f / camera.Scale;
            var origin = SkeletonNode.HalfJointVector;

            _joint.Draw(sb, node.Position, color, SpriteEffects.None, 0f, origin, scale);

            // Iterate through the children
            foreach (var child in node.Nodes)
            {
                colorIndex++;
                if (colorIndex == _colorList.Length)
                {
                    colorIndex = 0;
                }

                // Draw the bone to the child
                RenderLine.Draw(sb, node.Position, child.Position, _colorList[colorIndex], (1f / camera.Scale) * 2f);

                // Draw the child
                RecursiveDraw(camera, sb, selectedNode, child, colorIndex);
            }
        }
예제 #14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SkeletonNode"/> class.
 /// </summary>
 /// <param name="position">The position of the node relative to the <see cref="Skeleton"/>.</param>
 public SkeletonNode(Vector2 position)
 {
     _parent = null;
     _position = position;
 }
예제 #15
0
        /// <summary>
        /// Recursively moves a node and all its children by a given value
        /// </summary>
        /// <param name="node">Root node to move</param>
        /// <param name="diff">Distance to move the node</param>
        static void RecursiveMove(SkeletonNode node, Vector2 diff)
        {
            // Move the node
            node.Position -= diff;

            // Update the children
            foreach (var childNode in node.Nodes)
            {
                RecursiveMove(childNode, diff);
            }
        }
예제 #16
0
        /// <summary>
        /// Checks if a given point hits the node
        /// </summary>
        /// <param name="camera">World camera (determines node size)</param>
        /// <param name="position">World position</param>
        /// <param name="node">Node to test against</param>
        /// <returns>True if the node was hit, else false</returns>
        public static bool HitTest(ICamera2D camera, Vector2 position, SkeletonNode node)
        {
            if (node == null)
            {
                Debug.Fail("node is null.");
                return false;
            }
            if (camera == null)
            {
                Debug.Fail("camera is null.");
                return false;
            }

            var size = Vector2.Divide(HalfJointVector, camera.Scale);
            var min = node.Position - size;
            var max = node.Position + size;
            return (position.X >= min.X && position.X <= max.X && position.Y >= min.Y && position.Y <= max.Y);
        }
예제 #17
0
        /// <summary>
        /// Used to assist the recursive node acquisition
        /// </summary>
        /// <param name="root">Root node to work from</param>
        /// <returns>Children of the root</returns>
        static List<SkeletonNode> GetNodes(SkeletonNode root)
        {
            if (root == null)
            {
                Debug.Fail("root is null.");
                return new List<SkeletonNode>();
            }

            var ret = new List<SkeletonNode>();
            foreach (var node in root.Nodes)
            {
                ret.Add(node);
                foreach (var subNode in GetNodes(node))
                {
                    ret.Add(subNode);
                }
            }
            return ret;
        }
예제 #18
0
        /// <summary>
        /// Finds the angle between this node and another
        /// </summary>
        /// <param name="node">Node to compare to</param>
        /// <returns>Angle between the two nodes</returns>
        public float GetAngle(SkeletonNode node)
        {
            if (node == null)
                return 0f;

            return GetAngle(node.Position, Position);
        }
예제 #19
0
        /// <summary>
        /// Recursively creates a deep-copy of the node and all its child nodes
        /// </summary>
        /// <param name="root">Node to duplicate</param>
        /// <returns>Duplicate copy of the node</returns>
        static SkeletonNode Duplicate(SkeletonNode root)
        {
            if (root == null)
            {
                Debug.Fail("root is null.");
                return null;
            }

            var ret = new SkeletonNode(new Vector2(root.Position.X, root.Position.Y)) { Name = root.Name };
            foreach (var node in root.Nodes)
            {
                var newChild = Duplicate(node);
                newChild.Parent = ret;
                newChild.Name = node.Name;
                newChild.IsModifier = node.IsModifier;
                ret._nodes.Add(newChild);
            }
            return ret;
        }
예제 #20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SkeletonNode"/> class.
 /// </summary>
 /// <param name="position">The position of the node relative to the <see cref="Skeleton"/>.</param>
 public SkeletonNode(Vector2 position)
 {
     _parent   = null;
     _position = position;
 }
예제 #21
0
        /// <summary>
        /// Updates the parent <see cref="SkeletonAnimation"/> that this modifier modifies.
        /// </summary>
        /// <param name="src">Source root <see cref="SkeletonNode"/>.</param>
        /// <param name="dest">Destination root <see cref="SkeletonNode"/>.</param>
        static void RecursiveUpdateParent(SkeletonNode src, SkeletonNode dest)
        {
            // Update modified values
            if (src.IsModifier && dest.Parent != null)
                dest.SetAngle(src.GetAngle());

            // Update the child nodes (if there is any)
            for (var i = 0; i < src.internalNodes.Count; i++)
            {
                RecursiveUpdateParent(src.internalNodes[i], dest.internalNodes[i]);
            }
        }
예제 #22
0
파일: Skeleton.cs 프로젝트: wtfcolt/game
        static SkeletonNode SkeletonNodeReadHandler(IValueReader r,
                                                    ICollection<KeyValuePair<SkeletonNode, string>> nodesWithParents)
        {
            string parentName;
            var node = new SkeletonNode(r, out parentName);

            if (parentName != null)
            {
                var kvp = new KeyValuePair<SkeletonNode, string>(node, parentName);
                nodesWithParents.Add(kvp);
            }

            return node;
        }
예제 #23
0
파일: Skeleton.cs 프로젝트: wtfcolt/game
        /// <summary>
        /// Finds a SkeletonNode by a given name
        /// </summary>
        /// <param name="rootNode">Root node to look through</param>
        /// <param name="name">Name of the node to look for</param>
        /// <returns>SkeletonNode with the specified name, or null if none found</returns>
        static SkeletonNode FindNode(SkeletonNode rootNode, string name)
        {
            if (rootNode == null)
            {
                Debug.Fail("rootNode is null.");
                return null;
            }

            if (name == null)
            {
                Debug.Fail("name is null.");
                return null;
            }

            if (rootNode.Name == name)
            {
                // Root node matched the name
                return rootNode;
            }
            else
            {
                // Check the child nodes for a name match
                foreach (var child in rootNode.Nodes)
                {
                    var ret = FindNode(child, name);
                    if (ret != null)
                        return ret;
                }
            }

            // Node with the given name not found
            return null;
        }
예제 #24
0
        /// <summary>
        /// Draws a <see cref="Skeleton"/>.
        /// </summary>
        /// <param name="skeleton">The <see cref="Skeleton"/> to draw.</param>
        /// <param name="camera">Camera to use.</param>
        /// <param name="sb">The <see cref="ISpriteBatch"/> to draw with.</param>
        /// <param name="selectedNode">The <see cref="SkeletonNode"/> to draw as selected.</param>
        public static void Draw(Skeleton skeleton, ICamera2D camera, ISpriteBatch sb, SkeletonNode selectedNode = null)
        {
            if (skeleton == null)
            {
                Debug.Fail("skeleton is null.");
                return;
            }
            if (skeleton.RootNode == null)
            {
                Debug.Fail("skeleton contains no root node.");
                return;
            }
            if (sb == null)
            {
                Debug.Fail("sb is null.");
                return;
            }
            if (sb.IsDisposed)
            {
                Debug.Fail("sb is disposed.");
                return;
            }
            if (camera == null)
            {
                Debug.Fail("camera is null.");
                return;
            }

            RecursiveDraw(camera, sb, selectedNode, skeleton.RootNode, 0);
        }
예제 #25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SkeletonNode"/> class.
 /// </summary>
 /// <param name="parent">The parent <see cref="SkeletonNode"/>. If null, this will be treated as the root node in the
 /// <see cref="Skeleton"/>.</param>
 /// <param name="position">The position of the node relative to the <see cref="Skeleton"/>.</param>
 public SkeletonNode(SkeletonNode parent, Vector2 position)
 {
     _parent = parent;
     _parent._nodes.Add(this);
     _position = position;
 }
예제 #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SkeletonNode"/> class.
 /// </summary>
 /// <param name="parent">The parent <see cref="SkeletonNode"/>. If null, this will be treated as the root node in the
 /// <see cref="Skeleton"/>.</param>
 /// <param name="position">The position of the node relative to the <see cref="Skeleton"/>.</param>
 public SkeletonNode(SkeletonNode parent, Vector2 position)
 {
     _parent = parent;
     _parent._nodes.Add(this);
     _position = position;
 }
예제 #27
0
파일: Skeleton.cs 프로젝트: wtfcolt/game
        /// <summary>
        /// Recursively copies the length of one set of nodes to another set of nodes
        /// </summary>
        /// <param name="src">Source root SkeletonNode to copy from</param>
        /// <param name="dest">Destination root SkeletonNode to copy to</param>
        public static void CopyLength(SkeletonNode src, SkeletonNode dest)
        {
            if (src == null)
            {
                Debug.Fail("src is null.");
                return;
            }
            if (dest == null)
            {
                Debug.Fail("dest is null.");
                return;
            }

            dest.SetLength(src.GetLength());
            for (var i = 0; i < src.Nodes.Count(); i++)
            {
                CopyLength(src.Nodes.ElementAt(i), dest.Nodes.ElementAt(i));
            }
        }
예제 #28
0
        /// <summary>
        /// Adds a child node to the node
        /// </summary>
        /// <param name="node">Child node to add</param>
        public void Add(SkeletonNode node)
        {
            if (node == null)
            {
                Debug.Fail("node is null.");
                return;
            }

            _nodes.Add(node);
            node.Parent = this;
        }
예제 #29
0
파일: Skeleton.cs 프로젝트: wtfcolt/game
        /// <summary>
        /// Reads a <see cref="Skeleton"/> from an <see cref="IValueReader"/>.
        /// </summary>
        /// <param name="reader">The <see cref="IValueReader"/> to read from.</param>
        /// <exception cref="ArgumentNullException"><paramref name="reader" /> is <c>null</c>.</exception>
        /// <exception cref="InvalidOperationException">The loaded <see cref="Skeleton"/> was not properly structured.</exception>
        public void Read(IValueReader reader)
        {
            if (reader == null)
                throw new ArgumentNullException("reader");

            var nodesWithParents = new List<KeyValuePair<SkeletonNode, string>>();

            var loadedNodes = reader.ReadManyNodes(_nodesNodeName, x => SkeletonNodeReadHandler(x, nodesWithParents));

            // Add the root node (which should be the only one without a parent)
            var nodesWithoutParents = loadedNodes.Except(nodesWithParents.Select(x => x.Key));
            if (nodesWithoutParents.Count() != 1)
                throw new InvalidOperationException("Invalid number of parentless nodes. Was only expected one!");

            _rootNode = nodesWithoutParents.First();

            // Set up the parents
            foreach (var nodeWithParent in nodesWithParents)
            {
                var node = nodeWithParent.Key;
                var parentName = nodeWithParent.Value;

                var parentNode = loadedNodes.FirstOrDefault(x => parentName.Equals(x.Name, StringComparison.OrdinalIgnoreCase));

                if (parentNode == null)
                {
                    const string errmsg = "Unable to find parent node `{0}` for node `{1}`.";
                    var err = string.Format(errmsg, parentName, node.Name);
                    throw new InvalidOperationException(err);
                }

                node.Parent = parentNode;
                parentNode.internalNodes.Add(node);
            }
        }
예제 #30
0
        /// <summary>
        /// Handles the MouseDown event of the GameScreen control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
        void GameScreen_MouseDown(object sender, MouseEventArgs e)
        {
            if (radioEdit.Checked)
            {
                if (e.Button == MouseButtons.Left)
                {
                    // Select new node
                    var nodes = _skeleton.RootNode.GetAllNodes();
                    foreach (var node in nodes)
                    {
                        if (node.HitTest(_camera, _cursorPos))
                        {
                            SelectedNode = node; // Select the node
                            _moveSelectedNode = true; // Enable dragging
                            break;
                        }
                    }
                }
                else if (e.Button == MouseButtons.Right)
                {
                    // Add new node
                    if (!chkCanAlter.Checked)
                    {
                        MessageBox.Show("Node adding and removing locked. Enable node add/remove in the settings panel.",
                            "Invalid operation", MessageBoxButtons.OK);
                        return;
                    }

                    if (_skeleton.RootNode == null)
                    {
                        // Create the root node
                        _skeleton.RootNode = new SkeletonNode(_cursorPos);
                        SelectedNode = _skeleton.RootNode;
                        SelectedNode.Name = "New Root";
                    }
                    else
                    {
                        // Create a child node
                        if (SelectedNode == null)
                        {
                            const string errmsg =
                                "You must first select a node before creating a new node. The selected node will be used as the new node's parent.";
                            MessageBox.Show(errmsg, "Select a node", MessageBoxButtons.OK);
                        }
                        else
                        {
                            var newNode = new SkeletonNode(SelectedNode, _cursorPos);
                            UpdateFrameNodeCBs();
                            SelectedNode = newNode;
                        }
                    }
                }
            }
        }
예제 #31
0
파일: Skeleton.cs 프로젝트: wtfcolt/game
        /// <summary>
        /// Recursively copies the IsModifier property of one set of nodes to another set of nodes
        /// </summary>
        /// <param name="src">Source root SkeletonNode to copy from</param>
        /// <param name="dest">Destination root SkeletonNode to copy to</param>
        static void CopyIsModifier(SkeletonNode src, SkeletonNode dest)
        {
            if (src == null)
            {
                Debug.Fail("src is null.");
                return;
            }

            if (dest == null)
            {
                Debug.Fail("dest is null.");
                return;
            }

            dest.IsModifier = src.IsModifier;
            for (var i = 0; i < src.Nodes.Count(); i++)
            {
                CopyIsModifier(src.Nodes.ElementAt(i), dest.Nodes.ElementAt(i));
            }
        }
예제 #32
0
        /// <summary>
        /// Recursively updates all the children of a node.
        /// </summary>
        /// <param name="srcA">Source skeleton node for the current frame.</param>
        /// <param name="srcB">Source skeleton node for the next frame.</param>
        /// <param name="srcP">Parent skeleton node (use null if theres no parent).</param>
        /// <param name="dest">Destination skeleton node to have the two sources applied to.</param>
        /// <param name="framePercent">A value between 0.0 and 1.0 stating how far along the animation is
        /// from the current frame.</param>
        void RecursiveUpdate(SkeletonNode srcA, SkeletonNode srcB, SkeletonNode srcP, SkeletonNode dest, float framePercent)
        {
            // Set the position
            Vector2 vA;
            Vector2 vB;
            if (_scale == 1.0f)
            {
                vA = srcA.Position;
                vB = srcB.Position;
            }
            else
            {
                vA = srcA.Position * _scale;
                vB = srcB.Position * _scale;
            }
            dest.Position = Vector2.Lerp(vA, vB, framePercent);

            // Check if the node is part of a modifier animation
            if (srcP == null)
            {
                // Set the length
                dest.SetLength(srcA.GetLength() * _scale);
            }
            else
            {
                // This is a modifier so check for inheriting node values
                dest.SetLength(srcP.GetLength());
                if (!srcP.IsModifier && srcP.Parent != null)
                    dest.SetAngle(srcP.GetAngle());
            }

            // Update the child nodes (if there is any)
            for (var i = 0; i < srcA.internalNodes.Count; i++)
            {
                var nextSrcP = (srcP == null ? null : srcP.internalNodes[i]);
                RecursiveUpdate(srcA.internalNodes[i], srcB.internalNodes[i], nextSrcP, dest.internalNodes[i], framePercent);
            }
        }