ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic 1804 vars into 126 states, 64 into lets; 23498 edits in 460 files Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
70 lines
3.7 KiB
Text
70 lines
3.7 KiB
Text
# camera.ludic - the orbit: a pivot at the chest easing after the body, the camera on its orbit
|
|
# behind and a share of the distance to the right (so the body sits left of the crosshair), lifted
|
|
# out of the ground and aimed back at the pivot. Or the eyes, with the gait's bob on them.
|
|
function chr_eyes_allowed(character_st: CharacterState) -> bool { return not CharacterBody.riding() and not character_st.chr_sit and CharacterBody.eyes_ok() }
|
|
|
|
function chr_shoulder(character_st: CharacterState) -> float { return Math.clamp(character_st.chr_cam_dist * 0.30, 0.6, 1.9) }
|
|
|
|
export function char_camera(character_st: mut CharacterState, dt: float) -> void {
|
|
if character_st.chr_fps and chr_eyes_allowed(character_st) {
|
|
chr_camera_eyes(character_st, dt)
|
|
return
|
|
}
|
|
char_camera_third(character_st, dt)
|
|
}
|
|
|
|
# over the shoulder, whatever the player plays in (a figure looked at from inside its head is not)
|
|
export function char_camera_third(character_st: mut CharacterState, dt: float) -> void {
|
|
character_st.chr_eyes_now = false
|
|
let k = Math.min(1.0, 10.0 * dt)
|
|
var ty = character_st.chr_y + 1.45
|
|
if character_st.chr_swim { ty = character_st.chr_y + 0.9 }
|
|
character_st.chr_piv_x = Math.lerp(character_st.chr_piv_x, character_st.chr_x, k)
|
|
character_st.chr_piv_y = Math.lerp(character_st.chr_piv_y, ty, k)
|
|
character_st.chr_piv_z = Math.lerp(character_st.chr_piv_z, character_st.chr_z, k)
|
|
let cyw = Math.cos(character_st.chr_cam_yaw)
|
|
let syw = Math.sin(character_st.chr_cam_yaw)
|
|
let cpt = Math.cos(character_st.chr_cam_pitch)
|
|
let fx = -(syw * cpt)
|
|
let fy = Math.sin(character_st.chr_cam_pitch)
|
|
let fz = -(cyw * cpt)
|
|
let ax = character_st.chr_piv_x + cyw * chr_shoulder(character_st)
|
|
let az = character_st.chr_piv_z - syw * chr_shoulder(character_st)
|
|
let cx = ax - fx * character_st.chr_cam_dist
|
|
var cyy = character_st.chr_piv_y - fy * character_st.chr_cam_dist
|
|
let cz = az - fz * character_st.chr_cam_dist
|
|
cyy = Math.max(cyy, CharacterGround.bed(cx, cz) + 0.55)
|
|
# at the top of the water the camera is held clear of it; under it, it follows the dive
|
|
if character_st.chr_swim and not character_st.chr_dive and cyy < character_st.chr_water + 0.35 { cyy = character_st.chr_water + 0.35 }
|
|
let mid_g = CharacterGround.bed((cx + ax) * 0.5, (cz + az) * 0.5) + 0.4
|
|
let mid_y = (cyy + character_st.chr_piv_y) * 0.5
|
|
if mid_y < mid_g { cyy = cyy + (mid_g - mid_y) * 2.0 }
|
|
character_st.chr_eye_x = cx
|
|
character_st.chr_eye_y = cyy
|
|
character_st.chr_eye_z = cz
|
|
let ddx = ax - cx
|
|
let ddz = az - cz
|
|
character_st.chr_eye_yaw = Math.atan2(-ddx, -ddz)
|
|
character_st.chr_eye_pitch = Math.atan2(character_st.chr_piv_y - cyy, Math.sqrt(ddx * ddx + ddz * ddz))
|
|
}
|
|
|
|
# the eyes: the head's height, the walk's bob, and the look the player is already holding
|
|
function chr_camera_eyes(character_st: mut CharacterState, dt: float) -> void {
|
|
character_st.chr_eyes_now = true
|
|
var eye = 1.62
|
|
if character_st.chr_swim { eye = 0.42 }
|
|
if character_st.chr_dive { eye = 0.30 }
|
|
let moving = Math.clamp(character_st.chr_speed / 5.0, 0.0, 1.0)
|
|
let want = 0.035 * moving * (1.0 - Math.cos(character_st.chr_phase * 2.0))
|
|
character_st.chr_fps_bob = Math.lerp(character_st.chr_fps_bob, want, Math.min(1.0, 12.0 * dt))
|
|
# never inside the ground on a steep step
|
|
let ey = Math.max(character_st.chr_y + eye + character_st.chr_fps_bob, CharacterGround.bed(character_st.chr_x, character_st.chr_z) + 0.30)
|
|
character_st.chr_piv_x = character_st.chr_x
|
|
character_st.chr_piv_y = ey
|
|
character_st.chr_piv_z = character_st.chr_z
|
|
character_st.chr_eye_x = character_st.chr_x
|
|
character_st.chr_eye_y = ey
|
|
character_st.chr_eye_z = character_st.chr_z
|
|
character_st.chr_eye_yaw = character_st.chr_cam_yaw
|
|
character_st.chr_eye_pitch = character_st.chr_cam_pitch
|
|
}
|