-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Graphene can't handle axis aligned ray directions #214
Comments
I've looked at it a bit, and found an interesting oddity. In |
I think the bug here is that |
Indeed. I spent some time trying to work around that, and come up with a SSE 4.1 implementation that turned that Also, not sure requiring SSE4.1 is an option. |
Fwiw, here is the SSE4.1 variant:
|
Also not sure if |
So, based on your code for Mutter, this seems to work here: @@ -485,27 +486,46 @@ graphene_ray_intersect_box (const graphene_ray_t *r,
const graphene_box_t *b,
float *t_out)
{
+ graphene_vec3_t safe_direction;
graphene_vec3_t inv_dir;
+ float d[3];
+
+#define V(v) (graphene_approx_val (d[v], 0.f) ? 2 * FLT_EPSILON : d[v])
+ graphene_vec3_to_float (&r->direction, d);
+ graphene_vec3_init (&safe_direction, V (0), V (1), V (2));
+#undef V
/* FIXME: Needs a graphene_vec3_reciprocal() */
- inv_dir.value = graphene_simd4f_reciprocal (r->direction.value);
+ inv_dir.value = graphene_simd4f_reciprocal (safe_direction.value); |
Here seems like a better place for this code than in mutter. |
Ping @ebassi . |
The solution from @GeorgesStavracas looks good to me. I wonder if he wants to open a PR, or if I should do that. |
The formula used to calculate the inverse of the direction vector doesn't handle the direction vector aligning with an axis. Depending on the SIMD (or not SIMD) implementation used, a axis aligned vector would either remain the same, or e.g. end up with NaN components messing up any future calculations. Fixing the math to handle this is non-trivial, so for now work around this by nudging the direction vector slightly off axis so that it has a better hand of hitting the right box even when the direction is axis aligned. Closes: ebassi#214
I went and created #217 that works slightly the same, except it uses a static inline function and makes sure the direction stays on the correct side of the axis. |
The formula used to calculate the inverse of the direction vector doesn't handle the direction vector aligning with an axis. Depending on the SIMD (or not SIMD) implementation used, a axis aligned vector would either remain the same, or e.g. end up with NaN components messing up any future calculations. Fixing the math to handle this is non-trivial, so for now work around this by nudging the direction vector slightly off axis so that it has a better hand of hitting the right box even when the direction is axis aligned. Closes: ebassi#214
The formula used to calculate the inverse of the direction vector doesn't handle the direction vector aligning with an axis. Depending on the SIMD (or not SIMD) implementation used, a axis aligned vector would either remain the same, or e.g. end up with NaN components messing up any future calculations. Fixing the math to handle this is non-trivial, so for now work around this by nudging the direction vector slightly off axis so that it has a better hand of hitting the right box even when the direction is axis aligned. Closes: #214
Experienced behavior
Using
graphene_ray_intersect_box()
using a ray with a direction that is axis aligned (one or more components is0.0
), the formula used to calculate whether the ray intersects with the box fails.Expected behavior
The ray/box intersection should be correctly detected.
Steps to reproduce
Reproducer:
With SSE2, the above program prints:
and with SSE2 turned off, it prints:
Operating system in use
Fedora 33.
SIMD implementation in use
See above.
The text was updated successfully, but these errors were encountered: