From 9b485510fb5fa9c165dd8599c83e8c5eb20023fa Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Sun, 29 Jun 2025 02:41:52 +0900 Subject: [PATCH 01/33] =?UTF-8?q?SpringBoneJobs=E3=82=A2=E3=82=BB=E3=83=B3?= =?UTF-8?q?=E3=83=96=E3=83=AA=E3=81=AEBurst=E5=AF=BE=E5=BF=9C=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/SpringBoneJobs/SpringBoneJobs.asmdef | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef index 29d33d7c1..512272a3d 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef @@ -2,7 +2,8 @@ "name": "SpringBoneJobs", "rootNamespace": "", "references": [ - "GUID:8d76e605759c3f64a957d63ef96ada7c" + "GUID:8d76e605759c3f64a957d63ef96ada7c", + "GUID:2665a8d13d1b3f18800f46e256720795" ], "includePlatforms": [], "excludePlatforms": [], @@ -11,6 +12,12 @@ "precompiledReferences": [], "autoReferenced": true, "defineConstraints": [], - "versionDefines": [], + "versionDefines": [ + { + "name": "com.unity.burst", + "expression": "0.01", + "define": "ENABLE_SPRINGBONE_BURST" + } + ], "noEngineReferences": false } \ No newline at end of file From 8ff75be0f527afcdfa2a0273d5b041d3b9f0ee44 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Mon, 30 Jun 2025 00:47:25 +0900 Subject: [PATCH 02/33] =?UTF-8?q?mathematics=E3=83=91=E3=83=83=E3=82=B1?= =?UTF-8?q?=E3=83=BC=E3=82=B8=E3=81=AE=E5=8F=82=E7=85=A7=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef | 3 ++- Assets/VRM/Runtime/VRM.asmdef | 3 ++- Assets/VRM10/Runtime/VRM10.asmdef | 1 + .../ClothSample/ClothWarp/Runtime/ClothWarp.asmdef | 3 ++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef index 512272a3d..30cd518c6 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef @@ -3,7 +3,8 @@ "rootNamespace": "", "references": [ "GUID:8d76e605759c3f64a957d63ef96ada7c", - "GUID:2665a8d13d1b3f18800f46e256720795" + "GUID:2665a8d13d1b3f18800f46e256720795", + "GUID:d8b63aba1907145bea998dd612889d6b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/VRM/Runtime/VRM.asmdef b/Assets/VRM/Runtime/VRM.asmdef index d7d1718ab..0ced96160 100644 --- a/Assets/VRM/Runtime/VRM.asmdef +++ b/Assets/VRM/Runtime/VRM.asmdef @@ -7,7 +7,8 @@ "GUID:a9bc101fb0471f94a8f99fd242fdd934", "GUID:1cd941934d098654fa21a13f28346412", "GUID:60c8346e00a8ddd4cafc5a02eceeec57", - "GUID:3e5d614bc16b50d41bd94c8d7444ca46" + "GUID:3e5d614bc16b50d41bd94c8d7444ca46", + "GUID:d8b63aba1907145bea998dd612889d6b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/VRM10/Runtime/VRM10.asmdef b/Assets/VRM10/Runtime/VRM10.asmdef index decb9b22a..0ce554345 100644 --- a/Assets/VRM10/Runtime/VRM10.asmdef +++ b/Assets/VRM10/Runtime/VRM10.asmdef @@ -8,6 +8,7 @@ "GUID:b7aa47b240b57de44a4b2021c143c9bf", "GUID:f2ca1407928ebdc4bbe7765cc278be44", "GUID:2665a8d13d1b3f18800f46e256720795", + "GUID:d8b63aba1907145bea998dd612889d6b", "GUID:1cd941934d098654fa21a13f28346412", "GUID:3e5d614bc16b50d41bd94c8d7444ca46", "GUID:f06555f75b070af458a003d92f9efb00" diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/ClothWarp.asmdef b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/ClothWarp.asmdef index 6801da68a..93ddd3c01 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/ClothWarp.asmdef +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/ClothWarp.asmdef @@ -6,7 +6,8 @@ "GUID:e47c917724578cc43b5506c17a27e9a0", "GUID:8d76e605759c3f64a957d63ef96ada7c", "GUID:1cd941934d098654fa21a13f28346412", - "GUID:5f875fdc81c40184c8333b9d63c6ddd5" + "GUID:5f875fdc81c40184c8333b9d63c6ddd5", + "GUID:d8b63aba1907145bea998dd612889d6b" ], "includePlatforms": [], "excludePlatforms": [], From 24f5b10a635c7064acf94d2906f38d2d17bb54ef Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Mon, 30 Jun 2025 00:47:43 +0900 Subject: [PATCH 03/33] =?UTF-8?q?BlittableCollider=E3=81=AE=E6=9C=80?= =?UTF-8?q?=E9=81=A9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blittables/BlittableCollider.cs | 35 +++++++++++++++---- .../InputPorts/FastSpringBoneBuffer.cs | 4 +-- .../SpringBone/Jobs/FastSpringBoneReplacer.cs | 11 +++--- .../FastSpringBoneBufferFactory.cs | 12 +++---- .../Runtime/Jobs/ClothWarpJobRuntime.cs | 14 ++++---- 5 files changed, 45 insertions(+), 31 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableCollider.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableCollider.cs index 9bacf616d..119b4712e 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableCollider.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableCollider.cs @@ -1,4 +1,5 @@ using System; +using Unity.Mathematics; using UnityEngine; namespace UniGLTF.SpringBoneJobs.Blittables @@ -7,15 +8,35 @@ namespace UniGLTF.SpringBoneJobs.Blittables /// Blittableなコライダ /// [Serializable] - public struct BlittableCollider + public readonly struct BlittableCollider { - public BlittableColliderType colliderType; - public Vector3 offset; - public float radius; - // capsule tail or plane normal - public Vector3 tailOrNormal; - public int transformIndex; + private readonly float3x3 _data; + public BlittableColliderType colliderType => (BlittableColliderType)(int)_data.c2.y; + public float3 offset => _data.c0; + public float radius => _data.c2.x; + // capsule tail or plane normal + public float3 tailOrNormal => _data.c1; + public int transformIndex => (int)_data.c2.z; + + public BlittableCollider( + float3 offset = default, + float radius = 0, + float3 tailOrNormal = default, + BlittableColliderType colliderType = default, + int colliderTransformIndex = 0) + { + var c0 = offset; + var c1 = tailOrNormal; + var c2 = new float3(radius,(int)colliderType, colliderTransformIndex); + _data = new float3x3(c0, c1, c2); + } + + public BlittableCollider SetTransformIndex(int index) + { + return new BlittableCollider(offset, radius, tailOrNormal, colliderType, index); + } + public void DrawGizmo(BlittableTransform t) { Gizmos.matrix = t.localToWorldMatrix; diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index f420ed10e..5822c248f 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -86,8 +86,8 @@ namespace UniGLTF.SpringBoneJobs.InputPorts blittableColliders.AddRange(spring.colliders.Select(collider => { var blittable = collider.Collider; - blittable.transformIndex = Array.IndexOf(Transforms, collider.Transform); - return blittable; + var transformIndex = Array.IndexOf(Transforms, collider.Transform); + return blittable.SetTransformIndex(transformIndex); })); blittableJoints.AddRange(spring.joints .Take(spring.joints.Length - 1).Select(joint => diff --git a/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs index 58d6192b6..270658005 100644 --- a/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs +++ b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs @@ -40,13 +40,10 @@ namespace VRM.SpringBoneJobs var c = new FastSpringBoneCollider { Transform = group.transform, - Collider = new BlittableCollider - { - offset = collider.Offset, - radius = collider.Radius, - tailOrNormal = default, - colliderType = BlittableColliderType.Sphere - } + Collider = new BlittableCollider( + offset: collider.Offset, + radius: collider.Radius, + colliderType: BlittableColliderType.Sphere) }; colliders.Add(c); } diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs index f176a5e19..ce1fa24c5 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs @@ -49,13 +49,11 @@ namespace UniVRM10 .Select(collider => new FastSpringBoneCollider { Transform = collider.transform, - Collider = new BlittableCollider - { - offset = collider.Offset, - radius = collider.Radius, - tailOrNormal = collider.TailOrNormal, - colliderType = TranslateColliderType(collider.ColliderType) - } + Collider = new BlittableCollider( + offset: collider.Offset, + radius: collider.Radius, + tailOrNormal: collider.TailOrNormal, + colliderType: TranslateColliderType(collider.ColliderType)) }).ToArray(), joints = spring.Joints .Select(joint => new FastSpringBoneJoint diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs index e4461c273..8e2181786 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs @@ -193,14 +193,12 @@ namespace UniVRM10.ClothWarp.Jobs var colliderTransformIndex = GetOrAddColliderTransform(collider.transform); colliderRef.Add(colliderInfo.Count); - colliderInfo.Add(new BlittableCollider - { - offset = collider.Offset, - radius = collider.Radius, - tailOrNormal = collider.TailOrNormal, - colliderType = TranslateColliderType(collider.ColliderType), - transformIndex = colliderTransformIndex, - }); + colliderInfo.Add(new BlittableCollider( + offset: collider.Offset, + radius: collider.Radius, + tailOrNormal: collider.TailOrNormal, + colliderType: TranslateColliderType(collider.ColliderType), + colliderTransformIndex: colliderTransformIndex)); _colliders.Add(collider); } From e1bded5bd00f75dab8fecaf5b1921a0d1965e7e0 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Mon, 30 Jun 2025 00:53:51 +0900 Subject: [PATCH 04/33] =?UTF-8?q?BlittableJointImmutable=E3=81=AE=E6=9C=80?= =?UTF-8?q?=E9=81=A9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blittables/BlittableJointImmutable.cs | 31 ++++++++++++++----- .../InputPorts/FastSpringBoneBuffer.cs | 16 +++++----- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointImmutable.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointImmutable.cs index a4d0b9233..137bb083c 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointImmutable.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointImmutable.cs @@ -1,4 +1,5 @@ using System; +using Unity.Mathematics; using UnityEngine; namespace UniGLTF.SpringBoneJobs.Blittables @@ -9,15 +10,31 @@ namespace UniGLTF.SpringBoneJobs.Blittables /// 変わりにくいスコープ。 /// [Serializable] - public struct BlittableJointImmutable + public readonly struct BlittableJointImmutable { - public int parentTransformIndex; - public int headTransformIndex; - public int tailTransformIndex; - public float length; - public Quaternion localRotation; - public Vector3 boneAxis; + private readonly float4x3 _data; + + public int parentTransformIndex => (int)_data.c2.x; + public int headTransformIndex => (int)_data.c2.y; + public int tailTransformIndex => (int)_data.c2.z; + public float length => _data.c2.w; + public quaternion localRotation => _data.c0; + public float3 boneAxis => _data.c1.xyz; + public BlittableJointImmutable( + int parentTransformIndex = 0, + int headTransformIndex = 0, + int tailTransformIndex = 0, + float length = 0, + quaternion localRotation = default, + float3 boneAxis = default) + { + var c0 = localRotation.value; + var c1 = new float4(boneAxis, 0); + var c2 = new float4(parentTransformIndex, headTransformIndex, tailTransformIndex, length); + _data = new float4x3(c0, c1, c2); + } + public void DrawGizmo(BlittableTransform t, BlittableJointMutable m) { Gizmos.matrix = t.localToWorldMatrix; diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index 5822c248f..a87346731 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -129,15 +129,13 @@ namespace UniGLTF.SpringBoneJobs.InputPorts localPosition.z * scale.z ); - yield return new BlittableJointImmutable - { - headTransformIndex = Array.IndexOf(Transforms, joint.Transform), - parentTransformIndex = Array.IndexOf(Transforms, joint.Transform.parent), - tailTransformIndex = Array.IndexOf(Transforms, tailJoint.Transform), - localRotation = joint.DefaultLocalRotation, - boneAxis = localChildPosition.normalized, - length = localChildPosition.magnitude - }; + yield return new BlittableJointImmutable( + headTransformIndex: Array.IndexOf(Transforms, joint.Transform), + parentTransformIndex: Array.IndexOf(Transforms, joint.Transform.parent), + tailTransformIndex: Array.IndexOf(Transforms, tailJoint.Transform), + localRotation: joint.DefaultLocalRotation, + boneAxis: localChildPosition.normalized, + length: localChildPosition.magnitude); } } From 6c741cf3485034c83d2aca688a17f14005058745 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Mon, 30 Jun 2025 00:59:24 +0900 Subject: [PATCH 05/33] =?UTF-8?q?BlittableJointMutable=E3=81=AE=E6=9C=80?= =?UTF-8?q?=E9=81=A9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blittables/BlittableJointMutable.cs | 26 ++++++++++++++----- .../SpringBone/Jobs/FastSpringBoneReplacer.cs | 14 +++++----- .../SpringBone/VRM10SpringBoneJoint.cs | 14 +++++----- .../FastSpringBoneBufferFactory.cs | 14 +++++----- .../ClothWarp/Runtime/Jobs/Particle.cs | 14 +++++----- 5 files changed, 44 insertions(+), 38 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs index bbbd8c3ac..02e728a14 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs @@ -1,4 +1,5 @@ using System; +using Unity.Mathematics; using UnityEngine; namespace UniGLTF.SpringBoneJobs.Blittables @@ -10,12 +11,25 @@ namespace UniGLTF.SpringBoneJobs.Blittables /// JointReconfigure を呼ばなければ以前と同じで不変となる。 /// [Serializable] - public struct BlittableJointMutable + public readonly struct BlittableJointMutable { - public float stiffnessForce; - public float gravityPower; - public Vector3 gravityDir; - public float dragForce; - public float radius; + private readonly float4x2 _data; + + public float stiffnessForce => _data.c0.x; + public float gravityPower => _data.c0.y; + public Vector3 gravityDir => _data.c1.xyz; + public float dragForce => _data.c0.z; + public float radius => _data.c0.w; + + public BlittableJointMutable(float stiffnessForce = 0, + float gravityPower = 0, + float3 gravityDir = default, + float dragForce = 0, + float radius = 0) + { + var c0 = new float4(stiffnessForce, gravityPower, dragForce, radius); + var c1 = new float4(gravityDir, 0); + _data = new float4x2(c0, c1); + } } } \ No newline at end of file diff --git a/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs index 270658005..18b06b90f 100644 --- a/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs +++ b/Assets/VRM/Runtime/SpringBone/Jobs/FastSpringBoneReplacer.cs @@ -82,14 +82,12 @@ namespace VRM.SpringBoneJobs joints.Add(new FastSpringBoneJoint { Transform = joint, - Joint = new BlittableJointMutable - { - radius = spring.m_hitRadius, - dragForce = spring.m_dragForce, - gravityDir = spring.m_gravityDir, - gravityPower = spring.m_gravityPower, - stiffnessForce = spring.m_stiffnessForce - }, + Joint = new BlittableJointMutable( + radius: spring.m_hitRadius, + dragForce: spring.m_dragForce, + gravityDir: spring.m_gravityDir, + gravityPower: spring.m_gravityPower, + stiffnessForce: spring.m_stiffnessForce), DefaultLocalRotation = initMap[joint.transform].LocalRotation, }); foreach (Transform child in joint) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs index 33a3c75d6..4467d2a0b 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs @@ -26,14 +26,12 @@ namespace UniVRM10 [SerializeField] public float m_jointRadius = 0.02f; - public BlittableJointMutable Blittable => new BlittableJointMutable - { - stiffnessForce = m_stiffnessForce, - dragForce = m_dragForce, - gravityDir = m_gravityDir, - gravityPower = m_gravityPower, - radius = m_jointRadius, - }; + public BlittableJointMutable Blittable => new BlittableJointMutable( + stiffnessForce: m_stiffnessForce, + gravityPower: m_gravityPower, + gravityDir: m_gravityDir, + dragForce: m_dragForce, + radius: m_jointRadius); void AddJointRecursive(Transform t, VRM10SpringBoneJoint src) { diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs index ce1fa24c5..b763e4697 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs @@ -59,14 +59,12 @@ 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 = new BlittableJointMutable( + radius: joint.m_jointRadius, + dragForce: joint.m_dragForce, + gravityDir: joint.m_gravityDir, + gravityPower: joint.m_gravityPower, + stiffnessForce: joint.m_stiffnessForce), DefaultLocalRotation = GetOrAddDefaultTransformState(joint.transform).LocalRotation, }).ToArray(), }).ToArray(); diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs index 2df9886ab..0da858cd4 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/Particle.cs @@ -39,14 +39,12 @@ namespace UniVRM10.ClothWarp.Jobs public BlittableJointMutable ToBlittableJointMutable() { - return new BlittableJointMutable - { - stiffnessForce = Stiffness, - gravityPower = 1.0f, - gravityDir = Gravity, - dragForce = Deceleration, - radius = Radius, - }; + return new BlittableJointMutable( + stiffnessForce: Stiffness, + gravityPower: 1.0f, + gravityDir: Gravity, + dragForce: Deceleration, + radius: Radius); } } From 4cf52f7b3103322044ed9794280899c53c371a28 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Mon, 30 Jun 2025 01:04:48 +0900 Subject: [PATCH 06/33] =?UTF-8?q?BlittableModelLevel=E3=81=AE=E6=9C=80?= =?UTF-8?q?=E9=81=A9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blittables/BlittableModelLevel.cs | 21 ++++++++++++++----- .../VRM10Viewer/UIToolkit/VRM10MainView.cs | 11 +++++----- .../VRM10.Samples.VRM10Viewer.asmdef | 3 ++- .../VRM10Viewer/uGui/VRM10ViewerUI.cs | 11 +++++----- .../VRM.Samples.SimpleViewer.asmdef | 3 ++- Assets/VRM_Samples/SimpleViewer/ViewerUI.cs | 10 ++++----- 6 files changed, 35 insertions(+), 24 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs index 4b37dc84a..9bb4582e4 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs @@ -1,23 +1,34 @@ -using UnityEngine; +using Unity.Mathematics; +using UnityEngine; namespace UniGLTF.SpringBoneJobs.Blittables { - public struct BlittableModelLevel + public readonly struct BlittableModelLevel { + private readonly float4 _data; + /// /// World 座標系の追加の力。風など。 /// - public Vector3 ExternalForce; + public Vector3 ExternalForce => _data.xyz; /// /// 処理結果の Transform への書き戻しを停止する。 /// - public bool StopSpringBoneWriteback; + public bool StopSpringBoneWriteback => ((int)_data.w & 1) != 0; /// /// スケール値に連動して SpringBone のパラメータを自動調整する。 /// (見た目の角速度が同じになるようにする) /// - public bool SupportsScalingAtRuntime; + public bool SupportsScalingAtRuntime => ((int)_data.w & 2) != 0; + + public BlittableModelLevel(float3 externalForce = default, + bool stopSpringBoneWriteback = false, + bool supportsScalingAtRuntime = false) + { + var w = (stopSpringBoneWriteback ? 1 : 0) | ((supportsScalingAtRuntime ? 1 : 0) << 1); + _data = new float4(externalForce, w); + } } } \ No newline at end of file diff --git a/Assets/VRM10_Samples/VRM10Viewer/UIToolkit/VRM10MainView.cs b/Assets/VRM10_Samples/VRM10Viewer/UIToolkit/VRM10MainView.cs index 23a5b1495..8e45be6d8 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/UIToolkit/VRM10MainView.cs +++ b/Assets/VRM10_Samples/VRM10Viewer/UIToolkit/VRM10MainView.cs @@ -185,15 +185,14 @@ namespace UniVRM10.VRM10Viewer m_controller.ShowBoxMan(m_showBoxMan.value); if (m_controller.TryUpdate( m_motionMode.value == 0, - new BlittableModelLevel - { - ExternalForce = new Vector3( + new BlittableModelLevel( + externalForce: new Vector3( m_springboneExternalX.value, m_springboneExternalY.value, m_springboneExternalZ.value), - StopSpringBoneWriteback = m_useSpringbonePause.value, - SupportsScalingAtRuntime = m_useSpringboneScaling.value, - }, + stopSpringBoneWriteback: m_useSpringbonePause.value, + supportsScalingAtRuntime: m_useSpringboneScaling.value + ), out var loaded )) { diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10.Samples.VRM10Viewer.asmdef b/Assets/VRM10_Samples/VRM10Viewer/VRM10.Samples.VRM10Viewer.asmdef index b5eb2e01e..705584a0a 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/VRM10.Samples.VRM10Viewer.asmdef +++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10.Samples.VRM10Viewer.asmdef @@ -7,7 +7,8 @@ "GUID:e47c917724578cc43b5506c17a27e9a0", "GUID:1cd941934d098654fa21a13f28346412", "GUID:3e5d614bc16b50d41bd94c8d7444ca46", - "GUID:f06555f75b070af458a003d92f9efb00" + "GUID:f06555f75b070af458a003d92f9efb00", + "GUID:d8b63aba1907145bea998dd612889d6b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/VRM10_Samples/VRM10Viewer/uGui/VRM10ViewerUI.cs b/Assets/VRM10_Samples/VRM10Viewer/uGui/VRM10ViewerUI.cs index 88332f56c..1610570e6 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/uGui/VRM10ViewerUI.cs +++ b/Assets/VRM10_Samples/VRM10Viewer/uGui/VRM10ViewerUI.cs @@ -226,12 +226,11 @@ namespace UniVRM10.VRM10Viewer m_controller.ShowBoxMan(m_showBoxMan.isOn); if (m_controller.TryUpdate( m_ui.IsTPose, - new BlittableModelLevel - { - ExternalForce = new Vector3(m_springboneExternalX.value, m_springboneExternalY.value, m_springboneExternalZ.value), - StopSpringBoneWriteback = m_springbonePause.isOn, - SupportsScalingAtRuntime = m_springboneScaling.isOn, - }, + new BlittableModelLevel( + externalForce: new Vector3(m_springboneExternalX.value, m_springboneExternalY.value, m_springboneExternalZ.value), + stopSpringBoneWriteback: m_springbonePause.isOn, + supportsScalingAtRuntime: m_springboneScaling.isOn + ), out var loaded )) { diff --git a/Assets/VRM_Samples/SimpleViewer/VRM.Samples.SimpleViewer.asmdef b/Assets/VRM_Samples/SimpleViewer/VRM.Samples.SimpleViewer.asmdef index b356b2415..afadcbabe 100644 --- a/Assets/VRM_Samples/SimpleViewer/VRM.Samples.SimpleViewer.asmdef +++ b/Assets/VRM_Samples/SimpleViewer/VRM.Samples.SimpleViewer.asmdef @@ -6,7 +6,8 @@ "GUID:1cd941934d098654fa21a13f28346412", "GUID:b7aa47b240b57de44a4b2021c143c9bf", "GUID:05dd262a0c0a2f841b8252c8c3815582", - "GUID:3e5d614bc16b50d41bd94c8d7444ca46" + "GUID:3e5d614bc16b50d41bd94c8d7444ca46", + "GUID:d8b63aba1907145bea998dd612889d6b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/VRM_Samples/SimpleViewer/ViewerUI.cs b/Assets/VRM_Samples/SimpleViewer/ViewerUI.cs index 8f55d7e3a..8f188653c 100644 --- a/Assets/VRM_Samples/SimpleViewer/ViewerUI.cs +++ b/Assets/VRM_Samples/SimpleViewer/ViewerUI.cs @@ -343,15 +343,15 @@ namespace VRM.SimpleViewer m_loaded.EnableLipSyncValue = m_enableLipSync.isOn; m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn; m_loaded.SetSpringboneModelLevel(new UniGLTF.SpringBoneJobs.Blittables.BlittableModelLevel - { - ExternalForce = new Vector3( + ( + externalForce: new Vector3( m_springExternalX.value, m_springExternalY.value, m_springExternalZ.value ), - StopSpringBoneWriteback = m_springBonePause.isOn, - SupportsScalingAtRuntime = m_springBoneScaling.isOn, - }); + stopSpringBoneWriteback: m_springBonePause.isOn, + supportsScalingAtRuntime: m_springBoneScaling.isOn + )); m_loaded.Update(); } } From a447433f5c40a1262f97468829d5d4e29567722b Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Mon, 30 Jun 2025 01:10:22 +0900 Subject: [PATCH 07/33] =?UTF-8?q?BlittableSpan=E3=81=AE=E6=9C=80=E9=81=A9?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SpringBoneJobs/Blittables/BlittableSpan.cs | 15 ++++++++++++--- .../FastSpringBoneConbinedBuffer.cs | 4 ++-- .../InputPorts/FastSpringBoneBuffer.cs | 12 ++---------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpan.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpan.cs index 425d2a6be..bf7a400ef 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpan.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpan.cs @@ -3,11 +3,20 @@ using System; namespace UniGLTF.SpringBoneJobs.Blittables { [Serializable] - public struct BlittableSpan + public readonly struct BlittableSpan { - public int startIndex; - public int count; + private readonly int _startIndex; + private readonly int _count; + + public int startIndex => _startIndex; + public int count => _count; public int EndIndex => startIndex + count; + + public BlittableSpan(int startIndex, int count) + { + _startIndex = startIndex; + _count = count; + } } } \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index 8e8cc7835..fb65bc910 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -249,8 +249,8 @@ namespace UniGLTF.SpringBoneJobs { var spring = SrcSprings[index]; spring.modelIndex = ModelIndex; - spring.colliderSpan.startIndex += CollidersOffset; - spring.logicSpan.startIndex += LogicsOffset; + spring.colliderSpan = new BlittableSpan(spring.colliderSpan.startIndex + CollidersOffset, spring.colliderSpan.count); + spring.logicSpan = new BlittableSpan(spring.logicSpan.startIndex + LogicsOffset, spring.logicSpan.count); spring.transformIndexOffset = TransformOffset; DestSprings[index] = spring; } diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index a87346731..3c0fddec4 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -69,16 +69,8 @@ namespace UniGLTF.SpringBoneJobs.InputPorts { var blittableSpring = new BlittableSpring { - colliderSpan = new BlittableSpan - { - startIndex = blittableColliders.Count, - count = spring.colliders.Length, - }, - logicSpan = new BlittableSpan - { - startIndex = blittableJoints.Count, - count = spring.joints.Length - 1, - }, + colliderSpan = new BlittableSpan(blittableColliders.Count,spring.colliders.Length), + logicSpan = new BlittableSpan(blittableJoints.Count, spring.joints.Length - 1), centerTransformIndex = Array.IndexOf(Transforms, spring.center), }; blittableSprings.Add(blittableSpring); From e5f6819b6d0ea5e8db7d34b2a45b118c40697066 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Mon, 30 Jun 2025 01:14:07 +0900 Subject: [PATCH 08/33] =?UTF-8?q?BlittableSpring=E3=81=AE=E6=9C=80?= =?UTF-8?q?=E9=81=A9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blittables/BlittableSpring.cs | 21 +++++++++++++------ .../FastSpringBoneConbinedBuffer.cs | 11 +++++----- .../InputPorts/FastSpringBoneBuffer.cs | 10 ++++----- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpring.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpring.cs index c4de2b291..f98d231d0 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpring.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpring.cs @@ -7,12 +7,21 @@ namespace UniGLTF.SpringBoneJobs.Blittables /// FastSpringBoneではこれを起点として並列化し、処理を行う /// [Serializable] - public struct BlittableSpring + public readonly struct BlittableSpring { - public BlittableSpan colliderSpan; - public BlittableSpan logicSpan; - public int centerTransformIndex; - public int transformIndexOffset; - public int modelIndex; + public readonly BlittableSpan colliderSpan; + public readonly BlittableSpan logicSpan; + public readonly int centerTransformIndex; + public readonly int transformIndexOffset; + public readonly int modelIndex; + + public BlittableSpring(BlittableSpan colliderSpan = default, BlittableSpan logicSpan = default, int centerTransformIndex = 0, int transformIndexOffset = 0, int modelIndex = 0) + { + this.colliderSpan = colliderSpan; + this.logicSpan = logicSpan; + this.centerTransformIndex = centerTransformIndex; + this.transformIndexOffset = transformIndexOffset; + this.modelIndex = modelIndex; + } } } \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index fb65bc910..efc722c8a 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -248,11 +248,12 @@ namespace UniGLTF.SpringBoneJobs public void Execute(int index) { var spring = SrcSprings[index]; - spring.modelIndex = ModelIndex; - spring.colliderSpan = new BlittableSpan(spring.colliderSpan.startIndex + CollidersOffset, spring.colliderSpan.count); - spring.logicSpan = new BlittableSpan(spring.logicSpan.startIndex + LogicsOffset, spring.logicSpan.count); - spring.transformIndexOffset = TransformOffset; - DestSprings[index] = spring; + DestSprings[index] = new BlittableSpring( + modelIndex: ModelIndex, + colliderSpan: new BlittableSpan(spring.colliderSpan.startIndex + CollidersOffset, spring.colliderSpan.count), + logicSpan: new BlittableSpan(spring.logicSpan.startIndex + LogicsOffset, spring.logicSpan.count), + transformIndexOffset: TransformOffset, + centerTransformIndex: spring.centerTransformIndex); } } diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index 3c0fddec4..617c993f0 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -67,12 +67,10 @@ namespace UniGLTF.SpringBoneJobs.InputPorts List blittableLogics = new(); foreach (var spring in springs) { - var blittableSpring = new BlittableSpring - { - colliderSpan = new BlittableSpan(blittableColliders.Count,spring.colliders.Length), - logicSpan = new BlittableSpan(blittableJoints.Count, spring.joints.Length - 1), - centerTransformIndex = Array.IndexOf(Transforms, spring.center), - }; + var blittableSpring = new BlittableSpring( + centerTransformIndex: Array.IndexOf(Transforms, spring.center), + colliderSpan: new BlittableSpan(blittableColliders.Count, spring.colliders.Length), + logicSpan: new BlittableSpan(blittableJoints.Count, spring.joints.Length - 1)); blittableSprings.Add(blittableSpring); blittableColliders.AddRange(spring.colliders.Select(collider => From 022e23b6d519b99b8add8f13902f46d9fe0e49e5 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Mon, 30 Jun 2025 02:07:41 +0900 Subject: [PATCH 09/33] =?UTF-8?q?BlittableTransform=E3=81=AE=E6=9C=80?= =?UTF-8?q?=E9=81=A9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blittables/BlittableJointMutable.cs | 2 +- .../Blittables/BlittableModelLevel.cs | 2 +- .../Blittables/BlittableTransform.cs | 129 +++++++++++++- .../FastSpringBoneConbinedBuffer.cs | 27 +-- .../InputPorts/FastSpringBoneBuffer.cs | 27 +-- .../SpringBoneJobs/PullTransformJob.cs | 20 +-- .../SpringBoneJobs/UpdateFastSpringBoneJob.cs | 163 ++++++++++-------- 7 files changed, 249 insertions(+), 121 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs index 02e728a14..7df912d18 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs @@ -17,7 +17,7 @@ namespace UniGLTF.SpringBoneJobs.Blittables public float stiffnessForce => _data.c0.x; public float gravityPower => _data.c0.y; - public Vector3 gravityDir => _data.c1.xyz; + public float3 gravityDir => _data.c1.xyz; public float dragForce => _data.c0.z; public float radius => _data.c0.w; diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs index 9bb4582e4..769f72818 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs @@ -10,7 +10,7 @@ namespace UniGLTF.SpringBoneJobs.Blittables /// /// World 座標系の追加の力。風など。 /// - public Vector3 ExternalForce => _data.xyz; + public float3 ExternalForce => _data.xyz; /// /// 処理結果の Transform への書き戻しを停止する。 diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs index 786aa0bb2..7e6fac0e2 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs @@ -1,5 +1,5 @@ using System; -using UnityEngine; +using Unity.Mathematics; namespace UniGLTF.SpringBoneJobs.Blittables { @@ -7,14 +7,125 @@ namespace UniGLTF.SpringBoneJobs.Blittables /// Transformの必要な機能だけを絞り、Blittableに対応させたクラス /// [Serializable] - public struct BlittableTransform + public readonly struct BlittableTransform { - public Vector3 position; - public Quaternion rotation; - public Vector3 localPosition; - public Quaternion localRotation; - public Vector3 localScale; - public Matrix4x4 localToWorldMatrix; - public Matrix4x4 worldToLocalMatrix; + public readonly float3 position; + public readonly quaternion rotation; + public readonly float3 localPosition; + public readonly quaternion localRotation; + public readonly float3 localScale; + public readonly float4x4 localToWorldMatrix; + public readonly float4x4 worldToLocalMatrix; + public float3 lossyScale + { + get + { + float4x4 tr = float4x4.TRS(position, rotation, new float3(1.0f, 1.0f, 1.0f)); + float4x4 m = math.mul(math.inverse(tr), localToWorldMatrix); + return new float3(m.c0.x, m.c1.y, m.c2.z); + } + } + + public BlittableTransform( + float3 position = default, + quaternion rotation = default, + float3 localPosition = default, + quaternion localRotation = default, + float3 localScale = default, + float4x4 localToWorldMatrix = default, + float4x4 worldToLocalMatrix = default) + { + this.position = position; + this.rotation = rotation; + this.localPosition = localPosition; + this.localRotation = localRotation; + this.localScale = localScale; + this.localToWorldMatrix = localToWorldMatrix; + this.worldToLocalMatrix = worldToLocalMatrix; + } + + public BlittableTransform SetPosition(float3 newPosition) + { + return new BlittableTransform( + position: newPosition, + rotation: rotation, + localPosition: localPosition, + localRotation: localRotation, + localScale: localScale, + localToWorldMatrix: localToWorldMatrix, + worldToLocalMatrix: worldToLocalMatrix); + } + + public BlittableTransform SetRotation(quaternion newRotation) + { + return new BlittableTransform( + position: position, + rotation: newRotation, + localPosition: localPosition, + localRotation: localRotation, + localScale: localScale, + localToWorldMatrix: localToWorldMatrix, + worldToLocalMatrix: worldToLocalMatrix); + } + + public BlittableTransform SetLocalPosition(float3 newLocalPosition) + { + return new BlittableTransform( + position: position, + rotation: rotation, + localPosition: newLocalPosition, + localRotation: localRotation, + localScale: localScale, + localToWorldMatrix: localToWorldMatrix, + worldToLocalMatrix: worldToLocalMatrix); + } + + public BlittableTransform SetLocalRotation(quaternion newLocalRotation) + { + return new BlittableTransform( + position: position, + rotation: rotation, + localPosition: localPosition, + localRotation: newLocalRotation, + localScale: localScale, + localToWorldMatrix: localToWorldMatrix, + worldToLocalMatrix: worldToLocalMatrix); + } + + public BlittableTransform SetLocalScale(float3 newLocalScale) + { + return new BlittableTransform( + position: position, + rotation: rotation, + localPosition: localPosition, + localRotation: localRotation, + localScale: newLocalScale, + localToWorldMatrix: localToWorldMatrix, + worldToLocalMatrix: worldToLocalMatrix); + } + + public BlittableTransform SetLocalToWorldMatrix(float4x4 newLocalToWorldMatrix) + { + return new BlittableTransform( + position: position, + rotation: rotation, + localPosition: localPosition, + localRotation: localRotation, + localScale: localScale, + localToWorldMatrix: newLocalToWorldMatrix, + worldToLocalMatrix: math.inverse(newLocalToWorldMatrix)); + } + + public BlittableTransform SetWorldToLocalMatrix(float4x4 newWorldToLocalMatrix) + { + return new BlittableTransform( + position: position, + rotation: rotation, + localPosition: localPosition, + localRotation: localRotation, + localScale: localScale, + localToWorldMatrix: math.inverse(newWorldToLocalMatrix), + worldToLocalMatrix: newWorldToLocalMatrix); + } } } \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index efc722c8a..9305d2662 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -9,6 +9,7 @@ using UniGLTF.SpringBoneJobs.Blittables; using UniGLTF.SpringBoneJobs.InputPorts; using Unity.Collections; using Unity.Jobs; +using Unity.Mathematics; using UnityEngine; using UnityEngine.Jobs; using UnityEngine.Profiling; @@ -23,9 +24,9 @@ namespace UniGLTF.SpringBoneJobs // Joint Level private NativeArray _logics; private NativeArray _joints; - private NativeArray _prevTails; - private NativeArray _currentTails; - private NativeArray _nextTails; + private NativeArray _prevTails; + private NativeArray _currentTails; + private NativeArray _nextTails; // Spring Level private NativeArray _springs; // Moodel Level @@ -39,9 +40,9 @@ namespace UniGLTF.SpringBoneJobs // accessor: Joint Level public NativeArray Logics => _logics; public NativeArray Joints => _joints; - public NativeArray PrevTails => _prevTails; - public NativeArray CurrentTails => _currentTails; - public NativeArray NextTails => _nextTails; + public NativeArray PrevTails => _prevTails; + public NativeArray CurrentTails => _currentTails; + public NativeArray NextTails => _nextTails; // accessor: Spring Level public NativeArray Springs => _springs; // accessor: Model LEvel @@ -64,9 +65,9 @@ namespace UniGLTF.SpringBoneJobs // joint level _logics = new NativeArray(logicsCount, Allocator.Persistent); _joints = new NativeArray(logicsCount, Allocator.Persistent); - _prevTails = new NativeArray(logicsCount, Allocator.Persistent); - _currentTails = new NativeArray(logicsCount, Allocator.Persistent); - _nextTails = new NativeArray(logicsCount, Allocator.Persistent); + _prevTails = new NativeArray(logicsCount, Allocator.Persistent); + _currentTails = new NativeArray(logicsCount, Allocator.Persistent); + _nextTails = new NativeArray(logicsCount, Allocator.Persistent); // spring level _springs = new NativeArray(springsCount, Allocator.Persistent); // model level @@ -297,9 +298,9 @@ namespace UniGLTF.SpringBoneJobs [ReadOnly] public NativeArray Logics; [ReadOnly] public NativeArray Transforms; - [NativeDisableParallelForRestriction] public NativeSlice CurrentTails; - [NativeDisableParallelForRestriction] public NativeSlice PrevTails; - [NativeDisableParallelForRestriction] public NativeSlice NextTails; + [NativeDisableParallelForRestriction] public NativeSlice CurrentTails; + [NativeDisableParallelForRestriction] public NativeSlice PrevTails; + [NativeDisableParallelForRestriction] public NativeSlice NextTails; public void Execute(int springIndex) { @@ -324,7 +325,7 @@ namespace UniGLTF.SpringBoneJobs } var tail = Transforms[tailIndex]; - var tailPos = center.HasValue ? center.Value.worldToLocalMatrix.MultiplyPoint3x4(tail.position) : tail.position; + var tailPos = center.HasValue ? math.mul(center.Value.worldToLocalMatrix, new float4(tail.position, 1.0f)).xyz : tail.position; CurrentTails[jointIndex] = tailPos; PrevTails[jointIndex] = tailPos; NextTails[jointIndex] = tailPos; diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index 617c993f0..b507f60d7 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -2,9 +2,10 @@ using System; using System.Collections.Generic; using System.Linq; using Unity.Collections; -using UnityEngine; using UnityEngine.Profiling; using UniGLTF.SpringBoneJobs.Blittables; +using Unity.Mathematics; +using UnityEngine; namespace UniGLTF.SpringBoneJobs.InputPorts { @@ -22,8 +23,8 @@ namespace UniGLTF.SpringBoneJobs.InputPorts public NativeArray Joints { get; } public NativeArray Colliders { get; } public NativeArray Logics { get; } - private NativeArray _currentTailsBackup; - private NativeArray _nextTailsBackup; + private NativeArray _currentTailsBackup; + private NativeArray _nextTailsBackup; public Transform[] Transforms { get; } /// @@ -113,7 +114,7 @@ namespace UniGLTF.SpringBoneJobs.InputPorts var localPosition = tailJoint.Transform.localPosition; var scale = tailJoint.Transform.lossyScale; - var localChildPosition = new Vector3( + var localChildPosition = new float3( localPosition.x * scale.x, localPosition.y * scale.y, localPosition.z * scale.z @@ -124,12 +125,12 @@ namespace UniGLTF.SpringBoneJobs.InputPorts parentTransformIndex: Array.IndexOf(Transforms, joint.Transform.parent), tailTransformIndex: Array.IndexOf(Transforms, tailJoint.Transform), localRotation: joint.DefaultLocalRotation, - boneAxis: localChildPosition.normalized, - length: localChildPosition.magnitude); + boneAxis: math.normalize(localChildPosition), + length: math.length(localChildPosition)); } } - public void BackupCurrentTails(NativeArray currentTails, NativeArray nextTails, int offset) + public void BackupCurrentTails(NativeArray currentTails, NativeArray nextTails, int offset) { if (!Logics.IsCreated || Logics.Length == 0) { @@ -143,16 +144,16 @@ namespace UniGLTF.SpringBoneJobs.InputPorts { _nextTailsBackup = new(Logics.Length, Allocator.Persistent); } - NativeArray.Copy(currentTails, offset, _currentTailsBackup, 0, Logics.Length); - NativeArray.Copy(nextTails, offset, _nextTailsBackup, 0, Logics.Length); + NativeArray.Copy(currentTails, offset, _currentTailsBackup, 0, Logics.Length); + NativeArray.Copy(nextTails, offset, _nextTailsBackup, 0, Logics.Length); } - public void RestoreCurrentTails(NativeArray currentTails, NativeArray nextTails, int offset) + public void RestoreCurrentTails(NativeArray currentTails, NativeArray nextTails, int offset) { if (_currentTailsBackup.IsCreated) { - NativeArray.Copy(_currentTailsBackup, 0, currentTails, offset, Logics.Length); - NativeArray.Copy(_nextTailsBackup, 0, nextTails, offset, Logics.Length); + NativeArray.Copy(_currentTailsBackup, 0, currentTails, offset, Logics.Length); + NativeArray.Copy(_nextTailsBackup, 0, nextTails, offset, Logics.Length); } else { @@ -161,7 +162,7 @@ namespace UniGLTF.SpringBoneJobs.InputPorts { // mark velocity zero #if UNITY_2022_2_OR_NEWER - currentTails.GetSubArray(offset, Logics.Length).AsSpan().Fill(new Vector3(float.NaN, float.NaN, float.NaN)); + currentTails.GetSubArray(offset, Logics.Length).AsSpan().Fill(new float3(float.NaN, float.NaN, float.NaN)); #else var subArray = currentTails.GetSubArray(offset, Logics.Length); var value = new Vector3(float.NaN, float.NaN, float.NaN); diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs index f9074868c..006c3512c 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs @@ -17,16 +17,16 @@ namespace UniGLTF.SpringBoneJobs public void Execute(int index, TransformAccess transform) { - Transforms[index] = new BlittableTransform - { - position = transform.position, - rotation = transform.rotation, - localPosition = transform.localPosition, - localRotation = transform.localRotation, - localScale = transform.localScale, - localToWorldMatrix = transform.localToWorldMatrix, - worldToLocalMatrix = transform.worldToLocalMatrix - }; + Transforms[index] = new BlittableTransform( + position: transform.position, + rotation: transform.rotation, + localPosition: transform.localPosition, + + localRotation: transform.localRotation, + localScale: transform.localScale, + localToWorldMatrix: transform.localToWorldMatrix, + worldToLocalMatrix: transform.worldToLocalMatrix + ); } } } diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs index fc1a8983a..a05ffca59 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs @@ -1,8 +1,8 @@ using System; using Unity.Collections; using Unity.Jobs; -using UnityEngine; using UniGLTF.SpringBoneJobs.Blittables; +using Unity.Mathematics; #if ENABLE_SPRINGBONE_BURST using Unity.Burst; #endif @@ -26,10 +26,10 @@ namespace UniGLTF.SpringBoneJobs // Joints, Logics, PrevTail, CurrentTail, NextTail は同じ index [ReadOnly] public NativeArray Joints; [ReadOnly] public NativeArray Logics; - [ReadOnly] public NativeArray PrevTail; - [ReadOnly] public NativeArray CurrentTail; + [ReadOnly] public NativeArray PrevTail; + [ReadOnly] public NativeArray CurrentTail; // 処理後の tail 位置(ランダムアクセス) - [NativeDisableParallelForRestriction] public NativeArray NextTail; + [NativeDisableParallelForRestriction] public NativeArray NextTail; // Spring Level [ReadOnly] public NativeArray Springs; // Model Level @@ -67,43 +67,54 @@ namespace UniGLTF.SpringBoneJobs // 親があったら、親に依存するTransformを再計算 if (parentTransform.HasValue) { - headTransform.position = - parentTransform.Value.localToWorldMatrix.MultiplyPoint3x4(headTransform.localPosition); - headTransform.rotation = parentTransform.Value.rotation * headTransform.localRotation; + var newPosition = MultiplyPoint3x4(parentTransform.Value.localToWorldMatrix, headTransform.localPosition); + var newRotation = math.mul(parentTransform.Value.rotation, headTransform.localRotation); + + headTransform = new BlittableTransform( + position: newPosition, + rotation: newRotation, + localPosition: headTransform.localPosition, + localRotation: headTransform.localRotation, + localScale: headTransform.localScale, + localToWorldMatrix: headTransform.localToWorldMatrix, + worldToLocalMatrix: headTransform.worldToLocalMatrix); + + headTransform = headTransform.SetPosition(MultiplyPoint3x4(parentTransform.Value.localToWorldMatrix, headTransform.localPosition)); + headTransform = headTransform.SetRotation(math.mul(parentTransform.Value.rotation, headTransform.localRotation)); } var currentTail = centerTransform.HasValue - ? centerTransform.Value.localToWorldMatrix.MultiplyPoint3x4(CurrentTail[logicIndex]) + ? MultiplyPoint3x4(centerTransform.Value.localToWorldMatrix, CurrentTail[logicIndex]) : CurrentTail[logicIndex]; var prevTail = centerTransform.HasValue - ? centerTransform.Value.localToWorldMatrix.MultiplyPoint3x4(PrevTail[logicIndex]) + ? MultiplyPoint3x4(centerTransform.Value.localToWorldMatrix, PrevTail[logicIndex]) : PrevTail[logicIndex]; - var parentRotation = parentTransform?.rotation ?? Quaternion.identity; + var parentRotation = parentTransform?.rotation ?? quaternion.identity; // scaling 対応 - var scalingFactor = model.SupportsScalingAtRuntime ? TransformExtensions.AbsoluteMaxValue(headTransform.localToWorldMatrix.lossyScale) : 1.0f; + var scalingFactor = model.SupportsScalingAtRuntime ? TransformExtensions.AbsoluteMaxValue(headTransform.lossyScale) : 1.0f; // verlet積分で次の位置を計算 var external = (joint.gravityDir * joint.gravityPower + model.ExternalForce) * DeltaTime; var nextTail = currentTail + (currentTail - prevTail) * (1.0f - joint.dragForce) // 前フレームの移動を継続する(減衰もあるよ) - + parentRotation * logic.localRotation * logic.boneAxis * + + math.mul(math.mul(parentRotation, logic.localRotation), logic.boneAxis) * joint.stiffnessForce * DeltaTime * scalingFactor // 親の回転による子ボーンの移動目標 + external * scalingFactor; // 外力による移動量 // 長さをboneLengthに強制 - nextTail = headTransform.position + (nextTail - headTransform.position).normalized * logic.length; + nextTail = headTransform.position + math.normalize(nextTail - headTransform.position) * logic.length; // Collisionで移動 for (var colliderIndex = colliderSpan.startIndex; colliderIndex < colliderSpan.startIndex + colliderSpan.count; ++colliderIndex) { var collider = Colliders[colliderIndex]; var colliderTransform = Transforms[collider.transformIndex + transformIndexOffset]; - var colliderScale = colliderTransform.localToWorldMatrix.lossyScale; - var maxColliderScale = Mathf.Max(Mathf.Max(Mathf.Abs(colliderScale.x), Mathf.Abs(colliderScale.y)), Mathf.Abs(colliderScale.z)); - var worldPosition = colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset); - var worldTail = colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.tailOrNormal); + var colliderScale = colliderTransform.lossyScale; + var maxColliderScale = math.max(math.max(math.abs(colliderScale.x), math.abs(colliderScale.y)), math.abs(colliderScale.z)); + var worldPosition = MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.offset); + var worldTail = MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.tailOrNormal); switch (collider.colliderType) { @@ -133,38 +144,35 @@ namespace UniGLTF.SpringBoneJobs } NextTail[logicIndex] = centerTransform.HasValue - ? centerTransform.Value.worldToLocalMatrix.MultiplyPoint3x4(nextTail) + ? MultiplyPoint3x4(centerTransform.Value.worldToLocalMatrix, nextTail) : nextTail; //回転を適用 - var rotation = parentRotation * logic.localRotation; - headTransform.rotation = Quaternion.FromToRotation(rotation * logic.boneAxis, - nextTail - headTransform.position) * rotation; + var rotation = math.mul(parentRotation, logic.localRotation); + headTransform = headTransform.SetRotation(UnityEngine.Quaternion.FromToRotation(math.mul(rotation, logic.boneAxis), + nextTail - headTransform.position) * rotation); // Transformを更新 if (parentTransform.HasValue) { var parentLocalToWorldMatrix = parentTransform.Value.localToWorldMatrix; - headTransform.localRotation = Normalize(Quaternion.Inverse(parentTransform.Value.rotation) * headTransform.rotation); - headTransform.localToWorldMatrix = - parentLocalToWorldMatrix * - Matrix4x4.TRS( - headTransform.localPosition, - headTransform.localRotation, - headTransform.localScale - ); - headTransform.worldToLocalMatrix = headTransform.localToWorldMatrix.inverse; + headTransform = headTransform.SetLocalRotation(math.normalize(math.mul(math.inverse(parentTransform.Value.rotation), headTransform.rotation))); + headTransform = headTransform.SetLocalToWorldMatrix(math.mul( + parentLocalToWorldMatrix, + float4x4.TRS( + headTransform.localPosition, + headTransform.localRotation, + headTransform.localScale + ))); } else { - headTransform.localToWorldMatrix = - Matrix4x4.TRS( - headTransform.position, - headTransform.rotation, - headTransform.localScale - ); - headTransform.worldToLocalMatrix = headTransform.localToWorldMatrix.inverse; - headTransform.localRotation = headTransform.rotation; + headTransform = headTransform.SetLocalToWorldMatrix(float4x4.TRS( + headTransform.position, + headTransform.rotation, + headTransform.localScale + )); + headTransform = headTransform.SetLocalRotation(headTransform.rotation); } if (!model.StopSpringBoneWriteback) @@ -180,42 +188,33 @@ namespace UniGLTF.SpringBoneJobs } } - /// - /// BurstではMathfがエラーを吐くため、内部でMathfを呼ばないNormalizeを自前実装 - /// - private static Quaternion Normalize(Quaternion q) - { - var num = (float)Math.Sqrt(Quaternion.Dot(q, q)); - return num < float.Epsilon ? Quaternion.identity : new Quaternion(q.x / num, q.y / num, q.z / num, q.w / num); - } - private static void ResolveCapsuleCollision( - Vector3 worldTail, - Vector3 worldPosition, + float3 worldTail, + float3 worldPosition, BlittableTransform headTransform, BlittableJointMutable joint, BlittableCollider collider, float maxColliderScale, BlittableJointImmutable logic, - ref Vector3 nextTail) + ref float3 nextTail) { var direction = worldTail - worldPosition; - if (direction.sqrMagnitude == 0) + if (math.lengthsq(direction) == 0) { // head側半球の球判定 ResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail); return; } - var P = direction.normalized; + var P = math.normalize(direction); var Q = headTransform.position - worldPosition; - var dot = Vector3.Dot(P, Q); + var dot = math.dot(P, Q); if (dot <= 0) { // head側半球の球判定 ResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail); return; } - if (dot >= direction.magnitude) + if (dot >= math.length(direction)) { // tail側半球の球判定 ResolveSphereCollision(joint, collider, worldTail, headTransform, maxColliderScale, logic, ref nextTail); @@ -230,20 +229,20 @@ namespace UniGLTF.SpringBoneJobs private static void ResolveSphereCollision( BlittableJointMutable joint, BlittableCollider collider, - Vector3 worldPosition, + float3 worldPosition, BlittableTransform headTransform, float maxColliderScale, BlittableJointImmutable logic, - ref Vector3 nextTail) + ref float3 nextTail) { var r = joint.radius + collider.radius * maxColliderScale; - if (Vector3.SqrMagnitude(nextTail - worldPosition) <= (r * r)) + if (math.lengthsq(nextTail - worldPosition) <= (r * r)) { // ヒット。Colliderの半径方向に押し出す - var normal = (nextTail - worldPosition).normalized; + var normal = math.normalize(nextTail - worldPosition); var posFromCollider = worldPosition + normal * r; // 長さをboneLengthに強制 - nextTail = headTransform.position + (posFromCollider - headTransform.position).normalized * logic.length; + nextTail = headTransform.position + math.normalize(posFromCollider - headTransform.position) * logic.length; } } @@ -251,18 +250,18 @@ namespace UniGLTF.SpringBoneJobs BlittableJointMutable joint, BlittableCollider collider, BlittableTransform colliderTransform, - ref Vector3 nextTail) + ref float3 nextTail) { - var transformedOffset = colliderTransform.localToWorldMatrix.MultiplyPoint(collider.offset); + var transformedOffset = MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); var delta = nextTail - transformedOffset; // ジョイントとコライダーの距離。負の値は衝突していることを示す - var distance = collider.radius - joint.radius - delta.magnitude; + var distance = collider.radius - joint.radius - math.length(delta); // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す if (distance < 0) { - var direction = -delta.normalized; + var direction = -1 * math.normalize(delta); nextTail -= direction * distance; } } @@ -271,15 +270,15 @@ namespace UniGLTF.SpringBoneJobs BlittableJointMutable joint, BlittableCollider collider, BlittableTransform colliderTransform, - ref Vector3 nextTail) + ref float3 nextTail) { - var transformedOffset = colliderTransform.localToWorldMatrix.MultiplyPoint(collider.offset); - var transformedTail = colliderTransform.localToWorldMatrix.MultiplyPoint(collider.tailOrNormal); + var transformedOffset = MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); + var transformedTail = MultiplyPoint(colliderTransform.localToWorldMatrix, collider.tailOrNormal); var offsetToTail = transformedTail - transformedOffset; - var lengthSqCapsule = offsetToTail.sqrMagnitude; + var lengthSqCapsule = math.lengthsq(offsetToTail); var delta = nextTail - transformedOffset; - var dot = Vector3.Dot(offsetToTail, delta); + var dot = math.dot(offsetToTail, delta); if (dot < 0.0) { @@ -298,12 +297,12 @@ namespace UniGLTF.SpringBoneJobs } // ジョイントとコライダーの距離。負の値は衝突していることを示す - var distance = collider.radius - joint.radius - delta.magnitude; + var distance = collider.radius - joint.radius - math.length(delta); // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す if (distance < 0) { - var direction = -delta.normalized; + var direction = -1 * math.normalize(delta); nextTail -= direction * distance; } } @@ -320,14 +319,14 @@ namespace UniGLTF.SpringBoneJobs BlittableJointMutable joint, BlittableCollider collider, BlittableTransform colliderTransform, - ref Vector3 nextTail) + ref float3 nextTail) { - var transformedOffset = colliderTransform.localToWorldMatrix.MultiplyPoint(collider.offset); - var transformedNormal = colliderTransform.localToWorldMatrix.MultiplyVector(collider.tailOrNormal).normalized; + var transformedOffset = MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); + var transformedNormal = math.normalize(MultiplyVector(colliderTransform.localToWorldMatrix, collider.tailOrNormal)); var delta = nextTail - transformedOffset; // ジョイントとコライダーの距離。負の値は衝突していることを示す - var distance = Vector3.Dot(delta, transformedNormal) - joint.radius; + var distance = math.dot(delta, transformedNormal) - joint.radius; if (distance < 0) { @@ -336,5 +335,21 @@ namespace UniGLTF.SpringBoneJobs nextTail -= direction * distance; } } + + private static float3 MultiplyPoint3x4(float4x4 matrix, float3 point) + { + return math.mul(matrix, new float4(point, 1)).xyz; + } + + private static float3 MultiplyPoint(float4x4 matrix, float3 point) + { + var v = math.mul(matrix, new float4(point, 1.0f)); + return v.xyz / v.w; + } + + private static float3 MultiplyVector(float4x4 matrix, float3 vector) + { + return math.mul(matrix, new float4(vector, 0)).xyz; + } } } \ No newline at end of file From da1bdcb728583494c02a0d1af631a3bcbeae891f Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Tue, 1 Jul 2025 09:49:29 +0900 Subject: [PATCH 10/33] =?UTF-8?q?Mathematics=E3=83=91=E3=83=83=E3=82=B1?= =?UTF-8?q?=E3=83=BC=E3=82=B8=E6=BC=94=E7=AE=97=E3=82=92=E3=83=A6=E3=83=BC?= =?UTF-8?q?=E3=83=86=E3=82=A3=E3=83=AA=E3=83=86=E3=82=A3=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/UniGLTF/Runtime/Utils/MathHelper.cs | 89 +++++++++++++++++++ .../UniGLTF/Runtime/Utils/MathHelper.cs.meta | 3 + .../Runtime/Utils/UniGLTF.Utils.asmdef | 4 +- Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef | 3 +- Assets/UniGLTF/Tests/UniGLTF/MathTests.cs | 49 ++++++++++ .../UniGLTF/Tests/UniGLTF/MathTests.cs.meta | 3 + 6 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/Utils/MathHelper.cs create mode 100644 Assets/UniGLTF/Runtime/Utils/MathHelper.cs.meta create mode 100644 Assets/UniGLTF/Tests/UniGLTF/MathTests.cs create mode 100644 Assets/UniGLTF/Tests/UniGLTF/MathTests.cs.meta diff --git a/Assets/UniGLTF/Runtime/Utils/MathHelper.cs b/Assets/UniGLTF/Runtime/Utils/MathHelper.cs new file mode 100644 index 000000000..86cb3646b --- /dev/null +++ b/Assets/UniGLTF/Runtime/Utils/MathHelper.cs @@ -0,0 +1,89 @@ +using System.Runtime.CompilerServices; +using Unity.Mathematics; + +namespace UniGLTF.Runtime.Utils +{ + public static class MathHelper + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 MultiplyPoint3x4(float4x4 matrix, float3 point) + { + return math.mul(matrix, new float4(point, 1)).xyz; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 MultiplyPoint(float4x4 matrix, float3 point) + { + var v = math.mul(matrix, new float4(point, 1.0f)); + return v.xyz / v.w; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float3 MultiplyVector(float4x4 matrix, float3 vector) + { + return math.mul(matrix, new float4(vector, 0)).xyz; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static quaternion FromToRotation(in float3 fromVector, in float3 toVector) + { + if (math.lengthsq(fromVector) == 0 || math.lengthsq(toVector) == 0) + { + return quaternion.identity; + } + + float3 from = math.normalize(fromVector); + float3 to = math.normalize(toVector); + + var dot = math.dot(from, to); + switch(dot) + { + case >= 1.0f: + return quaternion.identity; + case <= -1.0f: + { + var axis = math.cross(from, new float3(1, 0, 0)); + if (math.lengthsq(axis) < 0.0001f) + { + axis = math.cross(from, new float3(0, 1, 0)); + } + return quaternion.AxisAngle(math.normalize(axis), math.PI); + } + default: + { + var angle = math.acos(dot); + var axis = math.cross(from, to); + return quaternion.AxisAngle(math.normalize(axis), angle); + } + } + } + + /// + /// を Unity.Mathematics パッケージ向けに再実装した関数 + /// + /// + /// + /// + public static bool Approximately(float a, float b) + { + return math.abs(b - a) < math.max(1E-06f * math.max(math.abs(a), math.abs(b)), math.EPSILON * 8f); + } + + /// + public static bool Approximately(float3 a, float3 b) + { + return Approximately(a.x, b.x) && + Approximately(a.y, b.y) && + Approximately(a.z, b.z); + } + + /// + public static bool Approximately(quaternion a, quaternion b) + { + return Approximately(a.value.x, b.value.x) && + Approximately(a.value.y, b.value.y) && + Approximately(a.value.z, b.value.z) && + Approximately(a.value.w, b.value.w); + } + } +} diff --git a/Assets/UniGLTF/Runtime/Utils/MathHelper.cs.meta b/Assets/UniGLTF/Runtime/Utils/MathHelper.cs.meta new file mode 100644 index 000000000..4fa53e41b --- /dev/null +++ b/Assets/UniGLTF/Runtime/Utils/MathHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 50ff9ccb88bd4c208ab432127ec7b04d +timeCreated: 1751330089 \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/Utils/UniGLTF.Utils.asmdef b/Assets/UniGLTF/Runtime/Utils/UniGLTF.Utils.asmdef index 57d5bdce8..682841075 100644 --- a/Assets/UniGLTF/Runtime/Utils/UniGLTF.Utils.asmdef +++ b/Assets/UniGLTF/Runtime/Utils/UniGLTF.Utils.asmdef @@ -1,7 +1,9 @@ { "name": "UniGLTF.Utils", "rootNamespace": "", - "references": [], + "references": [ + "GUID:d8b63aba1907145bea998dd612889d6b" + ], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false, diff --git a/Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef b/Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef index f3e06d294..d5dfef6ec 100644 --- a/Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef +++ b/Assets/UniGLTF/Tests/UniGLTF.Tests.asmdef @@ -6,7 +6,8 @@ "GUID:5f875fdc81c40184c8333b9d63c6ddd5", "GUID:27619889b8ba8c24980f49ee34dbb44a", "GUID:0acc523941302664db1f4e527237feb3", - "GUID:1cd941934d098654fa21a13f28346412" + "GUID:1cd941934d098654fa21a13f28346412", + "GUID:d8b63aba1907145bea998dd612889d6b" ], "includePlatforms": [ "Editor" diff --git a/Assets/UniGLTF/Tests/UniGLTF/MathTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MathTests.cs new file mode 100644 index 000000000..5c1395b64 --- /dev/null +++ b/Assets/UniGLTF/Tests/UniGLTF/MathTests.cs @@ -0,0 +1,49 @@ +using NUnit.Framework; +using UniGLTF.Runtime.Utils; +using Unity.Mathematics; +using UnityEngine; +namespace UniGLTF +{ + public class MathTests + { + private readonly float4x4 _matrix = new float4x4( + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16); + private readonly float3 _vector1 = new float3(1, 2, 3); + private readonly float3 _vector2 = new float3(4, 5, 6); + + [Test] + public void MultiplyPoint3x4Test() + { + var result = MathHelper.MultiplyPoint3x4(_matrix, _vector1); + var expected = ((Matrix4x4)_matrix).MultiplyPoint3x4(_vector1); + Assert.That(MathHelper.Approximately(result, expected), Is.True); + } + + [Test] + public void MultiplyPointTest() + { + var result = MathHelper.MultiplyPoint(_matrix, _vector1); + var expected = ((Matrix4x4)_matrix).MultiplyPoint(_vector1); + Assert.That(MathHelper.Approximately(result, expected), Is.True); + } + + [Test] + public void MultiplyVectorTest() + { + var result = MathHelper.MultiplyVector(_matrix, _vector1); + var expected = ((Matrix4x4)_matrix).MultiplyVector(_vector1); + Assert.That(MathHelper.Approximately(result, expected), Is.True); + } + + [Test] + public void FromToRotationTest() + { + var result = MathHelper.FromToRotation(_vector1, _vector2); + var expected = Quaternion.FromToRotation(_vector1, _vector2); + Assert.That(MathHelper.Approximately(result, expected), Is.True); + } + } +} diff --git a/Assets/UniGLTF/Tests/UniGLTF/MathTests.cs.meta b/Assets/UniGLTF/Tests/UniGLTF/MathTests.cs.meta new file mode 100644 index 000000000..33e86dc0f --- /dev/null +++ b/Assets/UniGLTF/Tests/UniGLTF/MathTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4b920c4a4ea1401085ba8923e4ccaca2 +timeCreated: 1751329860 \ No newline at end of file From 46f9d6b52dd59b246fdb0b3bb20b662d6301d74e Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Tue, 1 Jul 2025 09:54:52 +0900 Subject: [PATCH 11/33] =?UTF-8?q?=E6=BC=94=E7=AE=97=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=82=92MathHelper=E3=81=B8=E7=A7=BB=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SpringBoneJobs/SpringBoneJobs.asmdef | 1 + .../SpringBoneJobs/UpdateFastSpringBoneJob.cs | 47 +++++++------------ 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef index 30cd518c6..db37c2688 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneJobs.asmdef @@ -3,6 +3,7 @@ "rootNamespace": "", "references": [ "GUID:8d76e605759c3f64a957d63ef96ada7c", + "GUID:1cd941934d098654fa21a13f28346412", "GUID:2665a8d13d1b3f18800f46e256720795", "GUID:d8b63aba1907145bea998dd612889d6b" ], diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs index a05ffca59..21272c62a 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs @@ -1,4 +1,5 @@ using System; +using UniGLTF.Runtime.Utils; using Unity.Collections; using Unity.Jobs; using UniGLTF.SpringBoneJobs.Blittables; @@ -67,7 +68,7 @@ namespace UniGLTF.SpringBoneJobs // 親があったら、親に依存するTransformを再計算 if (parentTransform.HasValue) { - var newPosition = MultiplyPoint3x4(parentTransform.Value.localToWorldMatrix, headTransform.localPosition); + var newPosition = MathHelper.MultiplyPoint3x4(parentTransform.Value.localToWorldMatrix, headTransform.localPosition); var newRotation = math.mul(parentTransform.Value.rotation, headTransform.localRotation); headTransform = new BlittableTransform( @@ -79,21 +80,21 @@ namespace UniGLTF.SpringBoneJobs localToWorldMatrix: headTransform.localToWorldMatrix, worldToLocalMatrix: headTransform.worldToLocalMatrix); - headTransform = headTransform.SetPosition(MultiplyPoint3x4(parentTransform.Value.localToWorldMatrix, headTransform.localPosition)); + headTransform = headTransform.SetPosition(MathHelper.MultiplyPoint3x4(parentTransform.Value.localToWorldMatrix, headTransform.localPosition)); headTransform = headTransform.SetRotation(math.mul(parentTransform.Value.rotation, headTransform.localRotation)); } var currentTail = centerTransform.HasValue - ? MultiplyPoint3x4(centerTransform.Value.localToWorldMatrix, CurrentTail[logicIndex]) + ? MathHelper.MultiplyPoint3x4(centerTransform.Value.localToWorldMatrix, CurrentTail[logicIndex]) : CurrentTail[logicIndex]; var prevTail = centerTransform.HasValue - ? MultiplyPoint3x4(centerTransform.Value.localToWorldMatrix, PrevTail[logicIndex]) + ? MathHelper.MultiplyPoint3x4(centerTransform.Value.localToWorldMatrix, PrevTail[logicIndex]) : PrevTail[logicIndex]; var parentRotation = parentTransform?.rotation ?? quaternion.identity; // scaling 対応 - var scalingFactor = model.SupportsScalingAtRuntime ? TransformExtensions.AbsoluteMaxValue(headTransform.lossyScale) : 1.0f; + var scalingFactor = model.SupportsScalingAtRuntime ? math.cmax(math.abs(headTransform.lossyScale)) : 1.0f; // verlet積分で次の位置を計算 var external = (joint.gravityDir * joint.gravityPower + model.ExternalForce) * DeltaTime; @@ -113,8 +114,8 @@ namespace UniGLTF.SpringBoneJobs var colliderTransform = Transforms[collider.transformIndex + transformIndexOffset]; var colliderScale = colliderTransform.lossyScale; var maxColliderScale = math.max(math.max(math.abs(colliderScale.x), math.abs(colliderScale.y)), math.abs(colliderScale.z)); - var worldPosition = MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.offset); - var worldTail = MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.tailOrNormal); + var worldPosition = MathHelper.MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.offset); + var worldTail = MathHelper.MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.tailOrNormal); switch (collider.colliderType) { @@ -144,13 +145,13 @@ namespace UniGLTF.SpringBoneJobs } NextTail[logicIndex] = centerTransform.HasValue - ? MultiplyPoint3x4(centerTransform.Value.worldToLocalMatrix, nextTail) + ? MathHelper.MultiplyPoint3x4(centerTransform.Value.worldToLocalMatrix, nextTail) : nextTail; //回転を適用 var rotation = math.mul(parentRotation, logic.localRotation); - headTransform = headTransform.SetRotation(UnityEngine.Quaternion.FromToRotation(math.mul(rotation, logic.boneAxis), - nextTail - headTransform.position) * rotation); + headTransform = headTransform.SetRotation(math.mul(MathHelper.FromToRotation(math.mul(rotation, logic.boneAxis), + nextTail - headTransform.position), rotation)); // Transformを更新 if (parentTransform.HasValue) @@ -252,7 +253,7 @@ namespace UniGLTF.SpringBoneJobs BlittableTransform colliderTransform, ref float3 nextTail) { - var transformedOffset = MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); + var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); var delta = nextTail - transformedOffset; // ジョイントとコライダーの距離。負の値は衝突していることを示す @@ -272,8 +273,8 @@ namespace UniGLTF.SpringBoneJobs BlittableTransform colliderTransform, ref float3 nextTail) { - var transformedOffset = MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); - var transformedTail = MultiplyPoint(colliderTransform.localToWorldMatrix, collider.tailOrNormal); + var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); + var transformedTail = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.tailOrNormal); var offsetToTail = transformedTail - transformedOffset; var lengthSqCapsule = math.lengthsq(offsetToTail); @@ -321,8 +322,8 @@ namespace UniGLTF.SpringBoneJobs BlittableTransform colliderTransform, ref float3 nextTail) { - var transformedOffset = MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); - var transformedNormal = math.normalize(MultiplyVector(colliderTransform.localToWorldMatrix, collider.tailOrNormal)); + var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); + var transformedNormal = math.normalize(MathHelper.MultiplyVector(colliderTransform.localToWorldMatrix, collider.tailOrNormal)); var delta = nextTail - transformedOffset; // ジョイントとコライダーの距離。負の値は衝突していることを示す @@ -335,21 +336,5 @@ namespace UniGLTF.SpringBoneJobs nextTail -= direction * distance; } } - - private static float3 MultiplyPoint3x4(float4x4 matrix, float3 point) - { - return math.mul(matrix, new float4(point, 1)).xyz; - } - - private static float3 MultiplyPoint(float4x4 matrix, float3 point) - { - var v = math.mul(matrix, new float4(point, 1.0f)); - return v.xyz / v.w; - } - - private static float3 MultiplyVector(float4x4 matrix, float3 vector) - { - return math.mul(matrix, new float4(vector, 0)).xyz; - } } } \ No newline at end of file From f92ee46451d90578395848fc05fe2626912470e4 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Tue, 1 Jul 2025 09:56:56 +0900 Subject: [PATCH 12/33] =?UTF-8?q?BlittableTransform=E3=81=AE=E6=9C=80?= =?UTF-8?q?=E9=81=A9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blittables/BlittableTransform.cs | 240 +++++++++--------- .../SpringBoneJobs/PullTransformJob.cs | 11 +- .../SpringBoneJobs/UpdateFastSpringBoneJob.cs | 73 ++---- 3 files changed, 147 insertions(+), 177 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs index 7e6fac0e2..0bbf37e9a 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs @@ -1,5 +1,7 @@ using System; +using System.Runtime.CompilerServices; using Unity.Mathematics; +using UnityEngine.Jobs; namespace UniGLTF.SpringBoneJobs.Blittables { @@ -9,123 +11,135 @@ namespace UniGLTF.SpringBoneJobs.Blittables [Serializable] public readonly struct BlittableTransform { - public readonly float3 position; - public readonly quaternion rotation; - public readonly float3 localPosition; - public readonly quaternion localRotation; - public readonly float3 localScale; - public readonly float4x4 localToWorldMatrix; - public readonly float4x4 worldToLocalMatrix; - public float3 lossyScale + public readonly float3 _position; + public readonly quaternion _rotation; + public readonly float3 _localPosition; + public readonly quaternion _localRotation; + public readonly float3 _localScale; + public readonly float4x4 _localToWorldMatrix; + + public float3 position => _position; + public quaternion rotation => _rotation; + public float3 lossyScale => GetLossyScale(); + public float3 localPosition => _localPosition; + public quaternion localRotation => _localRotation; + public float3 localScale => _localScale; + public float4x4 localToWorldMatrix => _localToWorldMatrix; + public float4x4 worldToLocalMatrix => math.inverse(_localToWorldMatrix); + + public BlittableTransform(TransformAccess transform) { - get + _position = transform.position; + _rotation = transform.rotation; + _localPosition = transform.localPosition; + _localRotation = transform.localRotation; + _localScale = transform.localScale; + _localToWorldMatrix = transform.localToWorldMatrix; + } + + private BlittableTransform( + float3 position, + quaternion rotation, + float3 localPosition, + quaternion localRotation, + float3 localScale, + float4x4 localToWorldMatrix) + { + _position = position; + _rotation = rotation; + _localPosition = localPosition; + _localRotation = localRotation; + _localScale = localScale; + _localToWorldMatrix = localToWorldMatrix; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private float3 GetLossyScale() + { + float4x4 tr = float4x4.TRS(position, rotation, new float3(1.0f)); + float4x4 m = math.mul(math.inverse(tr), _localToWorldMatrix); + return new float3(m.c0.x, m.c1.y, m.c2.z); + } + + /// + /// 親Transformが移動や回転を行った際に、ローカル座標系の値をもとに新しい絶対座標系でのTransformを計算します。 + /// + /// + /// + public BlittableTransform UpdateParentMatrix(BlittableTransform parent) + { + float3 newPosition = math.mul(parent.localToWorldMatrix, new float4(localPosition, 1)).xyz; + quaternion newRotation = math.mul(parent.rotation, localRotation); + float3 newLocalPosition = _localPosition; + quaternion newLocalRotation = _localRotation; + float3 newLocalScale = _localScale; + float4x4 newLocalToWorldMatrix = math.mul(parent.localToWorldMatrix, float4x4.TRS(newLocalPosition, newLocalRotation, newLocalScale)); + + return new BlittableTransform(newPosition, newRotation, newLocalPosition, newLocalRotation, newLocalScale, newLocalToWorldMatrix); + } + + /// + /// グローバル座標系での位置を更新し、それに伴って連動する他の値も更新します。 + /// + /// + /// + /// + public BlittableTransform UpdatePosition(float3 newValue, BlittableTransform? parent = null) + { + float3 newPosition = newValue; + quaternion newRotation = _rotation; + float3 newLocalPosition = _localPosition; + quaternion newLocalRotation = _localRotation; + float3 newLocalScale = _localScale; + float4x4 newLocalToWorldMatrix = _localToWorldMatrix; + + if(parent.HasValue) { - float4x4 tr = float4x4.TRS(position, rotation, new float3(1.0f, 1.0f, 1.0f)); - float4x4 m = math.mul(math.inverse(tr), localToWorldMatrix); - return new float3(m.c0.x, m.c1.y, m.c2.z); + newLocalPosition = math.transform(parent.Value.worldToLocalMatrix, newValue); + newLocalRotation = math.mul(math.inverse(parent.Value.rotation), _rotation); + newPosition = math.transform(parent.Value.localToWorldMatrix, newLocalPosition); + newRotation = math.mul(parent.Value.rotation, newLocalRotation); + newLocalToWorldMatrix = math.mul(parent.Value.localToWorldMatrix, float4x4.TRS(newLocalPosition, newLocalRotation, newLocalScale)); } + else + { + newLocalPosition = newValue; + newPosition = newValue; + newLocalRotation = _rotation; + newRotation = _rotation; + newLocalToWorldMatrix = float4x4.TRS(newPosition, newRotation, newLocalScale); + } + + return new BlittableTransform(newPosition, newRotation, newLocalPosition, newLocalRotation, newLocalScale, newLocalToWorldMatrix); } - - public BlittableTransform( - float3 position = default, - quaternion rotation = default, - float3 localPosition = default, - quaternion localRotation = default, - float3 localScale = default, - float4x4 localToWorldMatrix = default, - float4x4 worldToLocalMatrix = default) + + /// + /// グローバル座標系での回転を更新し、それに伴って連動する他の値も更新します。 + /// + /// + /// + /// + public BlittableTransform UpdateRotation(quaternion newValue, BlittableTransform? parent = null) { - this.position = position; - this.rotation = rotation; - this.localPosition = localPosition; - this.localRotation = localRotation; - this.localScale = localScale; - this.localToWorldMatrix = localToWorldMatrix; - this.worldToLocalMatrix = worldToLocalMatrix; - } - - public BlittableTransform SetPosition(float3 newPosition) - { - return new BlittableTransform( - position: newPosition, - rotation: rotation, - localPosition: localPosition, - localRotation: localRotation, - localScale: localScale, - localToWorldMatrix: localToWorldMatrix, - worldToLocalMatrix: worldToLocalMatrix); - } - - public BlittableTransform SetRotation(quaternion newRotation) - { - return new BlittableTransform( - position: position, - rotation: newRotation, - localPosition: localPosition, - localRotation: localRotation, - localScale: localScale, - localToWorldMatrix: localToWorldMatrix, - worldToLocalMatrix: worldToLocalMatrix); - } - - public BlittableTransform SetLocalPosition(float3 newLocalPosition) - { - return new BlittableTransform( - position: position, - rotation: rotation, - localPosition: newLocalPosition, - localRotation: localRotation, - localScale: localScale, - localToWorldMatrix: localToWorldMatrix, - worldToLocalMatrix: worldToLocalMatrix); - } - - public BlittableTransform SetLocalRotation(quaternion newLocalRotation) - { - return new BlittableTransform( - position: position, - rotation: rotation, - localPosition: localPosition, - localRotation: newLocalRotation, - localScale: localScale, - localToWorldMatrix: localToWorldMatrix, - worldToLocalMatrix: worldToLocalMatrix); - } - - public BlittableTransform SetLocalScale(float3 newLocalScale) - { - return new BlittableTransform( - position: position, - rotation: rotation, - localPosition: localPosition, - localRotation: localRotation, - localScale: newLocalScale, - localToWorldMatrix: localToWorldMatrix, - worldToLocalMatrix: worldToLocalMatrix); - } - - public BlittableTransform SetLocalToWorldMatrix(float4x4 newLocalToWorldMatrix) - { - return new BlittableTransform( - position: position, - rotation: rotation, - localPosition: localPosition, - localRotation: localRotation, - localScale: localScale, - localToWorldMatrix: newLocalToWorldMatrix, - worldToLocalMatrix: math.inverse(newLocalToWorldMatrix)); - } - - public BlittableTransform SetWorldToLocalMatrix(float4x4 newWorldToLocalMatrix) - { - return new BlittableTransform( - position: position, - rotation: rotation, - localPosition: localPosition, - localRotation: localRotation, - localScale: localScale, - localToWorldMatrix: math.inverse(newWorldToLocalMatrix), - worldToLocalMatrix: newWorldToLocalMatrix); + quaternion newRotation = newValue; + float3 newPosition = _position; + float3 newLocalPosition = _localPosition; + quaternion newLocalRotation = _localRotation; + float3 newLocalScale = _localScale; + float4x4 newLocalToWorldMatrix = _localToWorldMatrix; + + if(parent.HasValue) + { + newLocalRotation = math.normalize(math.mul(math.inverse(parent.Value.rotation), newRotation)); + newLocalToWorldMatrix = math.mul(parent.Value.localToWorldMatrix, float4x4.TRS(_localPosition, newLocalRotation, _localScale)); + } + else + { + newLocalRotation = newValue; + newLocalToWorldMatrix = float4x4.TRS(newPosition, newRotation, newLocalScale); + } + + return new BlittableTransform(newPosition, newRotation, newLocalPosition, newLocalRotation, newLocalScale, newLocalToWorldMatrix); } } -} \ No newline at end of file +} diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs index 006c3512c..e2b4b1093 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs @@ -17,16 +17,7 @@ namespace UniGLTF.SpringBoneJobs public void Execute(int index, TransformAccess transform) { - Transforms[index] = new BlittableTransform( - position: transform.position, - rotation: transform.rotation, - localPosition: transform.localPosition, - - localRotation: transform.localRotation, - localScale: transform.localScale, - localToWorldMatrix: transform.localToWorldMatrix, - worldToLocalMatrix: transform.worldToLocalMatrix - ); + Transforms[index] = new BlittableTransform(transform); } } } diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs index 21272c62a..3235b8964 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs @@ -68,20 +68,7 @@ namespace UniGLTF.SpringBoneJobs // 親があったら、親に依存するTransformを再計算 if (parentTransform.HasValue) { - var newPosition = MathHelper.MultiplyPoint3x4(parentTransform.Value.localToWorldMatrix, headTransform.localPosition); - var newRotation = math.mul(parentTransform.Value.rotation, headTransform.localRotation); - - headTransform = new BlittableTransform( - position: newPosition, - rotation: newRotation, - localPosition: headTransform.localPosition, - localRotation: headTransform.localRotation, - localScale: headTransform.localScale, - localToWorldMatrix: headTransform.localToWorldMatrix, - worldToLocalMatrix: headTransform.worldToLocalMatrix); - - headTransform = headTransform.SetPosition(MathHelper.MultiplyPoint3x4(parentTransform.Value.localToWorldMatrix, headTransform.localPosition)); - headTransform = headTransform.SetRotation(math.mul(parentTransform.Value.rotation, headTransform.localRotation)); + headTransform = headTransform.UpdateParentMatrix(parentTransform.Value); } var currentTail = centerTransform.HasValue @@ -150,31 +137,9 @@ namespace UniGLTF.SpringBoneJobs //回転を適用 var rotation = math.mul(parentRotation, logic.localRotation); - headTransform = headTransform.SetRotation(math.mul(MathHelper.FromToRotation(math.mul(rotation, logic.boneAxis), - nextTail - headTransform.position), rotation)); - - // Transformを更新 - if (parentTransform.HasValue) - { - var parentLocalToWorldMatrix = parentTransform.Value.localToWorldMatrix; - headTransform = headTransform.SetLocalRotation(math.normalize(math.mul(math.inverse(parentTransform.Value.rotation), headTransform.rotation))); - headTransform = headTransform.SetLocalToWorldMatrix(math.mul( - parentLocalToWorldMatrix, - float4x4.TRS( - headTransform.localPosition, - headTransform.localRotation, - headTransform.localScale - ))); - } - else - { - headTransform = headTransform.SetLocalToWorldMatrix(float4x4.TRS( - headTransform.position, - headTransform.rotation, - headTransform.localScale - )); - headTransform = headTransform.SetLocalRotation(headTransform.rotation); - } + headTransform = headTransform.UpdateRotation( + math.mul(MathHelper.FromToRotation(math.mul(rotation, logic.boneAxis), nextTail - headTransform.position), rotation), + parentTransform); if (!model.StopSpringBoneWriteback) { @@ -228,12 +193,12 @@ namespace UniGLTF.SpringBoneJobs } private static void ResolveSphereCollision( - BlittableJointMutable joint, - BlittableCollider collider, - float3 worldPosition, - BlittableTransform headTransform, - float maxColliderScale, - BlittableJointImmutable logic, + in BlittableJointMutable joint, + in BlittableCollider collider, + in float3 worldPosition, + in BlittableTransform headTransform, + in float maxColliderScale, + in BlittableJointImmutable logic, ref float3 nextTail) { var r = joint.radius + collider.radius * maxColliderScale; @@ -248,9 +213,9 @@ namespace UniGLTF.SpringBoneJobs } private static void ResolveSphereCollisionInside( - BlittableJointMutable joint, - BlittableCollider collider, - BlittableTransform colliderTransform, + in BlittableJointMutable joint, + in BlittableCollider collider, + in BlittableTransform colliderTransform, ref float3 nextTail) { var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); @@ -268,9 +233,9 @@ namespace UniGLTF.SpringBoneJobs } private static void ResolveCapsuleCollisionInside( - BlittableJointMutable joint, - BlittableCollider collider, - BlittableTransform colliderTransform, + in BlittableJointMutable joint, + in BlittableCollider collider, + in BlittableTransform colliderTransform, ref float3 nextTail) { var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); @@ -317,9 +282,9 @@ namespace UniGLTF.SpringBoneJobs /// colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset); /// result of verlet integration private static void ResolvePlaneCollision( - BlittableJointMutable joint, - BlittableCollider collider, - BlittableTransform colliderTransform, + in BlittableJointMutable joint, + in BlittableCollider collider, + in BlittableTransform colliderTransform, ref float3 nextTail) { var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); From cf488a65243476636dc401e97f40139e5d49ccbc Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Tue, 1 Jul 2025 10:21:54 +0900 Subject: [PATCH 13/33] =?UTF-8?q?=E5=8F=AF=E8=AA=AD=E6=80=A7=E3=81=AE?= =?UTF-8?q?=E5=90=91=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs index 9305d2662..35a2f9dd5 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneConbinedBuffer.cs @@ -5,6 +5,7 @@ using Unity.Burst; using System; using System.Collections.Generic; using System.Linq; +using UniGLTF.Runtime.Utils; using UniGLTF.SpringBoneJobs.Blittables; using UniGLTF.SpringBoneJobs.InputPorts; using Unity.Collections; @@ -325,7 +326,7 @@ namespace UniGLTF.SpringBoneJobs } var tail = Transforms[tailIndex]; - var tailPos = center.HasValue ? math.mul(center.Value.worldToLocalMatrix, new float4(tail.position, 1.0f)).xyz : tail.position; + var tailPos = center.HasValue ? MathHelper.MultiplyPoint3x4(center.Value.worldToLocalMatrix, tail.position) : tail.position; CurrentTails[jointIndex] = tailPos; PrevTails[jointIndex] = tailPos; NextTails[jointIndex] = tailPos; From 54b8c0caf1a31c00bac23c04a028f8ab90114544 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Tue, 1 Jul 2025 11:25:19 +0900 Subject: [PATCH 14/33] =?UTF-8?q?BlittableSpring=E3=81=AE=E3=82=A2?= =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=83=A1=E3=83=B3=E3=83=88=E6=9C=80=E9=81=A9?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blittables/BlittableSpring.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpring.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpring.cs index f98d231d0..72fd4163e 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpring.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableSpring.cs @@ -1,4 +1,5 @@ using System; +using Unity.Mathematics; namespace UniGLTF.SpringBoneJobs.Blittables { @@ -9,19 +10,19 @@ namespace UniGLTF.SpringBoneJobs.Blittables [Serializable] public readonly struct BlittableSpring { - public readonly BlittableSpan colliderSpan; - public readonly BlittableSpan logicSpan; - public readonly int centerTransformIndex; - public readonly int transformIndexOffset; - public readonly int modelIndex; + private readonly int4x2 _data; + + public BlittableSpan colliderSpan => new(_data.c0.x, _data.c0.y); + public BlittableSpan logicSpan => new(_data.c0.z, _data.c0.w); + public int centerTransformIndex => _data.c1.x; + public int transformIndexOffset => _data.c1.y; + public int modelIndex => _data.c1.z; public BlittableSpring(BlittableSpan colliderSpan = default, BlittableSpan logicSpan = default, int centerTransformIndex = 0, int transformIndexOffset = 0, int modelIndex = 0) { - this.colliderSpan = colliderSpan; - this.logicSpan = logicSpan; - this.centerTransformIndex = centerTransformIndex; - this.transformIndexOffset = transformIndexOffset; - this.modelIndex = modelIndex; + var c0 = new int4(colliderSpan.startIndex, colliderSpan.count, logicSpan.startIndex, logicSpan.count); + var c1 = new int4(centerTransformIndex, transformIndexOffset, modelIndex, 0); + _data = new int4x2(c0, c1); } } } \ No newline at end of file From 3f9301824d69b98d4f52acd023d22e7323312af8 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Tue, 1 Jul 2025 11:50:58 +0900 Subject: [PATCH 15/33] =?UTF-8?q?BlittableTransform=E3=81=AE=E3=82=A2?= =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=83=A1=E3=83=B3=E3=83=88=E6=9C=80=E9=81=A9?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blittables/BlittableTransform.cs | 122 ++++++++++-------- .../SpringBoneJobs/PullTransformJob.cs | 2 +- 2 files changed, 67 insertions(+), 57 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs index 0bbf37e9a..16bb8e855 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableTransform.cs @@ -11,53 +11,74 @@ namespace UniGLTF.SpringBoneJobs.Blittables [Serializable] public readonly struct BlittableTransform { - public readonly float3 _position; - public readonly quaternion _rotation; - public readonly float3 _localPosition; - public readonly quaternion _localRotation; - public readonly float3 _localScale; - public readonly float4x4 _localToWorldMatrix; + private readonly float4x3 _localData; + private readonly float4x4 _globalData; - public float3 position => _position; - public quaternion rotation => _rotation; + public float3 position => GetPosition(); + public quaternion rotation => GetRotation(); public float3 lossyScale => GetLossyScale(); - public float3 localPosition => _localPosition; - public quaternion localRotation => _localRotation; - public float3 localScale => _localScale; - public float4x4 localToWorldMatrix => _localToWorldMatrix; - public float4x4 worldToLocalMatrix => math.inverse(_localToWorldMatrix); + public float3 localPosition => _localData.c0.xyz; + public quaternion localRotation => _localData.c1; + public float3 localScale => _localData.c2.xyz; + public float4x4 localToWorldMatrix => GetLocalToWorldMatrix(); + public float4x4 worldToLocalMatrix => math.inverse(localToWorldMatrix); - public BlittableTransform(TransformAccess transform) + public static BlittableTransform FromTransformAccess(TransformAccess transform) { - _position = transform.position; - _rotation = transform.rotation; - _localPosition = transform.localPosition; - _localRotation = transform.localRotation; - _localScale = transform.localScale; - _localToWorldMatrix = transform.localToWorldMatrix; + return new BlittableTransform( + transform.rotation, + transform.localPosition, + transform.localRotation, + transform.localScale, + transform.localToWorldMatrix); } private BlittableTransform( - float3 position, quaternion rotation, float3 localPosition, quaternion localRotation, float3 localScale, float4x4 localToWorldMatrix) { - _position = position; - _rotation = rotation; - _localPosition = localPosition; - _localRotation = localRotation; - _localScale = localScale; - _localToWorldMatrix = localToWorldMatrix; + var c10 = new float4(localPosition, 0); + var c11 = localRotation; + var c12 = new float4(localScale, 0); + _localData = new float4x3(c10, c11.value, c12); + + var c20 = new float4(localToWorldMatrix.c0.xyz, rotation.value.x); + var c21 = new float4(localToWorldMatrix.c1.xyz, rotation.value.y); + var c22 = new float4(localToWorldMatrix.c2.xyz, rotation.value.z); + var c23 = new float4(localToWorldMatrix.c3.xyz, rotation.value.w); + _globalData = new float4x4(c20, c21, c22, c23); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private float4x4 GetLocalToWorldMatrix() + { + var c0 = new float4(_globalData.c0.xyz, 0); + var c1 = new float4(_globalData.c1.xyz, 0); + var c2 = new float4(_globalData.c2.xyz, 0); + var c3 = new float4(_globalData.c3.xyz, 1); + return new float4x4(c0, c1, c2, c3); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private float3 GetPosition() + { + return localToWorldMatrix.c3.xyz; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private quaternion GetRotation() + { + return new quaternion(_globalData.c0.w, _globalData.c1.w, _globalData.c2.w, _globalData.c3.w); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private float3 GetLossyScale() { float4x4 tr = float4x4.TRS(position, rotation, new float3(1.0f)); - float4x4 m = math.mul(math.inverse(tr), _localToWorldMatrix); + float4x4 m = math.mul(math.inverse(tr), localToWorldMatrix); return new float3(m.c0.x, m.c1.y, m.c2.z); } @@ -68,14 +89,10 @@ namespace UniGLTF.SpringBoneJobs.Blittables /// public BlittableTransform UpdateParentMatrix(BlittableTransform parent) { - float3 newPosition = math.mul(parent.localToWorldMatrix, new float4(localPosition, 1)).xyz; quaternion newRotation = math.mul(parent.rotation, localRotation); - float3 newLocalPosition = _localPosition; - quaternion newLocalRotation = _localRotation; - float3 newLocalScale = _localScale; - float4x4 newLocalToWorldMatrix = math.mul(parent.localToWorldMatrix, float4x4.TRS(newLocalPosition, newLocalRotation, newLocalScale)); + float4x4 newLocalToWorldMatrix = math.mul(parent.localToWorldMatrix, float4x4.TRS(localPosition, localRotation, localScale)); - return new BlittableTransform(newPosition, newRotation, newLocalPosition, newLocalRotation, newLocalScale, newLocalToWorldMatrix); + return new BlittableTransform(newRotation, localPosition, localRotation, localScale, newLocalToWorldMatrix); } /// @@ -86,31 +103,27 @@ namespace UniGLTF.SpringBoneJobs.Blittables /// public BlittableTransform UpdatePosition(float3 newValue, BlittableTransform? parent = null) { - float3 newPosition = newValue; - quaternion newRotation = _rotation; - float3 newLocalPosition = _localPosition; - quaternion newLocalRotation = _localRotation; - float3 newLocalScale = _localScale; - float4x4 newLocalToWorldMatrix = _localToWorldMatrix; + quaternion newRotation; + float3 newLocalPosition; + quaternion newLocalRotation; + float4x4 newLocalToWorldMatrix; if(parent.HasValue) { newLocalPosition = math.transform(parent.Value.worldToLocalMatrix, newValue); - newLocalRotation = math.mul(math.inverse(parent.Value.rotation), _rotation); - newPosition = math.transform(parent.Value.localToWorldMatrix, newLocalPosition); + newLocalRotation = math.mul(math.inverse(parent.Value.rotation), rotation); newRotation = math.mul(parent.Value.rotation, newLocalRotation); - newLocalToWorldMatrix = math.mul(parent.Value.localToWorldMatrix, float4x4.TRS(newLocalPosition, newLocalRotation, newLocalScale)); + newLocalToWorldMatrix = math.mul(parent.Value.localToWorldMatrix, float4x4.TRS(newLocalPosition, newLocalRotation, localScale)); } else { newLocalPosition = newValue; - newPosition = newValue; - newLocalRotation = _rotation; - newRotation = _rotation; - newLocalToWorldMatrix = float4x4.TRS(newPosition, newRotation, newLocalScale); + newLocalRotation = rotation; + newRotation = rotation; + newLocalToWorldMatrix = float4x4.TRS(newValue, newRotation, localScale); } - return new BlittableTransform(newPosition, newRotation, newLocalPosition, newLocalRotation, newLocalScale, newLocalToWorldMatrix); + return new BlittableTransform(newRotation, newLocalPosition, newLocalRotation, localScale, newLocalToWorldMatrix); } /// @@ -122,24 +135,21 @@ namespace UniGLTF.SpringBoneJobs.Blittables public BlittableTransform UpdateRotation(quaternion newValue, BlittableTransform? parent = null) { quaternion newRotation = newValue; - float3 newPosition = _position; - float3 newLocalPosition = _localPosition; - quaternion newLocalRotation = _localRotation; - float3 newLocalScale = _localScale; - float4x4 newLocalToWorldMatrix = _localToWorldMatrix; + quaternion newLocalRotation; + float4x4 newLocalToWorldMatrix; if(parent.HasValue) { newLocalRotation = math.normalize(math.mul(math.inverse(parent.Value.rotation), newRotation)); - newLocalToWorldMatrix = math.mul(parent.Value.localToWorldMatrix, float4x4.TRS(_localPosition, newLocalRotation, _localScale)); + newLocalToWorldMatrix = math.mul(parent.Value.localToWorldMatrix, float4x4.TRS(localPosition, newLocalRotation, localScale)); } else { newLocalRotation = newValue; - newLocalToWorldMatrix = float4x4.TRS(newPosition, newRotation, newLocalScale); + newLocalToWorldMatrix = float4x4.TRS(position, newRotation, localScale); } - return new BlittableTransform(newPosition, newRotation, newLocalPosition, newLocalRotation, newLocalScale, newLocalToWorldMatrix); + return new BlittableTransform(newRotation, localPosition, newLocalRotation, localScale, newLocalToWorldMatrix); } } } diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs index e2b4b1093..e07e450ca 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/PullTransformJob.cs @@ -17,7 +17,7 @@ namespace UniGLTF.SpringBoneJobs public void Execute(int index, TransformAccess transform) { - Transforms[index] = new BlittableTransform(transform); + Transforms[index] = BlittableTransform.FromTransformAccess(transform); } } } From e477cf9fdfeed95e3c508ff1edc16b66bf422bd0 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Tue, 1 Jul 2025 11:51:05 +0900 Subject: [PATCH 16/33] =?UTF-8?q?=E6=9C=AA=E4=BD=BF=E7=94=A8using=E3=81=AE?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs | 1 - .../Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs index 7df912d18..96b48fa3a 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs @@ -1,6 +1,5 @@ using System; using Unity.Mathematics; -using UnityEngine; namespace UniGLTF.SpringBoneJobs.Blittables { diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs index 769f72818..5e93b8f85 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableModelLevel.cs @@ -1,5 +1,4 @@ using Unity.Mathematics; -using UnityEngine; namespace UniGLTF.SpringBoneJobs.Blittables { From d62d791c07e163f1355851c437904d90f8117709 Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Tue, 1 Jul 2025 20:27:14 +0900 Subject: [PATCH 17/33] =?UTF-8?q?FastSpringBoneScheduler=E3=81=8C=E4=BB=96?= =?UTF-8?q?=E3=81=AE=E4=BE=9D=E5=AD=98=E3=82=92=E5=8F=97=E3=81=91=E5=85=A5?= =?UTF-8?q?=E3=82=8C=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/SpringBoneJobs/FastSpringBoneScheduler.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneScheduler.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneScheduler.cs index 9a27260d9..637f8b1e5 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneScheduler.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/FastSpringBoneScheduler.cs @@ -18,9 +18,13 @@ namespace UniGLTF.SpringBoneJobs _bufferCombiner.Dispose(); } - public JobHandle Schedule(float deltaTime) + public JobHandle Schedule(float deltaTime, JobHandle? dependency = null) { var handle = _bufferCombiner.ReconstructIfDirty(default); + if(dependency.HasValue) + { + handle = JobHandle.CombineDependencies(handle, dependency.Value); + } if (!_bufferCombiner.HasBuffer) { return handle; From a010d2a772be0e32fafb6e3fb00b36e935f98c3e Mon Sep 17 00:00:00 2001 From: AoiKamishiro Date: Tue, 1 Jul 2025 20:28:04 +0900 Subject: [PATCH 18/33] =?UTF-8?q?=E3=82=88=E3=82=8A=E6=9F=94=E8=BB=9F?= =?UTF-8?q?=E3=81=ABJob=E3=82=92=E6=89=B1=E3=81=88=E3=82=8BManualUpdate?= =?UTF-8?q?=E3=81=AE=E3=82=AA=E3=83=BC=E3=83=90=E3=83=BC=E3=83=AD=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VRM10/Runtime/FastSpringBone/FastSpringBoneService.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Assets/VRM10/Runtime/FastSpringBone/FastSpringBoneService.cs b/Assets/VRM10/Runtime/FastSpringBone/FastSpringBoneService.cs index 51a76d887..45be4e92d 100644 --- a/Assets/VRM10/Runtime/FastSpringBone/FastSpringBoneService.cs +++ b/Assets/VRM10/Runtime/FastSpringBone/FastSpringBoneService.cs @@ -1,4 +1,5 @@ using UniGLTF.SpringBoneJobs; +using Unity.Jobs; using UnityEngine; namespace UniVRM10.FastSpringBones @@ -95,12 +96,17 @@ namespace UniVRM10.FastSpringBones } public void ManualUpdate(float deltaTime) + { + ManualUpdate(deltaTime, null).Complete(); + } + + public JobHandle ManualUpdate(in float deltaTime, in JobHandle? dependency = null) { if (UpdateType != UpdateTypes.Manual) { throw new global::System.ArgumentException("require UpdateTypes.Manual"); } - _fastSpringBoneScheduler.Schedule(deltaTime).Complete(); + return _fastSpringBoneScheduler.Schedule(deltaTime, dependency); } public void OnDrawGizmosSelected() From 614abff8bfe9c83673294c5f831c753885192bc6 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 15 Jul 2025 16:30:08 +0900 Subject: [PATCH 19/33] file move only --- .../VRM10/Runtime/Components/Vrm10Runtime/Springbone.meta | 8 ++++++++ .../{ => Springbone}/FastSpringBoneBufferFactory.cs | 0 .../{ => Springbone}/FastSpringBoneBufferFactory.cs.meta | 0 .../{ => Springbone}/Vrm10FastSpringboneRuntime.cs | 0 .../{ => Springbone}/Vrm10FastSpringboneRuntime.cs.meta | 0 .../Vrm10FastSpringboneRuntimeProvider.cs | 0 .../Vrm10FastSpringboneRuntimeProvider.cs.meta | 0 .../Vrm10FastSpringboneRuntimeStandalone.cs | 0 .../Vrm10FastSpringboneRuntimeStandalone.cs.meta | 0 .../Vrm10FastSpringboneRuntimeStandaloneProvider.cs | 0 .../Vrm10FastSpringboneRuntimeStandaloneProvider.cs.meta | 0 .../{ => Springbone}/Vrm10NopSpringboneRuntime.cs | 0 .../{ => Springbone}/Vrm10NopSpringboneRuntime.cs.meta | 0 13 files changed, 8 insertions(+) create mode 100644 Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone.meta rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/FastSpringBoneBufferFactory.cs (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/FastSpringBoneBufferFactory.cs.meta (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10FastSpringboneRuntime.cs (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10FastSpringboneRuntime.cs.meta (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10FastSpringboneRuntimeProvider.cs (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10FastSpringboneRuntimeProvider.cs.meta (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10FastSpringboneRuntimeStandalone.cs (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10FastSpringboneRuntimeStandalone.cs.meta (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10FastSpringboneRuntimeStandaloneProvider.cs (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10FastSpringboneRuntimeStandaloneProvider.cs.meta (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10NopSpringboneRuntime.cs (100%) rename Assets/VRM10/Runtime/Components/Vrm10Runtime/{ => Springbone}/Vrm10NopSpringboneRuntime.cs.meta (100%) diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone.meta new file mode 100644 index 000000000..5100c627f --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d243bd3237701034a82757f58a0ec3da +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/FastSpringBoneBufferFactory.cs similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/FastSpringBoneBufferFactory.cs diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/FastSpringBoneBufferFactory.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/FastSpringBoneBufferFactory.cs.meta rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/FastSpringBoneBufferFactory.cs.meta diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntime.cs similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntime.cs diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntime.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs.meta rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntime.cs.meta diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeProvider.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeProvider.cs similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeProvider.cs rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeProvider.cs diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeProvider.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeProvider.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeProvider.cs.meta rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeProvider.cs.meta diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandalone.cs similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandalone.cs diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandalone.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs.meta rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandalone.cs.meta diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandaloneProvider.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandaloneProvider.cs similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandaloneProvider.cs rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandaloneProvider.cs diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandaloneProvider.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandaloneProvider.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandaloneProvider.cs.meta rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandaloneProvider.cs.meta diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10NopSpringboneRuntime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10NopSpringboneRuntime.cs similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10NopSpringboneRuntime.cs rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10NopSpringboneRuntime.cs diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10NopSpringboneRuntime.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10NopSpringboneRuntime.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10NopSpringboneRuntime.cs.meta rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10NopSpringboneRuntime.cs.meta From 6182555ba293a98c9a6b1f9d749975682d66c4e1 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 16 Jul 2025 14:47:50 +0900 Subject: [PATCH 20/33] add two --- .../Vrm10Runtime/Springbone}/IVrm10SpringBoneRuntime.cs | 0 .../Vrm10Runtime/Springbone}/IVrm10SpringBoneRuntime.cs.meta | 0 .../Vrm10Runtime/Springbone}/IVrm10SpringBoneRuntimeProvider.cs | 0 .../Springbone}/IVrm10SpringBoneRuntimeProvider.cs.meta | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename Assets/VRM10/Runtime/{IO => Components/Vrm10Runtime/Springbone}/IVrm10SpringBoneRuntime.cs (100%) rename Assets/VRM10/Runtime/{IO => Components/Vrm10Runtime/Springbone}/IVrm10SpringBoneRuntime.cs.meta (100%) rename Assets/VRM10/Runtime/{IO => Components/Vrm10Runtime/Springbone}/IVrm10SpringBoneRuntimeProvider.cs (100%) rename Assets/VRM10/Runtime/{IO => Components/Vrm10Runtime/Springbone}/IVrm10SpringBoneRuntimeProvider.cs.meta (100%) diff --git a/Assets/VRM10/Runtime/IO/IVrm10SpringBoneRuntime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntime.cs similarity index 100% rename from Assets/VRM10/Runtime/IO/IVrm10SpringBoneRuntime.cs rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntime.cs diff --git a/Assets/VRM10/Runtime/IO/IVrm10SpringBoneRuntime.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntime.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/IO/IVrm10SpringBoneRuntime.cs.meta rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntime.cs.meta diff --git a/Assets/VRM10/Runtime/IO/IVrm10SpringBoneRuntimeProvider.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntimeProvider.cs similarity index 100% rename from Assets/VRM10/Runtime/IO/IVrm10SpringBoneRuntimeProvider.cs rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntimeProvider.cs diff --git a/Assets/VRM10/Runtime/IO/IVrm10SpringBoneRuntimeProvider.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntimeProvider.cs.meta similarity index 100% rename from Assets/VRM10/Runtime/IO/IVrm10SpringBoneRuntimeProvider.cs.meta rename to Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntimeProvider.cs.meta From d08e239541e98217512101b074849f5cb4a2b3a0 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 17 Jul 2025 22:16:36 +0900 Subject: [PATCH 21/33] add angle limit data BlittableJointMutable --- .../Runtime/SpringBoneJobs/Anglelimit.meta | 8 +++++ .../Anglelimit/AnglelimitCone.cs | 33 +++++++++++++++++ .../Anglelimit/AnglelimitCone.cs.meta | 11 ++++++ .../Anglelimit/AnglelimitHinge.cs | 32 +++++++++++++++++ .../Anglelimit/AnglelimitHinge.cs.meta | 11 ++++++ .../Anglelimit/AnglelimitSpace.cs | 36 +++++++++++++++++++ .../Anglelimit/AnglelimitSpace.cs.meta | 11 ++++++ .../Anglelimit/AnglelimitSpherical.cs | 36 +++++++++++++++++++ .../Anglelimit/AnglelimitSpherical.cs.meta | 11 ++++++ .../Anglelimit/AnglelimitTypes.cs | 11 ++++++ .../Anglelimit/AnglelimitTypes.cs.meta | 11 ++++++ .../Blittables/BlittableJointMutable.cs | 35 +++++++++++++++--- 12 files changed, 241 insertions(+), 5 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit.meta create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs.meta create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs.meta create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs.meta create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs.meta diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit.meta new file mode 100644 index 000000000..7185a9b0e --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b09ae318bccbfce4993fafb418e1e8c7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs new file mode 100644 index 000000000..d335044e3 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs @@ -0,0 +1,33 @@ +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class AnglelimitCone + { + /// AngleLimit空間の方向ベクトル + /// radius + /// AngleLimit空間の方向ベクトル + public static float3 Apply(in float3 src, float angleLimit) + { + // tailDirのy要素をjointに設定されたangleの余弦と比較する + var cosAngle = math.cos(angleLimit); + if (src.y >= cosAngle) + { + return src; + } + + var tailDir = src; + { + // x・z要素を、tailDirの正弦とjointに設定されたangleの正弦の比を用いてスケールする + var ratio = math.sqrt((1.0f - cosAngle * cosAngle) / (1.0f - tailDir.y * tailDir.y)); + tailDir.x *= ratio; + tailDir.z *= ratio; + + // y要素を、jointに設定されたangleの余弦とする + tailDir.y = cosAngle; + } + + return src; + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs.meta new file mode 100644 index 000000000..ce8cc27a8 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 780b79f298faea74ba4a123039a3faeb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs new file mode 100644 index 000000000..571984689 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs @@ -0,0 +1,32 @@ +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class AnglelimitHinge + { + /// AngleLimit空間の方向ベクトル + /// radius + /// AngleLimit空間の方向ベクトル + public static float3 Apply(in float3 src, float limitAngle) + { + // x要素を0にし、正規化する + float3 tailDir = src; + tailDir.x = 0.0f; + tailDir = math.normalize(tailDir); + + // tailDirのy要素をjointに設定されたangleの余弦と比較する + var cosAngle = math.cos(limitAngle); + if (tailDir.y < cosAngle) + { + // z要素を、tailDirの正弦とjointに設定されたangleの正弦の比を用いてスケールする + var ratio = math.sqrt((1.0f - cosAngle * cosAngle) / (1.0f - tailDir.y * tailDir.y)); + tailDir.z *= ratio; + + // y要素を、jointに設定されたangleの余弦とする + tailDir.y = cosAngle; + } + + return tailDir; + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs.meta new file mode 100644 index 000000000..b385eae67 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb1e1bbfc1a339c40b5df4d846f09da4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs new file mode 100644 index 000000000..1d9e06008 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs @@ -0,0 +1,36 @@ +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class AnglelimitSpace + { + public static float3 ToTailDir(in quaternion src) + { + // // Y+方向からjointのheadからtailに向かうベクトルへの最小回転 + // let axisRotation = fromToQuaternion(vec3(0, 1, 0), boneAxis); + + // // limitのローカル空間をワールド空間に写像する回転 + // let rotation = + // joint.parent.worldRotation * + // joint.localSpaceInitialRotation * + // axisRotation * + // joint.limit.rotation; + + // // tailの向きをlimitのローカル空間に写像する + // tailDir = tailDir.applyQuaternion(rotation.inverse); + + // // limitを適用する + // joint.limit.apply(tailDir); + + // // tailの向きをワールド空間に戻す + // tailDir = tailDir.applyQuaternion(rotation); + + throw new System.NotImplementedException(); + } + + public static quaternion FromTailDir(in float3 src) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta new file mode 100644 index 000000000..99e27a255 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e38e2998df511664cb0d6e582e6a05a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs new file mode 100644 index 000000000..e6d07be63 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs @@ -0,0 +1,36 @@ +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class AnglelimitSpherical + { + /// AngleLimit空間の方向ベクトル + /// radius + /// radius + /// AngleLimit空間の方向ベクトル + public static float3 Apply(in float3 tailDir, float limitAnglePhi, float limitAngleTheta) + { + // tailDirのphi・thetaを計算する + var phi = math.atan2(tailDir.z, tailDir.y); + var theta = math.asin(tailDir.x); + + // phi・thetaをjointに設定されたphi・thetaを用いて制限する + // var isLimited = false; + if (math.abs(phi) > limitAnglePhi) + { + // isLimited = true; + phi = limitAnglePhi * math.sign(phi); + } + + // thetaをjointに設定されたthetaを用いて制限する + if (math.abs(theta) > limitAngleTheta) + { + // isLimited = true; + theta = limitAngleTheta * math.sign(theta); + } + + // tailDirをphi・thetaを用いて再計算する + return new float3(math.sin(theta), math.cos(theta) * math.cos(phi), math.cos(theta) * math.sin(phi)); + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs.meta new file mode 100644 index 000000000..c0439fd3e --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc767b94391a0c44ebd21390c57a869e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs new file mode 100644 index 000000000..656ef327d --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs @@ -0,0 +1,11 @@ + +namespace UniGLTF.SpringBoneJobs +{ + public enum AnglelimitTypes + { + None, + Cone, + Hinge, + Spherical, + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs.meta new file mode 100644 index 000000000..839768b66 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56836f5a87c46a641a0ffc048c10655f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs index 96b48fa3a..d6566a659 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs @@ -12,23 +12,48 @@ namespace UniGLTF.SpringBoneJobs.Blittables [Serializable] public readonly struct BlittableJointMutable { - private readonly float4x2 _data; - + /// + /// |x |y |z |w | + /// |--------|--------|--------|--------| + /// |stiff |g-power |drag |radius | + /// |g-dir.x |g-dir.y |g-dir.z | | + /// |al.type |limit1 |limit2 | + /// |offset.x|offset.y|offset.z|offset.w| + /// + /// g-power = gravityPower + /// g-dir = gravityDir + /// al = anglelimit + /// offset = anglelimitOffset + /// + private readonly float4x4 _data; + public float stiffnessForce => _data.c0.x; public float gravityPower => _data.c0.y; public float3 gravityDir => _data.c1.xyz; public float dragForce => _data.c0.z; public float radius => _data.c0.w; - + + public AnglelimitTypes anglelimitType => (AnglelimitTypes)_data.c2.x; + public float anglelimit1 => _data.c2.y; + public float anglelimit2 => _data.c2.z; + public quaternion anglelimitOffset => _data.c3.xyzw; + public BlittableJointMutable(float stiffnessForce = 0, float gravityPower = 0, float3 gravityDir = default, float dragForce = 0, - float radius = 0) + float radius = 0, + // anglelimit + float alType = 0, + float limit1 = 0, + float limit2 = 0, + quaternion offset = default) { var c0 = new float4(stiffnessForce, gravityPower, dragForce, radius); var c1 = new float4(gravityDir, 0); - _data = new float4x2(c0, c1); + var c2 = new float4(alType, limit1, limit2, 0); + var c3 = offset.value; + _data = new float4x4(c0, c1, c2, c3); } } } \ No newline at end of file From 011664097d40e430e7b514863a9c7a2c9a33a411 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 17 Jul 2025 22:52:08 +0900 Subject: [PATCH 22/33] impl Anglelimit --- .../SpringBoneJobs/Anglelimit/Anglelimit.cs | 84 +++++++++++++++++++ ...elimitSpace.cs.meta => Anglelimit.cs.meta} | 2 +- .../Anglelimit/AnglelimitSpace.cs | 36 -------- .../SpringBoneJobs/UpdateFastSpringBoneJob.cs | 4 + 4 files changed, 89 insertions(+), 37 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs rename Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/{AnglelimitSpace.cs.meta => Anglelimit.cs.meta} (83%) delete mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs new file mode 100644 index 000000000..353a8547b --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs @@ -0,0 +1,84 @@ +using UniGLTF.SpringBoneJobs.Blittables; +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class Anglelimit + { + public static float3 Apply( + in BlittableJointImmutable logic, in BlittableJointMutable joint, + in quaternion parentRotation, in float3 head, in float3 nextTail) + { + switch (joint.anglelimitType) + { + case AnglelimitTypes.None: + // do nothing + return nextTail; + + case AnglelimitTypes.Cone: + { + var angleSpaceToWorld = anglelimitSpaceToWorld(logic, joint, parentRotation); + var tailDir = math.mul(math.inverse(angleSpaceToWorld), nextTail - head); + tailDir = AnglelimitCone.Apply(tailDir, joint.anglelimit1); + return math.mul(angleSpaceToWorld, tailDir); + } + + case AnglelimitTypes.Hinge: + { + var angleSpaceToWorld = anglelimitSpaceToWorld(logic, joint, parentRotation); + var tailDir = math.mul(math.inverse(angleSpaceToWorld), nextTail - head); + tailDir = AnglelimitHinge.Apply(tailDir, joint.anglelimit1); + return math.mul(angleSpaceToWorld, tailDir); + } + + + case AnglelimitTypes.Spherical: + { + var angleSpaceToWorld = anglelimitSpaceToWorld(logic, joint, parentRotation); + var tailDir = math.mul(math.inverse(angleSpaceToWorld), nextTail - head); + tailDir = AnglelimitSpherical.Apply(tailDir, joint.anglelimit1, joint.anglelimit2); + return math.mul(angleSpaceToWorld, tailDir); + } + + default: + throw new System.ArgumentException($"unknown joint.anglelimitType: {joint.anglelimitType}"); + } + } + + /// nextTail(position vector in world space) + /// tailDir(directionay vector in angle space) + /// + public static quaternion anglelimitSpaceToWorld(in BlittableJointImmutable logic, in BlittableJointMutable joint, + in quaternion parentRotation) + { + // Y+方向からjointのheadからtailに向かうベクトルへの最小回転 + var axisRotation = fromToQuaternion(new float3(0, 1, 0), logic.boneAxis); + + // limitのローカル空間をワールド空間に写像する回転 + return + math.mul(parentRotation, + math.mul(logic.localRotation, + math.mul(axisRotation, + joint.anglelimitOffset))) + ; + } + + // https://discussions.unity.com/t/unity-mathematics-equivalent-to-quaternion-fromtorotation/237459 + public static quaternion fromToQuaternion(in float3 from, in float3 to) + { + return quaternion.AxisAngle( + angle: math.acos( + math.clamp( + math.dot( + math.normalize(from), + math.normalize(to) + ), + -1f, + 1f) + ), + axis: math.normalize(math.cross(from, to)) + ); + } + + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs.meta similarity index 83% rename from Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta rename to Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs.meta index 99e27a255..f50304933 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e38e2998df511664cb0d6e582e6a05a3 +guid: 3c2f98858052fbe4c89b445bad4c979b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs deleted file mode 100644 index 1d9e06008..000000000 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Unity.Mathematics; - -namespace UniGLTF.SpringBoneJobs -{ - public static class AnglelimitSpace - { - public static float3 ToTailDir(in quaternion src) - { - // // Y+方向からjointのheadからtailに向かうベクトルへの最小回転 - // let axisRotation = fromToQuaternion(vec3(0, 1, 0), boneAxis); - - // // limitのローカル空間をワールド空間に写像する回転 - // let rotation = - // joint.parent.worldRotation * - // joint.localSpaceInitialRotation * - // axisRotation * - // joint.limit.rotation; - - // // tailの向きをlimitのローカル空間に写像する - // tailDir = tailDir.applyQuaternion(rotation.inverse); - - // // limitを適用する - // joint.limit.apply(tailDir); - - // // tailの向きをワールド空間に戻す - // tailDir = tailDir.applyQuaternion(rotation); - - throw new System.NotImplementedException(); - } - - public static quaternion FromTailDir(in float3 src) - { - throw new System.NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs index 3235b8964..139009d6c 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs @@ -94,6 +94,8 @@ namespace UniGLTF.SpringBoneJobs // 長さをboneLengthに強制 nextTail = headTransform.position + math.normalize(nextTail - headTransform.position) * logic.length; + nextTail = Anglelimit.Apply(logic, joint, parentRotation, head: headTransform.position, nextTail: nextTail); + // Collisionで移動 for (var colliderIndex = colliderSpan.startIndex; colliderIndex < colliderSpan.startIndex + colliderSpan.count; ++colliderIndex) { @@ -131,6 +133,8 @@ namespace UniGLTF.SpringBoneJobs } } + nextTail = Anglelimit.Apply(logic, joint, parentRotation, head: headTransform.position, nextTail: nextTail); + NextTail[logicIndex] = centerTransform.HasValue ? MathHelper.MultiplyPoint3x4(centerTransform.Value.worldToLocalMatrix, nextTail) : nextTail; From 6b71582ea631425623d4301ac40feeb449d17897 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 18 Jul 2025 05:00:14 +0900 Subject: [PATCH 23/33] =?UTF-8?q?=E3=81=99=E3=81=B9=E3=81=A6=E3=81=AE?= =?UTF-8?q?=E8=A1=9D=E7=AA=81=E5=BE=8C=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8F?= =?UTF-8?q?=E3=80=81=E8=A1=9D=E7=AA=81=E6=AF=8E=E3=81=AB=E8=A7=92=E5=BA=A6?= =?UTF-8?q?=E5=88=B6=E9=99=90=E3=81=99=E3=82=8B=E5=BF=85=E8=A6=81=E3=81=82?= =?UTF-8?q?=E3=82=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SpringBoneJobs/SpringBoneCollision.cs | 206 ++++++++++++++++++ .../SpringBoneCollision.cs.meta | 11 + .../SpringBoneJobs/UpdateFastSpringBoneJob.cs | 180 +-------------- 3 files changed, 225 insertions(+), 172 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs create mode 100644 Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs.meta diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs new file mode 100644 index 000000000..a8eeed670 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs @@ -0,0 +1,206 @@ +using UniGLTF.Runtime.Utils; +using UniGLTF.SpringBoneJobs.Blittables; +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class SpringBoneCollision + { + public static bool TryCollide( + in BlittableJointImmutable logic, in BlittableJointMutable joint, in BlittableTransform headTransform, + in BlittableCollider collider, in BlittableTransform colliderTransform, float maxColliderScale, + in float3 colliderWorldTail, in float3 colliderWorldPosition, + in float3 nextTail, out float3 newNextTail) + { + switch (collider.colliderType) + { + case BlittableColliderType.Sphere: + return TryResolveSphereCollision(joint, collider, colliderWorldPosition, headTransform, maxColliderScale, logic, nextTail, out newNextTail); + + case BlittableColliderType.Capsule: + return TryResolveCapsuleCollision(colliderWorldTail, colliderWorldPosition, headTransform, joint, collider, maxColliderScale, logic, nextTail, out newNextTail); + + case BlittableColliderType.Plane: + return TryResolvePlaneCollision(joint, collider, colliderTransform, nextTail, out newNextTail); + + case BlittableColliderType.SphereInside: + return TryResolveSphereCollisionInside(joint, collider, colliderTransform, nextTail, out newNextTail); + + case BlittableColliderType.CapsuleInside: + return TryResolveCapsuleCollisionInside(joint, collider, colliderTransform, nextTail, out newNextTail); + + default: + throw new System.NotImplementedException(); + } + } + + private static bool TryResolveSphereCollision( + in BlittableJointMutable joint, + in BlittableCollider collider, + in float3 worldPosition, + in BlittableTransform headTransform, + in float maxColliderScale, + in BlittableJointImmutable logic, + in float3 nextTail, out float3 newNextTail) + { + var r = joint.radius + collider.radius * maxColliderScale; + if (math.lengthsq(nextTail - worldPosition) <= (r * r)) + { + // ヒット。Colliderの半径方向に押し出す + var normal = math.normalize(nextTail - worldPosition); + var posFromCollider = worldPosition + normal * r; + // 長さをboneLengthに強制 + newNextTail = headTransform.position + math.normalize(posFromCollider - headTransform.position) * logic.length; + return true; + } + else + { + newNextTail = default; + return false; + } + } + + private static bool TryResolveCapsuleCollision( + float3 worldTail, + float3 worldPosition, + BlittableTransform headTransform, + BlittableJointMutable joint, + BlittableCollider collider, + float maxColliderScale, + BlittableJointImmutable logic, + in float3 nextTail, out float3 newNextTail) + { + var direction = worldTail - worldPosition; + if (math.lengthsq(direction) == 0) + { + // head側半球の球判定 + return TryResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, nextTail, out newNextTail); + } + var P = math.normalize(direction); + var Q = headTransform.position - worldPosition; + var dot = math.dot(P, Q); + if (dot <= 0) + { + // head側半球の球判定 + return TryResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, nextTail, out newNextTail); + } + if (dot >= math.length(direction)) + { + // tail側半球の球判定 + return TryResolveSphereCollision(joint, collider, worldTail, headTransform, maxColliderScale, logic, nextTail, out newNextTail); + } + + // head-tail上の m_transform.position との最近点 + var p = worldPosition + P * dot; + return TryResolveSphereCollision(joint, collider, p, headTransform, maxColliderScale, logic, nextTail, out newNextTail); + } + + /// + /// Collision with SpringJoint and PlaneCollider. + /// If collide update nextTail. + /// + /// joint + /// collier + /// colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset); + /// result of verlet integration + private static bool TryResolvePlaneCollision( + in BlittableJointMutable joint, + in BlittableCollider collider, + in BlittableTransform colliderTransform, + in float3 nextTail, out float3 newNextTail) + { + var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); + var transformedNormal = math.normalize(MathHelper.MultiplyVector(colliderTransform.localToWorldMatrix, collider.tailOrNormal)); + var delta = nextTail - transformedOffset; + + // ジョイントとコライダーの距離。負の値は衝突していることを示す + var distance = math.dot(delta, transformedNormal) - joint.radius; + + if (distance < 0) + { + // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す + var direction = transformedNormal; + newNextTail = nextTail - direction * distance; + return true; + } + else + { + newNextTail = default; + return false; + } + } + + private static bool TryResolveSphereCollisionInside( + in BlittableJointMutable joint, + in BlittableCollider collider, + in BlittableTransform colliderTransform, + in float3 nextTail, out float3 newNextTail) + { + var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); + var delta = nextTail - transformedOffset; + + // ジョイントとコライダーの距離。負の値は衝突していることを示す + var distance = collider.radius - joint.radius - math.length(delta); + + // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す + if (distance < 0) + { + var direction = -1 * math.normalize(delta); + newNextTail = nextTail - direction * distance; + return true; + } + else + { + newNextTail = default; + return false; + } + } + + private static bool TryResolveCapsuleCollisionInside( + in BlittableJointMutable joint, + in BlittableCollider collider, + in BlittableTransform colliderTransform, + in float3 nextTail, out float3 newNextTail) + { + var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); + var transformedTail = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.tailOrNormal); + var offsetToTail = transformedTail - transformedOffset; + var lengthSqCapsule = math.lengthsq(offsetToTail); + + var delta = nextTail - transformedOffset; + var dot = math.dot(offsetToTail, delta); + + if (dot < 0.0) + { + // ジョイントがカプセルの始点側にある場合 + // なにもしない + } + else if (dot > lengthSqCapsule) + { + // ジョイントがカプセルの終点側にある場合 + delta -= offsetToTail; + } + else + { + // ジョイントがカプセルの始点と終点の間にある場合 + delta -= offsetToTail * (dot / lengthSqCapsule); + } + + // ジョイントとコライダーの距離。負の値は衝突していることを示す + var distance = collider.radius - joint.radius - math.length(delta); + + // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す + if (distance < 0) + { + var direction = -1 * math.normalize(delta); + newNextTail = nextTail - direction * distance; + return true; + } + else + { + newNextTail = default; + return false; + } + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs.meta new file mode 100644 index 000000000..e52fa675b --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 400f2bc818ed9ed44ac8b852cbd9dcc5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs index 139009d6c..2cec59241 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/UpdateFastSpringBoneJob.cs @@ -106,35 +106,18 @@ namespace UniGLTF.SpringBoneJobs var worldPosition = MathHelper.MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.offset); var worldTail = MathHelper.MultiplyPoint3x4(colliderTransform.localToWorldMatrix, collider.tailOrNormal); - switch (collider.colliderType) + if (SpringBoneCollision.TryCollide(logic, joint, + headTransform, + collider, colliderTransform, maxColliderScale, + colliderWorldTail: worldTail, colliderWorldPosition: worldPosition, + nextTail: nextTail, + out var newNextTail)) { - case BlittableColliderType.Sphere: - ResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail); - break; - - case BlittableColliderType.Capsule: - ResolveCapsuleCollision(worldTail, worldPosition, headTransform, joint, collider, maxColliderScale, logic, ref nextTail); - break; - - case BlittableColliderType.Plane: - ResolvePlaneCollision(joint, collider, colliderTransform, ref nextTail); - break; - - case BlittableColliderType.SphereInside: - ResolveSphereCollisionInside(joint, collider, colliderTransform, ref nextTail); - break; - - case BlittableColliderType.CapsuleInside: - ResolveCapsuleCollisionInside(joint, collider, colliderTransform, ref nextTail); - break; - - default: - throw new NotImplementedException(); + // 衝突毎に nextTail を更新する。 + nextTail = Anglelimit.Apply(logic, joint, parentRotation, head: headTransform.position, nextTail: newNextTail); } } - nextTail = Anglelimit.Apply(logic, joint, parentRotation, head: headTransform.position, nextTail: nextTail); - NextTail[logicIndex] = centerTransform.HasValue ? MathHelper.MultiplyPoint3x4(centerTransform.Value.worldToLocalMatrix, nextTail) : nextTail; @@ -158,152 +141,5 @@ namespace UniGLTF.SpringBoneJobs } } - private static void ResolveCapsuleCollision( - float3 worldTail, - float3 worldPosition, - BlittableTransform headTransform, - BlittableJointMutable joint, - BlittableCollider collider, - float maxColliderScale, - BlittableJointImmutable logic, - ref float3 nextTail) - { - var direction = worldTail - worldPosition; - if (math.lengthsq(direction) == 0) - { - // head側半球の球判定 - ResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail); - return; - } - var P = math.normalize(direction); - var Q = headTransform.position - worldPosition; - var dot = math.dot(P, Q); - if (dot <= 0) - { - // head側半球の球判定 - ResolveSphereCollision(joint, collider, worldPosition, headTransform, maxColliderScale, logic, ref nextTail); - return; - } - if (dot >= math.length(direction)) - { - // tail側半球の球判定 - ResolveSphereCollision(joint, collider, worldTail, headTransform, maxColliderScale, logic, ref nextTail); - return; - } - - // head-tail上の m_transform.position との最近点 - var p = worldPosition + P * dot; - ResolveSphereCollision(joint, collider, p, headTransform, maxColliderScale, logic, ref nextTail); - } - - private static void ResolveSphereCollision( - in BlittableJointMutable joint, - in BlittableCollider collider, - in float3 worldPosition, - in BlittableTransform headTransform, - in float maxColliderScale, - in BlittableJointImmutable logic, - ref float3 nextTail) - { - var r = joint.radius + collider.radius * maxColliderScale; - if (math.lengthsq(nextTail - worldPosition) <= (r * r)) - { - // ヒット。Colliderの半径方向に押し出す - var normal = math.normalize(nextTail - worldPosition); - var posFromCollider = worldPosition + normal * r; - // 長さをboneLengthに強制 - nextTail = headTransform.position + math.normalize(posFromCollider - headTransform.position) * logic.length; - } - } - - private static void ResolveSphereCollisionInside( - in BlittableJointMutable joint, - in BlittableCollider collider, - in BlittableTransform colliderTransform, - ref float3 nextTail) - { - var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); - var delta = nextTail - transformedOffset; - - // ジョイントとコライダーの距離。負の値は衝突していることを示す - var distance = collider.radius - joint.radius - math.length(delta); - - // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す - if (distance < 0) - { - var direction = -1 * math.normalize(delta); - nextTail -= direction * distance; - } - } - - private static void ResolveCapsuleCollisionInside( - in BlittableJointMutable joint, - in BlittableCollider collider, - in BlittableTransform colliderTransform, - ref float3 nextTail) - { - var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); - var transformedTail = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.tailOrNormal); - var offsetToTail = transformedTail - transformedOffset; - var lengthSqCapsule = math.lengthsq(offsetToTail); - - var delta = nextTail - transformedOffset; - var dot = math.dot(offsetToTail, delta); - - if (dot < 0.0) - { - // ジョイントがカプセルの始点側にある場合 - // なにもしない - } - else if (dot > lengthSqCapsule) - { - // ジョイントがカプセルの終点側にある場合 - delta -= offsetToTail; - } - else - { - // ジョイントがカプセルの始点と終点の間にある場合 - delta -= offsetToTail * (dot / lengthSqCapsule); - } - - // ジョイントとコライダーの距離。負の値は衝突していることを示す - var distance = collider.radius - joint.radius - math.length(delta); - - // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す - if (distance < 0) - { - var direction = -1 * math.normalize(delta); - nextTail -= direction * distance; - } - } - - /// - /// Collision with SpringJoint and PlaneCollider. - /// If collide update nextTail. - /// - /// joint - /// collier - /// colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset); - /// result of verlet integration - private static void ResolvePlaneCollision( - in BlittableJointMutable joint, - in BlittableCollider collider, - in BlittableTransform colliderTransform, - ref float3 nextTail) - { - var transformedOffset = MathHelper.MultiplyPoint(colliderTransform.localToWorldMatrix, collider.offset); - var transformedNormal = math.normalize(MathHelper.MultiplyVector(colliderTransform.localToWorldMatrix, collider.tailOrNormal)); - var delta = nextTail - transformedOffset; - - // ジョイントとコライダーの距離。負の値は衝突していることを示す - var distance = math.dot(delta, transformedNormal) - joint.radius; - - if (distance < 0) - { - // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す - var direction = transformedNormal; - nextTail -= direction * distance; - } - } } } \ No newline at end of file From 08f22b917c9fb603b3e0c8aef1de48fdc5c5728a Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 18 Jul 2025 17:17:30 +0900 Subject: [PATCH 24/33] return tailDir --- .../UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs index d335044e3..d8c159f86 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs @@ -27,7 +27,7 @@ namespace UniGLTF.SpringBoneJobs tailDir.y = cosAngle; } - return src; + return tailDir; } } } \ No newline at end of file From df49cc5e1eec60cb62148e9f9653eb153c860bff Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 18 Jul 2025 17:27:48 +0900 Subject: [PATCH 25/33] Update Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../SpringBoneJobs/Anglelimit/Anglelimit.cs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs index 353a8547b..b91e3bd77 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs @@ -66,17 +66,24 @@ namespace UniGLTF.SpringBoneJobs // https://discussions.unity.com/t/unity-mathematics-equivalent-to-quaternion-fromtorotation/237459 public static quaternion fromToQuaternion(in float3 from, in float3 to) { + var fromNorm = math.normalize(from); + var toNorm = math.normalize(to); + var dot = math.dot(fromNorm, toNorm); + + // Handle the case where from and to are parallel but opposite + if (math.abs(dot + 1f) < 1e-6f) // dot is approximately -1 + { + // Find a perpendicular axis + var perpAxis = math.abs(fromNorm.x) > math.abs(fromNorm.z) + ? new float3(-fromNorm.y, fromNorm.x, 0f) + : new float3(0f, -fromNorm.z, fromNorm.y); + return quaternion.AxisAngle(math.normalize(perpAxis), math.PI); + } + + // General case return quaternion.AxisAngle( - angle: math.acos( - math.clamp( - math.dot( - math.normalize(from), - math.normalize(to) - ), - -1f, - 1f) - ), - axis: math.normalize(math.cross(from, to)) + angle: math.acos(math.clamp(dot, -1f, 1f)), + axis: math.normalize(math.cross(fromNorm, toNorm)) ); } From 8020b1ccadcb5a2c32a374204b4d83d6670d9d86 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 18 Jul 2025 17:28:06 +0900 Subject: [PATCH 26/33] Update Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs index a8eeed670..a8f5fc3b4 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/SpringBoneCollision.cs @@ -100,7 +100,7 @@ namespace UniGLTF.SpringBoneJobs /// If collide update nextTail. /// /// joint - /// collier + /// collider /// colliderTransform.localToWorldMatrix.MultiplyPoint3x4(collider.offset); /// result of verlet integration private static bool TryResolvePlaneCollision( From 9dddb6517bdcce28c8a13cc6002a463b4d4589cb Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 18 Jul 2025 17:32:21 +0900 Subject: [PATCH 27/33] cos_theta --- .../Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs index e6d07be63..b15ce10fa 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs @@ -30,7 +30,8 @@ namespace UniGLTF.SpringBoneJobs } // tailDirをphi・thetaを用いて再計算する - return new float3(math.sin(theta), math.cos(theta) * math.cos(phi), math.cos(theta) * math.sin(phi)); + var cos_theta = math.cos(theta); + return new float3(math.sin(theta), cos_theta * math.cos(phi), cos_theta * math.sin(phi)); } } } \ No newline at end of file From 8bf4cfe1ac7098a501a5c80b1265ddf76c20c3a3 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 18 Jul 2025 20:26:22 +0900 Subject: [PATCH 28/33] =?UTF-8?q?inspector=20=E3=81=8B=E3=82=89=20editor?= =?UTF-8?q?=20=E3=82=92=E9=96=8B=E3=81=91=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/SpringBone/VRM10SpringBoneJointEditor.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs index 2bb0fbd61..ad4a5cd42 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs @@ -8,6 +8,8 @@ namespace UniVRM10 class VRM10SpringBoneJointEditor : Editor { private VRM10SpringBoneJoint m_target; + + private SerializedProperty m_script; private SerializedProperty m_stiffnessForceProp; private SerializedProperty m_gravityPowerProp; private SerializedProperty m_gravityDirProp; @@ -24,6 +26,7 @@ namespace UniVRM10 } m_target = (VRM10SpringBoneJoint)target; + m_script = serializedObject.FindProperty("m_Script"); m_stiffnessForceProp = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_stiffnessForce)); m_gravityPowerProp = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_gravityPower)); m_gravityDirProp = serializedObject.FindProperty(nameof(VRM10SpringBoneJoint.m_gravityDir)); @@ -39,6 +42,11 @@ namespace UniVRM10 public override void OnInspectorGUI() { + using (new EditorGUI.DisabledScope(true)) + { + EditorGUILayout.PropertyField(m_script); + } + serializedObject.Update(); /// From 24b2aa18a9f38bbc2b013982d74448746dd84ff7 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 18 Jul 2025 21:49:44 +0900 Subject: [PATCH 29/33] =?UTF-8?q?VRM10SpringBoneJoint=20=E3=81=AB=20angle?= =?UTF-8?q?=20limit=20=E8=A8=AD=E5=AE=9A=E3=82=92=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=E3=81=97=E3=81=A6=E3=80=81runtime=20=E3=81=AB=E5=8F=8D?= =?UTF-8?q?=E6=98=A0=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SpringBoneJobs/Anglelimit/Anglelimit.cs | 12 +++--- .../Blittables/BlittableJointMutable.cs | 14 +++---- .../SpringBone/VRM10SpringBoneJointEditor.cs | 39 +++++++++++++++++++ .../SpringBone/VRM10SpringBoneJoint.cs | 28 ++++++++++++- .../Springbone/FastSpringBoneBufferFactory.cs | 7 +--- 5 files changed, 80 insertions(+), 20 deletions(-) diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs index b91e3bd77..178ab3d23 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/Anglelimit.cs @@ -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: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs index d6566a659..ccc69d2b6 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs @@ -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); } } diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs index ad4a5cd42..e3a55fe7e 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs @@ -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(); } @@ -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) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs index 4467d2a0b..5a18457a4 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs @@ -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) { diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/FastSpringBoneBufferFactory.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/FastSpringBoneBufferFactory.cs index b763e4697..e0430d6da 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/FastSpringBoneBufferFactory.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/FastSpringBoneBufferFactory.cs @@ -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(); From dfd5eceae5b3d8a2921145b96b7cd603aca87434 Mon Sep 17 00:00:00 2001 From: notargs Date: Thu, 7 Aug 2025 13:25:04 +0900 Subject: [PATCH 30/33] =?UTF-8?q?=E3=83=9E=E3=83=86=E3=83=AA=E3=82=A2?= =?UTF-8?q?=E3=83=AB=E3=81=8C=E6=AD=A3=E5=B8=B8=E3=81=AB=E9=96=8B=E6=94=BE?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=81=A6=E3=81=84=E3=81=AA=E3=81=84=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/Components/Expression/ExpressionMerger.cs | 5 ----- .../Expression/MaterialValueBindingMerger.cs | 11 ----------- .../Components/Vrm10Runtime/Vrm10RuntimeExpression.cs | 5 +---- 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs b/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs index e178df0c5..dd54cb70d 100644 --- a/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs +++ b/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs @@ -71,11 +71,6 @@ namespace UniVRM10 m_materialValueBindingMerger.AccumulateValue(clip, value); } - public void RestoreMaterialInitialValues() - { - m_materialValueBindingMerger.RestoreMaterialInitialValues(); - } - public void Dispose() { m_materialValueBindingMerger.Dispose(); diff --git a/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs b/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs index 665b2b611..a78a088cd 100644 --- a/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs +++ b/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs @@ -138,17 +138,6 @@ namespace UniVRM10 } } } - - /// - /// m_materialMap に記録した値に Material を復旧する - /// - public void RestoreMaterialInitialValues() - { - foreach (var kv in m_materialMap) - { - kv.Value.Clear(); - } - } #endregion #region Accumulate diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeExpression.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeExpression.cs index 902654f35..0a38b0481 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeExpression.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeExpression.cs @@ -51,14 +51,11 @@ namespace UniVRM10 public void Dispose() { - _merger?.RestoreMaterialInitialValues(); + _merger?.Dispose(); _merger = null; _eyeDirectionApplicable?.Restore(); _eyeDirectionApplicable = null; - - _merger?.Dispose(); - _merger = null; } internal void Process(LookAtEyeDirection inputEyeDirection) From b4bfb753b135dbf23c3e419d0ff938b1765a5eea Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 7 Aug 2025 17:01:40 +0900 Subject: [PATCH 31/33] Update Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs index 5a18457a4..d1e41e39d 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneJoint.cs @@ -51,7 +51,7 @@ namespace UniVRM10 angleLimitOffset: m_angleLimitRotation ); - void Oalidate() + void OnValidate() { if (m_angleLimitRotation == default) { From e8e6cc239e67dbd843cd60abc65bc93a4cb7373f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 7 Aug 2025 17:01:51 +0900 Subject: [PATCH 32/33] Update Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs index e3a55fe7e..b5f1e6dc3 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneJointEditor.cs @@ -85,7 +85,7 @@ namespace UniVRM10 } // - // angle limiet + // angle limit // m_showAnglelimitSettings = EditorGUILayout.Foldout(m_showAnglelimitSettings, "AngleLimit Settings(dev)"); if (m_showAnglelimitSettings) From 0f338a0b767f0ed85bebacd08aa3be8e11aef171 Mon Sep 17 00:00:00 2001 From: momoma-null Date: Fri, 8 Aug 2025 15:02:16 +0900 Subject: [PATCH 33/33] =?UTF-8?q?IVrm10SpringBoneRuntime=E3=81=AEProcess?= =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=81=ABdeltaTime=E5=BC=95=E6=95=B0=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Vrm10Runtime/Springbone/IVrm10SpringBoneRuntime.cs | 2 +- .../Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntime.cs | 2 +- .../Springbone/Vrm10FastSpringboneRuntimeStandalone.cs | 4 ++-- .../Vrm10Runtime/Springbone/Vrm10NopSpringboneRuntime.cs | 2 +- .../VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs | 2 +- .../ClothSample/ClothWarp/Runtime/ClothWarpRuntime.cs | 7 +------ .../ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs | 5 ----- 7 files changed, 7 insertions(+), 17 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntime.cs index 4a962499e..b45f1ae7e 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/IVrm10SpringBoneRuntime.cs @@ -43,7 +43,7 @@ namespace UniVRM10 /// /// 毎フレーム Vrm10Runtime.Process から呼ばれる。 /// - public void Process(); + public void Process(float deltaTime); /// /// from Vrm10Instance.OnDrawGizmosSelected diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntime.cs index 6dc1761e0..51a14b221 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntime.cs @@ -112,7 +112,7 @@ namespace UniVRM10 m_fastSpringBoneService.BufferCombiner.InitializeJointsLocalRotation(m_fastSpringBoneBuffer); } - public void Process() + public void Process(float deltaTime) { // FastSpringBoneService が実行するので何もしない } diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandalone.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandalone.cs index 12e151e07..c2fa75295 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandalone.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10FastSpringboneRuntimeStandalone.cs @@ -118,9 +118,9 @@ namespace UniVRM10 m_bufferCombiner.InitializeJointsLocalRotation(m_fastSpringBoneBuffer); } - public void Process() + public void Process(float deltaTime) { - m_fastSpringBoneScheduler.Schedule(Time.deltaTime).Complete(); + m_fastSpringBoneScheduler.Schedule(deltaTime).Complete(); } public void DrawGizmos() diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10NopSpringboneRuntime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10NopSpringboneRuntime.cs index 040b0b9de..f14e1e41e 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10NopSpringboneRuntime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Springbone/Vrm10NopSpringboneRuntime.cs @@ -20,7 +20,7 @@ namespace UniVRM10 return Task.CompletedTask; } - public void Process() + public void Process(float deltaTime) { } diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs index 5a800d2e1..e702496b1 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs @@ -156,7 +156,7 @@ namespace UniVRM10 Expression.Process(eyeDirection); // 6. SpringBone - SpringBone.Process(); + SpringBone.Process(Time.deltaTime); } } } \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/ClothWarpRuntime.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/ClothWarpRuntime.cs index 883af31c2..a36b11498 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/ClothWarpRuntime.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/ClothWarpRuntime.cs @@ -135,12 +135,7 @@ namespace UniVRM10.ClothWarp // } } - public void Process() - { - Process(Time.deltaTime); - } - - void Process(float deltaTime) + public void Process(float deltaTime) { if (!_initialized) { diff --git a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs index 8e2181786..294216ad1 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothWarp/Runtime/Jobs/ClothWarpJobRuntime.cs @@ -408,11 +408,6 @@ namespace UniVRM10.ClothWarp.Jobs } } - public void Process() - { - Process(Time.deltaTime); - } - public void Process(float deltaTime) { var frame = new FrameInfo(deltaTime, Vector3.zero);