Esempio n. 1
0
    public Mesh ExtractMesh(IEnumerable <int> geom_ids)
    {
        /* Returns a single Mesh containing all geometry from the geom_ids (except the UV
         * coordinates).  The mesh consists of two submeshes: the triangles, and the stems.
         * We fill them with dummies if they are empty, to simplify the callers.
         */
        CallRegularUpdate();

        lock (geometries_lock)
        {
            var extractor = new MeshExtractor();
            extractor.vertices = new Vector3[mgos.Count][];
            extractor.normals  = new Vector3[mgos.Count][];

            foreach (var geom_id in geom_ids)
            {
                Geom geom  = geometries[geom_id];
                uint gmask = geom.gindex & GINDEX_MASK;
                if (gmask != GINDEX_FREE)
                {
                    int renderer_index = (int)(geom.gindex >> GINDEX_SHIFT);
                    var mgo            = mgos[renderer_index];
                    if (mgo != null)
                    {
                        mgo._ExtractMeshGeometry(extractor, geom, renderer_index);
                    }
                }
            }

            if (extractor.out_vertices.Count == 0)
            {
                extractor.out_vertices.Add(Vector3.zero);
                extractor.out_normals.Add(Vector3.zero);
            }
            if (extractor.out_triangles.Count == 0)
            {
                extractor.out_triangles.Add(0);
                extractor.out_triangles.Add(0);
                extractor.out_triangles.Add(0);
            }
            if (extractor.out_stems.Count == 0)
            {
                extractor.out_stems.Add(0);
                extractor.out_stems.Add(0);
            }

            var mesh = new Mesh();
            if (extractor.out_vertices.Count >= 0xFFE0)
            {
                mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            }
            mesh.SetVertices(extractor.out_vertices);
            mesh.SetNormals(extractor.out_normals);
            mesh.subMeshCount = 2;
            mesh.SetTriangles(extractor.out_triangles, 0, calculateBounds: false);
            mesh.SetIndices(extractor.out_stems.ToArray(), MeshTopology.Lines, 1, calculateBounds: false);
            mesh.RecalculateBounds();
            return(mesh);
        }
    }
Esempio n. 2
0
        internal void _ExtractMeshGeometry(MeshExtractor extractor, Geom geom, int renderer_index)
        {
            var vertices = extractor.vertices[renderer_index];

            if (vertices == null)
            {
                vertices = extractor.vertices[renderer_index] = mesh.vertices;
            }

            var normals = extractor.normals[renderer_index];

            if (normals == null)
            {
                normals = extractor.normals[renderer_index] = mesh.normals;
            }

            int tstart, tstop;

            tstart = geom.triangle_start * 3;
            tstop  = geom.triangle_stop * 3;
            if (tstop == 0xFFFF * 3)
            {
                tstop = all_triangles.Length;
            }

            int sstart, sstop;

            sstart = geom.stem_start * 2;
            sstop  = geom.stem_stop * 2;
            if (sstop == 0xFFFF * 2)
            {
                sstop = all_stems.Length;
            }

            /* xxx this assumes that each independent geom_id was built from its
             * own set of new vertices, without reusing any of the previous vertices;
             * otherwise, we're going to get large ranges in min,max and a lot of
             * duplication if we're extracting a mesh with many geom_ids */
            int min = 0x7fffffff, max = -1;

            for (int j = tstart; j < tstop; j++)
            {
                if (all_triangles[j] < min)
                {
                    min = all_triangles[j];
                }
                if (all_triangles[j] > max)
                {
                    max = all_triangles[j];
                }
            }
            for (int j = sstart; j < sstop; j++)
            {
                if (all_stems[j] < min)
                {
                    min = all_stems[j];
                }
                if (all_stems[j] > max)
                {
                    max = all_stems[j];
                }
            }

            int diff = extractor.out_vertices.Count - min;

            for (int i = min; i <= max; i++)
            {
                extractor.out_vertices.Add(vertices[i]);
                extractor.out_normals.Add(i < normals.Length ? normals[i] : Vector3.zero);
            }
            for (int j = tstart; j < tstop; j++)
            {
                extractor.out_triangles.Add(all_triangles[j] + diff);
            }
            for (int j = sstart; j < sstop; j++)
            {
                extractor.out_stems.Add(all_stems[j] + diff);
            }
        }