Esempio n. 1
0
        public static SimpleMesh UnityMeshToSimpleMesh(UnityEngine.Mesh mesh, bool bSwapLeftright)
        {
            SimpleMesh smesh = new SimpleMesh();

            Vector3[] vertices = mesh.vertices;
            Vector3[] normals  = mesh.normals;
            Color32[] colors32 = mesh.colors32;
            Color[]   colors   = mesh.colors;
            Vector2[] uv       = mesh.uv;

            bool bNormals    = (normals.Length == mesh.vertexCount);
            bool bColors     = (colors.Length == mesh.vertexCount || colors32.Length == mesh.vertexCount);
            bool bByteColors = (colors32.Length == mesh.vertexCount);
            bool bUVs        = (uv.Length == mesh.vertexCount);

            smesh.Initialize(bNormals, bColors, bUVs, false);


            for (int i = 0; i < mesh.vertexCount; ++i)
            {
                Vector3d v = vertices[i];
                if (bSwapLeftright)
                {
                    v.x = -v.x;
                    v.z = -v.z;
                }
                NewVertexInfo vInfo = new NewVertexInfo(v);
                if (bNormals)
                {
                    vInfo.bHaveN = true;
                    vInfo.n      = normals[i];
                    if (bSwapLeftright)
                    {
                        vInfo.n.x = -vInfo.n.x;
                        vInfo.n.z = -vInfo.n.z;
                    }
                }
                if (bColors)
                {
                    vInfo.bHaveC = true;
                    if (bByteColors)
                    {
                        vInfo.c = new Colorf(colors32[i].r, colors32[i].g, colors32[i].b, 255);
                    }
                    else
                    {
                        vInfo.c = colors[i];
                    }
                }
                if (bUVs)
                {
                    vInfo.bHaveUV = true;
                    vInfo.uv      = uv[i];
                }

                int vid = smesh.AppendVertex(vInfo);
                if (vid != i)
                {
                    throw new InvalidOperationException("UnityUtil.UnityMeshToSimpleMesh: indices weirdness...");
                }
            }

            int[] triangles = mesh.triangles;
            for (int i = 0; i < triangles.Length / 3; ++i)
            {
                smesh.AppendTriangle(triangles[3 * i], triangles[3 * i + 1], triangles[3 * i + 2]);
            }

            return(smesh);
        }
        /// <summary>
        /// If go has a MeshFilter, extract it and append to SimpleMesh.
        /// Returns false if no filter.
        /// </summary>
        bool AppendGOMesh(GameObject go, SimpleMesh m, int[] vertexMap, FScene scene, int gid)
        {
            MeshFilter filter = go.GetComponent <MeshFilter>();

            if (filter == null || filter.mesh == null)
            {
                return(false);
            }

            Mesh curMesh = filter.sharedMesh;

            Vector3[] vertices = curMesh.vertices;
            Vector3[] normals  = (WriteNormals) ? curMesh.normals : null;
            Color[]   colors   = (WriteVertexColors) ? curMesh.colors : null;
            Vector2[] uvs      = (WriteUVs) ? curMesh.uv : null;

            if (vertexMap.Length < curMesh.vertexCount)
            {
                vertexMap = new int[curMesh.vertexCount * 2];
            }

            for (int i = 0; i < curMesh.vertexCount; ++i)
            {
                NewVertexInfo vi = new NewVertexInfo();
                vi.bHaveN = WriteNormals; vi.bHaveC = WriteVertexColors; vi.bHaveUV = WriteUVs;

                Vector3f v = vertices[i];
                // local to world
                v = filter.gameObject.transform.TransformPoint(v);
                // world back to scene
                v    = scene.ToSceneP(v);
                vi.v = UnityUtil.SwapLeftRight(v);

                if (WriteNormals)
                {
                    Vector3 n = normals[i];
                    n    = filter.gameObject.transform.TransformDirection(n); // to world
                    n    = scene.ToSceneN(n);                                 // to scene
                    vi.n = UnityUtil.SwapLeftRight(n);
                }
                if (WriteVertexColors)
                {
                    vi.c = colors[i];
                }
                if (WriteUVs)
                {
                    vi.uv = uvs[i];
                }

                vertexMap[i] = m.AppendVertex(vi);
            }

            int[] triangles  = curMesh.triangles;
            int   nTriangles = triangles.Length / 3;

            for (int i = 0; i < nTriangles; ++i)
            {
                int a = vertexMap[triangles[3 * i]];
                int b = vertexMap[triangles[3 * i + 1]];
                int c = vertexMap[triangles[3 * i + 2]];
                m.AppendTriangle(a, c, b, gid);  // TRI ORIENTATION IS REVERSED HERE!!
            }

            return(true);
        }
        public ExportStatus Export(FScene s, string filename)
        {
            List <WriteMesh> vMeshes = new List <WriteMesh>();

            if (WriteFaceGroups)
            {
                throw new Exception("SceneMeshExporter.Export: writing face groups has not yet been implemented!");
            }

            foreach (SceneObject so in s.SceneObjects)
            {
                if (so.IsTemporary)
                {
                    continue;
                }

                SimpleMesh m = new SimpleMesh();
                m.Initialize(WriteNormals, WriteVertexColors, WriteUVs, WriteFaceGroups);
                int groupCounter = 1;

                GameObject rootgo = so.RootGameObject;

                int[] vertexMap = new int[2048];
                foreach (GameObject childgo in rootgo.Children())
                {
                    MeshFilter filter = childgo.GetComponent <MeshFilter>();
                    if (filter == null || filter.mesh == null)
                    {
                        continue;
                    }
                    if (GOFilterF != null && GOFilterF(so, childgo) == false)
                    {
                        continue;
                    }

                    Mesh      curMesh  = filter.sharedMesh;
                    Vector3[] vertices = curMesh.vertices;
                    Vector3[] normals  = (WriteNormals) ? curMesh.normals : null;
                    Color[]   colors   = (WriteVertexColors) ? curMesh.colors : null;
                    Vector2[] uvs      = (WriteUVs) ? curMesh.uv : null;

                    if (vertexMap.Length < curMesh.vertexCount)
                    {
                        vertexMap = new int[curMesh.vertexCount * 2];
                    }

                    for (int i = 0; i < curMesh.vertexCount; ++i)
                    {
                        NewVertexInfo vi = new NewVertexInfo();
                        vi.bHaveN = WriteNormals; vi.bHaveC = WriteVertexColors; vi.bHaveUV = WriteUVs;

                        Vector3 v = vertices[i];
                        // local to world
                        v = filter.gameObject.transform.TransformPoint(v);
                        // world back to scene
                        vi.v = UnityUtil.SwapLeftRight(s.RootGameObject.transform.InverseTransformPoint(v));

                        if (WriteNormals)
                        {
                            Vector3 n = normals[i];
                            n    = filter.gameObject.transform.TransformDirection(n);
                            vi.n = UnityUtil.SwapLeftRight(s.RootGameObject.transform.InverseTransformDirection(n));
                        }
                        if (WriteVertexColors)
                        {
                            vi.c = colors[i];
                        }
                        if (WriteUVs)
                        {
                            vi.uv = uvs[i];
                        }

                        vertexMap[i] = m.AppendVertex(vi);
                    }

                    int[] triangles  = curMesh.triangles;
                    int   nTriangles = triangles.Length / 3;
                    for (int i = 0; i < nTriangles; ++i)
                    {
                        int a = vertexMap[triangles[3 * i]];
                        int b = vertexMap[triangles[3 * i + 1]];
                        int c = vertexMap[triangles[3 * i + 2]];
                        m.AppendTriangle(a, c, b, groupCounter);  // TRI ORIENTATION IS REVERSED HERE!!
                    }
                    groupCounter++;
                }

                vMeshes.Add(new WriteMesh(m, so.Name));
            }


            if (WriteInBackgroundThreads)
            {
                ExportStatus status = new ExportStatus()
                {
                    Exporter = this, IsComputing = true
                };
                WriteOptions useOptions = Options;
                useOptions.ProgressFunc = (cur, max) => {
                    status.Progress    = cur;
                    status.MaxProgress = max;
                };
                BackgroundWriteThread t = new BackgroundWriteThread()
                {
                    Meshes      = vMeshes, options = useOptions, Filename = filename,
                    CompletionF = (result) => {
                        LastWriteStatus         = result.code;
                        LastErrorMessage        = result.message;
                        status.LastErrorMessage = result.message;
                        status.Ok          = (result.code == IOCode.Ok);
                        status.IsComputing = false;
                    }
                };
                t.Start();
                return(status);
            }
            else
            {
                IOWriteResult result = StandardMeshWriter.WriteFile(filename, vMeshes, Options);
                LastWriteStatus  = result.code;
                LastErrorMessage = result.message;
                return(new ExportStatus()
                {
                    Exporter = this, IsComputing = false,
                    Ok = (result.code == IOCode.Ok),
                    LastErrorMessage = result.message
                });
            }
        }