feat(vehicles): 16.7 - a boat is a buoyant hull in the game's physics (VehicleHull), rowed along its bow and turned by the oars; the scripted bob, the wind's drift and the shore refusal are gone
The water floats the hull, the wind pushes every boat as a force, the lake bed stops it at the shore; the swell takes the outward share of a stroke. ludic.physics: phys_hull_add (a buoyant box), phys_row, phys_bow_speed, and a test that floats one a quarter under, rows, turns and grounds it. The vehicles tests row a real Jolt hull on the fake shore; the horse moved to horse.ludic. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ac815bf638
commit
510360b002
12 changed files with 284 additions and 103 deletions
26
packages/ludic.physics/hull.ludic
Normal file
26
packages/ludic.physics/hull.ludic
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# 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)
|
||||
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 id = phys_body_add(physics_st, phys_box(physics_st, hx, hy, hz), x, y, z, yaw, mass)
|
||||
if id < 0 { return -1 }
|
||||
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 {
|
||||
let p = phys_pose(physics_st, id)
|
||||
if p == null { return }
|
||||
let yaw = phys_yaw_of(p)
|
||||
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
|
||||
}
|
||||
|
|
@ -10,4 +10,5 @@ import "bodies.ludic"
|
|||
import "queries.ludic"
|
||||
import "water.ludic"
|
||||
import "walker.ludic"
|
||||
import "hull.ludic"
|
||||
import "system.ludic"
|
||||
|
|
|
|||
|
|
@ -127,4 +127,34 @@ program MotionTest {
|
|||
expect_eq(float_bits(a.z), float_bits(b.z))
|
||||
expect_eq(float_bits(a.qw), float_bits(b.qw))
|
||||
}
|
||||
|
||||
test "a hull floats a quarter under, is rowed along its bow, turned, and stopped by the lake bed" (physics_st: mut PhysicsState) {
|
||||
world(physics_st)
|
||||
let b = phys_hull_add(physics_st, 40.0, 0.5, 0.0, 1.5707963, 0.6, 0.25, 1.9, 180.0, 4.0, 1.0)
|
||||
sim(physics_st, 4.0)
|
||||
let p0 = phys_pose(physics_st, b)
|
||||
expect(p0.y > -0.2)
|
||||
expect(p0.y < 0.2)
|
||||
for i in 0 .. 240 {
|
||||
phys_row(physics_st, b, 420.0, 0.0)
|
||||
phys_step(physics_st)
|
||||
}
|
||||
let p1 = phys_pose(physics_st, b)
|
||||
expect(p1.x < 34.0)
|
||||
expect(phys_bow_speed(p1) > 1.0)
|
||||
for i in 0 .. 120 {
|
||||
phys_row(physics_st, b, 0.0, 520.0)
|
||||
phys_step(physics_st)
|
||||
}
|
||||
expect(Math.abs(phys_yaw_of(phys_pose(physics_st, b)) - phys_yaw_of(p1)) > 0.5)
|
||||
phys_close(physics_st)
|
||||
world(physics_st)
|
||||
let c = phys_hull_add(physics_st, 24.0, 0.5, 0.0, 1.5707963, 0.6, 0.25, 1.9, 180.0, 4.0, 1.0)
|
||||
for i in 0 .. 600 {
|
||||
phys_row(physics_st, c, 420.0, 0.0)
|
||||
phys_step(physics_st)
|
||||
}
|
||||
expect(phys_pose(physics_st, c).x > 19.5)
|
||||
phys_close(physics_st)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue