VRM10SpringBoneJoint に angle limit 設定を追加して、runtime に反映できるようにした

This commit is contained in:
ousttrue
2025-07-18 21:49:44 +09:00
parent 8bf4cfe1ac
commit 24b2aa18a9
5 changed files with 80 additions and 20 deletions

View File

@@ -18,26 +18,26 @@ namespace UniGLTF.SpringBoneJobs
case AnglelimitTypes.Cone:
{
var angleSpaceToWorld = anglelimitSpaceToWorld(logic, joint, parentRotation);
var tailDir = math.mul(math.inverse(angleSpaceToWorld), nextTail - head);
var tailDir = math.mul(math.inverse(angleSpaceToWorld), math.normalize(nextTail - head));
tailDir = AnglelimitCone.Apply(tailDir, joint.anglelimit1);
return math.mul(angleSpaceToWorld, tailDir);
return head + math.mul(angleSpaceToWorld, tailDir) * logic.length;
}
case AnglelimitTypes.Hinge:
{
var angleSpaceToWorld = anglelimitSpaceToWorld(logic, joint, parentRotation);
var tailDir = math.mul(math.inverse(angleSpaceToWorld), nextTail - head);
var tailDir = math.mul(math.inverse(angleSpaceToWorld), math.normalize(nextTail - head));
tailDir = AnglelimitHinge.Apply(tailDir, joint.anglelimit1);
return math.mul(angleSpaceToWorld, tailDir);
return head + math.mul(angleSpaceToWorld, tailDir) * logic.length;
}
case AnglelimitTypes.Spherical:
{
var angleSpaceToWorld = anglelimitSpaceToWorld(logic, joint, parentRotation);
var tailDir = math.mul(math.inverse(angleSpaceToWorld), nextTail - head);
var tailDir = math.mul(math.inverse(angleSpaceToWorld), math.normalize(nextTail - head));
tailDir = AnglelimitSpherical.Apply(tailDir, joint.anglelimit1, joint.anglelimit2);
return math.mul(angleSpaceToWorld, tailDir);
return head + math.mul(angleSpaceToWorld, tailDir) * logic.length;
}
default:

View File

@@ -43,16 +43,16 @@ namespace UniGLTF.SpringBoneJobs.Blittables
float3 gravityDir = default,
float dragForce = 0,
float radius = 0,
// anglelimit
float alType = 0,
float limit1 = 0,
float limit2 = 0,
quaternion offset = default)
// v0.129.4 anglelimit
float angleLimitType = 0,
float angleLimit1 = 0,
float angleLimit2 = 0,
quaternion angleLimitOffset = default)
{
var c0 = new float4(stiffnessForce, gravityPower, dragForce, radius);
var c1 = new float4(gravityDir, 0);
var c2 = new float4(alType, limit1, limit2, 0);
var c3 = offset.value;
var c2 = new float4(angleLimitType, angleLimit1, angleLimit2, 0);
var c3 = angleLimitOffset.value;
_data = new float4x4(c0, c1, c2, c3);
}
}

View File

@@ -15,6 +15,10 @@ namespace UniVRM10
private SerializedProperty m_gravityDirProp;
private SerializedProperty m_dragForceProp;
private SerializedProperty m_jointRadiusProp;
private SerializedProperty m_angleLimitType;
private SerializedProperty m_angleLimitRotation;
private SerializedProperty m_angleLimitAngle1;
private SerializedProperty m_angleLimitAngle2;
private Vrm10Instance m_root;
@@ -32,6 +36,10 @@ namespace UniVRM10
m_gravityDirProp = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_gravityDir));
m_dragForceProp = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_dragForce));
m_jointRadiusProp = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_jointRadius));
m_angleLimitType = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_anglelimitType));
m_angleLimitRotation = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_angleLimitRotation));
m_angleLimitAngle1 = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_angleLimitAngle1));
m_angleLimitAngle2 = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_angleLimitAngle2));
m_root = m_target.GetComponentInParent<Vrm10Instance>();
}
@@ -39,6 +47,7 @@ namespace UniVRM10
static bool m_showJoints;
static bool m_showColliders;
static bool m_showJointSettings;
static bool m_showAnglelimitSettings;
public override void OnInspectorGUI()
{
@@ -75,6 +84,36 @@ namespace UniVRM10
Vrm10EditorUtility.LimitBreakSlider(m_jointRadiusProp, 0.0f, 0.5f, 0.0f, Mathf.Infinity);
}
//
// angle limiet
//
m_showAnglelimitSettings = EditorGUILayout.Foldout(m_showAnglelimitSettings, "AngleLimit Settings(dev)");
if (m_showAnglelimitSettings)
{
EditorGUILayout.PropertyField(m_angleLimitType);
switch ((UniGLTF.SpringBoneJobs.AnglelimitTypes)m_angleLimitType.enumValueIndex)
{
case UniGLTF.SpringBoneJobs.AnglelimitTypes.None:
break;
case UniGLTF.SpringBoneJobs.AnglelimitTypes.Cone:
EditorGUILayout.PropertyField(m_angleLimitRotation);
EditorGUILayout.PropertyField(m_angleLimitAngle1);
break;
case UniGLTF.SpringBoneJobs.AnglelimitTypes.Hinge:
EditorGUILayout.PropertyField(m_angleLimitRotation);
EditorGUILayout.PropertyField(m_angleLimitAngle1);
break;
case UniGLTF.SpringBoneJobs.AnglelimitTypes.Spherical:
EditorGUILayout.PropertyField(m_angleLimitRotation);
EditorGUILayout.PropertyField(m_angleLimitAngle1);
EditorGUILayout.PropertyField(m_angleLimitAngle2);
break;
}
}
if (serializedObject.ApplyModifiedProperties())
{
if (Application.isPlaying)

View File

@@ -26,12 +26,38 @@ namespace UniVRM10
[SerializeField]
public float m_jointRadius = 0.02f;
[SerializeField]
public UniGLTF.SpringBoneJobs.AnglelimitTypes m_anglelimitType;
[SerializeField]
public Quaternion m_angleLimitRotation = Quaternion.identity;
[SerializeField, Range(0, Mathf.PI)]
public float m_angleLimitAngle1 = Mathf.PI;
[SerializeField, Range(0, Mathf.PI)]
public float m_angleLimitAngle2 = Mathf.PI;
public BlittableJointMutable Blittable => new BlittableJointMutable(
stiffnessForce: m_stiffnessForce,
gravityPower: m_gravityPower,
gravityDir: m_gravityDir,
dragForce: m_dragForce,
radius: m_jointRadius);
radius: m_jointRadius,
// v0.129.4
angleLimitType: (float)m_anglelimitType,
angleLimit1: m_angleLimitAngle1,
angleLimit2: m_angleLimitAngle2,
angleLimitOffset: m_angleLimitRotation
);
void Oalidate()
{
if (m_angleLimitRotation == default)
{
m_angleLimitRotation = Quaternion.identity;
}
}
void AddJointRecursive(Transform t, VRM10SpringBoneJoint src)
{

View File

@@ -59,12 +59,7 @@ namespace UniVRM10
.Select(joint => new FastSpringBoneJoint
{
Transform = joint.transform,
Joint = new BlittableJointMutable(
radius: joint.m_jointRadius,
dragForce: joint.m_dragForce,
gravityDir: joint.m_gravityDir,
gravityPower: joint.m_gravityPower,
stiffnessForce: joint.m_stiffnessForce),
Joint = joint.Blittable,
DefaultLocalRotation = GetOrAddDefaultTransformState(joint.transform).LocalRotation,
}).ToArray(),
}).ToArray();