Ejemplo n.º 1
0
        /// <summary>Sets the bones and constraints to their setup pose values.</summary>
        public void SetBonesToSetupPose()
        {
            var bonesItems = this.bones.Items;

            for (int i = 0, n = bones.Count; i < n; i++)
            {
                bonesItems[i].SetToSetupPose();
            }

            var ikConstraintsItems = this.ikConstraints.Items;

            for (int i = 0, n = ikConstraints.Count; i < n; i++)
            {
                IkConstraint constraint = ikConstraintsItems[i];
                constraint.mix           = constraint.data.mix;
                constraint.softness      = constraint.data.softness;
                constraint.bendDirection = constraint.data.bendDirection;
                constraint.compress      = constraint.data.compress;
                constraint.stretch       = constraint.data.stretch;
            }

            var transformConstraintsItems = this.transformConstraints.Items;

            for (int i = 0, n = transformConstraints.Count; i < n; i++)
            {
                TransformConstraint     constraint     = transformConstraintsItems[i];
                TransformConstraintData constraintData = constraint.data;
                constraint.rotateMix    = constraintData.rotateMix;
                constraint.translateMix = constraintData.translateMix;
                constraint.scaleMix     = constraintData.scaleMix;
                constraint.shearMix     = constraintData.shearMix;
            }

            var pathConstraintItems = this.pathConstraints.Items;

            for (int i = 0, n = pathConstraints.Count; i < n; i++)
            {
                PathConstraint     constraint     = pathConstraintItems[i];
                PathConstraintData constraintData = constraint.data;
                constraint.position     = constraintData.position;
                constraint.spacing      = constraintData.spacing;
                constraint.rotateMix    = constraintData.rotateMix;
                constraint.translateMix = constraintData.translateMix;
            }
        }
Ejemplo n.º 2
0
        // --- Path constraints.

        /// <returns>May be null.</returns>
        public PathConstraintData FindPathConstraint(string constraintName)
        {
            if (constraintName == null)
            {
                throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
            }
            ExposedList <PathConstraintData> pathConstraints = this.pathConstraints;

            for (int i = 0, n = pathConstraints.Count; i < n; i++)
            {
                PathConstraintData constraint = pathConstraints.Items[i];
                if (constraint.name.Equals(constraintName))
                {
                    return(constraint);
                }
            }
            return(null);
        }
Ejemplo n.º 3
0
 /// <summary>Copy constructor.</summary>
 public PathConstraint(PathConstraint constraint, Skeleton skeleton)
 {
     if (constraint == null)
     {
         throw new ArgumentNullException("constraint cannot be null.");
     }
     if (skeleton == null)
     {
         throw new ArgumentNullException("skeleton cannot be null.");
     }
     data  = constraint.data;
     bones = new ExposedList <Bone>(constraint.Bones.Count);
     foreach (Bone bone in constraint.Bones)
     {
         bones.Add(skeleton.Bones.Items[bone.data.index]);
     }
     target       = skeleton.slots.Items[constraint.target.data.index];
     position     = constraint.position;
     spacing      = constraint.spacing;
     rotateMix    = constraint.rotateMix;
     translateMix = constraint.translateMix;
 }
Ejemplo n.º 4
0
 public PathConstraint(PathConstraintData data, Skeleton skeleton)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data", "data cannot be null.");
     }
     if (skeleton == null)
     {
         throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
     }
     this.data = data;
     bones     = new ExposedList <Bone>(data.Bones.Count);
     foreach (BoneData boneData in data.bones)
     {
         bones.Add(skeleton.FindBone(boneData.name));
     }
     target       = skeleton.FindSlot(data.target.name);
     position     = data.position;
     spacing      = data.spacing;
     rotateMix    = data.rotateMix;
     translateMix = data.translateMix;
 }
Ejemplo n.º 5
0
        public void Update()
        {
            PathAttachment attachment = target.Attachment as PathAttachment;

            if (attachment == null)
            {
                return;
            }

            float rotateMix = this.rotateMix, translateMix = this.translateMix;
            bool  translate = translateMix > 0, rotate = rotateMix > 0;

            if (!translate && !rotate)
            {
                return;
            }

            PathConstraintData data = this.data;
            bool       percentSpacing = data.spacingMode == SpacingMode.Percent;
            RotateMode rotateMode = data.rotateMode;
            bool       tangents = rotateMode == RotateMode.Tangent, scale = rotateMode == RotateMode.ChainScale;
            int        boneCount = this.bones.Count, spacesCount = tangents ? boneCount : boneCount + 1;

            Bone[] bonesItems = this.bones.Items;
            ExposedList <float> spaces = this.spaces.Resize(spacesCount), lengths = null;
            float spacing = this.spacing;

            if (scale || !percentSpacing)
            {
                if (scale)
                {
                    lengths = this.lengths.Resize(boneCount);
                }
                bool lengthSpacing = data.spacingMode == SpacingMode.Length;
                for (int i = 0, n = spacesCount - 1; i < n;)
                {
                    Bone  bone        = bonesItems[i];
                    float setupLength = bone.data.length;
                    if (setupLength < PathConstraint.Epsilon)
                    {
                        if (scale)
                        {
                            lengths.Items[i] = 0;
                        }
                        spaces.Items[++i] = 0;
                    }
                    else if (percentSpacing)
                    {
                        if (scale)
                        {
                            float x = setupLength * bone.a, y = setupLength * bone.c;
                            float length = (float)Math.Sqrt(x * x + y * y);
                            lengths.Items[i] = length;
                        }
                        spaces.Items[++i] = spacing;
                    }
                    else
                    {
                        float x = setupLength * bone.a, y = setupLength * bone.c;
                        float length = (float)Math.Sqrt(x * x + y * y);
                        if (scale)
                        {
                            lengths.Items[i] = length;
                        }
                        spaces.Items[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
                    }
                }
            }
            else
            {
                for (int i = 1; i < spacesCount; i++)
                {
                    spaces.Items[i] = spacing;
                }
            }

            float[] positions = ComputeWorldPositions(attachment, spacesCount, tangents,
                                                      data.positionMode == PositionMode.Percent, percentSpacing);
            float boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
            bool  tip;

            if (offsetRotation == 0)
            {
                tip = rotateMode == RotateMode.Chain;
            }
            else
            {
                tip = false;
                Bone p = target.bone;
                offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.DegRad : -MathUtils.DegRad;
            }
            for (int i = 0, p = 3; i < boneCount; i++, p += 3)
            {
                Bone bone = bonesItems[i];
                bone.worldX += (boneX - bone.worldX) * translateMix;
                bone.worldY += (boneY - bone.worldY) * translateMix;
                float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;
                if (scale)
                {
                    float length = lengths.Items[i];
                    if (length >= PathConstraint.Epsilon)
                    {
                        float s = ((float)Math.Sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
                        bone.a *= s;
                        bone.c *= s;
                    }
                }
                boneX = x;
                boneY = y;
                if (rotate)
                {
                    float a = bone.a, b = bone.b, c = bone.c, d = bone.d, r, cos, sin;
                    if (tangents)
                    {
                        r = positions[p - 1];
                    }
                    else if (spaces.Items[i + 1] < PathConstraint.Epsilon)
                    {
                        r = positions[p + 2];
                    }
                    else
                    {
                        r = MathUtils.Atan2(dy, dx);
                    }
                    r -= MathUtils.Atan2(c, a);
                    if (tip)
                    {
                        cos = MathUtils.Cos(r);
                        sin = MathUtils.Sin(r);
                        float length = bone.data.length;
                        boneX += (length * (cos * a - sin * c) - dx) * rotateMix;
                        boneY += (length * (sin * a + cos * c) - dy) * rotateMix;
                    }
                    else
                    {
                        r += offsetRotation;
                    }
                    if (r > MathUtils.PI)
                    {
                        r -= MathUtils.PI2;
                    }
                    else if (r < -MathUtils.PI)                     //
                    {
                        r += MathUtils.PI2;
                    }
                    r     *= rotateMix;
                    cos    = MathUtils.Cos(r);
                    sin    = MathUtils.Sin(r);
                    bone.a = cos * a - sin * c;
                    bone.b = cos * b - sin * d;
                    bone.c = sin * a + cos * c;
                    bone.d = sin * b + cos * d;
                }
                bone.appliedValid = false;
            }
        }