diff --git a/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs b/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs index 847773adb..923980b26 100644 --- a/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs @@ -90,7 +90,7 @@ namespace UniGLTF.MeshUtility // write mesh asset. foreach (var result in results) { - var mesh = result.IntegratedRenderer.sharedMesh; + var mesh = result.MeshMap.Integrated; var assetPath = GetMeshWritePath(mesh); Debug.LogFormat("CreateAsset: {0}", assetPath); AssetDatabase.CreateAsset(mesh, assetPath); diff --git a/Assets/UniGLTF/Runtime/MeshUtility/BoneNormalizer.cs b/Assets/UniGLTF/Runtime/MeshUtility/BoneNormalizer.cs index bde593ee6..40981e773 100644 --- a/Assets/UniGLTF/Runtime/MeshUtility/BoneNormalizer.cs +++ b/Assets/UniGLTF/Runtime/MeshUtility/BoneNormalizer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using UnityEngine; @@ -144,5 +145,33 @@ namespace UniGLTF.MeshUtility return (normalized, boneMap); } + + public static void WriteBackResult(GameObject go, GameObject normalized, Dictionary boneMap) + { + Func getSrc = dst => + { + foreach (var (k, v) in boneMap) + { + if (v == dst) + { + return k; + } + } + throw new NotImplementedException(); + }; + foreach (var (src, dst) in boneMap) + { + src.localPosition = dst.localPosition; + src.localRotation = dst.localRotation; + src.localScale = dst.localScale; + var srcR = src.GetComponent(); + var dstR = dst.GetComponent(); + if (srcR != null && dstR != null) + { + srcR.sharedMesh = dstR.sharedMesh; + srcR.bones = dstR.bones.Select(x => getSrc(x)).ToArray(); + } + } + } } } diff --git a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationResult.cs b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationResult.cs index 50e0d3679..e5f8652c5 100644 --- a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationResult.cs +++ b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationResult.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using UnityEngine; namespace UniGLTF.MeshUtility @@ -8,14 +9,32 @@ namespace UniGLTF.MeshUtility { public List Sources = new List(); public Mesh Integrated; + public Material[] SharedMaterials; + public Transform[] Bones; } public class MeshIntegrationResult { public List SourceSkinnedMeshRenderers = new List(); public List SourceMeshRenderers = new List(); + public MeshMap MeshMap = new MeshMap(); public SkinnedMeshRenderer IntegratedRenderer; - public MeshMap MeshMap = new MeshMap(); + public void AddIntegratedRendererTo(GameObject parent) + { + var go = new GameObject(MeshMap.Integrated.name); + go.transform.SetParent(parent.transform, false); + var smr = go.AddComponent(); + smr.sharedMesh = MeshMap.Integrated; + smr.sharedMaterials = MeshMap.SharedMaterials; + smr.bones = MeshMap.Bones; + + IntegratedRenderer = smr; + } + + public void DestroySourceRenderer() + { + throw new NotImplementedException(); + } } } diff --git a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrator.cs b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrator.cs index 28b2e7f6b..92f12760d 100644 --- a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrator.cs +++ b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrator.cs @@ -280,15 +280,8 @@ namespace UniGLTF.MeshUtility } mesh.name = name; - // meshName - var meshNode = new GameObject(); - meshNode.name = name; - - var integrated = meshNode.AddComponent(); - integrated.sharedMesh = mesh; - integrated.sharedMaterials = SubMeshes.Select(x => x.Material).ToArray(); - integrated.bones = Bones.ToArray(); - Result.IntegratedRenderer = integrated; + Result.MeshMap.SharedMaterials = SubMeshes.Select(x => x.Material).ToArray(); + Result.MeshMap.Bones = Bones.ToArray(); Result.MeshMap.Integrated = mesh; return Result; } diff --git a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs index 68970c2c3..1478c8494 100644 --- a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs +++ b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs @@ -190,7 +190,7 @@ namespace UniGLTF.MeshUtility // Add integrated foreach (var result in results) { - result.IntegratedRenderer.transform.SetParent(copy.transform, false); + result.AddIntegratedRendererTo(copy); } } } diff --git a/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs b/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs index 23a91c19b..c4224252c 100644 --- a/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs +++ b/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs @@ -306,5 +306,30 @@ namespace UniHumanoid avatar.name = "created"; return avatar; } + + public static Avatar RecreateAvatar(Animator src) + { + if (src == null) + { + throw new ArgumentNullException("src"); + } + + var srcHumanBones = CachedEnum.GetValues() + .Where(x => x != HumanBodyBones.LastBone) + .Select(x => new { Key = x, Value = src.GetBoneTransform(x) }) + .Where(x => x.Value != null) + ; + + var map = + srcHumanBones + .ToDictionary(x => x.Key, x => x.Value) + ; + + var avatarDescription = UniHumanoid.AvatarDescription.Create(); + avatarDescription.SetHumanBones(map); + var avatar = avatarDescription.CreateAvatar(src.transform); + avatar.name = "created"; + return avatar; + } } } \ No newline at end of file diff --git a/Assets/VRM/Editor/SkinnedMeshUtility/VRMMeshIntegratorUtility.cs b/Assets/VRM/Editor/SkinnedMeshUtility/VRMMeshIntegratorUtility.cs index af74ab1bd..480f8b04c 100644 --- a/Assets/VRM/Editor/SkinnedMeshUtility/VRMMeshIntegratorUtility.cs +++ b/Assets/VRM/Editor/SkinnedMeshUtility/VRMMeshIntegratorUtility.cs @@ -21,7 +21,7 @@ namespace VRM { return clips; } - var result = results.FirstOrDefault(x => x.IntegratedRenderer.sharedMesh.blendShapeCount > 0); + var result = results.FirstOrDefault(x => x.MeshMap.Integrated.blendShapeCount > 0); if (result == null) { return clips; diff --git a/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs b/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs index 4e6279b00..639c48920 100644 --- a/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs +++ b/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.WebSockets; using UniGLTF.MeshUtility; using UniHumanoid; using UnityEngine; +using VrmLib; namespace UniVRM10 { @@ -135,31 +137,38 @@ namespace UniVRM10 // TODO: update: spring // TODO: update: constraint // TODO: update: firstPoint offset + // write back normalized transform to boneMap + BoneNormalizer.WriteBackResult(go, normalized, boneMap); + if (Application.isPlaying) + { + GameObject.Destroy(normalized); + } + else + { + GameObject.DestroyImmediate(normalized); + } - var newAvatar = AvatarDescription.CreateAvatarForCopyHierarchy(go.GetComponent(), normalized, boneMap); - var newAnimator = normalized.GetOrAddComponent(); - newAnimator.avatar = newAvatar; - - // TODO: write back normalized transform to boneMap + var animator = go.GetComponent(); + var newAvatar = AvatarDescription.RecreateAvatar(animator); + animator.avatar = newAvatar; // TODO: integration foreach (var group in MeshIntegrationGroups) { - var newMesh = MeshIntegrator.Integrate(group, true); + var result = MeshIntegrator.Integrate(group, true); // TODO: firstperson // TODO: split if (SplitByBlendShape) { // var withBlendShape, withoutBlendShape - // TODO: remove old renderer - // TODO: add new renderer to root } else { - // TODO: remove old renderer - // TODO: add new renderer to root } + + // TODO: remove old renderer + result.AddIntegratedRendererTo(go); } } }