mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-14 22:50:08 -05:00
Merge pull request #2180 from ousttrue/fix/refactor_mesh_integration
[vrm1.0] impl refactor mesh integration
This commit is contained in:
commit
e896c6c91b
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationGroup.cs
Normal file
15
Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationGroup.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF.MeshUtility
|
||||
{
|
||||
public class MeshIntegrationGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// FirstPerson flag
|
||||
/// TODO: enum
|
||||
/// </summary>
|
||||
public string Name;
|
||||
public List<Renderer> Renderers = new List<Renderer>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ae366b97d8d020245bbdb5d25df09314
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ namespace UniGLTF.MeshUtility
|
|||
{
|
||||
public class MeshIntegrator
|
||||
{
|
||||
public const string INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME = "Integrated(WithoutBlendShape)";
|
||||
public const string INTEGRATED_MESH_WITH_BLENDSHAPE_NAME = "Integrated(WithBlendShape)";
|
||||
public const string INTEGRATED_MESH_ALL_NAME = "Integrated(All)";
|
||||
private MeshIntegrator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct SubMesh
|
||||
{
|
||||
|
|
@ -81,7 +82,7 @@ namespace UniGLTF.MeshUtility
|
|||
return bw;
|
||||
}
|
||||
|
||||
public void Push(MeshRenderer renderer)
|
||||
void Push(MeshRenderer renderer)
|
||||
{
|
||||
var meshFilter = renderer.GetComponent<MeshFilter>();
|
||||
if (meshFilter == null)
|
||||
|
|
@ -232,7 +233,24 @@ namespace UniGLTF.MeshUtility
|
|||
}
|
||||
}
|
||||
|
||||
public MeshIntegrationResult Integrate(MeshEnumerateOption onlyBlendShapeRenderers)
|
||||
public static MeshIntegrationResult Integrate(MeshIntegrationGroup group, bool useBlendShape)
|
||||
{
|
||||
var integrator = new MeshUtility.MeshIntegrator();
|
||||
foreach (var x in group.Renderers)
|
||||
{
|
||||
if (x is SkinnedMeshRenderer smr)
|
||||
{
|
||||
integrator.Push(smr);
|
||||
}
|
||||
else if (x is MeshRenderer mr)
|
||||
{
|
||||
integrator.Push(mr);
|
||||
}
|
||||
}
|
||||
return integrator.Integrate(group.Name, useBlendShape);
|
||||
}
|
||||
|
||||
public MeshIntegrationResult Integrate(string name, bool useBlendShape)
|
||||
{
|
||||
var mesh = new Mesh();
|
||||
|
||||
|
|
@ -253,57 +271,14 @@ namespace UniGLTF.MeshUtility
|
|||
mesh.SetIndices(SubMeshes[i].Indices.ToArray(), MeshTopology.Triangles, i);
|
||||
}
|
||||
mesh.bindposes = BindPoses.ToArray();
|
||||
|
||||
// blendshape
|
||||
switch (onlyBlendShapeRenderers)
|
||||
if (useBlendShape)
|
||||
{
|
||||
case MeshEnumerateOption.OnlyWithBlendShape:
|
||||
{
|
||||
AddBlendShapesToMesh(mesh);
|
||||
mesh.name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME;
|
||||
break;
|
||||
}
|
||||
|
||||
case MeshEnumerateOption.All:
|
||||
{
|
||||
AddBlendShapesToMesh(mesh);
|
||||
mesh.name = INTEGRATED_MESH_ALL_NAME;
|
||||
break;
|
||||
}
|
||||
|
||||
case MeshEnumerateOption.OnlyWithoutBlendShape:
|
||||
{
|
||||
mesh.name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME;
|
||||
break;
|
||||
}
|
||||
AddBlendShapesToMesh(mesh);
|
||||
}
|
||||
mesh.name = name;
|
||||
|
||||
// meshName
|
||||
var meshNode = new GameObject();
|
||||
switch (onlyBlendShapeRenderers)
|
||||
{
|
||||
case MeshEnumerateOption.OnlyWithBlendShape:
|
||||
{
|
||||
meshNode.name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME;
|
||||
break;
|
||||
}
|
||||
case MeshEnumerateOption.OnlyWithoutBlendShape:
|
||||
{
|
||||
meshNode.name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME;
|
||||
break;
|
||||
}
|
||||
case MeshEnumerateOption.All:
|
||||
{
|
||||
meshNode.name = INTEGRATED_MESH_ALL_NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF.MeshUtility
|
||||
{
|
||||
public static class MeshIntegratorUtility
|
||||
{
|
||||
public const string INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME = "Integrated(WithoutBlendShape)";
|
||||
public const string INTEGRATED_MESH_WITH_BLENDSHAPE_NAME = "Integrated(WithBlendShape)";
|
||||
public const string INTEGRATED_MESH_ALL_NAME = "Integrated(All)";
|
||||
|
||||
/// <summary>
|
||||
/// go を root としたヒエラルキーから Renderer を集めて、統合された Mesh 作成する
|
||||
/// </summary>
|
||||
|
|
@ -22,32 +25,39 @@ namespace UniGLTF.MeshUtility
|
|||
{
|
||||
var exclude = new MeshExclude(excludes);
|
||||
|
||||
var integrator = new MeshUtility.MeshIntegrator();
|
||||
var group = new MeshIntegrationGroup();
|
||||
bool useBlendShape = false;
|
||||
|
||||
switch (onlyBlendShapeRenderers)
|
||||
{
|
||||
case MeshEnumerateOption.OnlyWithBlendShape:
|
||||
{
|
||||
group.Name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME;
|
||||
useBlendShape = true;
|
||||
|
||||
foreach (var x in EnumerateSkinnedMeshRenderer(go.transform, onlyBlendShapeRenderers))
|
||||
{
|
||||
if (exclude.IsExcluded(x))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
integrator.Push(x);
|
||||
group.Renderers.Add(x);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MeshEnumerateOption.OnlyWithoutBlendShape:
|
||||
{
|
||||
group.Name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME;
|
||||
useBlendShape = false;
|
||||
|
||||
foreach (var x in EnumerateSkinnedMeshRenderer(go.transform, onlyBlendShapeRenderers))
|
||||
{
|
||||
if (exclude.IsExcluded(x))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
integrator.Push(x);
|
||||
group.Renderers.Add(x);
|
||||
}
|
||||
|
||||
foreach (var x in EnumerateMeshRenderer(go.transform))
|
||||
|
|
@ -56,7 +66,7 @@ namespace UniGLTF.MeshUtility
|
|||
{
|
||||
continue;
|
||||
}
|
||||
integrator.Push(x);
|
||||
group.Renderers.Add(x);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -64,13 +74,16 @@ namespace UniGLTF.MeshUtility
|
|||
|
||||
case MeshEnumerateOption.All:
|
||||
{
|
||||
group.Name = INTEGRATED_MESH_ALL_NAME;
|
||||
useBlendShape = true;
|
||||
|
||||
foreach (var x in EnumerateSkinnedMeshRenderer(go.transform, onlyBlendShapeRenderers))
|
||||
{
|
||||
if (exclude.IsExcluded(x))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
integrator.Push(x);
|
||||
group.Renderers.Add(x);
|
||||
}
|
||||
|
||||
foreach (var x in EnumerateMeshRenderer(go.transform))
|
||||
|
|
@ -79,14 +92,14 @@ namespace UniGLTF.MeshUtility
|
|||
{
|
||||
continue;
|
||||
}
|
||||
integrator.Push(x);
|
||||
group.Renderers.Add(x);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return integrator.Integrate(onlyBlendShapeRenderers);
|
||||
return MeshIntegrator.Integrate(group, useBlendShape);
|
||||
}
|
||||
|
||||
public static IEnumerable<SkinnedMeshRenderer> EnumerateSkinnedMeshRenderer(Transform root, MeshEnumerateOption hasBlendShape)
|
||||
|
|
@ -177,7 +190,7 @@ namespace UniGLTF.MeshUtility
|
|||
// Add integrated
|
||||
foreach (var result in results)
|
||||
{
|
||||
result.IntegratedRenderer.transform.SetParent(copy.transform, false);
|
||||
result.AddIntegratedRendererTo(copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using UniGLTF.MeshUtility;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
|
@ -38,7 +39,7 @@ namespace UniVRM10
|
|||
_meshUti = meshUtility;
|
||||
_splitter = new VerticalSplitter(editor, 50, 50);
|
||||
|
||||
_groupList = new ReorderableList(_meshUti.MeshIntegrationGroups, typeof(Vrm10MeshUtility.MeshIntegrationGroup));
|
||||
_groupList = new ReorderableList(_meshUti.MeshIntegrationGroups, typeof(MeshIntegrationGroup));
|
||||
_groupList.drawHeaderCallback = (Rect rect) =>
|
||||
{
|
||||
GUI.Label(rect, "Integration group");
|
||||
|
|
|
|||
|
|
@ -48,16 +48,6 @@ namespace UniVRM10
|
|||
/// </summary>
|
||||
public bool FreezeRotation = false;
|
||||
|
||||
public class MeshIntegrationGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// FirstPerson flag
|
||||
/// TODO: enum
|
||||
/// </summary>
|
||||
public string Name;
|
||||
public List<Renderer> Renderers = new List<Renderer>();
|
||||
}
|
||||
|
||||
public List<MeshIntegrationGroup> MeshIntegrationGroups = new List<MeshIntegrationGroup>();
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -145,23 +135,39 @@ 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)
|
||||
{
|
||||
foreach (var renderer in group.Renderers)
|
||||
var result = MeshIntegrator.Integrate(group, true);
|
||||
// TODO: firstperson
|
||||
|
||||
// TODO: split
|
||||
if (SplitByBlendShape)
|
||||
{
|
||||
// var withBlendShape, withoutBlendShape
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: split
|
||||
// TODO: remove old renderer
|
||||
result.AddIntegratedRendererTo(go);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user