mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-14 06:19:47 -05:00
implement FreezeScaling
This commit is contained in:
parent
476c35433a
commit
ced5dc8918
|
|
@ -11,36 +11,35 @@ namespace UniGLTF.MeshUtility
|
|||
{
|
||||
public delegate Avatar CreateAvatarFunc(GameObject original, GameObject normalized, Dictionary<Transform, Transform> boneMap);
|
||||
|
||||
static (GameObject, Dictionary<Transform, Transform>) NormalizeHierarchy(GameObject go, CreateAvatarFunc createAvatar)
|
||||
public static (GameObject, Dictionary<Transform, Transform>) CreateNormalizedHierarchy(GameObject go,
|
||||
bool removeScaling = true,
|
||||
bool removeRotation = true)
|
||||
{
|
||||
var boneMap = new Dictionary<Transform, Transform>();
|
||||
|
||||
//
|
||||
// 回転・スケールの無いヒエラルキーをコピーする
|
||||
//
|
||||
var normalized = new GameObject(go.name + "(normalized)");
|
||||
normalized.transform.position = go.transform.position;
|
||||
CopyAndBuild(go.transform, normalized.transform, boneMap);
|
||||
|
||||
//
|
||||
// 新しいヒエラルキーからAvatarを作る
|
||||
//
|
||||
if (removeScaling && removeRotation)
|
||||
{
|
||||
var animator = normalized.AddComponent<Animator>();
|
||||
var avatar = createAvatar(go, normalized, boneMap);
|
||||
avatar.name = go.name + ".normalized";
|
||||
animator.avatar = avatar;
|
||||
RemoveScaleAndRotationRecursive(go.transform, normalized.transform, boneMap);
|
||||
}
|
||||
else if (removeScaling)
|
||||
{
|
||||
RemoveScaleAndRotationRecursive(go.transform, normalized.transform, boneMap);
|
||||
}
|
||||
else if (removeRotation)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return (normalized, boneMap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回転とスケールを除去したヒエラルキーをコピーする。
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="dst"></param>
|
||||
static void CopyAndBuild(Transform src, Transform dst, Dictionary<Transform, Transform> boneMap)
|
||||
static void RemoveScaleRecursive(Transform src, Transform dst, Dictionary<Transform, Transform> boneMap)
|
||||
{
|
||||
boneMap[src] = dst;
|
||||
|
||||
|
|
@ -50,9 +49,27 @@ namespace UniGLTF.MeshUtility
|
|||
{
|
||||
var dstChild = new GameObject(child.name);
|
||||
dstChild.transform.SetParent(dst);
|
||||
dstChild.transform.position = child.position; // copy position only
|
||||
dstChild.transform.position = child.position; // copy world position
|
||||
dstChild.transform.rotation = child.localToWorldMatrix.rotation; // copy world rotation
|
||||
// scale is removed
|
||||
RemoveScaleRecursive(child, dstChild.transform, boneMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CopyAndBuild(child, dstChild.transform, boneMap);
|
||||
static void RemoveScaleAndRotationRecursive(Transform src, Transform dst, Dictionary<Transform, Transform> boneMap)
|
||||
{
|
||||
boneMap[src] = dst;
|
||||
|
||||
foreach (Transform child in src)
|
||||
{
|
||||
if (child.gameObject.activeSelf)
|
||||
{
|
||||
var dstChild = new GameObject(child.name);
|
||||
dstChild.transform.SetParent(dst);
|
||||
dstChild.transform.position = child.position; // copy world position
|
||||
|
||||
RemoveScaleAndRotationRecursive(child, dstChild.transform, boneMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -489,12 +506,12 @@ namespace UniGLTF.MeshUtility
|
|||
/// <param name="bakeCurrentBlendShape">BlendShapeを0クリアするか否か。false の場合 BlendShape の現状を Bake する</param>
|
||||
/// <param name="createAvatar">Avatarを作る関数</param>
|
||||
/// <returns></returns>
|
||||
public static (GameObject, Dictionary<Transform, Transform>) Execute(GameObject go, CreateAvatarFunc createAvatar)
|
||||
public static (GameObject, Dictionary<Transform, Transform>) Execute(GameObject go)
|
||||
{
|
||||
//
|
||||
// 正規化されたヒエラルキーを作る
|
||||
//
|
||||
var (normalized, boneMap) = NormalizeHierarchy(go, createAvatar);
|
||||
var (normalized, boneMap) = CreateNormalizedHierarchy(go);
|
||||
|
||||
//
|
||||
// 各メッシュから回転・スケールを取り除いてBinding行列を再計算する
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using UnityEngine;
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UniGLTF.Utils;
|
||||
|
||||
|
||||
namespace UniHumanoid
|
||||
|
|
@ -271,5 +272,42 @@ namespace UniHumanoid
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void AddAnimator(GameObject _src,
|
||||
GameObject dst,
|
||||
IDictionary<Transform, Transform> boneMap,
|
||||
Action<AvatarDescription> modAvatarDesc = null)
|
||||
{
|
||||
var src = _src.GetComponent<Animator>();
|
||||
|
||||
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
|
||||
.Where(x => boneMap.ContainsKey(x.Value))
|
||||
.ToDictionary(x => x.Key, x => boneMap[x.Value])
|
||||
;
|
||||
|
||||
var animator = dst.AddComponent<Animator>();
|
||||
if (animator == null)
|
||||
{
|
||||
animator = dst.AddComponent<Animator>();
|
||||
}
|
||||
|
||||
var avatarDescription = UniHumanoid.AvatarDescription.Create();
|
||||
if (modAvatarDesc != null)
|
||||
{
|
||||
modAvatarDesc(avatarDescription);
|
||||
}
|
||||
avatarDescription.SetHumanBones(map);
|
||||
var avatar = avatarDescription.CreateAvatar(dst.transform);
|
||||
|
||||
avatar.name = dst.name;
|
||||
animator.avatar = avatar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,31 +65,13 @@ namespace VRM
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 正規化されたヒエラルキーを作る
|
||||
//
|
||||
var (normalized, bMap) = BoneNormalizer.Execute(go, (_src, dst, boneMap) =>
|
||||
var (normalized, bMap) = BoneNormalizer.Execute(go);
|
||||
|
||||
// 新しいヒエラルキーからAvatarを作る
|
||||
UniHumanoid.AvatarDescription.AddAnimator(go, normalized, bMap, avatarDescription =>
|
||||
{
|
||||
var src = _src.GetComponent<Animator>();
|
||||
|
||||
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
|
||||
.Where(x => boneMap.ContainsKey(x.Value))
|
||||
.ToDictionary(x => x.Key, x => boneMap[x.Value])
|
||||
;
|
||||
|
||||
if (dst.GetComponent<Animator>() == null)
|
||||
{
|
||||
var animator = dst.AddComponent<Animator>();
|
||||
}
|
||||
var vrmHuman = go.GetComponent<VRMHumanoidDescription>();
|
||||
var avatarDescription = AvatarDescription.Create();
|
||||
if (vrmHuman != null && vrmHuman.Description != null)
|
||||
{
|
||||
avatarDescription.armStretch = vrmHuman.Description.armStretch;
|
||||
|
|
@ -101,9 +83,6 @@ namespace VRM
|
|||
avatarDescription.feetSpacing = vrmHuman.Description.feetSpacing;
|
||||
avatarDescription.hasTranslationDoF = vrmHuman.Description.hasTranslationDoF;
|
||||
}
|
||||
avatarDescription.SetHumanBones(map);
|
||||
var avatar = avatarDescription.CreateAvatar(dst.transform);
|
||||
return avatar;
|
||||
});
|
||||
|
||||
CopyVRMComponents(go, normalized, bMap);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniGLTF.MeshUtility;
|
||||
using UniHumanoid;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
|
|
@ -118,9 +120,22 @@ namespace UniVRM10
|
|||
}
|
||||
}
|
||||
|
||||
public void Process()
|
||||
public void Process(GameObject go)
|
||||
{
|
||||
Debug.Log("Process !");
|
||||
// TODO: UNDO
|
||||
|
||||
// 正規化されたヒエラルキーを作る
|
||||
var (normalized, boneMap) = BoneNormalizer.CreateNormalizedHierarchy(go,
|
||||
removeScaling: FreezeScaling,
|
||||
removeRotation: FreezeRotation);
|
||||
|
||||
// TODO: update: spring
|
||||
// TODO: update: constraint
|
||||
// TODO: update: firstPoint offset
|
||||
|
||||
AvatarDescription.AddAnimator(go, normalized, boneMap);
|
||||
|
||||
// TODO: write back normalized transform to boneMap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user