mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 23:47:09 +01:00
No more diffuse divide
- Move PlacementSimulationWorld to Flywheel as VirtualRenderWorld - Simplify ModelTransformer - Model doesn't need #configure
This commit is contained in:
parent
1e9e4e0054
commit
c153995121
17 changed files with 679 additions and 84 deletions
|
@ -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');
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
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<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
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<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
data.removeIf(InstanceData::isRemoved);
|
||||
anyToRemove = false;
|
||||
}
|
||||
|
||||
if (false) {
|
||||
this.sbb.context.outputColorDiffuse = false;
|
||||
this.sbb.context.fullNormalTransform = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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?
|
||||
*/
|
||||
|
|
|
@ -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<BakedQuad> 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);
|
||||
|
|
|
@ -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 <code>renderWorld.getShade(...)</code> returns a constant.
|
||||
*/
|
||||
public WorldModel(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks, String name) {
|
||||
reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilderFromTemplate(renderWorld, layer, blocks));
|
||||
this.name = name;
|
||||
|
|
|
@ -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<BlockPos> 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<BlockPos> getBlockEntitiesPos() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Map.Entry<Heightmap.Types, Heightmap>> 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<StructureFeature<?>, 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<StructureFeature<?>, LongSet> arg0) {}
|
||||
|
||||
@Override
|
||||
public void setStartForFeature(StructureFeature<?> arg0, StructureStart<?> arg1) {}
|
||||
|
||||
@Override
|
||||
public void setAllStarts(Map<StructureFeature<?>, StructureStart<?>> p_201612_1_) {}
|
||||
|
||||
@Override
|
||||
public Map<StructureFeature<?>, StructureStart<?>> getAllStarts() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return world.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinBuildHeight() {
|
||||
return world.getMinBuildHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickContainerAccess<Fluid> getFluidTicks() {
|
||||
return BlackholeTickAccess.emptyContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TicksToSave getTicksForSerialization() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickContainerAccess<Block> getBlockTicks() {
|
||||
return BlackholeTickAccess.emptyContainer();
|
||||
}
|
||||
|
||||
}
|
|
@ -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.");
|
||||
}
|
||||
}
|
|
@ -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<Long, VirtualChunk> 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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
|
@ -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<T extends EntityAccess> implements LevelEntityGetter<T> {
|
||||
|
||||
@Override
|
||||
public T get(int p_156931_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(UUID pUuid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<T> getAll() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U extends T> void get(EntityTypeTest<T, U> p_156935_, Consumer<U> p_156936_) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void get(AABB p_156937_, Consumer<T> p_156938_) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U extends T> void get(EntityTypeTest<T, U> p_156932_, AABB p_156933_, Consumer<U> p_156934_) {
|
||||
}
|
||||
|
||||
}
|
|
@ -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<BlockPos, BlockState> blocksAdded = new HashMap<>();
|
||||
public final Map<BlockPos, BlockEntity> tesAdded = new HashMap<>();
|
||||
public final Set<SectionPos> spannedSections = new HashSet<>();
|
||||
private final BlockPos.MutableBlockPos scratch = new BlockPos.MutableBlockPos();
|
||||
|
||||
public final LevelLightEngine lighter;
|
||||
public final VirtualChunkSource chunkSource;
|
||||
|
||||
protected Level level;
|
||||
|
||||
protected LevelEntityGetter<Entity> 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<BlockPos, BlockState> 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<BlockEntity> 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<Entity> 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<BlockState> 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<Block> getBlockTicks() {
|
||||
return level.getBlockTicks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelTickAccess<Fluid> 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<? extends Player> 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) {}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.core.virtual;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue