public BoneMatrix TransformMatrix(BoneMatrix local) => new BoneMatrix { a = (this.a * local.a) + (this.b * local.c), b = (this.a * local.b) + (this.b * local.d), c = (this.c * local.a) + (this.d * local.c), d = (this.c * local.b) + (this.d * local.d), x = ((this.a * local.x) + (this.b * local.y)) + this.x, y = ((this.c * local.x) + (this.d * local.y)) + this.y };
public BoneMatrix TransformMatrix(BoneMatrix local) { return(new BoneMatrix { a = this.a * local.a + this.b * local.c, b = this.a * local.b + this.b * local.d, c = this.c * local.a + this.d * local.c, d = this.c * local.b + this.d * local.d, x = this.a * local.x + this.b * local.y + this.x, y = this.c * local.x + this.d * local.y + this.y }); }
public static BoneMatrix CalculateSetupWorld(BoneData boneData) { if (boneData == null) { return(new BoneMatrix()); } if (boneData.parent == null) { return(GetInheritedInternal(boneData, new BoneMatrix())); } BoneMatrix parentMatrix = CalculateSetupWorld(boneData.parent); return(GetInheritedInternal(boneData, parentMatrix)); }
/// <summary>Recursively calculates a worldspace bone matrix based on BoneData.</summary> public static BoneMatrix CalculateSetupWorld(BoneData boneData) { if (boneData == null) { return(default(BoneMatrix)); } // End condition: isRootBone if (boneData.parent == null) { return(GetInheritedInternal(boneData, default(BoneMatrix))); } BoneMatrix result = CalculateSetupWorld(boneData.parent); return(GetInheritedInternal(boneData, result)); }
static BoneMatrix GetInheritedInternal(BoneData boneData, BoneMatrix parentMatrix) { var parent = boneData.parent; if (parent == null) { return(new BoneMatrix(boneData)); // isRootBone } float pa = parentMatrix.a, pb = parentMatrix.b, pc = parentMatrix.c, pd = parentMatrix.d; BoneMatrix result = default(BoneMatrix); result.x = pa * boneData.x + pb * boneData.y + parentMatrix.x; result.y = pc * boneData.x + pd * boneData.y + parentMatrix.y; switch (boneData.transformMode) { case TransformMode.Normal: { float rotationY = boneData.rotation + 90 + boneData.shearY; float la = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; float lb = MathUtils.CosDeg(rotationY) * boneData.scaleY; float lc = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; float ld = MathUtils.SinDeg(rotationY) * boneData.scaleY; result.a = pa * la + pb * lc; result.b = pa * lb + pb * ld; result.c = pc * la + pd * lc; result.d = pc * lb + pd * ld; break; } case TransformMode.OnlyTranslation: { float rotationY = boneData.rotation + 90 + boneData.shearY; result.a = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; result.b = MathUtils.CosDeg(rotationY) * boneData.scaleY; result.c = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; result.d = MathUtils.SinDeg(rotationY) * boneData.scaleY; break; } case TransformMode.NoRotationOrReflection: { float s = pa * pa + pc * pc, prx; if (s > 0.0001f) { s = Math.Abs(pa * pd - pb * pc) / s; pb = pc * s; pd = pa * s; prx = MathUtils.Atan2(pc, pa) * MathUtils.RadDeg; } else { pa = 0; pc = 0; prx = 90 - MathUtils.Atan2(pd, pb) * MathUtils.RadDeg; } float rx = boneData.rotation + boneData.shearX - prx; float ry = boneData.rotation + boneData.shearY - prx + 90; float la = MathUtils.CosDeg(rx) * boneData.scaleX; float lb = MathUtils.CosDeg(ry) * boneData.scaleY; float lc = MathUtils.SinDeg(rx) * boneData.scaleX; float ld = MathUtils.SinDeg(ry) * boneData.scaleY; result.a = pa * la - pb * lc; result.b = pa * lb - pb * ld; result.c = pc * la + pd * lc; result.d = pc * lb + pd * ld; break; } case TransformMode.NoScale: case TransformMode.NoScaleOrReflection: { float cos = MathUtils.CosDeg(boneData.rotation), sin = MathUtils.SinDeg(boneData.rotation); float za = pa * cos + pb * sin; float zc = pc * cos + pd * sin; float s = (float)Math.Sqrt(za * za + zc * zc); if (s > 0.00001f) { s = 1 / s; } za *= s; zc *= s; s = (float)Math.Sqrt(za * za + zc * zc); float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za); float zb = MathUtils.Cos(r) * s; float zd = MathUtils.Sin(r) * s; float la = MathUtils.CosDeg(boneData.shearX) * boneData.scaleX; float lb = MathUtils.CosDeg(90 + boneData.shearY) * boneData.scaleY; float lc = MathUtils.SinDeg(boneData.shearX) * boneData.scaleX; float ld = MathUtils.SinDeg(90 + boneData.shearY) * boneData.scaleY; if (boneData.transformMode != TransformMode.NoScaleOrReflection ? pa * pd - pb * pc < 0 : false) { zb = -zb; zd = -zd; } result.a = za * la + zb * lc; result.b = za * lb + zb * ld; result.c = zc * la + zd * lc; result.d = zc * lb + zd * ld; break; } } return(result); }
private static BoneMatrix GetInheritedInternal(BoneData boneData, BoneMatrix parentMatrix) { float num12; if (boneData.parent == null) { return(new BoneMatrix(boneData)); } float a = parentMatrix.a; float b = parentMatrix.b; float c = parentMatrix.c; float d = parentMatrix.d; BoneMatrix matrix = new BoneMatrix { x = ((a * boneData.x) + (b * boneData.y)) + parentMatrix.x, y = ((c * boneData.x) + (d * boneData.y)) + parentMatrix.y }; switch (boneData.transformMode) { case TransformMode.Normal: { float num5 = (boneData.rotation + 90f) + boneData.shearY; float num6 = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; float num7 = MathUtils.CosDeg(num5) * boneData.scaleY; float num8 = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; float num9 = MathUtils.SinDeg(num5) * boneData.scaleY; matrix.a = (a * num6) + (b * num8); matrix.b = (a * num7) + (b * num9); matrix.c = (c * num6) + (d * num8); matrix.d = (c * num7) + (d * num9); return(matrix); } case TransformMode.NoRotationOrReflection: { float num11 = (a * a) + (c * c); if (num11 <= 0.0001f) { a = 0f; c = 0f; num12 = 90f - (MathUtils.Atan2(d, b) * 57.29578f); break; } num11 = Math.Abs((float)((a * d) - (b * c))) / num11; b = c * num11; d = a * num11; num12 = MathUtils.Atan2(c, a) * 57.29578f; break; } case TransformMode.NoScale: case TransformMode.NoScaleOrReflection: { float num19 = MathUtils.CosDeg(boneData.rotation); float num20 = MathUtils.SinDeg(boneData.rotation); float x = (a * num19) + (b * num20); float y = (c * num19) + (d * num20); float num23 = (float)Math.Sqrt((double)((x * x) + (y * y))); if (num23 > 1E-05f) { num23 = 1f / num23; } x *= num23; y *= num23; num23 = (float)Math.Sqrt((double)((x * x) + (y * y))); float radians = 1.570796f + MathUtils.Atan2(y, x); float num25 = MathUtils.Cos(radians) * num23; float num26 = MathUtils.Sin(radians) * num23; float num27 = MathUtils.CosDeg(boneData.shearX) * boneData.scaleX; float num28 = MathUtils.CosDeg(90f + boneData.shearY) * boneData.scaleY; float num29 = MathUtils.SinDeg(boneData.shearX) * boneData.scaleX; float num30 = MathUtils.SinDeg(90f + boneData.shearY) * boneData.scaleY; if ((boneData.transformMode != TransformMode.NoScaleOrReflection) && (((a * d) - (b * c)) < 0f)) { num25 = -num25; num26 = -num26; } matrix.a = (x * num27) + (num25 * num29); matrix.b = (x * num28) + (num25 * num30); matrix.c = (y * num27) + (num26 * num29); matrix.d = (y * num28) + (num26 * num30); return(matrix); } case (TransformMode.NoScale | TransformMode.NoRotationOrReflection): case 4: case 5: return(matrix); case TransformMode.OnlyTranslation: { float num10 = (boneData.rotation + 90f) + boneData.shearY; matrix.a = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; matrix.b = MathUtils.CosDeg(num10) * boneData.scaleY; matrix.c = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX; matrix.d = MathUtils.SinDeg(num10) * boneData.scaleY; return(matrix); } default: return(matrix); } float degrees = (boneData.rotation + boneData.shearX) - num12; float num14 = ((boneData.rotation + boneData.shearY) - num12) + 90f; float num15 = MathUtils.CosDeg(degrees) * boneData.scaleX; float num16 = MathUtils.CosDeg(num14) * boneData.scaleY; float num17 = MathUtils.SinDeg(degrees) * boneData.scaleX; float num18 = MathUtils.SinDeg(num14) * boneData.scaleY; matrix.a = (a * num15) - (b * num17); matrix.b = (a * num16) - (b * num18); matrix.c = (c * num15) + (d * num17); matrix.d = (c * num16) + (d * num18); return(matrix); }