output[2] = (float) resultAmbientOcclusion;
PerformanceMonitor.endActivity();
}
private void generateBlockVertices(ChunkView view, ChunkMesh mesh, int x, int y, int z, Biome biome) {
Block block = view.getBlock(x, y, z);
// TODO: Needs review - too much hardcoded special cases and corner cases resulting from this.
ChunkVertexFlag vertexFlag = ChunkVertexFlag.NORMAL;
if (block.isWater()) {
vertexFlag = ChunkVertexFlag.WATER;
} else if (block.isLava()) {
vertexFlag = ChunkVertexFlag.LAVA;
} else if (block.isWaving() && block.isDoubleSided()) {
vertexFlag = ChunkVertexFlag.WAVING;
} else if (block.isWaving()) {
vertexFlag = ChunkVertexFlag.WAVING_BLOCK;
}
// Gather adjacent blocks
Map<Side, Block> adjacentBlocks = Maps.newEnumMap(Side.class);
for (Side side : Side.values()) {
Vector3i offset = side.getVector3i();
Block blockToCheck = view.getBlock(x + offset.x, y + offset.y, z + offset.z);
adjacentBlocks.put(side, blockToCheck);
}
BlockAppearance blockAppearance = block.getAppearance(adjacentBlocks);
/*
* Determine the render process.
*/
ChunkMesh.RenderType renderType = ChunkMesh.RenderType.TRANSLUCENT;
if (!block.isTranslucent()) {
renderType = ChunkMesh.RenderType.OPAQUE;
}
// TODO: Review special case, or alternatively compare uris.
if (block.isWater() || block.isIce()) {
renderType = ChunkMesh.RenderType.WATER_AND_ICE;
}
if (block.isDoubleSided()) {
renderType = ChunkMesh.RenderType.BILLBOARD;
}
if (blockAppearance.getPart(BlockPart.CENTER) != null) {
Vector4f colorOffset = block.calcColorOffsetFor(BlockPart.CENTER, biome);
blockAppearance.getPart(BlockPart.CENTER).appendTo(mesh, x, y, z, colorOffset, renderType, vertexFlag);
}
boolean[] drawDir = new boolean[6];
for (Side side : Side.values()) {
drawDir[side.ordinal()] = blockAppearance.getPart(BlockPart.fromSide(side)) != null && isSideVisibleForBlockTypes(adjacentBlocks.get(side), block, side);
}
// If the block is lowered, some more faces may have to be drawn
if (block.isLiquid()) {
Block bottomBlock = adjacentBlocks.get(Side.BOTTOM);
// Draw horizontal sides if visible from below
for (Side side : Side.horizontalSides()) {
Vector3i offset = side.getVector3i();
Block adjacentBelow = view.getBlock(x + offset.x, y - 1, z + offset.z);
Block adjacent = adjacentBlocks.get(side);
boolean visible = (blockAppearance.getPart(BlockPart.fromSide(side)) != null
&& isSideVisibleForBlockTypes(adjacentBelow, block, side) && !isSideVisibleForBlockTypes(bottomBlock, adjacent, side.reverse()));
drawDir[side.ordinal()] |= visible;
}
// Draw the top if below a non-lowered block
// TODO: Don't need to render the top if each side and the block above each side are either liquid or opaque solids.
Block blockToCheck = adjacentBlocks.get(Side.TOP);
drawDir[Side.TOP.ordinal()] |= !blockToCheck.isLiquid();
if (bottomBlock.isLiquid() || bottomBlock.isInvisible()) {
for (Side dir : Side.values()) {
if (drawDir[dir.ordinal()]) {
Vector4f colorOffset = block.calcColorOffsetFor(BlockPart.fromSide(dir), biome);