public void ComputeUVNormalBlendData(object[] uvnbMeshIds, AnimatorEditor dstAnimatorEditor, UVNormalBlendMonoBehaviourEditor srcUVNBEditor, int srcUVNBMeshId, AnimatorEditor srcAnimatorEditor, object[] adjacentAnimatorEditorMeshIdPairs, double adjacentSquaredDistance, bool worldCoordinates)
        {
            foreach (double id in uvnbMeshIds)
            {
                UVNormalBlendMonoBehaviour.Data dstData = Datas[(int)id];
                dstData.baseNormals.Clear();
                dstData.blendNormals.Clear();
                dstData.baseUVs.Clear();
                dstData.blendUVs.Clear();

                int dstMeshRId = dstAnimatorEditor.GetMeshRendererId(dstData.rendererName);
                SkinnedMeshRenderer dstSMesh = (SkinnedMeshRenderer)dstAnimatorEditor.Meshes[dstMeshRId];
                dstData.renderer = new PPtr <MeshRenderer>(dstSMesh);
                Operations.vMesh          dstVMesh    = new Operations.vMesh(dstSMesh, false, false);
                List <Operations.vVertex> dstVertList = dstVMesh.submeshes[0].vertexList;
                for (int i = 1; i < dstVMesh.submeshes.Count; i++)
                {
                    dstVertList.AddRange(dstVMesh.submeshes[i].vertexList);
                }
                Transform meshTransform       = dstSMesh.m_GameObject.instance.FindLinkedComponent(typeof(Transform));
                Matrix    meshTransformMatrix = Transform.WorldTransform(meshTransform);
                foreach (var vert in dstVertList)
                {
                    vert.position = Vector3.TransformCoordinate(vert.position, meshTransformMatrix);
                }

                int srcMeshRId = srcAnimatorEditor.GetMeshRendererId(srcUVNBMeshId < 0 ? dstSMesh.m_GameObject.instance.m_Name : srcUVNBEditor.Datas[srcUVNBMeshId].rendererName);
                SkinnedMeshRenderer       srcSMesh    = (SkinnedMeshRenderer)srcAnimatorEditor.Meshes[srcMeshRId];
                Operations.vMesh          srcVMesh    = new Operations.vMesh(srcSMesh, false, false);
                List <Operations.vVertex> srcVertList = srcVMesh.submeshes[0].vertexList;
                for (int i = 1; i < srcVMesh.submeshes.Count; i++)
                {
                    srcVertList.AddRange(srcVMesh.submeshes[i].vertexList);
                }
                meshTransform       = srcSMesh.m_GameObject.instance.FindLinkedComponent(typeof(Transform));
                meshTransformMatrix = Transform.WorldTransform(meshTransform);
                foreach (var vert in srcVertList)
                {
                    vert.position = Vector3.TransformCoordinate(vert.position, meshTransformMatrix);
                }

                UVNormalBlendMonoBehaviour.Data srcData = srcUVNBMeshId < 0
                                        ? srcUVNBEditor.Datas.Find
                                                          (
                    delegate(UVNormalBlendMonoBehaviour.Data m)
                {
                    return(m.rendererName == dstSMesh.m_GameObject.instance.m_Name);
                }
                                                          )
                                        : srcUVNBEditor.Datas[srcUVNBMeshId];
                if (srcData == null)
                {
                    throw new Exception("Source UVNormalBlendMonoBehaviour.Data for " + dstSMesh.m_GameObject.instance.m_Name + " not found");
                }
                if (srcData.baseNormals.Count != srcVertList.Count)
                {
                    throw new Exception("Source UVNormalBlendMonoBehaviour.Data for " + dstSMesh.m_GameObject.instance.m_Name + " has " + srcData.baseNormals.Count + " normals, but the source mesh has " + srcVertList.Count + " vertices.");
                }

                for (int i = 0; i < dstVertList.Count; i++)
                {
                    var   vert       = dstVertList[i];
                    int   vertIdx    = -1;
                    float minDistPos = float.MaxValue;
                    float minDistUV  = float.MaxValue;
                    for (int j = 0; j < srcVertList.Count; j++)
                    {
                        var   srcVert    = srcVertList[j];
                        float distSquare = (vert.position - srcVert.position).LengthSquared();
                        if (distSquare < minDistPos)
                        {
                            vertIdx = j;
                            if ((minDistPos = distSquare) == 0)
                            {
                                distSquare = (new Vector2(vert.uv[0], vert.uv[1]) - new Vector2(srcVert.uv[0], srcVert.uv[1])).LengthSquared();
                                if (distSquare < minDistUV)
                                {
                                    if ((minDistUV = distSquare) == 0)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        else if (distSquare == minDistPos)
                        {
                            distSquare = (new Vector2(vert.uv[0], vert.uv[1]) - new Vector2(srcVert.uv[0], srcVert.uv[1])).LengthSquared();
                            if (distSquare < minDistUV)
                            {
                                vertIdx = j;
                                if ((minDistUV = distSquare) == 0)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    if (minDistUV == 0)
                    {
                        dstData.baseNormals.Add(srcData.baseNormals[vertIdx]);
                        dstData.blendNormals.Add(srcData.blendNormals[vertIdx]);
                        if (srcData.baseUVs.Count > 0)
                        {
                            dstData.baseUVs.Add(srcData.baseUVs[vertIdx]);
                            dstData.blendUVs.Add(srcData.blendUVs[vertIdx]);
                        }
                    }
                    else
                    {
                        if (srcData.baseNormals[vertIdx] == srcData.blendNormals[vertIdx])
                        {
                            dstData.baseNormals.Add(vert.normal);
                            dstData.blendNormals.Add(vert.normal);
                        }
                        else
                        {
                            dstData.baseNormals.Add(vert.normal + srcData.baseNormals[vertIdx] - srcVertList[vertIdx].normal);
                            dstData.blendNormals.Add(vert.normal + srcData.blendNormals[vertIdx] - srcVertList[vertIdx].normal);
                        }
                        if (srcData.baseUVs.Count > 0)
                        {
                            Vector2 mirroredDest = new Vector2(vert.uv[0], -vert.uv[1]);
                            Vector2 mirroredSrc  = new Vector2(srcVertList[vertIdx].uv[0], -srcVertList[vertIdx].uv[1]);
                            dstData.baseUVs.Add(mirroredDest + srcData.baseUVs[vertIdx] - mirroredSrc);
                            dstData.blendUVs.Add(mirroredDest + srcData.blendUVs[vertIdx] - mirroredSrc);
                        }
                    }
                }

                if (adjacentAnimatorEditorMeshIdPairs != null)
                {
                    HashSet <int>      dstVertIndices = new HashSet <int>();
                    Operations.vMesh[] adjVMeshes     = new Operations.vMesh[adjacentAnimatorEditorMeshIdPairs.Length / 2];
                    for (int i = 0; i < adjacentAnimatorEditorMeshIdPairs.Length / 2; i++)
                    {
                        MeshRenderer adjMeshR = (MeshRenderer)((AnimatorEditor)adjacentAnimatorEditorMeshIdPairs[i * 2]).Meshes[(int)(double)adjacentAnimatorEditorMeshIdPairs[i * 2 + 1]];
                        Matrix       worldTransform;
                        if (worldCoordinates)
                        {
                            meshTransform  = adjMeshR.m_GameObject.instance.FindLinkedComponent(typeof(Transform));
                            worldTransform = Transform.WorldTransform(meshTransform);
                        }
                        else
                        {
                            worldTransform = Matrix.Identity;
                        }
                        Operations.vMesh adjVMesh = new Operations.vMesh(adjMeshR, false, false);
                        int adjVertsAdapted       = 0;
                        foreach (var adjSubmesh in adjVMesh.submeshes)
                        {
                            foreach (var adjVert in adjSubmesh.vertexList)
                            {
                                Vector3 adjPos = worldCoordinates
                                                                        ? Vector3.TransformCoordinate(adjVert.position, worldTransform)
                                                                        : adjVert.position;
                                for (int j = 0; j < dstVertList.Count; j++)
                                {
                                    var dstVert = dstVertList[j];
                                    if ((adjPos - dstVert.position).LengthSquared() < adjacentSquaredDistance)
                                    {
                                        if (dstVertIndices.Add(j))
                                        {
                                            dstData.baseNormals[j] = dstData.blendNormals[j] = (dstData.baseNormals[j] + dstData.blendNormals[j]) / 2;
                                        }
                                        adjVert.normal = dstData.baseNormals[j];
                                        adjVertsAdapted++;
                                        break;
                                    }
                                }
                            }
                        }
                        if (adjVertsAdapted > 0)
                        {
                            adjVMeshes[i] = adjVMesh;
                            Report.ReportLog("Adjacent MeshRenderer " + adjMeshR.m_GameObject.instance.m_Name + " has " + adjVertsAdapted + " verts smaller squared distance than " + ((float)adjacentSquaredDistance).ToFloatString());
                        }
                    }

                    for (int i = 0; i < adjVMeshes.Length; i++)
                    {
                        var adjVMesh = adjVMeshes[i];
                        if (adjVMesh != null)
                        {
                            adjVMesh.Flush();
                            ((AnimatorEditor)adjacentAnimatorEditorMeshIdPairs[i * 2]).Changed = true;
                        }
                    }
                }
            }

            Parser.datas = Datas;

            Changed = true;
        }
        public void ComputeUVNormalBlendData(object[] uvnbMeshIds, AnimatorEditor dstAnimatorEditor, UVNormalBlendMonoBehaviour srcUVNBParser, int srcUVNBMeshId, AnimatorEditor srcAnimatorEditor, object[] adjacentAnimatorEditorMeshIdPairs, double adjacentSquaredDistance, bool worldCoordinates)
        {
            UVNormalBlendMonoBehaviourEditor srcUVNBEditor = new UVNormalBlendMonoBehaviourEditor(srcUVNBParser);

            ComputeUVNormalBlendData(uvnbMeshIds, dstAnimatorEditor, srcUVNBEditor, srcUVNBMeshId, srcAnimatorEditor, adjacentAnimatorEditorMeshIdPairs, adjacentSquaredDistance, worldCoordinates);
        }