mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-06-01 08:18:12 -05:00
Merge pull request #996 from ousttrue/feature10/update_spring_bone_tail_spec
Feature10/update spring bone tail spec
This commit is contained in:
commit
fd18413d67
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
[Serializable]
|
||||
public class VRM10SpringBoneJoint : MonoBehaviour
|
||||
{
|
||||
[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]
|
||||
public bool m_exclude;
|
||||
|
||||
[SerializeField, Range(0, 0.5f), Header("Collision")]
|
||||
public float m_jointRadius = 0.02f;
|
||||
|
||||
SpringBoneLogic m_logic;
|
||||
|
||||
public void DrawGizmo(Transform center, Color color)
|
||||
{
|
||||
if (m_logic != null)
|
||||
{
|
||||
m_logic.DrawGizmo(center, m_jointRadius, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// Gizmos.matrix = Transform.localToWorldMatrix;
|
||||
Gizmos.color = color;
|
||||
Gizmos.DrawSphere(transform.position, m_jointRadius);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5a7fc353e202e4f44a1025ba6e806262
|
||||
guid: 0a942e03b39600e41a1b161e958048f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
[Serializable]
|
||||
public class VRM10SpringJoint : MonoBehaviour
|
||||
{
|
||||
[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]
|
||||
public bool m_exclude;
|
||||
|
||||
[SerializeField, Range(0, 0.5f), Header("Collision")]
|
||||
public float m_jointRadius = 0.02f;
|
||||
|
||||
SpringBoneLogic m_logic;
|
||||
|
||||
public void DrawGizmo(Transform center, Color color)
|
||||
{
|
||||
if (m_logic != null)
|
||||
{
|
||||
m_logic.DrawGizmo(center, m_jointRadius, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// Gizmos.matrix = Transform.localToWorldMatrix;
|
||||
Gizmos.color = color;
|
||||
Gizmos.DrawSphere(transform.position, m_jointRadius);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public void Process(Transform center, float deltaTime, List<SpringBoneLogic.InternalCollider> colliders, VRM10SpringJoint tail)
|
||||
{
|
||||
if (m_logic == null)
|
||||
{
|
||||
// 初期化
|
||||
if (tail != null)
|
||||
{
|
||||
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
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 親からまっすぐの位置に tail を作成
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
m_logic.Update(center, m_stiffnessForce * deltaTime, m_dragForce, m_gravityDir * (m_gravityPower * deltaTime), colliders, m_jointRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,10 +32,11 @@ namespace UniVRM10
|
|||
public List<VRM10SpringBoneColliderGroup> ColliderGroups = new List<VRM10SpringBoneColliderGroup>();
|
||||
|
||||
[SerializeField]
|
||||
public List<VRM10SpringJoint> Joints = new List<VRM10SpringJoint>();
|
||||
public List<VRM10SpringBoneJoint> Joints = new List<VRM10SpringBoneJoint>();
|
||||
|
||||
Transform m_center;
|
||||
List<SpringBoneLogic.InternalCollider> m_colliderList;
|
||||
List<(VRM10SpringBoneJoint, SpringBoneLogic)> m_logics;
|
||||
|
||||
public Spring(string name)
|
||||
{
|
||||
|
|
@ -88,18 +89,32 @@ namespace UniVRM10
|
|||
}
|
||||
}
|
||||
|
||||
if (m_logics == null)
|
||||
{
|
||||
// udpate joints
|
||||
VRM10SpringJoint lastJoint = Joints.FirstOrDefault(x => x != null);
|
||||
foreach (var joint in Joints.Where(x => x != null).Skip(1))
|
||||
m_logics = Enumerable.Zip(Joints, Joints.Skip(1), (head, tail) =>
|
||||
{
|
||||
lastJoint.Process(center, Time.deltaTime, m_colliderList, joint);
|
||||
lastJoint = joint;
|
||||
}
|
||||
lastJoint.Process(center, Time.deltaTime, m_colliderList, null);
|
||||
var localPosition = tail.transform.localPosition;
|
||||
var scale = tail.transform.lossyScale;
|
||||
var logic = new SpringBoneLogic(center, head.transform,
|
||||
new Vector3(
|
||||
localPosition.x * scale.x,
|
||||
localPosition.y * scale.y,
|
||||
localPosition.z * scale.z
|
||||
));
|
||||
return (head, logic);
|
||||
}).ToList();
|
||||
}
|
||||
foreach (var (head, logic) in m_logics)
|
||||
{
|
||||
logic.Update(center,
|
||||
head.m_stiffnessForce * Time.deltaTime,
|
||||
head.m_dragForce,
|
||||
head.m_gravityDir * (head.m_gravityPower * Time.deltaTime),
|
||||
m_colliderList, head.m_jointRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
public List<Spring> Springs = new List<Spring>();
|
||||
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ namespace UniVRM10
|
|||
return shape;
|
||||
}
|
||||
|
||||
UniGLTF.Extensions.VRMC_springBone.SpringBoneJoint ExportJoint(VRM10SpringJoint y, Func<Transform, int> getIndexFromTransform)
|
||||
UniGLTF.Extensions.VRMC_springBone.SpringBoneJoint ExportJoint(VRM10SpringBoneJoint y, Func<Transform, int> getIndexFromTransform)
|
||||
{
|
||||
var joint = new UniGLTF.Extensions.VRMC_springBone.SpringBoneJoint
|
||||
{
|
||||
|
|
|
|||
|
|
@ -429,7 +429,7 @@ namespace UniVRM10
|
|||
{
|
||||
throw new IndexOutOfRangeException($"{index} > {Nodes.Count}");
|
||||
}
|
||||
var joint = Nodes[gltfJoint.Node.Value].gameObject.AddComponent<VRM10SpringJoint>();
|
||||
var joint = Nodes[gltfJoint.Node.Value].gameObject.AddComponent<VRM10SpringBoneJoint>();
|
||||
joint.m_jointRadius = gltfJoint.HitRadius.Value;
|
||||
joint.m_dragForce = gltfJoint.DragForce.Value;
|
||||
joint.m_gravityDir = Vector3InvertX(gltfJoint.GravityDir);
|
||||
|
|
|
|||
|
|
@ -6,19 +6,49 @@ namespace UniVRM10
|
|||
{
|
||||
public static class MigrationVrmSpringBone
|
||||
{
|
||||
static IEnumerable<UniGLTF.glTFNode> EnumJoint(List<UniGLTF.glTFNode> nodes, UniGLTF.glTFNode node)
|
||||
static IEnumerable<UniGLTF.glTFNode> TraverseFirstChild(List<UniGLTF.glTFNode> nodes, UniGLTF.glTFNode node)
|
||||
{
|
||||
yield return node;
|
||||
|
||||
if (node.children != null && node.children.Length > 0)
|
||||
{
|
||||
foreach (var x in EnumJoint(nodes, nodes[node.children[0]]))
|
||||
foreach (var x in TraverseFirstChild(nodes, nodes[node.children[0]]))
|
||||
{
|
||||
yield return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void AddTail7cm(UniGLTF.glTF gltf, UniGLTF.glTFNode[] joints)
|
||||
{
|
||||
if (joints.Length < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var last = joints.Last();
|
||||
var name = last.name ?? "";
|
||||
var v1 = new UnityEngine.Vector3(last.translation[0], last.translation[1], last.translation[2]);
|
||||
// var last2 = joints[joints.Length - 2];
|
||||
// var v2 = new UnityEngine.Vector3(last2.translation[0], last2.translation[1], last2.translation[2]);
|
||||
var delta = v1.normalized * 0.07f; // 7cm
|
||||
var tail = new UniGLTF.glTFNode
|
||||
{
|
||||
name = name + "_end",
|
||||
translation = new float[] {
|
||||
delta.x,
|
||||
delta.y,
|
||||
delta.z
|
||||
},
|
||||
};
|
||||
var tail_index = gltf.nodes.Count;
|
||||
gltf.nodes.Add(tail);
|
||||
if (last.children != null && last.children.Length > 0)
|
||||
{
|
||||
throw new System.Exception();
|
||||
}
|
||||
last.children = new[] { tail_index };
|
||||
}
|
||||
|
||||
public static UniGLTF.Extensions.VRMC_springBone.VRMC_springBone Migrate(UniGLTF.glTF gltf, JsonNode sa)
|
||||
{
|
||||
var colliderNodes = new List<int>();
|
||||
|
|
@ -86,6 +116,18 @@ namespace UniVRM10
|
|||
}
|
||||
}
|
||||
|
||||
// https://github.com/vrm-c/vrm-specification/pull/255
|
||||
// 1.0 では末端に7cmの遠さに joint を追加する動作をしなくなった。
|
||||
// その差異に対応して、7cmの遠さに node を追加する。
|
||||
foreach (var x in sa["boneGroups"].ArrayItems())
|
||||
{
|
||||
foreach (var y in x["bones"].ArrayItems())
|
||||
{
|
||||
var joints = TraverseFirstChild(gltf.nodes, gltf.nodes[y.GetInt32()]).ToArray();
|
||||
AddTail7cm(gltf, joints);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var x in sa["boneGroups"].ArrayItems())
|
||||
{
|
||||
// {
|
||||
|
|
@ -123,7 +165,7 @@ namespace UniVRM10
|
|||
Joints = new List<UniGLTF.Extensions.VRMC_springBone.SpringBoneJoint>(),
|
||||
};
|
||||
|
||||
foreach (var z in EnumJoint(gltf.nodes, gltf.nodes[y.GetInt32()]))
|
||||
foreach (var z in TraverseFirstChild(gltf.nodes, gltf.nodes[y.GetInt32()]))
|
||||
{
|
||||
spring.Joints.Add(new UniGLTF.Extensions.VRMC_springBone.SpringBoneJoint
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user