Take mesh-rotating out of the hot path

This commit is contained in:
quat1024 2023-07-03 05:17:48 -04:00
parent 3c57778ea1
commit e8ee279355
3 changed files with 58 additions and 46 deletions

View File

@ -1,39 +0,0 @@
package io.github.cottonmc.templates.model;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.util.math.AffineTransformation;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.joml.Vector4f;
public record AffineQuadTransformer(Matrix4f affineMatrix) implements RenderContext.QuadTransform {
public AffineQuadTransformer(AffineTransformation aff) {
this(aff.getMatrix());
}
@Override
public boolean transform(MutableQuadView quad) {
Vector3f pos3 = new Vector3f();
Vector4f pos4 = new Vector4f(); //ugh
for(int i = 0; i < 4; i++) {
//Copy pos into a vec3, then a vec4. the w component is set to 0 since this is a point, not a normal
quad.copyPos(i, pos3);
//kinda a hack to center the affine transformation not at 0,0,0
//it's an *affine* transformation, they can rotate around the not-origin... should modify the transformation instead?
pos3.add(-0.5f, -0.5f, -0.5f);
pos4.set(pos3, 0);
//Compute the matrix-vector product. This function mutates the vec4 in-place.
//Note that `transformAffine` has the same purpose as `transform`; the difference is it
//assumes (without checking) that the last row of the matrix is 0,0,0,1, as an optimization
affineMatrix.transformAffine(pos4);
//Manually copy the data back onto the vertex
quad.pos(i, pos4.x + 0.5f, pos4.y + 0.5f, pos4.z + 0.5f);
}
return true;
}
}

View File

@ -0,0 +1,57 @@
package io.github.cottonmc.templates.model;
import io.github.cottonmc.templates.TemplatesClient;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.minecraft.util.math.AffineTransformation;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.joml.Vector4f;
/**
* Transforms the position of each vertex in a `Mesh`.
* The transformation's origin is bumped to (0.5, 0.5, 0.5) just because it's more convenient for me lol.
*/
public class MatrixMeshTransformer {
public static Mesh transformAroundCenter(AffineTransformation aff, Mesh oldMesh) {
return transformAroundCenter(aff.getMatrix(), oldMesh);
}
public static Mesh transformAroundCenter(Matrix4f mat, Mesh oldMesh) {
Renderer r = TemplatesClient.getFabricRenderer();
MeshBuilder newMesh = r.meshBuilder();
QuadEmitter emitter = newMesh.getEmitter();
//re-used buffers
Vector3f pos3 = new Vector3f();
Vector4f pos4 = new Vector4f();
oldMesh.forEach(oldQuad -> {
//Initialize the new quad
emitter.copyFrom(oldQuad);
//For each vertex:
for(int i = 0; i < 4; i++) {
//Copy pos into a vec3, then a vec4. the w component is set to 0 since this is a point, not a normal
emitter.copyPos(i, pos3);
pos3.add(-0.5f, -0.5f, -0.5f);
pos4.set(pos3, 0);
//Compute the matrix-vector product. This function mutates the vec4 in-place.
//Note that `transformAffine` has the same purpose as `transform`; the difference is it
//assumes (without checking) that the last row of the matrix is 0,0,0,1, as an optimization
mat.transform(pos4);
//Manually copy the data back onto the vertex
emitter.pos(i, pos4.x + 0.5f, pos4.y + 0.5f, pos4.z + 0.5f);
}
//Output the quad
emitter.emit();
});
return newMesh.build();
}
}

View File

@ -31,8 +31,7 @@ public final class TemplateBakedModel extends ForwardingBakedModel {
this.wrapped = baseModel; this.wrapped = baseModel;
this.tam = tam; this.tam = tam;
this.affineTransformer = new AffineQuadTransformer(aff); this.baseMesh = MatrixMeshTransformer.transformAroundCenter(aff, baseMesh);
this.baseMesh = baseMesh;
//Hard to explain what this is for... //Hard to explain what this is for...
//Basically, the previous incarnation of this mod assembled the north/south/east/west faces all individually. //Basically, the previous incarnation of this mod assembled the north/south/east/west faces all individually.
@ -50,7 +49,6 @@ public final class TemplateBakedModel extends ForwardingBakedModel {
} }
private final TemplateAppearanceManager tam; private final TemplateAppearanceManager tam;
private final AffineQuadTransformer affineTransformer;
private final Mesh baseMesh; private final Mesh baseMesh;
private final Map<Direction, Direction> facePermutation = new EnumMap<>(Direction.class); private final Map<Direction, Direction> facePermutation = new EnumMap<>(Direction.class);
@ -62,20 +60,16 @@ public final class TemplateBakedModel extends ForwardingBakedModel {
@Override @Override
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) { public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
context.pushTransform(affineTransformer);
context.pushTransform(retexturingBlockTransformer(blockView, state, pos, randomSupplier)); context.pushTransform(retexturingBlockTransformer(blockView, state, pos, randomSupplier));
context.meshConsumer().accept(baseMesh); context.meshConsumer().accept(baseMesh);
context.popTransform(); context.popTransform();
context.popTransform();
} }
@Override @Override
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) { public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
context.pushTransform(affineTransformer);
context.pushTransform(retexturingItemTransformer(stack, randomSupplier)); context.pushTransform(retexturingItemTransformer(stack, randomSupplier));
context.meshConsumer().accept(baseMesh); context.meshConsumer().accept(baseMesh);
context.popTransform(); context.popTransform();
context.popTransform();
} }
@Override @Override