mirror of
https://github.com/open-goal/jak-project
synced 2026-08-20 14:24:45 -04:00
96 lines
4.8 KiB
Common Lisp
96 lines
4.8 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
(bundles "ENGINE.CGO" "GAME.CGO")
|
|
(require "engine/math/vector.gc")
|
|
(require "engine/physics/trajectory-h.gc")
|
|
(require "engine/debug/debug-h.gc")
|
|
|
|
;; DECOMP BEGINS
|
|
|
|
(defmethod eval-position! ((this trajectory) (elapsed-time float) (result vector))
|
|
"Evaluate position after elapsed-time game-time ticks into result. Vertical motion includes
|
|
one half gravity times time squared; evaluation is not clamped to the solved flight duration."
|
|
(vector-copy! result (-> this initial-position))
|
|
(+! (-> result x) (* elapsed-time (-> this initial-velocity x)))
|
|
(+! (-> result y) (* elapsed-time (-> this initial-velocity y)))
|
|
(+! (-> result z) (* elapsed-time (-> this initial-velocity z)))
|
|
(+! (-> result y) (* (/ elapsed-time 2) elapsed-time (-> this gravity)))
|
|
result)
|
|
|
|
(defmethod eval-velocity! ((this trajectory) (elapsed-time float) (result vector))
|
|
"Evaluate velocity after elapsed-time game-time ticks into result. Only the vertical
|
|
component changes under gravity."
|
|
(vector-copy! result (-> this initial-velocity))
|
|
(+! (-> result y) (* elapsed-time (-> this gravity)))
|
|
result)
|
|
|
|
(defmethod setup-from-to-duration! ((this trajectory) (start vector) (destination vector) (duration float) (gravity float))
|
|
"Solve the initial velocity that moves from start to destination in duration game-time ticks
|
|
under constant vertical gravity. Store the supplied duration; callers must provide a positive,
|
|
nonzero duration."
|
|
(vector-copy! (-> this initial-position) start)
|
|
(set! (-> this gravity) gravity)
|
|
(set! (-> this time) duration)
|
|
(let ((xz-speed (/ (vector-vector-xz-distance destination start) duration)))
|
|
(vector-! (-> this initial-velocity) destination start)
|
|
(vector-xz-normalize! (-> this initial-velocity) xz-speed))
|
|
(set! (-> this initial-velocity y)
|
|
(- (/ (- (-> destination y) (-> start y)) duration) (* (/ duration 2) (-> this gravity))))
|
|
0
|
|
(none))
|
|
|
|
(defmethod setup-from-to-xz-vel! ((this trajectory) (start vector) (destination vector) (xz-speed float) (gravity float))
|
|
"Solve a trajectory from start to destination at the requested nonzero horizontal speed
|
|
under constant vertical gravity. Horizontal distance divided by xz-speed determines the duration."
|
|
(let ((duration (/ (vector-vector-xz-distance destination start) xz-speed)))
|
|
(setup-from-to-duration! this start destination duration gravity))
|
|
0
|
|
(none))
|
|
|
|
(defmethod setup-from-to-y-vel! ((this trajectory) (start vector) (destination vector) (initial-y-velocity float) (gravity float))
|
|
"Solve a trajectory from start to destination with initial-y-velocity and constant vertical
|
|
gravity. Use the later real time at which the vertical equation reaches the destination; when no
|
|
real root exists, use a 900-tick fallback duration."
|
|
(let ((discriminant (- (square initial-y-velocity) (* 2.0 (- (-> start y) (-> destination y)) gravity)))
|
|
(duration 900.0))
|
|
(when (>= discriminant 0.0)
|
|
(let ((sqrt-discriminant (sqrtf discriminant)))
|
|
(set! duration
|
|
(fmax (/ (- (- initial-y-velocity) sqrt-discriminant) gravity) (/ (+ (- initial-y-velocity) sqrt-discriminant) gravity)))))
|
|
(setup-from-to-duration! this start destination duration gravity))
|
|
0
|
|
(none))
|
|
|
|
(defmethod setup-from-to-height! ((this trajectory) (start vector) (destination vector) (apex-height float) (gravity float))
|
|
"Solve a trajectory from start to destination whose apex is apex-height above the higher
|
|
endpoint. Derive the required initial vertical velocity, using 4096 when that square-root input is
|
|
not positive, then solve the corresponding flight duration."
|
|
(let* ((apex-y (+ apex-height (fmax (-> start y) (-> destination y))))
|
|
(initial-y-speed-squared (* 2.0 (- (-> start y) apex-y) gravity))
|
|
(initial-y-velocity 4096.0))
|
|
(if (< 0.0 initial-y-speed-squared) (set! initial-y-velocity (sqrtf initial-y-speed-squared)))
|
|
(setup-from-to-y-vel! this start destination initial-y-velocity gravity))
|
|
0
|
|
(none))
|
|
|
|
(defmethod debug-draw! ((this trajectory))
|
|
"Draw the solved flight as ten translucent red line segments from time zero through the
|
|
stored duration, without depth testing."
|
|
(let ((previous-position (new 'stack-no-clear 'vector))
|
|
(position (new 'stack-no-clear 'vector))
|
|
(num-segments 10))
|
|
(vector-copy! position (-> this initial-position))
|
|
(dotimes (i num-segments)
|
|
(vector-copy! previous-position position)
|
|
(let ((sample-time (* (-> this time) (/ (+ 1.0 (the float i)) (the float num-segments)))))
|
|
(eval-position! this sample-time position))
|
|
(add-debug-line #t
|
|
(bucket-id debug-no-zbuf)
|
|
previous-position
|
|
position
|
|
(new 'static 'rgba :r #xff :a #x80)
|
|
#f
|
|
(the-as rgba -1))))
|
|
0
|
|
(none))
|