mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-22 18:45:06 -05:00
use RuntimeGltfInstance.InitialTransformStates
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
using UniGLTF.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public interface IVrm10Constraint
|
||||
{
|
||||
internal void Process();
|
||||
Transform ConstraintDst { get; }
|
||||
Transform ConstriantSrc { get; }
|
||||
|
||||
GameObject ConstraintTarget { get; }
|
||||
/// <param name="targetInitState"></param>
|
||||
/// <param name="srcInitState"></param>
|
||||
internal void Process(in TransformState dstInitState, in TransformState srcInitState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using UniGLTF.Extensions.VRMC_node_constraint;
|
||||
using UniGLTF.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
@@ -10,8 +11,6 @@ namespace UniVRM10
|
||||
[DisallowMultipleComponent]
|
||||
public class Vrm10AimConstraint : MonoBehaviour, IVrm10Constraint
|
||||
{
|
||||
public GameObject ConstraintTarget => gameObject;
|
||||
|
||||
[SerializeField]
|
||||
public Transform Source = default;
|
||||
|
||||
@@ -36,18 +35,10 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
|
||||
Quaternion _dstRestLocalQuat;
|
||||
Transform IVrm10Constraint.ConstraintDst => transform;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (Source == null)
|
||||
{
|
||||
this.enabled = false;
|
||||
return;
|
||||
}
|
||||
Transform IVrm10Constraint.ConstriantSrc => Source;
|
||||
|
||||
_dstRestLocalQuat = transform.localRotation;
|
||||
}
|
||||
/// <summary>
|
||||
/// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_beta/README.ja.md#example-of-implementation-1
|
||||
///
|
||||
@@ -60,19 +51,17 @@ namespace UniVRM10
|
||||
/// weight
|
||||
/// )
|
||||
/// </summary>
|
||||
void IVrm10Constraint.Process()
|
||||
void IVrm10Constraint.Process(in TransformState dstInitState, in TransformState srcInitState)
|
||||
{
|
||||
if (Source == null) return;
|
||||
|
||||
// world coords
|
||||
var dstParentWorldQuat = transform.parent != null ? transform.parent.rotation : Quaternion.identity;
|
||||
var fromVec = (dstParentWorldQuat * _dstRestLocalQuat) * GetAxisVector();
|
||||
var fromVec = (dstParentWorldQuat * dstInitState.LocalRotation) * GetAxisVector();
|
||||
var toVec = (Source.position - transform.position).normalized;
|
||||
var fromToQuat = Quaternion.FromToRotation(fromVec, toVec);
|
||||
|
||||
transform.localRotation = Quaternion.SlerpUnclamped(
|
||||
_dstRestLocalQuat,
|
||||
Quaternion.Inverse(dstParentWorldQuat) * fromToQuat * dstParentWorldQuat * _dstRestLocalQuat,
|
||||
dstInitState.LocalRotation,
|
||||
Quaternion.Inverse(dstParentWorldQuat) * fromToQuat * dstParentWorldQuat * dstInitState.LocalRotation,
|
||||
Weight
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using UniGLTF.Extensions.VRMC_node_constraint;
|
||||
using UniGLTF.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
@@ -10,8 +11,6 @@ namespace UniVRM10
|
||||
[DisallowMultipleComponent]
|
||||
public class Vrm10RollConstraint : MonoBehaviour, IVrm10Constraint
|
||||
{
|
||||
public GameObject ConstraintTarget => gameObject;
|
||||
|
||||
[SerializeField]
|
||||
public Transform Source = default;
|
||||
|
||||
@@ -32,20 +31,10 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
|
||||
Quaternion _srcRestLocalQuat;
|
||||
Quaternion _dstRestLocalQuat;
|
||||
Transform IVrm10Constraint.ConstraintDst => transform;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (Source == null)
|
||||
{
|
||||
this.enabled = false;
|
||||
return;
|
||||
}
|
||||
Transform IVrm10Constraint.ConstriantSrc => Source?.transform;
|
||||
|
||||
_srcRestLocalQuat = Source.localRotation;
|
||||
_dstRestLocalQuat = transform.localRotation;
|
||||
}
|
||||
/// <summary>
|
||||
/// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_beta/README.ja.md#example-of-implementation
|
||||
///
|
||||
@@ -62,21 +51,19 @@ namespace UniVRM10
|
||||
/// weight
|
||||
/// )
|
||||
/// </summary>
|
||||
void IVrm10Constraint.Process()
|
||||
void IVrm10Constraint.Process(in TransformState dstInitState, in TransformState srcInitState)
|
||||
{
|
||||
if (Source == null) return;
|
||||
|
||||
var deltaSrcQuat = Quaternion.Inverse(_srcRestLocalQuat) * Source.localRotation;
|
||||
var deltaSrcQuatInParent = _srcRestLocalQuat * deltaSrcQuat * Quaternion.Inverse(_srcRestLocalQuat); // source to parent
|
||||
var deltaSrcQuatInDst = Quaternion.Inverse(_dstRestLocalQuat) * deltaSrcQuatInParent * _dstRestLocalQuat; // parent to destination
|
||||
var deltaSrcQuat = Quaternion.Inverse(srcInitState.LocalRotation) * Source.localRotation;
|
||||
var deltaSrcQuatInParent = srcInitState.LocalRotation * deltaSrcQuat * Quaternion.Inverse(srcInitState.LocalRotation); // source to parent
|
||||
var deltaSrcQuatInDst = Quaternion.Inverse(dstInitState.LocalRotation) * deltaSrcQuatInParent * dstInitState.LocalRotation; // parent to destination
|
||||
|
||||
var rollAxis = GetRollVector();
|
||||
var toVec = deltaSrcQuatInDst * rollAxis;
|
||||
var fromToQuat = Quaternion.FromToRotation(rollAxis, toVec);
|
||||
|
||||
transform.localRotation = Quaternion.SlerpUnclamped(
|
||||
_dstRestLocalQuat,
|
||||
_dstRestLocalQuat * Quaternion.Inverse(fromToQuat) * deltaSrcQuatInDst,
|
||||
dstInitState.LocalRotation,
|
||||
dstInitState.LocalRotation * Quaternion.Inverse(fromToQuat) * deltaSrcQuatInDst,
|
||||
Weight
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using UniGLTF.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
@@ -8,7 +9,9 @@ namespace UniVRM10
|
||||
[DisallowMultipleComponent]
|
||||
public class Vrm10RotationConstraint : MonoBehaviour, IVrm10Constraint
|
||||
{
|
||||
public GameObject ConstraintTarget => gameObject;
|
||||
Transform IVrm10Constraint.ConstraintDst => transform;
|
||||
|
||||
Transform IVrm10Constraint.ConstriantSrc => Source;
|
||||
|
||||
[SerializeField]
|
||||
public Transform Source = default;
|
||||
@@ -17,21 +20,6 @@ namespace UniVRM10
|
||||
[Range(0, 1.0f)]
|
||||
public float Weight = 1.0f;
|
||||
|
||||
Quaternion _srcRestLocalQuatInverse;
|
||||
Quaternion _dstRestLocalQuat;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (Source == null)
|
||||
{
|
||||
this.enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_srcRestLocalQuatInverse = Quaternion.Inverse(Source.localRotation);
|
||||
_dstRestLocalQuat = transform.localRotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_beta/README.ja.md#example-of-implementation-2
|
||||
///
|
||||
@@ -42,13 +30,11 @@ namespace UniVRM10
|
||||
/// weight
|
||||
/// )
|
||||
/// </summary>
|
||||
void IVrm10Constraint.Process()
|
||||
void IVrm10Constraint.Process(in TransformState dstInitState, in TransformState srcInitState)
|
||||
{
|
||||
if (Source == null) return;
|
||||
|
||||
// local coords
|
||||
var srcDeltaLocalQuat = _srcRestLocalQuatInverse * Source.localRotation;
|
||||
transform.localRotation = Quaternion.SlerpUnclamped(_dstRestLocalQuat, _dstRestLocalQuat * srcDeltaLocalQuat, Weight);
|
||||
var srcDeltaLocalQuat = Quaternion.Inverse(srcInitState.LocalRotation) * Source.localRotation;
|
||||
transform.localRotation = Quaternion.SlerpUnclamped(dstInitState.LocalRotation, dstInitState.LocalRotation * srcDeltaLocalQuat, Weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
@@ -46,14 +49,26 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<Transform, TransformState> _initPose;
|
||||
|
||||
public Vrm10Runtime(Vrm10Instance instance, bool useControlRig, IVrm10SpringBoneRuntime springBoneRuntime)
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
UniGLTFLogger.Warning($"{nameof(Vrm10Runtime)} expects runtime behaviour.");
|
||||
}
|
||||
if (instance == null)
|
||||
{
|
||||
m_instance = null;
|
||||
return;
|
||||
}
|
||||
|
||||
m_instance = instance;
|
||||
if (m_instance != instance)
|
||||
{
|
||||
m_instance = instance;
|
||||
var runtime = m_instance.GetComponent<RuntimeGltfInstance>();
|
||||
_initPose = runtime.InitialTransformStates.ToDictionary((kv) => kv.Key, (kv) => kv.Value);
|
||||
}
|
||||
|
||||
if (!instance.TryGetBoneTransform(HumanBodyBones.Head, out m_head))
|
||||
{
|
||||
@@ -121,7 +136,12 @@ namespace UniVRM10
|
||||
// 3. Constraints
|
||||
foreach (var constraint in Constraints)
|
||||
{
|
||||
constraint.Process();
|
||||
if (constraint.ConstriantSrc != null)
|
||||
{
|
||||
constraint.Process(
|
||||
dstInitState: _initPose[constraint.ConstraintDst],
|
||||
srcInitState: _initPose[constraint.ConstriantSrc]);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_instance.LookAtTargetType == VRM10ObjectLookAt.LookAtTargetTypes.SpecifiedTransform
|
||||
|
||||
@@ -601,7 +601,7 @@ namespace UniVRM10
|
||||
}
|
||||
|
||||
// serialize to gltfNode
|
||||
var node = converter.Nodes[constraint.ConstraintTarget];
|
||||
var node = converter.Nodes[constraint.ConstraintDst.gameObject];
|
||||
var nodeIndex = model.Nodes.IndexOf(node);
|
||||
var gltfNode = nodes[nodeIndex];
|
||||
UniGLTF.Extensions.VRMC_node_constraint.GltfSerializer.SerializeTo(ref gltfNode.extensions, vrmConstraint);
|
||||
|
||||
Reference in New Issue
Block a user