VRM10SpringBoneJoint の Gizmo を Spring 単位にまとめて描画するようにした

末端の joint を選択していても 根元から一連の joint を描画し、
末端を別色で highlight する。
This commit is contained in:
ousttrue
2024-07-02 20:11:08 +09:00
parent e85b246ce4
commit a87ceb0fd4
4 changed files with 60 additions and 43 deletions

View File

@@ -23,6 +23,7 @@ namespace UniVRM10
return;
}
m_target = (VRM10SpringBoneJoint)target;
VRM10SpringBoneJoint.s_activeForGizmoDraw = m_target;
m_stiffnessForceProp = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_stiffnessForce));
m_gravityPowerProp = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_gravityPower));

View File

@@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniVRM10
{
@@ -107,53 +105,27 @@ namespace UniVRM10
Debug.LogWarning($"{this} is found in {root}");
}
(Vrm10InstanceSpringBone.Spring, int) FindTail(Vrm10Instance vrm, VRM10SpringBoneJoint head)
{
foreach (var spring in vrm.SpringBone.Springs)
{
var index = spring.Joints.IndexOf(head);
if (index != -1)
{
if (index + 1 < spring.Joints.Count)
{
return (spring, index);
}
else
{
break;
}
}
}
return default;
}
// 一個だけ色を変えられる
public static VRM10SpringBoneJoint s_activeForGizmoDraw;
private void OnDrawGizmosSelected()
{
var vrm = GetComponentInParent<Vrm10Instance>();
if (vrm == null)
if (vrm != null)
{
return;
}
var (spring, joint_index) = FindTail(vrm, this);
if (spring == null)
{
return;
}
if (spring.Joints != null && joint_index + 1 < spring.Joints.Count)
{
var tail = spring.Joints[joint_index + 1];
if (tail != null)
var found = vrm.SpringBone.FindJoint(this);
if (found.HasValue)
{
// draw tail
Gizmos.color = Color.yellow;
// tail の radius は head の m_jointRadius で決まる
Gizmos.DrawWireSphere(tail.transform.position, m_jointRadius);
Gizmos.DrawLine(transform.position, tail.transform.position);
var (spring, i) = found.Value;
// Spring の房全体を描画する
spring.RequestDrawGizmos();
return;
}
}
// Spring から参照されていない孤立した Joint
Gizmos.color = new Color(1, 0.75f, 0f);
Gizmos.DrawSphere(transform.position, m_jointRadius);
}
}
}

View File

@@ -162,6 +162,14 @@ namespace UniVRM10
return true;
}
private void OnDrawGizmos()
{
foreach (var spring in SpringBone.Springs)
{
spring.DrawGizmos();
}
}
#region Obsolete
[Obsolete]

View File

@@ -61,12 +61,48 @@ namespace UniVRM10
}
}
}
/// <summary>
/// VRM10SpringBoneJoint.OnDrawGizmosSelected から複数の描画 Request が来うる。
/// Vrm10Instance.OnDrawGizmos 経由で1回だけ描画する。
/// </summary>
int m_drawRequest;
public void RequestDrawGizmos()
{
m_drawRequest++;
}
public void DrawGizmos()
{
if (m_drawRequest == 0)
{
return;
}
m_drawRequest = 0;
VRM10SpringBoneJoint lastJoint = null;
foreach (var joint in Joints)
{
Gizmos.color = joint == VRM10SpringBoneJoint.s_activeForGizmoDraw ? Color.green : Color.yellow;
Gizmos.matrix = joint.transform.localToWorldMatrix;
if (lastJoint == null)
{
const float f = 0.005f;
Gizmos.DrawCube(Vector3.zero, new Vector3(f, f, f));
}
else
{
Gizmos.DrawLine(Vector3.zero, -joint.transform.localPosition);
Gizmos.DrawWireSphere(Vector3.zero, joint.m_jointRadius);
}
lastJoint = joint;
}
}
}
[SerializeField]
public List<Spring> Springs = new List<Spring>();
public (Spring, int)? FindJoint(VRM10SpringBoneJoint joint)
{
for (int i = 0; i < Springs.Count; ++i)