diff options
| author | iamcheeseman <[hidden email]> | 2026-01-16 13:43:18 -0500 |
|---|---|---|
| committer | iamcheeseman <[hidden email]> | 2026-01-16 13:43:18 -0500 |
| commit | f5a8333aaf0104d3aba4f096c9180cd8287ac1ff (patch) | |
| tree | 5dd0643d7c4d0896aed32d5c3cf881af319a1ad0 /src/phys | |
| parent | 9180c51c40084aa30448bc4ffc06385489e7bf45 (diff) | |
Do collision checks in steps of the body's size
Diffstat (limited to 'src/phys')
| -rw-r--r-- | src/phys/world.odin | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/src/phys/world.odin b/src/phys/world.odin index 15e7826..6ab12d5 100644 --- a/src/phys/world.odin +++ b/src/phys/world.odin @@ -2,6 +2,7 @@ package phys import "core:log" import "core:math" +import "core:math/linalg" import rl "vendor:raylib" @@ -203,57 +204,68 @@ update_body :: proc(h: Body_Handle) { rect := b.rect rect.start += b.pos - res_rect := b.rect - res_rect.start += res_pos - - bin_list := _get_surrounding_bins(res_rect.start) + small_side := min(rect.size.x, rect.size.y) + steps := i32(math.ceil(linalg.length(b.vel * dt) / small_side)) b.collisions = {} - for bin in bin_list { - for c_h in bin { - if c_h == h { - continue - } + for i in 0..<steps { + p := f32(i + 1) / f32(steps) - c := _get_body(c_h) + res_rect := b.rect + res_rect.start += b.pos + b.vel * dt * p - if b.mask & c.layers == {} { - continue - } + bin_list := _get_surrounding_bins(res_rect.start) - c_rect := c.rect - c_rect.start += c.pos + for bin in bin_list { + for c_h in bin { + if c_h == h { + continue + } - if aabb(res_rect, c_rect) { - if aabb_hori(rect, c_rect) { - if b.vel.y > 0 { - res_pos.y = c_rect.start.y - b.rect.size.y - b.rect.start.y - b.collisions += {.DOWN} - } else { - res_pos.y = c_rect.start.y + c_rect.size.y - b.rect.start.y - b.collisions += {.UP} - } - b.collisions += {.VERTICAL} - } else if aabb_vert(rect, c.rect) { - if b.vel.x > 0 { - res_pos.x = c_rect.start.x - b.rect.size.x - b.rect.start.x - b.collisions += {.LEFT} - } else { - res_pos.x = c_rect.start.x + c_rect.size.x - b.rect.start.x - b.collisions += {.RIGHT} + c := _get_body(c_h) + + if b.mask & c.layers == {} { + continue + } + + c_rect := c.rect + c_rect.start += c.pos + + if aabb(res_rect, c_rect) { + if aabb_hori(rect, c_rect) { + if b.vel.y > 0 { + res_pos.y = c_rect.start.y - b.rect.size.y - b.rect.start.y + b.collisions += {.DOWN} + } else { + res_pos.y = c_rect.start.y + c_rect.size.y - b.rect.start.y + b.collisions += {.UP} + } + b.collisions += {.VERTICAL} + } else if aabb_vert(rect, c.rect) { + if b.vel.x > 0 { + res_pos.x = c_rect.start.x - b.rect.size.x - b.rect.start.x + b.collisions += {.LEFT} + } else { + res_pos.x = c_rect.start.x + c_rect.size.x - b.rect.start.x + b.collisions += {.RIGHT} + } + b.collisions += {.HORIZONTAL} } - b.collisions += {.HORIZONTAL} } } } - } - if .HORIZONTAL in b.collisions { - b.vel.x = 0 - } - if .VERTICAL in b.collisions { - b.vel.y = 0 + if .HORIZONTAL in b.collisions { + b.vel.x = 0 + } + if .VERTICAL in b.collisions { + b.vel.y = 0 + } + + if b.collisions != nil { + break + } } set_position(h, res_pos) |
