/// <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; } }
// --- 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); }
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; }
/// <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; }
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; } }