private bool AddQuads(TempMesh mesh, int submesh, int side, int offset) { int x, y, w, h, o; for (int i = 0; i < used.Count; i++) { references[i] = false; } bool hasQuads = false; for (x = 0; x < 16; x++) { for (y = 0; y < 16; y++) { if (storage[x, y] == -1) { continue; } if (references[storage[x, y]]) { continue; } o = storage[x, y]; references[o] = true; for (w = x; w < 16; w++) { if (storage[w, y] != o) { break; } } for (h = y; h < 16; h++) { if (storage[x, h] != o) { break; } } w -= x; h -= y; AddSingleQuad(mesh, submesh, side, x, y, w, h, offset); hasQuads = true; } } return(hasQuads); }
private void RebuildMesh(TempMesh mesh, int submesh, int blockId) { int x, y, z, index, next; for (x = 0; x < 16; x++) { for (y = 0; y < 16; y++) { for (z = 0; z < 16; z++) { index = x * 16 * 16 + y * 16 + z; if (blocks[index] != blockId) { continue; } next = (x + 1) * 16 * 16 + y * 16 + z; if (x == 15 || blocks[next] == 0 || (blockStates[next] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0) { if (x == 15 || blocks[index] != blocks[next] || (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0) { AddSingleQuad(visualMesh, submesh, 0, y, z, 1, 1, x); } } next = (x - 1) * 16 * 16 + y * 16 + z; if (x == 0 || blocks[next] == 0 || (blockStates[next] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0) { if (x == 0 || blocks[index] != blocks[next] || (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0) { AddSingleQuad(visualMesh, submesh, 1, y, z, 1, 1, x); } } next = x * 16 * 16 + (y + 1) * 16 + z; if (y == 15 || blocks[next] == 0 || (blockStates[next] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0) { if (y == 15 || blocks[index] != blocks[next] || (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0) { AddSingleQuad(visualMesh, submesh, 2, x, z, 1, 1, y); } } next = x * 16 * 16 + (y - 1) * 16 + z; if (y == 0 || blocks[next] == 0 || (blockStates[next] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0) { if (y == 0 || blocks[index] != blocks[next] || (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0) { AddSingleQuad(visualMesh, submesh, 3, x, z, 1, 1, y); } } next = x * 16 * 16 + y * 16 + (z + 1); if (z == 15 || blocks[next] == 0 || (blockStates[next] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0) { if (z == 15 || blocks[index] != blocks[next] || (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0) { AddSingleQuad(visualMesh, submesh, 4, x, y, 1, 1, z); } } next = x * 16 * 16 + y * 16 + (z + 1); if (z == 0 || blocks[next] == 0 || (blockStates[next] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0) { if (z == 0 || blocks[index] != blocks[next] || (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0) { AddSingleQuad(visualMesh, submesh, 5, x, y, 1, 1, z); } } } } } }
private void AddSingleQuad(TempMesh mesh, int submesh, int j, int x, int y, int w, int h, int o) { LinkedList <int> triangles = mesh.GetTriangleList(submesh); LinkedList <Vector3> verts = mesh.GetVertices(); LinkedList <Vector2> uvs = mesh.GetUVs(); int vertexCount = verts.Count; triangles.AddLast(vertexCount + 0); triangles.AddLast(vertexCount + 1); triangles.AddLast(vertexCount + 2); triangles.AddLast(vertexCount + 0); triangles.AddLast(vertexCount + 2); triangles.AddLast(vertexCount + 3); if (j == 0) { float sx = o; float sy = x; float sz = y; float bx = sx + 1; float by = sy + w; float bz = sz + h; verts.AddLast(new Vector3(bx, by, bz)); verts.AddLast(new Vector3(bx, sy, bz)); verts.AddLast(new Vector3(bx, sy, sz)); verts.AddLast(new Vector3(bx, by, sz)); if (uvs != null) { uvs.AddLast(new Vector2(0, 0)); uvs.AddLast(new Vector2(0, w)); uvs.AddLast(new Vector2(h, w)); uvs.AddLast(new Vector2(h, 0)); } } else if (j == 1) { float sx = o; float sy = x; float sz = y; float by = sy + w; float bz = sz + h; verts.AddLast(new Vector3(sx, sy, sz)); verts.AddLast(new Vector3(sx, sy, bz)); verts.AddLast(new Vector3(sx, by, bz)); verts.AddLast(new Vector3(sx, by, sz)); if (uvs != null) { uvs.AddLast(new Vector2(h, w)); uvs.AddLast(new Vector2(0, w)); uvs.AddLast(new Vector2(0, 0)); uvs.AddLast(new Vector2(h, 0)); } } else if (j == 2) { float sx = x; float sy = o; float sz = y; float bx = sx + w; float by = sy + 1; float bz = sz + h; verts.AddLast(new Vector3(sx, by, sz)); verts.AddLast(new Vector3(sx, by, bz)); verts.AddLast(new Vector3(bx, by, bz)); verts.AddLast(new Vector3(bx, by, sz)); if (uvs != null) { uvs.AddLast(new Vector2(0, 0)); uvs.AddLast(new Vector2(0, h)); uvs.AddLast(new Vector2(w, h)); uvs.AddLast(new Vector2(w, 0)); } } else if (j == 3) { float sx = x; float sy = o; float sz = y; float bx = sx + w; float bz = sz + h; verts.AddLast(new Vector3(bx, sy, bz)); verts.AddLast(new Vector3(sx, sy, bz)); verts.AddLast(new Vector3(sx, sy, sz)); verts.AddLast(new Vector3(bx, sy, sz)); if (uvs != null) { uvs.AddLast(new Vector2(w, h)); uvs.AddLast(new Vector2(0, h)); uvs.AddLast(new Vector2(0, 0)); uvs.AddLast(new Vector2(w, 0)); } } else if (j == 4) { float sx = x; float sy = y; float sz = o; float bx = sx + w; float by = sy + h; float bz = sz + 1; verts.AddLast(new Vector3(bx, by, bz)); verts.AddLast(new Vector3(sx, by, bz)); verts.AddLast(new Vector3(sx, sy, bz)); verts.AddLast(new Vector3(bx, sy, bz)); if (uvs != null) { uvs.AddLast(new Vector2(0, 0)); uvs.AddLast(new Vector2(0, w)); uvs.AddLast(new Vector2(h, w)); uvs.AddLast(new Vector2(h, 0)); } } else { float sx = x; float sy = y; float sz = o; float bx = sx + w; float by = sy + h; verts.AddLast(new Vector3(sx, sy, sz)); verts.AddLast(new Vector3(sx, by, sz)); verts.AddLast(new Vector3(bx, by, sz)); verts.AddLast(new Vector3(bx, sy, sz)); if (uvs != null) { uvs.AddLast(new Vector2(0, 0)); uvs.AddLast(new Vector2(0, h)); uvs.AddLast(new Vector2(w, h)); uvs.AddLast(new Vector2(w, 0)); } } }
private bool RebuildMeshStrong(TempMesh mesh, int submeshIndex, ushort blockId) { int x, y, z, j; int index, next, end, chunkBegin; int nearbyOffset; bool hasQuads = false; for (j = 0; j < 6; j++) { nearbyOffset = j * 4096; end = j % 2 == 0 ? 15 : 0; if (j <= 1) { for (x = 0; x < 16; x++) { for (y = 0; y < 16; y++) { for (z = 0; z < 16; z++) { index = x * 16 * 16 + y * 16 + z; if (j == 0) { chunkBegin = 0 * 16 * 16 + y * 16 + z; next = (x + 1) * 16 * 16 + y * 16 + z; } else { chunkBegin = 15 * 16 * 16 + y * 16 + z; next = (x - 1) * 16 * 16 + y * 16 + z; } quads[y, z] = blocks[index] == blockId; quads[y, z] &= x == end || blocks[next] == 0 || (blockStates[next] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0; if (x != end && blocks[index] == blocks[next]) { quads[y, z] &= (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0; } if (x == end) { quads[y, z] &= nearbyBlocks[chunkBegin + nearbyOffset] == 0 || (nearbyBlockStates[chunkBegin + nearbyOffset] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0; if (blocks[index] == nearbyBlocks[chunkBegin + nearbyOffset]) { quads[y, z] &= (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0; } } } } if (GreedyMesher() == 0) { continue; } hasQuads |= AddQuads(mesh, submeshIndex, j, x); } } else if (j <= 3) { for (y = 0; y < 16; y++) { for (x = 0; x < 16; x++) { for (z = 0; z < 16; z++) { index = x * 16 * 16 + y * 16 + z; if (j == 2) { chunkBegin = x * 16 * 16 + 0 * 16 + z; next = x * 16 * 16 + (y + 1) * 16 + z; } else { chunkBegin = x * 16 * 16 + 15 * 16 + z; next = x * 16 * 16 + (y - 1) * 16 + z; } quads[x, z] = blocks[index] == blockId; quads[x, z] &= y == end || blocks[next] == 0 || (blockStates[next] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0; if (y != end && blocks[index] == blocks[next]) { quads[x, z] &= (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0; } if (y == end) { quads[x, z] &= nearbyBlocks[chunkBegin + nearbyOffset] == 0 || (nearbyBlockStates[chunkBegin + nearbyOffset] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0; if (blocks[index] == nearbyBlocks[chunkBegin + nearbyOffset]) { quads[x, z] &= (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0; } } } } if (GreedyMesher() == 0) { continue; } hasQuads |= AddQuads(mesh, submeshIndex, j, y); } } else { for (z = 0; z < 16; z++) { for (x = 0; x < 16; x++) { for (y = 0; y < 16; y++) { index = x * 16 * 16 + y * 16 + z; if (j == 4) { chunkBegin = x * 16 * 16 + y * 16 + 0; next = x * 16 * 16 + y * 16 + (z + 1); } else { chunkBegin = x * 16 * 16 + y * 16 + 15; next = x * 16 * 16 + y * 16 + (z - 1); } quads[x, y] = blocks[index] == blockId; quads[x, y] &= z == end || blocks[next] == 0 || (blockStates[next] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0; if (z != end && blocks[index] == blocks[next]) { quads[x, y] &= (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0; } if (z == end) { quads[x, y] &= nearbyBlocks[chunkBegin + nearbyOffset] == 0 || (nearbyBlockStates[chunkBegin + nearbyOffset] & MaterialBlock.BLOCK_STATE_TRANSPARENT) > 0; if (blocks[index] == nearbyBlocks[chunkBegin + nearbyOffset]) { quads[x, y] &= (blockStates[index] & MaterialBlock.BLOCK_STATE_VIEW_INSIDES) > 0; } } } } if (GreedyMesher() == 0) { continue; } hasQuads |= AddQuads(mesh, submeshIndex, j, z); } } } return(hasQuads); }