collider_get_aabb & collider_test_aabb

This commit is contained in:
jacob 2025-01-27 12:11:23 -06:00
parent b9bc22a019
commit c200a618b0
7 changed files with 97 additions and 40 deletions

View File

@ -35,11 +35,11 @@ INTERNAL void _dbgbreakable(void)
#define DBGSTEP #define DBGSTEP
#endif #endif
INTERNAL struct collider_support_point collider_get_support_point_internal(struct collider_shape *a, struct xform xf, struct v2 dir, i32 ignore) INTERNAL struct collider_support_point collider_get_support_point_internal(struct collider_shape *shape, struct xform xf, struct v2 dir, i32 ignore)
{ {
struct v2 *points = a->points; struct v2 *points = shape->points;
u32 count = a->count; u32 count = shape->count;
f32 radius = a->radius; f32 radius = shape->radius;
dir = v2_rotated(dir, -xform_get_rotation(xf)); dir = v2_rotated(dir, -xform_get_rotation(xf));
dir = v2_mul_v2(dir, xform_get_scale(xf)); dir = v2_mul_v2(dir, xform_get_scale(xf));
@ -78,9 +78,9 @@ INTERNAL struct collider_support_point collider_get_support_point_internal(struc
return res; return res;
} }
struct collider_support_point collider_get_support_point(struct collider_shape *a, struct xform xf, struct v2 dir) struct collider_support_point collider_get_support_point(struct collider_shape *shape, struct xform xf, struct v2 dir)
{ {
return collider_get_support_point_internal(a, xf, dir, -1); return collider_get_support_point_internal(shape, xf, dir, -1);
} }
INTERNAL struct collider_menkowski_point get_menkowski_point(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1, struct v2 dir) INTERNAL struct collider_menkowski_point get_menkowski_point(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1, struct v2 dir)
@ -92,6 +92,33 @@ INTERNAL struct collider_menkowski_point get_menkowski_point(struct collider_sha
return res; return res;
} }
/* ========================== *
* AABB
* ========================== */
struct aabb collider_get_aabb(struct collider_shape *shape, struct xform xf)
{
struct aabb res;
res.p0.x = collider_get_support_point(shape, xf, V2(-1, 0)).p.x - COLLISION_TOLERANCE;
res.p0.y = collider_get_support_point(shape, xf, V2(0, -1)).p.y - COLLISION_TOLERANCE;
res.p1.x = collider_get_support_point(shape, xf, V2(1, 0)).p.x + COLLISION_TOLERANCE;
res.p1.y = collider_get_support_point(shape, xf, V2(0, 1)).p.y + COLLISION_TOLERANCE;
return res;
}
b32 collider_test_aabb(struct aabb box0, struct aabb box1)
{
b32 res = (box0.p0.x >= box1.p0.x && box0.p0.x <= box1.p1.x && box0.p0.y >= box1.p0.y && box0.p0.y <= box1.p1.y) || /* Test box0 top left inside box1 */
(box0.p1.x >= box1.p0.x && box0.p1.x <= box1.p1.x && box0.p0.y >= box1.p0.y && box0.p0.y <= box1.p1.y) || /* Test box0 top right inside box1 */
(box0.p1.x >= box1.p0.x && box0.p1.x <= box1.p1.x && box0.p1.y >= box1.p0.y && box0.p1.y <= box1.p1.y) || /* Test box0 bottom right inside box1 */
(box0.p0.x >= box1.p0.x && box0.p0.x <= box1.p1.x && box0.p1.y >= box1.p0.y && box0.p1.y <= box1.p1.y) || /* Test box0 bottom left inside box1 */
(box1.p0.x >= box0.p0.x && box1.p0.x <= box0.p1.x && box1.p0.y >= box0.p0.y && box1.p0.y <= box0.p1.y) || /* Test box1 top left inside box0 */
(box1.p1.x >= box0.p0.x && box1.p1.x <= box0.p1.x && box1.p0.y >= box0.p0.y && box1.p0.y <= box0.p1.y) || /* Test box1 top right inside box0 */
(box1.p1.x >= box0.p0.x && box1.p1.x <= box0.p1.x && box1.p1.y >= box0.p0.y && box1.p1.y <= box0.p1.y) || /* Test box1 bottom right inside box0 */
(box1.p0.x >= box0.p0.x && box1.p0.x <= box0.p1.x && box1.p1.y >= box0.p0.y && box1.p1.y <= box0.p1.y); /* Test box1 bottom left inside box0 */
return res;
}
/* ========================== * /* ========================== *
* GJK * GJK
* *

View File

@ -58,7 +58,11 @@ struct collider_closest_points_result {
struct collider_prototype prototype; struct collider_prototype prototype;
}; };
struct collider_support_point collider_get_support_point(struct collider_shape *a, struct xform xf, struct v2 dir); struct collider_support_point collider_get_support_point(struct collider_shape *shape, struct xform xf, struct v2 dir);
struct aabb collider_get_aabb(struct collider_shape *shape, struct xform xf);
b32 collider_test_aabb(struct aabb box0, struct aabb box1);
struct collider_collision_points_result collider_collision_points(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1); struct collider_collision_points_result collider_collision_points(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1);

View File

@ -524,7 +524,7 @@ struct sprite_tag {
#define BUFFER_FROM_STRING(str) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { (str).len, (str).text }) #define BUFFER_FROM_STRING(str) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { (str).len, (str).text })
#define BUFFER_FROM_POINTERS(p1, p2) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { (u8 *)(p2) - (u8 *)(p1), (u8 *)p1 }) #define BUFFER_FROM_POINTERS(p0, p1) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { (u8 *)(p1) - (u8 *)(p0), (u8 *)p0 })
#define BUFFER_FROM_STRUCT(ptr) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { sizeof(*(ptr)), (u8 *)(ptr) }) #define BUFFER_FROM_STRUCT(ptr) (CPPFRIENDLY_INITLIST_TYPE(struct buffer) { sizeof(*(ptr)), (u8 *)(ptr) })
@ -606,17 +606,21 @@ struct rect {
INLINE b32 rect_eq(struct rect r1, struct rect r2) { return r1.x == r2.x && r1.y == r2.y && r1.width == r2.width && r1.height == r2.height; } INLINE b32 rect_eq(struct rect r1, struct rect r2) { return r1.x == r2.x && r1.y == r2.y && r1.width == r2.width && r1.height == r2.height; }
struct aabb {
struct v2 p0, p1;
};
/* Values expected to be normalized 0.0 -> 1.0 */ /* Values expected to be normalized 0.0 -> 1.0 */
#define CLIP_ALL ((struct clip_rect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } }) #define CLIP_ALL ((struct clip_rect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } })
struct clip_rect { struct clip_rect {
struct v2 p1, p2; struct v2 p0, p1;
}; };
#define QUAD_UNIT_SQUARE (struct quad) { V2(0, 0), V2(0, 1), V2(1, 1), V2(1, 0) } #define QUAD_UNIT_SQUARE (struct quad) { V2(0, 0), V2(0, 1), V2(1, 1), V2(1, 0) }
#define QUAD_UNIT_SQUARE_CENTERED (struct quad) { V2(-0.5f, -0.5f), V2(0.5f, -0.5f), V2(0.5f, 0.5f), V2(-0.5f, 0.5f) } #define QUAD_UNIT_SQUARE_CENTERED (struct quad) { V2(-0.5f, -0.5f), V2(0.5f, -0.5f), V2(0.5f, 0.5f), V2(-0.5f, 0.5f) }
struct quad { struct quad {
union { union {
struct { struct v2 p1, p2, p3, p4; }; struct { struct v2 p0, p1, p2, p3; };
struct { struct v2 e[4]; }; struct { struct v2 e[4]; };
}; };
}; };

View File

@ -42,26 +42,26 @@ void draw_quad_texture_ex(struct renderer_cmd_buffer *cmdbuff, struct renderer_t
/* Top left */ /* Top left */
vertices[0] = (struct triangle_shader_vertex) { vertices[0] = (struct triangle_shader_vertex) {
.pos = quad.p1, .pos = quad.p0,
.uv = { clip.p1.x, clip.p1.y }, .uv = { clip.p0.x, clip.p0.y },
.color = tint0 .color = tint0
}; };
/* Top right */ /* Top right */
vertices[1] = (struct triangle_shader_vertex) { vertices[1] = (struct triangle_shader_vertex) {
.pos = quad.p2, .pos = quad.p1,
.uv = { clip.p2.x, clip.p1.y }, .uv = { clip.p1.x, clip.p0.y },
.color = tint0 .color = tint0
}; };
/* Bottom right */ /* Bottom right */
vertices[2] = (struct triangle_shader_vertex) { vertices[2] = (struct triangle_shader_vertex) {
.pos = quad.p3, .pos = quad.p2,
.uv = { clip.p2.x, clip.p2.y }, .uv = { clip.p1.x, clip.p1.y },
.color = tint1 .color = tint1
}; };
/* Bottom left */ /* Bottom left */
vertices[3] = (struct triangle_shader_vertex) { vertices[3] = (struct triangle_shader_vertex) {
.pos = quad.p4, .pos = quad.p3,
.uv = { clip.p1.x, clip.p2.y }, .uv = { clip.p0.x, clip.p1.y },
.color = tint1 .color = tint1
}; };
@ -213,7 +213,7 @@ void draw_circle_line(struct renderer_cmd_buffer *cmdbuff, struct v2 pos, f32 ra
void draw_quad_line(struct renderer_cmd_buffer *cmdbuff, struct quad quad, f32 thickness, u32 color) void draw_quad_line(struct renderer_cmd_buffer *cmdbuff, struct quad quad, f32 thickness, u32 color)
{ {
struct v2 points[] = { quad.p1, quad.p2, quad.p3, quad.p4 }; struct v2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
struct v2_array a = { .points = points, .count = ARRAY_COUNT(points) }; struct v2_array a = { .points = points, .count = ARRAY_COUNT(points) };
draw_poly_line(cmdbuff, a, true, thickness, color); draw_poly_line(cmdbuff, a, true, thickness, color);
} }
@ -305,16 +305,16 @@ void draw_grid(struct renderer_cmd_buffer *cmdbuff, struct rect rect, u32 color,
/* Top left */ /* Top left */
vertices[0] = attributes; vertices[0] = attributes;
vertices[0].pos = quad.p1; vertices[0].pos = quad.p0;
/* Top right */ /* Top right */
vertices[1] = attributes; vertices[1] = attributes;
vertices[1].pos = quad.p2; vertices[1].pos = quad.p1;
/* Bottom right */ /* Bottom right */
vertices[2] = attributes; vertices[2] = attributes;
vertices[2].pos = quad.p3; vertices[2].pos = quad.p2;
/* Bottom left */ /* Bottom left */
vertices[3] = attributes; vertices[3] = attributes;
vertices[3].pos = quad.p4; vertices[3].pos = quad.p3;
/* Top / right triangle */ /* Top / right triangle */
indices[0] = index_offset + 0; indices[0] = index_offset + 0;

View File

@ -1084,6 +1084,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
} }
} }
/* Step */
phys_step(&ctx, dt); phys_step(&ctx, dt);
} }

View File

@ -1069,10 +1069,10 @@ INLINE struct v2 xform_invert_mul_v2(struct xform xf, struct v2 v)
INLINE struct quad xform_mul_quad(struct xform xf, struct quad quad) INLINE struct quad xform_mul_quad(struct xform xf, struct quad quad)
{ {
return (struct quad) { return (struct quad) {
xform_mul_v2(xf, quad.p0),
xform_mul_v2(xf, quad.p1), xform_mul_v2(xf, quad.p1),
xform_mul_v2(xf, quad.p2), xform_mul_v2(xf, quad.p2),
xform_mul_v2(xf, quad.p3), xform_mul_v2(xf, quad.p3)
xform_mul_v2(xf, quad.p4)
}; };
} }
@ -1122,7 +1122,17 @@ INLINE struct quad quad_from_rect(struct rect rect)
(struct v2) { rect.x, rect.y }, /* Top left */ (struct v2) { rect.x, rect.y }, /* Top left */
(struct v2) { rect.x + rect.width, rect.y }, /* Top right */ (struct v2) { rect.x + rect.width, rect.y }, /* Top right */
(struct v2) { rect.x + rect.width, rect.y + rect.height }, /* Bottom right */ (struct v2) { rect.x + rect.width, rect.y + rect.height }, /* Bottom right */
(struct v2) { rect.x, rect.y + rect.height }, /* Bottom left */ (struct v2) { rect.x, rect.y + rect.height } /* Bottom left */
};
}
INLINE struct quad quad_from_aabb(struct aabb aabb)
{
return (struct quad) {
(struct v2) { aabb.p0.x, aabb.p0.y }, /* Top left */
(struct v2) { aabb.p1.x, aabb.p0.y }, /* Top right */
(struct v2) { aabb.p1.x, aabb.p1.y }, /* Bottom right */
(struct v2) { aabb.p0.x, aabb.p1.y } /* Bottom left */
}; };
} }
@ -1136,10 +1146,10 @@ INLINE struct quad quad_from_line(struct v2 start, struct v2 end, f32 thickness)
struct v2 left = v2_mul(dir_perp, -width); struct v2 left = v2_mul(dir_perp, -width);
struct v2 right = v2_mul(dir_perp, width); struct v2 right = v2_mul(dir_perp, width);
return (struct quad) { return (struct quad) {
.p1 = v2_add(start, left), .p0 = v2_add(start, left),
.p2 = v2_add(start, right), .p1 = v2_add(start, right),
.p3 = v2_add(end, right), .p2 = v2_add(end, right),
.p4 = v2_add(end, left) .p3 = v2_add(end, left)
}; };
} }
@ -1151,30 +1161,30 @@ INLINE struct quad quad_from_ray(struct v2 pos, struct v2 rel, f32 thickness)
INLINE struct quad quad_scale(struct quad q, f32 s) INLINE struct quad quad_scale(struct quad q, f32 s)
{ {
q.p0 = v2_mul(q.p0, s);
q.p1 = v2_mul(q.p1, s); q.p1 = v2_mul(q.p1, s);
q.p2 = v2_mul(q.p2, s); q.p2 = v2_mul(q.p2, s);
q.p3 = v2_mul(q.p3, s); q.p3 = v2_mul(q.p3, s);
q.p4 = v2_mul(q.p4, s);
return q; return q;
} }
INLINE struct quad quad_round(struct quad quad) INLINE struct quad quad_round(struct quad quad)
{ {
return (struct quad) { return (struct quad) {
v2_round(quad.p0),
v2_round(quad.p1), v2_round(quad.p1),
v2_round(quad.p2), v2_round(quad.p2),
v2_round(quad.p3), v2_round(quad.p3)
v2_round(quad.p4)
}; };
} }
INLINE struct quad quad_floor(struct quad quad) INLINE struct quad quad_floor(struct quad quad)
{ {
return (struct quad) { return (struct quad) {
v2_floor(quad.p1), v2_floor(quad.p0),
v2_round(quad.p1),
v2_round(quad.p2), v2_round(quad.p2),
v2_round(quad.p3), v2_round(quad.p3)
v2_round(quad.p4)
}; };
} }
@ -1185,10 +1195,10 @@ INLINE struct quad quad_floor(struct quad quad)
INLINE struct collider_shape collider_from_quad(struct quad quad) INLINE struct collider_shape collider_from_quad(struct quad quad)
{ {
struct collider_shape res; struct collider_shape res;
res.points[0] = quad.p1; res.points[0] = quad.p0;
res.points[1] = quad.p2; res.points[1] = quad.p1;
res.points[2] = quad.p3; res.points[2] = quad.p2;
res.points[3] = quad.p4; res.points[3] = quad.p3;
res.count = 4; res.count = 4;
res.radius = 0; res.radius = 0;
return res; return res;

View File

@ -999,12 +999,23 @@ INTERNAL void user_update(void)
debug_draw_movement(ent); debug_draw_movement(ent);
} }
/* Draw xform */
if (!skip_debug_draw_transform) { if (!skip_debug_draw_transform) {
u32 color_x = RGBA_32_F(1, 0, 0, 0.3); u32 color_x = RGBA_32_F(1, 0, 0, 0.3);
u32 color_y = RGBA_32_F(0, 1, 0, 0.3); u32 color_y = RGBA_32_F(0, 1, 0, 0.3);
debug_draw_xform(xf, color_x, color_y); debug_draw_xform(xf, color_x, color_y);
} }
/* Draw AABB */
if (ent->local_collider.count > 0) {
struct aabb aabb = collider_get_aabb(&ent->local_collider, xf);
f32 thickness = 1;
u32 color = RGBA_32_F(1, 0, 1, 0.5);
struct quad quad = quad_from_aabb(aabb);
quad = xform_mul_quad(G.world_to_ui_xf, quad);
draw_quad_line(G.ui_cmd_buffer, quad, thickness, color);
}
/* Draw focus arrow */ /* Draw focus arrow */
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite); struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite);