From 77188fb14807f482ba7817cc7e84566c236fbd86 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 15 Nov 2024 20:12:31 +0900 Subject: [PATCH] RotateParticleSystem use Warp --- .../ClothSample/ClothViewer/ClothGuess.cs | 198 ++++++++++++++++ .../ClothGuess.cs.meta} | 2 +- .../ClothViewer/ClothViewer.asmdef | 3 +- .../ClothViewer/HumanoidCollider.cs | 34 +++ .../ClothViewer/HumanoidCollider.cs.meta | 11 + .../Runtime/CollisionGroupMask.cs} | 34 +-- .../Runtime/CollisionGroupMask.cs.meta | 11 + .../Runtime/Components/RectCloth.cs | 2 +- .../RotateParticle/Runtime/ParticleList.cs | 43 ++-- .../RotateParticleSpringboneRuntime.cs | 217 +----------------- .../Runtime/RotateParticleSystem.cs | 103 ++++----- .../ClothSample/SphereTriangle/README.md | 3 + .../ClothSample/SphereTriangle/README.md.meta | 7 + 13 files changed, 339 insertions(+), 329 deletions(-) create mode 100644 Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs rename Assets/VRM10_Samples/ClothSample/{SphereTriangle/StrandGroup.cs.meta => ClothViewer/ClothGuess.cs.meta} (83%) create mode 100644 Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs create mode 100644 Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs.meta rename Assets/VRM10_Samples/ClothSample/{SphereTriangle/StrandGroup.cs => RotateParticle/Runtime/CollisionGroupMask.cs} (62%) create mode 100644 Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/CollisionGroupMask.cs.meta create mode 100644 Assets/VRM10_Samples/ClothSample/SphereTriangle/README.md create mode 100644 Assets/VRM10_Samples/ClothSample/SphereTriangle/README.md.meta diff --git a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs new file mode 100644 index 000000000..9afa7cfae --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs @@ -0,0 +1,198 @@ +using System.Collections.Generic; +using System.Linq; +using RotateParticle; +using RotateParticle.Components; +using SphereTriangle; +using UnityEngine; + + +namespace UniVRM10.Cloth.Viewer +{ + public static class ClothGuess + { + public enum StrandConnectionType + { + Cloth, + ClothLoop, + Strand, + } + + public static void Guess(RotateParticleSystem _system, Animator animator) + { + // skirt + { + if (TryAddGroup(animator, HumanBodyBones.Hips, + new[] { "skirt", "スカート", "スカート" }, out var g)) + { + _system._warps.AddRange(g); + // StrandConnectionType.ClothLoop + } + } + { + if (TryAddGroupChildChild(animator, HumanBodyBones.Hips, + new[] { "skirt", "スカート", "スカート" }, new string[] { }, out var g)) + { + _system._warps.AddRange(g); + // StrandConnectionType.ClothLoop, + } + } + { + if (TryAddGroup(animator, HumanBodyBones.Head, + new[] { "髪", "hair" }, out var g)) + { + _system._warps.AddRange(g); + // StrandConnectionType.Strand, + } + } + { + if (TryAddGroup(animator, HumanBodyBones.Hips, + new[] { "裾" }, out var g)) + { + _system._warps.AddRange(g); + // StrandConnectionType.Cloth, + } + } + { + if (TryAddGroupChildChild(animator, HumanBodyBones.LeftUpperArm, + new[] { "袖" }, new[] { "ひじ袖" }, out var g)) + { + _system._warps.AddRange(g); + // StrandConnectionType.ClothLoop, + } + } + { + if (TryAddGroupChildChild(animator, HumanBodyBones.LeftLowerArm, + new[] { "袖" }, new string[] { }, out var g)) + { + _system._warps.AddRange(g); + // StrandConnectionType.ClothLoop, + } + } + { + if (TryAddGroupChildChild(animator, HumanBodyBones.RightUpperArm, + new[] { "袖" }, new[] { "ひじ袖" }, out var g)) + { + _system._warps.AddRange(g); + // , StrandConnectionType.ClothLoop + } + } + { + if (TryAddGroupChildChild(animator, HumanBodyBones.RightLowerArm, + new[] { "袖" }, new string[] { }, out var g)) + { + _system._warps.AddRange(g); + // StrandConnectionType.ClothLoop, false, + } + } + { + if (TryAddGroup(animator, HumanBodyBones.Chest, new[] { "マント" }, + out var g)) + { + _system._warps.AddRange(g); + // StrandConnectionType.Cloth, + } + } + + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + static bool TryAddGroupChildChild( + Animator animator, HumanBodyBones humanBone, + string[] targets, string[] excludes, + out List group) + { + var bone = animator.GetBoneTransform(humanBone); + if (bone == null) + { + Debug.LogWarning($"{humanBone} not found"); + group = default; + return false; + } + + List transforms = new(); + foreach (Transform child in bone) + { + foreach (Transform childchild in child) + { + if (excludes.Any(x => childchild.name.ToLower().Contains(x.ToLower()))) + { + continue; + } + + foreach (var target in targets) + { + if (childchild.name.ToLower().Contains(target.ToLower())) + { + var warp = childchild.gameObject.AddComponent(); + // Name = name, + // CollisionMask = mask, + warp.BaseSettings.HitRadius = 0.02f; + // Connection = type + transforms.Add(warp); + break; + } + } + } + } + if (transforms.Count == 0) + { + // Debug.LogWarning($"{string.Join(',', targets)} not found"); + group = default; + return false; + } + + group = transforms; + return true; + } + + static bool TryAddGroup(Animator animator, HumanBodyBones humanBone, string[] targets, + out List group) + { + var bone = animator.GetBoneTransform(humanBone); + if (bone == null) + { + Debug.LogWarning($"{humanBone} not found"); + group = default; + return false; + } + + List transforms = new(); + foreach (Transform child in bone) + { + foreach (var target in targets) + { + if (child.name.ToLower().Contains(target.ToLower())) + { + var warp = child.gameObject.AddComponent(); + // CollisionMask = mask, + warp.BaseSettings.HitRadius = 0.02f; + // Connection = type + transforms.Add(warp); + break; + } + } + } + if (transforms.Count == 0) + { + // Debug.LogWarning($"{string.Join(',', targets)} not found"); + group = default; + return false; + } + + group = transforms; + return true; + } + } +} \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/SphereTriangle/StrandGroup.cs.meta b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs.meta similarity index 83% rename from Assets/VRM10_Samples/ClothSample/SphereTriangle/StrandGroup.cs.meta rename to Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs.meta index 4dbbe515d..2ac6006fa 100644 --- a/Assets/VRM10_Samples/ClothSample/SphereTriangle/StrandGroup.cs.meta +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: efab592ca762fea46adb3c38b41e65d0 +guid: 8ad944ee2631d2b4eb6a33e6bbcd349f MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewer.asmdef b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewer.asmdef index 75b04563e..7d155e41b 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewer.asmdef +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewer.asmdef @@ -6,7 +6,8 @@ "GUID:8d76e605759c3f64a957d63ef96ada7c", "GUID:1cd941934d098654fa21a13f28346412", "GUID:e47c917724578cc43b5506c17a27e9a0", - "GUID:308b348fb80d89d42a9620951b0f60db" + "GUID:308b348fb80d89d42a9620951b0f60db", + "GUID:0138a2c7639266f45b948ea162125de5" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs b/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs new file mode 100644 index 000000000..a09e16c99 --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs @@ -0,0 +1,34 @@ +using System.Collections; +using System.Collections.Generic; +using RotateParticle; +using UnityEngine; + +namespace UniVRM10.Cloth.Viewer +{ + public static class HumanCollider + { + static (string group, HumanBodyBones head, HumanBodyBones tail, float radius)[] Capsules = new[] + { + ("Leg", HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg, 0.06f), + ("Leg", HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot, 0.05f), + ("Leg", HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg, 0.06f), + ("Leg", HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot, 0.05f), + + ("Arm", HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, 0.03f), + ("Arm", HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand, 0.03f), + ("Arm", HumanBodyBones.LeftHand, HumanBodyBones.LeftMiddleProximal, 0.02f), + ("Arm", HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, 0.03f), + ("Arm", HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand, 0.03f), + ("Arm", HumanBodyBones.RightHand, HumanBodyBones.RightMiddleProximal, 0.02f), + }; + + public static void AddColliders(RotateParticleSystem _system, Animator animator) + { + foreach (var (group, head, tail, radius) in Capsules) + { + _system.AddColliderIfNotExists(group, + animator.GetBoneTransform(head), animator.GetBoneTransform(tail), radius); + } + } + } +} \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs.meta b/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs.meta new file mode 100644 index 000000000..ab43b935a --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/HumanoidCollider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6fd7b5b1e402644088796a17d7c2df9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10_Samples/ClothSample/SphereTriangle/StrandGroup.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/CollisionGroupMask.cs similarity index 62% rename from Assets/VRM10_Samples/ClothSample/SphereTriangle/StrandGroup.cs rename to Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/CollisionGroupMask.cs index c4392467b..e2a3204f9 100644 --- a/Assets/VRM10_Samples/ClothSample/SphereTriangle/StrandGroup.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/CollisionGroupMask.cs @@ -1,16 +1,5 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace SphereTriangle +namespace RotateParticle { - public enum StrandConnectionType - { - Cloth, - ClothLoop, - Strand, - } - [System.Flags] public enum CollisionGroupMask : uint { @@ -49,25 +38,4 @@ namespace SphereTriangle Group32 = 0x80000000, All = uint.MaxValue, } - - [Serializable] - public class StrandGroup - { - [SerializeField] - public string Name; - - [SerializeField] - public CollisionGroupMask CollisionMask; - - [SerializeField] - public StrandConnectionType Connection; - - [SerializeField] - public List Roots = new List(); - - [SerializeField] - [Range(0.001f, 0.5f)] - public float DefaultStrandRaius = 0.05f; - - } } \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/CollisionGroupMask.cs.meta b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/CollisionGroupMask.cs.meta new file mode 100644 index 000000000..8672185ef --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/CollisionGroupMask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ac7f1d83935aa84b9e80739be4ae02b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/Components/RectCloth.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/Components/RectCloth.cs index 078ad3abf..dda267afb 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/Components/RectCloth.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/Components/RectCloth.cs @@ -10,7 +10,7 @@ namespace RotateParticle.Components public class RectCloth : MonoBehaviour { [SerializeField] - public bool Loop = false; + public bool LoopIsClosed = false; [SerializeField] public List Warps = new(); diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/ParticleList.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/ParticleList.cs index de7babbed..ca5af0133 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/ParticleList.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/ParticleList.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using SphereTriangle; +using RotateParticle.Components; using UnityEngine; @@ -12,35 +12,28 @@ namespace RotateParticle public List _particles = new(); public List _particleTransforms = new(); - public Strand MakeParticleStrand(SimulationEnv env, Transform t, float radius, CollisionGroupMask mask) + public Strand MakeParticleStrand(SimulationEnv env, Warp warp, CollisionGroupMask mask) { var strand = new Strand(mask); - _MakeParticlesRecursive(strand, env, 0, t, radius, null); + + // root kinematic + var particle_index = _MakeAParticle(null, env, warp.transform, 0, 0, strand.CollisionMask); + var joint = _particles[particle_index]; + strand.Particles.Add(joint); + + foreach (var particle in warp.Particles) + { + var child_index = _MakeAParticle(joint, env, particle.Transform, + particle.GetSettings(warp.BaseSettings).HitRadius, 1, strand.CollisionMask); + var child = _particles[child_index]; + joint.Children.Add(child); + joint = child; + } + return strand; } - RotateParticle _MakeParticlesRecursive(Strand strand, SimulationEnv env, int child_index, Transform t, float radius, RotateParticle parent) - { - var mass = parent == null ? 0 : 1; - if (child_index > 0) - { - // 枝分かれ動かない - mass = 0; - } - - var particle_index = _MakeAParticle(env, t, radius, parent, mass, strand.CollisionMask); - var joint = _particles[particle_index]; - strand.Particles.Add(joint); - for (int i = 0; i < t.childCount; ++i) - { - var child = t.GetChild(i); - var child_joint = _MakeParticlesRecursive(strand, env, i, child, radius, joint); - joint.Children.Add(child_joint); - } - return joint; - } - - int _MakeAParticle(SimulationEnv env, Transform t, float radius, RotateParticle parent, float mass, CollisionGroupMask collisionMask) + int _MakeAParticle(RotateParticle parent, SimulationEnv env, Transform t, float radius, float mass, CollisionGroupMask collisionMask) { var index = _particles.Count; _particleTransforms.Add(t); diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSpringboneRuntime.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSpringboneRuntime.cs index 248c29b81..f8c04ca7b 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSpringboneRuntime.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSpringboneRuntime.cs @@ -1,19 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; -using SphereTriangle; +using RotateParticle.Components; using UniGLTF; using UniGLTF.SpringBoneJobs.Blittables; using UnityEngine; using UniVRM10; + namespace RotateParticle { - /// - /// SpcriptedImporter 経由の import 向け。 - /// NativeArray の確保や DontDestroyOnLoad を回避。 - /// public class RotateParticleSpringboneRuntime : IVrm10SpringBoneRuntime { RotateParticleSystem _system; @@ -24,12 +18,6 @@ namespace RotateParticle public async Task InitializeAsync(Vrm10Instance instance, IAwaitCaller awaitCaller) { - await awaitCaller.NextFrame(); - // if (_setup != null) - // { - // _setup(instance); - // } - var animator = instance.GetComponent(); if (animator == null) { @@ -48,211 +36,16 @@ namespace RotateParticle _system.Env.DragForce = 0.6f; _system.Env.Stiffness = 0.07f; - foreach (var (group, head, tail, radius) in Capsules) + foreach (var warp in instance.GetComponentsInChildren()) { - _system.AddColliderIfNotExists(group, - animator.GetBoneTransform(head), animator.GetBoneTransform(tail), radius); - } + _system._warps.Add(warp); - // skirt - { - if (TryAddGroup(CollisionGroupMask.Group01, "Skirt", animator, HumanBodyBones.Hips, new[] { "skirt", "スカート", "スカート" }, StrandConnectionType.ClothLoop, - out var g)) - { - _system._strandGroups.Add(g); - } - } - { - if (TryAddGroupChildChild(CollisionGroupMask.Group01, "Skirt", animator, HumanBodyBones.Hips, new[] { "skirt", "スカート", "スカート" }, new string[] { }, StrandConnectionType.ClothLoop, false, - out var g)) - { - _system._strandGroups.Add(g); - } - } - { - if (TryAddGroup(CollisionGroupMask.Group02, "髪", animator, HumanBodyBones.Head, new[] { "髪", "hair" }, StrandConnectionType.Strand, - out var g)) - { - _system._strandGroups.Add(g); - } - } - { - if (TryAddGroup(CollisionGroupMask.Group01, "裾", animator, HumanBodyBones.Hips, new[] { "裾" }, StrandConnectionType.Cloth, - out var g)) - { - _system._strandGroups.Add(g); - } - } - { - if (TryAddGroupChildChild(CollisionGroupMask.Group02, "左袖", animator, HumanBodyBones.LeftUpperArm, new[] { "袖" }, new[] { "ひじ袖" }, StrandConnectionType.ClothLoop, - false, - out var g)) - { - _system._strandGroups.Add(g); - } - } - { - if (TryAddGroupChildChild(CollisionGroupMask.Group02, "左ひじ袖", animator, HumanBodyBones.LeftLowerArm, new[] { "袖" }, new string[] { }, StrandConnectionType.ClothLoop, - false, - out var g)) - { - _system._strandGroups.Add(g); - } - } - { - if (TryAddGroupChildChild(CollisionGroupMask.Group02, "右袖", animator, HumanBodyBones.RightUpperArm, new[] { "袖" }, new[] { "ひじ袖" }, StrandConnectionType.ClothLoop, - false, - out var g)) - { - _system._strandGroups.Add(g); - } - } - { - if (TryAddGroupChildChild(CollisionGroupMask.Group02, "右ひじ袖", animator, HumanBodyBones.RightLowerArm, new[] { "袖" }, new string[] { }, StrandConnectionType.ClothLoop, - false, - out var g)) - { - _system._strandGroups.Add(g); - } - } - { - if (TryAddGroup(CollisionGroupMask.Group01 | CollisionGroupMask.Group02, "マント", animator, HumanBodyBones.Chest, new[] { "マント" }, StrandConnectionType.Cloth, - out var g)) - { - _system._strandGroups.Add(g); - } + await awaitCaller.NextFrame(); } _system.Initialize(); } - static (string group, HumanBodyBones head, HumanBodyBones tail, float radius)[] Capsules = new[] - { - ("Leg", HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg, 0.06f), - ("Leg", HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot, 0.05f), - ("Leg", HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg, 0.06f), - ("Leg", HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot, 0.05f), - - ("Arm", HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, 0.03f), - ("Arm", HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand, 0.03f), - ("Arm", HumanBodyBones.LeftHand, HumanBodyBones.LeftMiddleProximal, 0.02f), - ("Arm", HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, 0.03f), - ("Arm", HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand, 0.03f), - ("Arm", HumanBodyBones.RightHand, HumanBodyBones.RightMiddleProximal, 0.02f), - }; - - // T GetOrAddComponent() where T : Component - // { - // var t = GetComponent(); - // if (t != null) - // { - // return t; - // } - // return gameObject.AddComponent(); - // } - - bool TryAddGroup(CollisionGroupMask mask, string name, Animator animator, HumanBodyBones humanBone, string[] targets, StrandConnectionType type, - out StrandGroup group) - { - var bone = animator.GetBoneTransform(humanBone); - if (bone == null) - { - Debug.LogWarning($"{humanBone} not found"); - group = default; - return false; - } - - List transforms = new(); - foreach (Transform child in bone) - { - foreach (var target in targets) - { - if (child.name.ToLower().Contains(target.ToLower())) - { - transforms.Add(child); - break; - } - } - } - if (transforms.Count == 0) - { - // Debug.LogWarning($"{string.Join(',', targets)} not found"); - group = default; - return false; - } - - group = new StrandGroup - { - Name = name, - CollisionMask = mask, - DefaultStrandRaius = 0.02f, - Connection = type - }; - group.Roots.AddRange(transforms); - - // sort - group.Roots.Sort(new TransformSort(bone.position)); - return true; - } - - bool TryAddGroupChildChild(CollisionGroupMask mask, string name, Animator animator, HumanBodyBones humanBone, - string[] targets, string[] excludes, - StrandConnectionType type, - bool sort, - out StrandGroup group) - { - var bone = animator.GetBoneTransform(humanBone); - if (bone == null) - { - Debug.LogWarning($"{humanBone} not found"); - group = default; - return false; - } - - List transforms = new(); - foreach (Transform child in bone) - { - foreach (Transform childchild in child) - { - if (excludes.Any(x => childchild.name.ToLower().Contains(x.ToLower()))) - { - continue; - } - - foreach (var target in targets) - { - if (childchild.name.ToLower().Contains(target.ToLower())) - { - transforms.Add(childchild); - break; - } - } - } - } - if (transforms.Count == 0) - { - // Debug.LogWarning($"{string.Join(',', targets)} not found"); - group = default; - return false; - } - - group = new StrandGroup - { - Name = name, - CollisionMask = mask, - DefaultStrandRaius = 0.02f, - Connection = type - }; - group.Roots.AddRange(transforms); - - // sort - if (sort) - { - group.Roots.Sort(new TransformSort(bone.position)); - } - return true; - } - public void Process() { _system.Process(Time.deltaTime); diff --git a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSystem.cs b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSystem.cs index 437507c16..5a7ce3184 100644 --- a/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSystem.cs +++ b/Assets/VRM10_Samples/ClothSample/RotateParticle/Runtime/RotateParticleSystem.cs @@ -15,7 +15,7 @@ namespace RotateParticle public SimulationEnv Env = new(); [SerializeField] - public List _strandGroups = new List(); + public List _warps = new(); [SerializeField] public List _colliderGroups = new(); @@ -96,22 +96,53 @@ namespace RotateParticle HashSet _clothUsedParticles = new(); public void InitializeCloth( - StrandGroup g, + Components.RectCloth g, ParticleList list, List strands, List<(SpringConstraint, ClothRectCollision)> clothRects) { - if (g.Connection == StrandConnectionType.Cloth || g.Connection == StrandConnectionType.ClothLoop) + for (int i = 1; i < strands.Count; ++i) { - for (int i = 1; i < strands.Count; ++i) + var s0 = strands[i - 1]; + var s1 = strands[i]; + for (int j = 1; j < s0.Particles.Count && j < s1.Particles.Count; ++j) { - var s0 = strands[i - 1]; - var s1 = strands[i]; + // d x x c + // | | + // a x-x b + var a = s0.Particles[j]; + var b = s1.Particles[j]; + var c = s1.Particles[j - 1]; + var d = s0.Particles[j - 1]; + _clothUsedParticles.Add(a.Init.Index); + _clothUsedParticles.Add(b.Init.Index); + _clothUsedParticles.Add(c.Init.Index); + _clothUsedParticles.Add(d.Init.Index); + if (i % 2 == 1) + { + // 互い違いに + // abcd to badc + (a, b) = (b, a); + (c, d) = (d, c); + } + clothRects.Add(( + new SpringConstraint( + list._particles[a.Init.Index], + list._particles[b.Init.Index]), + new ClothRectCollision( + a.Init.Index, b.Init.Index, c.Init.Index, d.Init.Index))); + } + } + + if (strands.Count >= 3) + { + if (g.LoopIsClosed) + { + var i = strands.Count; + var s0 = strands.Last(); + var s1 = strands.First(); for (int j = 1; j < s0.Particles.Count && j < s1.Particles.Count; ++j) { - // d x x c - // | | - // a x-x b var a = s0.Particles[j]; var b = s1.Particles[j]; var c = s1.Particles[j - 1]; @@ -132,42 +163,9 @@ namespace RotateParticle list._particles[a.Init.Index], list._particles[b.Init.Index]), new ClothRectCollision( - a.Init.Index, b.Init.Index, c.Init.Index, d.Init.Index))); - } - } - if (strands.Count >= 3) - { - if (g.Connection == StrandConnectionType.ClothLoop) - { - var i = strands.Count; - var s0 = strands.Last(); - var s1 = strands.First(); - for (int j = 1; j < s0.Particles.Count && j < s1.Particles.Count; ++j) - { - var a = s0.Particles[j]; - var b = s1.Particles[j]; - var c = s1.Particles[j - 1]; - var d = s0.Particles[j - 1]; - _clothUsedParticles.Add(a.Init.Index); - _clothUsedParticles.Add(b.Init.Index); - _clothUsedParticles.Add(c.Init.Index); - _clothUsedParticles.Add(d.Init.Index); - if (i % 2 == 1) - { - // 互い違いに - // abcd to badc - (a, b) = (b, a); - (c, d) = (d, c); - } - clothRects.Add(( - new SpringConstraint( - list._particles[a.Init.Index], - list._particles[b.Init.Index]), - new ClothRectCollision( - a.Init.Index, b.Init.Index, c.Init.Index, d.Init.Index - ) - )); - } + a.Init.Index, b.Init.Index, c.Init.Index, d.Init.Index + ) + )); } } } @@ -175,20 +173,13 @@ namespace RotateParticle public void Initialize() { - foreach (var g in _strandGroups) + foreach (var g in _warps) { - if (g.Roots?.Count == 0) - { - continue; - } var strands = new List(); - foreach (var root in g.Roots) - { - var strand = _list.MakeParticleStrand(Env, root, g.DefaultStrandRaius, g.CollisionMask); - strands.Add(strand); - } + var strand = _list.MakeParticleStrand(Env, g, default); + strands.Add(strand); - InitializeCloth(g, _list, strands, _clothRects); + // InitializeCloth(g, _list, strands, _clothRects); _strands.AddRange(strands); } diff --git a/Assets/VRM10_Samples/ClothSample/SphereTriangle/README.md b/Assets/VRM10_Samples/ClothSample/SphereTriangle/README.md new file mode 100644 index 000000000..b2c397a77 --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/SphereTriangle/README.md @@ -0,0 +1,3 @@ +# SphereTriangle + +球と三角形の衝突判定に関する補助ライブラリー \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/SphereTriangle/README.md.meta b/Assets/VRM10_Samples/ClothSample/SphereTriangle/README.md.meta new file mode 100644 index 000000000..7135b4e26 --- /dev/null +++ b/Assets/VRM10_Samples/ClothSample/SphereTriangle/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 08a7b8ca5ff1079449b681d78a8f9c34 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: