RectCollisionReduceJob

This commit is contained in:
ousttrue 2024-12-01 01:55:44 +09:00
parent 4f40c44fea
commit 7fccb941f6
8 changed files with 216 additions and 129 deletions

View File

@ -53,9 +53,9 @@ namespace UniVRM10.ClothWarp.Jobs
NativeArray<Vector3> _nextPositions;
NativeArray<Quaternion> _nextRotations;
NativeArray<Vector3> _strandCollision;
// NativeArray<int> _clothCollisionCount;
NativeArray<Vector3> _clothCollision;
NativeArray<Vector3> _warpCollision;
NativeArray<int> _rectCollisionCount;
NativeArray<Vector3> _rectCollisionDelta;
NativeArray<Vector3> _forces;
//
@ -68,6 +68,7 @@ namespace UniVRM10.ClothWarp.Jobs
//
NativeArray<bool> _clothUsedParticles;
NativeArray<(int ClothGridIndex, SpringConstraint SpringConstraint, SphereTriangle.ClothRect Rect)> _clothRects;
NativeArray<(Vector3, Vector3, Vector3, Vector3)> _clothRectResults;
//
// cloth grid
@ -91,9 +92,9 @@ namespace UniVRM10.ClothWarp.Jobs
if (_prevPositions.IsCreated) _prevPositions.Dispose();
if (_nextPositions.IsCreated) _nextPositions.Dispose();
if (_nextRotations.IsCreated) _nextRotations.Dispose();
if (_strandCollision.IsCreated) _strandCollision.Dispose();
// if (_clothCollisionCount.IsCreated) _clothCollisionCount.Dispose();
if (_clothCollision.IsCreated) _clothCollision.Dispose();
if (_warpCollision.IsCreated) _warpCollision.Dispose();
if (_rectCollisionCount.IsCreated) _rectCollisionCount.Dispose();
if (_rectCollisionDelta.IsCreated) _rectCollisionDelta.Dispose();
if (_forces.IsCreated) _forces.Dispose();
if (_warps.IsCreated) _warps.Dispose();
@ -101,6 +102,7 @@ namespace UniVRM10.ClothWarp.Jobs
if (_clothUsedParticles.IsCreated) _clothUsedParticles.Dispose();
if (_clothRects.IsCreated) _clothRects.Dispose();
if (_clothRectResults.IsCreated) _clothRectResults.Dispose();
}
(int index, bool isNew) GetTransformIndex(Transform t,
@ -302,9 +304,9 @@ namespace UniVRM10.ClothWarp.Jobs
_nextPositions = new(pos.Length, Allocator.Persistent);
_nextRotations = new(pos.Length, Allocator.Persistent);
_info = new(info.ToArray(), Allocator.Persistent);
_strandCollision = new(pos.Length, Allocator.Persistent);
// _clothCollisionCount = new(pos.Length, Allocator.Persistent);
_clothCollision = new(pos.Length, Allocator.Persistent);
_warpCollision = new(pos.Length, Allocator.Persistent);
_rectCollisionCount = new(pos.Length, Allocator.Persistent);
_rectCollisionDelta = new(pos.Length, Allocator.Persistent);
_forces = new(pos.Length, Allocator.Persistent);
//
@ -312,6 +314,7 @@ namespace UniVRM10.ClothWarp.Jobs
//
var clothRects = new ClothRectList(_transforms, vrm);
_clothRects = new(clothRects.List.ToArray(), Allocator.Persistent);
_clothRectResults = new(clothRects.List.Count, Allocator.Persistent);
_clothUsedParticles = new(clothRects.ClothUsedParticles, Allocator.Persistent);
_building = false;
@ -388,8 +391,8 @@ namespace UniVRM10.ClothWarp.Jobs
CurrentPositions = _currentPositions,
Forces = _forces,
// CollisionCount = _clothCollisionCount,
CollisionDelta = _clothCollision,
CollisionCount = _rectCollisionCount,
CollisionDelta = _rectCollisionDelta,
}.Schedule(_transformAccessArray, handle);
// spring(cloth weft)
@ -425,7 +428,7 @@ namespace UniVRM10.ClothWarp.Jobs
// collision
{
var handle0 = new StrandCollisionJob
var handle0 = new WarpCollisionJob
{
Colliders = _colliderInfo,
CurrentColliders = _currentColliders,
@ -433,7 +436,7 @@ namespace UniVRM10.ClothWarp.Jobs
Info = _info,
NextPositions = _nextPositions,
ClothUsedParticles = _clothUsedParticles,
StrandCollision = _strandCollision,
StrandCollision = _warpCollision,
Warps = _warps,
ColliderGroupRef = _colliderGroupRef,
@ -441,17 +444,16 @@ namespace UniVRM10.ClothWarp.Jobs
ColliderRef = _colliderRef,
}.Schedule(_info.Length, 1, handle);
var handle1 = new ClothCollisionJob
var handle1 = new RectCollisionJob
{
ClothRects = _clothRects,
ClothRectResults = _clothRectResults,
Colliders = _colliderInfo,
CurrentColliders = _currentColliders,
Info = _info,
NextPositions = _nextPositions,
// CollisionCount = _clothCollisionCount,
ClothCollision = _clothCollision,
ClothRects = _clothRects,
Cloths = _cloths,
ColliderGroupRef = _colliderGroupRef,
@ -459,14 +461,24 @@ namespace UniVRM10.ClothWarp.Jobs
ColliderRef = _colliderRef,
}.Schedule(_clothRects.Length, 1, handle);
handle1 = new RectCollisionReduceJob
{
ClothRects = _clothRects,
ClothRectResults = _clothRectResults,
NextPositions = _nextPositions,
RectCollisionCount = _rectCollisionCount,
RectCollisionDelta = _rectCollisionDelta,
}.Schedule(handle1);
handle = JobHandle.CombineDependencies(handle0, handle1);
handle = new CollisionApplyJob
{
ClothUsedParticles = _clothUsedParticles,
StrandCollision = _strandCollision,
// ClothCollisionCount = _clothCollisionCount,
ClothCollision = _clothCollision,
StrandCollision = _warpCollision,
RectCollisionCount = _rectCollisionCount,
RectCollisionDelta = _rectCollisionDelta,
NextPosition = _nextPositions,
}.Schedule(_info.Length, 1, handle);
}

View File

@ -0,0 +1,51 @@
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Jobs;
namespace UniVRM10.ClothWarp.Jobs
{
public struct ClothInfo
{
public ArrayRange ColliderGroupRefRange;
}
public struct InputColliderJob : IJobParallelForTransform
{
[WriteOnly] public NativeArray<Matrix4x4> CurrentCollider;
public void Execute(int colliderIndex, TransformAccess transform)
{
CurrentCollider[colliderIndex] = transform.localToWorldMatrix;
}
}
public struct CollisionApplyJob : IJobParallelFor
{
[ReadOnly] public NativeArray<bool> ClothUsedParticles;
[ReadOnly] public NativeArray<Vector3> StrandCollision;
[ReadOnly] public NativeArray<int> RectCollisionCount;
[ReadOnly] public NativeArray<Vector3> RectCollisionDelta;
public NativeArray<Vector3> NextPosition;
public void Execute(int particleIndex)
{
if (ClothUsedParticles[particleIndex])
{
var count = RectCollisionCount[particleIndex];
if (count > 0)
{
// 一つの頂点が最大で近接する4つの rect で当たり判定をされる
// 衝突結果を足して割る
NextPosition[particleIndex] += RectCollisionDelta[particleIndex] / count;
}
}
else
{
NextPosition[particleIndex] = StrandCollision[particleIndex];
}
}
}
}

View File

@ -43,7 +43,7 @@ namespace UniVRM10.ClothWarp.Jobs
[WriteOnly] public NativeArray<TransformData> InputData;
[WriteOnly] public NativeArray<Vector3> CurrentPositions;
// [WriteOnly] public NativeArray<int> CollisionCount;
[WriteOnly] public NativeArray<int> CollisionCount;
[WriteOnly] public NativeArray<Vector3> CollisionDelta;
[WriteOnly] public NativeArray<Vector3> Forces;
@ -59,7 +59,7 @@ namespace UniVRM10.ClothWarp.Jobs
}
// clear cloth
// CollisionCount[particleIndex] = 0;
CollisionCount[particleIndex] = 0;
CollisionDelta[particleIndex] = Vector3.zero;
Forces[particleIndex] = Vector3.zero;
}

View File

@ -4,99 +4,23 @@ using UniGLTF.SpringBoneJobs.Blittables;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Jobs;
namespace UniVRM10.ClothWarp.Jobs
{
public struct ClothInfo
public struct RectCollisionJob : IJobParallelFor
{
public ArrayRange ColliderGroupRefRange;
}
public struct InputColliderJob : IJobParallelForTransform
{
[WriteOnly] public NativeArray<Matrix4x4> CurrentCollider;
public void Execute(int colliderIndex, TransformAccess transform)
{
CurrentCollider[colliderIndex] = transform.localToWorldMatrix;
}
}
public struct StrandCollisionJob : IJobParallelFor
{
// collider
[ReadOnly] public NativeArray<BlittableCollider> Colliders;
[ReadOnly] public NativeArray<Matrix4x4> CurrentColliders;
// particle
[ReadOnly] public NativeArray<TransformInfo> Info;
[ReadOnly] public NativeArray<Vector3> NextPositions;
[ReadOnly] public NativeArray<bool> ClothUsedParticles;
[WriteOnly] public NativeArray<Vector3> StrandCollision;
// collider group
[ReadOnly] public NativeArray<WarpInfo> Warps;
[ReadOnly] public NativeArray<int> ColliderGroupRef;
[ReadOnly] public NativeArray<ArrayRange> ColliderGroup;
[ReadOnly] public NativeArray<int> ColliderRef;
public void Execute(int particleIndex)
{
if (!ClothUsedParticles[particleIndex])
{
var info = Info[particleIndex];
var pos = NextPositions[particleIndex];
var warp = Warps[info.WarpIndex];
for (int groupRefIndex = warp.ColliderGroupRefRange.Start; groupRefIndex < warp.ColliderGroupRefRange.End; ++groupRefIndex)
{
var groupIndex = ColliderGroupRef[groupRefIndex];
var group = ColliderGroup[groupIndex];
for (int colliderRefIndex = group.Start; colliderRefIndex < group.End; ++colliderRefIndex)
{
var colliderIndex = ColliderRef[colliderRefIndex];
var c = Colliders[colliderIndex];
var m = CurrentColliders[c.transformIndex];
if (c.colliderType == BlittableColliderType.Capsule)
{
if (SphereSphereCollision.TryCollideCapsuleAndSphere(m.MultiplyPoint(c.offset), m.MultiplyPoint(c.tailOrNormal), c.radius,
pos, info.Settings.radius, out var l))
{
pos += l.GetDelta(c.radius);
}
}
else
{
if (SphereSphereCollision.TryCollideSphereAndSphere(m.MultiplyPoint(c.offset), c.radius,
pos, info.Settings.radius, out var l))
{
pos += l.GetDelta(c.radius);
}
}
}
}
StrandCollision[particleIndex] = pos;
}
}
}
public struct ClothCollisionJob : IJobParallelFor
{
// collider
[ReadOnly] public NativeArray<BlittableCollider> Colliders;
[ReadOnly] public NativeArray<Matrix4x4> CurrentColliders;
// particle
[ReadOnly] public NativeArray<TransformInfo> Info;
[ReadOnly] public NativeArray<Vector3> NextPositions;
// [NativeDisableParallelForRestriction] public NativeArray<int> CollisionCount;
[NativeDisableParallelForRestriction] public NativeArray<Vector3> ClothCollision;
// cloth
[ReadOnly] public NativeArray<(int, SpringConstraint, ClothRect)> ClothRects;
[WriteOnly] public NativeArray<(Vector3, Vector3, Vector3, Vector3)> ClothRectResults;
// collider
[ReadOnly] public NativeArray<BlittableCollider> Colliders;
[ReadOnly] public NativeArray<Matrix4x4> CurrentColliders;
// particle
[ReadOnly] public NativeArray<TransformInfo> Info;
[ReadOnly] public NativeArray<Vector3> NextPositions;
// collider group
[ReadOnly] public NativeArray<ClothInfo> Cloths;
@ -174,10 +98,7 @@ namespace UniVRM10.ClothWarp.Jobs
}
}
ClothCollision[rect._a] = a;
ClothCollision[rect._b] = b;
ClothCollision[rect._c] = c;
ClothCollision[rect._d] = d;
ClothRectResults[rectIndex] = (a, b, c, d);
}
static bool TryCollide(BlittableCollider collider, in Matrix4x4 colliderMatrix, in Triangle t, out LineSegment l)
@ -261,30 +182,43 @@ namespace UniVRM10.ClothWarp.Jobs
throw new NotImplementedException();
}
}
}
public struct CollisionApplyJob : IJobParallelFor
public struct RectCollisionReduceJob : IJob
{
[ReadOnly] public NativeArray<bool> ClothUsedParticles;
[ReadOnly] public NativeArray<Vector3> StrandCollision;
// [ReadOnly] public NativeArray<int> ClothCollisionCount;
[ReadOnly] public NativeArray<Vector3> ClothCollision;
[NativeDisableParallelForRestriction] public NativeArray<Vector3> NextPosition;
[ReadOnly] public NativeArray<(int, SpringConstraint, ClothRect)> ClothRects;
[ReadOnly] public NativeArray<(Vector3, Vector3, Vector3, Vector3)> ClothRectResults;
[ReadOnly] public NativeArray<Vector3> NextPositions;
public void Execute(int particleIndex)
public NativeArray<int> RectCollisionCount;
public NativeArray<Vector3> RectCollisionDelta;
public void Execute()
{
if (ClothUsedParticles[particleIndex])
for (int rectIndex = 0; rectIndex < ClothRects.Length; ++rectIndex)
{
// if (ClothCollisionCount[particleIndex] > 0)
var (clothGridIndex, spring, rect) = ClothRects[rectIndex];
var (a, b, c, d) = ClothRectResults[rectIndex];
if (a != NextPositions[rect._a])
{
// NextPosition[particleIndex] += (ClothCollision[particleIndex] / ClothCollisionCount[particleIndex]);
NextPosition[particleIndex] = ClothCollision[particleIndex];
RectCollisionDelta[rect._a] += a - NextPositions[rect._a];
RectCollisionCount[rect._a] += 1;
}
if (b != NextPositions[rect._b])
{
RectCollisionDelta[rect._b] += b - NextPositions[rect._b];
RectCollisionCount[rect._b] += 1;
}
if (c != NextPositions[rect._c])
{
RectCollisionDelta[rect._c] += c - NextPositions[rect._c];
RectCollisionCount[rect._c] += 1;
}
if (d != NextPositions[rect._d])
{
RectCollisionDelta[rect._d] += d - NextPositions[rect._d];
RectCollisionCount[rect._d] += 1;
}
}
else
{
NextPosition[particleIndex] = StrandCollision[particleIndex];
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 127d372d227187449960f33a08791017
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,68 @@
using SphereTriangle;
using UniGLTF.SpringBoneJobs.Blittables;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
namespace UniVRM10.ClothWarp.Jobs
{
public struct WarpCollisionJob : IJobParallelFor
{
// collider
[ReadOnly] public NativeArray<BlittableCollider> Colliders;
[ReadOnly] public NativeArray<Matrix4x4> CurrentColliders;
// particle
[ReadOnly] public NativeArray<TransformInfo> Info;
[ReadOnly] public NativeArray<Vector3> NextPositions;
[ReadOnly] public NativeArray<bool> ClothUsedParticles;
[WriteOnly] public NativeArray<Vector3> StrandCollision;
// collider group
[ReadOnly] public NativeArray<WarpInfo> Warps;
[ReadOnly] public NativeArray<int> ColliderGroupRef;
[ReadOnly] public NativeArray<ArrayRange> ColliderGroup;
[ReadOnly] public NativeArray<int> ColliderRef;
public void Execute(int particleIndex)
{
if (!ClothUsedParticles[particleIndex])
{
var info = Info[particleIndex];
var pos = NextPositions[particleIndex];
var warp = Warps[info.WarpIndex];
for (int groupRefIndex = warp.ColliderGroupRefRange.Start; groupRefIndex < warp.ColliderGroupRefRange.End; ++groupRefIndex)
{
var groupIndex = ColliderGroupRef[groupRefIndex];
var group = ColliderGroup[groupIndex];
for (int colliderRefIndex = group.Start; colliderRefIndex < group.End; ++colliderRefIndex)
{
var colliderIndex = ColliderRef[colliderRefIndex];
var c = Colliders[colliderIndex];
var m = CurrentColliders[c.transformIndex];
if (c.colliderType == BlittableColliderType.Capsule)
{
if (SphereSphereCollision.TryCollideCapsuleAndSphere(m.MultiplyPoint(c.offset), m.MultiplyPoint(c.tailOrNormal), c.radius,
pos, info.Settings.radius, out var l))
{
pos += l.GetDelta(c.radius);
}
}
else
{
if (SphereSphereCollision.TryCollideSphereAndSphere(m.MultiplyPoint(c.offset), c.radius,
pos, info.Settings.radius, out var l))
{
pos += l.GetDelta(c.radius);
}
}
}
}
StrandCollision[particleIndex] = pos;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 80e53200fa3841748ad1d1416efdd53b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: