-
Notifications
You must be signed in to change notification settings - Fork 24
/
transform.lisp
123 lines (99 loc) · 3.55 KB
/
transform.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
;;;; transform.lisp
;;;; Please see the licence.txt for the CLinch
(in-package #:clinch)
(defconstant +pi+ (coerce pi 'single-float)
"A single-float version of pi.")
(defmacro ensure-float (x)
"Coerce a number to a single-float."
`(coerce ,x 'single-float))
(defmacro degrees->radians (degrees)
"Converts degrees to radians."
`(coerce (* 2 pi (/ ,degrees 360)) 'single-float))
(defmacro d->r (degrees)
"Converts degrees to radians."
`(degrees->radians ,degrees))
(defmacro radians->degrees (radians)
"Converts radians to degrees."
`(coerce (* 180 (/ ,radians pi)) 'single-float))
(defmacro r->d (radians)
"Converts radians to degrees."
`(radians->degrees ,radians))
;;; Do I still need this? !!!
(defun make-orthogonal-transform (width height near far)
"Create a raw CFFI orthogonal matrix."
(rtg-math:m! (/ 2 width) 0.0 0.0 0.0
0.0 (/ 2 height) 0.0 0.0
0.0 0.0 (/ -2 (- far near)) (- (/ (+ far near) (- far near)))
0.0 0.0 0.0 1.0))
;;; Do I still need this? !!!
(defun make-frustum-transform (left right bottom top near far)
"Create a raw CFFI frustum matrix."
(let ((a (/ (+ right left) (- right left)))
(b (/ (+ top bottom) (- top bottom)))
(c (- (/ (+ far near) (- far near))))
(d (- (/ (* 2 far near) (- far near)))))
(rtg-math:m! (/ (* 2 near) (- right left)) 0.0 A 0.0
0.0 (/ (* 2 near) (- top bottom)) B 0.0
0.0 0.0 C D
0.0 0.0 -1.0 0.0)))
;;; Do I still need this? !!!
(defun make-perspective-transform (fovy aspect znear zfar)
"Create a raw CFFI perspective matrix."
(let* ((ymax (* znear (tan fovy)))
(xmax (* ymax aspect)))
(make-frustum-transform (- xmax) xmax (- ymax) ymax znear zfar)))
(defun get-point-by-index (points index)
(let ((start (* 3 index)))
(subseq points start (+ 3 start))))
(defun set-point-by-index (points index value)
(loop for x from (* 3 index)
for v across value
do (setf (elt points x) v))
points)
(defun transform-point (p m)
(let ((w (/
(+ (* (elt m 3) (elt p 0))
(* (elt m 7) (elt p 1))
(* (elt m 11) (elt p 2))
(elt m 15)))))
(v! (* w (+ (* (elt m 0) (elt p 0))
(* (elt m 4) (elt p 1))
(* (elt m 8) (elt p 2))
(elt m 12)))
(* w (+ (* (elt m 1) (elt p 0))
(* (elt m 5) (elt p 1))
(* (elt m 9) (elt p 2))
(elt m 13)))
(* w (+ (* (elt m 2) (elt p 0))
(* (elt m 6) (elt p 1))
(* (elt m 10) (elt p 2))
(elt m 14))))))
(defun transform-points (points matrix)
(loop
for i from 0 below (length points) by 3
do (loop
for j across (transform-point (v! (elt points (+ 0 i) )
(elt points (+ 1 i))
(elt points (+ 2 i)))
matrix)
for x from 0
do (setf (elt points (+ i x)) j)))
points)
;;; Do I still need this? !!!
(defun unproject (x y width height inv-transform)
"Unproject from the screen to transform space."
(let* ((new-x (1- (/ (* 2 x) width)))
(new-y (- (1- (/ (* 2 y) height))))
(start (clinch:transform-point (v! new-x new-y 0) inv-transform))
(end (clinch:transform-point (v! new-x new-y 1) inv-transform)))
(values start
(v3:normalize (v3:- end start)))))
;;; Do I still need this? !!!
(defun get-screen-direction (lens-1)
"Gets the direction from the middle of the screen."
(let ((start-of-box (clinch:transform-point (v! 0 0 0)
lens-1))
(end-of-box (clinch:transform-point (v! 0 0 1)
lens-1)))
(values start-of-box
(v3:normalize (v3:- end-of-box start-of-box)))))