1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
18
19/*
20 * rs_matrix.rsh: Matrix Functions
21 *
22 * These functions let you manipulate square matrices of rank 2x2, 3x3, and 4x4.
23 * They are particularly useful for graphical transformations and are compatible
24 * with OpenGL.
25 *
26 * We use a zero-based index for rows and columns.  E.g. the last element of a
27 * rs_matrix4x4 is found at (3, 3).
28 *
29 * RenderScript uses column-major matrices and column-based vectors.  Transforming
30 * a vector is done by postmultiplying the vector, e.g. (matrix * vector),
31 * as provided by rsMatrixMultiply().
32 *
33 * To create a transformation matrix that performs two transformations at once,
34 * multiply the two source matrices, with the first transformation as the right
35 * argument.  E.g. to create a transformation matrix that applies the
36 * transformation s1 followed by s2, call rsMatrixLoadMultiply(&combined, &s2, &s1).
37 * This derives from s2 * (s1 * v), which is (s2 * s1) * v.
38 *
39 * We have two style of functions to create transformation matrices:
40 * rsMatrixLoadTransformation and rsMatrixTransformation.  The former
41 * style simply stores the transformation matrix in the first argument.  The latter
42 * modifies a pre-existing transformation matrix so that the new transformation
43 * happens first.  E.g. if you call rsMatrixTranslate() on a matrix that already
44 * does a scaling, the resulting matrix when applied to a vector will first do the
45 * translation then the scaling.
46 */
47
48#ifndef RENDERSCRIPT_RS_MATRIX_RSH
49#define RENDERSCRIPT_RS_MATRIX_RSH
50
51#include "rs_vector_math.rsh"
52
53/*
54 * rsExtractFrustumPlanes: Compute frustum planes
55 *
56 * Computes 6 frustum planes from the view projection matrix
57 *
58 * Parameters:
59 *   viewProj: Matrix to extract planes from.
60 *   left: Left plane.
61 *   right: Right plane.
62 *   top: Top plane.
63 *   bottom: Bottom plane.
64 *   near: Near plane.
65 *   far: Far plane.
66 */
67static inline void __attribute__((always_inline, overloadable))
68    rsExtractFrustumPlanes(const rs_matrix4x4* viewProj, float4* left, float4* right, float4* top,
69                           float4* bottom, float4* near, float4* far) {
70    // x y z w = a b c d in the plane equation
71    left->x = viewProj->m[3] + viewProj->m[0];
72    left->y = viewProj->m[7] + viewProj->m[4];
73    left->z = viewProj->m[11] + viewProj->m[8];
74    left->w = viewProj->m[15] + viewProj->m[12];
75
76    right->x = viewProj->m[3] - viewProj->m[0];
77    right->y = viewProj->m[7] - viewProj->m[4];
78    right->z = viewProj->m[11] - viewProj->m[8];
79    right->w = viewProj->m[15] - viewProj->m[12];
80
81    top->x = viewProj->m[3] - viewProj->m[1];
82    top->y = viewProj->m[7] - viewProj->m[5];
83    top->z = viewProj->m[11] - viewProj->m[9];
84    top->w = viewProj->m[15] - viewProj->m[13];
85
86    bottom->x = viewProj->m[3] + viewProj->m[1];
87    bottom->y = viewProj->m[7] + viewProj->m[5];
88    bottom->z = viewProj->m[11] + viewProj->m[9];
89    bottom->w = viewProj->m[15] + viewProj->m[13];
90
91    near->x = viewProj->m[3] + viewProj->m[2];
92    near->y = viewProj->m[7] + viewProj->m[6];
93    near->z = viewProj->m[11] + viewProj->m[10];
94    near->w = viewProj->m[15] + viewProj->m[14];
95
96    far->x = viewProj->m[3] - viewProj->m[2];
97    far->y = viewProj->m[7] - viewProj->m[6];
98    far->z = viewProj->m[11] - viewProj->m[10];
99    far->w = viewProj->m[15] - viewProj->m[14];
100
101    float len = length(left->xyz);
102    *left /= len;
103    len = length(right->xyz);
104    *right /= len;
105    len = length(top->xyz);
106    *top /= len;
107    len = length(bottom->xyz);
108    *bottom /= len;
109    len = length(near->xyz);
110    *near /= len;
111    len = length(far->xyz);
112    *far /= len;
113}
114
115/*
116 * rsIsSphereInFrustum: Checks if a sphere is within the frustum planes
117 *
118 * Returns true if the sphere is within the 6 frustum planes.
119 *
120 * Parameters:
121 *   sphere: float4 representing the sphere.
122 *   left: Left plane.
123 *   right: Right plane.
124 *   top: Top plane.
125 *   bottom: Bottom plane.
126 *   near: Near plane.
127 *   far: Far plane.
128 */
129static inline bool __attribute__((always_inline, overloadable))
130    rsIsSphereInFrustum(float4* sphere, float4* left, float4* right, float4* top, float4* bottom,
131                        float4* near, float4* far) {
132    float distToCenter = dot(left->xyz, sphere->xyz) + left->w;
133    if (distToCenter < -sphere->w) {
134        return false;
135    }
136    distToCenter = dot(right->xyz, sphere->xyz) + right->w;
137    if (distToCenter < -sphere->w) {
138        return false;
139    }
140    distToCenter = dot(top->xyz, sphere->xyz) + top->w;
141    if (distToCenter < -sphere->w) {
142        return false;
143    }
144    distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w;
145    if (distToCenter < -sphere->w) {
146        return false;
147    }
148    distToCenter = dot(near->xyz, sphere->xyz) + near->w;
149    if (distToCenter < -sphere->w) {
150        return false;
151    }
152    distToCenter = dot(far->xyz, sphere->xyz) + far->w;
153    if (distToCenter < -sphere->w) {
154        return false;
155    }
156    return true;
157}
158
159/*
160 * rsMatrixGet: Get one element
161 *
162 * Returns one element of a matrix.
163 *
164 * Warning: The order of the column and row parameters may be unexpected.
165 *
166 * Parameters:
167 *   m: Matrix to extract the element from.
168 *   col: Zero-based column of the element to be extracted.
169 *   row: Zero-based row of the element to extracted.
170 */
171extern float __attribute__((overloadable))
172    rsMatrixGet(const rs_matrix4x4* m, uint32_t col, uint32_t row);
173
174extern float __attribute__((overloadable))
175    rsMatrixGet(const rs_matrix3x3* m, uint32_t col, uint32_t row);
176
177extern float __attribute__((overloadable))
178    rsMatrixGet(const rs_matrix2x2* m, uint32_t col, uint32_t row);
179
180/*
181 * rsMatrixInverse: Inverts a matrix in place
182 *
183 * Returns true if the matrix was successfully inverted.
184 *
185 * Parameters:
186 *   m: Matrix to invert.
187 */
188extern bool __attribute__((overloadable))
189    rsMatrixInverse(rs_matrix4x4* m);
190
191/*
192 * rsMatrixInverseTranspose: Inverts and transpose a matrix in place
193 *
194 * The matrix is first inverted then transposed. Returns true if the matrix was
195 * successfully inverted.
196 *
197 * Parameters:
198 *   m: Matrix to modify.
199 */
200extern bool __attribute__((overloadable))
201    rsMatrixInverseTranspose(rs_matrix4x4* m);
202
203/*
204 * rsMatrixLoad: Load or copy a matrix
205 *
206 * Set the elements of a matrix from an array of floats or from another matrix.
207 *
208 * If loading from an array, the floats should be in row-major order, i.e. the element a
209 * row 0, column 0 should be first, followed by the element at
210 * row 0, column 1, etc.
211 *
212 * If loading from a matrix and the source is smaller than the destination, the rest
213 * of the destination is filled with elements of the identity matrix.  E.g.
214 * loading a rs_matrix2x2 into a rs_matrix4x4 will give:
215 *
216 * m00 m01 0.0 0.0
217 * m10 m11 0.0 0.0
218 * 0.0 0.0 1.0 0.0
219 * 0.0 0.0 0.0 1.0
220 *
221 *
222 * Parameters:
223 *   destination: Matrix to set.
224 *   array: Array of values to set the matrix to. These arrays should be 4, 9, or 16 floats long, depending on the matrix size.
225 *   source: Source matrix.
226 */
227extern void __attribute__((overloadable))
228    rsMatrixLoad(rs_matrix4x4* destination, const float* array);
229
230extern void __attribute__((overloadable))
231    rsMatrixLoad(rs_matrix3x3* destination, const float* array);
232
233extern void __attribute__((overloadable))
234    rsMatrixLoad(rs_matrix2x2* destination, const float* array);
235
236extern void __attribute__((overloadable))
237    rsMatrixLoad(rs_matrix4x4* destination, const rs_matrix4x4* source);
238
239extern void __attribute__((overloadable))
240    rsMatrixLoad(rs_matrix3x3* destination, const rs_matrix3x3* source);
241
242extern void __attribute__((overloadable))
243    rsMatrixLoad(rs_matrix2x2* destination, const rs_matrix2x2* source);
244
245extern void __attribute__((overloadable))
246    rsMatrixLoad(rs_matrix4x4* destination, const rs_matrix3x3* source);
247
248extern void __attribute__((overloadable))
249    rsMatrixLoad(rs_matrix4x4* destination, const rs_matrix2x2* source);
250
251/*
252 * rsMatrixLoadFrustum: Load a frustum projection matrix
253 *
254 * Constructs a frustum projection matrix, transforming the box identified by
255 * the six clipping planes left, right, bottom, top, near, far.
256 *
257 * To apply this projection to a vector, multiply the vector by the created
258 * matrix using rsMatrixMultiply().
259 *
260 * Parameters:
261 *   m: Matrix to set.
262 */
263extern void __attribute__((overloadable))
264    rsMatrixLoadFrustum(rs_matrix4x4* m, float left, float right, float bottom, float top,
265                        float near, float far);
266
267/*
268 * rsMatrixLoadIdentity: Load identity matrix
269 *
270 * Set the elements of a matrix to the identity matrix.
271 *
272 * Parameters:
273 *   m: Matrix to set.
274 */
275extern void __attribute__((overloadable))
276    rsMatrixLoadIdentity(rs_matrix4x4* m);
277
278extern void __attribute__((overloadable))
279    rsMatrixLoadIdentity(rs_matrix3x3* m);
280
281extern void __attribute__((overloadable))
282    rsMatrixLoadIdentity(rs_matrix2x2* m);
283
284/*
285 * rsMatrixLoadMultiply: Multiply two matrices
286 *
287 * Sets m to the matrix product of lhs * rhs.
288 *
289 * To combine two 4x4 transformaton matrices, multiply the second transformation matrix
290 * by the first transformation matrix.  E.g. to create a transformation matrix that applies
291 * the transformation s1 followed by s2, call rsMatrixLoadMultiply(&combined, &s2, &s1).
292 *
293 * Warning: Prior to version 21, storing the result back into right matrix is not supported and
294 * will result in undefined behavior.  Use rsMatrixMulitply instead.   E.g. instead of doing
295 * rsMatrixLoadMultiply (&m2r, &m2r, &m2l), use rsMatrixMultiply (&m2r, &m2l).
296 * rsMatrixLoadMultiply (&m2l, &m2r, &m2l) works as expected.
297 *
298 * Parameters:
299 *   m: Matrix to set.
300 *   lhs: Left matrix of the product.
301 *   rhs: Right matrix of the product.
302 */
303extern void __attribute__((overloadable))
304    rsMatrixLoadMultiply(rs_matrix4x4* m, const rs_matrix4x4* lhs, const rs_matrix4x4* rhs);
305
306extern void __attribute__((overloadable))
307    rsMatrixLoadMultiply(rs_matrix3x3* m, const rs_matrix3x3* lhs, const rs_matrix3x3* rhs);
308
309extern void __attribute__((overloadable))
310    rsMatrixLoadMultiply(rs_matrix2x2* m, const rs_matrix2x2* lhs, const rs_matrix2x2* rhs);
311
312/*
313 * rsMatrixLoadOrtho: Load an orthographic projection matrix
314 *
315 * Constructs an orthographic projection matrix, transforming the box identified by the
316 * six clipping planes left, right, bottom, top, near, far into a unit cube
317 * with a corner at (-1, -1, -1) and the opposite at (1, 1, 1).
318 *
319 * To apply this projection to a vector, multiply the vector by the created matrix
320 * using rsMatrixMultiply().
321 *
322 * See https://en.wikipedia.org/wiki/Orthographic_projection .
323 *
324 * Parameters:
325 *   m: Matrix to set.
326 */
327extern void __attribute__((overloadable))
328    rsMatrixLoadOrtho(rs_matrix4x4* m, float left, float right, float bottom, float top, float near,
329                      float far);
330
331/*
332 * rsMatrixLoadPerspective: Load a perspective projection matrix
333 *
334 * Constructs a perspective projection matrix, assuming a symmetrical field of view.
335 *
336 * To apply this projection to a vector, multiply the vector by the created matrix
337 * using rsMatrixMultiply().
338 *
339 * Parameters:
340 *   m: Matrix to set.
341 *   fovy: Field of view, in degrees along the Y axis.
342 *   aspect: Ratio of x / y.
343 *   near: Near clipping plane.
344 *   far: Far clipping plane.
345 */
346extern void __attribute__((overloadable))
347    rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far);
348
349/*
350 * rsMatrixLoadRotate: Load a rotation matrix
351 *
352 * This function creates a rotation matrix.  The axis of rotation is the (x, y, z) vector.
353 *
354 * To rotate a vector, multiply the vector by the created matrix using rsMatrixMultiply().
355 *
356 * See http://en.wikipedia.org/wiki/Rotation_matrix .
357 *
358 * Parameters:
359 *   m: Matrix to set.
360 *   rot: How much rotation to do, in degrees.
361 *   x: X component of the vector that is the axis of rotation.
362 *   y: Y component of the vector that is the axis of rotation.
363 *   z: Z component of the vector that is the axis of rotation.
364 */
365extern void __attribute__((overloadable))
366    rsMatrixLoadRotate(rs_matrix4x4* m, float rot, float x, float y, float z);
367
368/*
369 * rsMatrixLoadScale: Load a scaling matrix
370 *
371 * This function creates a scaling matrix, where each component of a vector is multiplied
372 * by a number.  This number can be negative.
373 *
374 * To scale a vector, multiply the vector by the created matrix using rsMatrixMultiply().
375 *
376 * Parameters:
377 *   m: Matrix to set.
378 *   x: Multiple to scale the x components by.
379 *   y: Multiple to scale the y components by.
380 *   z: Multiple to scale the z components by.
381 */
382extern void __attribute__((overloadable))
383    rsMatrixLoadScale(rs_matrix4x4* m, float x, float y, float z);
384
385/*
386 * rsMatrixLoadTranslate: Load a translation matrix
387 *
388 * This function creates a translation matrix, where a number is added to each element of
389 * a vector.
390 *
391 * To translate a vector, multiply the vector by the created matrix using
392 * rsMatrixMultiply().
393 *
394 * Parameters:
395 *   m: Matrix to set.
396 *   x: Number to add to each x component.
397 *   y: Number to add to each y component.
398 *   z: Number to add to each z component.
399 */
400extern void __attribute__((overloadable))
401    rsMatrixLoadTranslate(rs_matrix4x4* m, float x, float y, float z);
402
403/*
404 * rsMatrixMultiply: Multiply a matrix by a vector or another matrix
405 *
406 * For the matrix by matrix variant, sets m to the matrix product m * rhs.
407 *
408 * When combining two 4x4 transformation matrices using this function, the resulting
409 * matrix will correspond to performing the rhs transformation first followed by
410 * the original m transformation.
411 *
412 * For the matrix by vector variant, returns the post-multiplication of the vector
413 * by the matrix, ie. m * in.
414 *
415 * When multiplying a float3 to a rs_matrix4x4, the vector is expanded with (1).
416 *
417 * When multiplying a float2 to a rs_matrix4x4, the vector is expanded with (0, 1).
418 *
419 * When multiplying a float2 to a rs_matrix3x3, the vector is expanded with (0).
420 *
421 * Starting with API 14, this function takes a const matrix as the first argument.
422 *
423 * Parameters:
424 *   m: Left matrix of the product and the matrix to be set.
425 *   rhs: Right matrix of the product.
426 */
427extern void __attribute__((overloadable))
428    rsMatrixMultiply(rs_matrix4x4* m, const rs_matrix4x4* rhs);
429
430extern void __attribute__((overloadable))
431    rsMatrixMultiply(rs_matrix3x3* m, const rs_matrix3x3* rhs);
432
433extern void __attribute__((overloadable))
434    rsMatrixMultiply(rs_matrix2x2* m, const rs_matrix2x2* rhs);
435
436#if !defined(RS_VERSION) || (RS_VERSION <= 13)
437extern float4 __attribute__((overloadable))
438    rsMatrixMultiply(rs_matrix4x4* m, float4 in);
439#endif
440
441#if !defined(RS_VERSION) || (RS_VERSION <= 13)
442extern float4 __attribute__((overloadable))
443    rsMatrixMultiply(rs_matrix4x4* m, float3 in);
444#endif
445
446#if !defined(RS_VERSION) || (RS_VERSION <= 13)
447extern float4 __attribute__((overloadable))
448    rsMatrixMultiply(rs_matrix4x4* m, float2 in);
449#endif
450
451#if !defined(RS_VERSION) || (RS_VERSION <= 13)
452extern float3 __attribute__((overloadable))
453    rsMatrixMultiply(rs_matrix3x3* m, float3 in);
454#endif
455
456#if !defined(RS_VERSION) || (RS_VERSION <= 13)
457extern float3 __attribute__((overloadable))
458    rsMatrixMultiply(rs_matrix3x3* m, float2 in);
459#endif
460
461#if !defined(RS_VERSION) || (RS_VERSION <= 13)
462extern float2 __attribute__((overloadable))
463    rsMatrixMultiply(rs_matrix2x2* m, float2 in);
464#endif
465
466#if (defined(RS_VERSION) && (RS_VERSION >= 14))
467extern float4 __attribute__((overloadable))
468    rsMatrixMultiply(const rs_matrix4x4* m, float4 in);
469#endif
470
471#if (defined(RS_VERSION) && (RS_VERSION >= 14))
472extern float4 __attribute__((overloadable))
473    rsMatrixMultiply(const rs_matrix4x4* m, float3 in);
474#endif
475
476#if (defined(RS_VERSION) && (RS_VERSION >= 14))
477extern float4 __attribute__((overloadable))
478    rsMatrixMultiply(const rs_matrix4x4* m, float2 in);
479#endif
480
481#if (defined(RS_VERSION) && (RS_VERSION >= 14))
482extern float3 __attribute__((overloadable))
483    rsMatrixMultiply(const rs_matrix3x3* m, float3 in);
484#endif
485
486#if (defined(RS_VERSION) && (RS_VERSION >= 14))
487extern float3 __attribute__((overloadable))
488    rsMatrixMultiply(const rs_matrix3x3* m, float2 in);
489#endif
490
491#if (defined(RS_VERSION) && (RS_VERSION >= 14))
492extern float2 __attribute__((overloadable))
493    rsMatrixMultiply(const rs_matrix2x2* m, float2 in);
494#endif
495
496/*
497 * rsMatrixRotate: Apply a rotation to a transformation matrix
498 *
499 * Multiply the matrix m with a rotation matrix.
500 *
501 * This function modifies a transformation matrix to first do a rotation.  The axis of
502 * rotation is the (x, y, z) vector.
503 *
504 * To apply this combined transformation to a vector, multiply the vector by the created
505 * matrix using rsMatrixMultiply().
506 *
507 * Parameters:
508 *   m: Matrix to modify.
509 *   rot: How much rotation to do, in degrees.
510 *   x: X component of the vector that is the axis of rotation.
511 *   y: Y component of the vector that is the axis of rotation.
512 *   z: Z component of the vector that is the axis of rotation.
513 */
514extern void __attribute__((overloadable))
515    rsMatrixRotate(rs_matrix4x4* m, float rot, float x, float y, float z);
516
517/*
518 * rsMatrixScale: Apply a scaling to a transformation matrix
519 *
520 * Multiply the matrix m with a scaling matrix.
521 *
522 * This function modifies a transformation matrix to first do a scaling.   When scaling,
523 * each component of a vector is multiplied by a number.  This number can be negative.
524 *
525 * To apply this combined transformation to a vector, multiply the vector by the created
526 * matrix using rsMatrixMultiply().
527 *
528 * Parameters:
529 *   m: Matrix to modify.
530 *   x: Multiple to scale the x components by.
531 *   y: Multiple to scale the y components by.
532 *   z: Multiple to scale the z components by.
533 */
534extern void __attribute__((overloadable))
535    rsMatrixScale(rs_matrix4x4* m, float x, float y, float z);
536
537/*
538 * rsMatrixSet: Set one element
539 *
540 * Set an element of a matrix.
541 *
542 * Warning: The order of the column and row parameters may be unexpected.
543 *
544 * Parameters:
545 *   m: Matrix that will be modified.
546 *   col: Zero-based column of the element to be set.
547 *   row: Zero-based row of the element to be set.
548 *   v: Value to set.
549 */
550extern void __attribute__((overloadable))
551    rsMatrixSet(rs_matrix4x4* m, uint32_t col, uint32_t row, float v);
552
553extern void __attribute__((overloadable))
554    rsMatrixSet(rs_matrix3x3* m, uint32_t col, uint32_t row, float v);
555
556extern void __attribute__((overloadable))
557    rsMatrixSet(rs_matrix2x2* m, uint32_t col, uint32_t row, float v);
558
559/*
560 * rsMatrixTranslate: Apply a translation to a transformation matrix
561 *
562 * Multiply the matrix m with a translation matrix.
563 *
564 * This function modifies a transformation matrix to first do a translation.  When
565 * translating, a number is added to each component of a vector.
566 *
567 * To apply this combined transformation to a vector, multiply the vector by the
568 * created matrix using rsMatrixMultiply().
569 *
570 * Parameters:
571 *   m: Matrix to modify.
572 *   x: Number to add to each x component.
573 *   y: Number to add to each y component.
574 *   z: Number to add to each z component.
575 */
576extern void __attribute__((overloadable))
577    rsMatrixTranslate(rs_matrix4x4* m, float x, float y, float z);
578
579/*
580 * rsMatrixTranspose: Transpose a matrix place
581 *
582 * Transpose the matrix m in place.
583 *
584 * Parameters:
585 *   m: Matrix to transpose.
586 */
587extern void __attribute__((overloadable))
588    rsMatrixTranspose(rs_matrix4x4* m);
589
590extern void __attribute__((overloadable))
591    rsMatrixTranspose(rs_matrix3x3* m);
592
593extern void __attribute__((overloadable))
594    rsMatrixTranspose(rs_matrix2x2* m);
595
596#endif // RENDERSCRIPT_RS_MATRIX_RSH
597