mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-10-01 07:11:02 -05:00
RotateParticleSystem use Warp
This commit is contained in:
198
Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs
Normal file
198
Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs
Normal file
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="mask"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="animator"></param>
|
||||
/// <param name="humanBone"></param>
|
||||
/// <param name="targets"></param>
|
||||
/// <param name="excludes"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="sort"></param>
|
||||
/// <param name="group"></param>
|
||||
/// <returns></returns>
|
||||
static bool TryAddGroupChildChild(
|
||||
Animator animator, HumanBodyBones humanBone,
|
||||
string[] targets, string[] excludes,
|
||||
out List<Warp> group)
|
||||
{
|
||||
var bone = animator.GetBoneTransform(humanBone);
|
||||
if (bone == null)
|
||||
{
|
||||
Debug.LogWarning($"{humanBone} not found");
|
||||
group = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Warp> 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<Warp>();
|
||||
// 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<Warp> group)
|
||||
{
|
||||
var bone = animator.GetBoneTransform(humanBone);
|
||||
if (bone == null)
|
||||
{
|
||||
Debug.LogWarning($"{humanBone} not found");
|
||||
group = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Warp> transforms = new();
|
||||
foreach (Transform child in bone)
|
||||
{
|
||||
foreach (var target in targets)
|
||||
{
|
||||
if (child.name.ToLower().Contains(target.ToLower()))
|
||||
{
|
||||
var warp = child.gameObject.AddComponent<Warp>();
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efab592ca762fea46adb3c38b41e65d0
|
||||
guid: 8ad944ee2631d2b4eb6a33e6bbcd349f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -6,7 +6,8 @@
|
||||
"GUID:8d76e605759c3f64a957d63ef96ada7c",
|
||||
"GUID:1cd941934d098654fa21a13f28346412",
|
||||
"GUID:e47c917724578cc43b5506c17a27e9a0",
|
||||
"GUID:308b348fb80d89d42a9620951b0f60db"
|
||||
"GUID:308b348fb80d89d42a9620951b0f60db",
|
||||
"GUID:0138a2c7639266f45b948ea162125de5"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6fd7b5b1e402644088796a17d7c2df9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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<Transform> Roots = new List<Transform>();
|
||||
|
||||
[SerializeField]
|
||||
[Range(0.001f, 0.5f)]
|
||||
public float DefaultStrandRaius = 0.05f;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ac7f1d83935aa84b9e80739be4ae02b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -10,7 +10,7 @@ namespace RotateParticle.Components
|
||||
public class RectCloth : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public bool Loop = false;
|
||||
public bool LoopIsClosed = false;
|
||||
|
||||
[SerializeField]
|
||||
public List<Warp> Warps = new();
|
||||
|
||||
@@ -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<RotateParticle> _particles = new();
|
||||
public List<Transform> _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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// SpcriptedImporter 経由の import 向け。
|
||||
/// NativeArray の確保や DontDestroyOnLoad を回避。
|
||||
/// </summary>
|
||||
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<Animator>();
|
||||
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<Warp>())
|
||||
{
|
||||
_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<T>() where T : Component
|
||||
// {
|
||||
// var t = GetComponent<T>();
|
||||
// if (t != null)
|
||||
// {
|
||||
// return t;
|
||||
// }
|
||||
// return gameObject.AddComponent<T>();
|
||||
// }
|
||||
|
||||
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<Transform> 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<Transform> 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);
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace RotateParticle
|
||||
public SimulationEnv Env = new();
|
||||
|
||||
[SerializeField]
|
||||
public List<StrandGroup> _strandGroups = new List<StrandGroup>();
|
||||
public List<Components.Warp> _warps = new();
|
||||
|
||||
[SerializeField]
|
||||
public List<ColliderGroup> _colliderGroups = new();
|
||||
@@ -96,22 +96,53 @@ namespace RotateParticle
|
||||
HashSet<int> _clothUsedParticles = new();
|
||||
|
||||
public void InitializeCloth(
|
||||
StrandGroup g,
|
||||
Components.RectCloth g,
|
||||
ParticleList list,
|
||||
List<Strand> 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<Strand>();
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# SphereTriangle
|
||||
|
||||
球と三角形の衝突判定に関する補助ライブラリー
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08a7b8ca5ff1079449b681d78a8f9c34
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user