Ejemplo n.º 1
0
        /////////////////////////////////////////////////////////////////////////////////////////////////
        // Private methods
        /////////////////////////////////////////////////////////////////////////////////////////////////

        unsafe void ConsolidateMesh(GameObject gameObject, Mesh meshOut, int[] permutation, int[] collapseMap, int nVertices)
        {
            int subMeshCount = _aSubMeshesOriginal.Length;

            if (null == _av3Vertices)
            {
                _av3Vertices = (Vector3[])_av3VerticesOriginal.Clone();
            }
            else
            {
                _av3VerticesOriginal.CopyTo(_av3Vertices, 0);
            }
            if (null == _av3NormalsIn)
            {
                _av3NormalsIn = (Vector3[])_av3NormalsOriginal.Clone();
            }
            else
            {
                _av3NormalsOriginal.CopyTo(_av3NormalsIn, 0);
            }
            if (null == _av4TangentsIn)
            {
                _av4TangentsIn = (Vector4[])_av4TangentsOriginal.Clone();
            }
            else
            {
                _av4TangentsOriginal.CopyTo(_av4TangentsIn, 0);
            }
            if (null == _av2Mapping1In)
            {
                _av2Mapping1In = (Vector2[])_av2Mapping1Original.Clone();
            }
            else
            {
                _av2Mapping1Original.CopyTo(_av2Mapping1In, 0);
            }
            if (null == _av2Mapping2In)
            {
                _av2Mapping2In = (Vector2[])_av2Mapping2Original.Clone();
            }
            else
            {
                _av2Mapping2Original.CopyTo(_av2Mapping2In, 0);
            }
            if (null == _aColors32In)
            {
                _aColors32In = (Color32[])_aColors32Original.Clone();
            }
            else
            {
                _aColors32Original.CopyTo(_aColors32In, 0);
            }
            if (null == _aBoneWeights)
            {
                _aBoneWeights = (BoneWeight[])_aBoneWeightsOriginal.Clone();
            }
            else
            {
                _aBoneWeightsOriginal.CopyTo(_aBoneWeights, 0);
            }
            if (null == _aSubMeshes)
            {
                _aSubMeshes = new int[subMeshCount][];
            }
            if (null == _aTriangleCount)
            {
                _aTriangleCount = new int[subMeshCount];
            }

            bool bUV1     = _av2Mapping1In != null && _av2Mapping1In.Length > 0;
            bool bUV2     = _av2Mapping2In != null && _av2Mapping2In.Length > 0;
            bool bNormal  = _av3NormalsIn != null && _av3NormalsIn.Length > 0;
            bool bTangent = _av4TangentsIn != null && _av4TangentsIn.Length > 0;
            bool bColor32 = (_aColors32In != null && _aColors32In.Length > 0);
            bool bBone    = _aBoneWeights != null && _aBoneWeights.Length > 0;

            _vertexMap = _vertexMap ?? new int[_av3Vertices.Length];
            for (int i = 0, imax = _vertexMap.Length; i < imax; i++)
            {
                _vertexMap[i] = -1;
            }
            int n = 0;

            for (int nSubMesh = 0; nSubMesh < subMeshCount; nSubMesh++)
            {
                if (null == _aSubMeshes[nSubMesh])
                {
                    _aSubMeshes[nSubMesh] = (int[])_aSubMeshesOriginal[nSubMesh].Clone();
                }
                else
                {
                    _aSubMeshesOriginal[nSubMesh].CopyTo(_aSubMeshes[nSubMesh], 0);
                }
                int[] triangles = _aSubMeshes[nSubMesh];
                for (int i = 0; i < triangles.Length; i += 3)
                {
                    int idx0 = triangles[i];
                    int idx1 = triangles[i + 1];
                    int idx2 = triangles[i + 2];
                    while (permutation[idx0] >= nVertices)
                    {
                        int idx = collapseMap[idx0];
                        if (idx == -1 || idx1 == idx || idx2 == idx)
                        {
                            idx0 = -1;
                            break;
                        }
                        idx0 = idx;
                    }
                    while (permutation[idx1] >= nVertices)
                    {
                        int idx = collapseMap[idx1];
                        if (idx == -1 || idx0 == idx || idx2 == idx)
                        {
                            idx1 = -1;
                            break;
                        }
                        idx1 = idx;
                    }
                    while (permutation[idx2] >= nVertices)
                    {
                        int idx = collapseMap[idx2];
                        if (idx == -1 || idx1 == idx || idx0 == idx)
                        {
                            idx2 = -1;
                            break;
                        }
                        idx2 = idx;
                    }
                    if (idx0 == -1 || idx1 == -1 || idx2 == -1)
                    {
                        triangles[i]     = -1;
                        triangles[i + 1] = -1;
                        triangles[i + 2] = -1;
                        continue;
                    }
                    if (_vertexMap[idx0] == -1)
                    {
                        _vertexMap[idx0] = n++;
                    }
                    triangles[i] = _vertexMap[idx0];
                    if (_vertexMap[idx1] == -1)
                    {
                        _vertexMap[idx1] = n++;
                    }
                    triangles[i + 1] = _vertexMap[idx1];
                    if (_vertexMap[idx2] == -1)
                    {
                        _vertexMap[idx2] = n++;
                    }
                    triangles[i + 2] = _vertexMap[idx2];
                }
                int l = triangles.Length;
                int h = 0;
                int t = l - 1;
                while (h < t)
                {
                    if (triangles[t] == -1)
                    {
                        t -= 3;
                        continue;
                    }
                    if (triangles[h] != -1)
                    {
                        h += 3;
                        continue;
                    }
                    triangles[h]     = triangles[t - 2];
                    triangles[h + 1] = triangles[t - 1];
                    triangles[h + 2] = triangles[t];
                    triangles[t - 2] = -1;
                    triangles[t - 1] = -1;
                    triangles[t]     = -1;
                    h += 3;
                    t -= 3;
                }
                if (t < l - 1)
                {
                    _aTriangleCount[nSubMesh] = t + 1;
                    //#if DEBUG
                    //                        if (t >= 0 && triangles[t] == -1)
                    //                        {
                    //                            throw new Exception("triangles[t] == -1");
                    //                        }
                    //#endif
                }
                else
                {
                    _aTriangleCount[nSubMesh] = l;
                }
            }
            Vector2    tmpUV          = Vector2.zero;
            Vector2    tmpUV2         = Vector2.zero;
            Vector3    tmpNormal      = Vector3.zero;
            Vector4    tmpTangent     = Vector4.zero;
            Color32    tmpColor       = Color.black;
            BoneWeight tmpBoneWeight  = new BoneWeight();
            Vector2    tmpUV_         = Vector2.zero;
            Vector2    tmpUV2_        = Vector2.zero;
            Vector3    tmpNormal_     = Vector3.zero;
            Vector4    tmpTangent_    = Vector4.zero;
            Color32    tmpColor_      = Color.black;
            BoneWeight tmpBoneWeight_ = new BoneWeight();

#if UNITY_2018_1_OR_NEWER
            NativeArray <MappingLinkedNode> headArray = new NativeArray <MappingLinkedNode>(_vertexMap.Length, Allocator.TempJob);
            int headCount = 0;
            int nodeSize  = UnsafeUtility.AlignOf <MappingLinkedNode>();
            for (int i = 0; i < _vertexMap.Length; i++)
            {
                int idx = i;
                MappingLinkedNode *head = (MappingLinkedNode *)UnsafeUtility.Malloc(1, nodeSize, Allocator.TempJob);
                head->Next    = null;
                head->Mapping = i;
                MappingLinkedNode *node = head;
                while (_vertexMap[idx] != -1)
                {
                    MappingLinkedNode *next = (MappingLinkedNode *)UnsafeUtility.Malloc(1, nodeSize, Allocator.TempJob);
                    next->Next    = null;
                    next->Mapping = _vertexMap[idx];
                    node->Next    = next;
                    int tmpI = _vertexMap[idx];
                    _vertexMap[idx] = -1;
                    idx             = tmpI;
                    node            = next;
                }
                if (head->Next != null)
                {
                    headArray[headCount++] = *head;
                }
            }
            for (int i = 0; i < headCount; i++)
            {
                MappingLinkedNode  head = headArray[i];
                MappingLinkedNode *node = &head;

                int     idx = node->Mapping;
                Vector3 tmp = _av3Vertices[idx];
                if (bUV1)
                {
                    tmpUV = _av2Mapping1In[idx];
                }
                if (bUV2)
                {
                    tmpUV2 = _av2Mapping2In[idx];
                }
                if (bNormal)
                {
                    tmpNormal = _av3NormalsIn[idx];
                }
                if (bTangent)
                {
                    tmpTangent = _av4TangentsIn[idx];
                }
                if (bColor32)
                {
                    tmpColor = _aColors32In[idx];
                }
                if (bBone)
                {
                    tmpBoneWeight = _aBoneWeights[idx];
                }
                node = node->Next;
                while (node != null)
                {
                    int     vidx = node->Mapping;
                    Vector3 tmp_ = _av3Vertices[vidx];
                    if (bUV1)
                    {
                        tmpUV_ = _av2Mapping1In[vidx];
                    }
                    if (bUV2)
                    {
                        tmpUV2_ = _av2Mapping2In[vidx];
                    }
                    if (bNormal)
                    {
                        tmpNormal_ = _av3NormalsIn[vidx];
                    }
                    if (bTangent)
                    {
                        tmpTangent_ = _av4TangentsIn[vidx];
                    }
                    if (bColor32)
                    {
                        tmpColor_ = _aColors32In[vidx];
                    }
                    if (bBone)
                    {
                        tmpBoneWeight_ = _aBoneWeights[vidx];
                    }
                    _av3Vertices[vidx] = tmp;
                    if (bUV1)
                    {
                        _av2Mapping1In[vidx] = tmpUV;
                    }
                    if (bUV2)
                    {
                        _av2Mapping2In[vidx] = tmpUV2;
                    }
                    if (bNormal)
                    {
                        _av3NormalsIn[vidx] = tmpNormal;
                    }
                    if (bTangent)
                    {
                        _av4TangentsIn[vidx] = tmpTangent;
                    }
                    if (bColor32)
                    {
                        _aColors32In[vidx] = tmpColor;
                    }
                    if (bBone)
                    {
                        _aBoneWeights[vidx] = tmpBoneWeight;
                    }
                    tmp           = tmp_;
                    tmpUV         = tmpUV_;
                    tmpUV2        = tmpUV2_;
                    tmpNormal     = tmpNormal_;
                    tmpTangent    = tmpTangent_;
                    tmpColor      = tmpColor_;
                    tmpBoneWeight = tmpBoneWeight_;
                    MappingLinkedNode *oldNode = node;
                    node = node->Next;
                    UnsafeUtility.Free(oldNode, Allocator.TempJob);
                }
            }
            headArray.Dispose();
#else
            for (int i = 0; i < _vertexMap.Length; i++)
            {
                int     idx = i;
                Vector3 tmp = _av3Vertices[idx];
                if (bUV1)
                {
                    tmpUV = _av2Mapping1In[idx];
                }
                if (bUV2)
                {
                    tmpUV2 = _av2Mapping2In[idx];
                }
                if (bNormal)
                {
                    tmpNormal = _av3NormalsIn[idx];
                }
                if (bTangent)
                {
                    tmpTangent = _av4TangentsIn[idx];
                }
                if (bColor32)
                {
                    tmpColor = _aColors32In[idx];
                }
                if (bBone)
                {
                    tmpBoneWeight = _aBoneWeights[idx];
                }
                while (_vertexMap[idx] != -1)
                {
                    Vector3 tmp_ = _av3Vertices[_vertexMap[idx]];
                    if (bUV1)
                    {
                        tmpUV_ = _av2Mapping1In[_vertexMap[idx]];
                    }
                    if (bUV2)
                    {
                        tmpUV2_ = _av2Mapping2In[_vertexMap[idx]];
                    }
                    if (bNormal)
                    {
                        tmpNormal_ = _av3NormalsIn[_vertexMap[idx]];
                    }
                    if (bTangent)
                    {
                        tmpTangent_ = _av4TangentsIn[_vertexMap[idx]];
                    }
                    if (bColor32)
                    {
                        tmpColor_ = _aColors32In[_vertexMap[idx]];
                    }
                    if (bBone)
                    {
                        tmpBoneWeight_ = _aBoneWeights[_vertexMap[idx]];
                    }
                    _av3Vertices[_vertexMap[idx]] = tmp;
                    if (bUV1)
                    {
                        _av2Mapping1In[_vertexMap[idx]] = tmpUV;
                    }
                    if (bUV2)
                    {
                        _av2Mapping2In[_vertexMap[idx]] = tmpUV2;
                    }
                    if (bNormal)
                    {
                        _av3NormalsIn[_vertexMap[idx]] = tmpNormal;
                    }
                    if (bTangent)
                    {
                        _av4TangentsIn[_vertexMap[idx]] = tmpTangent;
                    }
                    if (bColor32)
                    {
                        _aColors32In[_vertexMap[idx]] = tmpColor;
                    }
                    if (bBone)
                    {
                        _aBoneWeights[_vertexMap[idx]] = tmpBoneWeight;
                    }
                    tmp           = tmp_;
                    tmpUV         = tmpUV_;
                    tmpUV2        = tmpUV2_;
                    tmpNormal     = tmpNormal_;
                    tmpTangent    = tmpTangent_;
                    tmpColor      = tmpColor_;
                    tmpBoneWeight = tmpBoneWeight_;
                    int tmpI = _vertexMap[idx];
                    _vertexMap[idx] = -1;
                    idx             = tmpI;
                }
            }
#endif
            //#if DEBUG
            //                // Check
            //                for (int i = 0; i < n; i++)
            //                {
            //                    if (_vertexMap[i] != -1)
            //                    {
            //                        throw new Exception("");
            //                    }
            //                }
            //#endif
            //如果有法线 TODO:操作为了
            if (bNormal)
            {
                for (int i = 0; i < n; i++)
                {
                    _av3NormalsIn[i] = _av3NormalsIn[i] * 0.1f;
                }
                for (int i = 0; i < subMeshCount; i++)
                {
                    int[] triangles = _aSubMeshes[i];
                    for (int j = 0; j < _aTriangleCount[i]; j += 3)
                    {
                        int     i0 = triangles[j];
                        int     i1 = triangles[j + 1];
                        int     i2 = triangles[j + 2];
                        Vector3 v0 = _av3Vertices[i0];
                        Vector3 v1 = _av3Vertices[i1];
                        Vector3 v2 = _av3Vertices[i2];

                        Vector3 normal = Vector3.Cross((v1 - v0), (v2 - v1));
                        _av3NormalsIn[i0] += normal;
                        _av3NormalsIn[i1] += normal;
                        _av3NormalsIn[i2] += normal;
                    }
                }
                for (int i = 0; i < n; i++)
                {
                    _av3NormalsIn[i] = _av3NormalsIn[i].normalized;
                }
            }
            this._meshOut = meshOut;

            _assignVertices = _assignVertices ?? (arr => this._meshOut.vertices = arr);
            if (bNormal)
            {
                _assignNormals = _assignNormals ?? (arr => this._meshOut.normals = arr);
            }
            if (bTangent)
            {
                _assignTangents = _assignTangents ?? (arr => this._meshOut.tangents = arr);
            }
            if (bUV1)
            {
                _assignUV = _assignUV ?? (arr => this._meshOut.uv = arr);
            }
            if (bUV2)
            {
                _assignUV2 = _assignUV2 ?? (arr => this._meshOut.uv2 = arr);
            }
            if (bColor32)
            {
                _assignColor32 = _assignColor32 ?? (arr => this._meshOut.colors32 = arr);
            }
            if (bBone)
            {
                _assignBoneWeights = _assignBoneWeights ?? (arr => this._meshOut.boneWeights = arr);
            }
            if (null == _setTriangles)
            {
                _setTriangles = new Action <int[]> [subMeshCount];
                for (int i = 0; i < subMeshCount; i++)
                {
                    int idx = i;
                    _setTriangles[i] = (arr => this._meshOut.SetTriangles(arr, idx));
                }
            }

            meshOut.triangles = null;
            // NOTE: 禁术
            UnsafeUtil.Vector3HackArraySizeCall(_av3Vertices, n, _assignVertices);
            if (bNormal)
            {
                UnsafeUtil.Vector3HackArraySizeCall(_av3NormalsIn, n, _assignNormals);
            }
            if (bTangent)
            {
                UnsafeUtil.Vector4HackArraySizeCall(_av4TangentsIn, n, _assignTangents);
            }
            if (bUV1)
            {
                UnsafeUtil.Vector2HackArraySizeCall(_av2Mapping1In, n, _assignUV);
            }
            if (bUV2)
            {
                UnsafeUtil.Vector2HackArraySizeCall(_av2Mapping2In, n, _assignUV2);
            }
            if (bColor32)
            {
                UnsafeUtil.Color32HackArraySizeCall(_aColors32In, n, _assignColor32);
            }
            if (bBone)
            {
                UnsafeUtil.BoneWeightHackArraySizeCall(_aBoneWeights, n, _assignBoneWeights);
            }
            if (bBone)
            {
                meshOut.bindposes = _aBindPoses;
            }
            meshOut.subMeshCount = _aSubMeshes.Length;

            for (int i = 0; i < subMeshCount; i++)
            {
                UnsafeUtil.IntegerHackArraySizeCall(_aSubMeshes[i], _aTriangleCount[i], _setTriangles[i]);
            }
            meshOut.UploadMeshData(false);
            //meshOut.name = gameObject.name + " simplified mesh";
        }
Ejemplo n.º 2
0
        /////////////////////////////////////////////////////////////////////////////////////////////////
        // Private methods
        /////////////////////////////////////////////////////////////////////////////////////////////////
        unsafe void ConsolidateMesh(GameObject gameObject, Mesh meshOut, int[] permutation, int[] collapseMap, int nVertices)
        {
            int subMeshCount = _aSubMeshesOriginal.Length;

            if (null == _av3Vertices)
            {
                _av3Vertices = (Vector3[])_av3VerticesOriginal.Clone();
            }
            else
            {
                _av3VerticesOriginal.CopyTo(_av3Vertices, 0);
            }
            if (null == _av3NormalsIn)
            {
                _av3NormalsIn = (Vector3[])_av3NormalsOriginal.Clone();
            }
            else
            {
                _av3NormalsOriginal.CopyTo(_av3NormalsIn, 0);
            }
            if (null == _av4TangentsIn)
            {
                _av4TangentsIn = (Vector4[])_av4TangentsOriginal.Clone();
            }
            else
            {
                _av4TangentsOriginal.CopyTo(_av4TangentsIn, 0);
            }
            if (null == _av2Mapping1In)
            {
                _av2Mapping1In = (Vector2[])_av2Mapping1Original.Clone();
            }
            else
            {
                _av2Mapping1Original.CopyTo(_av2Mapping1In, 0);
            }
            if (null == _av2Mapping2In)
            {
                _av2Mapping2In = (Vector2[])_av2Mapping2Original.Clone();
            }
            else
            {
                _av2Mapping2Original.CopyTo(_av2Mapping2In, 0);
            }
            if (null == _aColors32In)
            {
                _aColors32In = (Color32[])_aColors32Original.Clone();
            }
            else
            {
                _aColors32Original.CopyTo(_aColors32In, 0);
            }
            if (null == _aBoneWeights)
            {
                _aBoneWeights = (BoneWeight[])_aBoneWeightsOriginal.Clone();
            }
            else
            {
                _aBoneWeightsOriginal.CopyTo(_aBoneWeights, 0);
            }
            if (null == _aSubMeshes)
            {
                _aSubMeshes = new int[subMeshCount][];
            }
            if (null == _aTriangleCount)
            {
                _aTriangleCount = new int[subMeshCount];
            }

            bool bUV1     = _av2Mapping1In != null && _av2Mapping1In.Length > 0;
            bool bUV2     = _av2Mapping2In != null && _av2Mapping2In.Length > 0;
            bool bNormal  = _av3NormalsIn != null && _av3NormalsIn.Length > 0;
            bool bTangent = _av4TangentsIn != null && _av4TangentsIn.Length > 0;
            bool bColor32 = (_aColors32In != null && _aColors32In.Length > 0);
            bool bBone    = _aBoneWeights != null && _aBoneWeights.Length > 0;

            _vertexMap = _vertexMap ?? new int[_av3Vertices.Length];
            for (int i = 0, imax = _vertexMap.Length; i < imax; i++)
            {
                _vertexMap[i] = -1;
            }
            int n = 0;

            for (int nSubMesh = 0; nSubMesh < subMeshCount; nSubMesh++)
            {
                if (null == _aSubMeshes[nSubMesh])
                {
                    _aSubMeshes[nSubMesh] = (int[])_aSubMeshesOriginal[nSubMesh].Clone();
                }
                else
                {
                    _aSubMeshesOriginal[nSubMesh].CopyTo(_aSubMeshes[nSubMesh], 0);
                }
                int[] triangles = _aSubMeshes[nSubMesh];
                for (int i = 0; i < triangles.Length; i += 3)
                {
                    int idx0 = triangles[i];
                    int idx1 = triangles[i + 1];
                    int idx2 = triangles[i + 2];
                    while (permutation[idx0] >= nVertices)
                    {
                        int idx = collapseMap[idx0];
                        if (idx == -1 || idx1 == idx || idx2 == idx)
                        {
                            idx0 = -1;
                            break;
                        }
                        idx0 = idx;
                    }
                    while (permutation[idx1] >= nVertices)
                    {
                        int idx = collapseMap[idx1];
                        if (idx == -1 || idx0 == idx || idx2 == idx)
                        {
                            idx1 = -1;
                            break;
                        }
                        idx1 = idx;
                    }
                    while (permutation[idx2] >= nVertices)
                    {
                        int idx = collapseMap[idx2];
                        if (idx == -1 || idx1 == idx || idx0 == idx)
                        {
                            idx2 = -1;
                            break;
                        }
                        idx2 = idx;
                    }
                    if (idx0 == -1 || idx1 == -1 || idx2 == -1)
                    {
                        triangles[i]     = -1;
                        triangles[i + 1] = -1;
                        triangles[i + 2] = -1;
                        continue;
                    }
                    if (_vertexMap[idx0] == -1)
                    {
                        _vertexMap[idx0] = n++;
                    }
                    triangles[i] = _vertexMap[idx0];
                    if (_vertexMap[idx1] == -1)
                    {
                        _vertexMap[idx1] = n++;
                    }
                    triangles[i + 1] = _vertexMap[idx1];
                    if (_vertexMap[idx2] == -1)
                    {
                        _vertexMap[idx2] = n++;
                    }
                    triangles[i + 2] = _vertexMap[idx2];
                }
                int l = triangles.Length;
                int h = 0;
                int t = l - 1;
                while (h < t)
                {
                    if (triangles[t] == -1)
                    {
                        t -= 3;
                        continue;
                    }
                    if (triangles[h] != -1)
                    {
                        h += 3;
                        continue;
                    }
                    triangles[h]     = triangles[t - 2];
                    triangles[h + 1] = triangles[t - 1];
                    triangles[h + 2] = triangles[t];
                    triangles[t - 2] = -1;
                    triangles[t - 1] = -1;
                    triangles[t]     = -1;
                    h += 3;
                    t -= 3;
                }
                if (t < l - 1)
                {
                    _aTriangleCount[nSubMesh] = t + 1;
                    //#if DEBUG
                    //                        if (t >= 0 && triangles[t] == -1)
                    //                        {
                    //                            throw new Exception("triangles[t] == -1");
                    //                        }
                    //#endif
                }
                else
                {
                    _aTriangleCount[nSubMesh] = l;
                }
            }
#if false//UNITY_2018_1_OR_NEWER
            NativeArray <MappingLinkedNode> headArray = new NativeArray <MappingLinkedNode>(_vertexMap.Length, Allocator.TempJob);
            NativeArray <MappingLinkedNode> nodeArray = new NativeArray <MappingLinkedNode>(_vertexMap.Length, Allocator.TempJob);
            MappingLinkedNode *pNodeArray             = (MappingLinkedNode *)nodeArray.GetUnsafeReadOnlyPtr();
            MappingLinkedNode *pHeadArray             = (MappingLinkedNode *)headArray.GetUnsafeReadOnlyPtr();
            int headCount = 0;
            for (int i = _vertexMap.Length - 1; i >= 0; i--)
            {
                if (_vertexMap[i] == -1)
                {
                    continue;
                }
                int idx = i;
                MappingLinkedNode *head = pNodeArray + i;
                head->Next    = null;
                head->Mapping = i;
                MappingLinkedNode *node = head;
                while (_vertexMap[idx] != -1)
                {
                    int vidx = _vertexMap[idx];
                    MappingLinkedNode *next = pNodeArray + vidx;
                    next->Next      = null;
                    next->Mapping   = vidx;
                    node->Next      = next;
                    _vertexMap[idx] = -1;
                    idx             = vidx;
                    node            = next;
                }
                //if (headHash[idx].Next != null)
                //{
                //    MappingLinkedNode h = headHash[idx];
                //    node->Next = h.Next;
                //    headHash[idx] = default(MappingLinkedNode);
                //}
                if (head->Next != null)
                {
                    UnsafeUtility.WriteArrayElement(pHeadArray, headCount++, new MappingLinkedNode()
                    {
                        Mapping = -1, Next = head
                    });
                    //headArray[headCount++] = new MappingLinkedNode()
                    //{
                    //    Mapping = -1,
                    //    Next = head,
                    //};
                }
            }

            //for (int i = 0; i < _vertexMap.Length; i++)
            //{
            //    if (headHash[i].Next != null)
            //    {
            //        headArray[headCount++] = headHash[i];
            //        headHash[i] = default(MappingLinkedNode);
            //    }
            //}

            int hi = 0;
            NativeArray <JobHandle> handles = new NativeArray <JobHandle>(7, Allocator.TempJob);
            int arrLen = _av3Vertices.Length;
            CopyMeshJob <Vector3> jobVert = CopyMeshJob <Vector3> .Create(pHeadArray, arrLen);

            jobVert.CopyFromArray(_av3Vertices);
            handles[hi++] = jobVert.Schedule(headCount, 1);

            CopyMeshJob <Vector2> jobUV = default(CopyMeshJob <Vector2>);
            if (bUV1)
            {
                jobUV = CopyMeshJob <Vector2> .Create(pHeadArray, arrLen);

                jobUV.CopyFromArray(_av2Mapping1In);
                handles[hi++] = jobUV.Schedule(headCount, 1);
            }
            CopyMeshJob <Vector2> jobUV2 = default(CopyMeshJob <Vector2>);
            if (bUV2)
            {
                jobUV2 = CopyMeshJob <Vector2> .Create(pHeadArray, arrLen);

                jobUV2.CopyFromArray(_av2Mapping2In);
                handles[hi++] = jobUV2.Schedule(headCount, 1);
            }
            CopyMeshJob <Vector3> jobNorm = default(CopyMeshJob <Vector3>);
            if (bNormal)
            {
                jobNorm = CopyMeshJob <Vector3> .Create(pHeadArray, arrLen);

                jobNorm.CopyFromArray(_av3NormalsIn);
                handles[hi++] = jobNorm.Schedule(headCount, 1);
            }
            CopyMeshJob <Vector4> jobTang = default(CopyMeshJob <Vector4>);
            if (bTangent)
            {
                jobTang = CopyMeshJob <Vector4> .Create(pHeadArray, arrLen);

                jobTang.CopyFromArray(_av4TangentsIn);
                handles[hi++] = jobTang.Schedule(headCount, 1);
            }
            CopyMeshJob <Color32> jobCol = default(CopyMeshJob <Color32>);
            if (bColor32)
            {
                jobCol = CopyMeshJob <Color32> .Create(pHeadArray, arrLen);

                jobCol.CopyFromArray(_aColors32In);
                handles[hi++] = jobCol.Schedule(headCount, 1);
            }
            CopyMeshJob <BoneWeight> jobBone = default(CopyMeshJob <BoneWeight>);
            if (bBone)
            {
                jobBone = CopyMeshJob <BoneWeight> .Create(pHeadArray, arrLen);

                jobBone.CopyFromArray(_aBoneWeights);
                handles[hi++] = jobBone.Schedule(headCount, 1);
            }

            JobHandle.CompleteAll(handles);
            jobVert.CopyToArrayAndDispose(_av3Vertices, n);
            if (bUV1)
            {
                jobUV.CopyToArrayAndDispose(_av2Mapping1In, n);
            }
            if (bUV2)
            {
                jobUV2.CopyToArrayAndDispose(_av2Mapping2In, n);
            }
            if (bNormal)
            {
                jobNorm.CopyToArrayAndDispose(_av3NormalsIn, n);
            }
            if (bTangent)
            {
                jobTang.CopyToArrayAndDispose(_av4TangentsIn, n);
            }
            if (bColor32)
            {
                jobCol.CopyToArrayAndDispose(_aColors32In, n);
            }
            if (bBone)
            {
                jobBone.CopyToArrayAndDispose(_aBoneWeights, n);
            }
            //for (int i = 0; i < headCount; i++)
            //{
            //    MappingLinkedNode head = UnsafeUtility.ReadArrayElement<MappingLinkedNode>(pHeadArray, i);
            //    MappingLinkedNode* node = head.Next;
            //    while (node != null)
            //    {
            //        MappingLinkedNode* oldNode = node;
            //        node = node->Next;
            //        UnsafeUtility.Free(oldNode, Allocator.TempJob);
            //    }
            //}
            handles.Dispose();
            nodeArray.Dispose();
            headArray.Dispose();
            //for (int i = 0; i < headCount; i++)
            //{
            //    MappingLinkedNode head = headArray[i];
            //    MappingLinkedNode *node = &head;

            //    int idx = node->Mapping;
            //    Vector3 tmp = _av3Vertices[idx];
            //    if (bUV1) tmpUV = _av2Mapping1In[idx];
            //    if (bUV2) tmpUV2 = _av2Mapping2In[idx];
            //    if (bNormal) tmpNormal = _av3NormalsIn[idx];
            //    if (bTangent) tmpTangent = _av4TangentsIn[idx];
            //    if (bColor32) tmpColor = _aColors32In[idx];
            //    if (bBone) tmpBoneWeight = _aBoneWeights[idx];
            //    node = node->Next;
            //    while (node != null)
            //    {
            //        int vidx = node->Mapping;
            //        Vector3 tmp_ = _av3Vertices[vidx];
            //        if (bUV1) tmpUV_ = _av2Mapping1In[vidx];
            //        if (bUV2) tmpUV2_ = _av2Mapping2In[vidx];
            //        if (bNormal) tmpNormal_ = _av3NormalsIn[vidx];
            //        if (bTangent) tmpTangent_ = _av4TangentsIn[vidx];
            //        if (bColor32) tmpColor_ = _aColors32In[vidx];
            //        if (bBone) tmpBoneWeight_ = _aBoneWeights[vidx];
            //        _av3Vertices[vidx] = tmp;
            //        if (bUV1) _av2Mapping1In[vidx] = tmpUV;
            //        if (bUV2) _av2Mapping2In[vidx] = tmpUV2;
            //        if (bNormal) _av3NormalsIn[vidx] = tmpNormal;
            //        if (bTangent) _av4TangentsIn[vidx] = tmpTangent;
            //        if (bColor32) _aColors32In[vidx] = tmpColor;
            //        if (bBone) _aBoneWeights[vidx] = tmpBoneWeight;
            //        tmp = tmp_;
            //        tmpUV = tmpUV_;
            //        tmpUV2 = tmpUV2_;
            //        tmpNormal = tmpNormal_;
            //        tmpTangent = tmpTangent_;
            //        tmpColor = tmpColor_;
            //        tmpBoneWeight = tmpBoneWeight_;
            //        MappingLinkedNode* oldNode = node;
            //        node = node->Next;
            //        UnsafeUtility.Free(oldNode, Allocator.TempJob);
            //    }
            //}
            //headArray.Dispose();
#else
            Vector2    tmpUV          = Vector2.zero;
            Vector2    tmpUV2         = Vector2.zero;
            Vector3    tmpNormal      = Vector3.zero;
            Vector4    tmpTangent     = Vector4.zero;
            Color32    tmpColor       = Color.black;
            BoneWeight tmpBoneWeight  = new BoneWeight();
            Vector2    tmpUV_         = Vector2.zero;
            Vector2    tmpUV2_        = Vector2.zero;
            Vector3    tmpNormal_     = Vector3.zero;
            Vector4    tmpTangent_    = Vector4.zero;
            Color32    tmpColor_      = Color.black;
            BoneWeight tmpBoneWeight_ = new BoneWeight();
            for (int i = 0; i < _vertexMap.Length; i++)
            {
                int     idx = i;
                Vector3 tmp = _av3Vertices[idx];
                if (bUV1)
                {
                    tmpUV = _av2Mapping1In[idx];
                }
                if (bUV2)
                {
                    tmpUV2 = _av2Mapping2In[idx];
                }
                if (bNormal)
                {
                    tmpNormal = _av3NormalsIn[idx];
                }
                if (bTangent)
                {
                    tmpTangent = _av4TangentsIn[idx];
                }
                if (bColor32)
                {
                    tmpColor = _aColors32In[idx];
                }
                if (bBone)
                {
                    tmpBoneWeight = _aBoneWeights[idx];
                }
                while (_vertexMap[idx] != -1)
                {
                    Vector3 tmp_ = _av3Vertices[_vertexMap[idx]];
                    if (bUV1)
                    {
                        tmpUV_ = _av2Mapping1In[_vertexMap[idx]];
                    }
                    if (bUV2)
                    {
                        tmpUV2_ = _av2Mapping2In[_vertexMap[idx]];
                    }
                    if (bNormal)
                    {
                        tmpNormal_ = _av3NormalsIn[_vertexMap[idx]];
                    }
                    if (bTangent)
                    {
                        tmpTangent_ = _av4TangentsIn[_vertexMap[idx]];
                    }
                    if (bColor32)
                    {
                        tmpColor_ = _aColors32In[_vertexMap[idx]];
                    }
                    if (bBone)
                    {
                        tmpBoneWeight_ = _aBoneWeights[_vertexMap[idx]];
                    }
                    _av3Vertices[_vertexMap[idx]] = tmp;
                    if (bUV1)
                    {
                        _av2Mapping1In[_vertexMap[idx]] = tmpUV;
                    }
                    if (bUV2)
                    {
                        _av2Mapping2In[_vertexMap[idx]] = tmpUV2;
                    }
                    if (bNormal)
                    {
                        _av3NormalsIn[_vertexMap[idx]] = tmpNormal;
                    }
                    if (bTangent)
                    {
                        _av4TangentsIn[_vertexMap[idx]] = tmpTangent;
                    }
                    if (bColor32)
                    {
                        _aColors32In[_vertexMap[idx]] = tmpColor;
                    }
                    if (bBone)
                    {
                        _aBoneWeights[_vertexMap[idx]] = tmpBoneWeight;
                    }
                    tmp           = tmp_;
                    tmpUV         = tmpUV_;
                    tmpUV2        = tmpUV2_;
                    tmpNormal     = tmpNormal_;
                    tmpTangent    = tmpTangent_;
                    tmpColor      = tmpColor_;
                    tmpBoneWeight = tmpBoneWeight_;
                    int tmpI = _vertexMap[idx];
                    _vertexMap[idx] = -1;
                    idx             = tmpI;
                }
            }
#endif
            //#if DEBUG
            //                // Check
            //                for (int i = 0; i < n; i++)
            //                {
            //                    if (_vertexMap[i] != -1)
            //                    {
            //                        throw new Exception("");
            //                    }
            //                }
            //#endif

            this._meshOut = meshOut;

            _assignVertices = _assignVertices ?? (arr => this._meshOut.vertices = arr);
            if (bNormal)
            {
                _assignNormals = _assignNormals ?? (arr => this._meshOut.normals = arr);
            }
            if (bTangent)
            {
                _assignTangents = _assignTangents ?? (arr => this._meshOut.tangents = arr);
            }
            if (bUV1)
            {
                _assignUV = _assignUV ?? (arr => this._meshOut.uv = arr);
            }
            if (bUV2)
            {
                _assignUV2 = _assignUV2 ?? (arr => this._meshOut.uv2 = arr);
            }
            if (bColor32)
            {
                _assignColor32 = _assignColor32 ?? (arr => this._meshOut.colors32 = arr);
            }
            if (bBone)
            {
                _assignBoneWeights = _assignBoneWeights ?? (arr => this._meshOut.boneWeights = arr);
            }
            if (null == _setTriangles)
            {
                _setTriangles = new Action <int[]> [subMeshCount];
                for (int i = 0; i < subMeshCount; i++)
                {
                    int idx = i;
                    _setTriangles[i] = (arr => this._meshOut.SetTriangles(arr, idx));
                }
            }

            meshOut.triangles = null;
            // NOTE: 禁术
            UnsafeUtil.Vector3HackArraySizeCall(_av3Vertices, n, _assignVertices);
            if (bNormal)
            {
                UnsafeUtil.Vector3HackArraySizeCall(_av3NormalsIn, n, _assignNormals);
            }
            if (bTangent)
            {
                UnsafeUtil.Vector4HackArraySizeCall(_av4TangentsIn, n, _assignTangents);
            }
            if (bUV1)
            {
                UnsafeUtil.Vector2HackArraySizeCall(_av2Mapping1In, n, _assignUV);
            }
            if (bUV2)
            {
                UnsafeUtil.Vector2HackArraySizeCall(_av2Mapping2In, n, _assignUV2);
            }
            if (bColor32)
            {
                UnsafeUtil.Color32HackArraySizeCall(_aColors32In, n, _assignColor32);
            }
            if (bBone)
            {
                UnsafeUtil.BoneWeightHackArraySizeCall(_aBoneWeights, n, _assignBoneWeights);
            }
            if (bBone)
            {
                meshOut.bindposes = _aBindPoses;
            }
            meshOut.subMeshCount = _aSubMeshes.Length;

            for (int i = 0; i < subMeshCount; i++)
            {
                UnsafeUtil.IntegerHackArraySizeCall(_aSubMeshes[i], _aTriangleCount[i], _setTriangles[i]);
            }
            meshOut.UploadMeshData(false);
            //meshOut.name = gameObject.name + " simplified mesh";
        }