1 #include "rs_core.rsh"
2 #include "rs_structs.h"
3
4 /* Function declarations from libRS */
5 extern float4 __attribute__((overloadable)) convert_float4(uchar4 c);
6
7 /* Implementation of Core Runtime */
8
9
10 /////////////////////////////////////////////////////
11 // Matrix ops
12 /////////////////////////////////////////////////////
13
14
15 extern void __attribute__((overloadable))
rsMatrixLoadIdentity(rs_matrix4x4 * m)16 rsMatrixLoadIdentity(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
35 extern void __attribute__((overloadable))
rsMatrixLoadIdentity(rs_matrix3x3 * m)36 rsMatrixLoadIdentity(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 }
47 extern void __attribute__((overloadable))
rsMatrixLoadIdentity(rs_matrix2x2 * m)48 rsMatrixLoadIdentity(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
55 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 * m,const float * f)56 rsMatrixLoad(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 }
74 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix3x3 * m,const float * f)75 rsMatrixLoad(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 }
86 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix2x2 * m,const float * f)87 rsMatrixLoad(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
94 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 * m,const rs_matrix4x4 * s)95 rsMatrixLoad(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 }
113 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 * m,const rs_matrix3x3 * v)114 rsMatrixLoad(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 }
132 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 * m,const rs_matrix2x2 * v)133 rsMatrixLoad(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 }
151 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix3x3 * m,const rs_matrix3x3 * s)152 rsMatrixLoad(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 }
163 extern void __attribute__((overloadable))
rsMatrixLoad(rs_matrix2x2 * m,const rs_matrix2x2 * s)164 rsMatrixLoad(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
172 extern void __attribute__((overloadable))
rsMatrixSet(rs_matrix4x4 * m,uint32_t col,uint32_t row,float v)173 rsMatrixSet(rs_matrix4x4 *m, uint32_t col, uint32_t row, float v) {
174 m->m[col * 4 + row] = v;
175 }
176
177 extern float __attribute__((overloadable))
rsMatrixGet(const rs_matrix4x4 * m,uint32_t col,uint32_t row)178 rsMatrixGet(const rs_matrix4x4 *m, uint32_t col, uint32_t row) {
179 return m->m[col * 4 + row];
180 }
181
182 extern void __attribute__((overloadable))
rsMatrixSet(rs_matrix3x3 * m,uint32_t col,uint32_t row,float v)183 rsMatrixSet(rs_matrix3x3 *m, uint32_t col, uint32_t row, float v) {
184 m->m[col * 3 + row] = v;
185 }
186
187 extern float __attribute__((overloadable))
rsMatrixGet(const rs_matrix3x3 * m,uint32_t col,uint32_t row)188 rsMatrixGet(const rs_matrix3x3 *m, uint32_t col, uint32_t row) {
189 return m->m[col * 3 + row];
190 }
191
192 extern void __attribute__((overloadable))
rsMatrixSet(rs_matrix2x2 * m,uint32_t col,uint32_t row,float v)193 rsMatrixSet(rs_matrix2x2 *m, uint32_t col, uint32_t row, float v) {
194 m->m[col * 2 + row] = v;
195 }
196
197 extern float __attribute__((overloadable))
rsMatrixGet(const rs_matrix2x2 * m,uint32_t col,uint32_t row)198 rsMatrixGet(const rs_matrix2x2 *m, uint32_t col, uint32_t row) {
199 return m->m[col * 2 + row];
200 }
201
202 extern float2 __attribute__((overloadable))
rsMatrixMultiply(const rs_matrix2x2 * m,float2 in)203 rsMatrixMultiply(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 }
209 extern float2 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix2x2 * m,float2 in)210 rsMatrixMultiply(rs_matrix2x2 *m, float2 in) {
211 return rsMatrixMultiply((const rs_matrix2x2 *)m, in);
212 }
213
214 extern float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * m,float4 in)215 rsMatrixMultiply(rs_matrix4x4 *m, float4 in) {
216 return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
217 }
218
219 extern float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * m,float3 in)220 rsMatrixMultiply(rs_matrix4x4 *m, float3 in) {
221 return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
222 }
223
224 extern float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * m,float2 in)225 rsMatrixMultiply(rs_matrix4x4 *m, float2 in) {
226 return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
227 }
228
229 extern float3 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 * m,float3 in)230 rsMatrixMultiply(rs_matrix3x3 *m, float3 in) {
231 return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
232 }
233
234 extern float3 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 * m,float2 in)235 rsMatrixMultiply(rs_matrix3x3 *m, float2 in) {
236 return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
237 }
238
239 extern void __attribute__((overloadable))
rsMatrixLoadMultiply(rs_matrix4x4 * ret,const rs_matrix4x4 * lhs,const rs_matrix4x4 * rhs)240 rsMatrixLoadMultiply(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
264 extern void __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * lhs,const rs_matrix4x4 * rhs)265 rsMatrixMultiply(rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
266 rsMatrixLoadMultiply(lhs, lhs, rhs);
267 }
268
269 extern void __attribute__((overloadable))
rsMatrixLoadMultiply(rs_matrix3x3 * ret,const rs_matrix3x3 * lhs,const rs_matrix3x3 * rhs)270 rsMatrixLoadMultiply(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
291 extern void __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 * lhs,const rs_matrix3x3 * rhs)292 rsMatrixMultiply(rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
293 rsMatrixLoadMultiply(lhs, lhs, rhs);
294 }
295
296 extern void __attribute__((overloadable))
rsMatrixLoadMultiply(rs_matrix2x2 * ret,const rs_matrix2x2 * lhs,const rs_matrix2x2 * rhs)297 rsMatrixLoadMultiply(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
315 extern void __attribute__((overloadable))
rsMatrixMultiply(rs_matrix2x2 * lhs,const rs_matrix2x2 * rhs)316 rsMatrixMultiply(rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
317 rsMatrixLoadMultiply(lhs, lhs, rhs);
318 }
319
320 extern void __attribute__((overloadable))
rsExtractFrustumPlanes(const rs_matrix4x4 * viewProj,float4 * left,float4 * right,float4 * top,float4 * bottom,float4 * near,float4 * far)321 rsExtractFrustumPlanes(const rs_matrix4x4* viewProj, float4* left, float4* right, float4* top,
322 float4* bottom, float4* near, float4* far) {
323 // x y z w = a b c d in the plane equation
324 left->x = viewProj->m[3] + viewProj->m[0];
325 left->y = viewProj->m[7] + viewProj->m[4];
326 left->z = viewProj->m[11] + viewProj->m[8];
327 left->w = viewProj->m[15] + viewProj->m[12];
328
329 right->x = viewProj->m[3] - viewProj->m[0];
330 right->y = viewProj->m[7] - viewProj->m[4];
331 right->z = viewProj->m[11] - viewProj->m[8];
332 right->w = viewProj->m[15] - viewProj->m[12];
333
334 top->x = viewProj->m[3] - viewProj->m[1];
335 top->y = viewProj->m[7] - viewProj->m[5];
336 top->z = viewProj->m[11] - viewProj->m[9];
337 top->w = viewProj->m[15] - viewProj->m[13];
338
339 bottom->x = viewProj->m[3] + viewProj->m[1];
340 bottom->y = viewProj->m[7] + viewProj->m[5];
341 bottom->z = viewProj->m[11] + viewProj->m[9];
342 bottom->w = viewProj->m[15] + viewProj->m[13];
343
344 near->x = viewProj->m[3] + viewProj->m[2];
345 near->y = viewProj->m[7] + viewProj->m[6];
346 near->z = viewProj->m[11] + viewProj->m[10];
347 near->w = viewProj->m[15] + viewProj->m[14];
348
349 far->x = viewProj->m[3] - viewProj->m[2];
350 far->y = viewProj->m[7] - viewProj->m[6];
351 far->z = viewProj->m[11] - viewProj->m[10];
352 far->w = viewProj->m[15] - viewProj->m[14];
353
354 float len = length(left->xyz);
355 *left /= len;
356 len = length(right->xyz);
357 *right /= len;
358 len = length(top->xyz);
359 *top /= len;
360 len = length(bottom->xyz);
361 *bottom /= len;
362 len = length(near->xyz);
363 *near /= len;
364 len = length(far->xyz);
365 *far /= len;
366 }
367
368 extern bool __attribute__((overloadable))
rsIsSphereInFrustum(float4 * sphere,float4 * left,float4 * right,float4 * top,float4 * bottom,float4 * near,float4 * far)369 rsIsSphereInFrustum(float4* sphere, float4* left, float4* right, float4* top, float4* bottom,
370 float4* near, float4* far) {
371 float distToCenter = dot(left->xyz, sphere->xyz) + left->w;
372 if (distToCenter < -sphere->w) {
373 return false;
374 }
375 distToCenter = dot(right->xyz, sphere->xyz) + right->w;
376 if (distToCenter < -sphere->w) {
377 return false;
378 }
379 distToCenter = dot(top->xyz, sphere->xyz) + top->w;
380 if (distToCenter < -sphere->w) {
381 return false;
382 }
383 distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w;
384 if (distToCenter < -sphere->w) {
385 return false;
386 }
387 distToCenter = dot(near->xyz, sphere->xyz) + near->w;
388 if (distToCenter < -sphere->w) {
389 return false;
390 }
391 distToCenter = dot(far->xyz, sphere->xyz) + far->w;
392 if (distToCenter < -sphere->w) {
393 return false;
394 }
395 return true;
396 }
397