From cf23267a9e40f8f5601b087ee9fda84c9a7d86e8 Mon Sep 17 00:00:00 2001 From: Benjamin Kraft Date: Sun, 6 Oct 2024 15:42:40 +0200 Subject: [PATCH] grab ignores back faces, properly selects closest face --- shaders/grab.comp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/shaders/grab.comp b/shaders/grab.comp index acc6d99..1d3e401 100644 --- a/shaders/grab.comp +++ b/shaders/grab.comp @@ -40,7 +40,7 @@ layout (set = 1, binding = 0) uniform CameraUniform { layout (std430, set = 2, binding = 1) buffer GrabInformation { float originalInverseMass; uint vID; - float distanceToFace; + uint distanceToFace; // bits are float format bool foundHit; }; @@ -88,7 +88,6 @@ void rayForward(out vec3 origin, out vec3 direction){ } void testFace(uint fID){ - // test this face, if hit, set grabinformation if distance is new minimum vec3 origin; vec3 direction; rayForward(origin, direction); @@ -102,7 +101,14 @@ void testFace(uint fID){ vec3 ac = c - a; vec3 n = cross(ab, ac); + if (dot(direction, n) < 0){ + return; + } + float r = dot(a - origin, n) / dot(direction, n); + if (r < 0){ + return; + } vec3 q = origin + r * direction; vec3 qa = a - q; @@ -117,14 +123,17 @@ void testFace(uint fID){ bool isOne = abs(alpha + beta + gamma - 1) < 0.001; if (alpha >= 0 && alpha <= 1 && beta >= 0 && beta <= 1 && gamma >= 0 && gamma <= 1 && isOne){ - if (r < distanceToFace){ + uint newDistance; + uint expectedOriginalDistance; + do { + expectedOriginalDistance = distanceToFace; + newDistance = floatBitsToUint(min(r, uintBitsToFloat(expectedOriginalDistance))); + } while (atomicCompSwap(distanceToFace, expectedOriginalDistance, newDistance) != expectedOriginalDistance); + if (newDistance == floatBitsToUint(r)){ foundHit = true; vID = face.a; - distanceToFace = r; } } - - } void move(){ @@ -146,7 +155,7 @@ void move(){ void release(){ vertices[vID].inverseMass = originalInverseMass; - distanceToFace = 1e20; + distanceToFace = floatBitsToUint(1.0e20); foundHit = false; }