better handling of cube face culling when dealing with alphablended cube tiles

This commit is contained in:
Gered 2013-10-14 23:21:25 -04:00
parent 0d1fd9568f
commit ece9fa98e8

View file

@ -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;