Example #1
0
        public static List <Mesh> ConvertTerrain2Mesh(Terrain terrain, IndexFormat format, int splitCount = 0, int lod = 0)
        {
            var terrainData = terrain.terrainData;
            var width       = GetTerrainResolution(terrainData, format, lod, splitCount);
            var height      = width;
            var size        = terrainData.size;

            var tileGridNum = (int)Mathf.Pow(2, splitCount);
            var maxWidth    = (width - 1) * tileGridNum + 1;
            var maxHeight   = maxWidth;
            var meshScale   = new Vector3(size.x / (width - 1) / tileGridNum, 1, size.z / (height - 1) / tileGridNum);

            // The function returns a two-dimensional array of size [yCount, xCount]
            var heights = terrainData.GetInterpolatedHeights(0, 0, maxWidth, maxHeight, 1f / (maxWidth - 1), 1f / (maxHeight - 1));

            var meshes = new List <Mesh>(tileGridNum * tileGridNum);

            for (int chunkI = 0; chunkI < tileGridNum; chunkI++)
            {
                for (int chunkJ = 0; chunkJ < tileGridNum; chunkJ++)
                {
                    var meshData = new QuadMeshData(width, height);

                    // 左下角开始,从下往上,从左往右添加顶点
                    for (int i = 0; i < width; i++)
                    {
                        for (int j = 0; j < height; j++)
                        {
                            // 共用一条边
                            var widthIndex  = chunkI * (width - 1) + i;
                            var heightIndex = chunkJ * (height - 1) + j;
                            // meshData.AddVertex(i, j, heights[heightIndex, widthIndex], meshScale);
                            meshData.AddVertex(i, j, heights[heightIndex, widthIndex], meshScale, new Vector2(widthIndex / (maxWidth - 1f), heightIndex / (maxHeight - 1f)));
                        }
                    }

                    // 正方形顺序随顶点顺序,三角形顺时针方向为模型的正面
                    for (int i = 0; i < width - 1; i++)
                    {
                        for (int j = 0; j < height - 1; j++)
                        {
                            var a = i + j * width;
                            var b = i + (j + 1) * width;
                            var c = (i + 1) + (j + 1) * width;
                            var d = (i + 1) + j * width;

                            meshData.AddTriangle(a, b, c);
                            meshData.AddTriangle(a, c, d);
                        }
                    }

                    meshes.Add(meshData.CreateMesh(format));
                }
            }

            return(meshes);
        }
Example #2
0
    public QuadMeshData Parse(TextAsset OBJFile)
    {
        lines      = OBJFile.text.Split('\n');
        currLine   = 0;
        parsedData = new QuadMeshData();

        string[] line;
        while ((line = getNextLine()) != null)
        {
            // Parse vertex position
            if (line[KEYWORD] == "v")
            {
                var vertex = new Vector3(float.Parse(line[X], CultureInfo.InvariantCulture),
                                         float.Parse(line[Y], CultureInfo.InvariantCulture),
                                         float.Parse(line[Z], CultureInfo.InvariantCulture));
                parsedData.vertices.Add(vertex);
            }
            // Parse face vertex indices
            else if (line[KEYWORD] == "f")
            {
                int     vertexIndex;
                string  vertexIndexString;
                Vector4 quad = new Vector4();
                for (int i = 1; i <= 4; i++)
                {
                    vertexIndexString = line[i];
                    if (vertexIndexString.Contains("//"))
                    {
                        vertexIndexString = vertexIndexString.Split(new string[] { "//" }, StringSplitOptions.None)[0];
                    }

                    // Remove 1 from index, in OBJ format indices start at 1 and not 0
                    vertexIndex = int.Parse(vertexIndexString, CultureInfo.InvariantCulture) - 1;
                    quad[i - 1] = vertexIndex;
                    if (vertexIndex > parsedData.vertices.Count)
                    {
                        PrintError("Vertex index out of bounds");
                    }
                }
                parsedData.quads.Add(quad);
            }
            // Ignore comments and other OBJ data
            else
            {
                // continue
            }
        }
        Debug.Log("Finished Parsing OBJ with " + parsedData.vertices.Count + " vertices " + (parsedData.quads.Count / 4) + " quads");
        return(parsedData);
    }
    // Returns a QuadMeshData representing the input mesh after one iteration of Catmull-Clark subdivision.
    public static QuadMeshData Subdivide(QuadMeshData quadMeshData)
    {
        // Create and initialize a CCMeshData corresponding to the given QuadMeshData
        CCMeshData meshData = new CCMeshData();

        meshData.points     = quadMeshData.vertices;
        meshData.faces      = quadMeshData.quads;
        meshData.edges      = GetEdges(meshData);
        meshData.facePoints = GetFacePoints(meshData);
        meshData.edgePoints = GetEdgePoints(meshData);
        meshData.newPoints  = GetNewPoints(meshData);

        // Combine facePoints, edgePoints and newPoints into a subdivided QuadMeshData
        return(CreateNewQuadMeshData(meshData));
    }
Example #4
0
    // Returns a QuadMeshData representing the input mesh after one iteration of Catmull-Clark subdivision.
    public static QuadMeshData Subdivide(QuadMeshData quadMeshData)
    {
        // Create and initialize a CCMeshData corresponding to the given QuadMeshData
        CCMeshData meshData = new CCMeshData();

        meshData.points     = quadMeshData.vertices;
        meshData.faces      = quadMeshData.quads;
        meshData.edges      = GetEdges(meshData);
        meshData.facePoints = GetFacePoints(meshData);
        meshData.edgePoints = GetEdgePoints(meshData);
        meshData.newPoints  = GetNewPoints(meshData);



        // Combine facePoints, edgePoints and newPoints into a subdivided QuadMeshData

        // Your implementation here...


        var quads     = new List <Vector4>();
        var vertices  = new List <Vector3>();
        var vertToIdx = getPointDict(meshData, vertices);
        var t         = edges_dict(meshData);

        for (int i = 0; i < meshData.facePoints.Count; i++)
        {
            var fp     = vertToIdx[meshData.facePoints[i]];
            var points = meshData.faces[i];

            for (int p = 0; p < 4; p++)
            {
                var np                 = vertToIdx[meshData.newPoints[(int)points[p]]];
                var next_point         = (int)points[(p + 1) % 4];
                var original_point_cur = (int)points[p];
                var key1               = new Vector2(i, original_point_cur);
                var key2               = new Vector2(i, next_point);
                var cur_original_edges = t[key1];
                var next_edges         = t[key2];
                int right              = 0;
                for (int idx1 = 0; idx1 < cur_original_edges.Count; idx1++)
                {
                    for (int idx2 = 0; idx2 < next_edges.Count; idx2++)
                    {
                        if (cur_original_edges[idx1] == next_edges[idx2])
                        {
                            right = idx1;
                            break;
                        }
                    }
                }

                var quad = new Vector4(fp, vertToIdx[meshData.edgePoints[(int)cur_original_edges[(right + 1) % 2]]], np,
                                       vertToIdx[meshData.edgePoints[(int)cur_original_edges[right % 2]]]);

                quads.Add(quad);
            }
        }


        return(new QuadMeshData(vertices, quads));
    }
Example #5
0
    // Returns a QuadMeshData representing the input mesh after one iteration of Catmull-Clark subdivision.
    public static QuadMeshData Subdivide(QuadMeshData quadMeshData)
    {
        // Create and initialize a CCMeshData corresponding to the given QuadMeshData
        CCMeshData meshData = new CCMeshData();

        meshData.points     = quadMeshData.vertices;
        meshData.faces      = quadMeshData.quads;
        meshData.edges      = GetEdges(meshData);
        meshData.facePoints = GetFacePoints(meshData);
        meshData.edgePoints = GetEdgePoints(meshData);
        meshData.newPoints  = GetNewPoints(meshData);
        List <List <int> > faceEdges = new List <List <int> >();

        for (int i = 0; i < meshData.faces.Count; ++i)
        {
            faceEdges.Add(new List <int>());
        }

        for (int i = 0; i < meshData.edges.Count; ++i)
        {
            faceEdges[(int)meshData.edges[i][2]].Add(i);
            faceEdges[(int)meshData.edges[i][3]].Add(i);
        }
        List <List <Vector2> > faceEdgePoints = new List <List <Vector2> >();

        for (int i = 0; i < faceEdges.Count; ++i)
        {
            faceEdgePoints.Add(new List <Vector2>());
            for (int j = 0; j < 4; ++j)
            {
                if (i == meshData.edges[faceEdges[i][j]][2])
                {
                    faceEdgePoints[i].Add(new Vector2(meshData.edges[faceEdges[i][j]][0], meshData.edges[faceEdges[i][j]][1]));
                }
                else
                {
                    faceEdgePoints[i].Add(new Vector2(meshData.edges[faceEdges[i][j]][1], meshData.edges[faceEdges[i][j]][0]));
                }
            }
        }
        List <Vector3> newPoints      = meshData.facePoints.Concat(meshData.edgePoints).Concat(meshData.newPoints).ToList();
        int            edgePointStart = meshData.facePoints.Count;
        int            newPointStart  = edgePointStart + meshData.edgePoints.Count;
        List <Vector4> newFaces       = new List <Vector4>();

        for (int i = 0; i < faceEdges.Count; ++i)
        {
            for (int j = 0; j < 3; ++j)
            {
                for (int k = j + 1; k < 4; ++k)
                {
                    if (faceEdgePoints[i][j][0] == faceEdgePoints[i][k][1])
                    {
                        newFaces.Add(new Vector4(i, faceEdges[i][k] + edgePointStart, faceEdgePoints[i][j][0] + newPointStart, faceEdges[i][j] + edgePointStart));
                    }
                    else if (faceEdgePoints[i][j][1] == faceEdgePoints[i][k][0])
                    {
                        newFaces.Add(new Vector4(i, faceEdges[i][j] + edgePointStart, faceEdgePoints[i][j][1] + newPointStart, faceEdges[i][k] + edgePointStart));
                    }
                }
            }
        }
        return(new QuadMeshData(newPoints, newFaces));
    }
 public void Subdivide()
 {
     meshData        = CatmullClark.Subdivide(meshData);
     meshFilter.mesh = meshData.ToUnityMesh();
 }
 // Loads a given OBJ file, calculates its surface normals and displays it
 public void ShowMesh()
 {
     meshData        = parser.Parse(QuadOBJFile);
     meshFilter.mesh = meshData.ToUnityMesh();
 }