]>
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
)
240 vec_t v
= vec_normalize(vec_new(x
, y
, z
));
244 scal_t c
= scal_cos(-theta
);
245 scal_t s
= scal_sin(-theta
);
246 scal_t t
= S(1.0) - c
;
247 return mat_new(t
* x
* x
+ c
, t
* x
* y
+ s
* z
, t
* x
* z
- s
* y
, S(0.0),
248 t
* x
* y
- s
* z
, t
* y
* y
+ c
, t
* y
* z
+ s
* x
, S(0.0),
249 t
* x
* z
+ s
* y
, t
* y
* z
- s
* x
, t
* z
* z
+ c
, S(0.0),
250 S(0.0), S(0.0), S(0.0), S(1.0));
254 * Create a view matrix based on eye, spot, and an up vector.
257 mat_t
MAT_LOOKAT(vec_t eye
, vec_t spot
, vec_t up
)
259 vec_t f
= vec_normalize(vec_sub(spot
, eye
));
260 vec_t s
= vec_normalize(vec_cross(f
, up
));
261 vec_t u
= vec_cross(s
, f
);
262 return mat_mult(mat_new(s
.x
, s
.y
, s
.z
, S(0.0),
263 u
.x
, u
.y
, u
.z
, S(0.0),
264 -f
.x
, -f
.y
, -f
.z
, S(0.0),
265 S(0.0), S(0.0), S(0.0), S(1.0)), MAT_TRANSLATE2(vec_neg(eye
)));
269 * Create a 3D orthogonal projection matrix.
272 mat_t
MAT_ORTHO(scal_t left
, scal_t right
,
273 scal_t bottom
, scal_t top
,
274 scal_t near
, scal_t far
)
276 scal_t rml
= right
- left
;
277 scal_t rpl
= right
+ left
;
278 scal_t tmb
= top
- bottom
;
279 scal_t tpb
= top
+ bottom
;
280 scal_t fmn
= far
- near
;
281 scal_t fpn
= far
+ near
;
282 return mat_new(S(2.0)/rml
, S(0.0), S(0.0), -rpl
/ rml
,
283 S(0.0), S(2.0)/tmb
, S(0.0), -tpb
/ tmb
,
284 S(0.0), S(0.0), S(-2.0)/fmn
, -fpn
/ fmn
,
285 S(0.0), S(0.0), S(0.0), S(1.0));
289 * Create a frustum-based projection matrix.
292 mat_t
MAT_FRUSTUM(scal_t left
, scal_t right
,
293 scal_t bottom
, scal_t top
,
294 scal_t near
, scal_t far
)
296 scal_t rml
= right
- left
;
297 scal_t rpl
= right
+ left
;
298 scal_t tmb
= top
- bottom
;
299 scal_t tpb
= top
+ bottom
;
300 scal_t fmn
= far
- near
;
301 scal_t fpn
= far
+ near
;
302 scal_t n2
= near
* S(2.0);
303 return mat_new(n2
/rml
, S(0.0), rpl
/rml
, S(0.0),
304 S(0.0), n2
/tmb
, tpb
/tmb
, S(0.0),
305 S(0.0), S(0.0), -fpn
/fmn
, -n2
*far
/fmn
,
306 S(0.0), S(0.0), S(-1.0), S(0.0));
310 * Create a perspective projection matrix.
313 mat_t
MAT_PERSPECTIVE(scal_t fovy
, scal_t aspect
, scal_t near
, scal_t far
)
315 scal_t top
= near
* scal_tan(fovy
* S(0.5));
316 scal_t bottom
= -top
;
317 scal_t left
= bottom
* aspect
;
318 scal_t right
= top
* aspect
;
319 return MAT_FRUSTUM(left
, right
, bottom
, top
, near
, far
);
323 * Create a viewport matrix.
326 mat_t
MAT_VIEWPORT(int x
, int y
, int w
, int h
)
328 scal_t xs
= (scal_t
)x
;
329 scal_t ys
= (scal_t
)y
;
330 scal_t ws
= (scal_t
)w
* S(0.5);
331 scal_t hs
= (scal_t
)h
* S(0.5);
332 return mat_new(ws
, S(0.0), S(0.0), ws
+xs
,
333 S(0.0), hs
, S(0.0), hs
+ys
,
334 S(0.0), S(0.0), S(1.0), S(0.0),
335 S(0.0), S(0.0), S(0.0), S(1.0));
This page took 0.049307 seconds and 4 git commands to generate.