mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-15 23:27:19 -05:00
Joint別パラメーターを実装
This commit is contained in:
@@ -36,8 +36,6 @@ namespace UniVRM10
|
||||
}
|
||||
public Vector3 m_boneAxis;
|
||||
|
||||
public float Radius { get; set; }
|
||||
|
||||
public SpringBoneLogic(Transform center, Transform transform, Vector3 localChildPosition)
|
||||
{
|
||||
m_transform = transform;
|
||||
@@ -73,7 +71,7 @@ namespace UniVRM10
|
||||
|
||||
public void Update(Transform center,
|
||||
float stiffnessForce, float dragForce, Vector3 external,
|
||||
List<InternalCollider> colliders)
|
||||
List<InternalCollider> colliders, float jointRadius)
|
||||
{
|
||||
var currentTail = center != null
|
||||
? center.TransformPoint(m_currentTail)
|
||||
@@ -95,7 +93,7 @@ namespace UniVRM10
|
||||
nextTail = m_transform.position + (nextTail - m_transform.position).normalized * m_length;
|
||||
|
||||
// Collisionで移動
|
||||
nextTail = Collision(colliders, nextTail);
|
||||
nextTail = Collision(colliders, nextTail, jointRadius);
|
||||
|
||||
m_prevTail = center != null
|
||||
? center.InverseTransformPoint(currentTail)
|
||||
@@ -117,14 +115,14 @@ namespace UniVRM10
|
||||
nextTail - m_transform.position) * rotation;
|
||||
}
|
||||
|
||||
bool TrySphereCollision(Vector3 worldPosition, float radius, ref Vector3 nextTail)
|
||||
bool TrySphereCollision(Vector3 worldPosition, float radius, ref Vector3 nextTail, float jointRadius)
|
||||
{
|
||||
var r = Radius + radius;
|
||||
var r = jointRadius + radius;
|
||||
if (Vector3.SqrMagnitude(nextTail - worldPosition) <= (r * r))
|
||||
{
|
||||
// ヒット。Colliderの半径方向に押し出す
|
||||
var normal = (nextTail - worldPosition).normalized;
|
||||
var posFromCollider = worldPosition + normal * (Radius + radius);
|
||||
var posFromCollider = worldPosition + normal * (jointRadius + radius);
|
||||
// 長さをboneLengthに強制
|
||||
nextTail = m_transform.position + (posFromCollider - m_transform.position).normalized * m_length;
|
||||
return true;
|
||||
@@ -135,7 +133,7 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
|
||||
bool TryCapsuleCollision(in InternalCollider collider, ref Vector3 nextTail)
|
||||
bool TryCapsuleCollision(in InternalCollider collider, ref Vector3 nextTail, float jointRadius)
|
||||
{
|
||||
var P = collider.WorldTail - collider.WorldPosition;
|
||||
var Q = m_transform.position - collider.WorldPosition;
|
||||
@@ -143,22 +141,22 @@ namespace UniVRM10
|
||||
if (dot <= 0)
|
||||
{
|
||||
// head側半球の球判定
|
||||
return TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail);
|
||||
return TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail, jointRadius);
|
||||
}
|
||||
|
||||
var t = dot / P.magnitude;
|
||||
if (t >= 1.0f)
|
||||
{
|
||||
// tail側半球の球判定
|
||||
return TrySphereCollision(collider.WorldTail, collider.Radius, ref nextTail);
|
||||
return TrySphereCollision(collider.WorldTail, collider.Radius, ref nextTail, jointRadius);
|
||||
}
|
||||
|
||||
// head-tail上の m_transform.position との最近点
|
||||
var p = collider.WorldPosition + P * t;
|
||||
return TrySphereCollision(p, collider.Radius, ref nextTail);
|
||||
return TrySphereCollision(p, collider.Radius, ref nextTail, jointRadius);
|
||||
}
|
||||
|
||||
protected virtual Vector3 Collision(List<InternalCollider> colliders, Vector3 nextTail)
|
||||
protected virtual Vector3 Collision(List<InternalCollider> colliders, Vector3 nextTail, float jointRadius)
|
||||
{
|
||||
foreach (var collider in colliders)
|
||||
{
|
||||
@@ -166,11 +164,11 @@ namespace UniVRM10
|
||||
switch (collider.ColliderTypes)
|
||||
{
|
||||
case VRM10SpringBoneColliderTypes.Sphere:
|
||||
TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail);
|
||||
TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail, jointRadius);
|
||||
break;
|
||||
|
||||
case VRM10SpringBoneColliderTypes.Capsule:
|
||||
TryCapsuleCollision(in collider, ref nextTail);
|
||||
TryCapsuleCollision(in collider, ref nextTail, jointRadius);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public class SpringBoneProcessor
|
||||
{
|
||||
List<SpringBoneLogic> m_logics = new List<SpringBoneLogic>();
|
||||
Dictionary<Transform, Quaternion> m_initialLocalRotationMap;
|
||||
|
||||
|
||||
public void ResetSpringBone()
|
||||
{
|
||||
foreach (var verlet in m_logics)
|
||||
{
|
||||
verlet.Head.localRotation = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetupRecursive(Transform parent, Transform center)
|
||||
{
|
||||
if (parent.childCount == 0)
|
||||
{
|
||||
// 末端に追加のスプリングを付加する
|
||||
var delta = parent.position - parent.parent.position;
|
||||
var childPosition = parent.position + delta.normalized * 0.07f;
|
||||
m_logics.Add(new SpringBoneLogic(center, parent, parent.worldToLocalMatrix.MultiplyPoint(childPosition)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 最初の子ボーンを尻尾としてスプリングを付加する
|
||||
var firstChild = parent.GetChild(0);
|
||||
var localPosition = firstChild.localPosition;
|
||||
var scale = firstChild.lossyScale;
|
||||
m_logics.Add(new SpringBoneLogic(center, parent,
|
||||
new Vector3(
|
||||
localPosition.x * scale.x,
|
||||
localPosition.y * scale.y,
|
||||
localPosition.z * scale.z
|
||||
)))
|
||||
;
|
||||
}
|
||||
|
||||
foreach (Transform child in parent)
|
||||
{
|
||||
SetupRecursive(child, center);
|
||||
}
|
||||
}
|
||||
|
||||
void Setup(List<Transform> RootBones, Transform m_center, bool force = false)
|
||||
{
|
||||
if (force || m_initialLocalRotationMap == null)
|
||||
{
|
||||
m_initialLocalRotationMap = new Dictionary<Transform, Quaternion>();
|
||||
}
|
||||
else
|
||||
{
|
||||
// restore initial rotation
|
||||
foreach (var kv in m_initialLocalRotationMap)
|
||||
{
|
||||
kv.Key.localRotation = kv.Value;
|
||||
}
|
||||
m_initialLocalRotationMap.Clear();
|
||||
}
|
||||
m_logics.Clear();
|
||||
|
||||
foreach (var transform in RootBones)
|
||||
{
|
||||
if (transform != null)
|
||||
{
|
||||
foreach (var x in transform.Traverse())
|
||||
{
|
||||
// backup initial rotation
|
||||
m_initialLocalRotationMap[x] = x.localRotation;
|
||||
}
|
||||
|
||||
SetupRecursive(transform, m_center);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(List<Transform> RootBones, List<SpringBoneLogic.InternalCollider> m_colliderList,
|
||||
float stiffness, float m_dragForce, Vector3 external,
|
||||
float m_hitRadius, Transform m_center)
|
||||
{
|
||||
if (m_logics == null || m_logics.Count == 0)
|
||||
{
|
||||
Setup(RootBones, m_center);
|
||||
}
|
||||
|
||||
foreach (var verlet in m_logics)
|
||||
{
|
||||
verlet.Radius = m_hitRadius;
|
||||
verlet.Update(m_center,
|
||||
stiffness,
|
||||
m_dragForce,
|
||||
external,
|
||||
m_colliderList
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawGizmos(Transform m_center, float m_hitRadius, Color m_gizmoColor)
|
||||
{
|
||||
foreach (var verlet in m_logics)
|
||||
{
|
||||
verlet.DrawGizmo(m_center, m_hitRadius, m_gizmoColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
@@ -20,25 +21,6 @@ namespace UniVRM10
|
||||
[SerializeField]
|
||||
Color m_gizmoColor = Color.yellow;
|
||||
|
||||
[Serializable]
|
||||
public class VRM10SpringJoint
|
||||
{
|
||||
[SerializeField, Range(0, 4), Header("Settings")]
|
||||
public float m_stiffnessForce = 1.0f;
|
||||
|
||||
[SerializeField, Range(0, 2)]
|
||||
public float m_gravityPower = 0;
|
||||
|
||||
[SerializeField]
|
||||
public Vector3 m_gravityDir = new Vector3(0, -1.0f, 0);
|
||||
|
||||
[SerializeField, Range(0, 1)]
|
||||
public float m_dragForce = 0.4f;
|
||||
|
||||
[SerializeField, Range(0, 0.5f), Header("Collision")]
|
||||
public float m_hitRadius = 0.02f;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
public Transform m_center;
|
||||
|
||||
@@ -48,12 +30,17 @@ namespace UniVRM10
|
||||
[SerializeField]
|
||||
public List<VRM10SpringBoneColliderGroup> ColliderGroups = new List<VRM10SpringBoneColliderGroup>();
|
||||
|
||||
SpringBoneProcessor m_processor = new SpringBoneProcessor();
|
||||
|
||||
[ContextMenu("Reset bones")]
|
||||
public void ResetSpringBone()
|
||||
public void ResetJoints()
|
||||
{
|
||||
m_processor.ResetSpringBone();
|
||||
foreach (var joint in Joints)
|
||||
{
|
||||
if (joint != null)
|
||||
{
|
||||
joint.Transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<SpringBoneLogic.InternalCollider> m_colliderList = new List<SpringBoneLogic.InternalCollider>();
|
||||
@@ -101,20 +88,30 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
|
||||
// var stiffness = m_stiffnessForce * Time.deltaTime;
|
||||
// var external = m_gravityDir * (m_gravityPower * Time.deltaTime);
|
||||
|
||||
// m_processor.Update(RootBones, m_colliderList,
|
||||
// stiffness, m_dragForce, external,
|
||||
// m_hitRadius, m_center);
|
||||
{
|
||||
// udpate joints
|
||||
VRM10SpringJoint lastJoint = Joints.FirstOrDefault(x => x != null);
|
||||
foreach (var joint in Joints.Where(x => x != null).Skip(1))
|
||||
{
|
||||
lastJoint.Update(m_center, Time.deltaTime, m_colliderList, joint);
|
||||
lastJoint = joint;
|
||||
}
|
||||
lastJoint.Update(m_center, Time.deltaTime, m_colliderList, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
// if (m_drawGizmo)
|
||||
// {
|
||||
// m_processor.DrawGizmos(m_center, m_hitRadius, m_gizmoColor);
|
||||
// }
|
||||
if (m_drawGizmo)
|
||||
{
|
||||
foreach (var joint in Joints)
|
||||
{
|
||||
if (joint != null)
|
||||
{
|
||||
joint.DrawGizmo(m_center, m_gizmoColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
[Serializable]
|
||||
public class VRM10SpringJoint
|
||||
{
|
||||
[SerializeField]
|
||||
public Transform Transform;
|
||||
|
||||
public VRM10SpringJoint(Transform t)
|
||||
{
|
||||
Transform = t;
|
||||
}
|
||||
|
||||
[SerializeField, Range(0, 4), Header("Settings")]
|
||||
public float m_stiffnessForce = 1.0f;
|
||||
|
||||
[SerializeField, Range(0, 2)]
|
||||
public float m_gravityPower = 0;
|
||||
|
||||
[SerializeField]
|
||||
public Vector3 m_gravityDir = new Vector3(0, -1.0f, 0);
|
||||
|
||||
[SerializeField, Range(0, 1)]
|
||||
public float m_dragForce = 0.4f;
|
||||
|
||||
[SerializeField, Range(0, 0.5f), Header("Collision")]
|
||||
public float m_hitRadius = 0.02f;
|
||||
|
||||
SpringBoneLogic m_logic;
|
||||
|
||||
public void DrawGizmo(Transform center, Color color)
|
||||
{
|
||||
if (m_logic != null)
|
||||
{
|
||||
m_logic.DrawGizmo(center, m_hitRadius, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(Transform center, float deltaTime, List<SpringBoneLogic.InternalCollider> colliders, VRM10SpringJoint tail)
|
||||
{
|
||||
if (m_logic == null)
|
||||
{
|
||||
// Setup(joints, m_center);
|
||||
// SetupRecursive(joint, m_center);
|
||||
if (tail == null)
|
||||
{
|
||||
// 末端に追加のスプリングを付加する
|
||||
var delta = Transform.position - Transform.parent.position;
|
||||
var childPosition = Transform.position + delta.normalized * 0.07f;
|
||||
m_logic = new SpringBoneLogic(center, Transform, Transform.worldToLocalMatrix.MultiplyPoint(childPosition));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 最初の子ボーンを尻尾としてスプリングを付加する
|
||||
var localPosition = tail.Transform.localPosition;
|
||||
var scale = tail.Transform.lossyScale;
|
||||
m_logic = new SpringBoneLogic(center, Transform,
|
||||
new Vector3(
|
||||
localPosition.x * scale.x,
|
||||
localPosition.y * scale.y,
|
||||
localPosition.z * scale.z
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
m_logic.Update(center, m_stiffnessForce * deltaTime, m_dragForce, m_gravityDir * (m_gravityPower * deltaTime), colliders, m_hitRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb0714842bac26b44b774260bbef58c3
|
||||
guid: 5a7fc353e202e4f44a1025ba6e806262
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -606,7 +606,7 @@ namespace UniVRM10
|
||||
|
||||
static void AssignHumanoid(List<Node> nodes, UniGLTF.Extensions.VRMC_vrm.HumanBone humanBone, VrmLib.HumanoidBones key)
|
||||
{
|
||||
if (humanBone!=null && humanBone.Node.HasValue)
|
||||
if (humanBone != null && humanBone.Node.HasValue)
|
||||
{
|
||||
nodes[humanBone.Node.Value].HumanoidBone = key;
|
||||
}
|
||||
@@ -722,7 +722,7 @@ namespace UniVRM10
|
||||
// joint
|
||||
foreach (var gltfJoint in gltfSpring.Joints)
|
||||
{
|
||||
var joint = new SpringJoint();
|
||||
var joint = new SpringJoint(nodes[gltfJoint.Node.Value]);
|
||||
joint.HitRadius = gltfJoint.HitRadius.Value;
|
||||
joint.DragForce = gltfJoint.DragForce.Value;
|
||||
joint.GravityDir = gltfJoint.GravityDir.ToVector3();
|
||||
|
||||
@@ -606,7 +606,6 @@ namespace UniVRM10
|
||||
|
||||
public static void Check(ListTreeNode<JsonValue> vrm0, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone vrm1, List<UniGLTF.glTFNode> nodes)
|
||||
{
|
||||
var a = 0;
|
||||
// Migration.CheckSpringBone(vrm0["secondaryAnimation"], vrm1.sp)
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -300,7 +300,8 @@ namespace UniVRM10
|
||||
// create joint for the spring
|
||||
foreach (var vrmJoint in vrmSpring.Joints)
|
||||
{
|
||||
var joint = new VRM10SpringBone.VRM10SpringJoint();
|
||||
var go = asset.Map.Nodes[vrmJoint.Node];
|
||||
var joint = new VRM10SpringJoint(go.transform);
|
||||
|
||||
joint.m_stiffnessForce = vrmJoint.Stiffness;
|
||||
joint.m_gravityPower = vrmJoint.GravityPower;
|
||||
|
||||
@@ -356,7 +356,7 @@ namespace UniVRM10
|
||||
|
||||
foreach (var joint in springBone.Joints)
|
||||
{
|
||||
vrmSpringBone.Joints.Add(new VrmLib.SpringJoint
|
||||
vrmSpringBone.Joints.Add(new VrmLib.SpringJoint(Nodes[joint.Transform.gameObject])
|
||||
{
|
||||
Stiffness = joint.m_stiffnessForce,
|
||||
GravityPower = joint.m_gravityPower,
|
||||
|
||||
@@ -53,6 +53,11 @@ namespace VrmLib
|
||||
{
|
||||
public readonly Node Node;
|
||||
|
||||
public SpringJoint(Node node)
|
||||
{
|
||||
Node = node;
|
||||
}
|
||||
|
||||
public float DragForce;
|
||||
|
||||
public Vector3 GravityDir;
|
||||
|
||||
Reference in New Issue
Block a user