;; note that xtlang mmmul is pre-multiplied! (not post as GLSL)
(bind-func xtm_unproject
(lambda (pt_in:float* pt_out:float* model view projection)
(let ((x (pref pt_in 0))
(y (pref pt_in 1))
(z (pref pt_in 2))
(vp_x (i32tof xtm_render_x)) ;; viewport x
(vp_y (i32tof xtm_render_y)) ;; viewport y
(vp_w (i32tof xtm_render_w))
(vp_h (i32tof xtm_render_h))
(tmp:float* (salloc 16))
(tmp2:float* (salloc 16))
(imvp:float* (salloc 16))
(vec:float* (salloc 4))
(out:float* (salloc 4)))
(mmmul model view tmp)
(mmmul tmp projection imvp)
(invert_matrix imvp)
(pset! vec 0 (- (* (/ x vp_w) 2.0) 1.0))
(pset! vec 1 (- (* (/ y vp_h) 2.0) 1.0))
(pset! vec 2 (- (* 2.0 z) 1.0))
(pset! vec 3 1.0)
(mmmul vec 1 4 imvp 4 4 out)
(if (= (pref out 3) 0.0)
void
(begin
(vsmul out (/ 1.0 (pref out 3)) 4 pt_out) ;; make sure W is normalised!
void)))))