Add line-AABB collision check function
parent
c27fa632a2
commit
7767b38221
|
@ -49,3 +49,45 @@ bool point_in_AABB(Vector2 point, Rectangle box)
|
||||||
&& point.y < box.y + box.height
|
&& point.y < box.y + box.height
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool line_in_AABB(Vector2 p1, Vector2 p2, Rectangle box)
|
||||||
|
{
|
||||||
|
float A = p2.y - p1.y;
|
||||||
|
float B = p1.x - p2.x;
|
||||||
|
float C = (p2.x * p1.y) - (p1.x * p2.y);
|
||||||
|
|
||||||
|
Vector2 corners[3] =
|
||||||
|
{
|
||||||
|
{box.x + box.width - 1, box.y},
|
||||||
|
{box.x + box.width - 1, box.y + box.height - 1},
|
||||||
|
{box.x, box.y + box.height - 1},
|
||||||
|
};
|
||||||
|
|
||||||
|
float F = (A * box.x + B * box.y + C);
|
||||||
|
uint8_t last_mode = 0;
|
||||||
|
if (fabs(F) < 1e-3)
|
||||||
|
{
|
||||||
|
last_mode = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last_mode = (F > 0) ? 1 : 2;
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
F = (A * corners[i].x + B * corners[i].y + C);
|
||||||
|
uint8_t mode = 0;
|
||||||
|
if (fabs(F) < 1e-3)
|
||||||
|
{
|
||||||
|
mode = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mode = (F > 0) ? 1 : 2;
|
||||||
|
}
|
||||||
|
if (mode != last_mode) return true;
|
||||||
|
last_mode = mode;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -6,4 +6,5 @@
|
||||||
uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap);
|
uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap);
|
||||||
uint8_t find_AABB_overlap(const Vector2 tl1, const Vector2 sz1, const Vector2 tl2, const Vector2 sz2, Vector2* overlap);
|
uint8_t find_AABB_overlap(const Vector2 tl1, const Vector2 sz1, const Vector2 tl2, const Vector2 sz2, Vector2* overlap);
|
||||||
bool point_in_AABB(Vector2 point, Rectangle box);
|
bool point_in_AABB(Vector2 point, Rectangle box);
|
||||||
|
bool line_in_AABB(Vector2 p1, Vector2 p2, Rectangle box);
|
||||||
#endif // __AABB_H
|
#endif // __AABB_H
|
||||||
|
|
|
@ -6,6 +6,44 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <cmocka.h>
|
#include <cmocka.h>
|
||||||
|
|
||||||
|
static void test_line_AABB(void **state)
|
||||||
|
{
|
||||||
|
(void) state;
|
||||||
|
|
||||||
|
Vector2 p1 = {0, 0};
|
||||||
|
Vector2 p2 = {20, 20};
|
||||||
|
|
||||||
|
Rectangle box = {5, 0, 10, 20};
|
||||||
|
assert_true(line_in_AABB(p1, p2, box));
|
||||||
|
|
||||||
|
p1.y = 20;
|
||||||
|
assert_false(line_in_AABB(p1, p2, box));
|
||||||
|
|
||||||
|
p1.y = 19;
|
||||||
|
p2 = (Vector2){19, 19};
|
||||||
|
assert_true(line_in_AABB(p1, p2, box));
|
||||||
|
|
||||||
|
p1.y = 0;
|
||||||
|
p2.y = 0;
|
||||||
|
assert_true(line_in_AABB(p1, p2, box));
|
||||||
|
|
||||||
|
p1 = (Vector2){5, 0};
|
||||||
|
p2 = (Vector2){5, 10};
|
||||||
|
assert_true(line_in_AABB(p1, p2, box));
|
||||||
|
|
||||||
|
p1 = (Vector2){14, 0};
|
||||||
|
p2 = (Vector2){14, 10};
|
||||||
|
assert_true(line_in_AABB(p1, p2, box));
|
||||||
|
|
||||||
|
p1 = (Vector2){15, 0};
|
||||||
|
p2 = (Vector2){15, 10};
|
||||||
|
assert_false(line_in_AABB(p1, p2, box));
|
||||||
|
|
||||||
|
p1 = (Vector2){0, 30};
|
||||||
|
p2 = (Vector2){6, 35};
|
||||||
|
assert_false(line_in_AABB(p1, p2, box));
|
||||||
|
}
|
||||||
|
|
||||||
static void test_point_AABB(void **state)
|
static void test_point_AABB(void **state)
|
||||||
{
|
{
|
||||||
(void) state;
|
(void) state;
|
||||||
|
@ -86,6 +124,7 @@ int main(void)
|
||||||
cmocka_unit_test(test_1D_overlap),
|
cmocka_unit_test(test_1D_overlap),
|
||||||
cmocka_unit_test(test_AABB_overlap),
|
cmocka_unit_test(test_AABB_overlap),
|
||||||
cmocka_unit_test(test_point_AABB),
|
cmocka_unit_test(test_point_AABB),
|
||||||
|
cmocka_unit_test(test_line_AABB),
|
||||||
};
|
};
|
||||||
|
|
||||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
|
Loading…
Reference in New Issue