Chronically inline

- Replace ModelUtil.VANILLA_RENDERER with the actual vanilla renderer
- Inline it and remove the static field
- Remove the BlockRenderDispatcher parameter from all BakedModelBufferer
  functions
- Remove FlwLibLink#createVanillaBlockRenderDispatcher
This commit is contained in:
Jozufozu 2024-12-24 20:35:42 -08:00
parent 843b7e9a0b
commit e57702f742
12 changed files with 36 additions and 55 deletions

View file

@ -6,7 +6,6 @@ import dev.engine_room.flywheel.api.internal.DependencyInjection;
import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.core.BlockPos;
@ -20,8 +19,6 @@ public interface FlwLibXplat {
@UnknownNullability
BakedModel getBakedModel(ModelManager modelManager, ResourceLocation location);
BlockRenderDispatcher createVanillaBlockRenderDispatcher();
BakedModelBuilder createBakedModelBuilder(BakedModel bakedModel);
BlockModelBuilder createBlockModelBuilder(BlockState state);

View file

@ -10,20 +10,13 @@ import dev.engine_room.flywheel.api.material.Material;
import dev.engine_room.flywheel.api.model.Mesh;
import dev.engine_room.flywheel.api.model.Model;
import dev.engine_room.flywheel.api.vertex.VertexList;
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
import dev.engine_room.flywheel.lib.material.Materials;
import dev.engine_room.flywheel.lib.memory.MemoryBlock;
import dev.engine_room.flywheel.lib.vertex.PosVertexView;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
public final class ModelUtil {
/**
* An alternative BlockRenderDispatcher that circumvents the Forge rendering pipeline to ensure consistency.
* Meant to be used for virtual rendering.
*/
public static final BlockRenderDispatcher VANILLA_RENDERER = FlwLibXplat.INSTANCE.createVanillaBlockRenderDispatcher();
private static final float BOUNDING_SPHERE_EPSILON = 1e-4f;
private ModelUtil() {

View file

@ -9,6 +9,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap;
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
@ -32,7 +33,7 @@ final class BakedModelBufferer {
private BakedModelBufferer() {
}
public static void bufferSingle(ModelBlockRenderer blockRenderer, @Nullable BlockAndTintGetter level, BakedModel model, @Nullable BlockState state, @Nullable PoseStack poseStack, ResultConsumer resultConsumer) {
public static void bufferSingle(@Nullable BlockAndTintGetter level, BakedModel model, @Nullable BlockState state, @Nullable PoseStack poseStack, ResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (level == null) {
if (state == null) {
@ -60,7 +61,10 @@ final class BakedModelBufferer {
model = universalEmitter.wrapModel(model);
poseStack.pushPose();
blockRenderer.tesselateBlock(level, model, state, BlockPos.ZERO, poseStack, universalEmitter, false, random, 42L, OverlayTexture.NO_OVERLAY);
Minecraft.getInstance()
.getBlockRenderer()
.getModelRenderer()
.tesselateBlock(level, model, state, BlockPos.ZERO, poseStack, universalEmitter, false, random, 42L, OverlayTexture.NO_OVERLAY);
poseStack.popPose();
universalEmitter.clear();
@ -70,15 +74,18 @@ final class BakedModelBufferer {
}
}
public static void bufferBlock(BlockRenderDispatcher renderDispatcher, @Nullable BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, ResultConsumer resultConsumer) {
public static void bufferBlock(@Nullable BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, ResultConsumer resultConsumer) {
if (state.getRenderShape() != RenderShape.MODEL) {
return;
}
bufferSingle(renderDispatcher.getModelRenderer(), level, renderDispatcher.getBlockModel(state), state, poseStack, resultConsumer);
var blockModel = Minecraft.getInstance()
.getBlockRenderer()
.getBlockModel(state);
bufferSingle(level, blockModel, state, poseStack, resultConsumer);
}
public static void bufferMultiBlock(BlockRenderDispatcher renderDispatcher, Iterator<BlockPos> posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, ResultConsumer resultConsumer) {
public static void bufferMultiBlock(Iterator<BlockPos> posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, ResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (poseStack == null) {
poseStack = objects.identityPoseStack;
@ -93,6 +100,9 @@ final class BakedModelBufferer {
emitter.prepare(resultConsumer);
}
BlockRenderDispatcher renderDispatcher = Minecraft.getInstance()
.getBlockRenderer();
ModelBlockRenderer blockRenderer = renderDispatcher.getModelRenderer();
ModelBlockRenderer.enableCaching();

View file

@ -51,7 +51,7 @@ public final class FabricBakedModelBuilder extends BakedModelBuilder {
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
BakedModelBufferer.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), level, bakedModel, blockState, poseStack, (renderType, shaded, data) -> {
BakedModelBufferer.bufferSingle(level, bakedModel, blockState, poseStack, (renderType, shaded, data) -> {
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BakedModelBuilder," + "bakedModel=" + bakedModel + ",renderType=" + renderType + ",shaded=" + shaded);

View file

@ -44,7 +44,7 @@ public final class FabricBlockModelBuilder extends BlockModelBuilder {
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
BakedModelBufferer.bufferBlock(ModelUtil.VANILLA_RENDERER, level, state, poseStack, (renderType, shaded, data) -> {
BakedModelBufferer.bufferBlock(level, state, poseStack, (renderType, shaded, data) -> {
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BlockModelBuilder," + "blockState=" + state + ",renderType=" + renderType + ",shaded=" + shaded);

View file

@ -44,7 +44,7 @@ public final class FabricMultiBlockModelBuilder extends MultiBlockModelBuilder {
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
BakedModelBufferer.bufferMultiBlock(ModelUtil.VANILLA_RENDERER, positions.iterator(), level, poseStack, renderFluids, (renderType, shaded, data) -> {
BakedModelBufferer.bufferMultiBlock(positions.iterator(), level, poseStack, renderFluids, (renderType, shaded, data) -> {
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=MultiBlockModelBuilder," + "renderType=" + renderType + ",shaded=" + shaded);

View file

@ -9,8 +9,6 @@ import dev.engine_room.flywheel.lib.model.baked.FabricBakedModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.FabricBlockModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.FabricMultiBlockModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.core.BlockPos;
@ -25,11 +23,6 @@ public class FlwLibXplatImpl implements FlwLibXplat {
return modelManager.getModel(location);
}
@Override
public BlockRenderDispatcher createVanillaBlockRenderDispatcher() {
return Minecraft.getInstance().getBlockRenderer();
}
@Override
public BakedModelBuilder createBakedModelBuilder(BakedModel bakedModel) {
return new FabricBakedModelBuilder(bakedModel);

View file

@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable;
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
@ -33,7 +34,7 @@ final class BakedModelBufferer {
private BakedModelBufferer() {
}
public static void bufferSingle(ModelBlockRenderer blockRenderer, @Nullable BlockAndTintGetter level, BakedModel model, @Nullable BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
public static void bufferSingle(@Nullable BlockAndTintGetter level, BakedModel model, @Nullable BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (level == null) {
if (state == null) {
@ -55,6 +56,10 @@ final class BakedModelBufferer {
random.setSeed(42L);
ChunkRenderTypeSet renderTypes = model.getRenderTypes(state, random, modelData);
ModelBlockRenderer blockRenderer = Minecraft.getInstance()
.getBlockRenderer()
.getModelRenderer();
for (RenderType renderType : renderTypes) {
int layerIndex = renderType.getChunkLayerId();
MeshEmitter emitter = emitters[layerIndex];
@ -69,15 +74,18 @@ final class BakedModelBufferer {
}
}
public static void bufferBlock(BlockRenderDispatcher renderDispatcher, @Nullable BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
public static void bufferBlock(@Nullable BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
if (state.getRenderShape() != RenderShape.MODEL) {
return;
}
bufferSingle(renderDispatcher.getModelRenderer(), level, renderDispatcher.getBlockModel(state), state, poseStack, modelData, resultConsumer);
var blockModel = Minecraft.getInstance()
.getBlockRenderer()
.getBlockModel(state);
bufferSingle(level, blockModel, state, poseStack, modelData, resultConsumer);
}
public static void bufferMultiBlock(BlockRenderDispatcher renderDispatcher, Iterator<BlockPos> posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, Function<BlockPos, ModelData> modelDataLookup, boolean renderFluids, ResultConsumer resultConsumer) {
public static void bufferMultiBlock(Iterator<BlockPos> posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, Function<BlockPos, ModelData> modelDataLookup, boolean renderFluids, ResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (poseStack == null) {
poseStack = objects.identityPoseStack;
@ -90,6 +98,9 @@ final class BakedModelBufferer {
emitter.prepare(resultConsumer);
}
BlockRenderDispatcher renderDispatcher = Minecraft.getInstance()
.getBlockRenderer();
ModelBlockRenderer blockRenderer = renderDispatcher.getModelRenderer();
ModelBlockRenderer.enableCaching();

View file

@ -65,7 +65,7 @@ public final class ForgeBakedModelBuilder extends BakedModelBuilder {
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
BakedModelBufferer.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), level, bakedModel, blockState, poseStack, modelData, (renderType, shaded, data) -> {
BakedModelBufferer.bufferSingle(level, bakedModel, blockState, poseStack, modelData, (renderType, shaded, data) -> {
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BakedModelBuilder," + "bakedModel=" + bakedModel + ",renderType=" + renderType + ",shaded=" + shaded);

View file

@ -58,7 +58,7 @@ public final class ForgeBlockModelBuilder extends BlockModelBuilder {
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
BakedModelBufferer.bufferBlock(ModelUtil.VANILLA_RENDERER, level, state, poseStack, modelData, (renderType, shaded, data) -> {
BakedModelBufferer.bufferBlock(level, state, poseStack, modelData, (renderType, shaded, data) -> {
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BlockModelBuilder," + "blockState=" + state + ",renderType=" + renderType + ",shaded=" + shaded);

View file

@ -59,7 +59,7 @@ public final class ForgeMultiBlockModelBuilder extends MultiBlockModelBuilder {
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
BakedModelBufferer.bufferMultiBlock(ModelUtil.VANILLA_RENDERER, positions.iterator(), level, poseStack, modelDataLookup, renderFluids, (renderType, shaded, data) -> {
BakedModelBufferer.bufferMultiBlock(positions.iterator(), level, poseStack, modelDataLookup, renderFluids, (renderType, shaded, data) -> {
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=MultiBlockModelBuilder," + "renderType=" + renderType + ",shaded=" + shaded);

View file

@ -1,7 +1,5 @@
package dev.engine_room.flywheel.impl;
import java.lang.reflect.Field;
import org.jetbrains.annotations.UnknownNullability;
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
@ -11,16 +9,12 @@ import dev.engine_room.flywheel.lib.model.baked.ForgeBakedModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.ForgeBlockModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.ForgeMultiBlockModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
public class FlwLibXplatImpl implements FlwLibXplat {
@Override
@ -29,23 +23,6 @@ public class FlwLibXplatImpl implements FlwLibXplat {
return modelManager.getModel(location);
}
@Override
public BlockRenderDispatcher createVanillaBlockRenderDispatcher() {
BlockRenderDispatcher defaultDispatcher = Minecraft.getInstance().getBlockRenderer();
BlockRenderDispatcher dispatcher = new BlockRenderDispatcher(null, null, null);
try {
for (Field field : BlockRenderDispatcher.class.getDeclaredFields()) {
field.setAccessible(true);
field.set(dispatcher, field.get(defaultDispatcher));
}
ObfuscationReflectionHelper.setPrivateValue(BlockRenderDispatcher.class, dispatcher, new ModelBlockRenderer(Minecraft.getInstance().getBlockColors()), "f_110900_");
} catch (Exception e) {
FlwImpl.LOGGER.error("Failed to initialize vanilla BlockRenderDispatcher!", e);
return defaultDispatcher;
}
return dispatcher;
}
@Override
public BakedModelBuilder createBakedModelBuilder(BakedModel bakedModel) {
return new ForgeBakedModelBuilder(bakedModel);