/// <summary> /// Turns Voxel data into a VBO surface /// </summary> /// <param name="data">the voxels</param> /// <param name="size">how big it is in local frame</param> /// <returns>new int[] {vb, ib, cb}</returns> public static int[] March(Voxel[,,] data, float size, string name, out int indexCount) { var vertices = new List<Vertex>(); var indices = new List<uint>(); float t = -size / 2f; float xi = size / data.GetLength(0); float yi = size / data.GetLength(1); float zi = size / data.GetLength(2); Action<Vertex, Vertex, Vertex> makeTri = (v0, v1, v2) => { //var i = -1; //if ((i = vertices.FindIndex(v => Math.Abs(v.X - v0.X) < xi / 4f && Math.Abs(v.Y - v0.Y) < yi / 4f && Math.Abs(v.Z - v0.Z) < zi / 4f)) != -1) //{ // indices.Add((uint)i); // colors[i] = colors[i].Blend(c0); //} //else //{ indices.Add((uint) vertices.Count); vertices.Add(v0); //} //if ((i = vertices.FindIndex(v => Math.Abs(v.X - v1.X) < xi / 4f && Math.Abs(v.Y - v1.Y) < yi / 4f && Math.Abs(v.Z - v1.Z) < zi / 4f)) != -1) //{ // indices.Add((uint)i); // colors[i] = colors[i].Blend(c1); //} //else //{ indices.Add((uint) vertices.Count); vertices.Add(v1); //} //if ((i = vertices.FindIndex(v => Math.Abs(v.X - v2.X) < xi / 4f && Math.Abs(v.Y - v2.Y) < yi / 4f && Math.Abs(v.Z - v2.Z) < zi / 4f)) != -1) //{ // indices.Add((uint) i); // colors[i] = colors[i].Blend(c2); //} //else //{ indices.Add((uint) vertices.Count); vertices.Add(v2); //} }; for (int x = 0; x < data.GetLength(0) - 1; x++) { for (int y = 0; y < data.GetLength(1) - 1; y++) { for (int z = 0; z < data.GetLength(2) - 1; z++) { int state = (data[x, y, z].IsSolid() ? 1 : 0) | (data[x, y, z + 1].IsSolid() ? 1 : 0) << 1 | (data[x, y + 1, z].IsSolid() ? 1 : 0) << 2 | (data[x, y + 1, z + 1].IsSolid() ? 1 : 0) << 3 | (data[x + 1, y, z].IsSolid() ? 1 : 0) << 4 | (data[x + 1, y, z + 1].IsSolid() ? 1 : 0) << 5 | (data[x + 1, y + 1, z].IsSolid() ? 1 : 0) << 6 | (data[x + 1, y + 1, z + 1].IsSolid() ? 1 : 0) << 7; var tris = StateTriangles[state]; if (state == 0 || state == 255 || tris == null) continue; var cpos = new Vector3(t + x * xi + xi / 2f, t + y * yi + yi / 2f, t + z * zi + zi / 2f); var n = data[x, y, z].Normal; for (var i = 0; i < tris.Length; i++) { var tri = tris[i]; var v0 = new Vertex( new Vector3( StateVertices[tri[0]].X * xi, StateVertices[tri[0]].Y * yi, StateVertices[tri[0]].Z * zi) + cpos, n, new Vector2(0, 1)); var v1 = new Vertex( new Vector3( StateVertices[tri[1]].X * xi, StateVertices[tri[1]].Y * yi, StateVertices[tri[1]].Z * zi) + cpos, n, new Vector2(0, 0)); var v2 = new Vertex( new Vector3( StateVertices[tri[2]].X * xi, StateVertices[tri[2]].Y * yi, StateVertices[tri[2]].Z * zi) + cpos, n, new Vector2(1, 1)); makeTri(v0, v1, v2); } } } } var ids = new[] {0, 0, 0}; ids[0] = BufferLibrary.CreateVertexBuffer(name, vertices.ToArray()); ids[1] = BufferLibrary.CreateIndexBuffer(name, indices.ToArray(), PrimitiveType.Triangles); indexCount = indices.Count; return ids; }
public static Voxel[,,] GenerateChunk(Vector2i i) { var data = new float[ChunkSize.X + 1, ChunkHeight, ChunkSize.Y + 1]; var voxels = new Voxel[ChunkSize.X + 1, ChunkHeight, ChunkSize.Y + 1]; var ns = new Vector3d( NoiseStep * ChunkSize.X * i.X, 0, NoiseStep * ChunkSize.Y * i.Y ); // gen data for (int x = 0; x < data.GetLength(0); x++) { for (int y = 0; y < data.GetLength(1); y++) { for (int z = 0; z < data.GetLength(2); z++) { float density = -y / (float) ChunkHeight / 2f + 0.1f; density += Noise.Generate( (float) (NoiseLocation.X + ns.X + NoiseStep * x * 1), (float) (NoiseLocation.X + ns.Y + NoiseStep * y * 1), (float) (NoiseLocation.X + ns.Z + NoiseStep * z * 1)) / 4f; //density += Noise.Generate( // (float)(NoiseLocation.X + ns.X * 2 + NoiseStep * x * 2), // (float)(NoiseLocation.X + ns.Y * 2 + NoiseStep * y * 2), // (float)(NoiseLocation.X + ns.Z * 2 + NoiseStep * z * 2)) / 8f; //density += Noise.Generate( // (float)(NoiseLocation.X + ns.X * 4 + NoiseStep * x * 4), // (float)(NoiseLocation.X + ns.Y * 4 + NoiseStep * y * 4), // (float)(NoiseLocation.X + ns.Z * 4 + NoiseStep * z * 4)) / 16f; //density += Noise.Generate( // (float)(NoiseLocation.X + ns.X * 8 + NoiseStep * x * 8), // (float)(NoiseLocation.X + ns.Y * 8 + NoiseStep * y * 8), // (float)(NoiseLocation.X + ns.Z * 8 + NoiseStep * z * 8)) / 32f; data[x, y, z] = density; } } } // make voxels for (int x = 0; x < data.GetLength(0); x++) { for (int y = 0; y < data.GetLength(1); y++) { for (int z = 0; z < data.GetLength(2); z++) { float density = data[x, y, z]; Vector3 normal = new Vector3( ((x < data.GetLength(0) - 1 ? data[x + 1, y, z] : data[x, y, z]) + (x > 0 ? data[x - 1, y, z] : data[x, y, z])) / 2f, ((y < data.GetLength(0) - 1 ? data[x, y + 1, z] : data[x, y, z]) + (y > 0 ? data[x, y - 1, z] : data[x, y, z])) / 2f, ((z < data.GetLength(0) - 1 ? data[x, y, z + 1] : data[x, y, z]) + (z > 0 ? data[x, y, z - 1] : data[x, y, z])) / 2f ).Normalized(); if (y / (float) ChunkHeight < 0.2f) voxels[x, y, z] = new Voxel(1d, VoxelType.Blue, normal); else if (density < 0f) voxels[x, y, z] = new Voxel(density, VoxelType.None, normal); else voxels[x, y, z] = new Voxel(density, VoxelType.DarkGray, normal); } } } return voxels; }