The bakery

- Port model baking infrastructure.
- VirtualEmptyModelData seems like it isn't needed anymore,
  but I left some stubs in.
This commit is contained in:
Jozufozu 2023-11-23 14:10:50 -08:00
parent 7bc6a7559a
commit aae0200d93
7 changed files with 104 additions and 100 deletions

View file

@ -17,6 +17,7 @@ import com.jozufozu.flywheel.api.vertex.VertexListProviderRegistry;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.lib.material.Materials;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.BufferBuilder.DrawState;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.datafixers.util.Pair;
@ -56,17 +57,17 @@ public final class ModelUtil {
return dispatcher;
}
public static boolean isVanillaBufferEmpty(Pair<DrawState, ByteBuffer> pair) {
return pair.getFirst().vertexCount() == 0;
public static boolean isVanillaBufferEmpty(BufferBuilder.RenderedBuffer renderedBuffer) {
return renderedBuffer.drawState().vertexCount() == 0;
}
public static MemoryBlock convertVanillaBuffer(Pair<DrawState, ByteBuffer> pair, VertexType vertexType) {
DrawState drawState = pair.getFirst();
public static MemoryBlock convertVanillaBuffer(BufferBuilder.RenderedBuffer renderedBuffer, VertexType vertexType) {
DrawState drawState = renderedBuffer.drawState();
int vertexCount = drawState.vertexCount();
VertexFormat srcFormat = drawState.format();
ByteBuffer src = pair.getSecond();
MemoryBlock dst = MemoryBlock.malloc(vertexCount * vertexType.getLayout().getStride());
ByteBuffer src = renderedBuffer.vertexBuffer();
MemoryBlock dst = MemoryBlock.malloc((long) vertexCount * vertexType.getLayout().getStride());
long srcPtr = MemoryUtil.memAddress(src);
long dstPtr = dst.ptr();

View file

@ -21,13 +21,14 @@ import net.minecraft.client.renderer.block.ModelBlockRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraftforge.client.ChunkRenderTypeSet;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelData;
public final class BakedModelBufferer {
private static final RenderType[] CHUNK_LAYERS = RenderType.chunkBufferLayers().toArray(RenderType[]::new);
@ -38,52 +39,52 @@ public final class BakedModelBufferer {
private BakedModelBufferer() {
}
public static void bufferSingle(ModelBlockRenderer blockRenderer, BlockAndTintGetter renderWorld, BakedModel model, BlockState state, @Nullable PoseStack poseStack, IModelData modelData, ResultConsumer resultConsumer) {
public static void bufferSingle(ModelBlockRenderer blockRenderer, BlockAndTintGetter renderWorld, BakedModel model, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (poseStack == null) {
poseStack = objects.identityPoseStack;
}
Random random = objects.random;
var random = objects.random;
BufferBuilder[] buffers = objects.shadedBuffers;
var renderTypes = model.getRenderTypes(state, random, modelData);
for (int layerIndex = 0; layerIndex < CHUNK_LAYER_AMOUNT; layerIndex++) {
RenderType renderType = CHUNK_LAYERS[layerIndex];
if (!ItemBlockRenderTypes.canRenderInLayer(state, renderType)) {
if (!renderTypes.contains(renderType)) {
continue;
}
BufferBuilder buffer = buffers[layerIndex];
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
ForgeHooksClient.setRenderType(renderType);
poseStack.pushPose();
blockRenderer.tesselateBlock(renderWorld, model, state, BlockPos.ZERO, poseStack, buffer, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData);
blockRenderer.tesselateBlock(renderWorld, model, state, BlockPos.ZERO, poseStack, buffer, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData, renderType);
poseStack.popPose();
buffer.end();
Pair<DrawState, ByteBuffer> data = buffer.popNextBuffer();
var data = buffer.end();
resultConsumer.accept(renderType, data);
}
ForgeHooksClient.setRenderType(null);
}
public static void bufferSingleShadeSeparated(ModelBlockRenderer blockRenderer, BlockAndTintGetter renderWorld, BakedModel model, BlockState state, @Nullable PoseStack poseStack, IModelData modelData, ShadeSeparatedResultConsumer resultConsumer) {
public static void bufferSingleShadeSeparated(ModelBlockRenderer blockRenderer, BlockAndTintGetter renderWorld, BakedModel model, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ShadeSeparatedResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (poseStack == null) {
poseStack = objects.identityPoseStack;
}
Random random = objects.random;
var random = objects.random;
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
BufferBuilder[] shadedBuffers = objects.shadedBuffers;
BufferBuilder[] unshadedBuffers = objects.unshadedBuffers;
var renderTypes = model.getRenderTypes(state, random, modelData);
for (int layerIndex = 0; layerIndex < CHUNK_LAYER_AMOUNT; layerIndex++) {
RenderType renderType = CHUNK_LAYERS[layerIndex];
if (!ItemBlockRenderTypes.canRenderInLayer(state, renderType)) {
if (!renderTypes.contains(renderType)) {
continue;
}
@ -93,26 +94,22 @@ public final class BakedModelBufferer {
shadedBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
ForgeHooksClient.setRenderType(renderType);
poseStack.pushPose();
blockRenderer.tesselateBlock(renderWorld, model, state, BlockPos.ZERO, poseStack, shadeSeparatingWrapper, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData);
blockRenderer.tesselateBlock(renderWorld, model, state, BlockPos.ZERO, poseStack, shadeSeparatingWrapper, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData, renderType);
poseStack.popPose();
shadedBuffer.end();
unshadedBuffer.end();
Pair<DrawState, ByteBuffer> shadedData = shadedBuffer.popNextBuffer();
Pair<DrawState, ByteBuffer> unshadedData = unshadedBuffer.popNextBuffer();
var shadedData = shadedBuffer.end();
var unshadedData = unshadedBuffer.end();
resultConsumer.accept(renderType, true, shadedData);
resultConsumer.accept(renderType, false, unshadedData);
}
ForgeHooksClient.setRenderType(null);
shadeSeparatingWrapper.clear();
}
public static void bufferBlock(BlockRenderDispatcher renderDispatcher, BlockAndTintGetter renderWorld, BlockState state, @Nullable PoseStack poseStack, IModelData modelData, ResultConsumer resultConsumer) {
public static void bufferBlock(BlockRenderDispatcher renderDispatcher, BlockAndTintGetter renderWorld, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
if (state.getRenderShape() != RenderShape.MODEL) {
return;
}
@ -120,7 +117,7 @@ public final class BakedModelBufferer {
bufferSingle(renderDispatcher.getModelRenderer(), renderWorld, renderDispatcher.getBlockModel(state), state, poseStack, modelData, resultConsumer);
}
public static void bufferBlockShadeSeparated(BlockRenderDispatcher renderDispatcher, BlockAndTintGetter renderWorld, BlockState state, @Nullable PoseStack poseStack, IModelData modelData, ShadeSeparatedResultConsumer resultConsumer) {
public static void bufferBlockShadeSeparated(BlockRenderDispatcher renderDispatcher, BlockAndTintGetter renderWorld, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ShadeSeparatedResultConsumer resultConsumer) {
if (state.getRenderShape() != RenderShape.MODEL) {
return;
}
@ -128,12 +125,12 @@ public final class BakedModelBufferer {
bufferSingleShadeSeparated(renderDispatcher.getModelRenderer(), renderWorld, renderDispatcher.getBlockModel(state), state, poseStack, modelData, resultConsumer);
}
public static void bufferMultiBlock(Collection<StructureTemplate.StructureBlockInfo> blocks, BlockRenderDispatcher renderDispatcher, BlockAndTintGetter renderWorld, @Nullable PoseStack poseStack, Map<BlockPos, IModelData> modelDataMap, ResultConsumer resultConsumer) {
public static void bufferMultiBlock(Collection<StructureTemplate.StructureBlockInfo> blocks, BlockRenderDispatcher renderDispatcher, BlockAndTintGetter renderWorld, @Nullable PoseStack poseStack, Map<BlockPos, ModelData> modelDataMap, ResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (poseStack == null) {
poseStack = objects.identityPoseStack;
}
Random random = objects.random;
var random = objects.random;
BufferBuilder[] buffers = objects.shadedBuffers;
for (BufferBuilder buffer : buffers) {
@ -144,53 +141,52 @@ public final class BakedModelBufferer {
ModelBlockRenderer.enableCaching();
for (StructureTemplate.StructureBlockInfo blockInfo : blocks) {
BlockState state = blockInfo.state;
BlockState state = blockInfo.state();
if (state.getRenderShape() != RenderShape.MODEL) {
continue;
}
BakedModel model = renderDispatcher.getBlockModel(state);
BlockPos pos = blockInfo.pos;
BlockPos pos = blockInfo.pos();
long seed = state.getSeed(pos);
IModelData modelData = modelDataMap.getOrDefault(pos, EmptyModelData.INSTANCE);
ModelData modelData = modelDataMap.getOrDefault(pos, ModelData.EMPTY);
var renderTypes = model.getRenderTypes(state, random, modelData);
for (int layerIndex = 0; layerIndex < CHUNK_LAYER_AMOUNT; layerIndex++) {
RenderType renderType = CHUNK_LAYERS[layerIndex];
if (!ItemBlockRenderTypes.canRenderInLayer(state, renderType)) {
if (!renderTypes.contains(renderType)) {
continue;
}
BufferBuilder buffer = buffers[layerIndex];
ForgeHooksClient.setRenderType(renderType);
poseStack.pushPose();
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
blockRenderer.tesselateBlock(renderWorld, model, state, pos, poseStack, buffer, true, random, seed, OverlayTexture.NO_OVERLAY, modelData);
blockRenderer.tesselateBlock(renderWorld, model, state, pos, poseStack, buffer, true, random, seed, OverlayTexture.NO_OVERLAY, modelData, renderType);
poseStack.popPose();
}
}
ForgeHooksClient.setRenderType(null);
ModelBlockRenderer.clearCache();
for (int layerIndex = 0; layerIndex < CHUNK_LAYER_AMOUNT; layerIndex++) {
RenderType renderType = CHUNK_LAYERS[layerIndex];
BufferBuilder buffer = buffers[layerIndex];
buffer.end();
Pair<DrawState, ByteBuffer> data = buffer.popNextBuffer();
var data = buffer.end();
resultConsumer.accept(renderType, data);
}
}
public static void bufferMultiBlockShadeSeparated(Collection<StructureTemplate.StructureBlockInfo> blocks, BlockRenderDispatcher renderDispatcher, BlockAndTintGetter renderWorld, @Nullable PoseStack poseStack, Map<BlockPos, IModelData> modelDataMap, ShadeSeparatedResultConsumer resultConsumer) {
public static void bufferMultiBlockShadeSeparated(Collection<StructureTemplate.StructureBlockInfo> blocks, BlockRenderDispatcher renderDispatcher, BlockAndTintGetter renderWorld, @Nullable PoseStack poseStack, Map<BlockPos, ModelData> modelDataMap, ShadeSeparatedResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (poseStack == null) {
poseStack = objects.identityPoseStack;
}
Random random = objects.random;
var random = objects.random;
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
BufferBuilder[] shadedBuffers = objects.shadedBuffers;
@ -206,36 +202,35 @@ public final class BakedModelBufferer {
ModelBlockRenderer.enableCaching();
for (StructureTemplate.StructureBlockInfo blockInfo : blocks) {
BlockState state = blockInfo.state;
BlockState state = blockInfo.state();
if (state.getRenderShape() != RenderShape.MODEL) {
continue;
}
BakedModel model = renderDispatcher.getBlockModel(state);
BlockPos pos = blockInfo.pos;
BlockPos pos = blockInfo.pos();
long seed = state.getSeed(pos);
IModelData modelData = modelDataMap.getOrDefault(pos, EmptyModelData.INSTANCE);
ModelData modelData = modelDataMap.getOrDefault(pos, ModelData.EMPTY);
var renderTypes = model.getRenderTypes(state, random, modelData);
for (int layerIndex = 0; layerIndex < CHUNK_LAYER_AMOUNT; layerIndex++) {
RenderType renderType = CHUNK_LAYERS[layerIndex];
if (!ItemBlockRenderTypes.canRenderInLayer(state, renderType)) {
if (!renderTypes.contains(renderType)) {
continue;
}
shadeSeparatingWrapper.prepare(shadedBuffers[layerIndex], unshadedBuffers[layerIndex]);
ForgeHooksClient.setRenderType(renderType);
poseStack.pushPose();
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
blockRenderer.tesselateBlock(renderWorld, model, state, pos, poseStack, shadeSeparatingWrapper, true, random, seed, OverlayTexture.NO_OVERLAY, modelData);
blockRenderer.tesselateBlock(renderWorld, model, state, pos, poseStack, shadeSeparatingWrapper, true, random, seed, OverlayTexture.NO_OVERLAY, modelData, renderType);
poseStack.popPose();
}
}
ForgeHooksClient.setRenderType(null);
ModelBlockRenderer.clearCache();
shadeSeparatingWrapper.clear();
@ -246,24 +241,24 @@ public final class BakedModelBufferer {
BufferBuilder unshadedBuffer = unshadedBuffers[layerIndex];
shadedBuffer.end();
unshadedBuffer.end();
Pair<DrawState, ByteBuffer> shadedData = shadedBuffer.popNextBuffer();
Pair<DrawState, ByteBuffer> unshadedData = unshadedBuffer.popNextBuffer();
var shadedData = shadedBuffer.end();
var unshadedData = unshadedBuffer.end();
resultConsumer.accept(renderType, true, shadedData);
resultConsumer.accept(renderType, false, unshadedData);
}
}
public interface ResultConsumer {
void accept(RenderType renderType, Pair<DrawState, ByteBuffer> data);
void accept(RenderType renderType, BufferBuilder.RenderedBuffer data);
}
public interface ShadeSeparatedResultConsumer {
void accept(RenderType renderType, boolean shaded, Pair<DrawState, ByteBuffer> data);
void accept(RenderType renderType, boolean shaded, BufferBuilder.RenderedBuffer data);
}
private static class ThreadLocalObjects {
public final PoseStack identityPoseStack = new PoseStack();
public final Random random = new Random();
public final RandomSource random = RandomSource.create();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();

View file

@ -18,7 +18,7 @@ import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelData;
public class BakedModelBuilder {
private final BakedModel bakedModel;
@ -26,7 +26,7 @@ public class BakedModelBuilder {
private BlockAndTintGetter renderWorld;
private BlockState blockState;
private PoseStack poseStack;
private IModelData modelData;
private ModelData modelData;
private BiFunction<RenderType, Boolean, Material> materialFunc;
public BakedModelBuilder(BakedModel bakedModel) {
@ -53,7 +53,7 @@ public class BakedModelBuilder {
return this;
}
public BakedModelBuilder modelData(IModelData modelData) {
public BakedModelBuilder modelData(ModelData modelData) {
this.modelData = modelData;
return this;
}
@ -71,7 +71,7 @@ public class BakedModelBuilder {
blockState = Blocks.AIR.defaultBlockState();
}
if (modelData == null) {
modelData = VirtualEmptyModelData.INSTANCE;
modelData = ModelData.EMPTY;
}
if (materialFunc == null) {
materialFunc = ModelUtil::getMaterial;

View file

@ -16,14 +16,14 @@ import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelData;
public class BlockModelBuilder {
private final BlockState state;
private boolean shadeSeparated = true;
private BlockAndTintGetter renderWorld;
private PoseStack poseStack;
private IModelData modelData;
private ModelData modelData = ModelData.EMPTY;
private BiFunction<RenderType, Boolean, Material> materialFunc;
public BlockModelBuilder(BlockState state) {
@ -45,7 +45,7 @@ public class BlockModelBuilder {
return this;
}
public BlockModelBuilder modelData(IModelData modelData) {
public BlockModelBuilder modelData(ModelData modelData) {
this.modelData = modelData;
return this;
}
@ -60,7 +60,7 @@ public class BlockModelBuilder {
renderWorld = VirtualEmptyBlockGetter.INSTANCE;
}
if (modelData == null) {
modelData = VirtualEmptyModelData.INSTANCE;
modelData = ModelData.EMPTY;
}
if (materialFunc == null) {
materialFunc = ModelUtil::getMaterial;

View file

@ -20,14 +20,14 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelData;
public class MultiBlockModelBuilder {
private final Collection<StructureTemplate.StructureBlockInfo> blocks;
private boolean shadeSeparated = true;
private BlockAndTintGetter renderWorld;
private PoseStack poseStack;
private Map<BlockPos, IModelData> modelDataMap;
private Map<BlockPos, ModelData> modelDataMap;
private BiFunction<RenderType, Boolean, Material> materialFunc;
public MultiBlockModelBuilder(Collection<StructureTemplate.StructureBlockInfo> blocks) {
@ -49,7 +49,7 @@ public class MultiBlockModelBuilder {
return this;
}
public MultiBlockModelBuilder modelDataMap(Map<BlockPos, IModelData> modelDataMap) {
public MultiBlockModelBuilder modelDataMap(Map<BlockPos, ModelData> modelDataMap) {
this.modelDataMap = modelDataMap;
return this;
}

View file

@ -1,10 +1,14 @@
package com.jozufozu.flywheel.lib.model.baked;
import java.util.function.BiConsumer;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ChunkPos;
@ -16,13 +20,15 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.LightChunk;
import net.minecraft.world.level.chunk.LightChunkGetter;
import net.minecraft.world.level.lighting.ChunkSkyLightSources;
import net.minecraft.world.level.lighting.LayerLightEventListener;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
public interface VirtualEmptyBlockGetter extends BlockAndTintGetter {
public interface VirtualEmptyBlockGetter extends BlockAndTintGetter, LightChunk {
public static final VirtualEmptyBlockGetter INSTANCE = new StaticLightImpl(0, 15);
public static final VirtualEmptyBlockGetter FULL_BRIGHT = new StaticLightImpl(15, 15);
public static final VirtualEmptyBlockGetter FULL_DARK = new StaticLightImpl(0, 0);
@ -63,17 +69,24 @@ public interface VirtualEmptyBlockGetter extends BlockAndTintGetter {
@Override
default int getBlockTint(BlockPos pos, ColorResolver resolver) {
Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getOrThrow(Biomes.PLAINS);
Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS);
return resolver.getColor(plainsBiome, pos.getX(), pos.getZ());
}
@Override
default void findBlockLightSources(BiConsumer<BlockPos, BlockState> pOutput) {
}
public static class StaticLightImpl implements VirtualEmptyBlockGetter {
private final LevelLightEngine lightEngine;
private final ChunkSkyLightSources lightSources;
public StaticLightImpl(int blockLight, int skyLight) {
lightEngine = new LevelLightEngine(new LightChunkGetter() {
@Override
public BlockGetter getChunkForLighting(int p_63023_, int p_63024_) {
public LightChunk getChunkForLighting(int p_63023_, int p_63024_) {
return StaticLightImpl.this;
}
@ -90,6 +103,8 @@ public interface VirtualEmptyBlockGetter extends BlockAndTintGetter {
return layer == LightLayer.BLOCK ? blockListener : skyListener;
}
};
lightSources = new ChunkSkyLightSources(this);
}
private static LayerLightEventListener createStaticListener(int light) {
@ -99,7 +114,18 @@ public interface VirtualEmptyBlockGetter extends BlockAndTintGetter {
}
@Override
public void onBlockEmissionIncrease(BlockPos pos, int emissionLevel) {
public int runLightUpdates() {
return 0;
}
@Override
public void setLightEnabled(ChunkPos pChunkPos, boolean pLightEnabled) {
}
@Override
public void propagateLightSources(ChunkPos pChunkPos) {
}
@Override
@ -107,19 +133,10 @@ public interface VirtualEmptyBlockGetter extends BlockAndTintGetter {
return false;
}
@Override
public int runUpdates(int pos, boolean isQueueEmpty, boolean updateBlockLight) {
return pos;
}
@Override
public void updateSectionStatus(SectionPos pos, boolean isQueueEmpty) {
}
@Override
public void enableLightSources(ChunkPos pos, boolean isQueueEmpty) {
}
@Override
public DataLayer getDataLayerData(SectionPos pos) {
return null;
@ -136,5 +153,10 @@ public interface VirtualEmptyBlockGetter extends BlockAndTintGetter {
public LevelLightEngine getLightEngine() {
return lightEngine;
}
@Override
public ChunkSkyLightSources getSkyLightSources() {
return lightSources;
}
}
}

View file

@ -2,7 +2,9 @@ package com.jozufozu.flywheel.lib.model.baked;
import org.jetbrains.annotations.Nullable;
import net.minecraftforge.client.model.data.IModelData;
import com.jozufozu.flywheel.api.model.Model;
import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.client.model.data.ModelProperty;
/**
@ -10,27 +12,11 @@ import net.minecraftforge.client.model.data.ModelProperty;
* available in-world context. BakedModel#getModelData can react accordingly
* and avoid looking for model data itself.
**/
public enum VirtualEmptyModelData implements IModelData {
INSTANCE;
public class VirtualEmptyModelData {
// TODO: Remove? Doesn't seem necessary anymore
public static final ModelData INSTANCE = ModelData.EMPTY;
public static boolean is(IModelData data) {
public static boolean is(ModelData data) {
return data == INSTANCE;
}
@Override
public boolean hasProperty(ModelProperty<?> prop) {
return false;
}
@Override
@Nullable
public <T> T getData(ModelProperty<T> prop) {
return null;
}
@Override
@Nullable
public <T> T setData(ModelProperty<T> prop, T data) {
return null;
}
}