Caching of fluid models. Fixes #2145.

This commit is contained in:
RainWarrior committed 2015-12-30 13:31:36 +03:00
1 parent db3e039b31
commit 33b1f8f30f
1 file changed
+70 -11
@@ -29,6 +29,9 @@ import net.minecraftforge.fml.common.FMLLog;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -100,12 +103,28 @@ public class ModelFluid implements IModelCustomData
private static final int z[] = { 0, 1, 1, 0 };
private static final float eps = 1e-3f;
private final LoadingCache<Long, BakedFluid> modelCache = CacheBuilder.newBuilder().maximumSize(200).build(new CacheLoader<Long, BakedFluid>()
{
public BakedFluid load(Long key) throws Exception
{
boolean statePresent = (key & 1) != 0;
key >>>= 1;
int[] cornerRound = new int[4];
for(int i = 0; i < 4; i++)
{
cornerRound[i] = (int)(key & 0x3FF);
key >>>= 10;
}
int flowRound = (int)(key & 0x7FF) - 1024;
return new BakedFluid(transformation, format, color, still, flowing, gas, statePresent, cornerRound, flowRound);
}
});
private final Optional<TRSRTransformation> transformation;
private final VertexFormat format;
private final int color;
private final TextureAtlasSprite still, flowing;
private final boolean gas;
private final Optional<IExtendedBlockState> state;
private final EnumMap<EnumFacing, List<BakedQuad>> faceQuads;
public BakedFluid(Optional<TRSRTransformation> transformation, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, boolean gas)
@@ -114,6 +133,35 @@ public class ModelFluid implements IModelCustomData
}
public BakedFluid(Optional<TRSRTransformation> transformation, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, boolean gas, Optional<IExtendedBlockState> stateOption)
{
this(transformation, format, color, still, flowing, gas, stateOption.isPresent(), getCorners(stateOption), getFlow(stateOption));
}
private static int[] getCorners(Optional<IExtendedBlockState> stateOption)
{
int[] cornerRound = new int[]{0, 0, 0, 0};
if(stateOption.isPresent())
{
IExtendedBlockState state = stateOption.get();
for(int i = 0; i < 4; i++)
{
cornerRound[i] = Math.round(state.getValue(BlockFluidBase.LEVEL_CORNERS[i]) * 768);
}
}
return cornerRound;
}
private static int getFlow(Optional<IExtendedBlockState> stateOption)
{
int flowRound = -1000;
if(stateOption.isPresent())
{
flowRound = (int)Math.round(Math.toDegrees(stateOption.get().getValue(BlockFluidBase.FLOW_DIRECTION)));
}
return flowRound;
}
public BakedFluid(Optional<TRSRTransformation> transformation, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, boolean gas, boolean statePresent, int[] cornerRound, int flowRound)
{
this.transformation = transformation;
this.format = format;
@@ -121,7 +169,6 @@ public class ModelFluid implements IModelCustomData
this.still = still;
this.flowing = flowing;
this.gas = gas;
this.state = stateOption;
faceQuads = Maps.newEnumMap(EnumFacing.class);
for(EnumFacing side : EnumFacing.values())
@@ -129,23 +176,22 @@ public class ModelFluid implements IModelCustomData
faceQuads.put(side, ImmutableList.<BakedQuad>of());
}
if(state.isPresent())
if(statePresent)
{
IExtendedBlockState state = this.state.get();
float[] y = new float[4];
for(int i = 0; i < 4; i++)
{
if(gas)
{
y[i] = 1 - state.getValue(BlockFluidBase.LEVEL_CORNERS[i]);
y[i] = 1 - cornerRound[i] / 768f;
}
else
{
y[i] = state.getValue(BlockFluidBase.LEVEL_CORNERS[i]);
y[i] = cornerRound[i] / 768f;
}
}
float flow = state.getValue(BlockFluidBase.FLOW_DIRECTION);
float flow = (float)Math.toRadians(flowRound);
// top
@@ -222,7 +268,6 @@ public class ModelFluid implements IModelCustomData
else
{
// 1 quad for inventory
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
builder.setQuadOrientation(EnumFacing.UP);
builder.setQuadColored();
@@ -242,7 +287,6 @@ public class ModelFluid implements IModelCustomData
{
for(int e = 0; e < format.getElementCount(); e++)
{
// TODO transformation
switch(format.getElement(e).getUsage())
{
case POSITION:
@@ -280,7 +324,7 @@ public class ModelFluid implements IModelCustomData
public boolean isAmbientOcclusion()
{
return false; // FIXME
return false;
}
public boolean isGui3d()
@@ -320,7 +364,22 @@ public class ModelFluid implements IModelCustomData
public IBakedModel handleBlockState(IBlockState state)
{
return new BakedFluid(transformation, format, color, still, flowing, gas, Optional.of((IExtendedBlockState)state));
if(state instanceof IExtendedBlockState)
{
IExtendedBlockState exState = (IExtendedBlockState)state;
int[] cornerRound = getCorners(Optional.of(exState));
int flowRound = getFlow(Optional.of(exState));
long key = flowRound + 1024;
for(int i = 3; i >= 0; i--)
{
key <<= 10;
key |= cornerRound[i];
}
key <<= 1;
key |= 1;
return modelCache.getUnchecked(key);
}
return this;
}
}