Files
ZHGD_Web/Assets/Art/Art Plugins/GPUInstancer/Resources/Compute/Include/Collider.hlsl

99 lines
3.5 KiB
HLSL
Raw Normal View History

2025-07-13 23:16:20 +08:00
#ifndef __collider_hlsl_
#define __collider_hlsl_
uniform float3 boundsCenter;
uniform float3 boundsExtents;
uniform float4x4 modifierTransform;
uniform float modifierRadius;
uniform float modifierHeight;
uniform float3 modifierAxis;
#include "Matrix.hlsl"
inline bool IsInsideBounds(float3 position)
{
float3 Min = boundsCenter - boundsExtents;
float3 Max = boundsCenter + boundsExtents;
return position.x >= Min.x && position.x <= Max.x
&& position.y >= Min.y && position.y <= Max.y
&& position.z >= Min.z && position.z <= Max.z;
}
inline bool IsInsideBox(float3 position)
{
float3 Min = boundsCenter - boundsExtents;
float3 Max = boundsCenter + boundsExtents;
float4 BoundingBox[8];
BoundingBox[0] = mul(modifierTransform, float4(Min.x, Max.y, Min.z, 1.0)); // P5
BoundingBox[1] = mul(modifierTransform, float4(Min.x, Max.y, Max.z, 1.0)); // P6
BoundingBox[2] = mul(modifierTransform, float4(Max.x, Max.y, Max.z, 1.0)); // P7
BoundingBox[3] = mul(modifierTransform, float4(Max.x, Max.y, Min.z, 1.0)); // P8
BoundingBox[4] = mul(modifierTransform, float4(Max.x, Min.y, Min.z, 1.0)); // P4
BoundingBox[5] = mul(modifierTransform, float4(Max.x, Min.y, Max.z, 1.0)); // P3
BoundingBox[6] = mul(modifierTransform, float4(Min.x, Min.y, Max.z, 1.0)); // P2
BoundingBox[7] = mul(modifierTransform, float4(Min.x, Min.y, Min.z, 1.0)); // P1
// https://math.stackexchange.com/questions/1472049/check-if-a-point-is-inside-a-rectangular-shaped-area-3d
//i=p2p1
float3 i = BoundingBox[6].xyz - BoundingBox[7].xyz;
//j=p4p1
float3 j = BoundingBox[4].xyz - BoundingBox[7].xyz;
//k=p5p1
float3 k = BoundingBox[0].xyz - BoundingBox[7].xyz;
//v=pvp1
float3 v = position - BoundingBox[7].xyz;
float vi = dot(v, i);
float vj = dot(v, j);
float vk = dot(v, k);
//0<v⋅i<i⋅i
return 0 < vi && vi < dot(i, i)
//0<v⋅j<j⋅j
&& 0 < vj && vj < dot(j, j)
//0<v⋅k<k⋅k
&& 0 < vk && vk < dot(k, k);
}
inline bool IsInsideSphere(float3 position)
{
return distance(boundsCenter, position) <= modifierRadius;
}
inline bool IsInsideCapsule(float3 position)
{
float pointChange = 0;
if (modifierHeight / 2 > modifierRadius)
{
pointChange = (modifierHeight / 2) - modifierRadius;
float4x4 scaled = SetScaleOfMatrix(modifierTransform, 1);
// https://math.stackexchange.com/questions/1905533/find-perpendicular-distance-from-point-to-line-in-3d
float3 A = position;
float3 B = mul(scaled, float4(boundsCenter.x + modifierAxis.x * pointChange, boundsCenter.y + modifierAxis.y * pointChange, boundsCenter.z + modifierAxis.z * pointChange, 1.0)).xyz;
float3 C = mul(scaled, float4(boundsCenter.x - modifierAxis.x * pointChange, boundsCenter.y - modifierAxis.y * pointChange, boundsCenter.z - modifierAxis.z * pointChange, 1.0)).xyz;
float3 d = (C - B) / distance(C, B);
float3 v = A - B;
float t = dot(v, d);
float3 P = B + t * d;
float distPB = distance(P, B);
float distPC = distance(P, C);
float distBC = distance(B, C);
if (abs(distBC - (distPB + distPC)) < 0.1)
return distance(P, A) <= modifierRadius;
else if (distPB < distPC)
return distance(B, A) <= modifierRadius;
else
return distance(C, A) <= modifierRadius;
}
else
return distance(boundsCenter + modifierTransform._14_24_34, position) <= modifierRadius;
}
#endif