diff --git a/core/build.gradle b/core/build.gradle index f1fe073..c18f6af 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -12,6 +12,7 @@ dependencies { implementation api("org.slf4j:slf4j-api:2.0.17") implementation api("it.unimi.dsi:fastutil:8.5.18") implementation api("io.netty:netty-buffer:4.2.7.Final") + implementation api("org.joml:joml:1.10.8") // Testing testImplementation("org.junit.jupiter:junit-jupiter-api:6.0.1") diff --git a/core/src/main/java/com/zigythebird/playeranimcore/easing/BezierEasing.java b/core/src/main/java/com/zigythebird/playeranimcore/easing/BezierEasing.java index 4ccdb5d..c013bb6 100644 --- a/core/src/main/java/com/zigythebird/playeranimcore/easing/BezierEasing.java +++ b/core/src/main/java/com/zigythebird/playeranimcore/easing/BezierEasing.java @@ -1,9 +1,9 @@ package com.zigythebird.playeranimcore.easing; import com.zigythebird.playeranimcore.animation.keyframe.AnimationPoint; -import com.zigythebird.playeranimcore.math.ModVector2d; import it.unimi.dsi.fastutil.floats.Float2FloatFunction; import org.jetbrains.annotations.Nullable; +import org.joml.Vector2f; import team.unnamed.mocha.MochaEngine; import team.unnamed.mocha.parser.ast.Expression; import team.unnamed.mocha.runtime.standard.MochaMath; @@ -44,25 +44,25 @@ public float apply(MochaEngine env, AnimationPoint animationPoint, @Nullable float time_handle_after = Math.clamp(leftTime, -gapTime, 0); CubicBezierCurve curve = new CubicBezierCurve( - new ModVector2d(0, animationPoint.animationStartValue()), - new ModVector2d(time_handle_before, animationPoint.animationStartValue() + rightValue), - new ModVector2d(time_handle_after + gapTime, animationPoint.animationEndValue() + leftValue), - new ModVector2d(gapTime, animationPoint.animationEndValue())); + new Vector2f(0, animationPoint.animationStartValue()), + new Vector2f(time_handle_before, animationPoint.animationStartValue() + rightValue), + new Vector2f(time_handle_after + gapTime, animationPoint.animationEndValue() + leftValue), + new Vector2f(gapTime, animationPoint.animationEndValue())); float time = gapTime * lerpValue; - List points = curve.getPoints(200); - ModVector2d closest = new ModVector2d(); + List points = curve.getPoints(200); + Vector2f closest = new Vector2f(); float closest_diff = Float.POSITIVE_INFINITY; - for (ModVector2d point : points) { + for (Vector2f point : points) { float diff = Math.abs(point.x - time); if (diff < closest_diff) { closest_diff = diff; closest.set(point); } } - ModVector2d second_closest = new ModVector2d(); + Vector2f second_closest = new Vector2f(); closest_diff = Float.POSITIVE_INFINITY; - for (ModVector2d point : points) { + for (Vector2f point : points) { if (point == closest) continue; float diff = Math.abs(point.x - time); if (diff < closest_diff) { @@ -90,25 +90,25 @@ boolean isEasingBefore() { } class CubicBezierCurve { - private ModVector2d v0; - private ModVector2d v1; - private ModVector2d v2; - private ModVector2d v3; + private Vector2f v0; + private Vector2f v1; + private Vector2f v2; + private Vector2f v3; - public CubicBezierCurve(ModVector2d v0, ModVector2d v1, ModVector2d v2, ModVector2d v3) { + public CubicBezierCurve(Vector2f v0, Vector2f v1, Vector2f v2, Vector2f v3) { this.v0 = v0; this.v1 = v1; this.v2 = v2; this.v3 = v3; } - public ModVector2d getPoint(float t) { - return getPoint(t, new ModVector2d()); + public Vector2f getPoint(float t) { + return getPoint(t, new Vector2f()); } - public ModVector2d getPoint(float t, ModVector2d target) { + public Vector2f getPoint(float t, Vector2f target) { if (target == null) { - target = new ModVector2d(); + target = new Vector2f(); } float u = 1 - t; @@ -123,8 +123,8 @@ public ModVector2d getPoint(float t, ModVector2d target) { return target; } - public List getPoints(int divisions) { - List points = new ArrayList<>(); + public List getPoints(int divisions) { + List points = new ArrayList<>(); for (int i = 0; i <= divisions; i++) { points.add(getPoint((float) i / divisions)); diff --git a/core/src/main/java/com/zigythebird/playeranimcore/math/ModMatrix4f.java b/core/src/main/java/com/zigythebird/playeranimcore/math/ModMatrix4f.java deleted file mode 100644 index 7a12b20..0000000 --- a/core/src/main/java/com/zigythebird/playeranimcore/math/ModMatrix4f.java +++ /dev/null @@ -1,416 +0,0 @@ -package com.zigythebird.playeranimcore.math; - -public class ModMatrix4f { - int properties; - float m00; - float m01; - float m02; - float m03; - float m10; - float m11; - float m12; - float m13; - float m20; - float m21; - float m22; - float m23; - float m30; - float m31; - float m32; - float m33; - - public ModMatrix4f() { - this._m00(1.0F)._m11(1.0F)._m22(1.0F)._m33(1.0F)._properties(30); - } - - public float m00() { - return this.m00; - } - - public float m01() { - return this.m01; - } - - public float m02() { - return this.m02; - } - - public float m03() { - return this.m03; - } - - public float m10() { - return this.m10; - } - - public float m11() { - return this.m11; - } - - public float m12() { - return this.m12; - } - - public float m13() { - return this.m13; - } - - public float m20() { - return this.m20; - } - - public float m21() { - return this.m21; - } - - public float m22() { - return this.m22; - } - - public float m23() { - return this.m23; - } - - public float m30() { - return this.m30; - } - - public float m31() { - return this.m31; - } - - public float m32() { - return this.m32; - } - - public float m33() { - return this.m33; - } - - public int properties() { - return properties; - } - - ModMatrix4f _m00(float m00) { - this.m00 = m00; - return this; - } - - ModMatrix4f _m01(float m01) { - this.m01 = m01; - return this; - } - - ModMatrix4f _m02(float m02) { - this.m02 = m02; - return this; - } - - ModMatrix4f _m03(float m03) { - this.m03 = m03; - return this; - } - - ModMatrix4f _m10(float m10) { - this.m10 = m10; - return this; - } - - ModMatrix4f _m11(float m11) { - this.m11 = m11; - return this; - } - - ModMatrix4f _m12(float m12) { - this.m12 = m12; - return this; - } - - ModMatrix4f _m13(float m13) { - this.m13 = m13; - return this; - } - - ModMatrix4f _m20(float m20) { - this.m20 = m20; - return this; - } - - ModMatrix4f _m21(float m21) { - this.m21 = m21; - return this; - } - - ModMatrix4f _m22(float m22) { - this.m22 = m22; - return this; - } - - ModMatrix4f _m23(float m23) { - this.m23 = m23; - return this; - } - - ModMatrix4f _m30(float m30) { - this.m30 = m30; - return this; - } - - ModMatrix4f _m31(float m31) { - this.m31 = m31; - return this; - } - - ModMatrix4f _m32(float m32) { - this.m32 = m32; - return this; - } - - ModMatrix4f _m33(float m33) { - this.m33 = m33; - return this; - } - - ModMatrix4f _properties(int properties) { - this.properties = properties; - return this; - } - - public void rotateX(float ang, ModMatrix4f dest) { - if ((this.properties & 4) != 0) { - dest.rotationX(ang); - } else if ((this.properties & 8) != 0) { - float x = this.m30(); - float y = this.m31(); - float z = this.m32(); - dest.rotationX(ang).setTranslation(x, y, z); - } else { - this.rotateXInternal(ang, dest); - } - } - - private void rotateXInternal(float ang, ModMatrix4f dest) { - float sin = (float) Math.sin(ang); - float cos = MathHelper.cosFromSin(sin, ang); - float lm10 = this.m10(); - float lm11 = this.m11(); - float lm12 = this.m12(); - float lm13 = this.m13(); - float lm20 = this.m20(); - float lm21 = this.m21(); - float lm22 = this.m22(); - float lm23 = this.m23(); - dest._m20(Math.fma(lm10, -sin, lm20 * cos))._m21(Math.fma(lm11, -sin, lm21 * cos))._m22(Math.fma(lm12, -sin, lm22 * cos))._m23(Math.fma(lm13, -sin, lm23 * cos))._m10(Math.fma(lm10, cos, lm20 * sin))._m11(Math.fma(lm11, cos, lm21 * sin))._m12(Math.fma(lm12, cos, lm22 * sin))._m13(Math.fma(lm13, cos, lm23 * sin))._m00(this.m00())._m01(this.m01())._m02(this.m02())._m03(this.m03())._m30(this.m30())._m31(this.m31())._m32(this.m32())._m33(this.m33())._properties(this.properties & -14); - } - - public void rotateX(float ang) { - this.rotateX(ang, this); - } - - public ModMatrix4f rotateY(float ang, ModMatrix4f dest) { - if ((this.properties & 4) != 0) { - return dest.rotationY(ang); - } else if ((this.properties & 8) != 0) { - float x = this.m30(); - float y = this.m31(); - float z = this.m32(); - return dest.rotationY(ang).setTranslation(x, y, z); - } else { - return this.rotateYInternal(ang, dest); - } - } - - private ModMatrix4f rotateYInternal(float ang, ModMatrix4f dest) { - float sin = (float) Math.sin(ang); - float cos = MathHelper.cosFromSin(sin, ang); - float nm00 = Math.fma(this.m00(), cos, this.m20() * -sin); - float nm01 = Math.fma(this.m01(), cos, this.m21() * -sin); - float nm02 = Math.fma(this.m02(), cos, this.m22() * -sin); - float nm03 = Math.fma(this.m03(), cos, this.m23() * -sin); - return dest._m20(Math.fma(this.m00(), sin, this.m20() * cos))._m21(Math.fma(this.m01(), sin, this.m21() * cos))._m22(Math.fma(this.m02(), sin, this.m22() * cos))._m23(Math.fma(this.m03(), sin, this.m23() * cos))._m00(nm00)._m01(nm01)._m02(nm02)._m03(nm03)._m10(this.m10())._m11(this.m11())._m12(this.m12())._m13(this.m13())._m30(this.m30())._m31(this.m31())._m32(this.m32())._m33(this.m33())._properties(this.properties & -14); - } - - public ModMatrix4f rotateY(float ang) { - return this.rotateY(ang, this); - } - - public ModMatrix4f rotateZ(float ang, ModMatrix4f dest) { - if ((this.properties & 4) != 0) { - return dest.rotationZ(ang); - } else if ((this.properties & 8) != 0) { - float x = this.m30(); - float y = this.m31(); - float z = this.m32(); - return dest.rotationZ(ang).setTranslation(x, y, z); - } else { - return this.rotateZInternal(ang, dest); - } - } - - private ModMatrix4f rotateZInternal(float ang, ModMatrix4f dest) { - float sin = (float) Math.sin(ang); - float cos = MathHelper.cosFromSin(sin, ang); - return this.rotateTowardsXY(sin, cos, dest); - } - - public ModMatrix4f rotateZ(float ang) { - return this.rotateZ(ang, this); - } - - public ModMatrix4f rotationX(float ang) { - float sin = (float) Math.sin(ang); - float cos = MathHelper.cosFromSin(sin, ang); - if ((this.properties & 4) == 0) { - identity(); - } - - this._m11(cos)._m12(sin)._m21(-sin)._m22(cos)._properties(18); - return this; - } - - public ModMatrix4f rotationY(float ang) { - float sin = (float) Math.sin(ang); - float cos = MathHelper.cosFromSin(sin, ang); - if ((this.properties & 4) == 0) { - identity(); - } - - this._m00(cos)._m02(-sin)._m20(sin)._m22(cos)._properties(18); - return this; - } - - public ModMatrix4f rotationZ(float ang) { - float sin = (float) Math.sin(ang); - float cos = MathHelper.cosFromSin(sin, ang); - if ((this.properties & 4) == 0) { - identity(); - } - - return this._m00(cos)._m01(sin)._m10(-sin)._m11(cos)._properties(18); - } - - public void identity() { - this._m00(1.0F)._m01(0.0F)._m02(0.0F)._m03(0.0F)._m10(0.0F)._m11(1.0F)._m12(0.0F)._m13(0.0F)._m20(0.0F)._m21(0.0F)._m22(1.0F)._m23(0.0F)._m30(0.0F)._m31(0.0F)._m32(0.0F)._m33(1.0F); - } - - public ModMatrix4f rotateTowardsXY(float dirX, float dirY, ModMatrix4f dest) { - if ((this.properties & 4) != 0) { - return dest.rotationTowardsXY(dirX, dirY); - } else { - float nm00 = Math.fma(this.m00(), dirY, this.m10() * dirX); - float nm01 = Math.fma(this.m01(), dirY, this.m11() * dirX); - float nm02 = Math.fma(this.m02(), dirY, this.m12() * dirX); - float nm03 = Math.fma(this.m03(), dirY, this.m13() * dirX); - return dest._m10(Math.fma(this.m00(), -dirX, this.m10() * dirY))._m11(Math.fma(this.m01(), -dirX, this.m11() * dirY))._m12(Math.fma(this.m02(), -dirX, this.m12() * dirY))._m13(Math.fma(this.m03(), -dirX, this.m13() * dirY))._m00(nm00)._m01(nm01)._m02(nm02)._m03(nm03)._m20(this.m20())._m21(this.m21())._m22(this.m22())._m23(this.m23())._m30(this.m30())._m31(this.m31())._m32(this.m32())._m33(this.m33())._properties(this.properties & -14); - } - } - - public ModMatrix4f rotationTowardsXY(float dirX, float dirY) { - if ((this.properties & 4) == 0) { - identity(); - } - - return this._m00(dirY)._m01(dirX)._m10(-dirX)._m11(dirY)._properties(18); - } - - public ModMatrix4f setTranslation(float x, float y, float z) { - return this._m30(x)._m31(y)._m32(z)._properties(this.properties & -6); - } - - public ModMatrix4f translate(float x, float y, float z) { - return (this.properties & 4) != 0 ? this.translation(x, y, z) : this.translateGeneric(x, y, z); - } - - private ModMatrix4f translateGeneric(float x, float y, float z) { - return this._m30(Math.fma(this.m00(), x, Math.fma(this.m10(), y, Math.fma(this.m20(), z, this.m30()))))._m31(Math.fma(this.m01(), x, Math.fma(this.m11(), y, Math.fma(this.m21(), z, this.m31()))))._m32(Math.fma(this.m02(), x, Math.fma(this.m12(), y, Math.fma(this.m22(), z, this.m32()))))._m33(Math.fma(this.m03(), x, Math.fma(this.m13(), y, Math.fma(this.m23(), z, this.m33()))))._properties(this.properties & -6); - } - - public ModMatrix4f translation(float x, float y, float z) { - if ((this.properties & 4) == 0) { - identity(); - } - - return this._m30(x)._m31(y)._m32(z)._properties(26); - } - - public ModMatrix4f scale(float x, float y, float z, ModMatrix4f dest) { - return (this.properties & 4) != 0 ? dest.scaling(x, y, z) : this.scaleGeneric(x, y, z, dest); - } - - private ModMatrix4f scaleGeneric(float x, float y, float z, ModMatrix4f dest) { - boolean one = MathHelper.absEqualsOne(x) && MathHelper.absEqualsOne(y) && MathHelper.absEqualsOne(z); - return dest._m00(this.m00() * x)._m01(this.m01() * x)._m02(this.m02() * x)._m03(this.m03() * x)._m10(this.m10() * y)._m11(this.m11() * y)._m12(this.m12() * y)._m13(this.m13() * y)._m20(this.m20() * z)._m21(this.m21() * z)._m22(this.m22() * z)._m23(this.m23() * z)._m30(this.m30())._m31(this.m31())._m32(this.m32())._m33(this.m33())._properties(this.properties & ~(13 | (one ? 0 : 16))); - } - - public ModMatrix4f scale(float x, float y, float z) { - return this.scale(x, y, z, this); - } - - public ModMatrix4f scaling(float x, float y, float z) { - if ((this.properties & 4) == 0) { - identity(); - } - - boolean one = MathHelper.absEqualsOne(x) && MathHelper.absEqualsOne(y) && MathHelper.absEqualsOne(z); - return this._m00(x)._m11(y)._m22(z)._properties(2 | (one ? 16 : 0)); - } - - public Vec3f getEulerRotation() { - float tr = m00 + m11 + m22; - float x; - float y; - float z; - float w; - if (tr >= 0.0F) { - float t = (float) Math.sqrt(tr + 1.0F); - w = t * 0.5F; - t = 0.5F / t; - x = (m12 - m21) * t; - y = (m20 - m02) * t; - z = (m01 - m10) * t; - } else if (m00 >= m11 && m00 >= m22) { - float t = (float) Math.sqrt(m00 - (m11 + m22) + 1.0F); - x = t * 0.5F; - t = 0.5F / t; - y = (m10 + m01) * t; - z = (m02 + m20) * t; - w = (m12 - m21) * t; - } else if (m11 > m22) { - float t = (float) Math.sqrt(m11 - (m22 + m00) + 1.0F); - y = t * 0.5F; - t = 0.5F / t; - z = (m21 + m12) * t; - x = (m10 + m01) * t; - w = (m20 - m02) * t; - } else { - float t = (float) Math.sqrt(m22 - (m00 + m11) + 1.0F); - z = t * 0.5F; - t = 0.5F / t; - x = (m02 + m20) * t; - y = (m21 + m12) * t; - w = (m01 - m10) * t; - } - - return new Vec3f((float) Math.atan2(y * z + w * x, 0.5F - x * x - y * y), - MathHelper.safeAsin(-2.0F * (x * z - w * y)), - (float) Math.atan2(x * y + w * z, 0.5F - y * y - z * z)); - } - - public float getColumnScale(int i) { - switch (i) { - case 0 -> { - return MathHelper.length(m00, m01, m02, m03); - } - case 1 -> { - return MathHelper.length(m10, m11, m12, m13); - } - case 2 -> { - return MathHelper.length(m20, m21, m22, m23); - } - case 3 -> { - return MathHelper.length(m30, m31, m32, m33); - } - } - return 1; - } -} diff --git a/core/src/main/java/com/zigythebird/playeranimcore/math/ModVector2d.java b/core/src/main/java/com/zigythebird/playeranimcore/math/ModVector2d.java deleted file mode 100644 index 69f7a68..0000000 --- a/core/src/main/java/com/zigythebird/playeranimcore/math/ModVector2d.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.zigythebird.playeranimcore.math; - -public class ModVector2d { - public float x; - public float y; - - public ModVector2d() {} - - public ModVector2d(float x, float y) { - this.x = x; - this.y = y; - } - - public void set(ModVector2d vector2d) { - this.x = vector2d.x; - this.y = vector2d.y; - } -} diff --git a/core/src/main/java/com/zigythebird/playeranimcore/math/ModVector4f.java b/core/src/main/java/com/zigythebird/playeranimcore/math/ModVector4f.java deleted file mode 100644 index 556bead..0000000 --- a/core/src/main/java/com/zigythebird/playeranimcore/math/ModVector4f.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.zigythebird.playeranimcore.math; - -public class ModVector4f { - public float x; - public float y; - public float z; - public float w; - - public ModVector4f(float x, float y, float z, float w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - - public ModVector4f mul(ModMatrix4f mat) { - int prop = mat.properties(); - if ((prop & 4) != 0) { - return this; - } else if ((prop & 8) != 0) { - return this.mulTranslation(mat); - } else { - return (prop & 2) != 0 ? this.mulAffine(mat) : this.mulGeneric(mat); - } - } - - public ModVector4f mulAffine(ModMatrix4f mat) { - float x = this.x; - float y = this.y; - float z = this.z; - float w = this.w; - this.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30() * w))); - this.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31() * w))); - this.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32() * w))); - this.w = w; - return this; - } - - public ModVector4f mulGeneric(ModMatrix4f mat) { - float x = this.x; - float y = this.y; - float z = this.z; - float w = this.w; - this.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30() * w))); - this.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31() * w))); - this.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32() * w))); - this.w = Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33() * w))); - return this; - } - - public ModVector4f mulTranslation(ModMatrix4f mat) { - this.x = Math.fma(mat.m30(), this.w, this.x); - this.y = Math.fma(mat.m31(), this.w, this.y); - this.z = Math.fma(mat.m32(), this.w, this.z); - return this; - } -} diff --git a/core/src/main/java/com/zigythebird/playeranimcore/util/MatrixUtil.java b/core/src/main/java/com/zigythebird/playeranimcore/util/MatrixUtil.java index ad4b6d3..561cf15 100644 --- a/core/src/main/java/com/zigythebird/playeranimcore/util/MatrixUtil.java +++ b/core/src/main/java/com/zigythebird/playeranimcore/util/MatrixUtil.java @@ -2,8 +2,9 @@ import com.zigythebird.playeranimcore.bones.PivotBone; import com.zigythebird.playeranimcore.bones.PlayerAnimBone; -import com.zigythebird.playeranimcore.math.ModMatrix4f; import com.zigythebird.playeranimcore.math.Vec3f; +import org.joml.Matrix4f; +import org.joml.Vector3f; import java.util.function.Function; @@ -12,28 +13,28 @@ * Used for applying custom pivot bones to player bones */ public class MatrixUtil { - public static void translateMatrixForBone(ModMatrix4f matrix, PlayerAnimBone bone) { + public static void translateMatrixForBone(Matrix4f matrix, PlayerAnimBone bone) { matrix.translate(-bone.getPosX(), bone.getPosY(), -bone.getPosZ()); } - public static void rotateMatrixAroundBone(ModMatrix4f matrix, PlayerAnimBone bone) { + public static void rotateMatrixAroundBone(Matrix4f matrix, PlayerAnimBone bone) { if (bone.getRotZ() != 0 || bone.getRotY() != 0 || bone.getRotX() != 0) matrix.rotateZ(bone.getRotZ()).rotateY(bone.getRotY()).rotateX(bone.getRotX()); } - public static void scaleMatrixForBone(ModMatrix4f matrix, PlayerAnimBone bone) { + public static void scaleMatrixForBone(Matrix4f matrix, PlayerAnimBone bone) { matrix.scale(bone.getScaleX(), bone.getScaleY(), bone.getScaleZ()); } - public static void translateToPivotPoint(ModMatrix4f matrix, Vec3f pivot) { + public static void translateToPivotPoint(Matrix4f matrix, Vec3f pivot) { matrix.translate(pivot.x(), pivot.y(), pivot.z()); } - public static void translateAwayFromPivotPoint(ModMatrix4f matrix, Vec3f pivot) { + public static void translateAwayFromPivotPoint(Matrix4f matrix, Vec3f pivot) { matrix.translate(-pivot.x(), -pivot.y(), -pivot.z()); } - public static void prepMatrixForBone(ModMatrix4f matrix, PlayerAnimBone bone, Vec3f pivot) { + public static void prepMatrixForBone(Matrix4f matrix, PlayerAnimBone bone, Vec3f pivot) { translateToPivotPoint(matrix, pivot); translateMatrixForBone(matrix, bone); rotateMatrixAroundBone(matrix, bone); @@ -42,7 +43,7 @@ public static void prepMatrixForBone(ModMatrix4f matrix, PlayerAnimBone bone, Ve } public static void applyParentsToChild(PlayerAnimBone child, Iterable parents, Function positions) { - ModMatrix4f matrix = new ModMatrix4f(); + Matrix4f matrix = new Matrix4f(); for (PlayerAnimBone parent : parents) { Vec3f pivot = parent instanceof PivotBone pivotBone ? pivotBone.getPivot() : positions.apply(parent.getName()); @@ -56,9 +57,10 @@ public static void applyParentsToChild(PlayerAnimBone child, Iterable