-
Notifications
You must be signed in to change notification settings - Fork 424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LookAt の整理 #2138
LookAt の整理 #2138
Changes from all commits
eddc4a0
44d2f2a
43033ae
0c4f768
f514e89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using UnityEngine; | ||
|
||
namespace UniVRM10 | ||
{ | ||
/// <summary> | ||
/// LookAt を具体的な値に解決する前の入力値 | ||
/// この値を元に LookAtEyeDirection を生成し、 | ||
/// LookAtEyeDirection を Bone もしくは MorphTarget に対して適用する。 | ||
/// </summary> | ||
public struct LookAtInput | ||
{ | ||
public LookAtEyeDirection? YawPitch; | ||
public Vector3? WorldPosition; | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ namespace UniVRM10 | |
/// </summary> | ||
public class Vrm10Runtime : IDisposable | ||
{ | ||
private readonly Vrm10Instance m_target; | ||
private readonly Vrm10Instance m_instance; | ||
private readonly Transform m_head; | ||
private readonly FastSpringBoneService m_fastSpringBoneService; | ||
private readonly IReadOnlyDictionary<Transform, TransformState> m_defaultTransformStates; | ||
|
@@ -51,46 +51,46 @@ public Vector3 ExternalForce | |
} | ||
} | ||
|
||
public Vrm10Runtime(Vrm10Instance target, bool useControlRig) | ||
public Vrm10Runtime(Vrm10Instance instance, bool useControlRig) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. target が LookAt target と紛らわしいような気がしたので、名前変更。 |
||
{ | ||
if (!Application.isPlaying) | ||
{ | ||
Debug.LogWarning($"{nameof(Vrm10Runtime)} expects runtime behaviour."); | ||
} | ||
|
||
m_target = target; | ||
m_instance = instance; | ||
|
||
if (!target.TryGetBoneTransform(HumanBodyBones.Head, out m_head)) | ||
if (!instance.TryGetBoneTransform(HumanBodyBones.Head, out m_head)) | ||
{ | ||
throw new Exception(); | ||
} | ||
|
||
if (useControlRig) | ||
{ | ||
ControlRig = new Vrm10RuntimeControlRig(target.Humanoid, m_target.transform); | ||
ControlRig = new Vrm10RuntimeControlRig(instance.Humanoid, m_instance.transform); | ||
} | ||
Constraints = target.GetComponentsInChildren<IVrm10Constraint>(); | ||
LookAt = new Vrm10RuntimeLookAt(target.Vrm.LookAt, target.Humanoid, ControlRig); | ||
Expression = new Vrm10RuntimeExpression(target, LookAt.EyeDirectionApplicable); | ||
Constraints = instance.GetComponentsInChildren<IVrm10Constraint>(); | ||
LookAt = new Vrm10RuntimeLookAt(instance.Vrm.LookAt, instance.Humanoid, ControlRig); | ||
Expression = new Vrm10RuntimeExpression(instance, LookAt.EyeDirectionApplicable); | ||
|
||
var instance = target.GetComponent<RuntimeGltfInstance>(); | ||
if (instance != null) | ||
var gltfInstance = instance.GetComponent<RuntimeGltfInstance>(); | ||
if (gltfInstance != null) | ||
{ | ||
// ランタイムインポートならここに到達してゼロコストになる | ||
m_defaultTransformStates = instance.InitialTransformStates; | ||
m_defaultTransformStates = gltfInstance.InitialTransformStates; | ||
} | ||
else | ||
{ | ||
// エディタでプレハブ配置してる奴ならこっちに到達して収集する | ||
m_defaultTransformStates = target.GetComponentsInChildren<Transform>() | ||
m_defaultTransformStates = instance.GetComponentsInChildren<Transform>() | ||
.ToDictionary(tf => tf, tf => new TransformState(tf)); | ||
} | ||
|
||
// NOTE: FastSpringBoneService は UnitTest などでは動作しない | ||
if (Application.isPlaying) | ||
{ | ||
m_fastSpringBoneService = FastSpringBoneService.Instance; | ||
m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_target.SpringBone); | ||
m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_instance.SpringBone); | ||
m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer); | ||
} | ||
} | ||
|
@@ -111,7 +111,7 @@ public void ReconstructSpringBone() | |
m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer); | ||
|
||
m_fastSpringBoneBuffer.Dispose(); | ||
m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_target.SpringBone); | ||
m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_instance.SpringBone); | ||
|
||
m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer); | ||
} | ||
|
@@ -203,20 +203,11 @@ public void Process() | |
Expression.SetWeight(k, v()); | ||
} | ||
|
||
// TODO: look at target | ||
// | ||
// この Frame の LookAt 値をアップデート | ||
// | ||
// struct LookAtValue | ||
// { | ||
// LookAtTargetTypes; | ||
// | ||
// (float, float) YawPitch; // 一番明確 | ||
// Vector3 GazePosition; // 座標系? | ||
// Transform GazeTarget; // 解決順のため遅延させる意図があるか | ||
// } | ||
// | ||
// あとで、LookAt.Process の引き数にわたす | ||
// look at | ||
if (VrmAnimation.LookAt.HasValue) | ||
{ | ||
LookAt.LookAtInput = VrmAnimation.LookAt.Value; | ||
} | ||
} | ||
|
||
// 2. Control Rig | ||
|
@@ -228,11 +219,20 @@ public void Process() | |
constraint.Process(); | ||
} | ||
|
||
if (m_instance.LookAtTargetType == VRM10ObjectLookAt.LookAtTargetTypes.SpecifiedTransform | ||
&& m_instance.LookAtTarget != null) | ||
{ | ||
// Transform 追跡で視線を生成する。 | ||
// 値を上書きします。 | ||
LookAt.LookAtInput = new LookAtInput { WorldPosition = m_instance.LookAtTarget.position }; | ||
} | ||
|
||
// 4. Gaze control | ||
LookAt.Process(m_target.LookAtTargetType, m_target.LookAtTarget); | ||
var eyeDirection = LookAt.Process(); | ||
|
||
// 5. Apply Expression | ||
Expression.Process(LookAt.EyeDirection); | ||
// LookAt の角度制限などはこちらで処理されます。 | ||
Expression.Process(eyeDirection); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,9 +13,17 @@ public sealed class Vrm10RuntimeLookAt : ILookAtEyeDirectionProvider | |
|
||
internal ILookAtEyeDirectionApplicable EyeDirectionApplicable { get; } | ||
|
||
public float Yaw { get; private set; } | ||
public float Pitch { get; private set; } | ||
/// <summary> | ||
/// 入力値。適宜更新可。 | ||
/// </summary> | ||
public LookAtInput LookAtInput { get; set; } | ||
|
||
/// <summary> | ||
/// 出力値。Process() のみが更新する | ||
/// </summary> | ||
public LookAtEyeDirection EyeDirection { get; private set; } | ||
Comment on lines
+16
to
24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
システムになる。 |
||
public float Yaw => EyeDirection.Yaw; | ||
public float Pitch => EyeDirection.Pitch; | ||
|
||
/// <summary> | ||
/// Transform that indicates the position center of eyes. | ||
|
@@ -52,39 +60,33 @@ internal Vrm10RuntimeLookAt(VRM10ObjectLookAt lookAt, UniHumanoid.Humanoid human | |
} | ||
} | ||
|
||
internal void Process(VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform lookAtTarget) | ||
internal LookAtEyeDirection Process() | ||
{ | ||
LookAtOriginTransform.localPosition = _lookAtOriginTransformLocalPosition; | ||
LookAtOriginTransform.localRotation = _lookAtOriginTransformLocalRotation; | ||
|
||
switch (lookAtTargetType) | ||
if (LookAtInput.YawPitch is LookAtEyeDirection dir) | ||
{ | ||
case VRM10ObjectLookAt.LookAtTargetTypes.SpecifiedTransform: | ||
// NOTE: 指定された Transform の位置を向くように Yaw/Pitch を計算して適用する | ||
if (lookAtTarget != null) | ||
{ | ||
var value = CalculateYawPitchFromLookAtPosition(lookAtTarget.position); | ||
SetYawPitchManually(value.Yaw, value.Pitch); | ||
} | ||
break; | ||
case VRM10ObjectLookAt.LookAtTargetTypes.YawPitchValue: | ||
// NOTE: 直接 Set された Yaw/Pitch を使って計算する | ||
break; | ||
EyeDirection = dir; | ||
} | ||
|
||
EyeDirection = new LookAtEyeDirection(Yaw, Pitch, 0, 0); | ||
else if (LookAtInput.WorldPosition is Vector3 worldPosition) | ||
{ | ||
// NOTE: 指定された Transform の位置を向くように Yaw/Pitch を計算して適用する | ||
var (yaw, pitch) = CalculateYawPitchFromLookAtPosition(worldPosition); | ||
EyeDirection = new LookAtEyeDirection(yaw, pitch); | ||
} | ||
return EyeDirection; | ||
} | ||
|
||
/// <summary> | ||
/// Yaw/Pitch 値を直接設定します。 | ||
/// LookAtTargetTypes が SpecifiedTransform の場合、ここで設定しても値は上書きされます。 | ||
/// Vrm10Instance.LookAtTargetTypes が SpecifiedTransform の場合、ここで設定しても値は上書きされます。 | ||
/// </summary> | ||
/// <param name="yaw">Headボーンのforwardに対するyaw角(度)</param> | ||
/// <param name="pitch">Headボーンのforwardに対するpitch角(度)</param> | ||
public void SetYawPitchManually(float yaw, float pitch) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
{ | ||
Yaw = yaw; | ||
Pitch = pitch; | ||
LookAtInput = new LookAtInput { YawPitch = new LookAtEyeDirection(yaw, pitch) }; | ||
} | ||
|
||
public (float Yaw, float Pitch) CalculateYawPitchFromLookAtPosition(Vector3 lookAtWorldPosition) | ||
|
@@ -105,7 +107,7 @@ private static Transform InitializeLookAtOriginTransform(Transform rawHead, Tran | |
return lookAtOrigin; | ||
} | ||
|
||
#region Obsolete | ||
#region Obsolete | ||
[Obsolete("Use " + nameof(LookAtOriginTransform))] | ||
public Transform GetLookAtOrigin(Transform head) | ||
{ | ||
|
@@ -134,6 +136,6 @@ public void SetLookAtYawPitch(float yaw, float pitch) | |
throw new ArgumentOutOfRangeException(nameof(lookAtTargetType), lookAtTargetType, null); | ||
} | ||
} | ||
#endregion | ||
#endregion | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using UnityEngine; | ||
|
||
namespace UniVRM10 | ||
{ | ||
|
@@ -8,5 +9,6 @@ public interface IVrm10Animation : IDisposable | |
(INormalizedPoseProvider, ITPoseProvider) ControlRig { get; } | ||
IReadOnlyDictionary<ExpressionKey, Func<float>> ExpressionMap { get; } | ||
public void ShowBoxMan(bool enable); | ||
LookAtInput? LookAt { get; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. VrmAnimation から LookAt を供給する。まだ入れ物だけ |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
今の段階では左右の目の YawPitch を区別する必要はない。
将来的にも規格レベルで解決するべきハードルが高いので、またいずれ……
参考:vrm-c/vrm-specification#177