public void CopyUVs(int id, bool baseOrBlend, bool setOrGet) { UVNormalBlendMonoBehaviour.Data dstData = Datas[(int)id]; MeshRenderer mr = dstData.renderer.instance; Operations.vMesh m = new Operations.vMesh(mr, false, false); List <Vector2> uvs = baseOrBlend ? dstData.blendUVs : dstData.baseUVs; if (setOrGet) { for (int i = 0; i < m.submeshes.Count; i++) { Operations.vSubmesh s = m.submeshes[i]; for (int j = 0; j < s.vertexList.Count; j++) { s.vertexList[j].uv[0] = uvs[j][0]; s.vertexList[j].uv[1] = -uvs[j][1]; } } m.Flush(); } else { uvs.Clear(); for (int i = 0; i < m.submeshes.Count; i++) { Operations.vSubmesh s = m.submeshes[i]; for (int j = 0; j < s.vertexList.Count; j++) { Vector2 uv = new Vector2(s.vertexList[j].uv[0], -s.vertexList[j].uv[1]); uvs.Add(uv); } } Parser.datas = Datas; } Changed = true; }
public void CopyNormals(int id, AnimatorEditor dstAnimatorEditor, bool minOrMax, bool setOrGet) { GenericMono dstData = GenericMonos[(int)id]; int dstMeshRId = dstAnimatorEditor.GetMeshRendererId(dstData.ObjectName); MeshRenderer mr = (MeshRenderer)dstAnimatorEditor.Meshes[dstMeshRId]; Operations.vMesh m = new Operations.vMesh(mr, false, false); List <Vector3> normals = minOrMax ? dstData.NormalMax : dstData.NormalMin; if (setOrGet) { for (int i = 0; i < m.submeshes.Count; i++) { Operations.vSubmesh s = m.submeshes[i]; for (int j = 0; j < s.vertexList.Count; j++) { s.vertexList[j].normal = normals[j]; } } m.Flush(); } else { normals.Clear(); for (int i = 0; i < m.submeshes.Count; i++) { Operations.vSubmesh s = m.submeshes[i]; for (int j = 0; j < s.vertexList.Count; j++) { normals.Add(s.vertexList[j].normal); } } Parser.Param = GenericMonos; } Changed = true; }
public void CopyNormals(int id, bool baseOrBlend, bool setOrGet) { UVNormalBlendMonoBehaviour.Data dstData = Datas[(int)id]; MeshRenderer mr = dstData.renderer.instance; Operations.vMesh m = new Operations.vMesh(mr, false, false); List <Vector3> normals = baseOrBlend ? dstData.blendNormals : dstData.baseNormals; if (setOrGet) { for (int i = 0; i < m.submeshes.Count; i++) { Operations.vSubmesh s = m.submeshes[i]; for (int j = 0; j < s.vertexList.Count; j++) { s.vertexList[j].normal = normals[j]; } } m.Flush(); } else { normals.Clear(); for (int i = 0; i < m.submeshes.Count; i++) { Operations.vSubmesh s = m.submeshes[i]; for (int j = 0; j < s.vertexList.Count; j++) { normals.Add(s.vertexList[j].normal); } } Parser.datas = Datas; } Changed = true; }
public static void ReplaceMeshRenderer(Transform frame, Transform rootBone, Animator parser, List <Material> materials, WorkspaceMesh mesh, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool targetFullMesh) { Matrix transform = Transform.WorldTransform(frame); int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; SkinnedMeshRenderer sMesh = CreateSkinnedMeshRenderer(parser, materials, mesh, transform, out indices, out worldCoords, out replaceSubmeshesOption); vMesh destMesh = new Operations.vMesh(sMesh, true, false); SkinnedMeshRenderer sFrameMesh = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.SkinnedMeshRenderer); MeshRenderer frameMeshR = sFrameMesh; if (sFrameMesh == null) { frameMeshR = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.MeshRenderer); } Mesh frameMesh = frameMeshR != null?Operations.GetMesh(frameMeshR) : null; vMesh srcMesh = null; List <vVertex> allVertices = null; if (frameMeshR == null || frameMesh == null) { sMesh.m_RootBone = new PPtr <Transform>(rootBone); if (rootBone != null) { sMesh.m_Mesh.instance.m_RootBoneNameHash = parser.m_Avatar.instance.BoneHash(rootBone.m_GameObject.instance.m_Name); } if (frameMeshR != null) { CopyUnknowns(frameMeshR, sMesh); } } else { if (sFrameMesh != null) { sMesh.m_RootBone = new PPtr <Transform>(sFrameMesh.m_RootBone.instance); sMesh.m_Mesh.instance.m_RootBoneNameHash = frameMesh.m_RootBoneNameHash; } else { sMesh.m_RootBone = new PPtr <Transform>((Component)null); } srcMesh = new Operations.vMesh(frameMeshR, true, false); CopyUnknowns(frameMeshR, sMesh); if (targetFullMesh && (normalsMethod == CopyMeshMethod.CopyNear || bonesMethod == CopyMeshMethod.CopyNear)) { allVertices = new List <vVertex>(); HashSet <Vector3> posSet = new HashSet <Vector3>(); foreach (vSubmesh submesh in srcMesh.submeshes) { allVertices.Capacity = allVertices.Count + submesh.vertexList.Count; foreach (vVertex vertex in submesh.vertexList) { if (!posSet.Contains(vertex.position)) { posSet.Add(vertex.position); allVertices.Add(vertex); } } } } } transform.Invert(); vSubmesh[] replaceSubmeshes = (srcMesh == null) ? null : new vSubmesh[srcMesh.submeshes.Count]; List <vSubmesh> addSubmeshes = new List <vSubmesh>(destMesh.submeshes.Count); for (int i = 0; i < destMesh.submeshes.Count; i++) { vSubmesh submesh = destMesh.submeshes[i]; List <vVertex> vVertexList = submesh.vertexList; if (worldCoords[i]) { for (int j = 0; j < vVertexList.Count; j++) { vVertexList[j].position = Vector3.TransformCoordinate(vVertexList[j].position, transform); } } vSubmesh baseSubmesh = null; int idx = indices[i]; if ((srcMesh != null) && (idx >= 0) && (idx < frameMesh.m_SubMeshes.Count)) { baseSubmesh = srcMesh.submeshes[idx]; CopyUnknowns(frameMesh.m_SubMeshes[idx], sMesh.m_Mesh.instance.m_SubMeshes[i]); } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { Operations.CopyNormalsOrder(baseSubmesh.vertexList, submesh.vertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { Operations.CopyNormalsNear(targetFullMesh ? allVertices : baseSubmesh.vertexList, submesh.vertexList); } if (baseSubmesh.vertexList[0].weights != null) { if (bonesMethod == CopyMeshMethod.CopyOrder) { Operations.CopyBonesOrder(baseSubmesh.vertexList, submesh.vertexList); } else if (bonesMethod == CopyMeshMethod.CopyNear) { Operations.CopyBonesNear(targetFullMesh ? allVertices : baseSubmesh.vertexList, submesh.vertexList); } } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = submesh; } else { addSubmeshes.Add(submesh); } } if ((srcMesh != null) && merge) { destMesh.submeshes = new List <vSubmesh>(replaceSubmeshes.Length + addSubmeshes.Count); List <vSubmesh> copiedSubmeshes = new List <vSubmesh>(replaceSubmeshes.Length); for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { vSubmesh srcSubmesh = srcMesh.submeshes[i]; copiedSubmeshes.Add(srcSubmesh); destMesh.submeshes.Add(srcSubmesh); } else { destMesh.submeshes.Add(replaceSubmeshes[i]); } } destMesh.submeshes.AddRange(addSubmeshes); if ((sFrameMesh == null || sFrameMesh.m_Bones.Count == 0) && (sMesh.m_Bones.Count > 0)) { for (int i = 0; i < copiedSubmeshes.Count; i++) { List <vVertex> vertexList = copiedSubmeshes[i].vertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].boneIndices = new int[4] { 0, 0, 0, 0 }; vertexList[j].weights = new float[4] { 0, 0, 0, 0 }; } } } else if (sFrameMesh != null && sFrameMesh.m_Bones.Count > 0) { int[] boneIdxMap; sMesh.m_Bones = MergeBoneList(sFrameMesh.m_Bones, sMesh.m_Bones, out boneIdxMap); uint[] boneHashes = new uint[sMesh.m_Bones.Count]; Matrix[] poseMatrices = new Matrix[sMesh.m_Bones.Count]; for (int i = 0; i < sFrameMesh.m_Bones.Count; i++) { boneHashes[i] = sFrameMesh.m_Mesh.instance.m_BoneNameHashes[i]; poseMatrices[i] = sFrameMesh.m_Mesh.instance.m_BindPose[i]; } for (int i = 0; i < boneIdxMap.Length; i++) { boneHashes[boneIdxMap[i]] = sMesh.m_Mesh.instance.m_BoneNameHashes[i]; poseMatrices[boneIdxMap[i]] = sMesh.m_Mesh.instance.m_BindPose[i]; } sMesh.m_Mesh.instance.m_BoneNameHashes.Clear(); sMesh.m_Mesh.instance.m_BoneNameHashes.AddRange(boneHashes); sMesh.m_Mesh.instance.m_BindPose.Clear(); sMesh.m_Mesh.instance.m_BindPose.AddRange(poseMatrices); if (bonesMethod == CopyMeshMethod.Replace) { for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] != null) { List <vVertex> vertexList = replaceSubmeshes[i].vertexList; if (vertexList[0].boneIndices != null) { for (int j = 0; j < vertexList.Count; j++) { int[] boneIndices = vertexList[j].boneIndices; vertexList[j].boneIndices = new int[4]; for (int k = 0; k < 4; k++) { vertexList[j].boneIndices[k] = boneIdxMap[boneIndices[k]]; } } } } } for (int i = 0; i < addSubmeshes.Count; i++) { List <vVertex> vertexList = addSubmeshes[i].vertexList; if (vertexList[0].boneIndices != null) { for (int j = 0; j < vertexList.Count; j++) { int[] boneIndices = vertexList[j].boneIndices; vertexList[j].boneIndices = new int[4]; for (int k = 0; k < 4; k++) { vertexList[j].boneIndices[k] = boneIdxMap[boneIndices[k]]; } } } } } } } destMesh.Flush(); if (frameMeshR != null) { frame.m_GameObject.instance.RemoveLinkedComponent(frameMeshR); //parser.file.RemoveSubfile(frameMeshR); if (frameMesh != null) { //parser.file.RemoveSubfile(frameMesh); parser.file.ReplaceSubfile(frameMesh, sMesh.m_Mesh.asset); } parser.file.ReplaceSubfile(frameMeshR, sMesh); } frame.m_GameObject.instance.AddLinkedComponent(sMesh); AssetBundle bundle = parser.file.Bundle; if (bundle != null) { if (frameMeshR != null) { if (frameMesh != null) { bundle.ReplaceComponent(frameMesh, sMesh.m_Mesh.asset); } bundle.ReplaceComponent(frameMeshR, sMesh); } else { bundle.RegisterForUpdate(parser.m_GameObject.asset); } } }
public static void ReplaceMeshRenderer(Transform frame, Transform rootBone, Animator parser, List<Material> materials, WorkspaceMesh mesh, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool targetFullMesh) { Matrix transform = Transform.WorldTransform(frame); int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; SkinnedMeshRenderer sMesh = CreateSkinnedMeshRenderer(parser, materials, mesh, transform, out indices, out worldCoords, out replaceSubmeshesOption); vMesh destMesh = new Operations.vMesh(sMesh, true, false); SkinnedMeshRenderer sFrameMesh = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.SkinnedMeshRenderer); MeshRenderer frameMeshR = sFrameMesh; if (sFrameMesh == null) { frameMeshR = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.MeshRenderer); } Mesh frameMesh = frameMeshR != null ? Operations.GetMesh(frameMeshR) : null; vMesh srcMesh = null; List<vVertex> allVertices = null; if (frameMeshR == null || frameMesh == null) { sMesh.m_RootBone = new PPtr<Transform>(rootBone); if (rootBone != null) { sMesh.m_Mesh.instance.m_RootBoneNameHash = parser.m_Avatar.instance.BoneHash(rootBone.m_GameObject.instance.m_Name); } if (frameMeshR != null) { CopyUnknowns(frameMeshR, sMesh); } } else { if (sFrameMesh != null) { sMesh.m_RootBone = new PPtr<Transform>(sFrameMesh.m_RootBone.instance); sMesh.m_Mesh.instance.m_RootBoneNameHash = frameMesh.m_RootBoneNameHash; } else { sMesh.m_RootBone = new PPtr<Transform>((Component)null); } srcMesh = new Operations.vMesh(frameMeshR, true, false); CopyUnknowns(frameMeshR, sMesh); if (targetFullMesh && (normalsMethod == CopyMeshMethod.CopyNear || bonesMethod == CopyMeshMethod.CopyNear)) { allVertices = new List<vVertex>(); HashSet<Vector3> posSet = new HashSet<Vector3>(); foreach (vSubmesh submesh in srcMesh.submeshes) { allVertices.Capacity = allVertices.Count + submesh.vertexList.Count; foreach (vVertex vertex in submesh.vertexList) { if (!posSet.Contains(vertex.position)) { posSet.Add(vertex.position); allVertices.Add(vertex); } } } } } transform.Invert(); vSubmesh[] replaceSubmeshes = (srcMesh == null) ? null : new vSubmesh[srcMesh.submeshes.Count]; List<vSubmesh> addSubmeshes = new List<vSubmesh>(destMesh.submeshes.Count); for (int i = 0; i < destMesh.submeshes.Count; i++) { vSubmesh submesh = destMesh.submeshes[i]; List<vVertex> vVertexList = submesh.vertexList; if (worldCoords[i]) { for (int j = 0; j < vVertexList.Count; j++) { vVertexList[j].position = Vector3.TransformCoordinate(vVertexList[j].position, transform); } } vSubmesh baseSubmesh = null; int idx = indices[i]; if ((srcMesh != null) && (idx >= 0) && (idx < frameMesh.m_SubMeshes.Count)) { baseSubmesh = srcMesh.submeshes[idx]; CopyUnknowns(frameMesh.m_SubMeshes[idx], sMesh.m_Mesh.instance.m_SubMeshes[i]); } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { Operations.CopyNormalsOrder(baseSubmesh.vertexList, submesh.vertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { Operations.CopyNormalsNear(targetFullMesh ? allVertices : baseSubmesh.vertexList, submesh.vertexList); } if (baseSubmesh.vertexList[0].weights != null) { if (bonesMethod == CopyMeshMethod.CopyOrder) { Operations.CopyBonesOrder(baseSubmesh.vertexList, submesh.vertexList); } else if (bonesMethod == CopyMeshMethod.CopyNear) { Operations.CopyBonesNear(targetFullMesh ? allVertices : baseSubmesh.vertexList, submesh.vertexList); } } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = submesh; } else { addSubmeshes.Add(submesh); } } if ((srcMesh != null) && merge) { destMesh.submeshes = new List<vSubmesh>(replaceSubmeshes.Length + addSubmeshes.Count); List<vSubmesh> copiedSubmeshes = new List<vSubmesh>(replaceSubmeshes.Length); for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { vSubmesh srcSubmesh = srcMesh.submeshes[i]; copiedSubmeshes.Add(srcSubmesh); destMesh.submeshes.Add(srcSubmesh); } else { destMesh.submeshes.Add(replaceSubmeshes[i]); } } destMesh.submeshes.AddRange(addSubmeshes); if ((sFrameMesh == null || sFrameMesh.m_Bones.Count == 0) && (sMesh.m_Bones.Count > 0)) { for (int i = 0; i < copiedSubmeshes.Count; i++) { List<vVertex> vertexList = copiedSubmeshes[i].vertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].boneIndices = new int[4] { 0, 0, 0, 0 }; vertexList[j].weights = new float[4] { 0, 0, 0, 0 }; } } } else if (sFrameMesh != null && sFrameMesh.m_Bones.Count > 0) { int[] boneIdxMap; sMesh.m_Bones = MergeBoneList(sFrameMesh.m_Bones, sMesh.m_Bones, out boneIdxMap); uint[] boneHashes = new uint[sMesh.m_Bones.Count]; Matrix[] poseMatrices = new Matrix[sMesh.m_Bones.Count]; for (int i = 0; i < sFrameMesh.m_Bones.Count; i++) { boneHashes[i] = sFrameMesh.m_Mesh.instance.m_BoneNameHashes[i]; poseMatrices[i] = sFrameMesh.m_Mesh.instance.m_BindPose[i]; } for (int i = 0; i < boneIdxMap.Length; i++) { boneHashes[boneIdxMap[i]] = sMesh.m_Mesh.instance.m_BoneNameHashes[i]; poseMatrices[boneIdxMap[i]] = sMesh.m_Mesh.instance.m_BindPose[i]; } sMesh.m_Mesh.instance.m_BoneNameHashes.Clear(); sMesh.m_Mesh.instance.m_BoneNameHashes.AddRange(boneHashes); sMesh.m_Mesh.instance.m_BindPose.Clear(); sMesh.m_Mesh.instance.m_BindPose.AddRange(poseMatrices); if (bonesMethod == CopyMeshMethod.Replace) { for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] != null) { List<vVertex> vertexList = replaceSubmeshes[i].vertexList; if (vertexList[0].boneIndices != null) { for (int j = 0; j < vertexList.Count; j++) { int[] boneIndices = vertexList[j].boneIndices; vertexList[j].boneIndices = new int[4]; for (int k = 0; k < 4; k++) { vertexList[j].boneIndices[k] = boneIdxMap[boneIndices[k]]; } } } } } for (int i = 0; i < addSubmeshes.Count; i++) { List<vVertex> vertexList = addSubmeshes[i].vertexList; if (vertexList[0].boneIndices != null) { for (int j = 0; j < vertexList.Count; j++) { int[] boneIndices = vertexList[j].boneIndices; vertexList[j].boneIndices = new int[4]; for (int k = 0; k < 4; k++) { vertexList[j].boneIndices[k] = boneIdxMap[boneIndices[k]]; } } } } } } } destMesh.Flush(); if (frameMeshR != null) { frame.m_GameObject.instance.RemoveLinkedComponent(frameMeshR); //parser.file.RemoveSubfile(frameMeshR); if (frameMesh != null) { //parser.file.RemoveSubfile(frameMesh); parser.file.ReplaceSubfile(frameMesh, sMesh.m_Mesh.asset); } parser.file.ReplaceSubfile(frameMeshR, sMesh); } frame.m_GameObject.instance.AddLinkedComponent(sMesh); AssetBundle bundle = parser.file.Bundle; if (bundle != null) { if (frameMeshR != null) { if (frameMesh != null) { bundle.ReplaceComponent(frameMesh, sMesh.m_Mesh.asset); } bundle.ReplaceComponent(frameMeshR, sMesh); } else { bundle.RegisterForUpdate(parser.m_GameObject.asset); } } }
public void RemoveSubMesh(int meshId, int subMeshId) { MeshRenderer meshR = Meshes[meshId]; Mesh mesh = Operations.GetMesh(meshR); if (mesh.m_SubMeshes.Count == 1 && subMeshId == 0) { Operations.SetMeshPtr(meshR, null); Parser.file.RemoveSubfile(mesh); if (Parser.file.Bundle != null) { Parser.file.Bundle.DeleteComponent(mesh); } } else { Operations.vMesh vMesh = new Operations.vMesh(meshR, true, false); vMesh.submeshes.RemoveAt(subMeshId); vMesh.Flush(); } if (Parser.file.Bundle != null) { Parser.file.Bundle.RegisterForUpdate(meshR); } Changed = true; }
public void RemoveBone(int meshId, int boneId) { SkinnedMeshRenderer smr = (SkinnedMeshRenderer)Meshes[meshId]; Mesh mesh = smr.m_Mesh.instance; if (mesh != null) { Operations.vMesh vMesh = new Operations.vMesh(smr, false, false); Transform boneFrame = smr.m_Bones[boneId].instance; int parentBoneIdx = -1; if (boneFrame != null) { Transform parentFrame = boneFrame.Parent; parentBoneIdx = Operations.FindBoneIndex(smr.m_Bones, parentFrame); } smr.m_Bones.RemoveAt(boneId); mesh.m_BindPose.RemoveAt(boneId); mesh.m_BoneNameHashes.RemoveAt(boneId); foreach (Operations.vSubmesh submesh in vMesh.submeshes) { foreach (Operations.vVertex vertex in submesh.vertexList) { for (int i = 0; i < vertex.boneIndices.Length; i++) { int boneIdx = vertex.boneIndices[i]; if (boneIdx == boneId) { float[] w4 = vertex.weights; for (int j = i + 1; j < vertex.boneIndices.Length; j++) { vertex.boneIndices[j - 1] = vertex.boneIndices[j]; vertex.weights[j - 1] = w4[j]; } vertex.boneIndices[vertex.boneIndices.Length - 1] = -1; w4 = vertex.weights; float normalize = 1f / (w4[0] + w4[1] + w4[2] + w4[3]); if (w4[3] != 1f) { for (int j = 0; vertex.boneIndices[j] != -1; j++) { vertex.weights[j] *= normalize; } } else if (parentBoneIdx >= 0) { vertex.boneIndices[0] = parentBoneIdx; vertex.weights[0] = 1f; } i--; } else if (boneIdx != -1 && boneIdx > boneId) { vertex.boneIndices[i]--; } } } } vMesh.Flush(); } }
public void MirrorV(int meshId) { MeshRenderer meshR = Meshes[meshId]; Operations.vMesh vMesh = new Operations.vMesh(meshR, true, false); foreach (Operations.vSubmesh submesh in vMesh.submeshes) { foreach (Operations.vVertex vert in submesh.vertexList) { vert.uv.Y *= -1; } } vMesh.Flush(); Changed = true; }