;; this is similar to gl_look_at
;; but returns a suitable VIEW matrix
;;
;; same as fill_view_matrix but
;; instead of a target:position
;; we provide a dir:vector
(bind-func fill_view_matrix_dir
(let ((orientation_matrix:float* (alloc 16))
(translation_matrix:float* (alloc 16))
(vz:float* (alloc 3)) ;; vector z axes
(vy:float* (alloc 3)) ;; vector y axes
(vx:float* (alloc 3)) ;; vector x axes
(vtmp:float* (alloc 3)))
(lambda (matrix:float* vEye:float* vDir vUp)
(let ((i 0))
(vnormalise vDir 3 vz)
(vnormalise vUp 3 vtmp)
(vvcross vtmp vz vy) ;; use vy as a tmp here
(vnormalise vy 3 vx)
(vvcross vz vx vy)
;; (pfill! mat
;; (pref vx 0) (pref vx 1) (pref vx 2) 0.0
;; (pref vy 0) (pref vy 1) (pref vy 2) 0.0
;; (pref vz 0) (pref vz 1) (pref vz 2) 0.0
;; (pref vEye 0) (pref vEye 1) (pref vEye 2) 1.0)
;; (minverse mat 4 matrix)
(pfill! orientation_matrix
(pref vx 0) (pref vy 0) (pref vz 0) 0.0
(pref vx 1) (pref vy 1) (pref vz 1) 0.0
(pref vx 2) (pref vy 2) (pref vz 2) 0.0
0.0 0.0 0.0 1.0)
(pfill! translation_matrix
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
(* -1.0 (pref vEye 0)) (* -1.0 (pref vEye 1)) (* -1.0 (pref vEye 2)) 1.0)
;; (minverse mat 4 matrix)
(mmmul translation_matrix orientation_matrix matrix)
void))))