From 32391d49cf38cf45e9cc99add10c60f6a9420bf5 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 5 Oct 2020 17:31:47 +0900 Subject: [PATCH] =?UTF-8?q?Scale=E3=81=8C=E5=90=AB=E3=81=BE=E3=82=8C?= =?UTF-8?q?=E3=81=A6=E3=81=84=E3=81=A6=E3=82=82SpringBone=E3=81=82?= =?UTF-8?q?=E3=82=8B=E7=A8=8B=E5=BA=A6=E5=8B=95=E3=81=8F=E3=80=82vci=20?= =?UTF-8?q?=E3=81=8B=E3=82=89=E3=83=90=E3=83=83=E3=82=AF=E3=83=9D=E3=83=BC?= =?UTF-8?q?=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Runtime でロードした後にスケールを変えた場合に影響。セットアップには影響しない --- .../Scripts/SpringBone/VRMSpringBone.cs | 266 ++++++++---------- 1 file changed, 114 insertions(+), 152 deletions(-) diff --git a/Assets/VRM/UniVRM/Scripts/SpringBone/VRMSpringBone.cs b/Assets/VRM/UniVRM/Scripts/SpringBone/VRMSpringBone.cs index 99ac2da4c..39ecbcd51 100644 --- a/Assets/VRM/UniVRM/Scripts/SpringBone/VRMSpringBone.cs +++ b/Assets/VRM/UniVRM/Scripts/SpringBone/VRMSpringBone.cs @@ -9,40 +9,36 @@ namespace VRM /// The base algorithm is http://rocketjump.skr.jp/unity3d/109/ of @ricopin416 /// DefaultExecutionOrder(11000) means calculate springbone after FinalIK( VRIK ) /// - #if UNITY_5_5_OR_NEWER [DefaultExecutionOrder(11000)] - #endif - public class VRMSpringBone : MonoBehaviour + // [RequireComponent(typeof(VCIObject))] + public sealed class VRMSpringBone : MonoBehaviour { [SerializeField] public string m_comment; - [SerializeField, Header("Gizmo")] - bool m_drawGizmo = default; + [SerializeField] [Header("Gizmo")] private bool m_drawGizmo; + + [SerializeField] private Color m_gizmoColor = Color.yellow; [SerializeField] - Color m_gizmoColor = Color.yellow; - - [SerializeField, Range(0, 4), Header("Settings")] + [Range(0, 4)] + [Header("Settings")] public float m_stiffnessForce = 1.0f; - [SerializeField, Range(0, 2)] - public float m_gravityPower = 0; + [SerializeField] [Range(0, 2)] public float m_gravityPower; - [SerializeField] - public Vector3 m_gravityDir = new Vector3(0, -1.0f, 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, 1)] public float m_dragForce = 0.4f; - [SerializeField] - public Transform m_center; + [SerializeField] public Transform m_center; - [SerializeField] - public List RootBones = new List(); + [SerializeField] public List RootBones = new List(); Dictionary m_initialLocalRotationMap; - [SerializeField, Range(0, 0.5f), Header("Collider")] + [SerializeField] + [Range(0, 0.5f)] + [Header("Collider")] public float m_hitRadius = 0.02f; [SerializeField] @@ -57,136 +53,121 @@ namespace VRM public SpringBoneUpdateType m_updateType = SpringBoneUpdateType.LateUpdate; /// - /// /// original from - /// /// http://rocketjump.skr.jp/unity3d/109/ - /// /// - public class VRMSpringBoneLogic + private class VRMSpringBoneLogic { Transform m_transform; - public Transform Head - { - get { return m_transform; } - } + public Transform Head => m_transform; - public Vector3 Tail - { - get { return m_transform.localToWorldMatrix.MultiplyPoint(m_boneAxis * m_length); } - } + private Vector3 m_boneAxis; + private Vector3 m_currentTail; - float m_length; - Vector3 m_currentTail; - Vector3 m_prevTail; - Vector3 m_localDir; - Quaternion m_localRotation; - public Quaternion LocalRotation - { - get { return m_localRotation; } - } - public Vector3 m_boneAxis; - - public float Radius { get; set; } + private readonly float m_length; + private Vector3 m_localDir; + private Vector3 m_prevTail; public VRMSpringBoneLogic(Transform center, Transform transform, Vector3 localChildPosition) { m_transform = transform; var worldChildPosition = m_transform.TransformPoint(localChildPosition); - m_currentTail = center!= null - ? center.InverseTransformPoint(worldChildPosition) - : worldChildPosition - ; + m_currentTail = center != null + ? center.InverseTransformPoint(worldChildPosition) + : worldChildPosition; m_prevTail = m_currentTail; - m_localRotation = transform.localRotation; + LocalRotation = transform.localRotation; m_boneAxis = localChildPosition.normalized; m_length = localChildPosition.magnitude; } - Quaternion ParentRotation - { - get - { - return m_transform.parent != null - ? m_transform.parent.rotation - : Quaternion.identity - ; - } - } + public Vector3 Tail => m_transform.localToWorldMatrix.MultiplyPoint(m_boneAxis * m_length); + + private Quaternion LocalRotation { get; } + + public float Radius { get; set; } + + private Quaternion ParentRotation => + m_transform.parent != null + ? m_transform.parent.rotation + : Quaternion.identity; public void Update(Transform center, float stiffnessForce, float dragForce, Vector3 external, List colliders) { - var currentTail = center!=null - ? center.TransformPoint(m_currentTail) - : m_currentTail - ; - var prevTail = center!=null - ? center.TransformPoint(m_prevTail) - : m_prevTail - ; + var currentTail = center != null + ? center.TransformPoint(m_currentTail) + : m_currentTail; + var prevTail = center != null + ? center.TransformPoint(m_prevTail) + : m_prevTail; // verlet積分で次の位置を計算 var nextTail = currentTail - + (currentTail - prevTail) * (1.0f - dragForce) // 前フレームの移動を継続する(減衰もあるよ) - + ParentRotation * m_localRotation * m_boneAxis * stiffnessForce // 親の回転による子ボーンの移動目標 - + external // 外力による移動量 - ; + + (currentTail - prevTail) * (1.0f - dragForce) // 前フレームの移動を継続する(減衰もあるよ) + + ParentRotation * LocalRotation * m_boneAxis * stiffnessForce // 親の回転による子ボーンの移動目標 + + external; // 外力による移動量 // 長さをboneLengthに強制 - nextTail = m_transform.position + (nextTail - m_transform.position).normalized * m_length; + var position = m_transform.position; + nextTail = position + (nextTail - position).normalized * m_length; // Collisionで移動 nextTail = Collision(colliders, nextTail); - m_prevTail = center!=null - ? center.InverseTransformPoint(currentTail) - : currentTail - ; - m_currentTail = center!=null - ? center.InverseTransformPoint(nextTail) - : nextTail - ; + m_prevTail = center != null + ? center.InverseTransformPoint(currentTail) + : currentTail; + + m_currentTail = center != null + ? center.InverseTransformPoint(nextTail) + : nextTail; //回転を適用 - Head.rotation = ApplyRotation(nextTail); + m_transform.rotation = ApplyRotation(nextTail); } protected virtual Quaternion ApplyRotation(Vector3 nextTail) { - var rotation = ParentRotation * m_localRotation; - return Quaternion.FromToRotation(rotation * m_boneAxis, - nextTail - m_transform.position) * rotation; + var rotation = ParentRotation * LocalRotation; + return Quaternion.FromToRotation(rotation * m_boneAxis, + nextTail - m_transform.position) * rotation; } protected virtual Vector3 Collision(List colliders, Vector3 nextTail) { + var position = m_transform.position; + foreach (var collider in colliders) { - var r = Radius + collider.Radius; - if (Vector3.SqrMagnitude(nextTail - collider.Position) <= (r * r)) - { - // ヒット。Colliderの半径方向に押し出す - var normal = (nextTail - collider.Position).normalized; - var posFromCollider = collider.Position + normal * (Radius + collider.Radius); - // 長さをboneLengthに強制 - nextTail = m_transform.position + (posFromCollider - m_transform.position).normalized * m_length; - } + var ls = collider.transform.lossyScale; + var scale = Mathf.Max(ls.x, ls.y, ls.z); + + var r = Radius + collider.radius * scale; + var colliderPosition = collider.transform.TransformPoint(collider.center); + + if (Vector3.SqrMagnitude(nextTail - colliderPosition) > r * r) continue; + + // ヒット。Colliderの半径方向に押し出す + var normal = (nextTail - colliderPosition).normalized; + var posFromCollider = colliderPosition + normal * (Radius + collider.radius * scale); + + // 長さをboneLengthに強制 + nextTail = position + (posFromCollider - position).normalized * m_length; } + return nextTail; } public void DrawGizmo(Transform center, float radius, Color color) { - var currentTail = center!=null - ? center.TransformPoint(m_currentTail) - : m_currentTail - ; + var currentTail = center != null + ? center.TransformPoint(m_currentTail) + : m_currentTail; var prevTail = center != null - ? center.TransformPoint(m_prevTail) - : m_prevTail - ; + ? center.TransformPoint(m_prevTail) + : m_prevTail; Gizmos.color = Color.gray; Gizmos.DrawLine(currentTail, prevTail); @@ -205,7 +186,7 @@ namespace VRM } [ContextMenu("Reset bones")] - public void Setup(bool force=false) + public void Setup(bool force = false) { if (RootBones != null) { @@ -215,10 +196,7 @@ namespace VRM } else { - foreach(var kv in m_initialLocalRotationMap) - { - kv.Key.localRotation = kv.Value; - } + foreach (var kv in m_initialLocalRotationMap) kv.Key.localRotation = kv.Value; m_initialLocalRotationMap.Clear(); } m_verlet.Clear(); @@ -227,10 +205,7 @@ namespace VRM { if (go != null) { - foreach(var x in go.transform.Traverse()) - { - m_initialLocalRotationMap[x] = x.localRotation; - } + foreach (var x in go.transform.GetComponentsInChildren(true)) m_initialLocalRotationMap[x] = x.localRotation; SetupRecursive(m_center, go); } @@ -240,27 +215,22 @@ namespace VRM public void SetLocalRotationsIdentity() { - foreach (var verlet in m_verlet) - { - verlet.Head.localRotation = Quaternion.identity; - } + foreach (var verlet in m_verlet) verlet.Head.localRotation = Quaternion.identity; } - static IEnumerable GetChildren(Transform parent) + private static IEnumerable GetChildren(Transform parent) { - for(int i=0; i m_colliderList = new List(); + private List m_colliders = new List(); private void UpdateProcess(float deltaTime) { if (m_verlet == null || m_verlet.Count == 0) { - if (RootBones == null) - { - return; - } + if (RootBones == null) return; Setup(); } - m_colliderList.Clear(); + m_colliders.Clear(); if (ColliderGroups != null) { foreach (var group in ColliderGroups) @@ -326,18 +290,19 @@ namespace VRM { foreach (var collider in group.Colliders) { - m_colliderList.Add(new SphereCollider + m_colliders.Add(new SphereCollider { - Position = group.transform.TransformPoint(collider.Offset), - Radius = collider.Radius, + transform = group.transform, + center = group.transform.TransformPoint(collider.Offset), + radius = collider.Radius, }); } } } } - var stiffness = m_stiffnessForce * deltaTime; - var external = m_gravityDir * (m_gravityPower * deltaTime); + var stiffness = m_stiffnessForce * Time.deltaTime; + var external = m_gravityDir * (m_gravityPower * Time.deltaTime); foreach (var verlet in m_verlet) { @@ -346,20 +311,17 @@ namespace VRM stiffness, m_dragForce, external, - m_colliderList - ); + m_colliders + ); } } private void OnDrawGizmos() { - if (m_drawGizmo) - { - foreach (var verlet in m_verlet) - { - verlet.DrawGizmo(m_center, m_hitRadius, m_gizmoColor); - } - } + if (!m_drawGizmo) return; + + foreach (var verlet in m_verlet) + verlet.DrawGizmo(m_center, m_hitRadius, m_gizmoColor); } } -} +} \ No newline at end of file