impl inplace MeshFreeze and MeshIntegration

This commit is contained in:
ousttrue
2023-10-27 16:18:07 +09:00
parent cd3d0573d6
commit 0f62aeffa1
8 changed files with 99 additions and 24 deletions

View File

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

View File

@@ -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<Transform, Transform> boneMap)
{
Func<Transform, Transform> 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<SkinnedMeshRenderer>();
var dstR = dst.GetComponent<SkinnedMeshRenderer>();
if (srcR != null && dstR != null)
{
srcR.sharedMesh = dstR.sharedMesh;
srcR.bones = dstR.bones.Select(x => getSrc(x)).ToArray();
}
}
}
}
}

View File

@@ -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<Mesh> Sources = new List<Mesh>();
public Mesh Integrated;
public Material[] SharedMaterials;
public Transform[] Bones;
}
public class MeshIntegrationResult
{
public List<SkinnedMeshRenderer> SourceSkinnedMeshRenderers = new List<SkinnedMeshRenderer>();
public List<MeshRenderer> SourceMeshRenderers = new List<MeshRenderer>();
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<SkinnedMeshRenderer>();
smr.sharedMesh = MeshMap.Integrated;
smr.sharedMaterials = MeshMap.SharedMaterials;
smr.bones = MeshMap.Bones;
IntegratedRenderer = smr;
}
public void DestroySourceRenderer()
{
throw new NotImplementedException();
}
}
}

View File

@@ -280,15 +280,8 @@ namespace UniGLTF.MeshUtility
}
mesh.name = name;
// meshName
var meshNode = new GameObject();
meshNode.name = name;
var integrated = meshNode.AddComponent<SkinnedMeshRenderer>();
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;
}

View File

@@ -190,7 +190,7 @@ namespace UniGLTF.MeshUtility
// Add integrated
foreach (var result in results)
{
result.IntegratedRenderer.transform.SetParent(copy.transform, false);
result.AddIntegratedRendererTo(copy);
}
}
}

View File

@@ -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<HumanBodyBones>()
.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;
}
}
}

View File

@@ -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;

View File

@@ -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<Animator>(), normalized, boneMap);
var newAnimator = normalized.GetOrAddComponent<Animator>();
newAnimator.avatar = newAvatar;
// TODO: write back normalized transform to boneMap
var animator = go.GetComponent<Animator>();
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);
}
}
}