Пример #1
0
    int CreateMarchingCube(Voxel v)
    {
        if (v == null)
        {
            return(0);
        }

        //allows us to track if the mesh is dirty and needs updating
        //needs to be above the early exit checks, otherwise cells
        //keep getting marked as dirty
        v.lastMeshedValue = v.value;

        //keep the meshing within the volume bounds
        if (v.xID >= divisions)
        {
            return(0);
        }
        if (v.yID >= divisions)
        {
            return(0);
        }
        if (v.zID >= divisions)
        {
            return(0);
        }
        if (v.xID < 0)
        {
            return(0);
        }
        if (v.yID < 0)
        {
            return(0);
        }
        if (v.zID < 0)
        {
            return(0);
        }

        Voxel v0 = v;

        //this conditions te input to the polygonize, and make sure all the neighbors have valid entries
        //if all input voxels are gauranteed to not be edge voxels, this may not be necessary.
        Voxel v1 = QueryVoxel(v.xID + 1, v.yID, v.zID);

        if (v1 == null)
        {
            voxelBuffer[1].value  = initialVoxelValue;
            voxelBuffer[1].anchor = v.anchor + new Vector3(v.size.x, 0, 0);
            v1 = voxelBuffer[1];
        }

        Voxel v2 = QueryVoxel(v.xID + 1, v.yID + 1, v.zID);

        if (v2 == null)
        {
            voxelBuffer[2].value  = initialVoxelValue;
            voxelBuffer[2].anchor = v.anchor + new Vector3(v.size.x, v.size.y, 0);
            v2 = voxelBuffer[2];
        }
        Voxel v3 = QueryVoxel(v.xID, v.yID + 1, v.zID);

        if (v3 == null)
        {
            voxelBuffer[3].value  = initialVoxelValue;
            voxelBuffer[3].anchor = v.anchor + new Vector3(0, v.size.y, 0);
            v3 = voxelBuffer[3];
        }
        Voxel v4 = QueryVoxel(v.xID, v.yID, v.zID + 1);

        if (v4 == null)
        {
            voxelBuffer[4].value  = initialVoxelValue;
            voxelBuffer[4].anchor = v.anchor + new Vector3(0, 0, v.size.z);
            v4 = voxelBuffer[4];
        }
        Voxel v5 = QueryVoxel(v.xID + 1, v.yID, v.zID + 1);

        if (v5 == null)
        {
            voxelBuffer[5].value  = initialVoxelValue;
            voxelBuffer[5].anchor = v.anchor + new Vector3(v.size.x, 0, v.size.z);
            v5 = voxelBuffer[5];
        }
        Voxel v6 = QueryVoxel(v.xID + 1, v.yID + 1, v.zID + 1);

        if (v6 == null)
        {
            voxelBuffer[6].value  = initialVoxelValue;
            voxelBuffer[6].anchor = v.anchor + new Vector3(v.size.x, v.size.y, v.size.z);
            v6 = voxelBuffer[6];
        }
        Voxel v7 = QueryVoxel(v.xID, v.yID + 1, v.zID + 1);

        if (v7 == null)
        {
            voxelBuffer[7].value  = initialVoxelValue;
            voxelBuffer[7].anchor = v.anchor + new Vector3(0, v.size.y, v.size.z);
            v7 = voxelBuffer[7];
        }

        int triangleStart    = triangles.Count;
        int createdTriangles = Polygonizer.Process(isolevel,
                                                   v0.value,
                                                   v1.value,
                                                   v2.value,
                                                   v3.value,
                                                   v4.value,
                                                   v5.value,
                                                   v6.value,
                                                   v7.value,
                                                   v0.anchor,
                                                   v1.anchor,
                                                   v2.anchor,
                                                   v3.anchor,
                                                   v4.anchor,
                                                   v5.anchor,
                                                   v6.anchor,
                                                   v7.anchor,
                                                   ref vertices, ref triangles);

        //compute per vertex normal
        int addedVertCount = 0;

        while (normals.Count < vertices.Count)
        {
            normals.Add(new Vector3(0, 1, 0));
            uvs.Add(new Vector2(-1, -1));
            addedVertCount++;
        }

        for (int i = triangleStart; i < triangles.Count; i += 3)
        {
            v.trianglesIndicies.Add(i);            //add it to each voxel this impacted?

            int     ia = triangles[i];
            int     ib = triangles[i + 1];
            int     ic = triangles[i + 2];
            Vector3 a  = vertices[ia];
            Vector3 b  = vertices[ib];
            Vector3 c  = vertices[ic];

            Vector3 n = Vector3.Cross(a - b, b - c).normalized;
            normals[ia] = n;
            normals[ib] = n;
            normals[ic] = n;

            CalculateUVs(ia, ib, ic);
        }

        //adjust per voxel normal

        return(createdTriangles);
    }
Пример #2
0
    /// <summary>
    /// For a given voxel, execute the polygonization algorithm to generate mesh vertices, triangles, normals, and UVs.
    /// </summary>
    /// <param name="v">The voxel to mesh.</param>
    /// <returns>Number of created triangles.</returns>
    private int Polygonize(Voxel v)
    {
        if (v == null)
        {
            return(0);
        }

        // allows us to track if the mesh is dirty and needs updating
        // needs to be above the early exit checks, otherwise voxels
        // keep getting marked as dirty
        v.lastMeshedValue = v.value;

        // keep the meshing within the volume bounds
        if (v.xID >= m_voxelResolution)
        {
            return(0);
        }
        if (v.yID >= m_voxelResolution)
        {
            return(0);
        }
        if (v.zID >= m_voxelResolution)
        {
            return(0);
        }
        if (v.xID < 0)
        {
            return(0);
        }
        if (v.yID < 0)
        {
            return(0);
        }
        if (v.zID < 0)
        {
            return(0);
        }

        Voxel v0 = v;

        // this conditions te input to the polygonize, and make sure all the neighbors have valid entries
        // if all input voxels are gauranteed to not be edge voxels, this may not be necessary.

        // OPIMTIZATION - voxel can store meshing neighbors, rather than query each
        // skip if they are null
        Voxel v1 = QueryVoxel(v.xID + 1, v.yID, v.zID);

        if (v1 == null)
        {
            return(0);
        }
        Voxel v2 = QueryVoxel(v.xID + 1, v.yID + 1, v.zID);

        if (v2 == null)
        {
            return(0);
        }
        Voxel v3 = QueryVoxel(v.xID, v.yID + 1, v.zID);

        if (v3 == null)
        {
            return(0);
        }
        Voxel v4 = QueryVoxel(v.xID, v.yID, v.zID + 1);

        if (v4 == null)
        {
            return(0);
        }
        Voxel v5 = QueryVoxel(v.xID + 1, v.yID, v.zID + 1);

        if (v5 == null)
        {
            return(0);
        }
        Voxel v6 = QueryVoxel(v.xID + 1, v.yID + 1, v.zID + 1);

        if (v6 == null)
        {
            return(0);
        }
        Voxel v7 = QueryVoxel(v.xID, v.yID + 1, v.zID + 1);

        if (v7 == null)
        {
            return(0);
        }

        int triangleStart    = m_triangles.Count;
        int createdTriangles = Polygonizer.Process(m_meshingIsolevel,
                                                   v0.value,
                                                   v1.value,
                                                   v2.value,
                                                   v3.value,
                                                   v4.value,
                                                   v5.value,
                                                   v6.value,
                                                   v7.value,
                                                   v0.anchor,
                                                   v1.anchor,
                                                   v2.anchor,
                                                   v3.anchor,
                                                   v4.anchor,
                                                   v5.anchor,
                                                   v6.anchor,
                                                   v7.anchor,
                                                   ref m_vertices,
                                                   ref m_triangles);

        // compute per vertex normal
        int addedVertCount = 0;

        while (m_normals.Count < m_vertices.Count)
        {
            m_normals.Add(new Vector3(0, 1, 0));
            m_uvs.Add(new Vector2(-1, -1));
            addedVertCount++;
        }

        for (int i = triangleStart; i < m_triangles.Count; i += 3)
        {
            v.trianglesIndicies.Add(i); // add it to each voxel this impacted?

            int     ia = m_triangles[i];
            int     ib = m_triangles[i + 1];
            int     ic = m_triangles[i + 2];
            Vector3 a  = m_vertices[ia];
            Vector3 b  = m_vertices[ib];
            Vector3 c  = m_vertices[ic];

            Vector3 n = Vector3.Cross(a - b, b - c).normalized;
            m_normals[ia] = n;
            m_normals[ib] = n;
            m_normals[ic] = n;

            CalculateUVs(ia, ib, ic);
        }

        // adjust per voxel normal
        return(createdTriangles);
    }