ForgePatch/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java

277 lines
8.5 KiB
Java

/*
* Minecraft Forge
* Copyright (c) 2016-2019.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.model.pipeline;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.ILightReader;
public class BlockInfo
{
private static final Direction[] SIDES = Direction.values();
private final BlockColors colors;
private ILightReader world;
private BlockState state;
private BlockPos blockPos;
private final boolean[][][] t = new boolean[3][3][3];
private final int[][][] s = new int[3][3][3];
private final int[][][] b = new int[3][3][3];
private final float[][][][] skyLight = new float[3][2][2][2];
private final float[][][][] blockLight = new float[3][2][2][2];
private final float[][][] ao = new float[3][3][3];
private final int[] packed = new int[7];
private boolean full;
private float shx = 0, shy = 0, shz = 0;
private int cachedTint = -1;
private int cachedMultiplier = -1;
public BlockInfo(BlockColors colors)
{
this.colors = colors;
}
public int getColorMultiplier(int tint)
{
if(cachedTint == tint) return cachedMultiplier;
cachedTint = tint;
cachedMultiplier = colors.getColor(state, world, blockPos, tint);
return cachedMultiplier;
}
public void updateShift()
{
Vec3d offset = state.getOffset(world, blockPos);
shx = (float) offset.x;
shy = (float) offset.y;
shz = (float) offset.z;
}
public void setWorld(ILightReader world)
{
this.world = world;
cachedTint = -1;
cachedMultiplier = -1;
}
public void setState(BlockState state)
{
this.state = state;
cachedTint = -1;
cachedMultiplier = -1;
}
public void setBlockPos(BlockPos blockPos)
{
this.blockPos = blockPos;
cachedTint = -1;
cachedMultiplier = -1;
shx = shy = shz = 0;
}
public void reset()
{
this.world = null;
this.state = null;
this.blockPos = null;
cachedTint = -1;
cachedMultiplier = -1;
shx = shy = shz = 0;
}
private float combine(int c, int s1, int s2, int s3, boolean t0, boolean t1, boolean t2, boolean t3)
{
if (c == 0 && !t0) c = Math.max(0, Math.max(s1, s2) - 1);
if (s1 == 0 && !t1) s1 = Math.max(0, c - 1);
if (s2 == 0 && !t2) s2 = Math.max(0, c - 1);
if (s3 == 0 && !t3) s3 = Math.max(0, Math.max(s1, s2) - 1);
return (float) (c + s1 + s2 + s3) * 0x20 / (4 * 0xFFFF);
}
public void updateLightMatrix()
{
for(int x = 0; x <= 2; x++)
{
for(int y = 0; y <= 2; y++)
{
for(int z = 0; z <= 2; z++)
{
BlockPos pos = blockPos.add(x - 1, y - 1, z - 1);
BlockState state = world.getBlockState(pos);
t[x][y][z] = state.getOpacity(world, pos) < 15;
int brightness = 0x00FF00FF; // FIXME: state.getPackedLightmapCoords(world, pos);
s[x][y][z] = (brightness >> 0x14) & 0xF;
b[x][y][z] = (brightness >> 0x04) & 0xF;
ao[x][y][z] = state.getAmbientOcclusionLightValue(world, pos);
}
}
}
for(Direction side : SIDES)
{
BlockPos pos = blockPos.offset(side);
BlockState state = world.getBlockState(pos);
BlockState thisStateShape = this.state.isSolid() && this.state.isTransparent() ? this.state : Blocks.AIR.getDefaultState();
BlockState otherStateShape = state.isSolid() && state.isTransparent() ? state : Blocks.AIR.getDefaultState();
if(state.getOpacity(world, blockPos) == 15 || VoxelShapes.faceShapeCovers(thisStateShape.getFaceOcclusionShape(world, blockPos, side), otherStateShape.getFaceOcclusionShape(world, pos, side.getOpposite())))
{
int x = side.getXOffset() + 1;
int y = side.getYOffset() + 1;
int z = side.getZOffset() + 1;
s[x][y][z] = Math.max(s[1][1][1] - 1, s[x][y][z]);
b[x][y][z] = Math.max(b[1][1][1] - 1, b[x][y][z]);
}
}
for(int x = 0; x < 2; x++)
{
for(int y = 0; y < 2; y++)
{
for(int z = 0; z < 2; z++)
{
int x1 = x * 2;
int y1 = y * 2;
int z1 = z * 2;
int sxyz = s[x1][y1][z1];
int bxyz = b[x1][y1][z1];
boolean txyz = t[x1][y1][z1];
int sxz = s[x1][1][z1], sxy = s[x1][y1][1], syz = s[1][y1][z1];
int bxz = b[x1][1][z1], bxy = b[x1][y1][1], byz = b[1][y1][z1];
boolean txz = t[x1][1][z1], txy = t[x1][y1][1], tyz = t[1][y1][z1];
int sx = s[x1][1][1], sy = s[1][y1][1], sz = s[1][1][z1];
int bx = b[x1][1][1], by = b[1][y1][1], bz = b[1][1][z1];
boolean tx = t[x1][1][1], ty = t[1][y1][1], tz = t[1][1][z1];
skyLight [0][x][y][z] = combine(sx, sxz, sxy, txz || txy ? sxyz : sx,
tx, txz, txy, txz || txy ? txyz : tx);
blockLight[0][x][y][z] = combine(bx, bxz, bxy, txz || txy ? bxyz : bx,
tx, txz, txy, txz || txy ? txyz : tx);
skyLight [1][x][y][z] = combine(sy, sxy, syz, txy || tyz ? sxyz : sy,
ty, txy, tyz, txy || tyz ? txyz : ty);
blockLight[1][x][y][z] = combine(by, bxy, byz, txy || tyz ? bxyz : by,
ty, txy, tyz, txy || tyz ? txyz : ty);
skyLight [2][x][y][z] = combine(sz, syz, sxz, tyz || txz ? sxyz : sz,
tz, tyz, txz, tyz || txz ? txyz : tz);
blockLight[2][x][y][z] = combine(bz, byz, bxz, tyz || txz ? bxyz : bz,
tz, tyz, txz, tyz || txz ? txyz : tz);
}
}
}
}
public void updateFlatLighting()
{
full = Block.isOpaque(state.getCollisionShape(world, blockPos));
packed[0] = 0x00FF00FF; // FIXME: state.getPackedLightmapCoords(world, blockPos);
for (Direction side : SIDES)
{
int i = side.ordinal() + 1;
packed[i] = 0x00FF00FF; // FIXME: state.getPackedLightmapCoords(world, blockPos.offset(side));
}
}
public ILightReader getWorld()
{
return world;
}
public BlockState getState()
{
return state;
}
public BlockPos getBlockPos()
{
return blockPos;
}
public boolean[][][] getTranslucent()
{
return t;
}
public float[][][][] getSkyLight()
{
return skyLight;
}
public float[][][][] getBlockLight()
{
return blockLight;
}
public float[][][] getAo()
{
return ao;
}
public int[] getPackedLight()
{
return packed;
}
public boolean isFullCube()
{
return full;
}
public float getShx()
{
return shx;
}
public float getShy()
{
return shy;
}
public float getShz()
{
return shz;
}
public int getCachedTint()
{
return cachedTint;
}
public int getCachedMultiplier()
{
return cachedMultiplier;
}
}