EA
This commit is contained in:
@@ -3,9 +3,11 @@ package me.cortex.voxy.client.core.model;
|
|||||||
import com.mojang.blaze3d.platform.GlConst;
|
import com.mojang.blaze3d.platform.GlConst;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
|
import me.cortex.voxy.client.core.IGetVoxelCore;
|
||||||
import me.cortex.voxy.client.core.gl.GlBuffer;
|
import me.cortex.voxy.client.core.gl.GlBuffer;
|
||||||
import me.cortex.voxy.client.core.gl.GlTexture;
|
import me.cortex.voxy.client.core.gl.GlTexture;
|
||||||
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||||
|
import me.cortex.voxy.common.world.other.Mapper;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
@@ -53,9 +55,9 @@ import static org.lwjgl.opengl.GL45C.glTextureSubImage2D;
|
|||||||
public class ModelManager {
|
public class ModelManager {
|
||||||
//TODO: replace the fluid BlockState with a client model id integer of the fluidState, requires looking up
|
//TODO: replace the fluid BlockState with a client model id integer of the fluidState, requires looking up
|
||||||
// the fluid state in the mipper
|
// the fluid state in the mipper
|
||||||
private record ModelEntry(List<ColourDepthTextureData> textures, BlockState fluidBlockState){
|
private record ModelEntry(List<ColourDepthTextureData> textures, int fluidBlockStateId){
|
||||||
private ModelEntry(ColourDepthTextureData[] textures, BlockState fluidBlockState) {
|
private ModelEntry(ColourDepthTextureData[] textures, int fluidBlockStateId) {
|
||||||
this(Stream.of(textures).map(ColourDepthTextureData::clone).toList(), fluidBlockState);
|
this(Stream.of(textures).map(ColourDepthTextureData::clone).toList(), fluidBlockStateId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,6 +98,7 @@ public class ModelManager {
|
|||||||
|
|
||||||
// this has an issue with scaffolding i believe tho, so maybe make it a probability to render??? idk
|
// this has an issue with scaffolding i believe tho, so maybe make it a probability to render??? idk
|
||||||
private final long[] metadataCache;
|
private final long[] metadataCache;
|
||||||
|
private final int[] fluidStateLUT;
|
||||||
|
|
||||||
//Provides a map from id -> model id as multiple ids might have the same internal model id
|
//Provides a map from id -> model id as multiple ids might have the same internal model id
|
||||||
private final int[] idMappings;
|
private final int[] idMappings;
|
||||||
@@ -116,8 +119,10 @@ public class ModelManager {
|
|||||||
//TODO: figure out how to do mipping :blobfox_pineapple:
|
//TODO: figure out how to do mipping :blobfox_pineapple:
|
||||||
this.textures = new GlTexture().store(GL_RGBA8, 4, modelTextureSize*3*256,modelTextureSize*2*256);
|
this.textures = new GlTexture().store(GL_RGBA8, 4, modelTextureSize*3*256,modelTextureSize*2*256);
|
||||||
this.metadataCache = new long[1<<16];
|
this.metadataCache = new long[1<<16];
|
||||||
|
this.fluidStateLUT = new int[1<<16];
|
||||||
this.idMappings = new int[1<<20];//Max of 1 million blockstates mapping to 65k model states
|
this.idMappings = new int[1<<20];//Max of 1 million blockstates mapping to 65k model states
|
||||||
Arrays.fill(this.idMappings, -1);
|
Arrays.fill(this.idMappings, -1);
|
||||||
|
Arrays.fill(this.fluidStateLUT, -1);
|
||||||
|
|
||||||
|
|
||||||
glSamplerParameteri(this.blockSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
|
glSamplerParameteri(this.blockSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
|
||||||
@@ -145,8 +150,24 @@ public class ModelManager {
|
|||||||
int modelId = -1;
|
int modelId = -1;
|
||||||
var textureData = this.bakery.renderFaces(blockState, 123456, isFluid);
|
var textureData = this.bakery.renderFaces(blockState, 123456, isFluid);
|
||||||
|
|
||||||
|
int clientFluidStateId = -1;
|
||||||
|
|
||||||
|
if ((!isFluid) && (!blockState.getFluidState().isEmpty())) {
|
||||||
|
//Insert into the fluid LUT
|
||||||
|
var fluidState = blockState.getFluidState().getBlockState();
|
||||||
|
|
||||||
|
//TODO:FIXME: PASS IN THE Mapper instead of grabbing it!!! THIS IS CRTICIAL TO FIX
|
||||||
|
int fluidStateId = ((IGetVoxelCore)MinecraftClient.getInstance().worldRenderer).getVoxelCore().getWorldEngine().getMapper().getIdForBlockState(fluidState);
|
||||||
|
|
||||||
|
|
||||||
|
clientFluidStateId = this.idMappings[fluidStateId];
|
||||||
|
if (clientFluidStateId == -1) {
|
||||||
|
clientFluidStateId = this.addEntry(fluidStateId, fluidState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{//Deduplicate same entries
|
{//Deduplicate same entries
|
||||||
var entry = new ModelEntry(textureData, isFluid||blockState.getFluidState().isEmpty()?null:blockState.getFluidState().getBlockState());
|
var entry = new ModelEntry(textureData, clientFluidStateId);
|
||||||
int possibleDuplicate = this.modelTexture2id.getInt(entry);
|
int possibleDuplicate = this.modelTexture2id.getInt(entry);
|
||||||
if (possibleDuplicate != -1) {//Duplicate found
|
if (possibleDuplicate != -1) {//Duplicate found
|
||||||
this.idMappings[blockId] = possibleDuplicate;
|
this.idMappings[blockId] = possibleDuplicate;
|
||||||
@@ -159,6 +180,12 @@ public class ModelManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isFluid) {
|
||||||
|
this.fluidStateLUT[modelId] = modelId;
|
||||||
|
} else if (clientFluidStateId != -1) {
|
||||||
|
this.fluidStateLUT[modelId] = clientFluidStateId;
|
||||||
|
}
|
||||||
|
|
||||||
var colourProvider = MinecraftClient.getInstance().getBlockColors().providers.get(Registries.BLOCK.getRawId(blockState.getBlock()));
|
var colourProvider = MinecraftClient.getInstance().getBlockColors().providers.get(Registries.BLOCK.getRawId(blockState.getBlock()));
|
||||||
|
|
||||||
|
|
||||||
@@ -205,6 +232,7 @@ public class ModelManager {
|
|||||||
metadata |= blockRenderLayer == RenderLayer.getTranslucent()?2:0;
|
metadata |= blockRenderLayer == RenderLayer.getTranslucent()?2:0;
|
||||||
metadata |= needsDoubleSidedQuads?4:0;
|
metadata |= needsDoubleSidedQuads?4:0;
|
||||||
metadata |= (!blockState.getFluidState().isEmpty())?8:0;//Has a fluid state accosiacted with it
|
metadata |= (!blockState.getFluidState().isEmpty())?8:0;//Has a fluid state accosiacted with it
|
||||||
|
metadata |= isFluid?16:0;//Is a fluid
|
||||||
|
|
||||||
//TODO: add a bunch of control config options for overriding/setting options of metadata for each face of each type
|
//TODO: add a bunch of control config options for overriding/setting options of metadata for each face of each type
|
||||||
for (int face = 5; face != -1; face--) {//In reverse order to make indexing into the metadata long easier
|
for (int face = 5; face != -1; face--) {//In reverse order to make indexing into the metadata long easier
|
||||||
@@ -464,11 +492,6 @@ public class ModelManager {
|
|||||||
return ((metadata>>(8*face))&0b1000) != 0;
|
return ((metadata>>(8*face))&0b1000) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isColoured(long metadata) {
|
|
||||||
//TODO: THIS
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDoubleSided(long metadata) {
|
public static boolean isDoubleSided(long metadata) {
|
||||||
return ((metadata>>(8*6))&4) != 0;
|
return ((metadata>>(8*6))&4) != 0;
|
||||||
}
|
}
|
||||||
@@ -481,6 +504,10 @@ public class ModelManager {
|
|||||||
return ((metadata>>(8*6))&8) != 0;
|
return ((metadata>>(8*6))&8) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isFluid(long metadata) {
|
||||||
|
return ((metadata>>(8*6))&16) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isBiomeColoured(long metadata) {
|
public static boolean isBiomeColoured(long metadata) {
|
||||||
return ((metadata>>(8*6))&1) != 0;
|
return ((metadata>>(8*6))&1) != 0;
|
||||||
}
|
}
|
||||||
@@ -538,6 +565,10 @@ public class ModelManager {
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getModelMetadataFromClientId(int clientId) {
|
||||||
|
return this.metadataCache[clientId];
|
||||||
|
}
|
||||||
|
|
||||||
public int getModelId(int blockId) {
|
public int getModelId(int blockId) {
|
||||||
int map = this.idMappings[blockId];
|
int map = this.idMappings[blockId];
|
||||||
if (map == -1) {
|
if (map == -1) {
|
||||||
@@ -546,6 +577,14 @@ public class ModelManager {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getFluidClientStateId(int clientBlockStateId) {
|
||||||
|
int map = this.fluidStateLUT[clientBlockStateId];
|
||||||
|
if (map == -1) {
|
||||||
|
throw new IdNotYetComputedException(clientBlockStateId);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
private void putTextures(int id, ColourDepthTextureData[] textures) {
|
private void putTextures(int id, ColourDepthTextureData[] textures) {
|
||||||
int X = (id&0xFF) * this.modelTextureSize*3;
|
int X = (id&0xFF) * this.modelTextureSize*3;
|
||||||
int Y = ((id>>8)&0xFF) * this.modelTextureSize*2;
|
int Y = ((id>>8)&0xFF) * this.modelTextureSize*2;
|
||||||
|
|||||||
@@ -141,8 +141,8 @@ public class RenderTracker {
|
|||||||
|
|
||||||
//Enqueues a renderTask for a section to cache the result
|
//Enqueues a renderTask for a section to cache the result
|
||||||
public void addCache(int lvl, int x, int y, int z) {
|
public void addCache(int lvl, int x, int y, int z) {
|
||||||
this.renderGen.markCache(lvl, x, y, z);
|
//this.renderGen.markCache(lvl, x, y, z);
|
||||||
this.renderGen.enqueueTask(lvl, x, y, z, ((lvl1, x1, y1, z1) -> true));//TODO: replace the true identity lambda with a callback check to the render cache
|
//this.renderGen.enqueueTask(lvl, x, y, z, ((lvl1, x1, y1, z1) -> true));//TODO: replace the true identity lambda with a callback check to the render cache
|
||||||
}
|
}
|
||||||
|
|
||||||
//Removes the position from the cache
|
//Removes the position from the cache
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ public class RenderDataFactory {
|
|||||||
|
|
||||||
private final Mesher2D negativeMesher = new Mesher2D(5, 15);
|
private final Mesher2D negativeMesher = new Mesher2D(5, 15);
|
||||||
private final Mesher2D positiveMesher = new Mesher2D(5, 15);
|
private final Mesher2D positiveMesher = new Mesher2D(5, 15);
|
||||||
|
private final Mesher2D negativeFluidMesher = new Mesher2D(5, 15);
|
||||||
|
private final Mesher2D positiveFluidMesher = new Mesher2D(5, 15);
|
||||||
|
|
||||||
private final long[] sectionCache = new long[32*32*32];
|
private final long[] sectionCache = new long[32*32*32];
|
||||||
private final long[] connectedSectionCache = new long[32*32*32];
|
private final long[] connectedSectionCache = new long[32*32*32];
|
||||||
@@ -45,10 +47,12 @@ public class RenderDataFactory {
|
|||||||
// instead of needing to regen the entire thing
|
// instead of needing to regen the entire thing
|
||||||
|
|
||||||
|
|
||||||
//section is already acquired and gets released by the parent
|
//Ok so the idea for fluid rendering is to make it use a seperate mesher and use a different code path for it
|
||||||
|
// since fluid states are explicitly overlays over the base block
|
||||||
|
// can do funny stuff like double rendering
|
||||||
|
|
||||||
//buildMask in the lower 6 bits contains the faces to build, the next 6 bits are whether the edge face builds against
|
|
||||||
// its neigbor or not (0 if it does 1 if it doesnt (0 is default behavior))
|
//section is already acquired and gets released by the parent
|
||||||
public BuiltSection generateMesh(WorldSection section) {
|
public BuiltSection generateMesh(WorldSection section) {
|
||||||
section.copyDataTo(this.sectionCache);
|
section.copyDataTo(this.sectionCache);
|
||||||
this.translucentQuadCollector.clear();
|
this.translucentQuadCollector.clear();
|
||||||
@@ -116,6 +120,7 @@ public class RenderDataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: FIXME: a block can have a face even if it doesnt, cause of if it has a fluid state
|
||||||
private void generateMeshForAxis(WorldSection section, int axisId) {
|
private void generateMeshForAxis(WorldSection section, int axisId) {
|
||||||
int aX = axisId==2?1:0;
|
int aX = axisId==2?1:0;
|
||||||
int aY = axisId==0?1:0;
|
int aY = axisId==0?1:0;
|
||||||
@@ -130,6 +135,8 @@ public class RenderDataFactory {
|
|||||||
for (int primary = 0; primary < 32; primary++) {
|
for (int primary = 0; primary < 32; primary++) {
|
||||||
this.negativeMesher.reset();
|
this.negativeMesher.reset();
|
||||||
this.positiveMesher.reset();
|
this.positiveMesher.reset();
|
||||||
|
this.negativeFluidMesher.reset();
|
||||||
|
this.positiveFluidMesher.reset();
|
||||||
|
|
||||||
for (int a = 0; a < 32; a++) {
|
for (int a = 0; a < 32; a++) {
|
||||||
for (int b = 0; b < 32; b++) {
|
for (int b = 0; b < 32; b++) {
|
||||||
@@ -147,8 +154,7 @@ public class RenderDataFactory {
|
|||||||
boolean putFace = false;
|
boolean putFace = false;
|
||||||
|
|
||||||
//Branch into 2 paths, the + direction and -direction, doing it at once makes it much faster as it halves the number of loops
|
//Branch into 2 paths, the + direction and -direction, doing it at once makes it much faster as it halves the number of loops
|
||||||
|
if (ModelManager.faceExists(selfMetadata, axisId<<1) || ModelManager.containsFluid(selfMetadata)) {//- direction
|
||||||
if (ModelManager.faceExists(selfMetadata, axisId<<1)) {//- direction
|
|
||||||
long facingState = Mapper.AIR;
|
long facingState = Mapper.AIR;
|
||||||
//Need to access the other connecting section
|
//Need to access the other connecting section
|
||||||
if (primary == 0) {
|
if (primary == 0) {
|
||||||
@@ -167,9 +173,14 @@ public class RenderDataFactory {
|
|||||||
facingState = this.sectionCache[WorldSection.getIndex(x-aX, y-aY, z-aZ)];
|
facingState = this.sectionCache[WorldSection.getIndex(x-aX, y-aY, z-aZ)];
|
||||||
}
|
}
|
||||||
|
|
||||||
putFace |= this.putFaceIfCan(this.negativeMesher, (axisId<<1), (axisId<<1)|1, self, selfMetadata, selfBlockId, facingState, a, b);
|
if (!ModelManager.isFluid(selfMetadata)) {
|
||||||
|
putFace |= this.putFaceIfCan(this.negativeMesher, (axisId << 1), (axisId << 1)|1, self, selfMetadata, selfBlockId, facingState, a, b);
|
||||||
}
|
}
|
||||||
if (ModelManager.faceExists(selfMetadata, axisId<<1)) {//+ direction
|
if (ModelManager.containsFluid(selfMetadata)) {
|
||||||
|
putFace |= this.putFluidFaceIfCan(this.negativeFluidMesher, (axisId << 1), (axisId << 1)|1, self, selfMetadata, selfBlockId, facingState, a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ModelManager.faceExists(selfMetadata, (axisId<<1)|1) || ModelManager.containsFluid(selfMetadata)) {//+ direction
|
||||||
long facingState = Mapper.AIR;
|
long facingState = Mapper.AIR;
|
||||||
//Need to access the other connecting section
|
//Need to access the other connecting section
|
||||||
if (primary == 31) {
|
if (primary == 31) {
|
||||||
@@ -187,8 +198,12 @@ public class RenderDataFactory {
|
|||||||
} else {
|
} else {
|
||||||
facingState = this.sectionCache[WorldSection.getIndex(x+aX, y+aY, z+aZ)];
|
facingState = this.sectionCache[WorldSection.getIndex(x+aX, y+aY, z+aZ)];
|
||||||
}
|
}
|
||||||
|
if (!ModelManager.isFluid(selfMetadata)) {
|
||||||
putFace |= this.putFaceIfCan(this.positiveMesher, (axisId<<1)|1, (axisId<<1), self, selfMetadata, selfBlockId, facingState, a, b);
|
putFace |= this.putFaceIfCan(this.positiveMesher, (axisId << 1) | 1, (axisId << 1), self, selfMetadata, selfBlockId, facingState, a, b);
|
||||||
|
}
|
||||||
|
if (ModelManager.containsFluid(selfMetadata)) {
|
||||||
|
putFace |= this.putFluidFaceIfCan(this.positiveFluidMesher, (axisId << 1) | 1, (axisId << 1), self, selfMetadata, selfBlockId, facingState, a, b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (putFace) {
|
if (putFace) {
|
||||||
@@ -204,9 +219,54 @@ public class RenderDataFactory {
|
|||||||
|
|
||||||
processMeshedFace(this.negativeMesher, axisId<<1, primary, this.directionalQuadCollectors[(axisId<<1)]);
|
processMeshedFace(this.negativeMesher, axisId<<1, primary, this.directionalQuadCollectors[(axisId<<1)]);
|
||||||
processMeshedFace(this.positiveMesher, (axisId<<1)|1, primary, this.directionalQuadCollectors[(axisId<<1)|1]);
|
processMeshedFace(this.positiveMesher, (axisId<<1)|1, primary, this.directionalQuadCollectors[(axisId<<1)|1]);
|
||||||
|
|
||||||
|
processMeshedFace(this.negativeFluidMesher, axisId<<1, primary, this.directionalQuadCollectors[(axisId<<1)]);
|
||||||
|
processMeshedFace(this.positiveFluidMesher, (axisId<<1)|1, primary, this.directionalQuadCollectors[(axisId<<1)|1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Returns true if a face was placed
|
||||||
|
private boolean putFluidFaceIfCan(Mesher2D mesher, int face, int opposingFace, long self, long metadata, int selfBlockId, long facingState, int a, int b) {
|
||||||
|
long facingMetadata = this.modelMan.getModelMetadata(Mapper.getBlockId(facingState));
|
||||||
|
|
||||||
|
int selfFluidClientId = this.modelMan.getFluidClientStateId(this.modelMan.getModelId(selfBlockId));
|
||||||
|
long selfFluidMetadata = this.modelMan.getModelMetadataFromClientId(selfFluidClientId);
|
||||||
|
|
||||||
|
int facingFluidClientId = -1;
|
||||||
|
if (ModelManager.containsFluid(facingMetadata)) {
|
||||||
|
facingFluidClientId = this.modelMan.getFluidClientStateId(this.modelMan.getModelId(Mapper.getBlockId(facingState)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//If both of the states are the same, then dont render the fluid face
|
||||||
|
if (selfFluidClientId == facingFluidClientId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (facingFluidClientId != -1) {
|
||||||
|
if (this.world.getMapper().getBlockStateFromId(selfBlockId).getFluidState().getFluid() == this.world.getMapper().getBlockStateFromId(facingState).getFluidState().getFluid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModelManager.faceOccludes(facingMetadata, opposingFace)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//NOTE: if the model has a fluid state but is not a liquid need to see if the solid state had a face rendered and that face is occluding, if so, dont render the fluid state face
|
||||||
|
|
||||||
|
//TODO:FIXME FINISH
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
long otherFlags = 0;
|
||||||
|
otherFlags |= ModelManager.isTranslucent(selfFluidMetadata)?1L<<33:0;
|
||||||
|
otherFlags |= ModelManager.isDoubleSided(selfFluidMetadata)?1L<<34:0;
|
||||||
|
mesher.put(a, b, ((long)selfFluidClientId) | (((long) Mapper.getLightId(ModelManager.faceUsesSelfLighting(selfFluidMetadata, face)?self:facingState))<<16) | ((((long) Mapper.getBiomeId(self))<<24) * (ModelManager.isBiomeColoured(selfFluidMetadata)?1:0)) | otherFlags);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//Returns true if a face was placed
|
//Returns true if a face was placed
|
||||||
private boolean putFaceIfCan(Mesher2D mesher, int face, int opposingFace, long self, long metadata, int selfBlockId, long facingState, int a, int b) {
|
private boolean putFaceIfCan(Mesher2D mesher, int face, int opposingFace, long self, long metadata, int selfBlockId, long facingState, int a, int b) {
|
||||||
long facingMetadata = this.modelMan.getModelMetadata(Mapper.getBlockId(facingState));
|
long facingMetadata = this.modelMan.getModelMetadata(Mapper.getBlockId(facingState));
|
||||||
@@ -222,36 +282,6 @@ public class RenderDataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//TODO: if the model has a fluid state, it should compute if a fluid face needs to be injected
|
|
||||||
// fluid face of type this.world.getMapper().getBlockStateFromId(self).getFluidState() and block type
|
|
||||||
// this.world.getMapper().getBlockStateFromId(self).getFluidState().getBlockState()
|
|
||||||
|
|
||||||
//If we are a fluid
|
|
||||||
if (ModelManager.containsFluid(metadata)) {
|
|
||||||
var selfBS = this.world.getMapper().getBlockStateFromId(self);
|
|
||||||
if (ModelManager.containsFluid(facingMetadata)) {//and the oposing face is also a fluid need to make a closer check
|
|
||||||
var faceBS = this.world.getMapper().getBlockStateFromId(facingState);
|
|
||||||
|
|
||||||
//If we are a fluid block that means our face is a fluid face, waterlogged blocks dont include fluid faces in the model data
|
|
||||||
if (selfBS.getBlock() instanceof FluidBlock) {
|
|
||||||
//If the fluid state of both blocks are the same we dont emit extra geometry
|
|
||||||
if (selfBS.getFluidState().getBlockState().equals(faceBS.getFluidState().getBlockState())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {//If we are not a fluid block, we might need to emit extra geometry (fluid faces) to the auxliery mesher
|
|
||||||
boolean shouldEmitFluidFace = !selfBS.getFluidState().getBlockState().equals(faceBS.getFluidState().getBlockState());
|
|
||||||
//TODO: THIS
|
|
||||||
int aa = 0;
|
|
||||||
}
|
|
||||||
} else if (!(selfBS.getBlock() instanceof FluidBlock)) {//If we are not a fluid block but we contain a fluid we might need to emit extra geometry
|
|
||||||
//Basicly need to get the fluid state and run putFaceIfCan using the fluid state as the self state and keep the same facing state
|
|
||||||
//TODO: THIS
|
|
||||||
int aa = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int clientModelId = this.modelMan.getModelId(selfBlockId);
|
int clientModelId = this.modelMan.getModelId(selfBlockId);
|
||||||
long otherFlags = 0;
|
long otherFlags = 0;
|
||||||
otherFlags |= ModelManager.isTranslucent(metadata)?1L<<33:0;
|
otherFlags |= ModelManager.isTranslucent(metadata)?1L<<33:0;
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class RenderGenerationService {
|
|||||||
mesh = factory.generateMesh(section);
|
mesh = factory.generateMesh(section);
|
||||||
} catch (IdNotYetComputedException e) {
|
} catch (IdNotYetComputedException e) {
|
||||||
//We need to reinsert the build task into the queue
|
//We need to reinsert the build task into the queue
|
||||||
System.err.println("Render task failed to complete due to un-computed client id");
|
//System.err.println("Render task failed to complete due to un-computed client id");
|
||||||
synchronized (this.taskQueue) {
|
synchronized (this.taskQueue) {
|
||||||
this.taskQueue.computeIfAbsent(section.key, key->{this.taskCounter.release(); return task;});
|
this.taskQueue.computeIfAbsent(section.key, key->{this.taskCounter.release(); return task;});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public class Mesher2D {
|
|||||||
private final long[] data;
|
private final long[] data;
|
||||||
private final BitSet setset;
|
private final BitSet setset;
|
||||||
private int[] quadCache;
|
private int[] quadCache;
|
||||||
|
private boolean isEmpty = true;
|
||||||
public Mesher2D(int sizeBits, int maxSize) {
|
public Mesher2D(int sizeBits, int maxSize) {
|
||||||
this.size = sizeBits;
|
this.size = sizeBits;
|
||||||
this.maxSize = maxSize;
|
this.maxSize = maxSize;
|
||||||
@@ -27,6 +28,7 @@ public class Mesher2D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Mesher2D put(int x, int z, long data) {
|
public Mesher2D put(int x, int z, long data) {
|
||||||
|
this.isEmpty = false;
|
||||||
int idx = this.getIdx(x, z);
|
int idx = this.getIdx(x, z);
|
||||||
this.data[idx] = data;
|
this.data[idx] = data;
|
||||||
this.setset.set(idx);
|
this.setset.set(idx);
|
||||||
@@ -61,6 +63,10 @@ public class Mesher2D {
|
|||||||
|
|
||||||
//Returns the number of compacted quads
|
//Returns the number of compacted quads
|
||||||
public int process() {
|
public int process() {
|
||||||
|
if (this.isEmpty) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int[] quads = this.quadCache;
|
int[] quads = this.quadCache;
|
||||||
int idxCount = 0;
|
int idxCount = 0;
|
||||||
|
|
||||||
@@ -144,9 +150,12 @@ public class Mesher2D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
|
if (!this.isEmpty) {
|
||||||
|
this.isEmpty = true;
|
||||||
this.setset.clear();
|
this.setset.clear();
|
||||||
Arrays.fill(this.data, 0);
|
Arrays.fill(this.data, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public long getDataFromQuad(int quad) {
|
public long getDataFromQuad(int quad) {
|
||||||
return this.getData(getX(quad), getZ(quad));
|
return this.getData(getX(quad), getZ(quad));
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class MixinClientChunkManager {
|
|||||||
private void injectUnload(ChunkPos pos, CallbackInfo ci, int index, WorldChunk worldChunk) {
|
private void injectUnload(ChunkPos pos, CallbackInfo ci, int index, WorldChunk worldChunk) {
|
||||||
var core = ((IGetVoxelCore)(world.worldRenderer)).getVoxelCore();
|
var core = ((IGetVoxelCore)(world.worldRenderer)).getVoxelCore();
|
||||||
if (core != null && VoxyConfig.CONFIG.ingestEnabled) {
|
if (core != null && VoxyConfig.CONFIG.ingestEnabled) {
|
||||||
core.enqueueIngest(worldChunk);
|
//core.enqueueIngest(worldChunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package me.cortex.voxy.client.mixin.sodium;
|
||||||
|
|
||||||
|
import me.cortex.voxy.client.config.VoxyConfig;
|
||||||
|
import me.cortex.voxy.client.core.IGetVoxelCore;
|
||||||
|
import me.jellysquid.mods.sodium.client.render.chunk.RenderSectionManager;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(value = RenderSectionManager.class, remap = false)
|
||||||
|
public class MixinRenderSectionManager {
|
||||||
|
@Shadow @Final private ClientWorld world;
|
||||||
|
|
||||||
|
@Inject(method = "onChunkRemoved", at = @At("HEAD"))
|
||||||
|
private void injectIngest(int x, int z, CallbackInfo ci) {
|
||||||
|
var core = ((IGetVoxelCore)(world.worldRenderer)).getVoxelCore();
|
||||||
|
if (core != null && VoxyConfig.CONFIG.ingestEnabled) {
|
||||||
|
core.enqueueIngest(world.getChunk(x, z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,15 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TranslocatingStorageAdaptor extends DelegatingStorageAdaptor {
|
public class TranslocatingStorageAdaptor extends DelegatingStorageAdaptor {
|
||||||
public record BoxTransform(int x1, int y1, int z1, int x2, int y2, int z2, int dx, int dy, int dz) {
|
public enum Mode {
|
||||||
|
BOX_ONLY,
|
||||||
|
PRIORITY_BOX,
|
||||||
|
PRIORITY_ORIGINAL
|
||||||
|
}
|
||||||
|
public record BoxTransform(int x1, int y1, int z1, int x2, int y2, int z2, int dx, int dy, int dz, Mode mode) {
|
||||||
|
public BoxTransform(int x1, int y1, int z1, int x2, int y2, int z2, int dx, int dy, int dz) {
|
||||||
|
this(x1, y1, z1, x2, y2, z2, dx, dy, dz, Mode.BOX_ONLY);
|
||||||
|
}
|
||||||
public long transformIfInBox(long pos) {
|
public long transformIfInBox(long pos) {
|
||||||
int lvl = WorldEngine.getLevel(pos);
|
int lvl = WorldEngine.getLevel(pos);
|
||||||
int x = WorldEngine.getX(pos);
|
int x = WorldEngine.getX(pos);
|
||||||
@@ -38,19 +46,29 @@ public class TranslocatingStorageAdaptor extends DelegatingStorageAdaptor {
|
|||||||
this.transforms = transforms;
|
this.transforms = transforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long transformPosition(long pos) {
|
|
||||||
for (var transform : this.transforms) {
|
|
||||||
long tpos = transform.transformIfInBox(pos);
|
|
||||||
if (tpos != -1) {
|
|
||||||
return tpos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer getSectionData(long key) {
|
public ByteBuffer getSectionData(long key) {
|
||||||
return super.getSectionData(this.transformPosition(key));
|
for (var transform : this.transforms) {
|
||||||
|
long tpos = transform.transformIfInBox(key);
|
||||||
|
if (tpos != -1) {
|
||||||
|
if (transform.mode == Mode.BOX_ONLY || transform.mode == null) {
|
||||||
|
return super.getSectionData(tpos);
|
||||||
|
} else if (transform.mode == Mode.PRIORITY_BOX) {
|
||||||
|
var data = super.getSectionData(tpos);
|
||||||
|
if (data == null) {
|
||||||
|
return super.getSectionData(key);
|
||||||
|
}
|
||||||
|
} else if (transform.mode == Mode.PRIORITY_ORIGINAL) {
|
||||||
|
var data = super.getSectionData(key);
|
||||||
|
if (data == null) {
|
||||||
|
return super.getSectionData(tpos);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.getSectionData(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -14,5 +14,8 @@
|
|||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
}
|
},
|
||||||
|
"mixins": [
|
||||||
|
"sodium.MixinRenderSectionManager"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user