diff --git a/Assets/VRM10/Editor/EditorTool/VRM10LookAtEditorTool.cs b/Assets/VRM10/Editor/EditorTool/VRM10LookAtEditorTool.cs
index 854f6845b..596bbb4f5 100644
--- a/Assets/VRM10/Editor/EditorTool/VRM10LookAtEditorTool.cs
+++ b/Assets/VRM10/Editor/EditorTool/VRM10LookAtEditorTool.cs
@@ -82,7 +82,7 @@ namespace UniVRM10
if (Application.isPlaying)
{
- OnSceneGUILookAt(root.Vrm.LookAt, head, root.LookAtTargetType, root.Gaze);
+ OnSceneGUILookAt(root.Vrm.LookAt, root.Runtime.LookAt, head, root.LookAtTargetType, root.Gaze);
}
else
{
@@ -121,7 +121,7 @@ namespace UniVRM10
const float RADIUS = 0.5f;
- static void OnSceneGUILookAt(VRM10ObjectLookAt lookAt, Transform head, VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gaze)
+ static void OnSceneGUILookAt(VRM10ObjectLookAt lookAt, Vrm10RuntimeLookAt runtime, Transform head, VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gaze)
{
if (head == null) return;
@@ -138,11 +138,11 @@ namespace UniVRM10
}
Handles.color = new Color(1, 1, 1, 0.6f);
- Handles.DrawDottedLine(lookAt.GetLookAtOrigin(head).position, gaze.position, 4.0f);
+ Handles.DrawDottedLine(runtime.GetLookAtOrigin(head).position, gaze.position, 4.0f);
}
- var (yaw, pitch) = lookAt.GetLookAtYawPitch(head, lookAtTargetType, gaze);
- var lookAtOriginMatrix = lookAt.GetLookAtOrigin(head).localToWorldMatrix;
+ var (yaw, pitch) = runtime.GetLookAtYawPitch(head, lookAtTargetType, gaze);
+ var lookAtOriginMatrix = runtime.GetLookAtOrigin(head).localToWorldMatrix;
Handles.matrix = lookAtOriginMatrix;
var p = lookAt.OffsetFromHead;
Handles.Label(Vector3.zero,
diff --git a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectLookAt.cs b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectLookAt.cs
index 0c3682256..1077211b1 100644
--- a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectLookAt.cs
+++ b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectLookAt.cs
@@ -8,7 +8,7 @@ using UnityEditor;
namespace UniVRM10
{
[Serializable]
- public class VRM10ObjectLookAt : ILookAtEyeDirectionProvider
+ public class VRM10ObjectLookAt
{
public enum LookAtTargetTypes
{
@@ -33,117 +33,5 @@ namespace UniVRM10
[SerializeField]
public CurveMapper VerticalUp = new CurveMapper(90.0f, 10.0f);
-
- private Transform m_head;
- private Transform m_leftEye;
- private Transform m_rightEye;
- private ILookAtEyeDirectionApplicable _eyeDirectionApplicable;
-
- internal ILookAtEyeDirectionApplicable EyeDirectionApplicable => _eyeDirectionApplicable;
-
- public LookAtEyeDirection EyeDirection { get; private set; }
-
- #region LookAtTargetTypes.CalcYawPitchToGaze
- // 座標計算用のempty
- Transform m_lookAtOrigin;
- public Transform GetLookAtOrigin(Transform head)
- {
- if (!Application.isPlaying)
- {
- return null;
- }
- if (m_lookAtOrigin == null)
- {
- m_lookAtOrigin = new GameObject("_lookat_origin_").transform;
- m_lookAtOrigin.SetParent(head);
- }
- return m_lookAtOrigin;
- }
-
- ///
- /// Headローカルの注視点からYaw, Pitch角を計算する
- ///
- (float, float) CalcLookAtYawPitch(Vector3 targetWorldPosition, Transform head)
- {
- GetLookAtOrigin(head).localPosition = OffsetFromHead;
-
- var localPosition = m_lookAtOrigin.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, LookAtTargetTypes lookAtTargetType, Transform gaze)
- {
- switch (lookAtTargetType)
- {
- case LookAtTargetTypes.CalcYawPitchToGaze:
- // Gaze(Transform)のワールド位置に対して計算する
- return CalcLookAtYawPitch(gaze.position, head);
-
- case LookAtTargetTypes.SetYawPitch:
- // 事前にSetYawPitchした値を使う
- return (m_yaw, m_pitch);
- }
-
- throw new NotImplementedException();
- }
-
- internal void Setup(Animator animator, Transform head, LookAtTargetTypes lookAtTargetType, Transform gaze)
- {
- m_head = head;
- m_leftEye = animator.GetBoneTransform(HumanBodyBones.LeftEye);
- m_rightEye = animator.GetBoneTransform(HumanBodyBones.RightEye);
-
- var isRuntimeAsset = true;
-#if UNITY_EDITOR
- isRuntimeAsset = Application.isPlaying && !PrefabUtility.IsPartOfAnyPrefab(m_head);
-#endif
- if (isRuntimeAsset && lookAtTargetType == LookAtTargetTypes.CalcYawPitchToGaze && gaze == null)
- {
- gaze = new GameObject().transform;
- gaze.name = "__LOOKAT_GAZE__";
- gaze.SetParent(m_head);
- gaze.localPosition = Vector3.forward;
- }
- switch (LookAtType)
- {
- case LookAtType.bone:
- _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToBone(m_leftEye, m_rightEye, HorizontalOuter, HorizontalInner, VerticalDown, VerticalUp);
- break;
- case LookAtType.expression:
- _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToExpression(HorizontalOuter, HorizontalInner, VerticalDown, VerticalUp);
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
-
- public void Process(LookAtTargetTypes lookAtTargetType, Transform gaze)
- {
- var (yaw, pitch) = GetLookAtYawPitch(m_head, lookAtTargetType, gaze);
- EyeDirection = new LookAtEyeDirection(yaw, pitch, 0, 0);
- }
}
}
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
index 3335207b6..7bcad98b1 100644
--- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs
@@ -19,9 +19,11 @@ namespace UniVRM10
private FastSpringBoneBuffer m_fastSpringBoneBuffer;
private Vrm10RuntimeExpression m_expression;
-
public Vrm10RuntimeExpression Expression => m_expression;
+ private Vrm10RuntimeLookAt m_lookat;
+ public Vrm10RuntimeLookAt LookAt => m_lookat;
+
public Vrm10Runtime(Vrm10Instance target)
{
m_target = target;
@@ -32,8 +34,8 @@ namespace UniVRM10
}
m_head = animator.GetBoneTransform(HumanBodyBones.Head);
- target.Vrm.LookAt.Setup(animator, m_head, target.LookAtTargetType, target.Gaze);
- m_expression = new Vrm10RuntimeExpression(target, target.Vrm.LookAt, target.Vrm.LookAt.EyeDirectionApplicable);
+ m_lookat = new Vrm10RuntimeLookAt(target.Vrm.LookAt, animator, m_head, target.LookAtTargetType, target.Gaze);
+ m_expression = new Vrm10RuntimeExpression(target, m_lookat, m_lookat.EyeDirectionApplicable);
if (m_constraints == null)
{
@@ -135,7 +137,7 @@ namespace UniVRM10
//
// gaze control
//
- m_target.Vrm.LookAt.Process(m_target.LookAtTargetType, m_target.Gaze);
+ m_target.Runtime.LookAt.Process(m_target.LookAtTargetType, m_target.Gaze);
//
// expression
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs
new file mode 100644
index 000000000..c23e9d14b
--- /dev/null
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs
@@ -0,0 +1,127 @@
+using System;
+using UniGLTF.Extensions.VRMC_vrm;
+using UnityEditor;
+using UnityEngine;
+
+namespace UniVRM10
+{
+ public class Vrm10RuntimeLookAt: ILookAtEyeDirectionProvider
+ {
+ VRM10ObjectLookAt m_lookat;
+
+ private Transform m_head;
+ private Transform m_leftEye;
+ private Transform m_rightEye;
+ private ILookAtEyeDirectionApplicable _eyeDirectionApplicable;
+
+ internal ILookAtEyeDirectionApplicable EyeDirectionApplicable => _eyeDirectionApplicable;
+
+ public LookAtEyeDirection EyeDirection { get; private set; }
+
+ #region LookAtTargetTypes.CalcYawPitchToGaze
+ // 座標計算用のempty
+ Transform m_lookAtOrigin;
+ public Transform GetLookAtOrigin(Transform head)
+ {
+ if (!Application.isPlaying)
+ {
+ return null;
+ }
+ if (m_lookAtOrigin == null)
+ {
+ m_lookAtOrigin = new GameObject("_lookat_origin_").transform;
+ m_lookAtOrigin.SetParent(head);
+ }
+ return m_lookAtOrigin;
+ }
+
+ ///
+ /// Headローカルの注視点からYaw, Pitch角を計算する
+ ///
+ (float, float) CalcLookAtYawPitch(Vector3 targetWorldPosition, Transform head)
+ {
+ GetLookAtOrigin(head).localPosition = m_lookat.OffsetFromHead;
+
+ var localPosition = m_lookAtOrigin.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, Animator animator, Transform head, VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gaze)
+ {
+ m_lookat = lookat;
+
+ m_head = head;
+ m_leftEye = animator.GetBoneTransform(HumanBodyBones.LeftEye);
+ m_rightEye = animator.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;
+ }
+ switch (m_lookat.LookAtType)
+ {
+ case LookAtType.bone:
+ _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToBone(m_leftEye, m_rightEye, m_lookat.HorizontalOuter, m_lookat.HorizontalInner, m_lookat.VerticalDown, m_lookat.VerticalUp);
+ break;
+ case LookAtType.expression:
+ _eyeDirectionApplicable = new LookAtEyeDirectionApplicableToExpression(m_lookat.HorizontalOuter, m_lookat.HorizontalInner, m_lookat.VerticalDown, m_lookat.VerticalUp);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ public void Process(VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, Transform gaze)
+ {
+ var (yaw, pitch) = GetLookAtYawPitch(m_head, lookAtTargetType, gaze);
+ EyeDirection = new LookAtEyeDirection(yaw, pitch, 0, 0);
+ }
+
+ }
+}
diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs.meta
new file mode 100644
index 000000000..2a02c607a
--- /dev/null
+++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 08fd3fec20846764dbb598cf75b13356
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: