mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-20 09:34:42 -05:00
sample の retarget を更新。
TPose を表現する empty クラスを追加。
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UniGLTF.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public class TPose : IVrm10Animation
|
||||
{
|
||||
public class NoRotation : INormalizedPoseProvider
|
||||
{
|
||||
readonly Vector3 m_hips;
|
||||
|
||||
public NoRotation(Vector3 hips)
|
||||
{
|
||||
m_hips = hips;
|
||||
}
|
||||
|
||||
public Quaternion GetNormalizedLocalRotation(HumanBodyBones bone, HumanBodyBones parentBone)
|
||||
{
|
||||
return new Quaternion(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public Vector3 GetRawHipsPosition()
|
||||
{
|
||||
return m_hips;
|
||||
}
|
||||
}
|
||||
|
||||
public class Skeleton : ITPoseProvider
|
||||
{
|
||||
Vector3 m_hips;
|
||||
public Skeleton(Vector3 hips)
|
||||
{
|
||||
m_hips = hips;
|
||||
}
|
||||
|
||||
public EuclideanTransform? GetWorldTransform(HumanBodyBones bone)
|
||||
{
|
||||
if (bone == HumanBodyBones.Hips)
|
||||
{
|
||||
return new EuclideanTransform(m_hips);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public (INormalizedPoseProvider, ITPoseProvider) m_controlRig;
|
||||
|
||||
public (INormalizedPoseProvider, ITPoseProvider) ControlRig => m_controlRig;
|
||||
|
||||
// empty
|
||||
public IReadOnlyDictionary<ExpressionKey, Func<float>> ExpressionMap => new Dictionary<ExpressionKey, Func<float>>();
|
||||
|
||||
public LookAtInput? LookAt => default;
|
||||
|
||||
public TPose(Vector3 hips)
|
||||
{
|
||||
m_controlRig = (new NoRotation(hips), new Skeleton(hips));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public void ShowBoxMan(bool enable)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49423dc9e9a224545a90221f41d975c8
|
||||
guid: 90e77483e976b074db9a08fcdc1b5d40
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -13,7 +13,8 @@ namespace UniVRM10
|
||||
}
|
||||
|
||||
// scaling hips position
|
||||
var scaling = sink.TPose.GetWorldTransform(HumanBodyBones.LeftUpperLeg).Value.Translation.y / source.TPose.GetWorldTransform(HumanBodyBones.LeftUpperLeg).Value.Translation.y;
|
||||
var scaleRef = HumanBodyBones.Hips;
|
||||
var scaling = sink.TPose.GetWorldTransform(scaleRef).Value.Translation.y / source.TPose.GetWorldTransform(scaleRef).Value.Translation.y;
|
||||
var delta = source.Pose.GetRawHipsPosition() - source.TPose.GetWorldTransform(HumanBodyBones.Hips).Value.Translation;
|
||||
sink.Pose.SetRawHipsPosition(sink.TPose.GetWorldTransform(HumanBodyBones.Hips).Value.Translation + delta * scaling);
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10.VRM10Viewer
|
||||
{
|
||||
public static class VRM10Retarget
|
||||
{
|
||||
public static void Retarget((INormalizedPoseProvider Pose, ITPoseProvider TPose) source, (INormalizedPoseApplicable Pose, ITPoseProvider TPose) sink)
|
||||
{
|
||||
foreach (var (head, parent) in sink.TPose.EnumerateBoneParentPairs())
|
||||
{
|
||||
var q = source.Pose.GetNormalizedLocalRotation(head, parent);
|
||||
sink.Pose.SetNormalizedLocalRotation(head, q);
|
||||
}
|
||||
|
||||
// scaling hips position
|
||||
var scaling = sink.TPose.GetWorldTransform(HumanBodyBones.LeftUpperLeg).Value.Translation.y / source.TPose.GetWorldTransform(HumanBodyBones.LeftUpperLeg).Value.Translation.y;
|
||||
var delta = source.Pose.GetRawHipsPosition() - source.TPose.GetWorldTransform(HumanBodyBones.Hips).Value.Translation;
|
||||
sink.Pose.SetRawHipsPosition(sink.TPose.GetWorldTransform(HumanBodyBones.Hips).Value.Translation + delta * scaling);
|
||||
}
|
||||
|
||||
public static void EnforceTPose((INormalizedPoseApplicable Pose, ITPoseProvider TPose) sink)
|
||||
{
|
||||
foreach (var (bone, parent) in sink.TPose.EnumerateBoneParentPairs())
|
||||
{
|
||||
sink.Pose.SetNormalizedLocalRotation(bone, Quaternion.identity);
|
||||
}
|
||||
|
||||
sink.Pose.SetRawHipsPosition(sink.TPose.GetWorldTransform(HumanBodyBones.Hips).Value.Translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,9 +61,13 @@ namespace UniVRM10.VRM10Viewer
|
||||
m_src.Dispose();
|
||||
}
|
||||
m_src = value;
|
||||
|
||||
TPose = new TPose(m_src.ControlRig.Item1.GetRawHipsPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public IVrm10Animation TPose;
|
||||
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
[Serializable]
|
||||
@@ -209,13 +213,13 @@ namespace UniVRM10.VRM10Viewer
|
||||
ToggleMotion = groups.First(x => x.name == "_Motion_");
|
||||
}
|
||||
|
||||
public bool IsBvhEnabled
|
||||
public bool IsTPose
|
||||
{
|
||||
get => ToggleMotion.ActiveToggles().FirstOrDefault() == ToggleMotionBVH;
|
||||
get => ToggleMotion.ActiveToggles().FirstOrDefault() == ToggleMotionTPose;
|
||||
set
|
||||
{
|
||||
ToggleMotionTPose.isOn = !value;
|
||||
ToggleMotionBVH.isOn = value;
|
||||
ToggleMotionTPose.isOn = value;
|
||||
ToggleMotionBVH.isOn = !value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,7 +335,7 @@ namespace UniVRM10.VRM10Viewer
|
||||
_cancellationTokenSource?.Dispose();
|
||||
}
|
||||
|
||||
bool? m_lastUseBvh = default;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.Tab))
|
||||
@@ -357,31 +361,19 @@ namespace UniVRM10.VRM10Viewer
|
||||
m_loaded.EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
m_loaded.EnableAutoExpressionValue = m_enableAutoExpression.isOn;
|
||||
}
|
||||
|
||||
var useBvh = Motion != null;
|
||||
if (useBvh)
|
||||
if (m_loaded != null)
|
||||
{
|
||||
if (m_ui.IsTPose)
|
||||
{
|
||||
// update humanoid
|
||||
if (Motion.ControlRig.Item1 != null && Motion.ControlRig.Item2 != null)
|
||||
{
|
||||
VRM10Retarget.Retarget(Motion.ControlRig, (m_loaded.ControlRig, m_loaded.ControlRig));
|
||||
}
|
||||
// update expressions
|
||||
foreach (var (k, v) in Motion.ExpressionMap)
|
||||
{
|
||||
// VRMA-expression use localPosition.x as expression weight
|
||||
m_loaded.Runtime.Expression.SetWeight(k, v());
|
||||
}
|
||||
m_loaded.Runtime.VrmAnimation = TPose;
|
||||
}
|
||||
else
|
||||
else if (Motion != null)
|
||||
{
|
||||
if (!m_lastUseBvh.HasValue || m_lastUseBvh.Value)
|
||||
{
|
||||
Debug.Log("SetPose");
|
||||
VRM10Retarget.EnforceTPose((m_loaded.ControlRig, m_loaded.ControlRig));
|
||||
}
|
||||
// Automatically retarget in Vrm10Runtime.Process
|
||||
m_loaded.Runtime.VrmAnimation = Motion;
|
||||
}
|
||||
m_lastUseBvh = useBvh;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,9 +438,6 @@ namespace UniVRM10.VRM10Viewer
|
||||
return;
|
||||
}
|
||||
|
||||
m_ui.IsBvhEnabled = false;
|
||||
m_lastUseBvh = false;
|
||||
|
||||
try
|
||||
{
|
||||
Motion = await Vrm10PoseLoader.LoadVrmAnimationPose(text);
|
||||
|
||||
Reference in New Issue
Block a user