]>
Dogcows Code - chaz/rasterize/blob - mat.h
3 * CS5600 University of Utah
5 * mcgarvey@eng.utah.edu
16 * A simple matrix class with column-major storage and notation.
22 typedef struct mat mat_t
;
25 * Initialize a matrix with individual components, row by row.
28 void mat_init(mat_t
* m
, scal_t m11
, scal_t m12
, scal_t m13
, scal_t m14
,
29 scal_t m21
, scal_t m22
, scal_t m23
, scal_t m24
,
30 scal_t m31
, scal_t m32
, scal_t m33
, scal_t m34
,
31 scal_t m41
, scal_t m42
, scal_t m43
, scal_t m44
)
33 m
->v
[0] = vec_new2(m11
, m21
, m31
, m41
);
34 m
->v
[1] = vec_new2(m12
, m22
, m32
, m42
);
35 m
->v
[2] = vec_new2(m13
, m23
, m33
, m43
);
36 m
->v
[3] = vec_new2(m14
, m24
, m34
, m44
);
41 * Create a new matrix with individual components, row by row.
44 mat_t
mat_new(scal_t m11
, scal_t m12
, scal_t m13
, scal_t m14
,
45 scal_t m21
, scal_t m22
, scal_t m23
, scal_t m24
,
46 scal_t m31
, scal_t m32
, scal_t m33
, scal_t m34
,
47 scal_t m41
, scal_t m42
, scal_t m43
, scal_t m44
)
50 mat_init(&m
, m11
, m12
, m13
, m14
,
58 * Create a new matrix with four column vectors.
61 mat_t
mat_new2(vec_t a
, vec_t b
, vec_t c
, vec_t d
)
71 #define MAT_IDENTITY mat_new(S(1.0), S(0.0), S(0.0), S(0.0), \
72 S(0.0), S(1.0), S(0.0), S(0.0), \
73 S(0.0), S(0.0), S(1.0), S(0.0), \
74 S(0.0), S(0.0), S(0.0), S(1.0))
78 * Get a pointer to the matrix data.
81 const scal_t
* mat_data(const mat_t
* m
)
88 * Get a column vector (can also access the vector array directly).
91 vec_t
mat_col(mat_t m
, int i
)
100 vec_t
mat_row(mat_t m
, int i
)
104 return vec_new2(m
.v
[0].x
, m
.v
[1].x
, m
.v
[2].x
, m
.v
[3].x
);
106 return vec_new2(m
.v
[0].y
, m
.v
[1].y
, m
.v
[2].y
, m
.v
[3].y
);
108 return vec_new2(m
.v
[0].z
, m
.v
[1].z
, m
.v
[2].z
, m
.v
[3].z
);
110 return vec_new2(m
.v
[0].w
, m
.v
[1].w
, m
.v
[2].w
, m
.v
[3].w
);
116 * Print the matrix to stdout.
119 void mat_print(mat_t m
)
122 vec_print(mat_row(m
, 0));
124 vec_print(mat_row(m
, 1));
126 vec_print(mat_row(m
, 2));
128 vec_print(mat_row(m
, 3));
134 * Multiply two matrices together.
137 mat_t
mat_mult(mat_t a
, mat_t b
)
139 #define _DOT(I,J) vec_dot2(mat_row(a,I), mat_col(b,J))
140 return mat_new(_DOT(0,0), _DOT(0,1), _DOT(0,2), _DOT(0,3),
141 _DOT(1,0), _DOT(1,1), _DOT(1,2), _DOT(1,3),
142 _DOT(2,0), _DOT(2,1), _DOT(2,2), _DOT(2,3),
143 _DOT(3,0), _DOT(3,1), _DOT(3,2), _DOT(3,3));
148 * Transform a vector using a matrix.
151 vec_t
mat_apply(mat_t m
, vec_t v
)
153 return vec_new2(vec_dot2(v
,mat_row(m
,0)),
154 vec_dot2(v
,mat_row(m
,1)),
155 vec_dot2(v
,mat_row(m
,2)),
156 vec_dot2(v
,mat_row(m
,3)));
161 * Create a new translate matrix.
164 mat_t
MAT_TRANSLATE(scal_t x
, scal_t y
, scal_t z
)
166 return mat_new(S(1.0), S(0.0), S(0.0), x
,
167 S(0.0), S(1.0), S(0.0), y
,
168 S(0.0), S(0.0), S(1.0), z
,
169 S(0.0), S(0.0), S(0.0), S(1.0));
173 * Create a new translate matrix from a vector.
176 mat_t
MAT_TRANSLATE2(vec_t v
)
178 return MAT_TRANSLATE(v
.x
, v
.y
, v
.z
);
182 * Create a new scale matrix.
185 mat_t
MAT_SCALE(scal_t x
, scal_t y
, scal_t z
)
187 return mat_new(x
, S(0.0), S(0.0), S(0.0),
188 S(0.0), y
, S(0.0), S(0.0),
189 S(0.0), S(0.0), z
, S(0.0),
190 S(0.0), S(0.0), S(0.0), S(1.0));
194 * Create a new scale matrix from a vector.
197 mat_t
MAT_SCALE2(vec_t v
)
199 return MAT_SCALE(v
.x
, v
.y
, v
.z
);
203 * Create a rotation matrix (around the X axis).
206 mat_t
MAT_ROTATE_X(scal_t theta
)
208 scal_t sin_a
= scal_sin(theta
);
209 scal_t cos_a
= scal_cos(theta
);
210 return mat_new(S(1.0), S(0.0), S(0.0), S(0.0),
211 S(0.0), cos_a
, -sin_a
, S(0.0),
212 S(0.0), sin_a
, cos_a
, S(0.0),
213 S(0.0), S(0.0), S(0.0), S(1.0));
217 * Create a rotation matrix (around the Y axis).
220 mat_t
MAT_ROTATE_Y(scal_t theta
)
222 scal_t sin_a
= scal_sin(theta
);
223 scal_t cos_a
= scal_cos(theta
);
224 return mat_new(cos_a
, S(0.0), sin_a
, S(0.0),
225 S(0.0), S(1.0), S(0.0), S(0.0),
226 -sin_a
, S(0.0), cos_a
, S(0.0),
227 S(0.0), S(0.0), S(0.0), S(1.0));
231 * Create a rotation matrix (around the Z axis).
234 mat_t
MAT_ROTATE_Z(scal_t theta
)
236 scal_t sin_a
= scal_sin(theta
);
237 scal_t cos_a
= scal_cos(theta
);
238 return mat_new(cos_a
, -sin_a
, S(0.0), S(0.0),
239 sin_a
, cos_a
, S(0.0), S(0.0),
240 S(0.0), S(0.0), S(1.0), S(0.0),
241 S(0.0), S(0.0), S(0.0), S(1.0));
245 * Create a rotation matrix (around an arbitrary axis).
248 mat_t
MAT_ROTATE(scal_t theta
, scal_t x
, scal_t y
, scal_t z
)
250 vec_t v
= vec_normalize(vec_new(x
, y
, z
));
254 scal_t c
= scal_cos(-theta
);
255 scal_t s
= scal_sin(-theta
);
256 scal_t t
= S(1.0) - c
;
257 return mat_new(t
* x
* x
+ c
, t
* x
* y
+ s
* z
, t
* x
* z
- s
* y
, S(0.0),
258 t
* x
* y
- s
* z
, t
* y
* y
+ c
, t
* y
* z
+ s
* x
, S(0.0),
259 t
* x
* z
+ s
* y
, t
* y
* z
- s
* x
, t
* z
* z
+ c
, S(0.0),
260 S(0.0), S(0.0), S(0.0), S(1.0));
264 * Create a view matrix based on eye, spot, and an up vector.
267 mat_t
MAT_LOOKAT(vec_t eye
, vec_t spot
, vec_t up
)
269 vec_t f
= vec_normalize(vec_sub(spot
, eye
));
270 vec_t s
= vec_normalize(vec_cross(f
, up
));
271 vec_t u
= vec_cross(s
, f
);
272 return mat_mult(mat_new(s
.x
, s
.y
, s
.z
, S(0.0),
273 u
.x
, u
.y
, u
.z
, S(0.0),
274 -f
.x
, -f
.y
, -f
.z
, S(0.0),
275 S(0.0), S(0.0), S(0.0), S(1.0)), MAT_TRANSLATE2(vec_neg(eye
)));
279 * Create a 3D orthogonal projection matrix.
282 mat_t
MAT_ORTHO(scal_t left
, scal_t right
,
283 scal_t bottom
, scal_t top
,
284 scal_t near
, scal_t far
)
286 scal_t rml
= right
- left
;
287 scal_t rpl
= right
+ left
;
288 scal_t tmb
= top
- bottom
;
289 scal_t tpb
= top
+ bottom
;
290 scal_t fmn
= far
- near
;
291 scal_t fpn
= far
+ near
;
292 return mat_new(S(2.0)/rml
, S(0.0), S(0.0), -rpl
/ rml
,
293 S(0.0), S(2.0)/tmb
, S(0.0), -tpb
/ tmb
,
294 S(0.0), S(0.0), S(-2.0)/fmn
, -fpn
/ fmn
,
295 S(0.0), S(0.0), S(0.0), S(1.0));
299 * Create a frustum-based projection matrix.
302 mat_t
MAT_FRUSTUM(scal_t left
, scal_t right
,
303 scal_t bottom
, scal_t top
,
304 scal_t near
, scal_t far
)
306 scal_t rml
= right
- left
;
307 scal_t rpl
= right
+ left
;
308 scal_t tmb
= top
- bottom
;
309 scal_t tpb
= top
+ bottom
;
310 scal_t fmn
= far
- near
;
311 scal_t fpn
= far
+ near
;
312 scal_t n2
= near
* S(2.0);
313 return mat_new(n2
/rml
, S(0.0), rpl
/rml
, S(0.0),
314 S(0.0), n2
/tmb
, tpb
/tmb
, S(0.0),
315 S(0.0), S(0.0), -fpn
/fmn
, -n2
*far
/fmn
,
316 S(0.0), S(0.0), S(-1.0), S(0.0));
320 * Create a perspective projection matrix.
323 mat_t
MAT_PERSPECTIVE(scal_t fovy
, scal_t aspect
, scal_t near
, scal_t far
)
325 scal_t top
= near
* scal_tan(fovy
* S(0.5));
326 scal_t bottom
= -top
;
327 scal_t left
= bottom
* aspect
;
328 scal_t right
= top
* aspect
;
329 return MAT_FRUSTUM(left
, right
, bottom
, top
, near
, far
);
333 * Create a viewport matrix.
336 mat_t
MAT_VIEWPORT(int x
, int y
, int w
, int h
)
338 scal_t xs
= (scal_t
)x
;
339 scal_t ys
= (scal_t
)y
;
340 scal_t ws
= (scal_t
)w
* S(0.5);
341 scal_t hs
= (scal_t
)h
* S(0.5);
342 return mat_new(ws
, S(0.0), S(0.0), ws
+xs
,
343 S(0.0), hs
, S(0.0), hs
+ys
,
344 S(0.0), S(0.0), S(1.0), S(0.0),
345 S(0.0), S(0.0), S(0.0), S(1.0));
This page took 0.047454 seconds and 4 git commands to generate.