# hull.ludic - a boat: a buoyant box floated by PhysWater, rowed along its bow and turned about its # middle. Its bow is -z at yaw 0, the way the valley faces (forward is (-sin yaw, -cos yaw)). # hx, hy, hz its half width, depth and length; buoyancy over 1 floats it (4: a quarter under) @creates(PhysBody) export function phys_hull_add(physics_st: mut PhysicsState, x: float, y: float, z: float, yaw: float, hx: float, hy: float, hz: float, mass: float, buoyancy: float, drag: float) -> int { let s = phys_box(physics_st, hx, hy, hz) let id = phys_body_add(physics_st, s, x, y, z, yaw, mass) if id < 0 { return -1 } phys_own(physics_st, id, s) phys_float(physics_st, id, buoyancy, drag, drag * 1.5) return id } # a stroke of `forward` newtons along the bow and a turn of `turn` newton-metres about y, over the # next step export function phys_row(physics_st: mut PhysicsState, id: int, forward: float, turn: float) -> void { if physics_st.ph_world == null or jph_body_read(physics_st.ph_world, id, physics_st.ph_vals) != 0 { return } let v = physics_st.ph_vals let yaw = Math.atan2(2.0 * (v[6] * v[4] + v[3] * v[5]), 1.0 - 2.0 * (v[4] * v[4] + v[3] * v[3])) phys_force(physics_st, id, -Math.sin(yaw) * forward, 0.0, -Math.cos(yaw) * forward) phys_torque(physics_st, id, 0.0, turn, 0.0) } # how fast it goes along its bow (backwards is negative) export function phys_bow_speed(p: PhysPose) -> float { let yaw = phys_yaw_of(p) return -Math.sin(yaw) * p.vx - Math.cos(yaw) * p.vz }