diff options
Diffstat (limited to 'src/phys')
| -rw-r--r-- | src/phys/world.odin | 102 |
1 files changed, 25 insertions, 77 deletions
diff --git a/src/phys/world.odin b/src/phys/world.odin index 25db947..c03445a 100644 --- a/src/phys/world.odin +++ b/src/phys/world.odin @@ -4,19 +4,17 @@ import "core:log" import "core:math" import "core:math/linalg" +import hm "core:container/handle_map" + import "../fw" BIN_COUNT :: 2056 BIN_SIZE :: 64 -Body_Handle :: struct { - idx: u32, - uses: u32, -} +Body_Handle :: hm.Handle64 world: struct { - bodies: [dynamic]Body, - holes: [dynamic]Body_Handle, + bodies: hm.Dynamic_Handle_Map(Body, Body_Handle), bins: [BIN_COUNT][dynamic]Body_Handle, } @@ -24,8 +22,8 @@ destroy_world :: proc() { for bin in world.bins { delete(bin) } - delete(world.holes) - delete(world.bodies) + + hm.dynamic_destroy(&world.bodies) } @(private = "file") @@ -85,77 +83,27 @@ _remove_from_bins :: proc(b: Body) { unordered_remove(bin, b.bin_idx) if int(b.bin_idx) != len(bin) { - swapped_body := _get_body(bin[b.bin_idx]) + swapped_body := hm.get(&world.bodies, bin[b.bin_idx]) swapped_body.bin_idx = b.bin_idx } } -@(private = "file") -_get_body :: proc(h: Body_Handle, location := #caller_location) -> ^Body { - if h.idx >= u32(len(world.bodies)) { - log.warn("Handle is out of range", location = location) - return nil - } - if world.bodies[h.idx].handle != h { - log.warnf( - "Handle isn't yours (querying %v, got %v)", - h, - world.bodies[h.idx].handle, - location = location, - ) - } - return &world.bodies[h.idx] -} - -@(require_results) -iterate_bodies :: proc(it: ^int) -> (Body_Handle, bool) { - for it^ < len(world.bodies) { - if world.bodies[it^].handle.uses > 0 { - it^ += 1 - return world.bodies[it^ - 1].handle, true - } - it^ += 1 - } - return {}, false -} - add_body :: proc(b: Body) -> Body_Handle { - handle: Body_Handle - if b.rect.size.x > BIN_SIZE || b.rect.size.y > BIN_SIZE { log.warnf("Body size is too big (%vx%v)", b.rect.size.x, b.rect.size.y) } - if len(world.holes) > 0 { - handle = pop(&world.holes) - handle.uses += 1 - } else { - resize(&world.bodies, len(world.bodies) + 1) - handle.idx = u32(len(world.bodies) - 1) - handle.uses = 1 - } - - world.bodies[handle.idx] = b - world.bodies[handle.idx].handle = handle - - _add_to_bins(_get_body(handle)) + handle := hm.add(&world.bodies, b) + body := hm.get(&world.bodies, handle) + _add_to_bins(body) return handle } remove_body :: proc(h: Body_Handle) { - if h.idx >= u32(len(world.bodies)) || - world.bodies[h.idx].handle != h { - log.warn("Handle isn't yours, or is out of range") - return - } - - b := _get_body(h) - + b := hm.get(&world.bodies, h) _remove_from_bins(b^) - - append(&world.holes, b.handle) - world.bodies[h.idx] = {} + hm.remove(&world.bodies, h) } @(require_results) @@ -169,7 +117,7 @@ get_closest_raycast_collision :: proc( for bin in bin_list { for b_h in bin { - b := _get_body(b_h) + b := hm.get(&world.bodies, b_h) if b.layers & rc.mask == nil { continue @@ -189,7 +137,7 @@ get_closest_raycast_collision :: proc( } } - return nearest_collision, nearest_collision.body.uses > 0 + return nearest_collision, nearest_collision.body.gen > 0 } is_colliding :: proc{ @@ -225,7 +173,7 @@ get_colliding_bodies_raycast_vs_body :: proc( for bin in bin_list { for b_h in bin { - b := _get_body(b_h) + b := hm.get(&world.bodies, b_h) if b.layers & rc.mask == nil { continue @@ -251,7 +199,7 @@ get_colliding_bodies_body_vs_body :: proc( ) -> []Body_Handle { bodies := make([dynamic]Body_Handle, allocator) - b := _get_body(h) + b := hm.get(&world.bodies, h) rect := b.rect rect.start += b.pos @@ -264,7 +212,7 @@ get_colliding_bodies_body_vs_body :: proc( continue } - c := _get_body(c_h) + c := hm.get(&world.bodies, c_h) if b.mask & c.layers == nil { continue @@ -285,7 +233,7 @@ get_colliding_bodies_body_vs_body :: proc( update_body :: proc(h: Body_Handle) { dt := f32(fw.get_delta_time()) - b := _get_body(h) + b := hm.get(&world.bodies, h) res_pos := b.pos + b.vel * dt @@ -311,7 +259,7 @@ update_body :: proc(h: Body_Handle) { continue } - c := _get_body(c_h) + c := hm.get(&world.bodies, c_h) if b.mask & c.layers == nil { continue @@ -361,20 +309,20 @@ update_body :: proc(h: Body_Handle) { @(require_results) get_velocity :: proc(h: Body_Handle) -> Vec2 { - return _get_body(h).vel + return hm.get(&world.bodies, h).vel } set_velocity :: proc(h: Body_Handle, vel: Vec2) { - _get_body(h).vel = vel + hm.get(&world.bodies, h).vel = vel } @(require_results) get_position :: proc(h: Body_Handle) -> Vec2 { - return _get_body(h).pos + return hm.get(&world.bodies, h).pos } set_position :: proc(h: Body_Handle, new_pos: Vec2) { - b := _get_body(h) + b := hm.get(&world.bodies, h) prev_bin := _hash_bin(_world_to_bin(b.pos + b.rect.start)) res_bin := _hash_bin(_world_to_bin(new_pos + b.rect.start)) @@ -390,10 +338,10 @@ set_position :: proc(h: Body_Handle, new_pos: Vec2) { @(require_results) get_collisions :: proc(h: Body_Handle) -> bit_set[Collision_Type;u8] { - return _get_body(h).collisions + return hm.get(&world.bodies, h).collisions } @(require_results) get_rect :: proc(h: Body_Handle) -> Rect { - return _get_body(h).rect + return hm.get(&world.bodies, h).rect } |
