You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
4.3 KiB
C#
89 lines
4.3 KiB
C#
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
namespace FluffyGroomingTool {
|
|
public static class ColliderHelper {
|
|
public static void setupCollidersBuffer(
|
|
ref ComputeBuffer colliderBuffer,
|
|
ref ColliderStruct[] collidersStruct,
|
|
SphereCollider[] sphereColliders,
|
|
CapsuleCollider[] capsuleColliders
|
|
) {
|
|
colliderBuffer?.Dispose();
|
|
colliderBuffer = null;
|
|
var collidersCount = getCollidersCount(sphereColliders, capsuleColliders);
|
|
if (collidersCount > 0) {
|
|
colliderBuffer = new ComputeBuffer(collidersCount, ColliderStruct.Size());
|
|
collidersStruct = new ColliderStruct[collidersCount];
|
|
for (int i = 0; i < collidersCount; i++) {
|
|
collidersStruct[i] = new ColliderStruct();
|
|
}
|
|
|
|
colliderBuffer.SetData(collidersStruct);
|
|
}
|
|
}
|
|
|
|
public static void setupColliderProperties(
|
|
ref ComputeBuffer colliderBuffer,
|
|
ref ColliderStruct[] collidersStruct,
|
|
SphereCollider[] sphereColliders,
|
|
CapsuleCollider[] capsuleColliders,
|
|
ComputeShader compute,
|
|
int kernel
|
|
) {
|
|
if (!collidersAssigned(sphereColliders, capsuleColliders)) return;
|
|
var collidersCount = getCollidersCount(sphereColliders, capsuleColliders);
|
|
if (collidersCount > 0) {
|
|
if (colliderBuffer?.count != collidersCount) setupCollidersBuffer(ref colliderBuffer, ref collidersStruct, sphereColliders, capsuleColliders);
|
|
|
|
var sphereCollidersLength = sphereColliders.Length;
|
|
setupSphereColliders(collidersStruct, sphereColliders, sphereCollidersLength);
|
|
setupCapsuleColliders(collidersStruct, capsuleColliders, sphereCollidersLength);
|
|
colliderBuffer.SetData(collidersStruct);
|
|
setSphereAndCapsuleColliders(compute, kernel, collidersCount, colliderBuffer);
|
|
}
|
|
else {
|
|
compute.DisableKeyword(ShaderID.HAS_COLLIDERS);
|
|
}
|
|
}
|
|
|
|
private static void setupSphereColliders(ColliderStruct[] collidersStruct, SphereCollider[] sphereColliders, int sphereCollidersLength) {
|
|
for (var i = 0; i < sphereCollidersLength; i++) {
|
|
if (sphereColliders[i] != null) {
|
|
collidersStruct[i].position = sphereColliders[i].transform.position + sphereColliders[i].center;
|
|
collidersStruct[i].radius = sphereColliders[i].radius * sphereColliders[i].transform.lossyScale.x;
|
|
collidersStruct[i].position2 = SPHERE_COLLIDER_ID; //For now this means that its a sphereCollider.
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void setupCapsuleColliders(ColliderStruct[] collidersStruct, CapsuleCollider[] capsuleColliders, int sphereCollidersLength) {
|
|
for (var i = 0; i < capsuleColliders.Length; i++) {
|
|
if (capsuleColliders[i] != null) {
|
|
ColliderStruct colliderStruct = collidersStruct[sphereCollidersLength + i];
|
|
capsuleColliders[i]
|
|
.toWorldSpaceCapsule(out colliderStruct.position, out colliderStruct.position2, out colliderStruct.radius);
|
|
collidersStruct[sphereCollidersLength + i] = colliderStruct;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void setSphereAndCapsuleColliders(ComputeShader compute, int kernel, int collidersCount, ComputeBuffer colliderBuffer) {
|
|
compute.SetBuffer(kernel, ShaderID.COLLIDER_BUFFER, colliderBuffer);
|
|
compute.SetInt(ShaderID.COLLIDERS_COUNT, collidersCount);
|
|
compute.EnableKeyword(ShaderID.HAS_COLLIDERS);
|
|
}
|
|
|
|
private static readonly Vector3 SPHERE_COLLIDER_ID = Vector3.left * 1000;
|
|
|
|
public static bool collidersAssigned(SphereCollider[] sphereColliders, CapsuleCollider[] capsuleColliders) {
|
|
return sphereColliders != null && capsuleColliders != null &&
|
|
sphereColliders.All(t => t != null) && capsuleColliders.All(t => t != null);
|
|
}
|
|
|
|
private static int getCollidersCount(SphereCollider[] sphereColliders, CapsuleCollider[] capsuleColliders) {
|
|
return sphereColliders == null ? 0 : sphereColliders.Length + capsuleColliders.Length;
|
|
}
|
|
}
|
|
}
|