diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java index 8cb66a7f0..433eb5445 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java @@ -17,7 +17,6 @@ public final class InstanceTypes { .vector("overlay", IntegerRepr.SHORT, 2) .vector("light", FloatRepr.UNSIGNED_SHORT, 2) .matrix("pose", FloatRepr.FLOAT, 4) - .matrix("normal", FloatRepr.FLOAT, 3) .build()) .writer((ptr, instance) -> { MemoryUtil.memPutByte(ptr, instance.red); @@ -27,12 +26,33 @@ public final class InstanceTypes { ExtraMemoryOps.put2x16(ptr + 4, instance.overlay); ExtraMemoryOps.put2x16(ptr + 8, instance.light); ExtraMemoryOps.putMatrix4f(ptr + 12, instance.model); - ExtraMemoryOps.putMatrix3f(ptr + 76, instance.normal); }) .vertexShader(Flywheel.rl("instance/transformed.vert")) .cullShader(Flywheel.rl("instance/cull/transformed.glsl")) .register(); + public static final InstanceType POSED = SimpleInstanceType.builder(PosedInstance::new) + .layout(LayoutBuilder.create() + .vector("color", FloatRepr.NORMALIZED_UNSIGNED_BYTE, 4) + .vector("overlay", IntegerRepr.SHORT, 2) + .vector("light", FloatRepr.UNSIGNED_SHORT, 2) + .matrix("pose", FloatRepr.FLOAT, 4) + .matrix("normal", FloatRepr.FLOAT, 3) + .build()) + .writer((ptr, instance) -> { + MemoryUtil.memPutByte(ptr, instance.red); + MemoryUtil.memPutByte(ptr + 1, instance.green); + MemoryUtil.memPutByte(ptr + 2, instance.blue); + MemoryUtil.memPutByte(ptr + 3, instance.alpha); + ExtraMemoryOps.put2x16(ptr + 4, instance.overlay); + ExtraMemoryOps.put2x16(ptr + 8, instance.light); + ExtraMemoryOps.putMatrix4f(ptr + 12, instance.model); + ExtraMemoryOps.putMatrix3f(ptr + 76, instance.normal); + }) + .vertexShader(Flywheel.rl("instance/posed.vert")) + .cullShader(Flywheel.rl("instance/cull/posed.glsl")) + .register(); + public static final InstanceType ORIENTED = SimpleInstanceType.builder(OrientedInstance::new) .layout(LayoutBuilder.create() .vector("color", FloatRepr.NORMALIZED_UNSIGNED_BYTE, 4) diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/PosedInstance.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/PosedInstance.java new file mode 100644 index 000000000..d21b5e17f --- /dev/null +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/PosedInstance.java @@ -0,0 +1,104 @@ +package dev.engine_room.flywheel.lib.instance; + +import org.joml.Matrix3f; +import org.joml.Matrix3fc; +import org.joml.Matrix4f; +import org.joml.Matrix4fc; +import org.joml.Quaternionfc; + +import com.mojang.blaze3d.vertex.PoseStack; + +import dev.engine_room.flywheel.api.instance.InstanceHandle; +import dev.engine_room.flywheel.api.instance.InstanceType; +import dev.engine_room.flywheel.lib.transform.Transform; +import net.minecraft.util.Mth; + +public class PosedInstance extends ColoredLitInstance implements Transform { + public final Matrix4f model = new Matrix4f(); + public final Matrix3f normal = new Matrix3f(); + + public PosedInstance(InstanceType type, InstanceHandle handle) { + super(type, handle); + } + + @Override + public PosedInstance mulPose(Matrix4fc pose) { + this.model.mul(pose); + return this; + } + + @Override + public PosedInstance mulNormal(Matrix3fc normal) { + this.normal.mul(normal); + return this; + } + + @Override + public PosedInstance rotateAround(Quaternionfc quaternion, float x, float y, float z) { + model.rotateAround(quaternion, x, y, z); + normal.rotate(quaternion); + return this; + } + + @Override + public PosedInstance translate(float x, float y, float z) { + model.translate(x, y, z); + return this; + } + + @Override + public PosedInstance rotate(Quaternionfc quaternion) { + model.rotate(quaternion); + normal.rotate(quaternion); + return this; + } + + @Override + public PosedInstance scale(float x, float y, float z) { + model.scale(x, y, z); + + if (x == y && y == z) { + if (x < 0.0f) { + normal.scale(-1.0f); + } + + return this; + } + + float invX = 1.0f / x; + float invY = 1.0f / y; + float invZ = 1.0f / z; + float f = Mth.fastInvCubeRoot(Math.abs(invX * invY * invZ)); + normal.scale(f * invX, f * invY, f * invZ); + return this; + } + + public PosedInstance setTransform(PoseStack.Pose pose) { + model.set(pose.pose()); + normal.set(pose.normal()); + return this; + } + + public PosedInstance setTransform(PoseStack stack) { + return setTransform(stack.last()); + } + + public PosedInstance setIdentityTransform() { + model.identity(); + normal.identity(); + return this; + } + + /** + * Sets the transform matrices to be all zeros. + * + *

+ * This will allow the GPU to quickly discard all geometry for this instance, effectively "turning it off". + *

+ */ + public PosedInstance setZeroTransform() { + model.zero(); + normal.zero(); + return this; + } +} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/TransformedInstance.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/TransformedInstance.java index 13938d201..73e57e4d0 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/TransformedInstance.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/TransformedInstance.java @@ -1,42 +1,25 @@ package dev.engine_room.flywheel.lib.instance; -import org.joml.Matrix3f; -import org.joml.Matrix3fc; import org.joml.Matrix4f; -import org.joml.Matrix4fc; import org.joml.Quaternionfc; import com.mojang.blaze3d.vertex.PoseStack; import dev.engine_room.flywheel.api.instance.InstanceHandle; import dev.engine_room.flywheel.api.instance.InstanceType; -import dev.engine_room.flywheel.lib.transform.Transform; -import net.minecraft.util.Mth; +import dev.engine_room.flywheel.lib.transform.Affine; -public class TransformedInstance extends ColoredLitInstance implements Transform { + +public class TransformedInstance extends ColoredLitInstance implements Affine { public final Matrix4f model = new Matrix4f(); - public final Matrix3f normal = new Matrix3f(); public TransformedInstance(InstanceType type, InstanceHandle handle) { super(type, handle); } - @Override - public TransformedInstance mulPose(Matrix4fc pose) { - this.model.mul(pose); - return this; - } - - @Override - public TransformedInstance mulNormal(Matrix3fc normal) { - this.normal.mul(normal); - return this; - } - @Override public TransformedInstance rotateAround(Quaternionfc quaternion, float x, float y, float z) { model.rotateAround(quaternion, x, y, z); - normal.rotate(quaternion); return this; } @@ -49,33 +32,17 @@ public TransformedInstance translate(float x, float y, float z) { @Override public TransformedInstance rotate(Quaternionfc quaternion) { model.rotate(quaternion); - normal.rotate(quaternion); return this; } @Override public TransformedInstance scale(float x, float y, float z) { model.scale(x, y, z); - - if (x == y && y == z) { - if (x < 0.0f) { - normal.scale(-1.0f); - } - - return this; - } - - float invX = 1.0f / x; - float invY = 1.0f / y; - float invZ = 1.0f / z; - float f = Mth.fastInvCubeRoot(Math.abs(invX * invY * invZ)); - normal.scale(f * invX, f * invY, f * invZ); return this; } public TransformedInstance setTransform(PoseStack.Pose pose) { model.set(pose.pose()); - normal.set(pose.normal()); return this; } @@ -85,7 +52,6 @@ public TransformedInstance setTransform(PoseStack stack) { public TransformedInstance setIdentityTransform() { model.identity(); - normal.identity(); return this; } @@ -98,7 +64,6 @@ public TransformedInstance setIdentityTransform() { */ public TransformedInstance setZeroTransform() { model.zero(); - normal.zero(); return this; } } diff --git a/common/src/lib/resources/assets/flywheel/flywheel/instance/cull/posed.glsl b/common/src/lib/resources/assets/flywheel/flywheel/instance/cull/posed.glsl new file mode 100644 index 000000000..c8d9a275c --- /dev/null +++ b/common/src/lib/resources/assets/flywheel/flywheel/instance/cull/posed.glsl @@ -0,0 +1,5 @@ +#include "flywheel:util/matrix.glsl" + +void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout float radius) { + transformBoundingSphere(i.pose, center, radius); +} diff --git a/common/src/lib/resources/assets/flywheel/flywheel/instance/posed.vert b/common/src/lib/resources/assets/flywheel/flywheel/instance/posed.vert new file mode 100644 index 000000000..918883e84 --- /dev/null +++ b/common/src/lib/resources/assets/flywheel/flywheel/instance/posed.vert @@ -0,0 +1,8 @@ +void flw_instanceVertex(in FlwInstance i) { + flw_vertexPos = i.pose * flw_vertexPos; + flw_vertexNormal = i.normal * flw_vertexNormal; + flw_vertexColor *= i.color; + flw_vertexOverlay = i.overlay; + // Some drivers have a bug where uint over float division is invalid, so use an explicit cast. + flw_vertexLight = vec2(i.light) / 256.0; +} diff --git a/common/src/lib/resources/assets/flywheel/flywheel/instance/transformed.vert b/common/src/lib/resources/assets/flywheel/flywheel/instance/transformed.vert index 918883e84..e0abf722b 100644 --- a/common/src/lib/resources/assets/flywheel/flywheel/instance/transformed.vert +++ b/common/src/lib/resources/assets/flywheel/flywheel/instance/transformed.vert @@ -1,6 +1,6 @@ void flw_instanceVertex(in FlwInstance i) { flw_vertexPos = i.pose * flw_vertexPos; - flw_vertexNormal = i.normal * flw_vertexNormal; + flw_vertexNormal = mat3(transpose(inverse(i.pose))) * flw_vertexNormal; flw_vertexColor *= i.color; flw_vertexOverlay = i.overlay; // Some drivers have a bug where uint over float division is invalid, so use an explicit cast.