Пример #1
0
 /// <summary>
 /// Sets the density value at a given point, if it is inside the chunk.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="z"></param>
 /// <param name="value"></param>
 public void SetValueAtPoint(int x, int y, int z, float value)
 {
     if (0 <= x && x < VoxelUtilities.pointsPerAxis && 0 <= y && y < VoxelUtilities.pointsPerAxis && 0 <= z && z < VoxelUtilities.pointsPerAxis)
     {
         points[VoxelUtilities.GetIndex(x, y, z)] = Mathf.Clamp01(value);
     }
 }
Пример #2
0
 /// <summary>
 /// Adds to the density value at a given point, if it is inside the chunk.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="z"></param>
 /// <param name="amount"></param>
 public void AddValueAtPoint(int x, int y, int z, float amount)
 {
     if (0 <= x && x < VoxelUtilities.pointsPerAxis && 0 <= y && y < VoxelUtilities.pointsPerAxis && 0 <= z && z < VoxelUtilities.pointsPerAxis)
     {
         points[VoxelUtilities.GetIndex(x, y, z)] += amount;
     }
 }
Пример #3
0
 /// <summary>
 /// Returns the density value at a given point. If the point is outside the chunk,
 /// then we return 1 (i.e solid). TODO: Allow Chunks to retrieve values from neigh-
 /// bouring chunks.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="z"></param>
 /// <returns>Density value at the specified point.</returns>
 public float GetValueAtPoint(int x, int y, int z)
 {
     if (0 <= x && x < VoxelUtilities.pointsPerAxis && 0 <= y && y < VoxelUtilities.pointsPerAxis && 0 <= z && z < VoxelUtilities.pointsPerAxis)
     {
         return(points[VoxelUtilities.GetIndex(x, y, z)]);
     }
     else
     {
         return(1f);
     }
 }
Пример #4
0
 /// <summary>
 /// Generates the initial density values representing the terrain.
 /// </summary>
 void GetPoints()
 {
     points = new float[VoxelUtilities.pointsPerAxis * VoxelUtilities.pointsPerAxis * VoxelUtilities.pointsPerAxis];
     //for (int z = 6; z < pointsPerAxis - 6; z++)
     //{
     //    for (int y = 14; y < pointsPerAxis -1; y++)
     //    {
     //        for (int x = 6; x < pointsPerAxis - 6; x++)
     //        {
     //            points[z * pointsPerAxisSqr + y * pointsPerAxis + x] = y < pointsPerAxis - 3 ? 0 : 1f;
     //        }
     //    }
     //}
     points[VoxelUtilities.GetIndex(8, 14, 8)] = 1f;
 }
Пример #5
0
    /// <summary>
    /// Runs on a worker thread. This method applies the Marching Cubes algorithm to
    /// extract a surface at the specified ISO-value.
    /// </summary>
    /// <param name="isoValue"></param>
    /// <returns>Returns prepared MeshData.</returns>
    VoxelUtilities.MeshData GenerateChunk(float isoValue = 0.5f)
    {
        // If points have not been generated, or the points are to be reset,
        // then call the GetPoints method.
        if (!pointsHaveBeenGenerated)
        {
            GetPoints();
            pointsHaveBeenGenerated = true;
        }

        // A list to store the Triangles
        List <VoxelUtilities.Triangle> triangles = new List <VoxelUtilities.Triangle>();

        // March through the 3D density values grid.
        for (int z = 0; z < VoxelUtilities.chunkSize; z++)
        {
            for (int y = 0; y < VoxelUtilities.chunkSize; y++)
            {
                for (int x = 0; x < VoxelUtilities.chunkSize; x++)
                {
                    // Get the vertices and values at the 8 corners of the cube.
                    VoxelUtilities.CubeCorner[] cubeCorners =
                    {
                        VoxelUtilities.GetCubeCorner(x,     y,     z,     points),
                        VoxelUtilities.GetCubeCorner(x + 1, y,     z,     points),
                        VoxelUtilities.GetCubeCorner(x + 1, y,     z + 1, points),
                        VoxelUtilities.GetCubeCorner(x,     y,     z + 1, points),
                        VoxelUtilities.GetCubeCorner(x,     y + 1, z,     points),
                        VoxelUtilities.GetCubeCorner(x + 1, y + 1, z,     points),
                        VoxelUtilities.GetCubeCorner(x + 1, y + 1, z + 1, points),
                        VoxelUtilities.GetCubeCorner(x,     y + 1, z + 1, points)
                    };

                    // Calculate the configuration number (256 possibilities)
                    int configNumber = 0;
                    for (int i = 0; i < 8; i++)
                    {
                        if (cubeCorners[i].value > isoValue)
                        {
                            configNumber |= (int)Mathf.Pow(2, i);
                        }
                    }

                    // Add triangles according to the predefined triangulation for the specified configuration
                    for (int i = 0; VoxelUtilities.triangulation[configNumber][i] != -1; i += 3)
                    {
                        int a0 = VoxelUtilities.cornerIndexAFromEdge[VoxelUtilities.triangulation[configNumber][i]];
                        int b0 = VoxelUtilities.cornerIndexBFromEdge[VoxelUtilities.triangulation[configNumber][i]];

                        int a1 = VoxelUtilities.cornerIndexAFromEdge[VoxelUtilities.triangulation[configNumber][i + 1]];
                        int b1 = VoxelUtilities.cornerIndexBFromEdge[VoxelUtilities.triangulation[configNumber][i + 1]];

                        int a2 = VoxelUtilities.cornerIndexAFromEdge[VoxelUtilities.triangulation[configNumber][i + 2]];
                        int b2 = VoxelUtilities.cornerIndexBFromEdge[VoxelUtilities.triangulation[configNumber][i + 2]];

                        VoxelUtilities.Triangle tri;
                        tri.a     = VoxelUtilities.InterpolateVerts(cubeCorners[a0], cubeCorners[b0], isoValue);
                        tri.b     = VoxelUtilities.InterpolateVerts(cubeCorners[a1], cubeCorners[b1], isoValue);
                        tri.c     = VoxelUtilities.InterpolateVerts(cubeCorners[a2], cubeCorners[b2], isoValue);
                        tri.color = Color.white;
                        triangles.Add(tri);
                    }
                }
            }
        }

        // Prepare MeshData from the triangles List

        int triangleCount = triangles.Count;


        List <Vector3> vertices = new List <Vector3>();
        List <Color>   colors   = new List <Color>();

        int[] tris = new int[triangleCount * 3];

        ////Smooth shading
        //Dictionary<Vector3, int> vertexToIndex = new Dictionary<Vector3, int>();


        for (int i = 0; i < triangleCount; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                ////Smooth shading
                //Vector3 vertex = triangles[i][j];
                //Color color = triangles[i].color;
                //if (vertexToIndex.ContainsKey(vertex))
                //{
                //    tris[i * 3 + j] = vertexToIndex[vertex];
                //} else
                //{
                //    vertices.Add(vertex);
                //    colors.Add(color);
                //    int index = vertexToIndex.Count;
                //    vertexToIndex.Add(vertex, index);
                //    tris[i * 3 + j] = index;
                //}

                // Flat shading
                tris[i * 3 + j] = i * 3 + j;
                vertices.Add(triangles[i][j]);
                colors.Add(triangles[i].color);
            }
        }

        VoxelUtilities.MeshData meshData;
        meshData.vertices  = vertices.ToArray();
        meshData.colors    = colors.ToArray();
        meshData.triangles = tris;

        return(meshData);
    }