rs_matrix.c revision 1bb2eed69caa28cf8198d58db7d9134cc2f563f5
1#include "rs_core.rsh"
2#include "rs_structs.h"
3
4/* Function declarations from libRS */
5extern float4 __attribute__((overloadable)) convert_float4(uchar4 c);
6
7/* Implementation of Core Runtime */
8
9
10/////////////////////////////////////////////////////
11// Matrix ops
12/////////////////////////////////////////////////////
13
14
15extern void __attribute__((overloadable))
16rsMatrixLoadIdentity(rs_matrix4x4 *m) {
17    m->m[0] = 1.f;
18    m->m[1] = 0.f;
19    m->m[2] = 0.f;
20    m->m[3] = 0.f;
21    m->m[4] = 0.f;
22    m->m[5] = 1.f;
23    m->m[6] = 0.f;
24    m->m[7] = 0.f;
25    m->m[8] = 0.f;
26    m->m[9] = 0.f;
27    m->m[10] = 1.f;
28    m->m[11] = 0.f;
29    m->m[12] = 0.f;
30    m->m[13] = 0.f;
31    m->m[14] = 0.f;
32    m->m[15] = 1.f;
33}
34
35extern void __attribute__((overloadable))
36rsMatrixLoadIdentity(rs_matrix3x3 *m) {
37    m->m[0] = 1.f;
38    m->m[1] = 0.f;
39    m->m[2] = 0.f;
40    m->m[3] = 0.f;
41    m->m[4] = 1.f;
42    m->m[5] = 0.f;
43    m->m[6] = 0.f;
44    m->m[7] = 0.f;
45    m->m[8] = 1.f;
46}
47extern void __attribute__((overloadable))
48rsMatrixLoadIdentity(rs_matrix2x2 *m) {
49    m->m[0] = 1.f;
50    m->m[1] = 0.f;
51    m->m[2] = 0.f;
52    m->m[3] = 1.f;
53}
54
55extern void __attribute__((overloadable))
56rsMatrixLoad(rs_matrix4x4 *m, const float *f) {
57    m->m[0] = f[0];
58    m->m[1] = f[1];
59    m->m[2] = f[2];
60    m->m[3] = f[3];
61    m->m[4] = f[4];
62    m->m[5] = f[5];
63    m->m[6] = f[6];
64    m->m[7] = f[7];
65    m->m[8] = f[8];
66    m->m[9] = f[9];
67    m->m[10] = f[10];
68    m->m[11] = f[11];
69    m->m[12] = f[12];
70    m->m[13] = f[13];
71    m->m[14] = f[14];
72    m->m[15] = f[15];
73}
74extern void __attribute__((overloadable))
75rsMatrixLoad(rs_matrix3x3 *m, const float *f) {
76    m->m[0] = f[0];
77    m->m[1] = f[1];
78    m->m[2] = f[2];
79    m->m[3] = f[3];
80    m->m[4] = f[4];
81    m->m[5] = f[5];
82    m->m[6] = f[6];
83    m->m[7] = f[7];
84    m->m[8] = f[8];
85}
86extern void __attribute__((overloadable))
87rsMatrixLoad(rs_matrix2x2 *m, const float *f) {
88    m->m[0] = f[0];
89    m->m[1] = f[1];
90    m->m[2] = f[2];
91    m->m[3] = f[3];
92}
93
94extern void __attribute__((overloadable))
95rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *s) {
96    m->m[0] = s->m[0];
97    m->m[1] = s->m[1];
98    m->m[2] = s->m[2];
99    m->m[3] = s->m[3];
100    m->m[4] = s->m[4];
101    m->m[5] = s->m[5];
102    m->m[6] = s->m[6];
103    m->m[7] = s->m[7];
104    m->m[8] = s->m[8];
105    m->m[9] = s->m[9];
106    m->m[10] = s->m[10];
107    m->m[11] = s->m[11];
108    m->m[12] = s->m[12];
109    m->m[13] = s->m[13];
110    m->m[14] = s->m[14];
111    m->m[15] = s->m[15];
112}
113extern void __attribute__((overloadable))
114rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v) {
115    m->m[0] = v->m[0];
116    m->m[1] = v->m[1];
117    m->m[2] = v->m[2];
118    m->m[3] = 0.f;
119    m->m[4] = v->m[3];
120    m->m[5] = v->m[4];
121    m->m[6] = v->m[5];
122    m->m[7] = 0.f;
123    m->m[8] = v->m[6];
124    m->m[9] = v->m[7];
125    m->m[10] = v->m[8];
126    m->m[11] = 0.f;
127    m->m[12] = 0.f;
128    m->m[13] = 0.f;
129    m->m[14] = 0.f;
130    m->m[15] = 1.f;
131}
132extern void __attribute__((overloadable))
133rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v) {
134    m->m[0] = v->m[0];
135    m->m[1] = v->m[1];
136    m->m[2] = 0.f;
137    m->m[3] = 0.f;
138    m->m[4] = v->m[2];
139    m->m[5] = v->m[3];
140    m->m[6] = 0.f;
141    m->m[7] = 0.f;
142    m->m[8] = 0.f;
143    m->m[9] = 0.f;
144    m->m[10] = 1.f;
145    m->m[11] = 0.f;
146    m->m[12] = 0.f;
147    m->m[13] = 0.f;
148    m->m[14] = 0.f;
149    m->m[15] = 1.f;
150}
151extern void __attribute__((overloadable))
152rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *s) {
153    m->m[0] = s->m[0];
154    m->m[1] = s->m[1];
155    m->m[2] = s->m[2];
156    m->m[3] = s->m[3];
157    m->m[4] = s->m[4];
158    m->m[5] = s->m[5];
159    m->m[6] = s->m[6];
160    m->m[7] = s->m[7];
161    m->m[8] = s->m[8];
162}
163extern void __attribute__((overloadable))
164rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *s) {
165    m->m[0] = s->m[0];
166    m->m[1] = s->m[1];
167    m->m[2] = s->m[2];
168    m->m[3] = s->m[3];
169}
170
171
172extern void __attribute__((overloadable))
173rsMatrixSet(rs_matrix4x4 *m, uint32_t col, uint32_t row, float v) {
174    m->m[col * 4 + row] = v;
175}
176
177extern float __attribute__((overloadable))
178rsMatrixGet(const rs_matrix4x4 *m, uint32_t col, uint32_t row) {
179    return m->m[col * 4 + row];
180}
181
182extern void __attribute__((overloadable))
183rsMatrixSet(rs_matrix3x3 *m, uint32_t col, uint32_t row, float v) {
184    m->m[col * 3 + row] = v;
185}
186
187extern float __attribute__((overloadable))
188rsMatrixGet(const rs_matrix3x3 *m, uint32_t col, uint32_t row) {
189    return m->m[col * 3 + row];
190}
191
192extern void __attribute__((overloadable))
193rsMatrixSet(rs_matrix2x2 *m, uint32_t col, uint32_t row, float v) {
194    m->m[col * 2 + row] = v;
195}
196
197extern float __attribute__((overloadable))
198rsMatrixGet(const rs_matrix2x2 *m, uint32_t col, uint32_t row) {
199    return m->m[col * 2 + row];
200}
201
202extern float2 __attribute__((overloadable))
203rsMatrixMultiply(const rs_matrix2x2 *m, float2 in) {
204    float2 ret;
205    ret.x = (m->m[0] * in.x) + (m->m[2] * in.y);
206    ret.y = (m->m[1] * in.x) + (m->m[3] * in.y);
207    return ret;
208}
209extern float2 __attribute__((overloadable))
210rsMatrixMultiply(rs_matrix2x2 *m, float2 in) {
211    return rsMatrixMultiply((const rs_matrix2x2 *)m, in);
212}
213
214extern float4 __attribute__((overloadable))
215rsMatrixMultiply(rs_matrix4x4 *m, float4 in) {
216    return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
217}
218
219extern float4 __attribute__((overloadable))
220rsMatrixMultiply(rs_matrix4x4 *m, float3 in) {
221    return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
222}
223
224extern float4 __attribute__((overloadable))
225rsMatrixMultiply(rs_matrix4x4 *m, float2 in) {
226    return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
227}
228
229extern float3 __attribute__((overloadable))
230rsMatrixMultiply(rs_matrix3x3 *m, float3 in) {
231    return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
232}
233
234extern float3 __attribute__((overloadable))
235rsMatrixMultiply(rs_matrix3x3 *m, float2 in) {
236    return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
237}
238
239extern void __attribute__((overloadable))
240rsMatrixLoadMultiply(rs_matrix4x4 *ret, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
241    // Use a temporary variable to support the case where one of the inputs
242    // is also the destination, e.g. rsMatrixLoadMultiply(&left, &left, &right);
243    rs_matrix4x4 result;
244    for (int i=0 ; i<4 ; i++) {
245        float ri0 = 0;
246        float ri1 = 0;
247        float ri2 = 0;
248        float ri3 = 0;
249        for (int j=0 ; j<4 ; j++) {
250            const float rhs_ij = rsMatrixGet(rhs, i, j);
251            ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
252            ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
253            ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
254            ri3 += rsMatrixGet(lhs, j, 3) * rhs_ij;
255        }
256        rsMatrixSet(&result, i, 0, ri0);
257        rsMatrixSet(&result, i, 1, ri1);
258        rsMatrixSet(&result, i, 2, ri2);
259        rsMatrixSet(&result, i, 3, ri3);
260    }
261    rsMatrixLoad(ret, &result);
262}
263
264extern void __attribute__((overloadable))
265rsMatrixMultiply(rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
266    rsMatrixLoadMultiply(lhs, lhs, rhs);
267}
268
269extern void __attribute__((overloadable))
270rsMatrixLoadMultiply(rs_matrix3x3 *ret, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
271    // Use a temporary variable to support the case where one of the inputs
272    // is also the destination, e.g. rsMatrixLoadMultiply(&left, &left, &right);
273    rs_matrix3x3 result;
274    for (int i=0 ; i<3 ; i++) {
275        float ri0 = 0;
276        float ri1 = 0;
277        float ri2 = 0;
278        for (int j=0 ; j<3 ; j++) {
279            const float rhs_ij = rsMatrixGet(rhs, i, j);
280            ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
281            ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
282            ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
283        }
284        rsMatrixSet(&result, i, 0, ri0);
285        rsMatrixSet(&result, i, 1, ri1);
286        rsMatrixSet(&result, i, 2, ri2);
287    }
288    rsMatrixLoad(ret, &result);
289}
290
291extern void __attribute__((overloadable))
292rsMatrixMultiply(rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
293    rsMatrixLoadMultiply(lhs, lhs, rhs);
294}
295
296extern void __attribute__((overloadable))
297rsMatrixLoadMultiply(rs_matrix2x2 *ret, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
298    // Use a temporary variable to support the case where one of the inputs
299    // is also the destination, e.g. rsMatrixLoadMultiply(&left, &left, &right);
300    rs_matrix2x2 result;
301    for (int i=0 ; i<2 ; i++) {
302        float ri0 = 0;
303        float ri1 = 0;
304        for (int j=0 ; j<2 ; j++) {
305            const float rhs_ij = rsMatrixGet(rhs, i, j);
306            ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
307            ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
308        }
309        rsMatrixSet(&result, i, 0, ri0);
310        rsMatrixSet(&result, i, 1, ri1);
311    }
312    rsMatrixLoad(ret, &result);
313}
314
315extern void __attribute__((overloadable))
316rsMatrixMultiply(rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
317    rsMatrixLoadMultiply(lhs, lhs, rhs);
318}
319
320