2 (in-package :cl-tuples
)
4 (def-tuple-type matrix22
5 :tuple-element-type fast-float
10 (export-tuple-operations matrix22
)
12 (def-tuple-type matrix33
13 :tuple-element-type fast-float
14 :initial-element
0.0f0
15 :elements
(e00 e01 e02
19 (export-tuple-operations matrix33
)
21 (def-tuple-type matrix44
22 :tuple-element-type fast-float
23 :initial-element
0.0f0
24 :elements
(e00 e01 e02 e03
29 (export-tuple-operations matrix44
)
31 (def-tuple-op matrix33-equal
*
32 ((k matrix33
(k00 k01 k02
35 (m matrix33
(m00 m01 m02
40 (= k00 m00
) (= k01 m01
) (= k02 m02
)
41 (= k10 m10
) (= k11 m11
) (= k12 m12
)
42 (= k20 m20
) (= k21 m21
) (= k22 m22
))))
44 (def-tuple-op matrix44-equal
*
45 ((k matrix44
(k00 k01 k02 k03
49 (m matrix44
(m00 m01 m02 m03
55 (= k00 m00
) (= k01 m01
) (= k02 m02
) (= k03 m03
)
56 (= k10 m10
) (= k11 m11
) (= k12 m12
) (= k13 m13
)
57 (= k20 m20
) (= k21 m21
) (= k22 m22
) (= k23 m23
)
58 (= k30 m30
) (= k31 m31
) (= k32 m32
) (= k33 m33
))))
60 ;; TODO: this probably needs to check the TRACE as well, since otherwise
61 ;; it might crash in other functions (e.g. MATRIX33-ANGLE-AXIS*)
62 (def-tuple-op check-rotation-matrix33
*
63 ((m matrix33
:default
))
64 (:return boolean
(matrix33-equal*
67 m
(transpose-matrix33* m
)))))
69 ;; TODO: maybe check also whether it is purely a rotation?
70 (def-tuple-op check-rotation-matrix44
*
71 ((m matrix44
:default
))
72 (:return boolean
(check-rotation-matrix33* (matrix44-matrix33* m
))))
74 (def-tuple-op transpose-matrix22
*
78 "Return the transpose of the matrix"
84 (defmacro matrix-dot
(dimension row col
)
85 "Generate the symbols required for a dot product between the row and column of a matrix, assuming accessor symbol is e<row><col>"
87 ((make-matrix-element-symbol (mat row col
)
88 (intern (string-upcase (format nil
"e~A~A~A" mat row col
)) :cl-tuples
)))
91 (loop for row from
0 below dimension
92 collect
(make-matrix-element-symbol 0 row col
)))
94 (loop for col from
0 below dimension
95 collect
(make-matrix-element-symbol 1 row col
))))
98 for col-sym in col-sym-names
99 for row-sym in row-sym-names
100 collect
`(* ,col-sym
,row-sym
))))))
103 (def-tuple-op transform-vertex2d
*
104 ((mat matrix33
(e00 e01 e02 e10 e11 e12 e20 e21 e22
))
105 (vert vector2d
(x y w
)))
108 (+ (* x e00
) (* y e01
) (* w e02
))
109 (+ (* x e10
) (* y e11
) (* w e12
))
110 (+ (* x e20
) (* y e21
) (* w e22
)))))
113 (def-tuple-op transform-vector2d
*
114 ((mat matrix33
(e00 e01 e02 e10 e11 e12 e20 e21 e22
))
115 (vec vector2d
(x y
)))
118 (+ (* x e00
) (* y e01
))
119 (+ (* x e10
) (* y e11
)))))
122 (def-tuple-op matrix33-product
*
123 ((m0 matrix33
(e000 e001 e002 e010 e011 e012 e020 e021 e022
))
124 (m1 matrix33
(e100 e101 e102 e110 e111 e112 e120 e121 e122
)))
137 (matrix-dot 3 2 2))))
140 (def-tuple-op transform-vertex3d
*
146 (vert vertex3d
(x y z w
)))
149 (+ (* x e00
) (* y e01
) (* z e02
) (* w e03
))
150 (+ (* x e10
) (* y e11
) (* z e12
) (* w e13
))
151 (+ (* x e20
) (* y e21
) (* z e22
) (* w e23
))
152 (+ (* x e30
) (* y e31
) (* z e32
) (* w e33
)))))
154 (def-tuple-op transform-vector3d
*
159 (vect vector3d
(x y z
)))
162 (+ (* x e00
) (* y e01
) (* z e02
) )
163 (+ (* x e10
) (* y e11
) (* z e12
) )
164 (+ (* x e20
) (* y e21
) (* z e12
) ))))
166 (def-tuple-op transpose-matrix33
*
167 ((mat33 matrix33
(e00 e01 e02 e10 e11 e12 e20 e21 e22
)))
168 "Return the transpose of the matrix"
175 (def-tuple-op print-matrix33
*
176 ((mat matrix44
(e00 e01 e02 e03
180 "Print a 3x3 matrix in a useful format."
182 (format t
"~A ~A ~A ~A ~%" e00 e01 e02
)
183 (format t
"~A ~A ~A ~A ~%" e10 e11 e12
)
184 (format t
"~A ~A ~A ~A ~%" e20 e21 e22
)))
186 (def-tuple-op matrix44-product
*
187 ((m0 matrix44
(e000 e001 e002 e003 e010 e011 e012 e013 e020 e021 e022 e023 e030 e031 e032 e033
))
188 (m1 matrix44
(e100 e101 e102 e103 e110 e111 e112 e113 e120 e121 e122 e123 e130 e131 e132 e133
)))
209 (matrix-dot 4 3 3))))
211 (def-tuple-op identity-matrix22
*
218 (def-tuple-op identity-matrix33
*
226 (def-tuple-op identity-matrix44
*
235 (def-tuple-op translation-matrix44
*
239 "Return a matrix that represents a translation transformation"
245 0.0f0
0.0f0
0.0f0
1.0f0
)))
247 (def-tuple-op scaling-matrix44
*
258 (def-tuple-op vertex3d-translation-matrix44
*
259 ((vert vertex3d
(tx ty tz tw
)))
260 "Return a matrix that represents a translation transformation"
266 0.0f0
0.0f0
0.0f0
1.0f0
)))
268 (def-tuple-op rotatex-matrix33
*
269 ((rotation fast-float
))
270 "Return a matrix for rotating around the x axis."
272 (let* ((sin (sin rotation
))
274 (cos (cos rotation
)))
280 (def-tuple-op rotatex-matrix44
*
281 ((rotation fast-float
))
282 "Return a matrix for rotating around the x axis."
285 (rotatex-matrix33* rotation
))))
287 (def-tuple-op rotatey-matrix33
*
288 ((rotation fast-float
))
289 "Return a matrix for rotating around the y axis."
291 (let* ((sin (sin rotation
))
293 (cos (cos rotation
)))
299 (def-tuple-op rotatey-matrix44
*
300 ((rotation fast-float
))
301 "Return a matrix for rotating around the y axis."
304 (rotatey-matrix33* rotation
))))
306 (def-tuple-op rotatez-matrix33
*
307 ((rotation fast-float
))
308 "Return a matrix for rotating around the z axis."
310 (let* ((sin (sin rotation
))
312 (cos (cos rotation
)))
318 (def-tuple-op rotatez-matrix44
*
319 ((rotation fast-float
))
320 "Return a matrix for rotating around the z axis."
323 (rotatez-matrix33* rotation
))))
325 (def-tuple-op transpose-matrix44
*
331 "Return the transpose of the matrix"
339 (def-tuple-op make-test-matrix44
*
341 "Return a matrix for testing purposes"
344 1.0f0
2.0f0
3.0f0
4.0f0
345 5.0f0
6.0f0
7.0f0
8.0f0
346 9.0f0
10.0f0
11.0f0
12.0f0
347 13.0f0
14.0f0
15.0f0
16.0f0
)))
350 (def-tuple-op print-matrix44
*
351 ((mat matrix44
(e00 e01 e02 e03
355 "Print a matrix in a useful format."
357 (format t
"~A ~A ~A ~A ~%" e00 e01 e02 e03
)
358 (format t
"~A ~A ~A ~A ~%" e10 e11 e12 e13
)
359 (format t
"~A ~A ~A ~A ~%" e20 e21 e22 e23
)
360 (format t
"~A ~A ~A ~A ~%" e30 e31 e32 e33
)))
363 (def-tuple-op matrix44-matrix33
*
369 "Convert a 4x4 matrix to a 3x3 matrix"
371 (matrix33-values* e00 e01 e02 e10 e11 e12 e20 e21 e22
)))
373 (def-tuple-op matrix33-matrix44
*
378 "Convert a 3x3 matrix to a 4x4 matrix"
380 (matrix44-values* e00 e01 e02
0.0f0
383 0.0f0
0.0f0
0.0f0
1.0f0
)))
385 (def-tuple-op vector3d-matrix3d
*
386 ((zvec vector3d
(zx zy zz
))
387 (yvec vector3d
(yx yy yz
)))
388 "Construct a rotation matrix from 2 vectors"
400 (def-tuple-op matrix22-determinant
*
401 ((mat matrix22
#.
(tuple-elements 'matrix22
)))
406 (def-tuple-op matrix33-determinant
*
407 ((mat matrix33
#.
(tuple-elements 'matrix33
)))
409 (- (+ (* e00 e11 e22
)
416 (def-tuple-op matrix44-determinant
*
417 ((mat matrix44
#.
(tuple-elements 'matrix44
)))
419 (let ((t0 (* e00 e22
))
436 (def-tuple-op matrix22-scale
*
438 (mat matrix22
#1=#.
(tuple-elements 'matrix22
)))
439 (:return matrix22
(multiply-arguments matrix22-values
* x
#1#)))
441 (def-tuple-op matrix33-scale
*
443 (mat matrix33
#1=#.
(tuple-elements 'matrix33
)))
444 (:return matrix33
(multiply-arguments matrix33-values
* x
#1#)))
446 (def-tuple-op matrix44-scale
*
448 (mat matrix44
#1=#.
(tuple-elements 'matrix44
)))
449 (:return matrix44
(multiply-arguments matrix44-values
* x
#1#)))
451 (def-tuple-op cofactor-matrix22
*
452 ((mat matrix22
#.
(tuple-elements 'matrix22
)))
458 (def-tuple-op cofactor-matrix33
*
459 ((mat matrix33
#.
(tuple-elements 'matrix33
)))
461 (macrolet ((cofactors ()
463 ,@(matrix-cofactors 3))))
466 (def-tuple-op cofactor-matrix44
*
467 ((mat matrix44
#.
(tuple-elements 'matrix44
)))
469 (macrolet ((cofactors ()
471 ,@(matrix-cofactors 4))))
474 (def-tuple-op inverted-matrix22
*
475 ((mat matrix22
#.
(tuple-elements 'matrix22
)))
478 (matrix22-determinant* mat
)
480 (cofactor-matrix22* mat
)))))
482 (def-tuple-op inverted-matrix33
*
483 ((mat matrix33
#.
(tuple-elements 'matrix33
)))
486 (matrix33-determinant* mat
)
488 (cofactor-matrix33* mat
)))))
490 (def-tuple-op inverted-matrix44
*
491 ((mat matrix44
#.
(tuple-elements 'matrix44
)))
494 (matrix44-determinant* mat
)
496 (cofactor-matrix44* mat
)))))