public void RebuildMesh() { ChunkLightmap lightmap = _world.GetLightmap(_chunk.Key); var appearances = new System.Collections.Generic.Dictionary <BlockType, BlockAppearance>(); // air appearances.Add(BlockType.Empty, new BlockAppearance()); // stone BlockAppearance tmp = new BlockAppearance(); for (int i = 0; i < 6; i++) { tmp.UVRects[i] = _atlas.Rects[0]; tmp.Colors[i] = new Color(0.4f, 0.4f, 0.4f); } appearances.Add(new BlockType(2), tmp); // dirt tmp = new BlockAppearance(); for (int i = 0; i < 6; i++) { if (i != (int)BlockFace.Top) { tmp.UVRects[i] = _atlas.Rects[1]; } else { tmp.UVRects[i] = _atlas.Rects[3]; } } appearances.Add(new BlockType(1), tmp); // grass tmp = new BlockAppearance(); for (int i = 0; i < 6; i++) { tmp.UVRects[i] = _atlas.Rects[2]; } tmp.UVRects[(int)BlockFace.Top] = _atlas.Rects[4]; tmp.UVRects[(int)BlockFace.Bottom] = _atlas.Rects[1]; appearances.Add(new BlockType(3), tmp); Profiler.BeginSample("RebuildMesh"); for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { BlockType block = _chunk.GetBlock(x, y, z); if (block.isTransparent() == false && _chunk.IsBlockVisible(x, y, z)) { BlockAppearance appearance; if (!appearances.TryGetValue(block, out appearance)) { appearance = new BlockAppearance(); } CubeBuilder.buildCube(_meshBuilder, new Vector3i(x, y, z), _chunk, lightmap, appearance); } } } } _mesh.Clear(); _meshBuilder.BuildMesh(_mesh); _meshBuilder.Clear(); _dirty = false; Profiler.EndSample(); }
public static void buildCube(MeshBuilder mb, Vector3i pos, Chunk chunk, ChunkLightmap lightmap, BlockAppearance appearance) { // FIXME foo... Color brown = new Color(0.65f, 0.4f, 0.2f); //Color[] foo = {brown*0.8f, brown*0.8f, Color.green, brown*0.5f, brown, brown}; //Color[] foo = {brown, brown, Color.green, brown, brown, brown}; BlockType block = chunk.GetBlock(pos); for (int i = 0; i < 6; i++) { if (!chunk.IsBlockFaceVisible(pos, (BlockFace)i)) { continue; } Rect UVs = appearance.UVRects[i]; Color tint = appearance.Colors[i]; Vector3i normal = cubeNormals[i]; mb.UVs.Add(new Vector2(UVs.xMin, UVs.yMin)); mb.UVs.Add(new Vector2(UVs.xMax, UVs.yMin)); mb.UVs.Add(new Vector2(UVs.xMin, UVs.yMax)); mb.UVs.Add(new Vector2(UVs.xMax, UVs.yMax)); float[] ao = new float[4]; for (int v = 0; v < 4; v++) { Vector3i vertex = cubeVertices[cubeFaces[i, v]]; // for sake of simplicity, get diagonal light value too even though it could be blocked by the two adjacent blocks if (i == 0 || i == 1) { // x ao[v] = lightmap.GetLightValue(pos + new Vector3i(-1 + normal.x + 1, -1 + vertex.y, -1 + vertex.z)) + lightmap.GetLightValue(pos + new Vector3i(-1 + normal.x + 1, -1 + vertex.y + 1, -1 + vertex.z)) + lightmap.GetLightValue(pos + new Vector3i(-1 + normal.x + 1, -1 + vertex.y, -1 + vertex.z + 1)) + lightmap.GetLightValue(pos + new Vector3i(-1 + normal.x + 1, -1 + vertex.y + 1, -1 + vertex.z + 1)); } else if (i == 2 || i == 3) { // y ao[v] = lightmap.GetLightValue(pos + new Vector3i(-1 + vertex.x, -1 + normal.y + 1, -1 + vertex.z)) + lightmap.GetLightValue(pos + new Vector3i(-1 + vertex.x + 1, -1 + normal.y + 1, -1 + vertex.z)) + lightmap.GetLightValue(pos + new Vector3i(-1 + vertex.x, -1 + normal.y + 1, -1 + vertex.z + 1)) + lightmap.GetLightValue(pos + new Vector3i(-1 + vertex.x + 1, -1 + normal.y + 1, -1 + vertex.z + 1)); } else { // z ao[v] = lightmap.GetLightValue(pos + new Vector3i(-1 + vertex.x, -1 + vertex.y, -1 + normal.z + 1)) + lightmap.GetLightValue(pos + new Vector3i(-1 + vertex.x + 1, -1 + vertex.y, -1 + normal.z + 1)) + lightmap.GetLightValue(pos + new Vector3i(-1 + vertex.x, -1 + vertex.y + 1, -1 + normal.z + 1)) + lightmap.GetLightValue(pos + new Vector3i(-1 + vertex.x + 1, -1 + vertex.y + 1, -1 + normal.z + 1)); } vertex += pos; mb.Vertices.Add((Vector3)vertex); mb.Normals.Add((Vector3)normal); float aoFactor = Mathf.Clamp(ao[v], 0, 4); aoFactor /= 4; Color color = tint * aoFactor; mb.Colors32.Add(color); } // prefer the bright edge in the middle, suitable for outdoors but bad for drastic light level transitions into darkness if (ao[0] + ao[3] < ao[1] + ao[2]) { mb.AddTriangle(-2, -3, -4); mb.AddTriangle(-3, -2, -1); } else { mb.AddTriangle(-2, -1, -4); mb.AddTriangle(-1, -3, -4); } } }