Ejemplo n.º 1
0
        /// <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;
        }
Ejemplo n.º 2
0
        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;
        }