diff --git a/src/collider.c b/src/collider.c index a76204b8..021058d3 100644 --- a/src/collider.c +++ b/src/collider.c @@ -35,11 +35,11 @@ INTERNAL void _dbgbreakable(void) #define DBGSTEP #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; - u32 count = a->count; - f32 radius = a->radius; + struct v2 *points = shape->points; + u32 count = shape->count; + f32 radius = shape->radius; dir = v2_rotated(dir, -xform_get_rotation(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; } -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) @@ -92,6 +92,33 @@ INTERNAL struct collider_menkowski_point get_menkowski_point(struct collider_sha 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 * diff --git a/src/collider.h b/src/collider.h index 5290a6e4..8b7523da 100644 --- a/src/collider.h +++ b/src/collider.h @@ -58,7 +58,11 @@ struct collider_closest_points_result { 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); diff --git a/src/common.h b/src/common.h index 43dc4891..21c52d74 100644 --- a/src/common.h +++ b/src/common.h @@ -524,7 +524,7 @@ struct sprite_tag { #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) }) @@ -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; } +struct aabb { + struct v2 p0, p1; +}; + /* Values expected to be normalized 0.0 -> 1.0 */ #define CLIP_ALL ((struct clip_rect) { { 0.0f, 0.0f }, { 1.0f, 1.0f } }) 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_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 { union { - struct { struct v2 p1, p2, p3, p4; }; + struct { struct v2 p0, p1, p2, p3; }; struct { struct v2 e[4]; }; }; }; diff --git a/src/draw.c b/src/draw.c index 4781e3c1..676f9d8b 100644 --- a/src/draw.c +++ b/src/draw.c @@ -42,26 +42,26 @@ void draw_quad_texture_ex(struct renderer_cmd_buffer *cmdbuff, struct renderer_t /* Top left */ vertices[0] = (struct triangle_shader_vertex) { - .pos = quad.p1, - .uv = { clip.p1.x, clip.p1.y }, + .pos = quad.p0, + .uv = { clip.p0.x, clip.p0.y }, .color = tint0 }; /* Top right */ vertices[1] = (struct triangle_shader_vertex) { - .pos = quad.p2, - .uv = { clip.p2.x, clip.p1.y }, + .pos = quad.p1, + .uv = { clip.p1.x, clip.p0.y }, .color = tint0 }; /* Bottom right */ vertices[2] = (struct triangle_shader_vertex) { - .pos = quad.p3, - .uv = { clip.p2.x, clip.p2.y }, + .pos = quad.p2, + .uv = { clip.p1.x, clip.p1.y }, .color = tint1 }; /* Bottom left */ vertices[3] = (struct triangle_shader_vertex) { - .pos = quad.p4, - .uv = { clip.p1.x, clip.p2.y }, + .pos = quad.p3, + .uv = { clip.p0.x, clip.p1.y }, .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) { - 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) }; 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 */ vertices[0] = attributes; - vertices[0].pos = quad.p1; + vertices[0].pos = quad.p0; /* Top right */ vertices[1] = attributes; - vertices[1].pos = quad.p2; + vertices[1].pos = quad.p1; /* Bottom right */ vertices[2] = attributes; - vertices[2].pos = quad.p3; + vertices[2].pos = quad.p2; /* Bottom left */ vertices[3] = attributes; - vertices[3].pos = quad.p4; + vertices[3].pos = quad.p3; /* Top / right triangle */ indices[0] = index_offset + 0; diff --git a/src/game.c b/src/game.c index 089d575f..7217ef7f 100644 --- a/src/game.c +++ b/src/game.c @@ -1084,6 +1084,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) } } + /* Step */ phys_step(&ctx, dt); } diff --git a/src/math.h b/src/math.h index 72d96da4..f481b3ee 100644 --- a/src/math.h +++ b/src/math.h @@ -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) { return (struct quad) { + xform_mul_v2(xf, quad.p0), xform_mul_v2(xf, quad.p1), xform_mul_v2(xf, quad.p2), - xform_mul_v2(xf, quad.p3), - xform_mul_v2(xf, quad.p4) + xform_mul_v2(xf, quad.p3) }; } @@ -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.width, rect.y }, /* Top 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 right = v2_mul(dir_perp, width); return (struct quad) { - .p1 = v2_add(start, left), - .p2 = v2_add(start, right), - .p3 = v2_add(end, right), - .p4 = v2_add(end, left) + .p0 = v2_add(start, left), + .p1 = v2_add(start, right), + .p2 = v2_add(end, right), + .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) { + q.p0 = v2_mul(q.p0, s); q.p1 = v2_mul(q.p1, s); q.p2 = v2_mul(q.p2, s); q.p3 = v2_mul(q.p3, s); - q.p4 = v2_mul(q.p4, s); return q; } INLINE struct quad quad_round(struct quad quad) { return (struct quad) { + v2_round(quad.p0), v2_round(quad.p1), v2_round(quad.p2), - v2_round(quad.p3), - v2_round(quad.p4) + v2_round(quad.p3) }; } INLINE struct quad quad_floor(struct quad quad) { return (struct quad) { - v2_floor(quad.p1), + v2_floor(quad.p0), + v2_round(quad.p1), v2_round(quad.p2), - v2_round(quad.p3), - v2_round(quad.p4) + v2_round(quad.p3) }; } @@ -1185,10 +1195,10 @@ INLINE struct quad quad_floor(struct quad quad) INLINE struct collider_shape collider_from_quad(struct quad quad) { struct collider_shape res; - res.points[0] = quad.p1; - res.points[1] = quad.p2; - res.points[2] = quad.p3; - res.points[3] = quad.p4; + res.points[0] = quad.p0; + res.points[1] = quad.p1; + res.points[2] = quad.p2; + res.points[3] = quad.p3; res.count = 4; res.radius = 0; return res; diff --git a/src/user.c b/src/user.c index 03387027..fb39b162 100644 --- a/src/user.c +++ b/src/user.c @@ -999,12 +999,23 @@ INTERNAL void user_update(void) debug_draw_movement(ent); } + /* Draw xform */ if (!skip_debug_draw_transform) { u32 color_x = RGBA_32_F(1, 0, 0, 0.3); u32 color_y = RGBA_32_F(0, 1, 0, 0.3); 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 */ if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite);