diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/model/human/animator/ArmAnimator.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/model/human/animator/ArmAnimator.kt index a923df90c..33f5bc592 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/model/human/animator/ArmAnimator.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/model/human/animator/ArmAnimator.kt @@ -66,7 +66,7 @@ class ArmAnimator( val z = (1.0f - (swing * 1.2f)) * (-20.0f).rad // TODO: animate the 1.2f back to 1.0f val y = sin * 0.2f - val x = (sin * 1.2f + sin) * -0.65f + val x = sin * -1.4f transform.value.rotateRadAssign(Vec3(x, y, if (arm == Arms.RIGHT) z else -z)) diff --git a/src/main/resources/assets/minosoft/rendering/shader/includes/skeletal/shade.glsl b/src/main/resources/assets/minosoft/rendering/shader/includes/skeletal/shade.glsl index d9a12e064..4a236e2ef 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/includes/skeletal/shade.glsl +++ b/src/main/resources/assets/minosoft/rendering/shader/includes/skeletal/shade.glsl @@ -26,7 +26,7 @@ vec3 decodeNormal(uint normal) { vec3 transformNormal(vec3 normal, mat4 transform) { // return normalize(mat3(transpose(inverse(transform))) * normal); - return mat3(transform) * normal; + return normalize(mat3(transform) * normal); } float interpolateShade(float delta, float max) { diff --git a/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/SkeletalShadeTest.kt b/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/SkeletalShadeTest.kt index af74a5383..9fa04fb03 100644 --- a/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/SkeletalShadeTest.kt +++ b/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/SkeletalShadeTest.kt @@ -13,6 +13,9 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.baked +import de.bixilon.kotlinglm.func.rad +import de.bixilon.kotlinglm.mat3x3.Mat3 +import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.kotlinglm.vec3.Vec3 import org.junit.jupiter.api.Test import kotlin.math.abs @@ -50,6 +53,11 @@ class SkeletalShadeTest { return x + y + z } + fun transformNormal(normal: Vec3, transform: Mat4): Vec3 { + // return normalize(mat3(transpose(inverse(transform))) * normal); + return (Mat3(transform) * normal).normalizeAssign() + } + @Test fun up() { assertEquals(1.0f, getShade(Vec3(0, 1, 0))) @@ -105,7 +113,63 @@ class SkeletalShadeTest { assertEquals(0.94f, getShade(Vec3(1, 1, 1))) } - // TODO: test transforming + + private fun assertEquals(actual: Vec3, expected: Vec3) { + val delta = actual - expected + if (delta.length2() < 0.01f) return + throw AssertionError("Expected $expected, but got $actual") + } + + @Test + fun `transform rotate Y 90deg`() { + val transform = Mat4().rotateYassign(90.0f.rad) + val normal = Vec3(0.0f, 1.0f, 0.0f) + assertEquals(transformNormal(normal, transform), Vec3(0.0f, 1.0f, 0.0f)) + } + + @Test + fun `transform rotate Y 180deg`() { + val transform = Mat4().rotateYassign(180.0f.rad) + val normal = Vec3(0.0f, -1.0f, 0.0f) + assertEquals(transformNormal(normal, transform), Vec3(0.0f, -1.0f, 0.0f)) + } + + + @Test + fun `transform rotate Y 90deg 2`() { + val transform = Mat4().rotateYassign(90.0f.rad) + val normal = Vec3(1.0f, 0.0f, 0.0f) + assertEquals(transformNormal(normal, transform), Vec3(0.0f, 0.0f, -1.0f)) + } + + @Test + fun `transform rotate Y 180deg 2`() { + val transform = Mat4().rotateYassign(180.0f.rad) + val normal = Vec3(1.0f, 0.0f, 0.0f) + assertEquals(transformNormal(normal, transform), Vec3(-1.0f, 0.0f, 0.0f)) + } + + @Test + fun `transform translated`() { + val transform = Mat4() + .translateAssign(Vec3(123, 456, 789)) + .rotateYassign(180.0f.rad) + val normal = Vec3(1.0f, 0.0f, 0.0f) + assertEquals(transformNormal(normal, transform), Vec3(-1.0f, 0.0f, 0.0f)) + } + + @Test + fun `transform translated scaled`() { + val transform = Mat4() + .scaleAssign(0.4f) + .translateAssign(Vec3(123, 456, 789)) + .rotateYassign(180.0f.rad) + val normal = Vec3(1.0f, 0.0f, 0.0f) + assertEquals(transformNormal(normal, transform), Vec3(-1.0f, 0.0f, 0.0f)) + } + + // TODO: test why shade is wrong sometimes + private fun assertEquals(expected: Float, actual: Float) { if (abs(expected - actual) < 0.03f) return