diff --git a/src/main/java/net/minecraftforge/client/model/obj/ObjModel.java b/src/main/java/net/minecraftforge/client/model/obj/ObjModel.java index 5901efb8ad..c2bf5db5b0 100644 --- a/src/main/java/net/minecraftforge/client/model/obj/ObjModel.java +++ b/src/main/java/net/minecraftforge/client/model/obj/ObjModel.java @@ -490,7 +490,7 @@ public class ObjModel extends SimpleUnbakedGeometry } } - return Pair.of(quadBaker.getQuad(), cull); + return Pair.of(quadBaker.build(), cull); } public CompositeRenderable bakeRenderable(IGeometryBakingContext configuration) diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/QuadBakingVertexConsumer.java b/src/main/java/net/minecraftforge/client/model/pipeline/QuadBakingVertexConsumer.java index 94bfaa7efc..174adab668 100644 --- a/src/main/java/net/minecraftforge/client/model/pipeline/QuadBakingVertexConsumer.java +++ b/src/main/java/net/minecraftforge/client/model/pipeline/QuadBakingVertexConsumer.java @@ -33,11 +33,12 @@ public class QuadBakingVertexConsumer implements VertexConsumer for (var element : DefaultVertexFormat.BLOCK.getElements()) map.put(element, DefaultVertexFormat.BLOCK.getOffset(i++) / 4); // Int offset }); - private static final int QUAD_DATA_SIZE = IQuadTransformer.STRIDE * 4; + private static final int MAX_VERTICES = 4; + private static final int QUAD_DATA_SIZE = IQuadTransformer.STRIDE * MAX_VERTICES; private final Consumer quadConsumer; - int vertexIndex = 0; + int vertexIndex = -1; private int[] quadData = new int[QUAD_DATA_SIZE]; private int tintIndex; @@ -54,7 +55,8 @@ public class QuadBakingVertexConsumer implements VertexConsumer @Override public VertexConsumer addVertex(float x, float y, float z) { - endVertex(); + if (vertexIndex++ == MAX_VERTICES) + build(); int offset = vertexIndex * IQuadTransformer.STRIDE + IQuadTransformer.POSITION; quadData[offset] = Float.floatToRawIntBits((float) x); @@ -124,16 +126,14 @@ public class QuadBakingVertexConsumer implements VertexConsumer return this; } - private void endVertex() + public BakedQuad build() { - if (vertexIndex != 4) { - ++vertexIndex; - return; - } + BakedQuad quad = new BakedQuad(quadData, tintIndex, direction, sprite, shade, hasAmbientOcclusion); // We have a full quad, pass it to the consumer and reset - quadConsumer.accept(new BakedQuad(quadData, tintIndex, direction, sprite, shade, hasAmbientOcclusion)); + quadConsumer.accept(quad); vertexIndex = 0; quadData = new int[QUAD_DATA_SIZE]; + return quad; } public void setTintIndex(int tintIndex) diff --git a/src/test/java/net/minecraftforge/debug/client/ObjModelTest.java b/src/test/java/net/minecraftforge/debug/client/ObjModelTest.java new file mode 100644 index 0000000000..4b479ce722 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/client/ObjModelTest.java @@ -0,0 +1,74 @@ +package net.minecraftforge.debug.client; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.client.event.ModelEvent; +import net.minecraftforge.client.event.RenderLevelStageEvent; +import net.minecraftforge.client.model.data.ModelData; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + +/** + * Tests loading and rendering an obj-model using the using Forge's {@link net.minecraftforge.client.model.obj.ObjLoader}. + * When enabled, this will render a pyramid loaded from an obj model at coordinates 0,0,0. + */ +@Mod(ObjModelTest.MODID) +public class ObjModelTest { + private static final boolean ENABLED = true; + + public static final String MODID = "obj_model_test"; + private static final PoseStack POSE_STACK = new PoseStack(); + private static final ModelResourceLocation PYRAMID_MODEL_LOCATION = new ModelResourceLocation(ResourceLocation.fromNamespaceAndPath(MODID, "pyramid"), ""); + private static BakedModel pyramidModel; + + public ObjModelTest() { + if (ENABLED) { + FMLJavaModLoadingContext.get().getModEventBus().addListener(ObjModelTest::registerObjModel); + FMLJavaModLoadingContext.get().getModEventBus().addListener(ObjModelTest::collectObjModel); + MinecraftForge.EVENT_BUS.addListener(ObjModelTest::renderModel); + } + } + + public static void registerObjModel(ModelEvent.RegisterAdditional e) { + e.register(PYRAMID_MODEL_LOCATION); + } + + public static void collectObjModel(ModelEvent.BakingCompleted e) { + pyramidModel = e.getModels().get(PYRAMID_MODEL_LOCATION); + } + + public static void renderModel(RenderLevelStageEvent e) { + if (e.getStage() == RenderLevelStageEvent.Stage.AFTER_SOLID_BLOCKS) { + POSE_STACK.setIdentity(); + Vec3 camera = e.getCamera().getPosition(); + //noinspection removal + POSE_STACK.mulPose(e.getPoseStack()); + POSE_STACK.translate(0.5 - camera.x, 0.5 - camera.y, 0.5 - camera.z); + MultiBufferSource.BufferSource bufferSource = Minecraft.getInstance().renderBuffers().bufferSource(); + // Render the obj model + Minecraft.getInstance().getBlockRenderer().getModelRenderer().renderModel( + POSE_STACK.last(), + bufferSource.getBuffer(RenderType.solid()), + null, + pyramidModel, + 1, + 1, + 1, + LightTexture.FULL_BRIGHT, + OverlayTexture.NO_OVERLAY, + ModelData.EMPTY, + RenderType.solid() + ); + bufferSource.endBatch(); + } + } +} diff --git a/src/test/resources/obj_model_test/assets/minecraft/atlases/blocks.json b/src/test/resources/obj_model_test/assets/minecraft/atlases/blocks.json new file mode 100644 index 0000000000..7e6f3ae7a8 --- /dev/null +++ b/src/test/resources/obj_model_test/assets/minecraft/atlases/blocks.json @@ -0,0 +1,8 @@ +{ + "sources": [ + { + "type": "single", + "resource": "obj_model_test:pyramid" + } + ] +} diff --git a/src/test/resources/obj_model_test/assets/obj_model_test/models/pyramid.json b/src/test/resources/obj_model_test/assets/obj_model_test/models/pyramid.json new file mode 100644 index 0000000000..b90ab42ede --- /dev/null +++ b/src/test/resources/obj_model_test/assets/obj_model_test/models/pyramid.json @@ -0,0 +1,8 @@ +{ + "loader": "forge:obj", + "model": "obj_model_test:models/pyramid.obj", + "flip-v": true, + "detectCullableFaces": false, + "diffuseLighting": false, + "ambientToFullbright": true +} \ No newline at end of file diff --git a/src/test/resources/obj_model_test/assets/obj_model_test/models/pyramid.mtl b/src/test/resources/obj_model_test/assets/obj_model_test/models/pyramid.mtl new file mode 100644 index 0000000000..862e652bca --- /dev/null +++ b/src/test/resources/obj_model_test/assets/obj_model_test/models/pyramid.mtl @@ -0,0 +1,4 @@ +# Made in Blockbench 4.9.4 +newmtl m_d61f9499-1bf7-4e99-8524-c1ff74261694 +map_Kd obj_model_test:pyramid +newmtl none \ No newline at end of file diff --git a/src/test/resources/obj_model_test/assets/obj_model_test/models/pyramid.obj b/src/test/resources/obj_model_test/assets/obj_model_test/models/pyramid.obj new file mode 100644 index 0000000000..cda9a03cd6 --- /dev/null +++ b/src/test/resources/obj_model_test/assets/obj_model_test/models/pyramid.obj @@ -0,0 +1,36 @@ +# Made in Blockbench 4.9.4 +mtllib pyramid.mtl + +o pyramid +v 0 1 0 +v 0.5 0 0.5 +v 0.5 0 -0.5 +v -0.5 0 0.5 +v -0.5 0 -0.5 +vt 0.6875 0.25 +vt 0.6875 0 +vt 0.4375 0 +vt 0.4375 0.25 +vt 0.3780786804403148 0.5791233118566227 +vt 0.6062963195596852 0.6811855928167345 +vt 0.6062963195596851 0.375 +vt 0.003078680440314799 0.2041233118566227 +vt 0.23129631955968522 0.3061855928167345 +vt 0.23129631955968505 0 +vt 0.19057868044031478 0.3916233118566227 +vt 0.4187963195596852 0.4936855928167345 +vt 0.41879631955968505 0.1875 +vt 0.003078680440314799 0.6416233118566227 +vt 0.23129631955968522 0.7436855928167345 +vt 0.23129631955968505 0.4375 +vn 0 -1 0 +vn 0.8944271909999161 0.44721359549995804 0 +vn 0 0.44721359549995804 0.8944271909999161 +vn 0 0.44721359549995804 -0.8944271909999161 +vn -0.8944271909999161 0.44721359549995804 0 +usemtl m_d61f9499-1bf7-4e99-8524-c1ff74261694 +f 3/1/1 2/2/1 4/3/1 5/4/1 +f 2/5/2 3/6/2 1/7/2 +f 4/8/3 2/9/3 1/10/3 +f 3/11/4 5/12/4 1/13/4 +f 5/14/5 4/15/5 1/16/5 \ No newline at end of file diff --git a/src/test/resources/obj_model_test/assets/obj_model_test/textures/pyramid.png b/src/test/resources/obj_model_test/assets/obj_model_test/textures/pyramid.png new file mode 100644 index 0000000000..c5d8a446c1 Binary files /dev/null and b/src/test/resources/obj_model_test/assets/obj_model_test/textures/pyramid.png differ