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); }