From db10e319cc2201924815b2d8c9a4c2d21c2bfbb6 Mon Sep 17 00:00:00 2001 From: iamcheeseman <[hidden email]> Date: Sat, 17 Jan 2026 18:19:57 -0500 Subject: Verlet ropes :) --- src/verlet.odin | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/verlet.odin (limited to 'src/verlet.odin') diff --git a/src/verlet.odin b/src/verlet.odin new file mode 100644 index 0000000..1434109 --- /dev/null +++ b/src/verlet.odin @@ -0,0 +1,80 @@ +package demonchime + +import "core:math" +import "core:math/linalg" + +import rl "vendor:raylib" + +import "phys" + +VERLET_STEPS :: 50 +VERLET_MIN_DIST_TO_PLAYER :: 8 + +Verlet_Node :: struct { + pos: Vec2, + prev_pos: Vec2, + accel: Vec2, + is_static: bool, +} + +Verlet_Rope :: struct { + nodes: []Verlet_Node, + node_length: f32, +} + +create_verlet_node :: proc(pos: Vec2, is_static := false) -> Verlet_Node { + return Verlet_Node{ + pos = pos, + prev_pos = pos, + is_static = is_static, + } +} + +update_verlet_node :: proc(node: ^Verlet_Node) { + if node.is_static { + return + } + + dt: f32 = FIXED_UPDATE_RATE + + node.accel.y += GRAVITY + + player_pos := phys.get_position(player.body) + player_dist := linalg.distance(node.pos, player_pos) + if player_dist < VERLET_MIN_DIST_TO_PLAYER { + dir := linalg.normalize(node.pos - player_pos) + node.pos = player_pos + dir * VERLET_MIN_DIST_TO_PLAYER + } + + prev_pos := node.pos + node.pos = (node.pos * 2 - node.prev_pos) + node.accel * (dt*dt) + node.prev_pos = prev_pos + + node.accel = {} +} + +update_verlet_rope :: proc(rope: ^Verlet_Rope) { + for &node in rope.nodes { + update_verlet_node(&node) + } + + for _ in 0..