From c15399512104ff1a798022eae80b305b994ab861 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sat, 25 Dec 2021 01:01:47 -0800 Subject: [PATCH] No more diffuse divide - Move PlacementSimulationWorld to Flywheel as VirtualRenderWorld - Simplify ModelTransformer - Model doesn't need #configure --- build.gradle | 2 +- .../batching/BatchedMaterialGroup.java | 8 +- .../instancing/batching/CPUInstancer.java | 11 - .../flywheel/core/model/BlockModel.java | 7 +- .../jozufozu/flywheel/core/model/Model.java | 8 +- .../flywheel/core/model/ModelTransformer.java | 42 +-- .../flywheel/core/model/ModelUtil.java | 12 +- .../flywheel/core/model/WorldModel.java | 5 +- .../flywheel/core/virtual/VirtualChunk.java | 240 ++++++++++++++++ .../core/virtual/VirtualChunkSection.java | 39 +++ .../core/virtual/VirtualChunkSource.java | 65 +++++ .../virtual}/VirtualEmptyBlockGetter.java | 4 +- .../virtual}/VirtualEmptyModelData.java | 2 +- .../virtual/VirtualLevelEntityGetter.java | 41 +++ .../core/virtual/VirtualRenderWorld.java | 265 ++++++++++++++++++ .../flywheel/core/virtual/package-info.java | 6 + .../flywheel/flywheel/shaders/block.frag | 6 - 17 files changed, 679 insertions(+), 84 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSection.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java rename src/main/java/com/jozufozu/flywheel/{util => core/virtual}/VirtualEmptyBlockGetter.java (97%) rename src/main/java/com/jozufozu/flywheel/{util => core/virtual}/VirtualEmptyModelData.java (94%) create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualLevelEntityGetter.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/package-info.java diff --git a/build.gradle b/build.gradle index a45bf118b..759b5e7f0 100644 --- a/build.gradle +++ b/build.gradle @@ -17,10 +17,10 @@ plugins { } apply plugin: 'net.minecraftforge.gradle' +apply plugin: 'org.parchmentmc.librarian.forgegradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' apply plugin: 'org.spongepowered.mixin' -apply plugin: 'org.parchmentmc.librarian.forgegradle' boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equalsIgnoreCase('false'); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java index cbeaf7c60..890dce0e1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java @@ -51,13 +51,7 @@ public class BatchedMaterialGroup implements MaterialGroup { for (BatchedMaterial material : materials.values()) { for (CPUInstancer instancer : material.models.values()) { - if (consumer.hasOverlay()) { - instancer.sbb.context.fullNormalTransform = false; - instancer.sbb.context.outputColorDiffuse = false; - } else { - instancer.sbb.context.fullNormalTransform = false; - instancer.sbb.context.outputColorDiffuse = true; - } + instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay(); instancer.submitTasks(stack, pool, consumer); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java index 1486ef14e..d16f4a4d2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java @@ -7,7 +7,6 @@ import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; import com.jozufozu.flywheel.core.model.Model; import com.jozufozu.flywheel.core.model.ModelTransformer; -import com.jozufozu.flywheel.util.Color; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -22,7 +21,6 @@ public class CPUInstancer extends AbstractInstancer { batchingType = type; sbb = new ModelTransformer(modelData); - modelData.configure(sbb.context); } void submitTasks(PoseStack stack, TaskEngine pool, DirectVertexConsumer consumer) { @@ -44,15 +42,11 @@ public class CPUInstancer extends AbstractInstancer { private void drawRange(PoseStack stack, VertexConsumer buffer, int from, int to) { ModelTransformer.Params params = new ModelTransformer.Params(); - // Color color = Color.generateFromLong(from); - for (D d : data.subList(from, to)) { params.loadDefault(); batchingType.transform(d, params); - //params.color(color.getRGB()); - sbb.renderInto(params, stack, buffer); } } @@ -73,11 +67,6 @@ public class CPUInstancer extends AbstractInstancer { data.removeIf(InstanceData::isRemoved); anyToRemove = false; } - - if (false) { - this.sbb.context.outputColorDiffuse = false; - this.sbb.context.fullNormalTransform = false; - } } @Override diff --git a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java index bfb01f00b..8c527bea6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.core.model; -import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.core.Formats; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; @@ -33,11 +33,6 @@ public class BlockModel implements Model { name = referenceState.toString(); } - @Override - public void configure(ModelTransformer.Context ctx) { - ctx.inputHasDiffuse = true; - } - @Override public String name() { return name; diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Model.java b/src/main/java/com/jozufozu/flywheel/core/model/Model.java index e505ba74b..6d1c2c0c5 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Model.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Model.java @@ -2,11 +2,11 @@ package com.jozufozu.flywheel.core.model; import java.nio.ByteBuffer; +import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.model.ElementBuffer; import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.QuadConverter; -import com.jozufozu.flywheel.api.vertex.VertexList; -import com.jozufozu.flywheel.api.vertex.VertexType; /** * A model that can be rendered by flywheel. @@ -42,10 +42,6 @@ public interface Model { */ int vertexCount(); - default void configure(ModelTransformer.Context ctx) { - - } - default VertexType getType() { return Formats.POS_TEX_NORMAL; } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java index fc2223da5..d856b5020 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java @@ -5,7 +5,11 @@ import com.jozufozu.flywheel.util.RenderMath; import com.jozufozu.flywheel.util.transform.Transform; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.*; +import com.mojang.math.Matrix3f; +import com.mojang.math.Matrix4f; +import com.mojang.math.Quaternion; +import com.mojang.math.Vector3f; +import com.mojang.math.Vector4f; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.texture.OverlayTexture; @@ -75,34 +79,11 @@ public class ModelTransformer { builder.color(params.r, params.g, params.b, params.a); } } else { - if (context.inputHasDiffuse) { - int r = Byte.toUnsignedInt(reader.getR(i)); - int g = Byte.toUnsignedInt(reader.getG(i)); - int b = Byte.toUnsignedInt(reader.getB(i)); - int a = Byte.toUnsignedInt(reader.getA(i)); - - float undoStaticDiffuse = 1 / LightUtil.diffuseLight(normalX, normalY, normalZ); - float diffuse; - if (context.outputColorDiffuse) { - diffuse = LightUtil.diffuseLight(nx, ny, nz) * undoStaticDiffuse; - } else { - diffuse = undoStaticDiffuse; - } - - if (diffuse != 1) { - r = transformColor(r, diffuse); - g = transformColor(g, diffuse); - b = transformColor(b, diffuse); - } - - builder.color(r, g, b, a); + if (context.outputColorDiffuse) { + int d = RenderMath.unb(LightUtil.diffuseLight(nx, ny, nz)); + builder.color(d, d, d, 0xFF); } else { - if (context.outputColorDiffuse) { - int d = RenderMath.unb(LightUtil.diffuseLight(nx, ny, nz)); - builder.color(d, d, d, 0xFF); - } else { - builder.color(reader.getR(i), reader.getG(i), reader.getB(i), reader.getA(i)); - } + builder.color(reader.getR(i), reader.getG(i), reader.getB(i), reader.getA(i)); } } @@ -152,11 +133,6 @@ public class ModelTransformer { */ public boolean fullNormalTransform = false; - /** - * Does the model we're transforming have diffuse light baked into its colors? - */ - public boolean inputHasDiffuse = false; - /** * Do we need to bake diffuse lighting into the output colors? */ diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java index 921b1f4df..a34d1f4d8 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java @@ -5,9 +5,9 @@ import java.util.Collection; import java.util.Random; import java.util.function.Supplier; +import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; +import com.jozufozu.flywheel.core.virtual.VirtualEmptyModelData; import com.jozufozu.flywheel.util.Lazy; -import com.jozufozu.flywheel.util.VirtualEmptyBlockGetter; -import com.jozufozu.flywheel.util.VirtualEmptyModelData; import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; @@ -45,14 +45,6 @@ public class ModelUtil { public static BufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack ms) { ModelBlockRenderer blockRenderer = Minecraft.getInstance().getBlockRenderer().getModelRenderer(); BufferBuilder builder = new BufferBuilder(512); - - // BakedQuadWrapper quadReader = new BakedQuadWrapper(); - // - // IModelData modelData = model.getModelData(VirtualEmptyBlockGetter.INSTANCE, BlockPos.ZERO, referenceState, VirtualEmptyModelData.INSTANCE); - // List quads = Arrays.stream(CULL_FACES) - // .flatMap(dir -> model.getQuads(referenceState, dir, new Random(), modelData).stream()) - // .collect(Collectors.toList()); - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); blockRenderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, BlockPos.ZERO, ms, builder, false, new Random(), 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE); diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java index b910de2a6..b3e96aa7d 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java @@ -2,9 +2,9 @@ package com.jozufozu.flywheel.core.model; import java.util.Collection; -import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.core.Formats; import net.minecraft.client.renderer.RenderType; import net.minecraft.world.level.BlockAndTintGetter; @@ -15,6 +15,9 @@ public class WorldModel implements Model { private final VertexList reader; private final String name; + /** + * It is expected that renderWorld.getShade(...) returns a constant. + */ public WorldModel(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks, String name) { reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilderFromTemplate(renderWorld, layer, blocks)); this.name = name; diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java new file mode 100644 index 000000000..925d7516a --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java @@ -0,0 +1,240 @@ +package com.jozufozu.flywheel.core.virtual; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import javax.annotation.Nullable; + +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.shorts.ShortList; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.StructureFeature; +import net.minecraft.world.level.levelgen.structure.StructureStart; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.ticks.BlackholeTickAccess; +import net.minecraft.world.ticks.TickContainerAccess; + +public class VirtualChunk extends ChunkAccess { + + final VirtualRenderWorld world; + boolean needsLight; + final int x; + final int z; + + private final LevelChunkSection[] sections; + + public VirtualChunk(VirtualRenderWorld world, int x, int z) { + super(new ChunkPos(x, z), UpgradeData.EMPTY, world, world.registryAccess() + .registry(Registry.BIOME_REGISTRY) + .orElseThrow(), 0L, null, null); + + this.world = world; + this.needsLight = true; + this.x = x; + this.z = z; + + this.sections = new LevelChunkSection[16]; + + for (int i = 0; i < 16; i++) { + sections[i] = new VirtualChunkSection(this, i << 4); + } + } + + @Override + public Stream getLights() { + return world.blocksAdded.entrySet() + .stream() + .filter(it -> { + BlockPos blockPos = it.getKey(); + boolean chunkContains = blockPos.getX() >> 4 == x && blockPos.getZ() >> 4 == z; + return chunkContains && it.getValue() + .getLightEmission(world, blockPos) != 0; + }) + .map(Map.Entry::getKey); + } + + @Override + public LevelChunkSection[] getSections() { + return sections; + } + + @Override + public ChunkStatus getStatus() { + return ChunkStatus.LIGHT; + } + + @Nullable + @Override + public BlockState setBlockState(BlockPos p_177436_1_, BlockState p_177436_2_, boolean p_177436_3_) { + return null; + } + + @Override + public void setBlockEntity(BlockEntity p_177426_2_) {} + + @Override + public void addEntity(Entity p_76612_1_) {} + + @Override + public Set getBlockEntitiesPos() { + return null; + } + + @Override + public Collection> getHeightmaps() { + return null; + } + + @Override + public void setHeightmap(Heightmap.Types p_201607_1_, long[] p_201607_2_) {} + + @Override + public Heightmap getOrCreateHeightmapUnprimed(Heightmap.Types p_217303_1_) { + return null; + } + + @Override + public int getHeight(Heightmap.Types p_201576_1_, int p_201576_2_, int p_201576_3_) { + return 0; + } + + @Override + public void setUnsaved(boolean p_177427_1_) {} + + @Override + public boolean isUnsaved() { + return false; + } + + @Override + public void removeBlockEntity(BlockPos p_177425_1_) {} + + @Override + public ShortList[] getPostProcessing() { + return new ShortList[0]; + } + + @Nullable + @Override + public CompoundTag getBlockEntityNbt(BlockPos p_201579_1_) { + return null; + } + + @Nullable + @Override + public CompoundTag getBlockEntityNbtForSaving(BlockPos p_223134_1_) { + return null; + } + + @Override + public UpgradeData getUpgradeData() { + return null; + } + + @Override + public void setInhabitedTime(long p_177415_1_) {} + + @Override + public long getInhabitedTime() { + return 0; + } + + @Override + public boolean isLightCorrect() { + return needsLight; + } + + @Override + public void setLightCorrect(boolean needsLight) { + this.needsLight = needsLight; + } + + @Nullable + @Override + public BlockEntity getBlockEntity(BlockPos pos) { + return null; + } + + @Override + public BlockState getBlockState(BlockPos pos) { + return world.getBlockState(pos); + } + + @Override + public FluidState getFluidState(BlockPos p_204610_1_) { + return null; + } + + @Override + public void addReferenceForFeature(StructureFeature arg0, long arg1) {} + + @Override + public Map, LongSet> getAllReferences() { + return null; + } + + @Override + public LongSet getReferencesForFeature(StructureFeature arg0) { + return null; + } + + @Override + public StructureStart getStartForFeature(StructureFeature arg0) { + return null; + } + + @Override + public void setAllReferences(Map, LongSet> arg0) {} + + @Override + public void setStartForFeature(StructureFeature arg0, StructureStart arg1) {} + + @Override + public void setAllStarts(Map, StructureStart> p_201612_1_) {} + + @Override + public Map, StructureStart> getAllStarts() { + return null; + } + + @Override + public int getHeight() { + return world.getHeight(); + } + + @Override + public int getMinBuildHeight() { + return world.getMinBuildHeight(); + } + + @Override + public TickContainerAccess getFluidTicks() { + return BlackholeTickAccess.emptyContainer(); + } + + @Override + public TicksToSave getTicksForSerialization() { + return null; + } + + @Override + public TickContainerAccess getBlockTicks() { + return BlackholeTickAccess.emptyContainer(); + } + +} diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSection.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSection.java new file mode 100644 index 000000000..a3d4f1952 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSection.java @@ -0,0 +1,39 @@ +package com.jozufozu.flywheel.core.virtual; + +import net.minecraft.core.Registry; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.LevelChunkSection; + +public class VirtualChunkSection extends LevelChunkSection { + + public VirtualChunk owner; + + public final int xStart; + public final int yStart; + public final int zStart; + + public VirtualChunkSection(VirtualChunk owner, int yBase) { + super(yBase, owner.world.registryAccess() + .registry(Registry.BIOME_REGISTRY) + .orElseThrow()); + this.owner = owner; + this.xStart = owner.getPos() + .getMinBlockX(); + this.yStart = yBase; + this.zStart = owner.getPos() + .getMinBlockZ(); + } + + @Override + public BlockState getBlockState(int x, int y, int z) { + // ChunkSection#getBlockState expects local chunk coordinates, so we add to get + // back into world coords. + return owner.world.getBlockState(x + xStart, y + yStart, z + zStart); + } + + @Override + public BlockState setBlockState(int p_177484_1_, int p_177484_2_, int p_177484_3_, BlockState p_177484_4_, + boolean p_177484_5_) { + throw new IllegalStateException("Chunk sections should not be mutated in a fake world."); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java new file mode 100644 index 000000000..bfef41047 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java @@ -0,0 +1,65 @@ +package com.jozufozu.flywheel.core.virtual; + +import java.util.HashMap; +import java.util.function.BooleanSupplier; + +import javax.annotation.Nullable; + +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.lighting.LevelLightEngine; + +public class VirtualChunkSource extends ChunkSource { + private final VirtualRenderWorld world; + + public final HashMap chunks = new HashMap<>(); + + public VirtualChunkSource(VirtualRenderWorld world) { + this.world = world; + } + + @Nullable + @Override + public BlockGetter getChunkForLighting(int x, int z) { + return getChunk(x, z); + } + + @Override + public Level getLevel() { + return world; + } + + @Nullable + @Override + public ChunkAccess getChunk(int x, int z, ChunkStatus status, boolean p_212849_4_) { + return getChunk(x, z); + } + + public ChunkAccess getChunk(int x, int z) { + long pos = ChunkPos.asLong(x, z); + + return chunks.computeIfAbsent(pos, $ -> new VirtualChunk(world, x, z)); + } + + @Override + public String gatherStats() { + return "WrappedChunkProvider"; + } + + @Override + public LevelLightEngine getLightEngine() { + return world.getLightEngine(); + } + + @Override + public void tick(BooleanSupplier pHasTimeLeft) {} + + @Override + public int getLoadedChunksCount() { + return 0; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/util/VirtualEmptyBlockGetter.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java similarity index 97% rename from src/main/java/com/jozufozu/flywheel/util/VirtualEmptyBlockGetter.java rename to src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java index 4f88342ab..8058bcf68 100644 --- a/src/main/java/com/jozufozu/flywheel/util/VirtualEmptyBlockGetter.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.util; +package com.jozufozu.flywheel.core.virtual; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; @@ -120,7 +120,7 @@ public enum VirtualEmptyBlockGetter implements BlockAndTintGetter { @Override public float getShade(Direction direction, boolean bool) { - return Minecraft.getInstance().level.getShade(direction, bool); + return 1f; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/util/VirtualEmptyModelData.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyModelData.java similarity index 94% rename from src/main/java/com/jozufozu/flywheel/util/VirtualEmptyModelData.java rename to src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyModelData.java index 6d60d2bdb..4a8195857 100644 --- a/src/main/java/com/jozufozu/flywheel/util/VirtualEmptyModelData.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyModelData.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.util; +package com.jozufozu.flywheel.core.virtual; import net.minecraftforge.client.model.data.IModelData; import net.minecraftforge.client.model.data.ModelProperty; diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualLevelEntityGetter.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualLevelEntityGetter.java new file mode 100644 index 000000000..2edd3fdf3 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualLevelEntityGetter.java @@ -0,0 +1,41 @@ +package com.jozufozu.flywheel.core.virtual; + +import java.util.Collections; +import java.util.UUID; +import java.util.function.Consumer; + +import net.minecraft.world.level.entity.EntityAccess; +import net.minecraft.world.level.entity.EntityTypeTest; +import net.minecraft.world.level.entity.LevelEntityGetter; +import net.minecraft.world.phys.AABB; + +public class VirtualLevelEntityGetter implements LevelEntityGetter { + + @Override + public T get(int p_156931_) { + return null; + } + + @Override + public T get(UUID pUuid) { + return null; + } + + @Override + public Iterable getAll() { + return Collections.emptyList(); + } + + @Override + public void get(EntityTypeTest p_156935_, Consumer p_156936_) { + } + + @Override + public void get(AABB p_156937_, Consumer p_156938_) { + } + + @Override + public void get(EntityTypeTest p_156932_, AABB p_156933_, Consumer p_156934_) { + } + +} diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java new file mode 100644 index 000000000..7d616c665 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java @@ -0,0 +1,265 @@ +package com.jozufozu.flywheel.core.virtual; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; + +import javax.annotation.Nullable; + +import com.jozufozu.flywheel.api.FlywheelWorld; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.SectionPos; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.TagContainer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +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.ChunkSource; +import net.minecraft.world.level.entity.LevelEntityGetter; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; +import net.minecraft.world.level.storage.WritableLevelData; +import net.minecraft.world.scores.Scoreboard; +import net.minecraft.world.ticks.LevelTickAccess; + +public class VirtualRenderWorld extends Level implements FlywheelWorld { + public final Map blocksAdded = new HashMap<>(); + public final Map tesAdded = new HashMap<>(); + public final Set spannedSections = new HashSet<>(); + private final BlockPos.MutableBlockPos scratch = new BlockPos.MutableBlockPos(); + + public final LevelLightEngine lighter; + public final VirtualChunkSource chunkSource; + + protected Level level; + + protected LevelEntityGetter entityGetter = new VirtualLevelEntityGetter<>(); + + public VirtualRenderWorld(Level level) { + super((WritableLevelData) level.getLevelData(), level.dimension(), level.dimensionType(), level::getProfiler, + true, false, 0); + this.level = level; + this.chunkSource = new VirtualChunkSource(this); + this.lighter = new LevelLightEngine(chunkSource, true, false); + } + + /** + * Run this after you're done using setBlock(). + */ + public void runLightingEngine() { + for (Map.Entry entry : blocksAdded.entrySet()) { + BlockPos pos = entry.getKey(); + BlockState state = entry.getValue(); + int light = state.getLightEmission(this, pos); + if (light > 0) { + lighter.onBlockEmissionIncrease(pos, light); + } + } + + lighter.runUpdates(Integer.MAX_VALUE, false, false); + } + + public void setTileEntities(Collection tileEntities) { + tesAdded.clear(); + tileEntities.forEach(te -> tesAdded.put(te.getBlockPos(), te)); + } + + public void clear() { + blocksAdded.clear(); + } + + // MEANINGFUL OVERRIDES + + @Override + public ChunkSource getChunkSource() { + return chunkSource; + } + + @Override + public LevelLightEngine getLightEngine() { + return lighter; + } + + @Override + protected LevelEntityGetter getEntities() { + return entityGetter; + } + + @Override + public BlockState getBlockState(@Nullable BlockPos pos) { + BlockState state = blocksAdded.get(pos); + if (state != null) + return state; + return Blocks.AIR.defaultBlockState(); + } + + @Override + public boolean setBlockAndUpdate(BlockPos pos, BlockState state) { + return setBlock(pos, state, 0); + } + + @Override + public boolean setBlock(BlockPos pos, BlockState newState, int flags) { + blocksAdded.put(pos, newState); + + SectionPos sectionPos = SectionPos.of(pos); + if (spannedSections.add(sectionPos)) { + lighter.updateSectionStatus(sectionPos, false); + } + + if ((flags & Block.UPDATE_SUPPRESS_LIGHT) == 0) { + lighter.checkBlock(pos); + } + + return true; + } + + @Override + @Nullable + public BlockEntity getBlockEntity(BlockPos pos) { + return tesAdded.get(pos); + } + + @Override + public boolean isStateAtPosition(BlockPos pos, Predicate condition) { + return condition.test(getBlockState(pos)); + } + + public BlockState getBlockState(int x, int y, int z) { + return getBlockState(scratch.set(x, y, z)); + } + + // RENDERING CONSTANTS + + @Override + public int getMaxLocalRawBrightness(BlockPos pos) { + return 15; + } + + @Override + public float getShade(Direction p_230487_1_, boolean p_230487_2_) { + return 1f; + } + + // THIN WRAPPERS AHEAD + + @Override + public RegistryAccess registryAccess() { + return level.registryAccess(); + } + + @Override + public LevelTickAccess getBlockTicks() { + return level.getBlockTicks(); + } + + @Override + public LevelTickAccess getFluidTicks() { + return level.getFluidTicks(); + } + + @Override + public RecipeManager getRecipeManager() { + return level.getRecipeManager(); + } + + @Override + public TagContainer getTagManager() { + return level.getTagManager(); + } + + @Override + public int getFreeMapId() { + return level.getFreeMapId(); + } + + @Override + public Scoreboard getScoreboard() { + return level.getScoreboard(); + } + + @Override + public Biome getUncachedNoiseBiome(int p_225604_1_, int p_225604_2_, int p_225604_3_) { + return level.getUncachedNoiseBiome(p_225604_1_, p_225604_2_, p_225604_3_); + } + + // UNIMPORTANT CONSTANTS + + @Override + @Nullable + public Entity getEntity(int id) { + return null; + } + + @Override + @Nullable + public MapItemSavedData getMapData(String mapName) { + return null; + } + + @Override + public boolean isLoaded(BlockPos pos) { + return true; + } + + @Override + public boolean isAreaLoaded(BlockPos center, int range) { + return true; + } + + @Override + public List players() { + return Collections.emptyList(); + } + + @Override + public String gatherChunkSourceStats() { + return ""; + } + + // NOOP + + @Override + public void levelEvent(@Nullable Player player, int type, BlockPos pos, int data) {} + + @Override + public void playSound(@Nullable Player player, double x, double y, double z, SoundEvent soundIn, + SoundSource category, float volume, float pitch) {} + + @Override + public void playSound(@Nullable Player p_217384_1_, Entity p_217384_2_, SoundEvent p_217384_3_, + SoundSource p_217384_4_, float p_217384_5_, float p_217384_6_) {} + + @Override + public void setMapData(String pMapId, MapItemSavedData pData) {} + + @Override + public void destroyBlockProgress(int breakerId, BlockPos pos, int progress) {} + + @Override + public void updateNeighbourForOutputSignal(BlockPos p_175666_1_, Block p_175666_2_) {} + + @Override + public void gameEvent(@Nullable Entity pEntity, GameEvent pEvent, BlockPos pPos) {} + + @Override + public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) {} + +} diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/package-info.java b/src/main/java/com/jozufozu/flywheel/core/virtual/package-info.java new file mode 100644 index 000000000..c9b5451c0 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/package-info.java @@ -0,0 +1,6 @@ +@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault +package com.jozufozu.flywheel.core.virtual; + +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/block.frag b/src/main/resources/assets/flywheel/flywheel/shaders/block.frag index 5e1402b05..d8e5169fe 100644 --- a/src/main/resources/assets/flywheel/flywheel/shaders/block.frag +++ b/src/main/resources/assets/flywheel/flywheel/shaders/block.frag @@ -12,12 +12,6 @@ void fragment(BlockFrag r) { vec4 color = vec4(tex.rgb * FLWLight(r.light).rgb * r.diffuse, tex.a) * r.color; -// flw_WorldPos = ; -// flw_Normal = ; -// flw_Albedo = tex.rgb; -// flw_Alpha = tex.a; -// flw_LightMap = r.light; -// flw_Tint = r.color; FLWFinalizeColor(color); } #endif