仕様に準拠

This commit is contained in:
ousttrue
2022-04-12 15:04:12 +09:00
parent 325fe98980
commit d2f17b9257
7 changed files with 144 additions and 74 deletions

View File

@@ -1,28 +0,0 @@
using UnityEditor;
using UnityEngine;
namespace UniVRM10
{
[CustomPropertyDrawer(typeof(VRM10RotationOffset))]
public class IngredientDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 16f + 18f;
}
// Draw the property inside the given rect
void DrawEuler(Rect position, SerializedProperty property)
{
Vector3 euler = property.quaternionValue.eulerAngles;
euler = EditorGUI.Vector3Field(position, "Offset", euler);
property.quaternionValue = Quaternion.Euler(euler);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
DrawEuler(position, property.FindPropertyRelative(nameof(VRM10RotationOffset.Rotation)));
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 615a7cbd2c3cd5d42ab2719d6e74c1b8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -15,9 +15,38 @@ namespace UniVRM10
[Range(0, 10.0f)]
public float Weight = 1.0f;
Quaternion _srcRestLocalQuatInverse;
Quaternion _dstRestLocalQuat;
void Awake()
{
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_draft/README.ja.md#example-of-implementation-2
///
/// srcDeltaQuat = srcRestQuat.inverse * srcQuat
/// targetQuat = Quaternion.slerp(
/// dstRestQuat,
/// dstRestQuat * srcDeltaQuat,
/// weight
/// )
/// </summary>
public override void Process()
{
throw new System.NotImplementedException();
if (Source == null) return;
// local coords
var srcDeltaLocalQuat = _srcRestLocalQuatInverse * Source.localRotation;
transform.localRotation = Quaternion.SlerpUnclamped(_dstRestLocalQuat, _dstRestLocalQuat * srcDeltaLocalQuat, Weight);
}
}
}

View File

@@ -1,17 +0,0 @@
using System;
using UnityEngine;
namespace UniVRM10
{
[Serializable]
public struct VRM10RotationOffset
{
[SerializeField]
public Quaternion Rotation;
public static VRM10RotationOffset Identity => new VRM10RotationOffset
{
Rotation = Quaternion.identity,
};
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 5b8a5228a8756d64684e8dca601ccafc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,6 @@
using UnityEngine;
using System;
using UniGLTF.Extensions.VRMC_node_constraint;
using UnityEngine;
namespace UniVRM10
{
@@ -16,11 +18,61 @@ namespace UniVRM10
public float Weight = 1.0f;
[SerializeField]
public UniGLTF.Extensions.VRMC_node_constraint.AimAxis AimAxis;
public AimAxis AimAxis;
Vector3 GetAxisVector()
{
switch (AimAxis)
{
case AimAxis.PositiveX: return Vector3.right;
case AimAxis.NegativeX: return Vector3.left;
case AimAxis.PositiveY: return Vector3.up;
case AimAxis.NegativeY: return Vector3.down;
case AimAxis.PositiveZ: return Vector3.forward;
case AimAxis.NegativeZ: return Vector3.back;
default: throw new NotImplementedException();
}
}
Quaternion _dstRestLocalQuat;
void Awake()
{
if (Source == null)
{
this.enabled = false;
return;
}
_dstRestLocalQuat = transform.localRotation;
}
/// <summary>
/// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/README.ja.md#example-of-implementation-1
///
/// fromVec = aimAxis.applyQuaternion( dstParentWorldQuat * dstRestQuat )
/// toVec = ( srcWorldPos - dstWorldPos ).normalized
/// fromToQuat = Quaternion.fromToRotation( fromVec, toVec )
/// targetQuat = Quaternion.slerp(
/// dstRestQuat,
/// dstParentWorldQuat.inverse * fromToQuat * dstParentWorldQuat * dstRestQuat,
/// weight
/// )
/// </summary>
public override void Process()
{
throw new System.NotImplementedException();
if (Source == null) return;
// world coords
var dstParentWorldQuat = transform.parent != null ? transform.parent.rotation : Quaternion.identity;
var fromVec = (dstParentWorldQuat * _dstRestLocalQuat) * GetAxisVector();
var toVec = (Source.position - transform.position).normalized;
var fromToQuat = Quaternion.FromToRotation(fromVec, toVec);
transform.rotation = Quaternion.SlerpUnclamped(
_dstRestLocalQuat,
Quaternion.Inverse(dstParentWorldQuat) * fromToQuat * dstParentWorldQuat * _dstRestLocalQuat,
Weight
);
}
}
}

View File

@@ -1,4 +1,6 @@
using UnityEngine;
using System;
using UniGLTF.Extensions.VRMC_node_constraint;
using UnityEngine;
namespace UniVRM10
{
@@ -16,11 +18,65 @@ namespace UniVRM10
public float Weight = 1.0f;
[SerializeField]
public UniGLTF.Extensions.VRMC_node_constraint.RollAxis RollAxis;
public RollAxis RollAxis;
Vector3 GetRollVector()
{
switch (RollAxis)
{
case RollAxis.X: return Vector3.right;
case RollAxis.Y: return Vector3.up;
case RollAxis.Z: return Vector3.forward;
default: throw new NotImplementedException();
}
}
Quaternion _srcRestLocalQuat;
Quaternion _dstRestLocalQuat;
void Awake()
{
if (Source == null)
{
this.enabled = false;
return;
}
_srcRestLocalQuat = Source.localRotation;
_dstRestLocalQuat = transform.localRotation;
}
/// <summary>
/// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0_draft/README.ja.md#example-of-implementation
///
/// deltaSrcQuat = srcRestQuat.inverse * srcQuat
/// deltaSrcQuatInParent = srcRestQuat * deltaSrcQuat * srcRestQuat.inverse // source to parent
/// deltaSrcQuatInDst = dstRestQuat.inverse * deltaSrcQuatInWorld * dstRestQuat // parent to destination
///
/// toVec = rollAxis.applyQuaternion( deltaSrcQuatInDst )
/// fromToQuat = Quaternion.fromToRotation( rollAxis, toVec )
///
/// targetQuat = Quaternion.slerp(
/// dstRestQuat,
/// dstRestQuat * fromToQuat.inverse * deltaSrcQuatInDst,
/// weight
/// )
/// </summary>
public override void Process()
{
throw new System.NotImplementedException();
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 rollAxis = GetRollVector();
var toVec = deltaSrcQuatInDst * rollAxis;
var fromToQuat = Quaternion.FromToRotation(rollAxis, toVec);
transform.localRotation = Quaternion.SlerpUnclamped(
_dstRestLocalQuat,
_dstRestLocalQuat * Quaternion.Inverse(fromToQuat) * deltaSrcQuatInDst,
Weight
);
}
}
}