]>
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 column vector (can also access the vector array directly).
81 vec_t
mat_col(mat_t m
, int i
)
90 vec_t
mat_row(mat_t m
, int i
)
94 return vec_new2(m
.v
[0].x
, m
.v
[1].x
, m
.v
[2].x
, m
.v
[3].x
);
96 return vec_new2(m
.v
[0].y
, m
.v
[1].y
, m
.v
[2].y
, m
.v
[3].y
);
98 return vec_new2(m
.v
[0].z
, m
.v
[1].z
, m
.v
[2].z
, m
.v
[3].z
);
100 return vec_new2(m
.v
[0].w
, m
.v
[1].w
, m
.v
[2].w
, m
.v
[3].w
);
106 * Print the matrix to stdout.
109 void mat_print(mat_t m
)
112 vec_print(mat_row(m
, 0));
114 vec_print(mat_row(m
, 1));
116 vec_print(mat_row(m
, 2));
118 vec_print(mat_row(m
, 3));
124 * Multiply two matrices together.
127 mat_t
mat_mult(mat_t a
, mat_t b
)
129 #define _DOT(I,J) vec_dot2(mat_row(a,I), mat_col(b,J))
130 return mat_new(_DOT(0,0), _DOT(0,1), _DOT(0,2), _DOT(0,3),
131 _DOT(1,0), _DOT(1,1), _DOT(1,2), _DOT(1,3),
132 _DOT(2,0), _DOT(2,1), _DOT(2,2), _DOT(2,3),
133 _DOT(3,0), _DOT(3,1), _DOT(3,2), _DOT(3,3));
138 * Transform a vector using a matrix.
141 vec_t
mat_apply(mat_t m
, vec_t v
)
143 return vec_new2(vec_dot2(v
,mat_row(m
,0)),
144 vec_dot2(v
,mat_row(m
,1)),
145 vec_dot2(v
,mat_row(m
,2)),
146 vec_dot2(v
,mat_row(m
,3)));
151 * Create a new translate matrix.
154 mat_t
MAT_TRANSLATE(scal_t x
, scal_t y
, scal_t z
)
156 return mat_new(S(1.0), S(0.0), S(0.0), x
,
157 S(0.0), S(1.0), S(0.0), y
,
158 S(0.0), S(0.0), S(1.0), z
,
159 S(0.0), S(0.0), S(0.0), S(1.0));
163 * Create a new translate matrix from a vector.
166 mat_t
MAT_TRANSLATE2(vec_t v
)
168 return MAT_TRANSLATE(v
.x
, v
.y
, v
.z
);
172 * Create a new scale matrix.
175 mat_t
MAT_SCALE(scal_t x
, scal_t y
, scal_t z
)
177 return mat_new(x
, S(0.0), S(0.0), S(0.0),
178 S(0.0), y
, S(0.0), S(0.0),
179 S(0.0), S(0.0), z
, S(0.0),
180 S(0.0), S(0.0), S(0.0), S(1.0));
184 * Create a new scale matrix from a vector.
187 mat_t
MAT_SCALE2(vec_t v
)
189 return MAT_SCALE(v
.x
, v
.y
, v
.z
);
193 * Create a rotation matrix (around the X axis).
196 mat_t
MAT_ROTATE_X(scal_t theta
)
198 scal_t sin_a
= scal_sin(theta
);
199 scal_t cos_a
= scal_cos(theta
);
200 return mat_new(S(1.0), S(0.0), S(0.0), S(0.0),
201 S(0.0), cos_a
, -sin_a
, S(0.0),
202 S(0.0), sin_a
, cos_a
, S(0.0),
203 S(0.0), S(0.0), S(0.0), S(1.0));
207 * Create a rotation matrix (around the Y axis).
210 mat_t
MAT_ROTATE_Y(scal_t theta
)
212 scal_t sin_a
= scal_sin(theta
);
213 scal_t cos_a
= scal_cos(theta
);
214 return mat_new(cos_a
, S(0.0), sin_a
, S(0.0),
215 S(0.0), S(1.0), S(0.0), S(0.0),
216 -sin_a
, S(0.0), cos_a
, S(0.0),
217 S(0.0), S(0.0), S(0.0), S(1.0));
221 * Create a rotation matrix (around the Z axis).
224 mat_t
MAT_ROTATE_Z(scal_t theta
)
226 scal_t sin_a
= scal_sin(theta
);
227 scal_t cos_a
= scal_cos(theta
);
228 return mat_new(cos_a
, -sin_a
, S(0.0), S(0.0),
229 sin_a
, cos_a
, S(0.0), S(0.0),
230 S(0.0), S(0.0), S(1.0), S(0.0),
231 S(0.0), S(0.0), S(0.0), S(1.0));
235 * Create a rotation matrix (around an arbitrary axis).
238 mat_t
MAT_ROTATE(scal_t theta
, scal_t x
, scal_t y
, scal_t z
)
241 * This code is an implementation of an algorithm described by Glenn
242 * Murray at http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/
244 vec_t v
= vec_normalize(vec_new(x
, y
, z
));
248 scal_t sin_a
= scal_sin(theta
);
249 scal_t cos_a
= scal_cos(theta
);
253 return mat_new(x2
+(S(1.0)-x2
)*cos_a
, x
*y
*(S(1.0)-cos_a
)-z
*sin_a
, x
*z
*(S(1.0)-cos_a
)+y
*sin_a
, S(0.0),
254 x
*y
*(S(1.0)-cos_a
)+z
*sin_a
, y2
+(S(1.0)-y2
)*cos_a
, y
*z
*(S(1.0)-cos_a
)-y
*sin_a
, S(0.0),
255 x
*z
*(S(1.0)-cos_a
)-y
*sin_a
, y
*z
*(S(1.0)-cos_a
)+x
*sin_a
, z2
+(S(1.0)-z2
)*cos_a
, S(0.0),
256 S(0.0), S(0.0), S(0.0), S(1.0));
260 * Create a view matrix based on eye, spot, and an up vector.
263 mat_t
MAT_LOOKAT(vec_t eye
, vec_t spot
, vec_t up
)
265 vec_t f
= vec_normalize(vec_sub(spot
, eye
));
266 vec_t s
= vec_normalize(vec_cross(f
, up
));
267 vec_t u
= vec_cross(s
, f
);
268 return mat_mult(mat_new(s
.x
, s
.y
, s
.z
, S(0.0),
269 u
.x
, u
.y
, u
.z
, S(0.0),
270 -f
.x
, -f
.y
, -f
.z
, S(0.0),
271 S(0.0), S(0.0), S(0.0), S(1.0)), MAT_TRANSLATE2(vec_neg(eye
)));
275 * Create a 3D orthogonal projection matrix.
278 mat_t
MAT_ORTHO(scal_t left
, scal_t right
,
279 scal_t bottom
, scal_t top
,
280 scal_t near
, scal_t far
)
282 scal_t rml
= right
- left
;
283 scal_t rpl
= right
+ left
;
284 scal_t tmb
= top
- bottom
;
285 scal_t tpb
= top
+ bottom
;
286 scal_t fmn
= far
- near
;
287 scal_t fpn
= far
+ near
;
288 return mat_new(S(2.0)/rml
, S(0.0), S(0.0), -rpl
/ rml
,
289 S(0.0), S(2.0)/tmb
, S(0.0), -tpb
/ tmb
,
290 S(0.0), S(0.0), S(-2.0)/fmn
, -fpn
/ fmn
,
291 S(0.0), S(0.0), S(0.0), S(1.0));
295 * Create a frustum-based projection matrix.
298 mat_t
MAT_FRUSTUM(scal_t left
, scal_t right
,
299 scal_t bottom
, scal_t top
,
300 scal_t near
, scal_t far
)
302 scal_t rml
= right
- left
;
303 scal_t rpl
= right
+ left
;
304 scal_t tmb
= top
- bottom
;
305 scal_t tpb
= top
+ bottom
;
306 scal_t fmn
= far
- near
;
307 scal_t fpn
= far
+ near
;
308 scal_t n2
= near
* S(2.0);
309 return mat_new(n2
/rml
, S(0.0), rpl
/rml
, S(0.0),
310 S(0.0), n2
/tmb
, tpb
/tmb
, S(0.0),
311 S(0.0), S(0.0), -fpn
/fmn
, -n2
*far
/fmn
,
312 S(0.0), S(0.0), S(-1.0), S(0.0));
316 * Create a perspective projection matrix.
319 mat_t
MAT_PERSPECTIVE(scal_t fovy
, scal_t aspect
, scal_t near
, scal_t far
)
321 scal_t top
= near
* scal_tan(fovy
* S(0.5));
322 scal_t bottom
= -top
;
323 scal_t left
= bottom
* aspect
;
324 scal_t right
= top
* aspect
;
325 return MAT_FRUSTUM(left
, right
, bottom
, top
, near
, far
);
329 * Create a viewport matrix.
332 mat_t
MAT_VIEWPORT(int x
, int y
, int w
, int h
)
334 scal_t xs
= (scal_t
)x
;
335 scal_t ys
= (scal_t
)y
;
336 scal_t ws
= (scal_t
)w
* S(0.5);
337 scal_t hs
= (scal_t
)h
* S(0.5);
338 return mat_new(ws
, S(0.0), S(0.0), ws
+xs
,
339 S(0.0), hs
, S(0.0), hs
+ys
,
340 S(0.0), S(0.0), S(1.0), S(0.0),
341 S(0.0), S(0.0), S(0.0), S(1.0));
This page took 0.049143 seconds and 4 git commands to generate.