aboutsummaryrefslogtreecommitdiff
path: root/src/phys
diff options
context:
space:
mode:
authoriamcheeseman <[hidden email]>2026-02-28 20:57:58 -0500
committeriamcheeseman <[hidden email]>2026-02-28 20:57:58 -0500
commitae870b9e6bf9faaf45a1470e64dacaa20084d3fa (patch)
treea3fa1ef776650db7ad2ea7aa30ad06de90c55c6a /src/phys
parent97e7909e4d730524b3ea319fa86520ed3bb3df5c (diff)
Use odin's new handle maps in physics too
Diffstat (limited to 'src/phys')
-rw-r--r--src/phys/world.odin102
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
}