initial commit
[chaz/rasterize] / mat.h
1
2 /*
3 * CS5600 University of Utah
4 * Charles McGarvey
5 * mcgarvey@eng.utah.edu
6 */
7
8 #ifndef __MAT_H__
9 #define __MAT_H__
10
11 #include "common.h"
12 #include "vec.h"
13
14
15 /*
16 * A simple matrix class with column-major storage and notation.
17 */
18 struct mat
19 {
20 vec_t v[4];
21 };
22 typedef struct mat mat_t;
23
24 /*
25 * Initialize a matrix with individual components, row by row.
26 */
27 __fast__
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)
32 {
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);
37 }
38
39
40 /*
41 * Create a new matrix with individual components, row by row.
42 */
43 __fast__
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)
48 {
49 mat_t m;
50 mat_init(&m, m11, m12, m13, m14,
51 m21, m22, m23, m24,
52 m31, m32, m33, m34,
53 m41, m42, m43, m44);
54 return m;
55 }
56
57 /*
58 * Create a new matrix with four column vectors.
59 */
60 __fast__
61 mat_t mat_new2(vec_t a, vec_t b, vec_t c, vec_t d)
62 {
63 mat_t m;
64 m.v[0] = a;
65 m.v[1] = b;
66 m.v[2] = c;
67 m.v[3] = d;
68 return m;
69 }
70
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))
75
76
77 /*
78 * Create a new translate matrix.
79 */
80 __fast__
81 mat_t MAT_TRANSLATE(scal_t x, scal_t y, scal_t z)
82 {
83 return mat_new(S(1.0), S(0.0), S(0.0), x,
84 S(0.0), S(1.0), S(0.0), y,
85 S(0.0), S(0.0), S(1.0), z,
86 S(0.0), S(0.0), S(0.0), S(1.0));
87 }
88
89 /*
90 * Create a new scale matrix.
91 */
92 __fast__
93 mat_t MAT_SCALE(scal_t x, scal_t y, scal_t z)
94 {
95 return mat_new( x, S(0.0), S(0.0), S(0.0),
96 S(0.0), y, S(0.0), S(0.0),
97 S(0.0), S(0.0), z, S(0.0),
98 S(0.0), S(0.0), S(0.0), S(1.0));
99 }
100
101 /*
102 * Create a rotation matrix (around the Z axis).
103 */
104 __fast__
105 mat_t MAT_ROTATE_Z(scal_t a)
106 {
107 scal_t sin_a = scal_sin(a);
108 scal_t cos_a = scal_cos(a);
109 return mat_new( cos_a, -sin_a, S(0.0), S(0.0),
110 sin_a, cos_a, S(0.0), S(0.0),
111 S(0.0), S(0.0), S(1.0), S(0.0),
112 S(0.0), S(0.0), S(0.0), S(1.0));
113 }
114
115 /*
116 * Create a 2D orthogonal projection matrix.
117 */
118 __fast__
119 mat_t MAT_ORTHO(scal_t left, scal_t right, scal_t bottom, scal_t top)
120 {
121 scal_t rml = right - left;
122 scal_t rpl = right + left;
123 scal_t tmb = top - bottom;
124 scal_t tpb = top + bottom;
125 return mat_new(S(2.0) / rml, S(0.0), S(0.0), -rpl / rml,
126 S(0.0), S(2.0) / tmb, S(0.0), -tpb / tmb,
127 S(0.0), S(0.0), S(-1.0), S(0.0),
128 S(0.0), S(0.0), S(0.0), S(1.0));
129 }
130
131 /*
132 * Create a viewport matrix.
133 */
134 __fast__
135 mat_t MAT_VIEWPORT(int x, int y, unsigned w, unsigned h)
136 {
137 scal_t xs = (scal_t)x;
138 scal_t ys = (scal_t)y;
139 scal_t ws = (scal_t)w / S(2.0);
140 scal_t hs = (scal_t)h / S(2.0);
141 return mat_new( ws, S(0.0), S(0.0), ws + xs,
142 S(0.0), hs, S(0.0), hs + ys,
143 S(0.0), S(0.0), S(1.0), S(0.0),
144 S(0.0), S(0.0), S(0.0), S(1.0));
145 }
146
147
148 /*
149 * Get a column vector (can also access the vector array directly).
150 */
151 __fast__
152 vec_t mat_col(mat_t m, int i)
153 {
154 return m.v[i];
155 }
156
157 /*
158 * Get a row vector.
159 */
160 __fast__
161 vec_t mat_row(mat_t m, int i)
162 {
163 switch (i) {
164 case 0:
165 return vec_new2(m.v[0].x, m.v[1].x, m.v[2].x, m.v[3].x);
166 case 1:
167 return vec_new2(m.v[0].y, m.v[1].y, m.v[2].y, m.v[3].y);
168 case 2:
169 return vec_new2(m.v[0].z, m.v[1].z, m.v[2].z, m.v[3].z);
170 case 3:
171 return vec_new2(m.v[0].w, m.v[1].w, m.v[2].w, m.v[3].w);
172 }
173 }
174
175
176 /*
177 * Multiply two matrices together.
178 */
179 __fast__
180 mat_t mat_mult(mat_t a, mat_t b)
181 {
182 #define _DOT(I,J) vec_dot(mat_row(a,I), mat_col(b,J))
183 return mat_new(_DOT(0,0), _DOT(0,1), _DOT(0,2), _DOT(0,3),
184 _DOT(1,0), _DOT(1,1), _DOT(1,2), _DOT(1,3),
185 _DOT(2,0), _DOT(2,1), _DOT(2,2), _DOT(2,3),
186 _DOT(3,0), _DOT(3,1), _DOT(3,2), _DOT(3,3));
187 #undef _DOT
188 }
189
190 /*
191 * Transform a vector using a matrix.
192 */
193 __fast__
194 vec_t mat_apply(mat_t m, vec_t v)
195 {
196 return vec_new2(vec_dot(v,mat_row(m,0)),
197 vec_dot(v,mat_row(m,1)),
198 vec_dot(v,mat_row(m,2)),
199 vec_dot(v,mat_row(m,3)));
200 }
201
202
203 #endif // __MAT_H__
204
This page took 0.051902 seconds and 4 git commands to generate.