Refactor and cleanup ClientBlockStateCache
This commit is contained in:
+18
-9
@@ -29,20 +29,29 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class ClientBlockDetailMap
|
||||
{
|
||||
private final ConcurrentHashMap<BlockState, ClientBlockStateCache> blockCache = new ConcurrentHashMap<>();
|
||||
//private final ConcurrentHashMap<#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif, Biome> biomeMap = new ConcurrentHashMap<>();
|
||||
private final ClientLevelWrapper level;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public ClientBlockDetailMap(ClientLevelWrapper level) { this.level = level; }
|
||||
|
||||
public ClientBlockStateCache getBlockStateData(BlockState state, DhBlockPos pos)
|
||||
{ //TODO: Allow a per pos unique setting
|
||||
return blockCache.computeIfAbsent(state, (s) -> new ClientBlockStateCache(s, level, pos));
|
||||
}
|
||||
|
||||
public void clear() { blockCache.clear(); }
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
public ClientBlockStateCache getBlockStateData(BlockState blockState)
|
||||
{ return this.blockCache.computeIfAbsent(blockState, (block) -> new ClientBlockStateCache(block, this.level)); }
|
||||
|
||||
public int getColor(BlockState state, BiomeWrapper biome, DhBlockPos pos)
|
||||
{
|
||||
return getBlockStateData(state, pos).getAndResolveFaceColor(biome, pos);
|
||||
}
|
||||
{ return this.getBlockStateData(state).getAndResolveFaceColor(biome, pos); }
|
||||
|
||||
public void clear() { this.blockCache.clear(); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
+223
-168
@@ -50,7 +50,9 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @version 2022-9-16
|
||||
* This keeps track of the color each block state should be for a given level.
|
||||
*
|
||||
* @see ColorUtil
|
||||
*/
|
||||
public class ClientBlockStateCache
|
||||
{
|
||||
@@ -59,62 +61,42 @@ public class ClientBlockStateCache
|
||||
private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>();
|
||||
private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>();
|
||||
|
||||
/** This is the order each direction on a block is processed when attempting to get the texture/color */
|
||||
private static final Direction[] COLOR_RESOLUTION_DIRECTION_ORDER = { Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN };
|
||||
|
||||
private static final int FLOWER_COLOR_SCALE = 5;
|
||||
|
||||
|
||||
|
||||
#if MC_VER < MC_1_19_2
|
||||
public static final Random random = new Random(0);
|
||||
private static final Random random = new Random(0);
|
||||
#else
|
||||
public static final RandomSource random = RandomSource.create();
|
||||
private static final RandomSource random = RandomSource.create();
|
||||
#endif
|
||||
|
||||
public final IClientLevelWrapper levelWrapper;
|
||||
public final BlockState blockState;
|
||||
public final LevelReader level;
|
||||
public final BlockPos pos;
|
||||
private final IClientLevelWrapper levelWrapper;
|
||||
private final BlockState blockState;
|
||||
private final LevelReader level;
|
||||
|
||||
private boolean isColorResolved = false;
|
||||
private int baseColor = 0;
|
||||
private boolean needShade = true;
|
||||
private boolean needPostTinting = false;
|
||||
private int tintIndex = 0;
|
||||
|
||||
|
||||
|
||||
public ClientBlockStateCache(BlockState blockState, IClientLevelWrapper samplingLevel, DhBlockPos samplingPos)
|
||||
{
|
||||
this.blockState = blockState;
|
||||
this.levelWrapper = samplingLevel;
|
||||
this.level = (LevelReader) samplingLevel.getWrappedMcObject();
|
||||
this.pos = McObjectConverter.Convert(samplingPos);
|
||||
this.resolveColors();
|
||||
//LOGGER.info("ClientBlocKCache created for {}", blockState);
|
||||
}
|
||||
//===========//
|
||||
// constants //
|
||||
//===========//
|
||||
|
||||
boolean isColorResolved = false;
|
||||
int baseColor = 0; //TODO: Impl per-face color
|
||||
boolean needShade = true;
|
||||
boolean needPostTinting = false;
|
||||
int tintIndex = 0;
|
||||
private static final int MIN_SRGB_BITS = 0x39000000; // 2^(-13)
|
||||
private static final int MAX_SRGB_BITS = 0x3f7fffff; // 1.0 - f32::EPSILON
|
||||
private static final float MIN_SRGB_BOUND = Float.intBitsToFloat(MIN_SRGB_BITS);
|
||||
private static final float MAX_SRGB_BOUND = Float.intBitsToFloat(MAX_SRGB_BITS);
|
||||
|
||||
|
||||
public static final int FLOWER_COLOR_SCALE = 5;
|
||||
|
||||
enum ColorMode
|
||||
{
|
||||
Default,
|
||||
Flower,
|
||||
Leaves,
|
||||
Chisel,
|
||||
Glass;
|
||||
static ColorMode getColorMode(Block b)
|
||||
private static final int[] linearToSrgbTable = new int[]
|
||||
{
|
||||
if (b instanceof LeavesBlock) return Leaves;
|
||||
if (b instanceof FlowerBlock) return Flower;
|
||||
if (b.toString().contains("glass")) return Glass;
|
||||
if (b.toString().equals("Block{chiselsandbits:chiseled}")) return Chisel;
|
||||
return Default;
|
||||
}
|
||||
}
|
||||
|
||||
//Way to efficiently do this was suggested by IMS from sodium. This is where those numbers and support code was lifted from.
|
||||
private static final int MIN_BITS = 0x39000000; // 2^(-13)
|
||||
private static final int MAX_BITS = 0x3f7fffff; // 1.0 - f32::EPSILON
|
||||
private static final float MIN_BOUND = Float.intBitsToFloat(MIN_BITS);
|
||||
private static final float MAX_BOUND = Float.intBitsToFloat(MAX_BITS);
|
||||
|
||||
private static final int[] linearToSrgbTable = new int[] {
|
||||
0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d,
|
||||
0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a,
|
||||
0x010e0033, 0x01280033, 0x01410033, 0x015b0033, 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033,
|
||||
@@ -128,81 +110,131 @@ public class ClientBlockStateCache
|
||||
0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401,
|
||||
0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559,
|
||||
0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723,
|
||||
};
|
||||
};
|
||||
|
||||
private static final float[] srgbToLinearTable = new float[] {
|
||||
0.0f, 0.000303527f, 0.000607054f, 0.00091058103f, 0.001214108f, 0.001517635f, 0.0018211621f, 0.002124689f,
|
||||
0.002428216f, 0.002731743f, 0.00303527f, 0.0033465356f, 0.003676507f, 0.004024717f, 0.004391442f,
|
||||
0.0047769533f, 0.005181517f, 0.0056053917f, 0.0060488326f, 0.006512091f, 0.00699541f, 0.0074990317f,
|
||||
0.008023192f, 0.008568125f, 0.009134057f, 0.009721218f, 0.010329823f, 0.010960094f, 0.011612245f,
|
||||
0.012286487f, 0.012983031f, 0.013702081f, 0.014443844f, 0.015208514f, 0.015996292f, 0.016807375f,
|
||||
0.017641952f, 0.018500218f, 0.019382361f, 0.020288562f, 0.02121901f, 0.022173883f, 0.023153365f,
|
||||
0.02415763f, 0.025186857f, 0.026241222f, 0.027320892f, 0.028426038f, 0.029556843f, 0.03071345f, 0.03189604f,
|
||||
0.033104774f, 0.03433981f, 0.035601325f, 0.036889452f, 0.038204376f, 0.039546248f, 0.04091521f, 0.042311423f,
|
||||
0.043735042f, 0.045186214f, 0.046665095f, 0.048171833f, 0.049706575f, 0.051269468f, 0.052860655f, 0.05448028f,
|
||||
0.056128494f, 0.057805434f, 0.05951124f, 0.06124607f, 0.06301003f, 0.06480328f, 0.06662595f, 0.06847818f,
|
||||
0.07036011f, 0.07227186f, 0.07421358f, 0.07618539f, 0.07818743f, 0.08021983f, 0.082282715f, 0.084376216f,
|
||||
0.086500466f, 0.088655606f, 0.09084173f, 0.09305898f, 0.095307484f, 0.09758736f, 0.09989874f, 0.10224175f,
|
||||
0.10461649f, 0.10702311f, 0.10946172f, 0.111932434f, 0.11443538f, 0.116970696f, 0.11953845f, 0.12213881f,
|
||||
0.12477186f, 0.12743773f, 0.13013652f, 0.13286836f, 0.13563336f, 0.13843165f, 0.14126332f, 0.1441285f,
|
||||
0.1470273f, 0.14995982f, 0.15292618f, 0.1559265f, 0.15896086f, 0.16202943f, 0.16513224f, 0.16826946f,
|
||||
0.17144115f, 0.17464745f, 0.17788847f, 0.1811643f, 0.18447503f, 0.1878208f, 0.19120172f, 0.19461787f,
|
||||
0.19806935f, 0.2015563f, 0.20507877f, 0.2086369f, 0.21223079f, 0.21586053f, 0.21952623f, 0.22322798f,
|
||||
0.22696589f, 0.23074007f, 0.23455065f, 0.23839766f, 0.2422812f, 0.2462014f, 0.25015837f, 0.25415218f,
|
||||
0.2581829f, 0.26225072f, 0.26635566f, 0.27049786f, 0.27467737f, 0.27889434f, 0.2831488f, 0.2874409f,
|
||||
0.2917707f, 0.29613832f, 0.30054384f, 0.30498737f, 0.30946895f, 0.31398875f, 0.31854683f, 0.32314324f,
|
||||
0.32777813f, 0.33245158f, 0.33716366f, 0.34191445f, 0.3467041f, 0.3515327f, 0.35640025f, 0.36130688f,
|
||||
0.3662527f, 0.37123778f, 0.37626222f, 0.3813261f, 0.38642952f, 0.39157256f, 0.3967553f, 0.40197787f,
|
||||
0.4072403f, 0.4125427f, 0.41788515f, 0.42326775f, 0.42869055f, 0.4341537f, 0.43965724f, 0.44520125f,
|
||||
0.45078585f, 0.45641106f, 0.46207705f, 0.46778384f, 0.47353154f, 0.47932023f, 0.48514998f, 0.4910209f,
|
||||
0.49693304f, 0.5028866f, 0.50888145f, 0.5149178f, 0.5209957f, 0.52711535f, 0.5332766f, 0.5394797f,
|
||||
0.5457247f, 0.5520116f, 0.5583406f, 0.5647117f, 0.57112503f, 0.57758063f, 0.5840786f, 0.590619f, 0.597202f,
|
||||
0.60382754f, 0.61049575f, 0.61720675f, 0.62396055f, 0.63075733f, 0.637597f, 0.6444799f, 0.6514058f,
|
||||
0.65837497f, 0.66538745f, 0.67244333f, 0.6795426f, 0.68668544f, 0.69387203f, 0.70110214f, 0.70837605f,
|
||||
0.7156938f, 0.72305536f, 0.730461f, 0.7379107f, 0.7454045f, 0.75294244f, 0.76052475f, 0.7681514f, 0.77582246f,
|
||||
0.78353804f, 0.79129815f, 0.79910296f, 0.8069525f, 0.8148468f, 0.822786f, 0.8307701f, 0.83879924f, 0.84687346f,
|
||||
0.8549928f, 0.8631574f, 0.87136734f, 0.8796226f, 0.8879232f, 0.89626956f, 0.90466136f, 0.913099f, 0.92158204f,
|
||||
0.93011117f, 0.9386859f, 0.9473069f, 0.9559735f, 0.9646866f, 0.9734455f, 0.98225087f, 0.9911022f, 1.0f
|
||||
};
|
||||
|
||||
private static int linearToSrgb(float c) {
|
||||
if (!(c > MIN_BOUND)) {
|
||||
c = MIN_BOUND;
|
||||
}
|
||||
|
||||
if (c > MAX_BOUND) {
|
||||
c = MAX_BOUND;
|
||||
}
|
||||
int inputBits = Float.floatToRawIntBits(c);
|
||||
int entry = linearToSrgbTable[((inputBits - MIN_BITS) >> 20)];
|
||||
|
||||
int bias = (entry >>> 16) << 9;
|
||||
int scale = entry & 0xffff;
|
||||
int t = (inputBits >>> 12) & 0xff;
|
||||
|
||||
return (bias + (scale * t)) >>> 16;
|
||||
}
|
||||
//////////////
|
||||
private static final float[] srgbToLinearTable = new float[]
|
||||
{
|
||||
0.0f, 0.000303527f, 0.000607054f, 0.00091058103f, 0.001214108f, 0.001517635f, 0.0018211621f, 0.002124689f,
|
||||
0.002428216f, 0.002731743f, 0.00303527f, 0.0033465356f, 0.003676507f, 0.004024717f, 0.004391442f,
|
||||
0.0047769533f, 0.005181517f, 0.0056053917f, 0.0060488326f, 0.006512091f, 0.00699541f, 0.0074990317f,
|
||||
0.008023192f, 0.008568125f, 0.009134057f, 0.009721218f, 0.010329823f, 0.010960094f, 0.011612245f,
|
||||
0.012286487f, 0.012983031f, 0.013702081f, 0.014443844f, 0.015208514f, 0.015996292f, 0.016807375f,
|
||||
0.017641952f, 0.018500218f, 0.019382361f, 0.020288562f, 0.02121901f, 0.022173883f, 0.023153365f,
|
||||
0.02415763f, 0.025186857f, 0.026241222f, 0.027320892f, 0.028426038f, 0.029556843f, 0.03071345f, 0.03189604f,
|
||||
0.033104774f, 0.03433981f, 0.035601325f, 0.036889452f, 0.038204376f, 0.039546248f, 0.04091521f, 0.042311423f,
|
||||
0.043735042f, 0.045186214f, 0.046665095f, 0.048171833f, 0.049706575f, 0.051269468f, 0.052860655f, 0.05448028f,
|
||||
0.056128494f, 0.057805434f, 0.05951124f, 0.06124607f, 0.06301003f, 0.06480328f, 0.06662595f, 0.06847818f,
|
||||
0.07036011f, 0.07227186f, 0.07421358f, 0.07618539f, 0.07818743f, 0.08021983f, 0.082282715f, 0.084376216f,
|
||||
0.086500466f, 0.088655606f, 0.09084173f, 0.09305898f, 0.095307484f, 0.09758736f, 0.09989874f, 0.10224175f,
|
||||
0.10461649f, 0.10702311f, 0.10946172f, 0.111932434f, 0.11443538f, 0.116970696f, 0.11953845f, 0.12213881f,
|
||||
0.12477186f, 0.12743773f, 0.13013652f, 0.13286836f, 0.13563336f, 0.13843165f, 0.14126332f, 0.1441285f,
|
||||
0.1470273f, 0.14995982f, 0.15292618f, 0.1559265f, 0.15896086f, 0.16202943f, 0.16513224f, 0.16826946f,
|
||||
0.17144115f, 0.17464745f, 0.17788847f, 0.1811643f, 0.18447503f, 0.1878208f, 0.19120172f, 0.19461787f,
|
||||
0.19806935f, 0.2015563f, 0.20507877f, 0.2086369f, 0.21223079f, 0.21586053f, 0.21952623f, 0.22322798f,
|
||||
0.22696589f, 0.23074007f, 0.23455065f, 0.23839766f, 0.2422812f, 0.2462014f, 0.25015837f, 0.25415218f,
|
||||
0.2581829f, 0.26225072f, 0.26635566f, 0.27049786f, 0.27467737f, 0.27889434f, 0.2831488f, 0.2874409f,
|
||||
0.2917707f, 0.29613832f, 0.30054384f, 0.30498737f, 0.30946895f, 0.31398875f, 0.31854683f, 0.32314324f,
|
||||
0.32777813f, 0.33245158f, 0.33716366f, 0.34191445f, 0.3467041f, 0.3515327f, 0.35640025f, 0.36130688f,
|
||||
0.3662527f, 0.37123778f, 0.37626222f, 0.3813261f, 0.38642952f, 0.39157256f, 0.3967553f, 0.40197787f,
|
||||
0.4072403f, 0.4125427f, 0.41788515f, 0.42326775f, 0.42869055f, 0.4341537f, 0.43965724f, 0.44520125f,
|
||||
0.45078585f, 0.45641106f, 0.46207705f, 0.46778384f, 0.47353154f, 0.47932023f, 0.48514998f, 0.4910209f,
|
||||
0.49693304f, 0.5028866f, 0.50888145f, 0.5149178f, 0.5209957f, 0.52711535f, 0.5332766f, 0.5394797f,
|
||||
0.5457247f, 0.5520116f, 0.5583406f, 0.5647117f, 0.57112503f, 0.57758063f, 0.5840786f, 0.590619f, 0.597202f,
|
||||
0.60382754f, 0.61049575f, 0.61720675f, 0.62396055f, 0.63075733f, 0.637597f, 0.6444799f, 0.6514058f,
|
||||
0.65837497f, 0.66538745f, 0.67244333f, 0.6795426f, 0.68668544f, 0.69387203f, 0.70110214f, 0.70837605f,
|
||||
0.7156938f, 0.72305536f, 0.730461f, 0.7379107f, 0.7454045f, 0.75294244f, 0.76052475f, 0.7681514f, 0.77582246f,
|
||||
0.78353804f, 0.79129815f, 0.79910296f, 0.8069525f, 0.8148468f, 0.822786f, 0.8307701f, 0.83879924f, 0.84687346f,
|
||||
0.8549928f, 0.8631574f, 0.87136734f, 0.8796226f, 0.8879232f, 0.89626956f, 0.90466136f, 0.913099f, 0.92158204f,
|
||||
0.93011117f, 0.9386859f, 0.9473069f, 0.9559735f, 0.9646866f, 0.9734455f, 0.98225087f, 0.9911022f, 1.0f
|
||||
};
|
||||
|
||||
private static int getWidth(TextureAtlasSprite texture)
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public ClientBlockStateCache(BlockState blockState, IClientLevelWrapper samplingLevel)
|
||||
{
|
||||
#if MC_VER < MC_1_19_4
|
||||
return texture.getWidth();
|
||||
#else
|
||||
return texture.contents().width();
|
||||
#endif
|
||||
this.blockState = blockState;
|
||||
this.levelWrapper = samplingLevel;
|
||||
this.level = (LevelReader) samplingLevel.getWrappedMcObject();
|
||||
this.resolveColors();
|
||||
}
|
||||
|
||||
private static int getHeight(TextureAtlasSprite texture)
|
||||
|
||||
|
||||
//===================//
|
||||
// color calculation //
|
||||
//===================//
|
||||
|
||||
private void resolveColors()
|
||||
{
|
||||
#if MC_VER < MC_1_19_4
|
||||
return texture.getHeight();
|
||||
#else
|
||||
return texture.contents().height();
|
||||
#endif
|
||||
if (this.isColorResolved)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.blockState.getFluidState().isEmpty())
|
||||
{
|
||||
// look for the first non-empty direction
|
||||
List<BakedQuad> quads = null;
|
||||
for (Direction direction : COLOR_RESOLUTION_DIRECTION_ORDER)
|
||||
{
|
||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||
// TODO getQuads sometimes throws a "makeThreadingException", is there anything we can do about that?
|
||||
// Note: this isn't a critical issue, it just prints an ugly error and the render data will need to be regenerated.
|
||||
getBlockModel(this.blockState).getQuads(this.blockState, direction, random);
|
||||
|
||||
if (quads != null && !quads.isEmpty()
|
||||
&& !(
|
||||
this.blockState.getBlock() instanceof RotatedPillarBlock
|
||||
&& direction == Direction.UP
|
||||
)
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (quads == null || quads.isEmpty())
|
||||
{
|
||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||
getBlockModel(this.blockState).getQuads(this.blockState, null, random);
|
||||
}
|
||||
|
||||
if (quads != null && !quads.isEmpty())
|
||||
{
|
||||
this.needPostTinting = quads.get(0).isTinted();
|
||||
this.needShade = quads.get(0).isShade();
|
||||
this.tintIndex = quads.get(0).getTintIndex();
|
||||
this.baseColor = calculateColorFromTexture(
|
||||
#if MC_VER < MC_1_17_1 quads.get(0).sprite,
|
||||
#else quads.get(0).getSprite(), #endif
|
||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Backup method.
|
||||
this.needPostTinting = false;
|
||||
this.needShade = false;
|
||||
this.tintIndex = 0;
|
||||
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Liquid Block
|
||||
this.needPostTinting = true;
|
||||
this.needShade = false;
|
||||
this.tintIndex = 0;
|
||||
this.baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
|
||||
ColorMode.getColorMode(this.blockState.getBlock()));
|
||||
}
|
||||
|
||||
this.isColorResolved = true;
|
||||
}
|
||||
|
||||
|
||||
//TODO: Perhaps make this not just use the first frame?
|
||||
private static int calculateColorFromTexture(TextureAtlasSprite texture, ColorMode colorMode)
|
||||
{
|
||||
@@ -212,13 +244,15 @@ public class ClientBlockStateCache
|
||||
double green = 0;
|
||||
double blue = 0;
|
||||
int tempColor;
|
||||
//make Chiseled block not render. Since ColorMode is set per block, you only need to check it once
|
||||
|
||||
// don't render Chiseled blocks.
|
||||
// Since ColorMode is set per block, you only need to check this once.
|
||||
if (colorMode != ColorMode.Chisel)
|
||||
{
|
||||
// textures normally use u and v instead of x and y
|
||||
for (int v = 0; v < getHeight(texture); v++)
|
||||
for (int v = 0; v < getTextureHeight(texture); v++)
|
||||
{
|
||||
for (int u = 0; u < getWidth(texture); u++)
|
||||
for (int u = 0; u < getTextureWidth(texture); u++)
|
||||
{
|
||||
//note: Minecraft color format is: 0xAA BB GG RR
|
||||
//________ DH mod color format is: 0xAA RR GG BB
|
||||
@@ -270,8 +304,10 @@ public class ClientBlockStateCache
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
// this block is entirely transparent
|
||||
tempColor = ColorUtil.rgbToInt(0, 255, 255, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine the average color
|
||||
@@ -281,6 +317,7 @@ public class ClientBlockStateCache
|
||||
linearToSrgb((float) (green / (double) alpha)),
|
||||
linearToSrgb((float) (blue / (double) alpha)));
|
||||
}
|
||||
|
||||
//check if not missing texture
|
||||
if (tempColor == ColorUtil.rgbToInt(255, 182, 0, 182))
|
||||
{
|
||||
@@ -289,61 +326,53 @@ public class ClientBlockStateCache
|
||||
}
|
||||
return tempColor;
|
||||
}
|
||||
private static final Direction[] DIRECTION_ORDER = {Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN};
|
||||
|
||||
private void resolveColors()
|
||||
private static int getTextureWidth(TextureAtlasSprite texture)
|
||||
{
|
||||
if (isColorResolved) return;
|
||||
if (blockState.getFluidState().isEmpty())
|
||||
{
|
||||
List<BakedQuad> quads = null;
|
||||
for (Direction direction : DIRECTION_ORDER)
|
||||
{
|
||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||
getBlockModel(blockState).getQuads(blockState, direction, random); // TODO getQuads sometimes throws a "makeThreadingException", is there anything we can do about that? Note: this isn't a critical issue, it just prints an ugly error and the render data will need to be regenered.
|
||||
if (quads != null && !quads.isEmpty() &&
|
||||
!(blockState.getBlock() instanceof RotatedPillarBlock && direction == Direction.UP))
|
||||
break;
|
||||
} ;
|
||||
if (quads == null || quads.isEmpty())
|
||||
{
|
||||
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
|
||||
getBlockModel(blockState).getQuads(blockState, null, random);
|
||||
}
|
||||
if (quads != null && !quads.isEmpty())
|
||||
{
|
||||
needPostTinting = quads.get(0).isTinted();
|
||||
needShade = quads.get(0).isShade();
|
||||
tintIndex = quads.get(0).getTintIndex();
|
||||
baseColor = calculateColorFromTexture(
|
||||
#if MC_VER < MC_1_17_1 quads.get(0).sprite,
|
||||
#else quads.get(0).getSprite(), #endif
|
||||
ColorMode.getColorMode(blockState.getBlock()));
|
||||
}
|
||||
else
|
||||
{ // Backup method.
|
||||
needPostTinting = false;
|
||||
needShade = false;
|
||||
tintIndex = 0;
|
||||
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(blockState),
|
||||
ColorMode.getColorMode(blockState.getBlock()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Liquid Block
|
||||
needPostTinting = true;
|
||||
needShade = false;
|
||||
tintIndex = 0;
|
||||
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(blockState),
|
||||
ColorMode.getColorMode(blockState.getBlock()));
|
||||
}
|
||||
isColorResolved = true;
|
||||
#if MC_VER < MC_1_19_4
|
||||
return texture.getWidth();
|
||||
#else
|
||||
return texture.contents().width();
|
||||
#endif
|
||||
}
|
||||
private static int getTextureHeight(TextureAtlasSprite texture)
|
||||
{
|
||||
#if MC_VER < MC_1_19_4
|
||||
return texture.getHeight();
|
||||
#else
|
||||
return texture.contents().height();
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* This method was suggested by IMS from the Iris/Sodium team.
|
||||
* That's where the numbers and code are based.
|
||||
*/
|
||||
private static int linearToSrgb(float c)
|
||||
{
|
||||
if (!(c > MIN_SRGB_BOUND)) {
|
||||
c = MIN_SRGB_BOUND;
|
||||
}
|
||||
|
||||
if (c > MAX_SRGB_BOUND) {
|
||||
c = MAX_SRGB_BOUND;
|
||||
}
|
||||
int inputBits = Float.floatToRawIntBits(c);
|
||||
int entry = linearToSrgbTable[((inputBits - MIN_SRGB_BITS) >> 20)];
|
||||
|
||||
int bias = (entry >>> 16) << 9;
|
||||
int scale = entry & 0xffff;
|
||||
int t = (inputBits >>> 12) & 0xff;
|
||||
|
||||
return (bias + (scale * t)) >>> 16;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===============//
|
||||
// public getter //
|
||||
//===============//
|
||||
|
||||
public int getAndResolveFaceColor(BiomeWrapper biome, DhBlockPos pos)
|
||||
{
|
||||
// FIXME: impl per-face colors
|
||||
|
||||
// only get the tint if the block needs to be tinted
|
||||
if (!this.needPostTinting)
|
||||
{
|
||||
@@ -409,4 +438,30 @@ public class ClientBlockStateCache
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper classes //
|
||||
//================//
|
||||
|
||||
enum ColorMode
|
||||
{
|
||||
Default,
|
||||
Flower,
|
||||
Leaves,
|
||||
Chisel,
|
||||
Glass;
|
||||
|
||||
static ColorMode getColorMode(Block block)
|
||||
{
|
||||
if (block instanceof LeavesBlock) return Leaves;
|
||||
if (block instanceof FlowerBlock) return Flower;
|
||||
if (block.toString().contains("glass")) return Glass;
|
||||
if (block.toString().equals("Block{chiselsandbits:chiseled}")) return Chisel;
|
||||
return Default;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user