X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fgame%2Flevel%2Frigid_bodies.c;h=667916e87fc7b5cf9e31688f1454b001e0fe6555;hb=41e24206d6b0211307641bef85a252890bfc7339;hp=0c2a0b93c3638a15123a5321218e249fe5f5b199;hpb=8b12625b6981a2cd303980e04a05b85dff26321c;p=nothing.git diff --git a/src/game/level/rigid_bodies.c b/src/game/level/rigid_bodies.c index 0c2a0b93..667916e8 100644 --- a/src/game/level/rigid_bodies.c +++ b/src/game/level/rigid_bodies.c @@ -1,10 +1,15 @@ #include #include +#include "game/camera.h" +#include "game/level/platforms.h" #include "system/lt.h" #include "system/nth_alloc.h" #include "system/stacktrace.h" -#include "game/camera.h" +#include "system/line_stream.h" +#include "system/str.h" +#include "system/log.h" +#include "hashset.h" #include "./rigid_bodies.h" @@ -14,21 +19,18 @@ struct RigidBodies size_t capacity; size_t count; - Vec *positions; - Vec *velocities; - Vec *movements; - Vec *sizes; - Color *colors; + Rect *bodies; + Vec2f *velocities; + Vec2f *movements; bool *grounded; - Vec *forces; + Vec2f *forces; + bool *deleted; + bool *disabled; }; RigidBodies *create_rigid_bodies(size_t capacity) { Lt *lt = create_lt(); - if (lt == NULL) { - return NULL; - } RigidBodies *rigid_bodies = PUSH_LT(lt, nth_calloc(1, sizeof(RigidBodies)), free); if (rigid_bodies == NULL) { @@ -39,38 +41,41 @@ RigidBodies *create_rigid_bodies(size_t capacity) rigid_bodies->capacity = capacity; rigid_bodies->count = 0; - rigid_bodies->positions = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free); - if (rigid_bodies->positions == NULL) { + rigid_bodies->bodies = PUSH_LT(lt, nth_calloc(capacity, sizeof(Rect)), free); + if (rigid_bodies->bodies == NULL) { RETURN_LT(lt, NULL); } - rigid_bodies->velocities = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free); + rigid_bodies->velocities = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec2f)), free); if (rigid_bodies->velocities == NULL) { RETURN_LT(lt, NULL); } - rigid_bodies->movements = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free); + rigid_bodies->movements = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec2f)), free); if (rigid_bodies->movements == NULL) { RETURN_LT(lt, NULL); } - rigid_bodies->sizes = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free); - if (rigid_bodies->sizes == NULL) { + rigid_bodies->grounded = PUSH_LT(lt, nth_calloc(capacity, sizeof(bool)), free); + if (rigid_bodies->grounded == NULL) { RETURN_LT(lt, NULL); } - rigid_bodies->colors = PUSH_LT(lt, nth_calloc(capacity, sizeof(Color)), free); - if (rigid_bodies->colors == NULL) { + rigid_bodies->forces = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec2f)), free); + if (rigid_bodies->forces == NULL) { RETURN_LT(lt, NULL); } - rigid_bodies->grounded = PUSH_LT(lt, nth_calloc(capacity, sizeof(bool)), free); - if (rigid_bodies->grounded == NULL) { + rigid_bodies->deleted = PUSH_LT(lt, nth_calloc(capacity, sizeof(bool)), free); + if (rigid_bodies->deleted == NULL) { RETURN_LT(lt, NULL); } - rigid_bodies->forces = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free); - if (rigid_bodies->forces == NULL) { + rigid_bodies->disabled = PUSH_LT( + lt, + nth_calloc(capacity, sizeof(bool)), + free); + if (rigid_bodies->disabled == NULL) { RETURN_LT(lt, NULL); } @@ -83,67 +88,228 @@ void destroy_rigid_bodies(RigidBodies *rigid_bodies) RETURN_LT0(rigid_bodies->lt); } +int rigid_bodies_collide(RigidBodies *rigid_bodies, + const Platforms *platforms) +{ + memset(rigid_bodies->grounded, 0, sizeof(bool) * rigid_bodies->count); + + if (rigid_bodies->count == 0) { + return 0; + } + + int sides[RECT_SIDE_N] = { 0, 0, 0, 0 }; + + + int t = 100; + int the_variable_that_gets_set_when_a_collision_happens_xd = 1; + while (t-- > 0 && the_variable_that_gets_set_when_a_collision_happens_xd) { + the_variable_that_gets_set_when_a_collision_happens_xd = 0; + + for (size_t i1 = 0; i1 < rigid_bodies->count; ++i1) { + if (rigid_bodies->deleted[i1] || rigid_bodies->disabled[i1]) { + continue; + } + + // Platforms + memset(sides, 0, sizeof(int) * RECT_SIDE_N); + + platforms_touches_rect_sides(platforms, rigid_bodies->bodies[i1], sides); + + for (int i = 0; i < RECT_SIDE_N; ++i) { + if (sides[i]) { + the_variable_that_gets_set_when_a_collision_happens_xd = 1; + } + } + + if (sides[RECT_SIDE_BOTTOM]) { + rigid_bodies->grounded[i1] = true; + } + + Vec2f v = platforms_snap_rect(platforms, &rigid_bodies->bodies[i1]); + rigid_bodies->velocities[i1] = vec_entry_mult(rigid_bodies->velocities[i1], v); + rigid_bodies->movements[i1] = vec_entry_mult(rigid_bodies->movements[i1], v); + rigid_bodies_damper(rigid_bodies, i1, vec_entry_mult(v, vec(-16.0f, 0.0f))); + + if (i1 >= rigid_bodies->count - 1) { + continue; + } + + // Self-collision + for (size_t i2 = i1 + 1; i2 < rigid_bodies->count; ++i2) { + if (rigid_bodies->deleted[i2] || rigid_bodies->disabled[i1]) { + continue; + } + + if (!rects_overlap(rigid_bodies->bodies[i1], rigid_bodies->bodies[i2])) { + continue; + } + + the_variable_that_gets_set_when_a_collision_happens_xd = 1; + + Vec2f orient = rect_impulse(&rigid_bodies->bodies[i1], &rigid_bodies->bodies[i2]); + + if (orient.x > orient.y) { + if (rigid_bodies->bodies[i1].y < rigid_bodies->bodies[i2].y) { + rigid_bodies->grounded[i1] = true; + } else { + rigid_bodies->grounded[i2] = true; + } + } + + rigid_bodies->velocities[i1] = vec(rigid_bodies->velocities[i1].x * orient.x, rigid_bodies->velocities[i1].y * orient.y); + rigid_bodies->velocities[i2] = vec(rigid_bodies->velocities[i2].x * orient.x, rigid_bodies->velocities[i2].y * orient.y); + rigid_bodies->movements[i1] = vec(rigid_bodies->movements[i1].x * orient.x, rigid_bodies->movements[i1].y * orient.y); + rigid_bodies->movements[i2] = vec(rigid_bodies->movements[i2].x * orient.x, rigid_bodies->movements[i2].y * orient.y); + } + } + } + + return 0; +} + int rigid_bodies_update(RigidBodies *rigid_bodies, + RigidBodyId id, float delta_time) { trace_assert(rigid_bodies); - (void) delta_time; - /* TODO(#639): rigid_bodies_update is not implemented */ + + if (rigid_bodies->deleted[id] || rigid_bodies->disabled[id]) { + return 0; + } + + rigid_bodies->velocities[id] = vec_sum( + rigid_bodies->velocities[id], + vec_scala_mult( + rigid_bodies->forces[id], + delta_time)); + + Vec2f position = vec(rigid_bodies->bodies[id].x, + rigid_bodies->bodies[id].y); + + position = vec_sum( + position, + vec_scala_mult( + vec_sum( + rigid_bodies->velocities[id], + rigid_bodies->movements[id]), + delta_time)); + + rigid_bodies->bodies[id].x = position.x; + rigid_bodies->bodies[id].y = position.y; + + rigid_bodies->forces[id] = vec(0.0f, 0.0f); + return 0; } int rigid_bodies_render(RigidBodies *rigid_bodies, - Camera *camera) + RigidBodyId id, + Color color, + const Camera *camera) { trace_assert(rigid_bodies); trace_assert(camera); - for (size_t i = 0; i < rigid_bodies->count; ++i) { - if (camera_fill_rect( - camera, - rect_from_vecs( - rigid_bodies->positions[i], - rigid_bodies->sizes[i]), - rigid_bodies->colors[i]) < 0) { - return -1; - } + if (rigid_bodies->deleted[id] || rigid_bodies->disabled[id]) { + return 0; + } + + char text_buffer[256]; + + if (camera_fill_rect( + camera, + rigid_bodies->bodies[id], + color) < 0) { + return -1; + } + + snprintf(text_buffer, 256, "id: %zd", id); + + if (camera_render_debug_text( + camera, + text_buffer, + vec(rigid_bodies->bodies[id].x, + rigid_bodies->bodies[id].y)) < 0) { + return -1; + } + + snprintf(text_buffer, 256, "p:(%.2f, %.2f)", + rigid_bodies->bodies[id].x, + rigid_bodies->bodies[id].y); + if (camera_render_debug_text( + camera, + text_buffer, + vec(rigid_bodies->bodies[id].x, + rigid_bodies->bodies[id].y + FONT_CHAR_HEIGHT * 2.0f))) { + return -1; + } + + snprintf(text_buffer, 256, "v:(%.2f, %.2f)", + rigid_bodies->velocities[id].x, + rigid_bodies->velocities[id].y); + if (camera_render_debug_text( + camera, + text_buffer, + vec(rigid_bodies->bodies[id].x, + rigid_bodies->bodies[id].y + FONT_CHAR_HEIGHT * 4.0f))) { + return -1; + } + + snprintf(text_buffer, 256, "m:(%.2f, %.2f)", + rigid_bodies->movements[id].x, + rigid_bodies->movements[id].y); + if (camera_render_debug_text( + camera, + text_buffer, + vec(rigid_bodies->bodies[id].x, + rigid_bodies->bodies[id].y + FONT_CHAR_HEIGHT * 6.0f))) { + return -1; } return 0; } RigidBodyId rigid_bodies_add(RigidBodies *rigid_bodies, - Rect rect, - Color color) + Rect rect) { trace_assert(rigid_bodies); trace_assert(rigid_bodies->count < rigid_bodies->capacity); RigidBodyId id = rigid_bodies->count++; - rigid_bodies->positions[id] = vec(rect.x, rect.y); - rigid_bodies->sizes[id] = vec(rect.w, rect.h); - rigid_bodies->colors[id] = color; + rigid_bodies->bodies[id] = rect; return id; } +void rigid_bodies_remove(RigidBodies *rigid_bodies, + RigidBodyId id) +{ + trace_assert(rigid_bodies); + trace_assert(id < rigid_bodies->capacity); + + rigid_bodies->deleted[id] = true; +} + Rect rigid_bodies_hitbox(const RigidBodies *rigid_bodies, RigidBodyId id) { trace_assert(rigid_bodies); trace_assert(id < rigid_bodies->count); - return rect_from_vecs(rigid_bodies->positions[id], - rigid_bodies->sizes[id]); + return rigid_bodies->bodies[id]; } void rigid_bodies_move(RigidBodies *rigid_bodies, RigidBodyId id, - Vec movement) + Vec2f movement) { trace_assert(rigid_bodies); trace_assert(id < rigid_bodies->count); + if (rigid_bodies->deleted[id] || rigid_bodies->disabled[id]) { + return; + } + rigid_bodies->movements[id] = movement; } @@ -156,13 +322,25 @@ int rigid_bodies_touches_ground(const RigidBodies *rigid_bodies, return rigid_bodies->grounded[id]; } +void rigid_bodies_apply_omniforce(RigidBodies *rigid_bodies, + Vec2f force) +{ + for (size_t i = 0; i < rigid_bodies->count; ++i) { + rigid_bodies_apply_force(rigid_bodies, i, force); + } +} + void rigid_bodies_apply_force(RigidBodies * rigid_bodies, RigidBodyId id, - Vec force) + Vec2f force) { trace_assert(rigid_bodies); trace_assert(id < rigid_bodies->count); + if (rigid_bodies->deleted[id] || rigid_bodies->disabled[id]) { + return; + } + rigid_bodies->forces[id] = vec_sum(rigid_bodies->forces[id], force); } @@ -173,6 +351,10 @@ void rigid_bodies_transform_velocity(RigidBodies *rigid_bodies, trace_assert(rigid_bodies); trace_assert(id < rigid_bodies->count); + if (rigid_bodies->deleted[id] || rigid_bodies->disabled[id]) { + return; + } + rigid_bodies->velocities[id] = point_mat3x3_product( rigid_bodies->velocities[id], trans_mat); @@ -180,24 +362,43 @@ void rigid_bodies_transform_velocity(RigidBodies *rigid_bodies, void rigid_bodies_teleport_to(RigidBodies *rigid_bodies, RigidBodyId id, - Vec position) + Vec2f position) { trace_assert(rigid_bodies); trace_assert(id < rigid_bodies->count); - rigid_bodies->positions[id] = position; + if (rigid_bodies->deleted[id] || rigid_bodies->disabled[id]) { + return; + } + + rigid_bodies->bodies[id].x = position.x; + rigid_bodies->bodies[id].y = position.y; } void rigid_bodies_damper(RigidBodies *rigid_bodies, RigidBodyId id, - Vec v) + Vec2f v) { trace_assert(rigid_bodies); trace_assert(id < rigid_bodies->count); + if (rigid_bodies->deleted[id] || rigid_bodies->disabled[id]) { + return; + } + rigid_bodies_apply_force( rigid_bodies, id, vec( rigid_bodies->velocities[id].x * v.x, rigid_bodies->velocities[id].y * v.y)); } + +void rigid_bodies_disable(RigidBodies *rigid_bodies, + RigidBodyId id, + bool disabled) +{ + trace_assert(rigid_bodies); + trace_assert(id < rigid_bodies->count); + + rigid_bodies->disabled[id] = disabled; +}