Use UniFBX load model is too slow in problem solving in Unity3D

  • Unity3D UniFBX often used in the model is loaded FBX, but the loading is too slow, 35M model requires 48 seconds. My UniFBX version is 2.2.3.1, the problem lies in the UniFBXGeometries.csfile ProcessingByNormalsfunction code is as follows:
private UniFBXGeometry.KFbxMesh ProcessingByNormals (List<Vector3> vs, List<int> ts, List<Vector3> ns, List<Vector2> us, List<int> ms) {
        List<Vector3> nn = new List<Vector3> ();
        List<Vector2> uv = new List<Vector2> ();
        //List<int> newVertexIndexes = new List<int> ();
        //List<int> newVertexWeights = new List<int> ();

        int MAX = Mathf.Max (ts.ToArray ());
        int TRIANGLE_SIZE = MAX + 1;

        //效率低下的代码-------------------
        for (int i = 0; i < TRIANGLE_SIZE; i++)
        {
            int j = 0;
            for (int k = 0; k < ts.Count; k++)
            {
                if (ts[k] == i)
                {
                    j = k;
                    break;
                }
            }
            nn.Add(ns[j]);
            uv.Add(us[j]);
        }
        //-------------------------------
        
        if (this.setting.meshes.meshMethode == ImportMethode.Unity) {
            //int MAX_VERTICES = vs.Count - 1;
            //int skip = 1;
            for (int i = 0; i < ts.Count; i++) {
                if (ns[i] != nn[ts[i]] || us[i] != uv[ts[i]]) {
                    //if (vs.Count > (skip * MAX_VERTICES)) skip++;
                    //newVertexIndexes.Add (ts[i] * skip);
                    //newVertexWeights.Add (ts[i]);
                    vs.Add (vs[ts[i]]);
                    nn.Add (ns[i]);
                    uv.Add (us[i]);
                    ns[i] = nn[ts[i]];
                    us[i] = uv[ts[i]];
                    int inc = MAX + 1;
                    ts[i] = inc;
                    MAX = inc;
                    if (vs.Count >= 64000) break;
                }
            }
        }
        ns = nn;
        us = uv;

        UniFBXGeometry.KFbxMesh temp = new UniFBXGeometry.KFbxMesh ();
        temp.vertices = vs;
        //temp.newVeretexIndexes = newVertexIndexes;
        //temp.newVeretexWeights = newVertexWeights;
        temp.normals = ns;
        temp.uvs = us;

        //Debug.Log (vs.Count + " :: " + ns.Count + " :: " + us.Count);
        if (this.setting.textures.normalmaps) {
            if (vs.Count == us.Count) temp.tangents = this.GetTangents (vs, ts, ns, us);
        }
        temp.submeshes = this.GetSubmeshes (ts, ms);
        return temp;
    }
  • After optimization, 35M loading model requires only 4 seconds (10 times), optimized code is as follows:
private UniFBXGeometry.KFbxMesh ProcessingByNormals (List<Vector3> vs, List<int> ts, List<Vector3> ns, List<Vector2> us, List<int> ms) {
        List<Vector3> nn = new List<Vector3> ();
        List<Vector2> uv = new List<Vector2> ();
        //List<int> newVertexIndexes = new List<int> ();
        //List<int> newVertexWeights = new List<int> ();

        int MAX = Mathf.Max (ts.ToArray ());
        int TRIANGLE_SIZE = MAX + 1;

		//优化的代码-------------------
		var tmpNN = new Vector3[TRIANGLE_SIZE];
		var tmpUV = new Vector2[TRIANGLE_SIZE];
		
		var tmpNNFlag = new bool[TRIANGLE_SIZE];
		var tmpUVFlag = new bool[TRIANGLE_SIZE];
		
		for(int i = 0; i < ts.Count; ++i)
		{
		    if (!tmpNNFlag[ts[i]])
		    {
		        tmpNNFlag[ts[i]] = true;
		        tmpNN[ts[i]] = ns[i];
		    }
		    if (!tmpUVFlag[ts[i]])
		    {
		        tmpUVFlag[ts[i]] = true;
		        tmpUV[ts[i]] = us[i];
		    }
		}
		nn.AddRange(tmpNN);
		uv.AddRange(tmpUV);
		//------------------------------
        
        if (this.setting.meshes.meshMethode == ImportMethode.Unity) {
            //int MAX_VERTICES = vs.Count - 1;
            //int skip = 1;
            for (int i = 0; i < ts.Count; i++) {
                if (ns[i] != nn[ts[i]] || us[i] != uv[ts[i]]) {
                    //if (vs.Count > (skip * MAX_VERTICES)) skip++;
                    //newVertexIndexes.Add (ts[i] * skip);
                    //newVertexWeights.Add (ts[i]);
                    vs.Add (vs[ts[i]]);
                    nn.Add (ns[i]);
                    uv.Add (us[i]);
                    ns[i] = nn[ts[i]];
                    us[i] = uv[ts[i]];
                    int inc = MAX + 1;
                    ts[i] = inc;
                    MAX = inc;
                    if (vs.Count >= 64000) break;
                }
            }
        }
        ns = nn;
        us = uv;

        UniFBXGeometry.KFbxMesh temp = new UniFBXGeometry.KFbxMesh ();
        temp.vertices = vs;
        //temp.newVeretexIndexes = newVertexIndexes;
        //temp.newVeretexWeights = newVertexWeights;
        temp.normals = ns;
        temp.uvs = us;

        //Debug.Log (vs.Count + " :: " + ns.Count + " :: " + us.Count);
        if (this.setting.textures.normalmaps) {
            if (vs.Count == us.Count) temp.tangents = this.GetTangents (vs, ts, ns, us);
        }
        temp.submeshes = this.GetSubmeshes (ts, ms);
        return temp;
    }
	   
  • Note: UniFBX load model 文本格式, not more than a single mesh 65000vertices.
Published 41 original articles · won praise 4 · Views 3886

Guess you like

Origin blog.csdn.net/weixin_42487874/article/details/103413367