From ac76bb95a49071cf31a0791468ea5fa9a6f5c567 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 11 Aug 2024 19:48:09 +0100 Subject: [PATCH] box2d: Add inlined intersection operator If we want to just know if two boxes intersect each other, we can do that with an inlined function. It's not the fastest possible function, because it still requires calling into graphene_box2d_get_minmax(), as the calling code does not have access to the private fields of the graphene_box2d_t type. --- include/graphene-box2d.h | 42 ++++++++++++++++++++++++++++++++++++++++ tests/box2d.c | 19 ++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/graphene-box2d.h b/include/graphene-box2d.h index dcfbe4e..ccb3c02 100644 --- a/include/graphene-box2d.h +++ b/include/graphene-box2d.h @@ -11,6 +11,8 @@ #endif #include "graphene-types.h" +#include "graphene-point.h" +#include "graphene-simd4f.h" #include "graphene-vec2.h" #include "graphene-vec4.h" @@ -121,6 +123,46 @@ GRAPHENE_AVAILABLE_IN_1_12 bool graphene_box2d_equal (const graphene_box2d_t *a, const graphene_box2d_t *b); +static inline bool +graphene_box2d_intersects (const graphene_box2d_t *a, + const graphene_box2d_t *b); + +/** + * graphene_box2d_intersects: + * @a: a #graphene_box2d_t + * @b: a #graphene_box2d_t + * + * Checks whether two boxes intersect. + * + * See also: graphene_box2d_intersection() + * + * Returns: true if the boxes intersect, and false otherwise + * + * Since: 1.12 + */ +static inline bool +graphene_box2d_intersects (const graphene_box2d_t *a, + const graphene_box2d_t *b) +{ + graphene_point_t min_a, max_a; + graphene_box2d_get_minmax (a, &min_a, &max_a); + + graphene_point_t min_b, max_b; + graphene_box2d_get_minmax (b, &min_b, &max_b); + + graphene_simd4f_t min_v = + graphene_simd4f_max (graphene_simd4f_init (min_a.x, min_a.y, 0.f, 0.f), + graphene_simd4f_init (min_b.x, min_b.y, 0.f, 0.f)); + graphene_simd4f_t max_v = + graphene_simd4f_min (graphene_simd4f_init (max_a.x, max_a.y, 0.f, 0.f), + graphene_simd4f_init (max_b.x, max_b.y, 0.f, 0.f)); + + if (!graphene_simd4f_cmp_le (min_v, max_v)) + return false; + + return true; +} + GRAPHENE_AVAILABLE_IN_1_12 const graphene_box2d_t * graphene_box2d_zero (void); GRAPHENE_AVAILABLE_IN_1_12 diff --git a/tests/box2d.c b/tests/box2d.c index 2003184..562f9b5 100644 --- a/tests/box2d.c +++ b/tests/box2d.c @@ -322,6 +322,25 @@ box2d_intersection (mutest_spec_t *spec) mutest_bool_value (graphene_box2d_intersection (&top, &bottom, NULL)), mutest_to_be_false, NULL); + + graphene_box2d_t a, b, c; + graphene_box2d_init (&a, &GRAPHENE_POINT_INIT (0.f, 0.f), &GRAPHENE_POINT_INIT (2.f, 2.f)); + graphene_box2d_init (&b, &GRAPHENE_POINT_INIT (1.f, 1.f), &GRAPHENE_POINT_INIT (2.f, 2.f)); + graphene_box2d_init (&c, &GRAPHENE_POINT_INIT (3.f, 3.f), &GRAPHENE_POINT_INIT (4.f, 4.f)); + + bool a_b = graphene_box2d_intersects (&a, &b); + mutest_expect ("intersect to match intersection (positive)", + mutest_bool_value (a_b), + mutest_to_be_true, + mutest_to_be, graphene_box2d_intersection (&a, &b, NULL), + NULL); + + bool a_c = graphene_box2d_intersects (&a, &c); + mutest_expect ("intersect to match intersection (negative)", + mutest_bool_value (a_c), + mutest_to_be_false, + mutest_to_be, graphene_box2d_intersection (&a, &c, NULL), + NULL); } static void