diff --git a/Assets/VRM10/Editor/EditorTool/VRM10LookAtEditorTool.cs b/Assets/VRM10/Editor/EditorTool/VRM10LookAtEditorTool.cs
index d0458b33a..63ce8ace9 100644
--- a/Assets/VRM10/Editor/EditorTool/VRM10LookAtEditorTool.cs
+++ b/Assets/VRM10/Editor/EditorTool/VRM10LookAtEditorTool.cs
@@ -86,7 +86,7 @@ namespace UniVRM10
if (Application.isPlaying)
{
- OnSceneGUILookAt(root.Vrm.LookAt, root.Runtime.LookAt, head, root.LookAtTargetType, root.Gaze);
+ OnSceneGUILookAt(root.Vrm.LookAt, root.Runtime.LookAt, root.LookAtTargetType, root.Gaze);
}
else
{
@@ -125,28 +125,27 @@ namespace UniVRM10
const float RADIUS = 0.5f;
- static void OnSceneGUILookAt(VRM10ObjectLookAt lookAt, Vrm10RuntimeLookAt runtime, Transform head, VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gaze)
+ static void OnSceneGUILookAt(VRM10ObjectLookAt lookAt, Vrm10RuntimeLookAt runtime, VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gazeTarget)
{
- if (head == null) return;
-
- if (gaze != null)
+ if (lookAtTargetType == VRM10ObjectLookAt.LookAtTargetTypes.Auto && gazeTarget != null)
{
{
EditorGUI.BeginChangeCheck();
- var newTargetPosition = Handles.PositionHandle(gaze.position, Quaternion.identity);
+ var newTargetPosition = Handles.PositionHandle(gazeTarget.position, Quaternion.identity);
if (EditorGUI.EndChangeCheck())
{
- Undo.RecordObject(gaze, "Change Look At Target Position");
- gaze.position = newTargetPosition;
+ Undo.RecordObject(gazeTarget, "Change Look At Target Position");
+ gazeTarget.position = newTargetPosition;
}
}
Handles.color = new Color(1, 1, 1, 0.6f);
- Handles.DrawDottedLine(runtime.GetLookAtOrigin(head).position, gaze.position, 4.0f);
+ Handles.DrawDottedLine(runtime.EyeTransform.position, gazeTarget.position, 4.0f);
}
- var (yaw, pitch) = runtime.GetLookAtYawPitch(head, lookAtTargetType, gaze);
- var lookAtOriginMatrix = runtime.GetLookAtOrigin(head).localToWorldMatrix;
+ var yaw = runtime.Yaw;
+ var pitch = runtime.Pitch;
+ var lookAtOriginMatrix = runtime.EyeTransform.localToWorldMatrix;
Handles.matrix = lookAtOriginMatrix;
var p = lookAt.OffsetFromHead;
Handles.Label(Vector3.zero,
diff --git a/Assets/VRM10/Runtime/AssemblyInfo.cs b/Assets/VRM10/Runtime/AssemblyInfo.cs
new file mode 100644
index 000000000..cdd50e031
--- /dev/null
+++ b/Assets/VRM10/Runtime/AssemblyInfo.cs
@@ -0,0 +1,5 @@
+#if UNITY_EDITOR
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("VRM10.Tests")]
+#endif
\ No newline at end of file
diff --git a/Assets/VRM10/Runtime/AssemblyInfo.cs.meta b/Assets/VRM10/Runtime/AssemblyInfo.cs.meta
new file mode 100644
index 000000000..e78efb4ef
--- /dev/null
+++ b/Assets/VRM10/Runtime/AssemblyInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c0bb9ff90c68a3f4bb86b5fed930f30e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/VRM10/Runtime/Components/Expression/LookAtEyeDirection.cs b/Assets/VRM10/Runtime/Components/Expression/LookAtEyeDirection.cs
index e3d486f41..f4d9db503 100644
--- a/Assets/VRM10/Runtime/Components/Expression/LookAtEyeDirection.cs
+++ b/Assets/VRM10/Runtime/Components/Expression/LookAtEyeDirection.cs
@@ -13,11 +13,13 @@
public float LeftPitch { get; }
///
+ /// NOTE: 何故か使われていない
/// Yaw of RightEye
///
public float RightYaw { get; }
///
+ /// NOTE: 何故か使われていない
/// Pitch of RightEye
///
public float RightPitch { get; }
diff --git a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectLookAt.cs b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectLookAt.cs
index 1077211b1..158529fb8 100644
--- a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectLookAt.cs
+++ b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectLookAt.cs
@@ -1,9 +1,6 @@
using System;
using UnityEngine;
using UniGLTF.Extensions.VRMC_vrm;
-#if UNITY_EDITOR
-using UnityEditor;
-#endif
namespace UniVRM10
{
@@ -12,8 +9,17 @@ namespace UniVRM10
{
public enum LookAtTargetTypes
{
- CalcYawPitchToGaze,
- SetYawPitch,
+ ///
+ /// Vrm10Instance に設定した Gaze Transform を見ます.
+ ///
+ Auto = 0,
+ ///
+ /// Vrm10RuntimeLookAt に設定した Yaw/Pitch 値に従います.
+ ///
+ Manual = 1,
+
+ [Obsolete] CalcYawPitchToGaze = 0,
+ [Obsolete] SetYawPitch = 1,
}
[SerializeField]
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs
index e3a888704..2a8e7eeba 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs
@@ -110,15 +110,7 @@ namespace UniVRM10
// cause new Vrm10Runtime.
// init LookAt init rotation.
- var runtime = Runtime;
-
- if (LookAtTargetType == VRM10ObjectLookAt.LookAtTargetTypes.CalcYawPitchToGaze)
- {
- if (Gaze == null)
- {
- LookAtTargetType = VRM10ObjectLookAt.LookAtTargetTypes.SetYawPitch;
- }
- }
+ var _ = Runtime;
}
private void Update()
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
index 0265e65b7..261ff44a8 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
@@ -63,7 +63,7 @@ namespace UniVRM10
ControlRig = new Vrm10RuntimeControlRig(target.Humanoid, m_target.transform, controlRigInitialRotations);
}
Constraints = target.GetComponentsInChildren();
- LookAt = new Vrm10RuntimeLookAt(target.Vrm.LookAt, target.Humanoid, m_head, target.LookAtTargetType, target.Gaze);
+ LookAt = new Vrm10RuntimeLookAt(target.Vrm.LookAt, target.Humanoid, m_head);
Expression = new Vrm10RuntimeExpression(target, LookAt, LookAt.EyeDirectionApplicable);
var instance = target.GetComponent();
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs
index f01dd1e3b..18b17a309 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs
@@ -1,128 +1,128 @@
using System;
using UniGLTF.Extensions.VRMC_vrm;
-using UnityEditor;
using UnityEngine;
namespace UniVRM10
{
public sealed class Vrm10RuntimeLookAt : ILookAtEyeDirectionProvider
{
- VRM10ObjectLookAt m_lookat;
+ private readonly VRM10ObjectLookAt _lookAt;
+ private readonly Transform _head;
+ private readonly Vector3 _eyeTransformLocalPosition;
+ private readonly Quaternion _eyeTransformLocalRotation;
- private Transform m_head;
- private Transform m_leftEye;
- private Transform m_rightEye;
- private ILookAtEyeDirectionApplicable _eyeDirectionApplicable;
+ public float Yaw { get; private set; }
+ public float Pitch { get; private set; }
- internal ILookAtEyeDirectionApplicable EyeDirectionApplicable => _eyeDirectionApplicable;
+ internal ILookAtEyeDirectionApplicable EyeDirectionApplicable { get; }
public LookAtEyeDirection EyeDirection { get; private set; }
- #region LookAtTargetTypes.CalcYawPitchToGaze
- // 座標計算用のempty
- Transform m_lookAtSpace;
- public Transform GetLookAtOrigin(Transform head)
+ public Transform EyeTransform { get; }
+
+ internal Vrm10RuntimeLookAt(VRM10ObjectLookAt lookAt, UniHumanoid.Humanoid humanoid, Transform head)
{
- if (!Application.isPlaying)
+ _lookAt = lookAt;
+ _head = head;
+ EyeTransform = InitializeEyePositionTransform(_head, _lookAt.OffsetFromHead);
+ _eyeTransformLocalPosition = EyeTransform.localPosition;
+ _eyeTransformLocalRotation = EyeTransform.localRotation;
+
+ var leftEyeBone = humanoid.GetBoneTransform(HumanBodyBones.LeftEye);
+ var rightEyeBone = humanoid.GetBoneTransform(HumanBodyBones.RightEye);
+ if (_lookAt.LookAtType == LookAtType.bone && leftEyeBone != null && rightEyeBone != null)
{
- return null;
- }
- if (m_lookAtSpace == null)
- {
- m_lookAtSpace = new GameObject("_lookat_origin_").transform;
- m_lookAtSpace.SetParent(head);
- }
- return m_lookAtSpace;
- }
-
- ///
- /// Headローカルの注視点からYaw, Pitch角を計算する
- ///
- (float, float) CalcLookAtYawPitch(Vector3 targetWorldPosition, Transform head)
- {
- var lookAtSpace = GetLookAtOrigin(head);
- lookAtSpace.localPosition = m_lookat.OffsetFromHead;
- var localPosition = lookAtSpace.worldToLocalMatrix.MultiplyPoint(targetWorldPosition);
- float yaw, pitch;
- Matrix4x4.identity.CalcYawPitch(localPosition, out yaw, out pitch);
- return (yaw, pitch);
- }
- #endregion
-
- #region LookAtTargetTypes.SetYawPitch
- float m_yaw;
- float m_pitch;
-
- ///
- /// LookAtTargetTypes.SetYawPitch時の視線の角度を指定する
- ///
- /// Headボーンのforwardに対するyaw角(度)
- /// Headボーンのforwardに対するpitch角(度)
- public void SetLookAtYawPitch(float yaw, float pitch)
- {
- m_yaw = yaw;
- m_pitch = pitch;
- }
- #endregion
-
- ///
- /// LookAtTargetType に応じた yaw, pitch を得る
- ///
- /// Headボーンのforwardに対するyaw角(度), pitch角(度)
- public (float, float) GetLookAtYawPitch(Transform head, VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gaze)
- {
- switch (lookAtTargetType)
- {
- case VRM10ObjectLookAt.LookAtTargetTypes.CalcYawPitchToGaze:
- // Gaze(Transform)のワールド位置に対して計算する
- return CalcLookAtYawPitch(gaze.position, head);
-
- case VRM10ObjectLookAt.LookAtTargetTypes.SetYawPitch:
- // 事前にSetYawPitchした値を使う
- return (m_yaw, m_pitch);
- }
-
- throw new NotImplementedException();
- }
-
- internal Vrm10RuntimeLookAt(VRM10ObjectLookAt lookat, UniHumanoid.Humanoid humanoid, Transform head, VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gaze)
- {
- // 初期姿勢で初期化する!
- GetLookAtOrigin(head);
-
- m_lookat = lookat;
-
- m_head = head;
- m_leftEye = humanoid.GetBoneTransform(HumanBodyBones.LeftEye);
- m_rightEye = humanoid.GetBoneTransform(HumanBodyBones.RightEye);
-
- var isRuntimeAsset = true;
-#if UNITY_EDITOR
- isRuntimeAsset = Application.isPlaying && !PrefabUtility.IsPartOfAnyPrefab(m_head);
-#endif
- if (isRuntimeAsset && lookAtTargetType == VRM10ObjectLookAt.LookAtTargetTypes.CalcYawPitchToGaze && gaze == null)
- {
- gaze = new GameObject().transform;
- gaze.name = "__LOOKAT_GAZE__";
- gaze.SetParent(m_head);
- gaze.localPosition = Vector3.forward;
- }
-
- // bone が無いときのエラー防止。マイグレーション失敗?
- if (m_lookat.LookAtType == LookAtType.bone && m_leftEye != null && m_rightEye != null)
- {
- _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToBone(m_leftEye, m_rightEye, m_lookat.HorizontalOuter, m_lookat.HorizontalInner, m_lookat.VerticalDown, m_lookat.VerticalUp);
+ EyeDirectionApplicable = new LookAtEyeDirectionApplicableToBone(leftEyeBone, rightEyeBone, _lookAt.HorizontalOuter, _lookAt.HorizontalInner, _lookAt.VerticalDown, _lookAt.VerticalUp);
}
else
{
- _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToExpression(m_lookat.HorizontalOuter, m_lookat.HorizontalInner, m_lookat.VerticalDown, m_lookat.VerticalUp);
+ EyeDirectionApplicable = new LookAtEyeDirectionApplicableToExpression(_lookAt.HorizontalOuter, _lookAt.HorizontalInner, _lookAt.VerticalDown, _lookAt.VerticalUp);
}
}
- internal void Process(VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gaze)
+ internal void Process(VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gazeTarget)
{
- var (yaw, pitch) = GetLookAtYawPitch(m_head, lookAtTargetType, gaze);
- EyeDirection = new LookAtEyeDirection(yaw, pitch, 0, 0);
+ EyeTransform.localPosition = _eyeTransformLocalPosition;
+ EyeTransform.localRotation = _eyeTransformLocalRotation;
+
+ switch (lookAtTargetType)
+ {
+ case VRM10ObjectLookAt.LookAtTargetTypes.Auto:
+ // NOTE: 指定された Gaze Transform の位置を向くように Yaw/Pitch を計算して適用する
+ if (gazeTarget != null)
+ {
+ var value = CalculateYawPitchFromGazePosition(gazeTarget.position);
+ SetYawPitchManually(value.Yaw, value.Pitch);
+ }
+ break;
+ case VRM10ObjectLookAt.LookAtTargetTypes.Manual:
+ // NOTE: 直接 Set された Yaw/Pitch を使って計算する
+ break;
+ }
+
+ EyeDirection = new LookAtEyeDirection(Yaw, Pitch, 0, 0);
}
+
+ ///
+ /// LookAtTargetTypes.Manual 時に考慮される Yaw/Pitch 値を設定する
+ ///
+ /// Headボーンのforwardに対するyaw角(度)
+ /// Headボーンのforwardに対するpitch角(度)
+ public void SetYawPitchManually(float yaw, float pitch)
+ {
+ Yaw = yaw;
+ Pitch = pitch;
+ }
+
+ private (float Yaw, float Pitch) CalculateYawPitchFromGazePosition(Vector3 gazeWorldPosition)
+ {
+ var localPosition = EyeTransform.worldToLocalMatrix.MultiplyPoint(gazeWorldPosition);
+ Matrix4x4.identity.CalcYawPitch(localPosition, out var yaw, out var pitch);
+ return (yaw, pitch);
+ }
+
+ private static Transform InitializeEyePositionTransform(Transform head, Vector3 eyeOffsetValue)
+ {
+ if (!Application.isPlaying) return null;
+
+ // NOTE: このメソッドを実行するとき、モデル全体は初期姿勢(T-Pose)でなければならない。
+ var eyePositionTransform = new GameObject("_eye_transform_").transform;
+ eyePositionTransform.SetParent(head);
+ eyePositionTransform.localPosition = eyeOffsetValue;
+ eyePositionTransform.rotation = Quaternion.identity;
+
+ return eyePositionTransform;
+ }
+
+#region Obsolete
+ [Obsolete]
+ public Transform GetLookAtOrigin(Transform head)
+ {
+ return EyeTransform;
+ }
+
+ [Obsolete]
+ public void SetLookAtYawPitch(float yaw, float pitch)
+ {
+ SetYawPitchManually(yaw, pitch);
+ }
+
+ [Obsolete]
+ public (float, float) GetLookAtYawPitch(
+ Transform head,
+ VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType,
+ Transform gaze)
+ {
+ switch (lookAtTargetType)
+ {
+ case VRM10ObjectLookAt.LookAtTargetTypes.Auto:
+ return CalculateYawPitchFromGazePosition(gaze.position);
+ case VRM10ObjectLookAt.LookAtTargetTypes.Manual:
+ return (Yaw, Pitch);
+ default:
+ throw new ArgumentOutOfRangeException(nameof(lookAtTargetType), lookAtTargetType, null);
+ }
+ }
+#endregion
}
}
diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs b/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs
index 861c2e783..cefcb8e06 100644
--- a/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs
+++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs
@@ -69,7 +69,7 @@ namespace UniVRM10.VRM10Viewer
m_blink = instance.gameObject.AddComponent();
m_autoExpression = instance.gameObject.AddComponent();
- m_controller.LookAtTargetType = VRM10ObjectLookAt.LookAtTargetTypes.CalcYawPitchToGaze;
+ m_controller.LookAtTargetType = VRM10ObjectLookAt.LookAtTargetTypes.Auto;
m_controller.Gaze = lookAtTarget;
}
}