implement Constraint

This commit is contained in:
ousttrue
2021-04-01 15:00:17 +09:00
parent 572354079d
commit ca559b526e
13 changed files with 132 additions and 88 deletions

View File

@@ -7,7 +7,7 @@ namespace UniVRM10
/// FreezeAxesで使う。bitマスク
/// </summary>
[Flags]
public enum AxesMask
public enum AxisMask
{
X = 1,
Y = 2,
@@ -16,17 +16,17 @@ namespace UniVRM10
public static class AxesMaskExtensions
{
public static Vector3 Freeze(this AxesMask mask, Vector3 src)
public static Vector3 Freeze(this AxisMask mask, Vector3 src)
{
if (mask.HasFlag(AxesMask.X))
if (mask.HasFlag(AxisMask.X))
{
src.x = 0;
}
if (mask.HasFlag(AxesMask.Y))
if (mask.HasFlag(AxisMask.Y))
{
src.y = 0;
}
if (mask.HasFlag(AxesMask.Z))
if (mask.HasFlag(AxisMask.Z))
{
src.z = 0;
}

View File

@@ -1,33 +1,28 @@
using System;
using UniGLTF.Extensions.VRMC_constraints;
using UnityEngine;
namespace UniVRM10
{
public enum DestinationCoordinates
{
World,
Local,
}
class ConstraintDestination
{
readonly Transform m_transform;
readonly DestinationCoordinates m_coords;
readonly ObjectSpace m_coords;
readonly TRS m_initial;
public ConstraintDestination(Transform t, DestinationCoordinates coords)
public ConstraintDestination(Transform t, ObjectSpace coords)
{
m_transform = t;
m_coords = coords;
switch (m_coords)
{
case DestinationCoordinates.World:
m_initial = TRS.GetWorld(t);
break;
// case ObjectSpace.World:
// m_initial = TRS.GetWorld(t);
// break;
case DestinationCoordinates.Local:
case ObjectSpace.local:
m_initial = TRS.GetLocal(t);
break;
@@ -41,11 +36,11 @@ namespace UniVRM10
var value = m_initial.Translation + delta * weight;
switch (m_coords)
{
case DestinationCoordinates.World:
m_transform.position = value;
break;
// case DestinationCoordinates.World:
// m_transform.position = value;
// break;
case DestinationCoordinates.Local:
case ObjectSpace.local:
m_transform.localPosition = value;
break;
@@ -60,11 +55,11 @@ namespace UniVRM10
var value = Quaternion.LerpUnclamped(Quaternion.identity, delta, weight) * m_initial.Rotation;
switch (m_coords)
{
case DestinationCoordinates.World:
m_transform.rotation = value;
break;
// case DestinationCoordinates.World:
// m_transform.rotation = value;
// break;
case DestinationCoordinates.Local:
case ObjectSpace.local:
m_transform.localRotation = value;
break;

View File

@@ -1,33 +1,16 @@
using UnityEngine;
using System;
using UniGLTF.Extensions.VRMC_constraints;
namespace UniVRM10
{
public enum SourceCoordinates
{
/// <summary>
/// ワールド座標
/// </summary>
World,
/// <summary>
/// モデルルート(指定のTransform)ローカル座標
/// </summary>
Model,
/// <summary>
/// m_transform ローカル座標
/// </summary>
Local,
}
class ConstraintSource
{
readonly Transform m_modelRoot;
readonly Transform m_transform;
readonly SourceCoordinates m_coords;
readonly ObjectSpace m_coords;
readonly TRS m_initial;
@@ -37,9 +20,9 @@ namespace UniVRM10
{
switch (m_coords)
{
case SourceCoordinates.World: return m_transform.position - m_initial.Translation;
case SourceCoordinates.Local: return m_transform.localPosition - m_initial.Translation;
case SourceCoordinates.Model: return m_modelRoot.worldToLocalMatrix.MultiplyPoint(m_transform.position) - m_initial.Translation;
// case ObjectSpace.World: return m_transform.position - m_initial.Translation;
case ObjectSpace.local: return m_transform.localPosition - m_initial.Translation;
case ObjectSpace.model: return m_modelRoot.worldToLocalMatrix.MultiplyPoint(m_transform.position) - m_initial.Translation;
default: throw new NotImplementedException();
}
}
@@ -52,30 +35,30 @@ namespace UniVRM10
switch (m_coords)
{
// 右からかけるか、左からかけるか、それが問題なのだ
case SourceCoordinates.World: return m_transform.rotation * Quaternion.Inverse(m_initial.Rotation);
case SourceCoordinates.Local: return m_transform.localRotation * Quaternion.Inverse(m_initial.Rotation);
case SourceCoordinates.Model: return m_transform.rotation * Quaternion.Inverse(m_modelRoot.rotation) * Quaternion.Inverse(m_initial.Rotation);
// case SourceCoordinates.World: return m_transform.rotation * Quaternion.Inverse(m_initial.Rotation);
case ObjectSpace.local: return m_transform.localRotation * Quaternion.Inverse(m_initial.Rotation);
case ObjectSpace.model: return m_transform.rotation * Quaternion.Inverse(m_modelRoot.rotation) * Quaternion.Inverse(m_initial.Rotation);
default: throw new NotImplementedException();
}
}
}
public ConstraintSource(Transform t, SourceCoordinates coords, Transform modelRoot = null)
public ConstraintSource(Transform t, ObjectSpace coords, Transform modelRoot = null)
{
m_transform = t;
m_coords = coords;
switch (coords)
{
case SourceCoordinates.World:
m_initial = TRS.GetWorld(t);
break;
// case SourceCoordinates.World:
// m_initial = TRS.GetWorld(t);
// break;
case SourceCoordinates.Local:
case ObjectSpace.local:
m_initial = TRS.GetLocal(t);
break;
case SourceCoordinates.Model:
case ObjectSpace.model:
{
var world = TRS.GetWorld(t);
m_modelRoot = modelRoot;

View File

@@ -11,10 +11,10 @@ namespace UniVRM10
///
/// </summary>
[DisallowMultipleComponent]
public class VRMAimConstraint : VRMConstraint
public class VRM10AimConstraint : VRM10Constraint
{
[SerializeField]
Transform Source = default;
public Transform Source = default;
// [SerializeField]
// [Range(0, 10.0f)]
@@ -24,12 +24,13 @@ namespace UniVRM10
/// Forward
/// </summary>
[SerializeField]
Vector3 AimVector = Vector3.forward;
public Vector3 AimVector = Vector3.forward;
[SerializeField]
Vector3 UpVector = Vector3.up;
public Vector3 UpVector = Vector3.up;
Vector3 RightVector;
[SerializeField]
public Vector3 RightVector;
Quaternion m_selfInitial;
Matrix4x4 m_coords;

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 0f104dcf447611a4ca99f4ac41e806e8
guid: e1e8c3a00191fbd4db98fb47ddb80e8c
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -2,7 +2,7 @@ using UnityEngine;
namespace UniVRM10
{
public abstract class VRMConstraint : MonoBehaviour
public abstract class VRM10Constraint : MonoBehaviour
{
public virtual void Process()
{

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a8f13bc2bb7b6734e92bba2b204e2e49
guid: ded8c4db12c688b46814cf0bf925cacf
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using UniGLTF.Extensions.VRMC_constraints;
using UnityEngine;
namespace UniVRM10
{
@@ -6,26 +7,26 @@ namespace UniVRM10
/// 対象の初期位置と現在位置の差分(delta)を、自身の初期位置に対してWeightを乗算して加算する。
/// </summary>
[DisallowMultipleComponent]
public class VRMPositionConstraint : VRMConstraint
public class VRM10PositionConstraint : VRM10Constraint
{
[SerializeField]
Transform Source = default;
public Transform Source = default;
[SerializeField]
SourceCoordinates SourceCoordinate = default;
public ObjectSpace SourceCoordinate = default;
[SerializeField]
DestinationCoordinates DestinationCoordinate = default;
public ObjectSpace DestinationCoordinate = default;
[SerializeField]
AxesMask FreezeAxes = default;
public AxisMask FreezeAxes = default;
[SerializeField]
[Range(0, 10.0f)]
float Weight = 1.0f;
public float Weight = 1.0f;
[SerializeField]
Transform ModelRoot = default;
public Transform ModelRoot = default;
ConstraintSource m_src;

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e7e95091802973e488fdcc4b3840cdc5
guid: 6fec0847a81b2124c9f67575d247b1f9
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using UniGLTF.Extensions.VRMC_constraints;
using UnityEngine;
namespace UniVRM10
@@ -7,26 +8,26 @@ namespace UniVRM10
/// 対象の初期回転と現在回転の差分(delta)を、自身の初期回転と自身の初期回転にdeltaを乗算したものに対してWeightでSlerpする。
/// </summary>
[DisallowMultipleComponent]
public class VRMRotationConstraint : VRMConstraint
public class VRM10RotationConstraint : VRM10Constraint
{
[SerializeField]
Transform Source = default;
public Transform Source = default;
[SerializeField]
SourceCoordinates SourceCoordinate = default;
public ObjectSpace SourceCoordinate = default;
[SerializeField]
DestinationCoordinates DestinationCoordinate = default;
public ObjectSpace DestinationCoordinate = default;
[SerializeField]
AxesMask FreezeAxes = default;
public AxisMask FreezeAxes = default;
[SerializeField]
[Range(0, 10.0f)]
float Weight = 1.0f;
public float Weight = 1.0f;
[SerializeField]
Transform ModelRoot = default;
public Transform ModelRoot = default;
ConstraintSource m_src;

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e017e9a63d31c4e4cbcc905a0caf0605
guid: 7a07fbecedce41b4396f286fd7634e1d
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -55,7 +55,7 @@ namespace UniVRM10
}
}
VRMConstraint[] m_constraints;
VRM10Constraint[] m_constraints;
Transform m_head;
public Transform Head
@@ -113,7 +113,7 @@ namespace UniVRM10
//
if (m_constraints == null)
{
m_constraints = GetComponentsInChildren<VRMConstraint>();
m_constraints = GetComponentsInChildren<VRM10Constraint>();
}
foreach (var constraint in m_constraints)
{

View File

@@ -346,7 +346,7 @@ namespace UniVRM10
var joint = new VRM10SpringJoint(Nodes[gltfJoint.Node.Value]);
joint.m_jointRadius = gltfJoint.HitRadius.Value;
joint.m_dragForce = gltfJoint.DragForce.Value;
joint.m_gravityDir = new Vector3(gltfJoint.GravityDir[0], gltfJoint.GravityDir[1], gltfJoint.GravityDir[2]);
joint.m_gravityDir = Vector3(gltfJoint.GravityDir);
joint.m_gravityPower = gltfJoint.GravityPower.Value;
joint.m_stiffnessForce = gltfJoint.Stiffness.Value;
// joint.m_exclude = gltfJoint.Exclude.GetValueOrDefault();
@@ -368,7 +368,7 @@ namespace UniVRM10
return new VRM10SpringBoneCollider
{
ColliderType = VRM10SpringBoneColliderTypes.Sphere,
Offset = new Vector3(x.Sphere.Offset[0], x.Sphere.Offset[1], x.Sphere.Offset[2]),
Offset = Vector3(x.Sphere.Offset),
Radius = x.Sphere.Radius.Value,
};
}
@@ -377,9 +377,9 @@ namespace UniVRM10
return new VRM10SpringBoneCollider
{
ColliderType = VRM10SpringBoneColliderTypes.Capsule,
Offset = new Vector3(x.Capsule.Offset[0], x.Capsule.Offset[1], x.Capsule.Offset[2]),
Offset = Vector3(x.Capsule.Offset),
Radius = x.Capsule.Radius.Value,
Tail = new Vector3(x.Capsule.Tail[0], x.Capsule.Tail[1], x.Capsule.Tail[2]),
Tail = Vector3(x.Capsule.Tail),
};
}
else
@@ -400,8 +400,71 @@ namespace UniVRM10
}
}
static AxisMask FreezeAxis(bool[] flags)
{
var mask = default(AxisMask);
if (flags != null && flags.Length == 3)
{
if (flags[0]) mask |= AxisMask.X;
if (flags[1]) mask |= AxisMask.Y;
if (flags[2]) mask |= AxisMask.Z;
}
return mask;
}
static Vector3 Vector3(float[] f)
{
var v = default(Vector3);
if (f != null && f.Length == 3)
{
v.x = f[0];
v.y = f[1];
v.z = f[2];
}
return v;
}
async Task LoadConstraintAsync(IAwaitCaller awaitCaller, VRM10Controller controller)
{
for (int i = 0; i < Parser.GLTF.nodes.Count; ++i)
{
var gltfNode = Parser.GLTF.nodes[i];
if (UniGLTF.Extensions.VRMC_constraints.GltfDeserializer.TryGet(gltfNode.extensions, out UniGLTF.Extensions.VRMC_constraints.VRMC_constraints constraint))
{
var node = Nodes[i];
if (constraint.Position != null)
{
var p = constraint.Position;
var positionConstraint = node.gameObject.AddComponent<VRM10PositionConstraint>();
positionConstraint.SourceCoordinate = p.SourceSpace;
positionConstraint.Source = Nodes[p.Source.Value];
positionConstraint.DestinationCoordinate = p.DestinationSpace;
positionConstraint.FreezeAxes = FreezeAxis(p.FreezeAxes);
positionConstraint.Weight = p.Weight.Value;
positionConstraint.ModelRoot = Root.transform;
}
else if (constraint.Rotation != null)
{
var r = constraint.Rotation;
var rotationConstraint = node.gameObject.AddComponent<VRM10RotationConstraint>();
rotationConstraint.SourceCoordinate = r.SourceSpace;
rotationConstraint.Source = Nodes[r.Source.Value];
rotationConstraint.DestinationCoordinate = r.DestinationSpace;
rotationConstraint.FreezeAxes = FreezeAxis(r.FreezeAxes);
rotationConstraint.Weight = r.Weight.Value;
rotationConstraint.ModelRoot = Root.transform;
}
else if (constraint.Aim != null)
{
var a = constraint.Aim;
var aimConstraint = node.gameObject.AddComponent<VRM10AimConstraint>();
aimConstraint.Source = Nodes[a.Source.Value];
aimConstraint.AimVector = Vector3(a.AimVector);
aimConstraint.UpVector = Vector3(a.UpVector);
}
}
}
await awaitCaller.NextFrame();
}