Table of Contents
Matrices
mat3 and mat4 are 3x3 and 4x4 matrices, stored column by column, and
dmat3 and dmat4 the same of doubles; see Doubles. mat3x2,
the 2D affine transform, has a page of its own,
2D Transforms. Read Conventions for the
storage and the multiplication order.
Functions that return a matrix or a vector take an optional last argument,
result; see Results and Allocation.
Making matrices
(gm:mat4-identity) ; the identity
(gm:make-mat3 1 2 3 4 5 6 7 8 9) ; columns (1 2 3), (4 5 6) and (7 8 9)
gm:make-mat3 and gm:make-mat4 take their 9 or 16 elements column by
column, as GLSL's constructors do. The transforms on
Transforms and Cameras make the usual matrices.
Elements
mref reads the element at a row and a column, counting from 0, of a
matrix of either precision, and setf writes it, as any real:
(let ((m (gm:make-mat3 1 2 3 4 5 6 7 8 9)))
(list (gm:mref m 0 1) (gm:mref m 1 0)))
;; => (4.0 2.0)
Operations
Each exists for both sizes, as mat3-... and mat4-...:
| Function | Returns |
|---|---|
mat4* |
The product A B: the transform that applies B, then A. |
mat4*vec4, mat3*vec3 |
The matrix times a column vector. |
mat4-transpose |
The transpose. |
mat4-determinant |
The determinant, a single float. |
mat4-inverse |
The inverse. Signals gmath-error for a singular matrix. |
mat4-copy |
A copy. |
mat4-approx= |
True if no element differs by more than an epsilon, 1e-5 by default. |
(gm:mat4-inverse (gm:mat4-translation (gm:make-vec3 :x 1 :y 2 :z 3)))
;; => #(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 -2.0 -3.0 1.0)
(gm:mat4-determinant (gm:mat4-scaling (gm:make-vec3 :x 2 :y 3 :z 4)))
;; => 24.0
(gm:mat4-approx= (gm:mat4* (gm:mat4-rotation-y 1.0) (gm:mat4-inverse (gm:mat4-rotation-y 1.0)))
(gm:mat4-identity))
;; => T
A vec4 with a W of 1 is a point, which translation moves; with a W of 0,
a direction, which it does not:
(let ((move (gm:mat4-translation (gm:make-vec3 :x 1 :y 2 :z 3))))
(list (gm:mat4*vec4 move (gm:make-vec4 :w 1)) ; a point, at the origin
(gm:mat4*vec4 move (gm:make-vec4 :x 1)))) ; a direction, along X
;; => (#(1.0 2.0 3.0 1.0) #(1.0 0.0 0.0 0.0))
For vec3 points and directions, mat4-transform-point and
mat4-transform-direction do the same without a W; see
Transforms and Cameras.
From a 4x4 to a 3x3
mat3-from-mat4takes the upper left 3x3 of amat4: its rotation and scale, without its translation.mat3-normal-matrixreturns the matrix that transforms normals for a model matrix: the inverse transpose of its upper left 3x3, which keeps normals perpendicular to surfaces under a scale that differs between axes. It signalsgmath-errorif that 3x3 is singular.
(gm:mat3-normal-matrix (gm:mat4-scaling (gm:make-vec3 :x 2 :y 1 :z 1)))
;; => #(0.5 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0)
A model stretched twice as wide has its normals' X halved, so that they still stand straight on its surfaces once normalised.