better handling of cube face culling when dealing with alphablended cube tiles
This commit is contained in:
parent
0d1fd9568f
commit
ece9fa98e8
|
@ -9,6 +9,7 @@ import com.badlogic.gdx.math.Vector3;
|
|||
import com.blarg.gdx.graphics.Vertices;
|
||||
import com.blarg.gdx.tilemap3d.tilemesh.CubeTileMesh;
|
||||
import com.blarg.gdx.tilemap3d.tilemesh.TileMesh;
|
||||
import com.blarg.gdx.tilemap3d.tilemesh.TileMeshCollection;
|
||||
|
||||
public class ChunkVertexGenerator {
|
||||
protected final MeshBuilder.VertexInfo vertex = new MeshPartBuilder.VertexInfo();
|
||||
|
@ -80,42 +81,42 @@ public class ChunkVertexGenerator {
|
|||
Tile up = chunk.getWithinSelfOrNeighbourSafe(x, y + 1, z);
|
||||
|
||||
// evaluate each face's visibility and add it's vertices if needed one at a time
|
||||
if ((left == null || left.tile == Tile.NO_TILE || !chunk.tileMap.tileMeshes.get(left).isOpaque(TileMesh.SIDE_RIGHT)) && mesh.hasFace(TileMesh.SIDE_LEFT)) {
|
||||
if (canRenderCubeFace(tile, mesh, left, TileMesh.SIDE_LEFT, TileMesh.SIDE_RIGHT, color, chunk.tileMap.tileMeshes)) {
|
||||
// left face is visible
|
||||
if (mesh.alpha)
|
||||
addMesh(alphaBuilder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.leftFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
else
|
||||
addMesh(builder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.leftFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
}
|
||||
if ((right == null || right.tile == Tile.NO_TILE || !chunk.tileMap.tileMeshes.get(right).isOpaque(TileMesh.SIDE_LEFT)) && mesh.hasFace(TileMesh.SIDE_RIGHT)) {
|
||||
if (canRenderCubeFace(tile, mesh, right, TileMesh.SIDE_RIGHT, TileMesh.SIDE_LEFT, color, chunk.tileMap.tileMeshes)) {
|
||||
// right face is visible
|
||||
if (mesh.alpha)
|
||||
addMesh(alphaBuilder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.rightFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
else
|
||||
addMesh(builder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.rightFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
}
|
||||
if ((forward == null || forward.tile == Tile.NO_TILE || !chunk.tileMap.tileMeshes.get(forward).isOpaque(TileMesh.SIDE_BACK)) && mesh.hasFace(TileMesh.SIDE_FRONT)) {
|
||||
if (canRenderCubeFace(tile, mesh, forward, TileMesh.SIDE_FRONT, TileMesh.SIDE_BACK, color, chunk.tileMap.tileMeshes)) {
|
||||
// front face is visible
|
||||
if (mesh.alpha)
|
||||
addMesh(alphaBuilder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.frontFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
else
|
||||
addMesh(builder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.frontFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
}
|
||||
if ((backward == null || backward.tile == Tile.NO_TILE || !chunk.tileMap.tileMeshes.get(backward).isOpaque(TileMesh.SIDE_FRONT)) && mesh.hasFace(TileMesh.SIDE_BACK)) {
|
||||
if (canRenderCubeFace(tile, mesh, backward, TileMesh.SIDE_BACK, TileMesh.SIDE_FRONT, color, chunk.tileMap.tileMeshes)) {
|
||||
// back face is visible
|
||||
if (mesh.alpha)
|
||||
addMesh(alphaBuilder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.backFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
else
|
||||
addMesh(builder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.backFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
}
|
||||
if ((down == null || down.tile == Tile.NO_TILE || !chunk.tileMap.tileMeshes.get(down).isOpaque(TileMesh.SIDE_TOP)) && mesh.hasFace(TileMesh.SIDE_BOTTOM)) {
|
||||
if (canRenderCubeFace(tile, mesh, down, TileMesh.SIDE_BOTTOM, TileMesh.SIDE_TOP, color, chunk.tileMap.tileMeshes)) {
|
||||
// bottom face is visible
|
||||
if (mesh.alpha)
|
||||
addMesh(alphaBuilder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.bottomFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
else
|
||||
addMesh(builder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.bottomFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
}
|
||||
if ((up == null || up.tile == Tile.NO_TILE || !chunk.tileMap.tileMeshes.get(up).isOpaque(TileMesh.SIDE_BOTTOM)) && mesh.hasFace(TileMesh.SIDE_TOP)) {
|
||||
if (canRenderCubeFace(tile, mesh, up, TileMesh.SIDE_TOP, TileMesh.SIDE_BOTTOM, color, chunk.tileMap.tileMeshes)) {
|
||||
// top face is visible
|
||||
if (mesh.alpha)
|
||||
addMesh(alphaBuilder, tile, mesh, chunk, tileMapPosition, transform, color, mesh.topFaceVertexOffset, TileMesh.CUBE_VERTICES_PER_FACE);
|
||||
|
@ -124,6 +125,26 @@ public class ChunkVertexGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean canRenderCubeFace(Tile currentTile, CubeTileMesh currentTileMesh, Tile adjacentTile, byte faceToCheck, byte adjacentFace, Color color, TileMeshCollection tileMeshes) {
|
||||
if (!currentTileMesh.hasFace(faceToCheck))
|
||||
return false;
|
||||
|
||||
if (adjacentTile == null || adjacentTile.tile == Tile.NO_TILE)
|
||||
return true;
|
||||
|
||||
TileMesh adjacentTileMesh = tileMeshes.get(adjacentTile);
|
||||
|
||||
// both cube faces that are facing each other are part of the same tile and that tile is alpha + blended
|
||||
// we should therefore not render this face as it tends to look a little weird in the rendered result (at best)
|
||||
if (currentTileMesh.alpha && adjacentTileMesh.alpha && currentTile.tile == adjacentTile.tile && color.a < 1.0f)
|
||||
return false;
|
||||
|
||||
if (!adjacentTileMesh.isOpaque(adjacentFace))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handleGenericMesh(int x, int y, int z, Tile tile, TileChunk chunk, TileMesh mesh, TileCoord tileMapPosition, Matrix4 transform, Color color) {
|
||||
boolean visible = false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue