;;-*-Lisp-*- (in-package goal) ;; This file demonstrates how to use the debug draw. ;; To run this: #| (make-group "iso") ;; build the game (lt) ;; connect to the runtime (lg) ;; have the runtime load the game engine (test-play) ;; start the game loop (ml "goal_src/examples/debug-draw-example.gc") ;; build and load this file. ;; to get control of camera from keyboard (kill-test-procs) (launch-wasd-process) ;; you can turn on actor marks (full) or visibilty boxes in the debug menu. |# (defun hack-update-camera ((location vector) (inv-rot matrix)) "Debugging function to set the camera's position and orientation" ;; update to compute the perspective matrix. (update-math-camera *math-camera* (-> *setting-control* current video-mode) (-> *setting-control* current aspect-ratio) ) ;; copy the input rotation (matrix-copy! (-> *math-camera* inv-camera-rot) inv-rot) ;; inverse of rotation matrix matrix is its transpose (matrix-transpose! (-> *math-camera* camera-rot) (-> *math-camera* inv-camera-rot)) ;; fake some value here (set! (-> *math-camera* fov-correction-factor) 1.0) ;; do the math (set! (-> *math-camera* trans quad) (-> location quad)) (let ((cam-temp (-> *math-camera* camera-temp)) (cam-rot (-> *math-camera* camera-rot)) (inv-cam-rot (-> *math-camera* inv-camera-rot)) (cam-trans (-> *math-camera* trans)) ) (let ((rotated-trans (new-stack-vector0))) (set! (-> rotated-trans x) (- (-> cam-trans x))) (set! (-> rotated-trans y) (- (-> cam-trans y))) (set! (-> rotated-trans z) (- (-> cam-trans z))) (set! (-> rotated-trans w) 1.0) (vector-matrix*! rotated-trans rotated-trans cam-rot) (set! (-> cam-rot vector 3 quad) (-> rotated-trans quad)) ) (matrix*! cam-temp cam-rot (-> *math-camera* perspective)) (set! (-> inv-cam-rot vector 3 quad) (-> cam-trans quad)) ) (none) ) (defun test-function ((iter int)) "This function draws the debug stuff. You can edit this, then reload this file to play with it." ;; val will increase from 0 to 1, then reset back to 0. (let* ((frame (the float (mod (* 4 iter) 1600))) (val (/ frame 1600.0))) (format *stdcon* "~0kval ~f~%" val) ;; orbit the camera around in a circle with radius 5 m. (let* ((rad (meters 5.0)) (x (* rad (sin (* (degrees 360.0) val)))) (z (* rad (cos (* (degrees 360.0) val)))) (cam-pos (new 'stack 'vector)) (cam-inv-rot (new 'stack 'matrix)) ) ;; this matrix will look directly at the origin... (set! (-> cam-pos x) x) (set! (-> cam-pos z) z) (set! (-> cam-pos y) (meters 2.)) (forward-down->inv-matrix cam-inv-rot cam-pos (new 'static 'vector :y 1.0)) ;; if the camera is here. (set! (-> cam-pos x) (- 0. x)) (set! (-> cam-pos z) (- 0. z)) (set! (-> cam-pos y) (meters -2.)) (hack-update-camera cam-pos cam-inv-rot) ;; create some test points (let ((p0 (new 'static 'vector :x (meters .8) :y (meters .2) :z (meters 2.0))) (p1 (new 'static 'vector :x (meters .3) :y (meters .3) :z (meters 2.5))) (p2 (new 'static 'vector :x (meters .5) :y (meters .7) :z (meters 1.5))) ) ;;(add-debug-point #t (bucket-id debug-draw0) (new 'static 'vector)) (add-debug-x #t (bucket-id debug-draw0) (new 'static 'vector) (new 'static 'rgba :g #x80 :a #x80)) (add-debug-box #t (bucket-id debug-draw0) p0 p2 (new 'static 'rgba :b #x80 :a #x80)) (add-debug-flat-triangle #t (bucket-id debug-draw0) p0 p1 p2 (new 'static 'rgba :r #x80)) (add-debug-text-3d #t (bucket-id debug-draw0) "triangle!" p0 (font-color yellow-green) (the vector2h #f)) (add-debug-sphere #t (bucket-id debug-draw0) p2 (meters 0.5) (new 'static 'rgba :r #x80)) ) ) ;; these also work ;; (draw-end-credits (the int frame)) ;; (draw-title-credits val) ) (none) ) (define *wasd-camera-transform* (new 'global 'transform)) (defun wasd-camera-update () (let ((local-trans (new-stack-vector0)) (trans *wasd-camera-transform*) (pad-idx 0)) ;; circle/square move camera relative x (left and right) (set! (-> local-trans x) (cond ((logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons circle)) -80.0 ) ((logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons square)) 80.0 ) (else 0.0 ) ) ) ;; no way to move camera relative y (up/down) (set! (-> local-trans y) 0.0) ;; in and out movement (set! (-> local-trans z) (cond ((logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons down)) -800.0 ) ((logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons up)) 800.0 ) (else 0.0 ) ) ) (set! (-> local-trans w) 1.0) ;; rotate this into world frame (let ((inv-cam-rot (new-stack-vector0)) (cam-rot-mat (new-stack-matrix0))) ;; unused. (vector-negate! inv-cam-rot (-> trans rot)) ;; convert rotation to rotation matrix. (matrix-rotate-zyx! cam-rot-mat (-> trans rot)) ;; and rotate the translation. (vector-matrix*! local-trans local-trans cam-rot-mat) ) ;; and update the transform (vector+! (-> trans trans) (-> trans trans) local-trans) ;; don't forget to fix w. (set! (-> trans trans w) 1.0) ;; global translation (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons l1)) (set! (-> trans trans y) (+ 800.0 (-> trans trans y))) ) (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons r1)) (set! (-> trans trans y) (+ -800.0 (-> trans trans y))) ) ;; rotation (don't allow camera roll) (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons x)) (set! (-> trans rot x) (+ 54.13336 (-> trans rot x))) ) (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons triangle)) (set! (-> trans rot x) (+ -54.13336 (-> trans rot x))) ) (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons left)) (set! (-> trans rot y) (+ 546.13336 (-> trans rot y))) ) (if (logtest? (-> *cpad-list* cpads pad-idx button0-abs 0) (pad-buttons right)) (set! (-> trans rot y) (+ -546.13336 (-> trans rot y))) ) (set! (-> trans scale x) 1.) (set! (-> trans scale y) 1.) (set! (-> trans scale z) 1.) (set! (-> trans scale w) 1.) ) ) (defun launch-test-process () "Call this to launch a process that draws the debug demo" (let ((proc (get-process *nk-dead-pool* process 1024))) (activate proc *active-pool* 'test *kernel-dram-stack*) (run-next-time-in-process proc (lambda () (let ((iter 0)) (while #t (test-function iter) (suspend) (+! iter 1) ) ) ) ) proc) ) (defun launch-wasd-process () "Launch a process to control the camera with keyboard. Note that the test process above also controls the camera and should be killed first. For example, after loading this file, do (kill-test-procs) (launch-wasd-process)" (let ((proc (get-process *nk-dead-pool* process 1024))) (activate proc *active-pool* 'test *kernel-dram-stack*) (set! (-> *wasd-camera-transform* trans y) (meters 4.0)) (run-next-time-in-process proc (lambda () (let ((iter 0)) (while #t (wasd-camera-update) (let ((mat (new-stack-matrix0))) (transform-matrix-calc! *wasd-camera-transform* mat) (set! (-> mat data 3) 0.) (set! (-> mat data 7) 0.) (set! (-> mat data 11) 0.) (set! (-> mat data 12) 0.) (set! (-> mat data 13) 0.) (set! (-> mat data 14) 0.) (set! (-> mat data 15) 1.) ;;(matrix-transpose! mat mat) (hack-update-camera (-> *wasd-camera-transform* trans) mat) ) (suspend) (+! iter 1) ) ) ) ) proc) ) ;; This will spawn a process the first time this file is loaded (define-perm *test-process* process (launch-test-process)) (defun kill-test-procs () "Kill all processes started by launch-test-process" (kill-by-name "test" *active-pool*) ) (set! *display-profile* #t)