Added opacity based mipping

This commit is contained in:
mcrcortex
2025-01-15 01:24:37 +10:00
parent 6539e69fb0
commit dbf1188b12
2 changed files with 50 additions and 15 deletions

View File

@@ -197,6 +197,13 @@ public class Mapper {
return this.block2stateEntry.computeIfAbsent(state, this::registerNewBlockState).id; return this.block2stateEntry.computeIfAbsent(state, this::registerNewBlockState).id;
} }
public int getBlockStateOpacity(long mappingId) {
return this.getBlockStateOpacity(getBlockId(mappingId));
}
public int getBlockStateOpacity(int blockId) {
return this.blockId2stateEntry.get(blockId).opacity;
}
//TODO: replace lambda with a class cached lambda ref (cause doing this:: still does a lambda allocation) //TODO: replace lambda with a class cached lambda ref (cause doing this:: still does a lambda allocation)
public int getIdForBiome(RegistryEntry<Biome> biome) { public int getIdForBiome(RegistryEntry<Biome> biome) {
@@ -279,9 +286,11 @@ public class Mapper {
public static final class StateEntry { public static final class StateEntry {
public final int id; public final int id;
public final BlockState state; public final BlockState state;
public final int opacity;
public StateEntry(int id, BlockState state) { public StateEntry(int id, BlockState state) {
this.id = id; this.id = id;
this.state = state; this.state = state;
this.opacity = state.getOpacity();
} }
public byte[] serialize() { public byte[] serialize() {

View File

@@ -4,11 +4,23 @@ import static me.cortex.voxy.common.world.other.Mapper.withLight;
//Mipper for data //Mipper for data
public class Mipper { public class Mipper {
//TODO: compute the opacity of the block then mip w.r.t those blocks
// as distant horizons done
//TODO: also pass in the level its mipping from, cause at lower levels you want to preserve block details //TODO: also pass in the level its mipping from, cause at lower levels you want to preserve block details
// but at higher details you want more air // but at higher details you want more air
public static long mip(long I000, long I100, long I001, long I101, public static long mip(long I000, long I100, long I001, long I101,
long I010, long I110, long I011, long I111, long I010, long I110, long I011, long I111,
Mapper mapper) { Mapper mapper) {
//TODO: do a stable sort on all the entires, w.r.t the opacity and maybe light as a secondary???
// then select the highest value
// UPDATE, dumbass, the highest value _is_ the max/min
int max = -1;
//TODO: mip with respect to all the variables, what that means is take whatever has the highest count and return that //TODO: mip with respect to all the variables, what that means is take whatever has the highest count and return that
//TODO: also average out the light level and set that as the new light level //TODO: also average out the light level and set that as the new light level
//For now just take the most top corner //For now just take the most top corner
@@ -17,37 +29,51 @@ public class Mipper {
// you can see it from really really damn far away. // you can see it from really really damn far away.
// it could be a heavily weighted average with a huge preference to the top most lighting value // it could be a heavily weighted average with a huge preference to the top most lighting value
if (!Mapper.isAir(I111)) { if (!Mapper.isAir(I111)) {
return I111; max = (mapper.getBlockStateOpacity(I111)<<4)|0b111;
} }
if (!Mapper.isAir(I110)) { if (!Mapper.isAir(I110)) {
return I110; max = Math.max((mapper.getBlockStateOpacity(I110)<<4)|0b110, max);
} }
if (!Mapper.isAir(I011)) { if (!Mapper.isAir(I011)) {
return I011; max = Math.max((mapper.getBlockStateOpacity(I011)<<4)|0b011, max);
} }
if (!Mapper.isAir(I010)) { if (!Mapper.isAir(I010)) {
return I010; max = Math.max((mapper.getBlockStateOpacity(I010)<<4)|0b010, max);
} }
if (!Mapper.isAir(I101)) { if (!Mapper.isAir(I101)) {
return I101; max = Math.max((mapper.getBlockStateOpacity(I101)<<4)|0b101, max);
} }
if (!Mapper.isAir(I100)) { if (!Mapper.isAir(I100)) {
return I100; max = Math.max((mapper.getBlockStateOpacity(I100)<<4)|0b100, max);
} }
if (!Mapper.isAir(I001)) { if (!Mapper.isAir(I001)) {
return I001; max = Math.max((mapper.getBlockStateOpacity(I001)<<4)|0b001, max);
} }
if (!Mapper.isAir(I000)) { if (!Mapper.isAir(I000)) {
return I000; max = Math.max((mapper.getBlockStateOpacity(I000)<<4), max);
} }
int blockLight = (Mapper.getLightId(I000)&0xF0)+(Mapper.getLightId(I001)&0xF0)+(Mapper.getLightId(I010)&0xF0)+(Mapper.getLightId(I011)&0xF0)+ if (max != -1) {
(Mapper.getLightId(I100)&0xF0)+(Mapper.getLightId(I101)&0xF0)+(Mapper.getLightId(I110)&0xF0)+(Mapper.getLightId(I111)&0xF0); return switch (max&0b111) {
int skyLight = (Mapper.getLightId(I000)&0x0F)+(Mapper.getLightId(I001)&0x0F)+(Mapper.getLightId(I010)&0x0F)+(Mapper.getLightId(I011)&0x0F)+ case 0 -> I000;
(Mapper.getLightId(I100)&0x0F)+(Mapper.getLightId(I101)&0x0F)+(Mapper.getLightId(I110)&0x0F)+(Mapper.getLightId(I111)&0x0F); case 1 -> I001;
blockLight = blockLight/8; case 2 -> I010;
skyLight = (int) Math.ceil((double)skyLight/8); case 3 -> I011;
case 4 -> I100;
case 5 -> I101;
case 6 -> I110;
case 7 -> I111;
default -> throw new IllegalStateException("Unexpected value: " + (max&0b111));
};
} else {
int blockLight = (Mapper.getLightId(I000) & 0xF0) + (Mapper.getLightId(I001) & 0xF0) + (Mapper.getLightId(I010) & 0xF0) + (Mapper.getLightId(I011) & 0xF0) +
(Mapper.getLightId(I100) & 0xF0) + (Mapper.getLightId(I101) & 0xF0) + (Mapper.getLightId(I110) & 0xF0) + (Mapper.getLightId(I111) & 0xF0);
int skyLight = (Mapper.getLightId(I000) & 0x0F) + (Mapper.getLightId(I001) & 0x0F) + (Mapper.getLightId(I010) & 0x0F) + (Mapper.getLightId(I011) & 0x0F) +
(Mapper.getLightId(I100) & 0x0F) + (Mapper.getLightId(I101) & 0x0F) + (Mapper.getLightId(I110) & 0x0F) + (Mapper.getLightId(I111) & 0x0F);
blockLight = blockLight / 8;
skyLight = (int) Math.ceil((double) skyLight / 8);
return withLight(I111, (blockLight<<4)|skyLight); return withLight(I111, (blockLight << 4) | skyLight);
}
} }
} }