Files
jak-project/goal_src/jak1/engine/camera/cam-debug.gc
T
2026-08-07 20:58:40 -04:00

989 lines
50 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
(bundles "ENGINE.CGO" "GAME.CGO")
(require "engine/collide/pat-h.gc")
(require "engine/anim/joint-mod-h.gc")
(require "engine/math/euler.gc")
(require "engine/geometry/bounding-box-h.gc")
(require "engine/debug/debug.gc")
(require "engine/collide/collide-mesh-h.gc")
(require "engine/camera/camera.gc")
;; DECOMP BEGINS
;; this file is debug only
(declare-file (debug))
(when (or (not *camera-old-cpu*) (zero? *camera-old-cpu*))
(set! *camera-old-cpu* 0)
0)
(when (or (not *camera-old-vu*) (zero? *camera-old-vu*))
(set! *camera-old-vu* 0)
0)
(when (or (not *camera-old-tfrag-bytes*) (zero? *camera-old-tfrag-bytes*))
(set! *camera-old-tfrag-bytes* 0)
0)
(define-perm *camera-old-level* string (new 'global 'string 128 (the-as string #f)))
(define-perm *camera-old-stat-string-tfrag* string (new 'global 'string 128 (the-as string #f)))
(define-perm *camera-old-stat-string-tfrag-near* string (new 'global 'string 128 (the-as string #f)))
(define-perm *camera-old-stat-string-total* string (new 'global 'string 128 (the-as string #f)))
(deftype cam-dbg-scratch (structure)
((linevec4w vector4w 2 :inline)
(color vector :inline)
(plotvec vector4w 2 :inline)
(linevec vector 2 :inline)
(rel-vec vector :inline)
(sphere-v-start vector :inline)
(sphere-v-end vector :inline)
(sphere-v-down vector :inline)
(sphere-vec vector :inline)
(crossvec vector 3 :inline)
(bboxvec vector 6 :inline)
(fov-vv vector 4 :inline)
(fov-src vector :inline)
(fov-dest vector :inline)
(fov-vert vector :inline)
(fov-horz vector :inline)))
(defun cam-slave-options->string ((options cam-slave-options) (output object))
"Append the names of the enabled camera-slave option bits to output and
return output as a string."
(if (= (logand (cam-slave-options AIR_EXIT) options) (cam-slave-options AIR_EXIT))
(format output "AIR_EXIT "))
(if (= (logand (cam-slave-options STICKY_ANGLE) options) (cam-slave-options STICKY_ANGLE))
(format output "STICKY_ANGLE "))
(if (= (logand options (cam-slave-options NO_ROTATE)) (cam-slave-options NO_ROTATE))
(format output "NO_ROTATE "))
(if (= (logand options (cam-slave-options BIKE_MODE)) (cam-slave-options BIKE_MODE))
(format output "BIKE_MODE "))
(if (= (logand options (cam-slave-options BLOCK_SHIFT_BUTTONS)) (cam-slave-options BLOCK_SHIFT_BUTTONS))
(format output "BLOCK_SHIFT_BUTTONS "))
(if (= (logand options (cam-slave-options GOTO_GOOD_POINT)) (cam-slave-options GOTO_GOOD_POINT))
(format output "GOTO_GOOD_POINT "))
(if (= (logand options (cam-slave-options SHRINK_MAX_ANGLE)) (cam-slave-options SHRINK_MAX_ANGLE))
(format output "SHRINK_MAX_ANGLE "))
(if (= (logand options (cam-slave-options MOVEMENT_BLOCKED)) (cam-slave-options MOVEMENT_BLOCKED))
(format output "MOVEMENT_BLOCKED "))
(if (= (logand options (cam-slave-options LINE_OF_SIGHT)) (cam-slave-options LINE_OF_SIGHT))
(format output "LINE_OF_SIGHT "))
(if (= (logand options (cam-slave-options PLAYER_MOVING_CAMERA)) (cam-slave-options PLAYER_MOVING_CAMERA))
(format output "PLAYER_MOVING_CAMERA "))
(if (= (logand options (cam-slave-options DRAG)) (cam-slave-options DRAG))
(format output "DRAG "))
(if (= (logand options (cam-slave-options FIND_HIDDEN_TARGET)) (cam-slave-options FIND_HIDDEN_TARGET))
(format output "FIND_HIDDEN_TARGET "))
(if (= (logand options (cam-slave-options COLLIDE)) (cam-slave-options COLLIDE))
(format output "COLLIDE "))
(if (= (logand options (cam-slave-options JUMP_PITCHES)) (cam-slave-options JUMP_PITCHES))
(format output "JUMP_PITCHES "))
(if (= (logand options (cam-slave-options ALLOW_Z_ROT)) (cam-slave-options ALLOW_Z_ROT))
(format output "ALLOW_Z_ROT "))
(if (= (logand options (cam-slave-options MOVE_SPHERICAL)) (cam-slave-options MOVE_SPHERICAL))
(format output "MOVE_SPHERICAL "))
(if (= (logand options (cam-slave-options SAME_SIDE)) (cam-slave-options SAME_SIDE))
(format output "SAME_SIDE "))
(if (= (logand options (cam-slave-options BUTT_CAM)) (cam-slave-options BUTT_CAM))
(format output "BUTT_CAM "))
(the-as string output))
(defun cam-index-options->string ((options cam-index-options) (output object))
"Append the historical labels for the enabled camera-index option bits to
output. These strings are opposite the current SPHERICAL and RADIAL enum
names."
(if (= (logand options (cam-index-options SPHERICAL)) (cam-index-options SPHERICAL))
(format output "RADIAL "))
(if (= (logand options (cam-index-options RADIAL)) (cam-index-options RADIAL))
(format output "SPHERICAL "))
(the-as string output))
(defun slave-los-state->string ((los-state slave-los-state))
"Return the debug name of a camera line-of-sight state, or *unknown* for an
unrecognized value."
(case los-state
(((slave-los-state between)) "between")
(((slave-los-state ccw)) "ccw")
(((slave-los-state cw)) "cw")
(((slave-los-state none)) "none")
(else "*unknown*")))
(defun cam-line-dma ()
"Append the current transformed debug-line endpoints and color to the
no-depth-test debug DMA bucket."
(slet (spad cam-dbg-scratch)
(with-dma-buffer-add-bucket ((dma-buf (-> (current-frame) debug-buf)) (bucket-id debug-no-zbuf))
(with-cnt-vif-block (dma-buf)
(dma-buffer-add-gif-tag dma-buf
(new 'static
'gif-tag64
:nloop #x1
:eop #x1
:pre #x1
:prim
(new 'static 'gs-prim :prim (gs-prim-type line) :iip #x1 :abe #x1)
:nreg #x4)
(gs-reg-list rgbaq xyzf2 rgbaq xyzf2))
(dma-buffer-add-uint128 dma-buf (-> spad color quad) (-> spad linevec4w 0 quad))
(dma-buffer-add-uint128 dma-buf (-> spad color quad) (-> spad linevec4w 1 quad))))))
(defun camera-line2d ((start vector4w) (end vector4w))
"Draw a line between two screen-space points. Convert pixels to GS 12.4
coordinates, invert Y, and place both endpoints at the far 24-bit depth."
(slet (spad cam-dbg-scratch)
(set! (-> spad linevec4w 0 x) (* (+ (-> start x) 1792) 16))
(set! (-> spad linevec4w 0 y) (* (- (-> *video-parms* screen-maxy) (-> start y)) 16))
(set! (-> spad linevec4w 0 z) #x7fffff)
(set! (-> spad linevec4w 1 x) (* (+ (-> end x) 1792) 16))
(set! (-> spad linevec4w 1 y) (* (- (-> *video-parms* screen-maxy) (-> end y)) 16))
(set! (-> spad linevec4w 1 z) #x7fffff)
(cam-line-dma)))
(defun camera-plot-float-func ((x-min float) (x-max float) (y-min float) (y-max float) (fn (function float float)) (color vector4w))
"Plot fn over [x-min, x-max] in a 400 by 200 pixel debug graph. Map
[y-min, y-max] to the plot height, draw the axes and border at screen offset
(20, 20), then connect one sample per horizontal pixel in color."
(slet (spad cam-dbg-scratch)
(let ((x-range (- x-max x-min))
(y-range (- y-max y-min)))
0.0
0.0
(let ((y-scale (/ 200.0 y-range))
(x-scale (/ 400.0 x-range)))
(set! (-> spad color x) (the-as float 128))
(set! (-> spad color y) (the-as float 128))
(set! (-> spad color z) (the-as float 128))
(set! (-> spad color w) (the-as float 128))
(when (and (< x-min 0.0) (< 0.0 x-max))
(set! (-> spad plotvec 0 x) (+ (the int (* x-scale x-range (/ (- x-min) x-range))) 20))
(set! (-> spad plotvec 0 y) 20)
(set! (-> spad plotvec 1 x) (-> spad plotvec 0 x))
(set! (-> spad plotvec 1 y) (+ (the int (* y-scale y-range)) 20))
(camera-line2d (-> spad plotvec 0) (-> spad plotvec 1)))
(when (and (< y-min 0.0) (< 0.0 y-max))
(set! (-> spad plotvec 0 x) 20)
(set! (-> spad plotvec 0 y) (+ (the int (* y-scale y-range (/ (- y-min) y-range))) 20))
(set! (-> spad plotvec 1 x) (+ (the int (* x-scale x-range)) 20))
(set! (-> spad plotvec 1 y) (-> spad plotvec 0 y))
(camera-line2d (-> spad plotvec 0) (-> spad plotvec 1)))
(set! (-> spad plotvec 0 x) 20)
(set! (-> spad plotvec 0 y) 20)
(set! (-> spad plotvec 1 x) (+ (the int (* x-scale x-range)) 20))
(set! (-> spad plotvec 1 y) 20)
(camera-line2d (-> spad plotvec 0) (-> spad plotvec 1))
(set! (-> spad plotvec 0 x) 20)
(set! (-> spad plotvec 0 y) (+ (the int (* y-scale y-range)) 20))
(set! (-> spad plotvec 1 x) (+ (the int (* x-scale x-range)) 20))
(set! (-> spad plotvec 1 y) (+ (the int (* y-scale y-range)) 20))
(camera-line2d (-> spad plotvec 0) (-> spad plotvec 1))
(set! (-> spad plotvec 0 x) 20)
(set! (-> spad plotvec 0 y) 20)
(set! (-> spad plotvec 1 x) 20)
(set! (-> spad plotvec 1 y) (+ (the int (* y-scale y-range)) 20))
(camera-line2d (-> spad plotvec 0) (-> spad plotvec 1))
(set! (-> spad plotvec 0 x) (+ (the int (* x-scale x-range)) 20))
(set! (-> spad plotvec 0 y) 20)
(set! (-> spad plotvec 1 x) (+ (the int (* x-scale x-range)) 20))
(set! (-> spad plotvec 1 y) (+ (the int (* y-scale y-range)) 20))
(camera-line2d (-> spad plotvec 0) (-> spad plotvec 1))
(vector4w-copy! (-> spad color) color)
(set! (-> spad plotvec 1 x) 20)
(set! (-> spad plotvec 1 y) (+ (the int (* y-scale (- (fn x-min) y-min))) 20))
(let ((x-pixel 1))
(while (>= (the int (* x-scale x-range)) x-pixel)
(let ((previous-point-quad (-> spad plotvec 1 quad)))
(set! (-> spad plotvec 0 quad) previous-point-quad))
(set! (-> spad plotvec 1 x) (+ x-pixel 20))
(set! (-> spad plotvec 1 y)
(+ (the int (* y-scale (- (fn (+ x-min (* x-range (/ (the float x-pixel) (* x-scale x-range))))) y-min))) 20))
(camera-line2d (-> spad plotvec 0) (-> spad plotvec 1))
(+! x-pixel 1)))))
0
(none)))
(defun camera-line-setup ((color vector4w))
"Select the color for subsequent camera-line-draw calls and initialize the
identity world-to-screen transform."
(slet (spad cam-dbg-scratch)
(vector4w-copy! (-> spad color) color)
(init-for-transform *identity-matrix*)
0
(none)))
;; WARN: Function camera-line-draw has a return type of none, but the expression builder found a return statement.
(defun camera-line-draw ((start vector) (end vector))
"Transform and draw one world-space line using the color selected by
camera-line-setup. Reject either endpoint whose transformed depth is past
the debug renderer's unsigned cutoff."
(slet (spad cam-dbg-scratch)
(vector-copy! (-> spad linevec 0) start)
(vector-copy! (-> spad linevec 1) end)
(set! (-> spad linevec 0 w) 1.0)
(set! (-> spad linevec 1 w) 1.0)
(transform-float-point (-> spad linevec 0) (-> spad linevec4w 0))
(transform-float-point (-> spad linevec 1) (-> spad linevec4w 1))
(cond
((< (the-as uint #xe00000) (the-as uint (-> spad linevec4w 0 z))) (return #f))
((< (the-as uint #xe00000) (the-as uint (-> spad linevec4w 1 z))) (return #f)))
(cam-line-dma)
0
(none)))
(defun camera-line ((start vector) (end vector) (color vector4w))
"Draw one world-space line in color."
(camera-line-setup color)
(camera-line-draw start end)
0
(none))
(defun camera-line-rel ((start vector) (offset vector) (color vector4w))
"Draw a line from start to start plus offset."
(slet (spad cam-dbg-scratch)
(vector+! (-> spad rel-vec) start offset)
(camera-line start (-> spad rel-vec) color)
(none)))
(defun camera-line-rel-len ((start vector) (direction vector) (length meters) (color vector4w))
(slet (spad cam-dbg-scratch)
(vector-normalize-copy! (-> spad rel-vec) direction length)
(vector+! (-> spad rel-vec) (-> spad rel-vec) start)
(camera-line start (-> spad rel-vec) color)
(none)))
(defun camera-sphere ((center vector) (radius meters) (color vector4w))
"Draw a sphere as a ten-by-ten latitude/longitude wireframe."
(slet (spad cam-dbg-scratch)
(camera-line-setup color)
(dotimes (latitude 10)
(let ((ring-radius (* radius (sin (* 3276.8 (the float latitude)))))
(next-ring-radius (* radius (sin (* 3276.8 (the float (+ latitude 1)))))))
(set! (-> spad sphere-v-start y) (+ (-> center y) (* (cos (* 3276.8 (the float latitude))) radius)))
(set! (-> spad sphere-v-end y) (-> spad sphere-v-start y))
(set! (-> spad sphere-v-down y) (+ (-> center y) (* (cos (* 3276.8 (the float (+ latitude 1)))) radius)))
(dotimes (longitude 10)
(set! (-> spad sphere-v-start x) (+ (-> center x) (* (cos (* 6553.6 (the float longitude))) ring-radius)))
(set! (-> spad sphere-v-start z) (+ (-> center z) (* (sin (* 6553.6 (the float longitude))) ring-radius)))
(set! (-> spad sphere-v-end x) (+ (-> center x) (* (cos (* 6553.6 (the float (+ longitude 1)))) ring-radius)))
(set! (-> spad sphere-v-end z) (+ (-> center z) (* (sin (* 6553.6 (the float (+ longitude 1)))) ring-radius)))
(set! (-> spad sphere-v-down x) (+ (-> center x) (* (cos (* 6553.6 (the float longitude))) next-ring-radius)))
(set! (-> spad sphere-v-down z) (+ (-> center z) (* (sin (* 6553.6 (the float longitude))) next-ring-radius)))
(camera-line-draw (-> spad sphere-v-start) (-> spad sphere-v-end))
(camera-line-draw (-> spad sphere-v-start) (-> spad sphere-v-down)))))
0
(none)))
(defun camera-cross ((axis-a vector) (axis-b vector) (center vector) (color vector4w) (half-length meters))
"Draw three perpendicular diameter lines through center. The first axis is
axis-a; the other two are formed by successive crosses with axis-b and
axis-a. half-length is the distance from center to each endpoint."
(slet (spad cam-dbg-scratch)
(vector-normalize-copy! (-> spad crossvec 0) axis-a half-length)
(vector+! (-> spad crossvec 1) center (-> spad crossvec 0))
(vector-! (-> spad crossvec 2) center (-> spad crossvec 0))
(camera-line (-> spad crossvec 1) (-> spad crossvec 2) color)
(vector-cross! (-> spad crossvec 0) (-> spad crossvec 0) axis-b)
(vector-normalize! (-> spad crossvec 0) half-length)
(vector+! (-> spad crossvec 1) center (-> spad crossvec 0))
(vector-! (-> spad crossvec 2) center (-> spad crossvec 0))
(camera-line (-> spad crossvec 1) (-> spad crossvec 2) color)
(vector-cross! (-> spad crossvec 0) (-> spad crossvec 0) axis-a)
(vector-normalize! (-> spad crossvec 0) half-length)
(vector+! (-> spad crossvec 1) center (-> spad crossvec 0))
(vector-! (-> spad crossvec 2) center (-> spad crossvec 0))
(camera-line (-> spad crossvec 1) (-> spad crossvec 2) color)
(none)))
(defun camera-bounding-box-draw ((bounds bounding-box))
"Draw the twelve edges of bounds in the original fixed gray."
(slet (spad cam-dbg-scratch)
(camera-line-setup (new 'static 'vector4w :x #x7f :y #x7f :z #x7f :w #x80))
(vector-copy! (-> spad bboxvec 0) (-> bounds min))
(set! (-> spad bboxvec 0 x) (-> bounds max x))
(vector-copy! (-> spad bboxvec 1) (-> bounds min))
(set! (-> spad bboxvec 1 y) (-> bounds max y))
(vector-copy! (-> spad bboxvec 2) (-> bounds min))
(set! (-> spad bboxvec 2 z) (-> bounds max z))
(vector-copy! (-> spad bboxvec 3) (-> bounds max))
(set! (-> spad bboxvec 3 x) (-> bounds min x))
(vector-copy! (-> spad bboxvec 4) (-> bounds max))
(set! (-> spad bboxvec 4 y) (-> bounds min y))
(vector-copy! (-> spad bboxvec 5) (-> bounds max))
(set! (-> spad bboxvec 5 z) (-> bounds min z))
(camera-line-draw (-> bounds min) (-> spad bboxvec 0))
(camera-line-draw (-> bounds min) (-> spad bboxvec 1))
(camera-line-draw (-> bounds min) (-> spad bboxvec 2))
(camera-line-draw (-> bounds max) (-> spad bboxvec 3))
(camera-line-draw (-> bounds max) (-> spad bboxvec 4))
(camera-line-draw (-> bounds max) (-> spad bboxvec 5))
(camera-line-draw (-> spad bboxvec 0) (-> spad bboxvec 4))
(camera-line-draw (-> spad bboxvec 4) (-> spad bboxvec 2))
(camera-line-draw (-> spad bboxvec 2) (-> spad bboxvec 3))
(camera-line-draw (-> spad bboxvec 3) (-> spad bboxvec 1))
(camera-line-draw (-> spad bboxvec 1) (-> spad bboxvec 5))
(camera-line-draw (-> spad bboxvec 5) (-> spad bboxvec 0))
0
(none)))
(deftype cam-debug-tri (structure)
((vertex vector 3 :inline)
(intersect vector :inline)
(color vector4w)))
(define *cam-debug-los-tri-current* 0)
(define *cam-debug-los-tri* (the-as (inline-array cam-debug-tri) (malloc 'debug #x8fc0)))
(define *cam-debug-coll-tri-current* 0)
(define *cam-debug-coll-tri* (the-as (inline-array cam-debug-tri) (malloc 'debug #x8fc0)))
(defun cam-debug-reset-coll-tri ()
"Clear the per-frame camera collision and line-of-sight triangle lists."
(set! *cam-debug-los-tri-current* 0)
(set! *cam-debug-coll-tri-current* 0)
0
(none))
(defun cam-debug-add-los-tri ((triangles (inline-array collide-cache-tri)) (intersection vector) (color vector4w))
"Save the first collision-cache triangle, intersection, and color in the
line-of-sight debug list. The list holds at most 460 entries."
(cond
((>= *cam-debug-los-tri-current* 460))
(else
(let ((saved-triangle (-> *cam-debug-los-tri* *cam-debug-los-tri-current*)))
(vector-copy! (-> saved-triangle vertex 0) (-> triangles 0 vertex 0))
(vector-copy! (-> saved-triangle vertex 1) (-> triangles 0 vertex 1))
(vector-copy! (-> saved-triangle vertex 2) (-> triangles 0 vertex 2))
(vector-copy! (-> saved-triangle intersect) intersection)
(set! (-> saved-triangle color) color))
(set! *cam-debug-los-tri-current* (+ *cam-debug-los-tri-current* 1))
(if (= *cam-debug-los-tri-current* 460)
(format 0 "ERROR <GMJ>: cam-debug-add-los-tri overflow~%"))))
0
(none))
(defun cam-debug-add-coll-tri ((triangle cam-debug-tri) (intersection vector) (color vector4w))
"Copy a camera debug triangle with a new intersection and color into the
collision debug list. The list holds at most 460 entries."
(cond
((>= *cam-debug-coll-tri-current* 460))
(else
(let ((saved-triangle (-> *cam-debug-coll-tri* *cam-debug-coll-tri-current*)))
(vector-copy! (-> saved-triangle vertex 0) (-> triangle vertex 0))
(vector-copy! (-> saved-triangle vertex 1) (-> triangle vertex 1))
(vector-copy! (-> saved-triangle vertex 2) (-> triangle vertex 2))
(vector-copy! (-> saved-triangle intersect) intersection)
(set! (-> saved-triangle color) color))
(set! *cam-debug-coll-tri-current* (+ *cam-debug-coll-tri-current* 1))
(if (>= *cam-debug-coll-tri-current* 460)
(format 0 "ERROR <GMJ>: cam-debug-add-coll-tri overflow~%"))))
0
(none))
(defun cam-debug-draw-tris ()
"Draw the recorded camera line-of-sight and collision triangles selected by
the corresponding display flags, with a cross at each intersection."
(slet (spad cam-dbg-scratch)
(camera-line-setup (new 'stack 'vector4w))
(when *display-cam-los-marks*
(dotimes (i *cam-debug-los-tri-current*)
(vector4w-copy! (-> spad color) (-> *cam-debug-los-tri* i color))
(camera-line-draw (-> *cam-debug-los-tri* i vertex 0) (-> *cam-debug-los-tri* i vertex 1))
(camera-line-draw (-> *cam-debug-los-tri* i vertex 1) (-> *cam-debug-los-tri* i vertex 2))
(camera-line-draw (-> *cam-debug-los-tri* i vertex 2) (-> *cam-debug-los-tri* i vertex 0))
(camera-cross (new 'static 'vector :y 1024.0)
(new 'static 'vector :z 1024.0)
(-> *cam-debug-los-tri* i intersect)
(-> *cam-debug-los-tri* i color)
(meters 0.25))))
(when *display-cam-coll-marks*
(dotimes (i *cam-debug-coll-tri-current*)
(vector4w-copy! (-> spad color) (-> *cam-debug-coll-tri* i color))
(camera-line-draw (-> *cam-debug-coll-tri* i vertex 0) (-> *cam-debug-coll-tri* i vertex 1))
(camera-line-draw (-> *cam-debug-coll-tri* i vertex 1) (-> *cam-debug-coll-tri* i vertex 2))
(camera-line-draw (-> *cam-debug-coll-tri* i vertex 2) (-> *cam-debug-coll-tri* i vertex 0))
(camera-cross (new 'static 'vector :y 1024.0)
(new 'static 'vector :z 1024.0)
(-> *cam-debug-coll-tri* i intersect)
(-> *cam-debug-coll-tri* i color)
(meters 0.25)))
#f)))
(defun camera-fov-draw ((direction-a vector)
(direction-b vector)
(origin vector)
(near-distance meters)
(far-distance meters)
(color vector4w))
"Draw one side of a camera frustum from two direction vectors,
origin, near distance, far distance, and color."
(slet (spad cam-dbg-scratch)
(vector+float*! (-> spad fov-vv 0) origin direction-b near-distance)
(vector+float*! (-> spad fov-vv 1) origin direction-a near-distance)
(vector+float*! (-> spad fov-vv 2) origin direction-a far-distance)
(vector+float*! (-> spad fov-vv 3) origin direction-b far-distance)
(camera-line-setup color)
(camera-line-draw (-> spad fov-vv 0) (-> spad fov-vv 1))
(camera-line-draw (-> spad fov-vv 1) (-> spad fov-vv 2))
(camera-line-draw (-> spad fov-vv 2) (-> spad fov-vv 3))
(none)))
(defun camera-fov-frame ((inverse-rotation matrix)
(origin vector)
(half-fov float)
(vertical-scale float)
(horizontal-scale float)
(color vector4w))
"Draw a camera frustum from its inverse rotation, origin, half field of view,
vertical scale, horizontal scale, and color. The near and far outlines are
4096 and 20480 GOAL units from the origin."
(slet (spad cam-dbg-scratch)
(vector-float*! (-> spad fov-vert) (-> inverse-rotation vector 1) (* vertical-scale (tan half-fov)))
(vector-float*! (-> spad fov-horz) (-> inverse-rotation vector 0) (* horizontal-scale (tan half-fov)))
(vector+! (-> spad fov-src)
(-> inverse-rotation vector 2)
(vector+! (-> spad fov-src) (-> spad fov-vert) (-> spad fov-horz)))
(vector-normalize! (-> spad fov-src) 1.0)
(vector+! (-> spad fov-dest)
(-> inverse-rotation vector 2)
(vector-! (-> spad fov-dest) (-> spad fov-vert) (-> spad fov-horz)))
(vector-normalize! (-> spad fov-dest) 1.0)
(camera-fov-draw (-> spad fov-src) (-> spad fov-dest) origin (meters 1) (meters 5) color)
(vector-copy! (-> spad fov-src) (-> spad fov-dest))
(vector-! (-> spad fov-dest)
(-> inverse-rotation vector 2)
(vector+! (-> spad fov-dest) (-> spad fov-vert) (-> spad fov-horz)))
(vector-normalize! (-> spad fov-dest) 1.0)
(camera-fov-draw (-> spad fov-src) (-> spad fov-dest) origin (meters 1) (meters 5) color)
(vector-copy! (-> spad fov-src) (-> spad fov-dest))
(vector-! (-> spad fov-dest)
(-> inverse-rotation vector 2)
(vector-! (-> spad fov-dest) (-> spad fov-vert) (-> spad fov-horz)))
(vector-normalize! (-> spad fov-dest) 1.0)
(camera-fov-draw (-> spad fov-src) (-> spad fov-dest) origin (meters 1) (meters 5) color)
(vector-copy! (-> spad fov-src) (-> spad fov-dest))
(vector+! (-> spad fov-dest)
(-> inverse-rotation vector 2)
(vector+! (-> spad fov-dest) (-> spad fov-vert) (-> spad fov-horz)))
(vector-normalize! (-> spad fov-dest) 1.0)
(camera-fov-draw (-> spad fov-src) (-> spad fov-dest) origin (meters 1) (meters 5) color)
(none)))
(defmethod print-nth-point ((this tracking-spline) (point-index int))
"Print one breadcrumb with markers for the used head,
next-to-last point, and end point."
(if (= point-index (-> this used-point)) (format 0 "u") (format 0 " "))
(if (= point-index (-> this next-to-last-point)) (format 0 "n") (format 0 " "))
(if (= point-index (-> this end-point)) (format 0 "e") (format 0 " "))
(if (= point-index -134250495)
(format 0 " ~D~%" point-index)
(format 0
" ~D ~M ~M ~M~%"
point-index
(-> this point point-index position x)
(-> this point point-index position y)
(-> this point point-index position z)))
0
(none))
(defmethod print-all-points ((this tracking-spline))
"Print every breadcrumb in the used chain, followed by
the chain terminator."
(let ((point-index (-> this used-point)))
(while (!= point-index -134250495)
(print-nth-point this point-index)
(set! point-index (-> this point point-index next)))
(print-nth-point this point-index))
0
(none))
(defmethod debug-draw ((this tracking-spline))
"Draw the used breadcrumb chain, the endpoints of the current
sampling window, and the trail correction applied to the last output."
(let ((point-index (-> this used-point))
(next-point-index (-> this point (-> this used-point) next)))
(let ((sample-position (new 'stack-no-clear 'vector)))
(when (!= next-point-index -134250495)
(sample-point! this 0.0 sample-position (the-as tracking-spline-sampler #f))
(camera-cross (new 'static 'vector :y 1024.0)
(new 'static 'vector :z 1024.0)
sample-position
(new 'static 'vector4w :x #xff :w #x80)
(meters 0.25))
(sample-point! this (-> this sample-len) sample-position (the-as tracking-spline-sampler #f))
(camera-cross (new 'static 'vector :y 1024.0)
(new 'static 'vector :z 1024.0)
sample-position
(new 'static 'vector4w :x #xff :w #x80)
(meters 0.25))))
(while (!= next-point-index -134250495)
(camera-line (-> this point point-index position)
(-> this point next-point-index position)
(new 'static 'vector4w :x #x80 :y #x80 :z #x80 :w #x80))
(set! point-index next-point-index)
(set! next-point-index (-> this point next-point-index next))))
(let ((corrected-move (new 'stack-no-clear 'vector)))
(camera-line (-> this debug-out-position) (-> this debug-old-position) (new 'static 'vector4w :x #xff :y #xff :w #x80))
(vector-! corrected-move (-> this debug-out-position) (-> this debug-old-position))
(apply-trail-correction! this corrected-move (-> this debug-last-point))
(camera-line-rel (-> this debug-old-position) corrected-move (new 'static 'vector4w :x #xff :z #xff :w #x80)))
0
(none))
(defun debug-euler ((scratch camera-slave))
"Convert the camera rotation matrix to euler angles and back and report whether
any component differs by more than 0.001."
(let ((angles (new 'stack-no-clear 'euler-angles))
(reconstructed (new 'stack-no-clear 'matrix)))
(matrix->eul angles (-> scratch tracking inv-mat) 21)
(format *stdcon* "euler angles x ~R y ~R z ~R~%" (-> angles x) (-> angles y) (-> angles z))
(format *stdcon*
"~f ~f ~f ~f~%"
(-> scratch tracking inv-mat vector 0 x)
(-> scratch tracking inv-mat vector 0 y)
(-> scratch tracking inv-mat vector 0 z)
(-> scratch tracking inv-mat vector 0 w))
(format *stdcon*
"~f ~f ~f ~f~%"
(-> scratch tracking inv-mat vector 1 x)
(-> scratch tracking inv-mat vector 1 y)
(-> scratch tracking inv-mat vector 1 z)
(-> scratch tracking inv-mat vector 1 w))
(format *stdcon*
"~f ~f ~f ~f~%"
(-> scratch tracking inv-mat vector 2 x)
(-> scratch tracking inv-mat vector 2 y)
(-> scratch tracking inv-mat vector 2 z)
(-> scratch tracking inv-mat vector 2 w))
(format *stdcon*
"~f ~f ~f ~f~%"
(-> scratch tracking inv-mat vector 3 x)
(-> scratch tracking inv-mat vector 3 y)
(-> scratch tracking inv-mat vector 3 z)
(-> scratch tracking inv-mat vector 3 w))
(eul->matrix reconstructed angles)
(format *stdcon*
"~f ~f ~f ~f~%"
(-> reconstructed vector 0 x)
(-> reconstructed vector 0 y)
(-> reconstructed vector 0 z)
(-> reconstructed vector 0 w))
(format *stdcon*
"~f ~f ~f ~f~%"
(-> reconstructed vector 1 x)
(-> reconstructed vector 1 y)
(-> reconstructed vector 1 z)
(-> reconstructed vector 1 w))
(format *stdcon*
"~f ~f ~f ~f~%"
(-> reconstructed vector 2 x)
(-> reconstructed vector 2 y)
(-> reconstructed vector 2 z)
(-> reconstructed vector 2 w))
(format *stdcon*
"~f ~f ~f ~f~%"
(-> reconstructed vector 3 x)
(-> reconstructed vector 3 y)
(-> reconstructed vector 3 z)
(-> reconstructed vector 3 w))
(if (or (< 0.001 (fabs (- (-> scratch tracking inv-mat vector 0 x) (-> reconstructed vector 0 x))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 0 y) (-> reconstructed vector 0 y))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 0 z) (-> reconstructed vector 0 z))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 0 w) (-> reconstructed vector 0 w))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 1 x) (-> reconstructed vector 1 x))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 1 y) (-> reconstructed vector 1 y))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 1 z) (-> reconstructed vector 1 z))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 1 w) (-> reconstructed vector 1 w))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 2 x) (-> reconstructed vector 2 x))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 2 y) (-> reconstructed vector 2 y))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 2 z) (-> reconstructed vector 2 z))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 2 w) (-> reconstructed vector 2 w))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 3 x) (-> reconstructed vector 3 x))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 3 y) (-> reconstructed vector 3 y))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 3 z) (-> reconstructed vector 3 z))))
(< 0.001 (fabs (- (-> scratch tracking inv-mat vector 3 w) (-> reconstructed vector 3 w)))))
(format *stdcon* "different~%")
(format *stdcon* "same~%")))
(none))
(defun bike-cam-limit ((input meters))
"Return a cosine camera limit that rises from zero to one as the nonnegative
scaled input approaches 8192, and remains one beyond that range."
(let* ((scaled-input (* 10012.444 input))
(clamped-input (fmax 0.0 scaled-input)))
(if (< clamped-input 8192.0)
(* (/ 1.0 (- 1.0 (cos (degrees 120)))) (+ (- (cos (degrees 120))) (cos (* 2.6666667 (- 8192.0 clamped-input)))))
1.0)))
(defun camera-slave-debug ((slave camera-slave))
"Draw the active camera-slave frustum, tracking basis and follow point,
target body spheres, spline trail, and state-specific string, circular, or
authored-spline geometry when camera marks are enabled."
(when *display-camera-marks*
(let ((half-fov (/ (-> *camera-combiner* fov) 2)))
(camera-fov-frame (-> *camera-combiner* inv-camera-rot)
(camera-pos)
half-fov
0.75
1.0
(new 'static 'vector4w :z #xff :w #x80)))
(cond
((= (-> slave blend-to-type) (camera-blend-to-type combiner-tracked))
(let ((half-fov (/ (-> slave fov) 2)))
(camera-fov-frame (-> *camera-combiner* tracking inv-mat)
(-> slave trans)
half-fov
0.75
1.0
(new 'static 'vector4w :y #xff :w #x80))))
(else
(let ((half-fov (/ (-> slave fov) 2)))
(camera-fov-frame (-> slave tracking inv-mat) (-> slave trans) half-fov 0.75 1.0 (new 'static 'vector4w :y #xff :w #x80)))))
(debug-draw (-> slave position-spline))
(let ((line-end (new-stack-vector0)))
(let ((line-start (new-stack-vector0)))
(new-stack-matrix0)
(cond
((or (= (-> slave next-state name) 'cam-fixed)
(or (= (-> slave next-state name) 'cam-eye)
(= (-> slave next-state name) 'cam-point-watch)
(= (-> slave next-state name) 'cam-free-floating)
(= (-> slave next-state name) 'cam-orbit)))
(vector+float*! line-end (-> slave trans) (-> *camera* local-down) (meters 1))
(camera-line (-> slave trans) line-end (new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80)))
((= (-> slave blend-to-type) (camera-blend-to-type combiner-tracked))
(camera-line (-> *camera-combiner* tracking follow-pt)
(-> slave trans)
(new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80))
(vector+float*! line-end (-> *camera-combiner* tracking follow-pt) (-> *camera* local-down) (meters 1))
(camera-line (-> *camera-combiner* tracking follow-pt) line-end (new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80)))
(else
(camera-line (-> slave tracking follow-pt) (-> slave trans) (new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80))
(vector+float*! line-end (-> slave tracking follow-pt) (-> *camera* local-down) (meters 1))
(camera-line (-> slave tracking follow-pt) line-end (new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80))))
(vector-copy! line-start (-> slave trans))
(cond
((= (-> slave blend-to-type) (camera-blend-to-type combiner-tracked))
(vector+float*! line-end line-start (-> *camera-combiner* tracking inv-mat vector 0) (meters 0.5))
(camera-line line-start line-end (new 'static 'vector4w :x #xff :w #x80))
(vector+float*! line-end line-start (-> *camera-combiner* tracking inv-mat vector 1) (meters 0.5))
(camera-line line-start line-end (new 'static 'vector4w :y #xff :w #x80))
(vector+float*! line-end line-start (-> *camera-combiner* tracking inv-mat vector 2) (meters 0.5))
(camera-line line-start line-end (new 'static 'vector4w :z #xff :w #x80)))
(else
(vector+float*! line-end line-start (-> slave tracking inv-mat vector 0) (meters 0.5))
(camera-line line-start line-end (new 'static 'vector4w :x #xff :w #x80))
(vector+float*! line-end line-start (-> slave tracking inv-mat vector 1) (meters 0.5))
(camera-line line-start line-end (new 'static 'vector4w :y #xff :w #x80))
(vector+float*! line-end line-start (-> slave tracking inv-mat vector 2) (meters 0.5))
(camera-line line-start line-end (new 'static 'vector4w :z #xff :w #x80)))))
(vector--float*! line-end (-> *camera* tpos-curr) (-> *camera* local-down) (-> *camera* foot-offset))
(camera-sphere line-end (meters 0.125) (new 'static 'vector4w :y #xff :w #x80))
(vector--float*! line-end (-> *camera* tpos-curr) (-> *camera* local-down) (-> *camera* head-offset))
(camera-sphere line-end (meters 0.125) (new 'static 'vector4w :y #xff :w #x80)))
(cond
((= (-> slave next-state name) 'cam-string)
(camera-sphere (-> slave desired-pos) (meters 0.125) (new 'static 'vector4w :z #xff :w #x80))
(camera-line-rel (-> *camera* tpos-curr-adj) (-> slave view-flat) (new 'static 'vector4w :z #xff :w #x80))
(camera-line (-> slave string-trans)
(-> *camera* target-spline point (-> slave los-tgt-spline-pt) position)
(new 'static 'vector4w :y #xff :w #x80))
(camera-line (-> slave los-last-pos)
(-> *camera* target-spline point (-> slave los-tgt-spline-pt) position)
(new 'static 'vector4w :x #xff :w #x80)))
((= (-> slave next-state name) 'cam-circular)
(let ((pivot-axis-end (new-stack-vector0)))
(vector+float*! pivot-axis-end (-> slave pivot-pt) (-> *camera* local-down) (meters 1))
(camera-line (-> slave pivot-pt) pivot-axis-end (new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80)))
(camera-line (-> slave pivot-pt) (-> slave trans) (new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80)))
((= (-> slave next-state name) 'cam-spline)
(let ((path-data (new 'stack 'curve))
(path-offset (res-lump-struct (-> slave cam-entity) 'spline-offset vector)))
(if (not (the-as structure path-offset))
(set! path-offset (new-stack-vector0)))
(when (get-curve-data! (-> slave cam-entity) path-data 'campath 'campath-k -1000000000.0)
(let ((previous-point (new-stack-vector0))
(current-point (new-stack-vector0))
(authored-line (res-lump-data (-> slave cam-entity) 'campoints pointer :time 1.0)))
(curve-get-pos! current-point 0.0 path-data)
(vector+! current-point current-point path-offset)
(dotimes (i 8)
(vector-copy! previous-point current-point)
(curve-get-pos! current-point (* 0.125 (the float (+ i 1))) path-data)
(vector+! current-point current-point path-offset)
(camera-line previous-point current-point (new 'static 'vector4w :x #xff :y #xff :w #x80)))
(dotimes (i (-> path-data num-cverts))
(vector+! previous-point (-> path-data cverts i) path-offset)
(vector+! current-point (-> path-data cverts (mod (+ i 1) (-> path-data num-cverts))) path-offset)
(camera-line previous-point current-point (new 'static 'vector4w :y #xff :z #xff :w #x80)))
(if authored-line
(camera-line (the-as vector (&+ authored-line 0))
(the-as vector (&+ authored-line 16))
(new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80))
(camera-line (-> path-data cverts 0)
(-> path-data cverts (+ (-> path-data num-cverts) -1))
(new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80)))))))))
0
(none))
(defun master-draw-coordinates ((direction vector))
"Draw RGB world axes in front of the camera combiner. If direction is
non-null, also draw its normalized direction in yellow."
(let ((axis-end (new-stack-vector0))
(axis-origin (new-stack-vector0)))
(let ((rotation (new-stack-matrix0)))
(set-vector! axis-end 0.0 (meters 2) 0.0 1.0)
(matrix-rotate-yxz! rotation axis-end))
(vector+! axis-origin
(-> *camera-combiner* trans)
(vector-normalize-copy! axis-origin (-> *camera-combiner* inv-camera-rot vector 2) (meters 6)))
(let ((axis-destination axis-end)
(origin-copy axis-origin)
(axis-offset axis-end))
(set-vector! axis-offset (meters 1) 0.0 0.0 1.0)
(vector+! axis-destination origin-copy axis-offset))
(add-debug-line #t (bucket-id debug-no-zbuf) axis-origin axis-end (new 'static 'rgba :r #xff :a #x80) #f (the-as rgba -1))
(let ((axis-destination2 axis-end)
(origin-copy2 axis-origin)
(axis-offset2 axis-end))
(set-vector! axis-offset2 0.0 (meters 1) 0.0 1.0)
(vector+! axis-destination2 origin-copy2 axis-offset2))
(add-debug-line #t (bucket-id debug-no-zbuf) axis-origin axis-end (new 'static 'rgba :g #xff :a #x80) #f (the-as rgba -1))
(let ((axis-destination3 axis-end)
(origin-copy3 axis-origin)
(axis-offset3 axis-end))
(set-vector! axis-offset3 0.0 0.0 (meters 1) 1.0)
(vector+! axis-destination3 origin-copy3 axis-offset3))
(add-debug-line #t (bucket-id debug-no-zbuf) axis-origin axis-end (new 'static 'rgba :b #xff :a #x80) #f (the-as rgba -1))
(when direction
(vector-copy! axis-end direction)
(vector-normalize! axis-end (meters 1))
(vector+! axis-end axis-origin axis-end)
(add-debug-line #t
(bucket-id debug-no-zbuf)
axis-origin
axis-end
(new 'static 'rgba :r #x7f :g #x7f :a #x80)
#f
(the-as rgba -1))))
0
(none))
(deftype cam-collision-record (structure)
((pos vector :inline)
(vel vector :inline)
(desired-pos vector :inline)
(cam-tpos-cur vector :inline)
(cam-tpos-old vector :inline)
(view-flat vector :inline)
(string-min-val vector :inline)
(string-max-val vector :inline)
(view-off vector :inline)
(min-z-override float)
(string-push-z float)
(view-off-param float)
(frame int32)
(iteration int32)
(move-type symbol)))
(deftype cam-collision-record-array (inline-array-class)
((data cam-collision-record :inline :dynamic)))
(set! (-> cam-collision-record-array heap-base) (the-as uint 176))
(define *cam-collision-record-first* 0)
(define *cam-collision-record-last* 0)
(define *cam-collision-record-show* 0)
(define *cam-collision-record* (new 'debug 'cam-collision-record-array 600))
(defun cam-collision-record-save ((position vector) (velocity vector) (iteration int) (move-kind symbol) (slave camera-slave))
"When collision history recording is enabled, append one camera movement
attempt to the 600-entry ring, including collision parameters and the
camera-slave state needed to reproduce and inspect the probe."
(when *record-cam-collide-history*
(let ((record (-> *cam-collision-record* data *cam-collision-record-last*)))
(vector-copy! (-> record pos) position)
(vector-copy! (-> record vel) velocity)
(vector-copy! (-> record view-flat) (-> slave view-flat))
(vector-copy! (-> record desired-pos) (-> slave desired-pos))
(vector-copy! (-> record cam-tpos-cur) (-> *camera* tpos-curr-adj))
(vector-copy! (-> record cam-tpos-old) (-> *camera* tpos-old-adj))
(vector-copy! (-> record string-min-val) (-> slave string-min-val))
(vector-copy! (-> record string-max-val) (-> slave string-max-val))
(vector-copy! (-> record view-off) (-> slave view-off))
(set! (-> record frame) (the-as int (current-time)))
(set! (-> record iteration) iteration)
(set! (-> record move-type) move-kind)
(set! (-> record min-z-override) (-> slave min-z-override))
(set! (-> record string-push-z) (-> *camera* string-push-z))
(set! (-> record view-off-param) (-> slave view-off-param)))
(set! *cam-collision-record-show* *cam-collision-record-last*)
(set! *cam-collision-record-last* (+ *cam-collision-record-last* 1))
(set! *cam-collision-record-last* (mod *cam-collision-record-last* 600))
(when (= *cam-collision-record-last* *cam-collision-record-first*)
(set! *cam-collision-record-first* (+ *cam-collision-record-first* 1))
(set! *cam-collision-record-first* (mod *cam-collision-record-first* 600))))
0
(none))
(defun cam-collision-record-step ((delta int))
"Move the selected collision-history index by delta, wrapping within all 600
storage slots."
(set! *cam-collision-record-show* (+ *cam-collision-record-show* delta))
(while (>= *cam-collision-record-show* 600)
(set! *cam-collision-record-show* (+ *cam-collision-record-show* -600)))
(while (< *cam-collision-record-show* 0)
(set! *cam-collision-record-show* (+ *cam-collision-record-show* 600)))
0
(none))
(defun cam-collision-record-draw ()
"Select a collision-history entry with the d-pad, print its saved camera
state, repeat its line-sphere probe, and draw the movement, hit triangle,
intersection direction, and normal."
(cond
((cpad-pressed? 0 down)
(cam-collision-record-step 1))
((cpad-hold? 0 right)
(cam-collision-record-step 1))
((cpad-pressed? 0 up)
(cam-collision-record-step -1))
((cpad-hold? 0 left)
(cam-collision-record-step -1)))
(let ((record (-> *cam-collision-record* data *cam-collision-record-show*))
(movement-color (new 'stack 'vector4w))
(collision-color (new 'stack 'vector4w)))
(format *stdcon* "move-type ~A~%" (-> record move-type))
(cond
((= (-> record move-type) 'normal)
(set! (-> movement-color x) 255)
(set! (-> movement-color y) 255))
((= (-> record move-type) 'jump)
(set! (-> movement-color x) 255))
((= (-> record move-type) 'no-hit)
(set! (-> movement-color y) 255))
(else
(set! (-> movement-color z) 255)))
(set! (-> movement-color w) 128)
(set-vector! collision-color 127 127 127 128)
(camera-line-rel-len (-> record pos) (-> record vel) (fmax 81.92 (vector-length (-> record vel))) movement-color)
(let* ((hit (new 'stack-no-clear 'collide-tri-result))
(travel (fill-and-probe-using-line-sphere *collide-cache*
(-> record pos)
(-> record vel)
(-> *CAMERA-bank* collide-move-rad)
(collide-kind background)
(the-as process #f)
hit
(new 'static 'pat-surface :nocamera #x1)))
(toward-start (new 'stack-no-clear 'vector)))
(format *stdcon* "frame ~D iteration ~D travel ~f~%" (-> record frame) (-> record iteration) travel)
(format *stdcon*
"mzo ~M psz ~M vop ~f~%"
(-> record min-z-override)
(-> record string-push-z)
(-> record view-off-param))
(format *stdcon* "pos ~M ~M ~M~%" (-> record pos x) (-> record pos y) (-> record pos z))
(format *stdcon* "vel ~M ~M ~M~%" (-> record vel x) (-> record vel y) (-> record vel z))
(format *stdcon* "des ~M ~M ~M~%" (-> record desired-pos x) (-> record desired-pos y) (-> record desired-pos z))
(format *stdcon* "flt ~M ~M ~M~%" (-> record view-flat x) (-> record view-flat y) (-> record view-flat z))
(format *stdcon* "cur ~M ~M ~M~%" (-> record cam-tpos-cur x) (-> record cam-tpos-cur y) (-> record cam-tpos-cur z))
(format *stdcon* "old ~M ~M ~M~%" (-> record cam-tpos-old x) (-> record cam-tpos-old y) (-> record cam-tpos-old z))
(format *stdcon*
"smn ~M ~M ~M~%"
(-> record string-min-val x)
(-> record string-min-val y)
(-> record string-min-val z))
(format *stdcon*
"smx ~M ~M ~M~%"
(-> record string-max-val x)
(-> record string-max-val y)
(-> record string-max-val z))
(format *stdcon* "vof ~M ~M ~M~%" (-> record view-off x) (-> record view-off y) (-> record view-off z))
(when (>= travel 0.0)
(camera-line (-> hit vertex 0) (-> hit vertex 1) movement-color)
(camera-line (-> hit vertex 1) (-> hit vertex 2) movement-color)
(camera-line (-> hit vertex 2) (-> hit vertex 0) movement-color)
(vector-! toward-start (-> record pos) (-> hit intersect))
(vector-normalize! toward-start 1.0)
(camera-line-rel-len (-> hit intersect) toward-start (-> *CAMERA-bank* collide-move-rad) collision-color)
(camera-line-rel-len (-> hit intersect) (-> hit normal) (-> *CAMERA-bank* collide-move-rad) collision-color))))
0
(none))
(defun camera-master-debug ((cam-master camera-master))
"Draw the camera-master diagnostics selected by the global display flags:
alternate-camera geometry, last attacker, saved performance statistics,
collision history, target spline, coordinate axes, and collision triangles."
(when *display-cam-other*
(let ((half-fov (/ (-> *camera-other-fov* data) 2)))
(camera-fov-frame *camera-other-matrix* *camera-other-trans* half-fov 0.75 1.0 (new 'static 'vector4w :x #xff :w #x80)))
(camera-line *camera-other-trans* *camera-other-root* (new 'static 'vector4w :x #xff :y #xff :z #xff :w #x80))
(let ((axis-end (new 'stack-no-clear 'vector))
(axis-origin *camera-other-trans*))
(vector+float*! axis-end axis-origin (-> *camera-other-matrix* vector 0) (meters 0.5))
(camera-line axis-origin axis-end (new 'static 'vector4w :x #xff :w #x80))
(vector+float*! axis-end axis-origin (-> *camera-other-matrix* vector 1) (meters 0.5))
(camera-line axis-origin axis-end (new 'static 'vector4w :y #xff :w #x80))
(vector+float*! axis-end axis-origin (-> *camera-other-matrix* vector 2) (meters 0.5))
(camera-line axis-origin axis-end (new 'static 'vector4w :z #xff :w #x80))))
(when *display-camera-last-attacker*
(format *stdcon* "last attacker '")
(let ((last-attacker (handle->process (-> last-try-to-look-at-data who))))
(if last-attacker
(format *stdcon* "~S" (-> last-attacker name))))
(format *stdcon* "'~%"))
(when *display-camera-old-stats*
(format *stdcon*
"old ~S cpu ~D old vu ~D (go to menu before comparing)~%"
*camera-old-level*
*camera-old-cpu*
*camera-old-vu*)
(format *stdcon* "old tfrag-mem ~D~%" (sar *camera-old-tfrag-bytes* 10))
(format *stdcon* "~S~%" *camera-old-stat-string-tfrag-near*)
(format *stdcon* "~S~%" *camera-old-stat-string-tfrag*)
(format *stdcon* "~S~%" *camera-old-stat-string-total*))
(if *display-cam-collide-history*
(cam-collision-record-draw))
(if *display-cam-master-marks*
(debug-draw (-> cam-master target-spline)))
(if *display-xyz-axes*
(master-draw-coordinates (the-as vector #f)))
(cam-debug-draw-tris)
0
(none))
(defun debug-set-camera-pos-rot! ((position vector) (inverse-rotation matrix))
"Move the live camera combiner to position and inverse-rotation. Temporarily
enter the free-floating state so the transform can be replaced, then return
to the fixed state. Return position."
(when (and *camera* *camera-combiner*)
(send-event *camera* 'change-state cam-free-floating 0)
(vector-copy! (-> *camera-combiner* trans) position)
(matrix-copy! (-> *camera-combiner* inv-camera-rot) inverse-rotation)
(send-event *camera* 'change-state cam-fixed 0))
position)
(defun external-cam-reset! ()
"Reset the external math camera to the current combiner transform,
or to the identity at the origin when the combiner is unavailable."
(vector-reset! (-> *math-camera* trans))
(matrix-identity! (-> *math-camera* inv-camera-rot))
(when *camera-combiner*
(matrix-copy! (-> *math-camera* inv-camera-rot) (-> *camera-combiner* inv-camera-rot))
(vector-copy! (-> *math-camera* trans) (-> *camera-combiner* trans)))
0
(none))