protected void ConstructRawMesh(string id, BinaryReader br, int size, Vector3 bbMin, Vector3 bbMax)
        {
            // TODO: solve the issue that OpenCTM does NOT support multi-threading
            lock (PCQueue.Current.LockerForUser)
                if (_rawMeshCache.ContainsKey(id) == false)
                {
                    OpenCTM.CtmFileReader reader = new OpenCTM.CtmFileReader(br.BaseStream);
                    OpenCTM.Mesh          mesh   = reader.decode();

                    RawMesh rawMesh = new RawMesh();

                    mesh.checkIntegrity();

                    {
                        List <Vector3> Vertices = new List <Vector3>();
                        for (int j = 0; j < mesh.getVertexCount(); j++)
                        {
                            Vertices.Add(new Vector3(mesh.vertices[(j * 3)], mesh.vertices[(j * 3) + 2], mesh.vertices[(j * 3) + 1]));
                        }
                        rawMesh.Vertices = Vertices.ToArray();
                    }

                    {
                        List <int> Triangles = new List <int>();
                        for (int j = 0; j < mesh.indices.Length / 3; j++)
                        {
                            Triangles.Add(mesh.indices[(j * 3)]);
                            Triangles.Add(mesh.indices[(j * 3) + 2]);
                            Triangles.Add(mesh.indices[(j * 3) + 1]);
                        }
                        rawMesh.Triangles = Triangles.ToArray();
                    }

                    if (mesh.getUVCount() > 0)
                    {
                        List <Vector2> UVList = new List <Vector2>();
                        for (int j = 0; j < mesh.texcoordinates[0].values.Length / 2; j++)
                        {
                            UVList.Add(new Vector2(mesh.texcoordinates[0].values[(j * 2)], 1 - mesh.texcoordinates[0].values[(j * 2) + 1]));
                        }
                        rawMesh.UVList = UVList.ToArray();
                    }

                    if (mesh.hasNormals())
                    {
                        List <Vector3> Normals = new List <Vector3>();
                        for (int j = 0; j < mesh.getVertexCount(); j++)
                        {
                            Normals.Add(new Vector3(mesh.normals[(j * 3)], mesh.normals[(j * 3) + 2], mesh.normals[(j * 3) + 1]));
                        }
                        rawMesh.Normals = Normals.ToArray();
                    }
                    rawMesh.BBMin = bbMin;
                    rawMesh.BBMax = bbMax;

                    _rawMeshCache.Add(id, rawMesh);
                }
        }
Example #2
0
        public override GameObject BuildScene(string name, bool saveToDisk = false)
        {
            try {
                foreach (Eppy.Tuple <int, OpenCTM.Mesh> openctm in _openctm)
                {
                    OpenCTM.Mesh ctmMesh = openctm.Item2;
                    if (ctmMesh == null || ctmMesh.getVertexCount() == 0 || ctmMesh.getTriangleCount() == 0)
                    {
                        state = SceneLoadingStatus.eCancelled;
                        return(gameObject);
                    }

                    Eppy.Tuple <int, int, GameObject, JSONNode> item = fragments.Single(x => x.Item1 == openctm.Item1);
                    GameObject meshObject = item.Item3;

                    Mesh       mesh     = new Mesh();
                    Vector3 [] vertices = MeshRequest2.getAsVector3(ctmMesh.vertices);
                    mesh.vertices  = vertices;
                    mesh.triangles = ctmMesh.indices;
                    if (ctmMesh.hasNormals())
                    {
                        mesh.normals = MeshRequest2.getAsVector3(ctmMesh.normals);
                    }
                    for (int i = 0; i < ctmMesh.getUVCount(); i++)
                    {
                        mesh.SetUVs(i, MeshRequest2.getAsVector2List(ctmMesh.texcoordinates [i].values));
                    }

                    mesh.RecalculateNormals();
                    mesh.RecalculateBounds();

                    MeshFilter filter = meshObject.AddComponent <MeshFilter> ();
                    filter.sharedMesh = mesh;
                    MeshRenderer renderer = meshObject.AddComponent <MeshRenderer> ();
                    renderer.sharedMaterial = ForgeLoaderEngine.GetDefaultMaterial();
                    if (createCollider)
                    {
                        MeshCollider collider = meshObject.AddComponent <MeshCollider> ();
                        collider.sharedMesh = mesh;
                    }
#if UNITY_EDITOR
                    if (saveToDisk)
                    {
                        AssetDatabase.CreateAsset(mesh, ForgeConstants._resourcesPath + this.loader.PROJECTID + "/" + GetName(item.Item1) + ".asset");
                        //AssetDatabase.SaveAssets () ;
                        //AssetDatabase.Refresh () ;
                        //mesh =AssetDatabase.LoadAssetAtPath<Mesh> (ForgeConstants._resourcesPath + this.loader.PROJECTID + "/" + name + ".asset") ;
                    }
#endif

                    // Add our material to the queue
                    loader.GetMgr()._materials.Add(item.Item2);
                    //if ( loader.GetMgr ()._materials.Add (item.Item2) ) {
                    //	MaterialRequest req = new MaterialRequest (loader, null, bearer, item.Item2, item.Item4);
                    //	req.gameObject = meshObject;
                    //	if ( fireRequestCallback != null )
                    //		fireRequestCallback (this, req);
                    //}
                }
                base.BuildScene(name, saveToDisk);
                state = SceneLoadingStatus.eWaitingMaterial;
            } catch (Exception ex) {
                Debug.Log(ForgeLoader.GetCurrentMethod() + " " + ex.Message);
                state = SceneLoadingStatus.eError;
            }
            return(gameObject);
        }
Example #3
0
        protected IEnumerator ConstructMesh(string id, BinaryReader br, int size, Vector3 bbMin, Vector3 bbMax)
        {
            // NOTE: OpenCTM does NOT support multi-threading
            if (_MeshCache.ContainsKey(id) == false)
            {
                OpenCTM.CtmFileReader reader = new OpenCTM.CtmFileReader(br.BaseStream);
                yield return(null);

                OpenCTM.Mesh mesh = reader.decode();
                yield return(null);

                UnityEngine.Mesh um = new UnityEngine.Mesh();
                {
                    Vector3[] Vertices = new Vector3[mesh.getVertexCount()];
                    for (int j = 0; j < mesh.getVertexCount(); j++)
                    {
                        Vertices[j].x = mesh.vertices[(j * 3)];
                        Vertices[j].y = mesh.vertices[(j * 3) + 2];
                        Vertices[j].z = mesh.vertices[(j * 3) + 1];
                    }
                    um.vertices = Vertices;
                }
                yield return(null);

                {
                    int[] Triangles = new int[mesh.indices.Length];
                    for (int j = 0; j < mesh.indices.Length / 3; j++)
                    {
                        Triangles[(j * 3)]     = mesh.indices[(j * 3)];
                        Triangles[(j * 3) + 1] = mesh.indices[(j * 3) + 2];
                        Triangles[(j * 3) + 2] = mesh.indices[(j * 3) + 1];
                    }
                    um.triangles = Triangles;
                }
                yield return(null);

                if (mesh.getUVCount() > 0)
                {
                    Vector2[] UVList = new Vector2[mesh.texcoordinates[0].values.Length / 2];
                    for (int j = 0; j < mesh.texcoordinates[0].values.Length / 2; j++)
                    {
                        UVList[j].x = mesh.texcoordinates[0].values[(j * 2)];
                        UVList[j].y = mesh.texcoordinates[0].values[(j * 2) + 1];
                    }
                    um.uv = UVList;
                }
                yield return(null);

                if (mesh.hasNormals())
                {
                    Vector3[] Normals = new Vector3[mesh.getVertexCount()];
                    for (int j = 0; j < mesh.getVertexCount(); j++)
                    {
                        Normals[j].x = mesh.normals[(j * 3)];
                        Normals[j].y = mesh.normals[(j * 3) + 2];
                        Normals[j].z = mesh.normals[(j * 3) + 1];
                    }
                    um.normals = Normals;
                }
                else
                {
                    um.RecalculateNormals();
                }
                yield return(null);

                um.bounds.SetMinMax(bbMin, bbMax);

                _MeshCache.Add(id, um);
            }
        }
Example #4
0
        /// <summary>
        /// split openCTM Mesh
        /// </summary>
        /// <param name="ctmMesh"></param>
        /// <param name="splitMeshes"></param>
        public void SplitMesh(Mesh ctmMesh, ref List <Mesh> splitMeshes)
        {
            //是否包含UV坐标
            bool isContainUVs;

            //顶点个数
            int ctmMeshVerticesNum = ctmMesh.vertices.Length;

            int maxNumVerticesFloatArray = maxNumVerticesPerMesh * 3;

            //判断需要分割成多少个Mesh
            int splitCTMMeshNum = Mathf.CeilToInt(ctmMeshVerticesNum / (maxNumVerticesFloatArray * 1.0f));

            int[]   oldIndicesArray  = ctmMesh.indices;
            float[] oldVerticesArray = ctmMesh.vertices;
            float[] oldUVArray;

            if (ctmMesh.texcoordinates == null || ctmMesh.texcoordinates.Length == 0)
            {
                isContainUVs = false;
                oldUVArray   = new float[0];
            }
            else
            {
                isContainUVs = true;
                oldUVArray   = ctmMesh.texcoordinates[0].values;
            }



            //下一个Mesh的Indices开始时的索引
            int lastMeshEndIndicesCount = 0;

            for (int i = 0; i < splitCTMMeshNum; i++)
            {
                OpenCTM.Mesh splitCTMMesh;

                //判断是不是最后一个分割的Mesh
                if (i != splitCTMMeshNum - 1)
                {
                    //oldIndicesArray.
                    int newIndicesCount = Array.IndexOf(oldIndicesArray, maxNumVerticesPerMesh * (i + 1));

                    //索引数必须为3的倍数
                    newIndicesCount -= newIndicesCount % 3;

                    int newIndicesArrayLength = newIndicesCount - lastMeshEndIndicesCount;

                    int[] newIndicesArray       = new int[newIndicesArrayLength];
                    int[] splitMeshIndicesArray = new int[newIndicesArrayLength];

                    Array.Copy(oldIndicesArray, lastMeshEndIndicesCount, newIndicesArray, 0, newIndicesArrayLength);
                    Array.Copy(oldIndicesArray, lastMeshEndIndicesCount, splitMeshIndicesArray, 0, newIndicesArrayLength);

                    Array.Sort(newIndicesArray);

                    //找到Indices中最小的索引,将其设置为Vertices中第一个参数
                    int startVerticeCount = newIndicesArray[0];
                    //找到Indices中最大的索引,将其设置为Vertices中最后一个参数
                    int endVerticeCount        = newIndicesArray[newIndicesArray.Length - 1];
                    int newVerticesArrayLength = (endVerticeCount - startVerticeCount + 1) * 3;

                    float[] splitMeshVerticesArray = new float[newVerticesArrayLength];
                    Array.Copy(oldVerticesArray, startVerticeCount * 3, splitMeshVerticesArray, 0, newVerticesArrayLength);

                    AttributeData[] texcoordinates;
                    if (isContainUVs)
                    {
                        int     newUVArrayLength = (endVerticeCount - startVerticeCount + 1) * 2;
                        float[] splitMeshUVArray = new float[newUVArrayLength];
                        Array.Copy(oldUVArray, startVerticeCount * 2, splitMeshUVArray, 0, newUVArrayLength);

                        texcoordinates = new AttributeData[1];
                        AttributeData oldTexcoordinate = ctmMesh.texcoordinates[0];
                        texcoordinates[0] = new AttributeData(oldTexcoordinate.name, oldTexcoordinate.materialName, oldTexcoordinate.precision, splitMeshUVArray);
                    }
                    else
                    {
                        texcoordinates = new AttributeData[0];
                    }


                    //将索引数组跟顶点数组对应
                    for (int k = 0; k < splitMeshIndicesArray.Length; k++)
                    {
                        splitMeshIndicesArray[k] -= startVerticeCount;
                    }


                    splitCTMMesh = new OpenCTM.Mesh(splitMeshVerticesArray, null, splitMeshIndicesArray, texcoordinates, null);
                    splitMeshes.Add(splitCTMMesh);
                    lastMeshEndIndicesCount += newIndicesArrayLength;
                }
                else
                {
                    int newIndicesArrayLength = oldIndicesArray.Length - lastMeshEndIndicesCount;

                    int[] newIndicesArray       = new int[newIndicesArrayLength];
                    int[] splitMeshIndicesArray = new int[newIndicesArrayLength];

                    Array.Copy(oldIndicesArray, lastMeshEndIndicesCount, newIndicesArray, 0, newIndicesArrayLength);
                    Array.Copy(oldIndicesArray, lastMeshEndIndicesCount, splitMeshIndicesArray, 0, newIndicesArrayLength);

                    Array.Sort(newIndicesArray);

                    //找到Indices中最小的索引,将其设置为Vertices中第一个参数
                    int startVerticeCount = newIndicesArray[0];
                    //找到Indices中最大的索引,将其设置为Vertices中最后一个参数
                    int endVerticeCount = newIndicesArray[newIndicesArray.Length - 1];

                    int     newVerticesArrayLength = (endVerticeCount - startVerticeCount + 1) * 3;
                    float[] splitMeshVerticesArray = new float[newVerticesArrayLength];
                    Array.Copy(oldVerticesArray, startVerticeCount * 3, splitMeshVerticesArray, 0, newVerticesArrayLength);

                    AttributeData[] texcoordinates;
                    //判断是否包含UV坐标
                    if (isContainUVs)
                    {
                        int     newUVArrayLength = (endVerticeCount - startVerticeCount + 1) * 2;
                        float[] splitMeshUVArray = new float[newUVArrayLength];
                        Array.Copy(oldUVArray, startVerticeCount * 2, splitMeshUVArray, 0, newUVArrayLength);

                        texcoordinates = new AttributeData[1];
                        AttributeData oldTexcoordinate = ctmMesh.texcoordinates[0];
                        texcoordinates[0] = new AttributeData(oldTexcoordinate.name, oldTexcoordinate.materialName, oldTexcoordinate.precision, splitMeshUVArray);
                    }
                    else
                    {
                        texcoordinates = new AttributeData[0];
                    }


                    //将索引数组跟顶点数组对应
                    for (int k = 0; k < splitMeshIndicesArray.Length; k++)
                    {
                        splitMeshIndicesArray[k] -= startVerticeCount;
                    }


                    splitCTMMesh = new OpenCTM.Mesh(splitMeshVerticesArray, null, splitMeshIndicesArray, texcoordinates, null);
                    splitMeshes.Add(splitCTMMesh);
                }
            }
        }