1/*
2 * Copyright (C) 2011 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/** @file rs_matrix.rsh
18 *  \brief Matrix functions.
19 *
20 * These functions let you manipulate square matrices of rank 2x2, 3x3, and 4x4.
21 * They are particularly useful for graphical transformations and are
22 * compatible with OpenGL.
23 *
24 * A few general notes:
25 *
26 * \li We use a zero-based index for rows and columns.  E.g. the last element of
27 * a \ref rs_matrix4x4 is found at (3, 3).
28 *
29 * \li RenderScript uses column-based vectors.  Transforming a vector is done by
30 * postmultiplying the vector, e.g. <em>(matrix * vector)</em>, as provided by
31 * \ref rsMatrixMultiply.
32 *
33 * \li To create a transformation matrix that performs two transformations at
34 * once, multiply the two source matrices, with the first transformation as the
35 * right argument.  E.g. to create a transformation matrix that applies the
36 * transformation \e s1 followed by \e s2, call
37 * </c>rsMatrixLoadMultiply(&combined, &s2, &s1)</c>.
38 * This derives from <em>s2 * (s1 * v)</em>, which is <em>(s2 * s1) * v</em>.
39 *
40 * \li We have two style of functions to create transformation matrices:
41 * rsMatrixLoad<em>Transformation</em> and rsMatrix<em>Transformation</em>.  The
42 * former style simply stores the transformation matrix in the first argument.
43 * The latter modifies a pre-existing transformation matrix so that the new
44 * transformation happens first.  E.g. if you call \ref rsMatrixTranslate
45 * on a matrix that already does a scaling, the resulting matrix when applied
46 * to a vector will first do the translation then the scaling.
47 *
48 */
49
50#ifndef __RS_MATRIX_RSH__
51#define __RS_MATRIX_RSH__
52
53/**
54 * Set an element of a matrix.
55 *
56 * @param m The matrix that will be modified.
57 * @param col The zero-based column of the element to be set.
58 * @param row The zero-based row of the element to be set.
59 * @param v The value to set.
60 *
61 * \warning The order of the column and row parameters may be
62 * unexpected.
63 *
64 * @return void
65 */
66_RS_RUNTIME void __attribute__((overloadable))
67rsMatrixSet(rs_matrix4x4 *m, uint32_t col, uint32_t row, float v);
68/**
69 * \overload
70 */
71_RS_RUNTIME void __attribute__((overloadable))
72rsMatrixSet(rs_matrix3x3 *m, uint32_t col, uint32_t row, float v);
73/**
74 * \overload
75 */
76_RS_RUNTIME void __attribute__((overloadable))
77rsMatrixSet(rs_matrix2x2 *m, uint32_t col, uint32_t row, float v);
78
79/**
80 * Returns one element of a matrix.
81 *
82 * @param m The matrix to extract the element from.
83 * @param col The zero-based column of the element to be extracted.
84 * @param row The zero-based row of the element to extracted.
85 *
86 * \warning The order of the column and row parameters may be
87 * unexpected.
88 *
89 * @return float
90 */
91_RS_RUNTIME float __attribute__((overloadable))
92rsMatrixGet(const rs_matrix4x4 *m, uint32_t col, uint32_t row);
93/**
94 * \overload
95 */
96_RS_RUNTIME float __attribute__((overloadable))
97rsMatrixGet(const rs_matrix3x3 *m, uint32_t col, uint32_t row);
98/**
99 * \overload
100 */
101_RS_RUNTIME float __attribute__((overloadable))
102rsMatrixGet(const rs_matrix2x2 *m, uint32_t col, uint32_t row);
103
104/**
105 * Set the elements of a matrix to the identity matrix.
106 *
107 * @param m The matrix to set.
108 */
109extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix4x4 *m);
110/**
111 * \overload
112 */
113extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix3x3 *m);
114/**
115 * \overload
116 */
117extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix2x2 *m);
118
119/**
120 * Set the elements of a matrix from an array of floats.
121 *
122 * The array of floats should be in row-major order, i.e. the element a
123 * <em>row 0, column 0</em> should be first, followed by the element at
124 * <em>row 0, column 1</em>, etc.
125 *
126 * @param m The matrix to set.
127 * @param v The array of values to set the matrix to. These arrays should be
128 * 4, 9, or 16 floats long, depending on the matrix size.
129 */
130extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const float *v);
131/**
132 * \overload
133 */
134extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const float *v);
135/**
136 * \overload
137 */
138extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const float *v);
139/**
140 * Set the elements of a matrix from another matrix.
141 *
142 * If the source matrix is smaller than the destination, the rest of the
143 * destination is filled with elements of the identity matrix.  E.g.
144 * loading a rs_matrix2x2 into a rs_matrix4x4 will give:
145 *
146 * \htmlonly<table>
147 * <tr><td>m00</td><td>m01</td><td>0.0</td><td>0.0</td></tr>
148 * <tr><td>m10</td><td>m11</td><td>0.0</td><td>0.0</td></tr>
149 * <tr><td>0.0</td><td>0.0</td><td>1.0</td><td>0.0</td></tr>
150 * <tr><td>0.0</td><td>0.0</td><td>0.0</td><td>1.0</td></tr>
151 * </table>\endhtmlonly
152 *
153 * @param m The matrix to set.
154 * @param v The source matrix.
155 */
156extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v);
157/**
158 * \overload
159 */
160extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v);
161/**
162 * \overload
163 */
164extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v);
165/**
166 * \overload
167 */
168extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v);
169/**
170 * \overload
171 */
172extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v);
173
174/**
175 * Load a rotation matrix.
176 *
177 * This function creates a rotation matrix.  The axis of rotation is the
178 * <em>(x, y, z)</em> vector.
179 *
180 * To rotate a vector, multiply the vector by the created matrix
181 * using \ref rsMatrixMultiply.
182 *
183 * See http://en.wikipedia.org/wiki/Rotation_matrix .
184 *
185 * @param m The matrix to set.
186 * @param rot How much rotation to do, in degrees.
187 * @param x The x component of the vector that is the axis of rotation.
188 * @param y The y component of the vector that is the axis of rotation.
189 * @param z The z component of the vector that is the axis of rotation.
190 */
191extern void __attribute__((overloadable))
192rsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
193
194/**
195 * Load a scale matrix.
196 *
197 * This function creates a scaling matrix, where each component of a
198 * vector is multiplied by a number.  This number can be negative.
199 *
200 * To scale a vector, multiply the vector by the created matrix
201 * using \ref rsMatrixMultiply.
202 *
203 * @param m The matrix to set.
204 * @param x The multiple to scale the x components by.
205 * @param y The multiple to scale the y components by.
206 * @param z The multiple to scale the z components by.
207 */
208extern void __attribute__((overloadable))
209rsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z);
210
211/**
212 * Load a translation matrix.
213 *
214 * This function creates a translation matrix, where a
215 * number is added to each element of a vector.
216 *
217 * To translate a vector, multiply the vector by the created matrix
218 * using \ref rsMatrixMultiply.
219 *
220 * @param m The matrix to set.
221 * @param x The number to add to each x component.
222 * @param y The number to add to each y component.
223 * @param z The number to add to each z component.
224 */
225extern void __attribute__((overloadable))
226rsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z);
227
228/**
229 * Multiply two matrices.
230 *
231 * Sets \e m to the matrix product of <em>lhs * rhs</em>.
232 *
233 * To combine two 4x4 transformaton matrices, multiply the second transformation matrix
234 * by the first transformation matrix.  E.g. to create a transformation matrix that applies
235 * the transformation \e s1 followed by \e s2, call
236 * </c>rsMatrixLoadMultiply(&combined, &s2, &s1)</c>.
237 *
238 * \warning Prior to version 21, storing the result back into right matrix is not supported and
239 * will result in undefined behavior.  Use rsMatrixMulitply instead.   E.g. instead of doing
240 * rsMatrixLoadMultiply (&m2r, &m2r, &m2l), use rsMatrixMultiply (&m2r, &m2l).
241 * rsMatrixLoadMultiply (&m2l, &m2r, &m2l) works as expected.
242 *
243 * @param m The matrix to set.
244 * @param lhs The left matrix of the product.
245 * @param rhs The right matrix of the product.
246 */
247extern void __attribute__((overloadable))
248rsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs);
249/**
250 * \overload
251 */
252extern void __attribute__((overloadable))
253rsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs);
254/**
255 * \overload
256 */
257extern void __attribute__((overloadable))
258rsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs);
259
260/**
261 * Multiply a matrix into another one.
262 *
263 * Sets \e m to the matrix product <em>m * rhs</em>.
264 *
265 * When combining two 4x4 transformation matrices using this function, the resulting
266 * matrix will correspond to performing the \e rhs transformation first followed by
267 * the original \e m transformation.
268 *
269 * @param m The left matrix of the product and the matrix to be set.
270 * @param rhs The right matrix of the product.
271 */
272extern void __attribute__((overloadable))
273rsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs);
274/**
275 * \overload
276 */
277extern void __attribute__((overloadable))
278rsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs);
279/**
280 * \overload
281 */
282extern void __attribute__((overloadable))
283rsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs);
284
285/**
286 * Multiply the matrix \e m with a rotation matrix.
287 *
288 * This function modifies a transformation matrix to first do a rotation.
289 * The axis of rotation is the <em>(x, y, z)</em> vector.
290 *
291 * To apply this combined transformation to a vector, multiply
292 * the vector by the created matrix using \ref rsMatrixMultiply.
293 *
294 * @param m The matrix to modify.
295 * @param rot How much rotation to do, in degrees.
296 * @param x The x component of the vector that is the axis of rotation.
297 * @param y The y component of the vector that is the axis of rotation.
298 * @param z The z component of the vector that is the axis of rotation.
299 */
300extern void __attribute__((overloadable))
301rsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
302
303/**
304 * Multiply the matrix \e m with a scaling matrix.
305 *
306 * This function modifies a transformation matrix to first do a scaling.
307 * When scaling, each component of a vector is multiplied by a number.
308 * This number can be negative.
309 *
310 * To apply this combined transformation to a vector, multiply
311 * the vector by the created matrix using \ref rsMatrixMultiply.
312 *
313 * @param m The matrix to modify.
314 * @param x The multiple to scale the x components by.
315 * @param y The multiple to scale the y components by.
316 * @param z The multiple to scale the z components by.
317 */
318extern void __attribute__((overloadable))
319rsMatrixScale(rs_matrix4x4 *m, float x, float y, float z);
320
321/**
322 * Multiply the matrix \e m with a translation matrix.
323 *
324 * This function modifies a transformation matrix to first
325 * do a translation.  When translating, a number is added
326 * to each component of a vector.
327 *
328 * To apply this combined transformation to a vector, multiply
329 * the vector by the created matrix using \ref rsMatrixMultiply.
330 *
331 * @param m The matrix to modify.
332 * @param x The number to add to each x component.
333 * @param y The number to add to each y component.
334 * @param z The number to add to each z component.
335 */
336extern void __attribute__((overloadable))
337rsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z);
338
339/**
340 * Load an orthographic projection matrix.
341 *
342 * Constructs an orthographic projection matrix, transforming the box
343 * identified by the six clipping planes <em>left, right, bottom, top,
344 * near, far</em> into a unit cube with a corner at
345 * <em>(-1, -1, -1)</em> and the opposite at <em>(1, 1, 1)</em>.
346 *
347 * To apply this projection to a vector, multiply the vector by the
348 * created matrix using \ref rsMatrixMultiply.
349 *
350 * See https://en.wikipedia.org/wiki/Orthographic_projection .
351 *
352 * @param m The matrix to set.
353 * @param left
354 * @param right
355 * @param bottom
356 * @param top
357 * @param near
358 * @param far
359 */
360extern void __attribute__((overloadable))
361rsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
362
363/**
364 * Load a frustum projection matrix.
365 *
366 * Constructs a frustum projection matrix, transforming the box
367 * identified by the six clipping planes <em>left, right, bottom, top,
368 * near, far</em>.
369 *
370 * To apply this projection to a vector, multiply the vector by the
371 * created matrix using \ref rsMatrixMultiply.
372 *
373 * @param m The matrix to set.
374 * @param left
375 * @param right
376 * @param bottom
377 * @param top
378 * @param near
379 * @param far
380 */
381extern void __attribute__((overloadable))
382rsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
383
384/**
385 * Load a perspective projection matrix.
386 *
387 * Constructs a perspective projection matrix, assuming a symmetrical field of view.
388 *
389 * To apply this projection to a vector, multiply the vector by the
390 * created matrix using \ref rsMatrixMultiply.
391 *
392 * @param m The matrix to set.
393 * @param fovy Field of view, in degrees along the Y axis.
394 * @param aspect Ratio of x / y.
395 * @param near The near clipping plane.
396 * @param far The far clipping plane.
397 */
398extern void __attribute__((overloadable))
399rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far);
400
401#if !defined(RS_VERSION) || (RS_VERSION < 14)
402/**
403 * Multiply a vector by a matrix.
404 *
405 * Returns the post-multiplication of the vector by the matrix, ie. <em>m * in</em>.
406 *
407 * When multiplying a \e float3 to a \e rs_matrix4x4, the vector is expanded with (1).
408 *
409 * When multiplying a \e float2 to a \e rs_matrix4x4, the vector is expanded with (0, 1).
410 *
411 * When multiplying a \e float2 to a \e rs_matrix3x3, the vector is expanded with (0).
412 *
413 * This function is available in API version 10-13.  Starting with API 14,
414 * the function takes a const matrix as the first argument.
415 */
416_RS_RUNTIME float4 __attribute__((overloadable))
417rsMatrixMultiply(rs_matrix4x4 *m, float4 in);
418
419/**
420 * \overload
421 */
422_RS_RUNTIME float4 __attribute__((overloadable))
423rsMatrixMultiply(rs_matrix4x4 *m, float3 in);
424
425/**
426 * \overload
427 */
428_RS_RUNTIME float4 __attribute__((overloadable))
429rsMatrixMultiply(rs_matrix4x4 *m, float2 in);
430
431/**
432 * \overload
433 */
434_RS_RUNTIME float3 __attribute__((overloadable))
435rsMatrixMultiply(rs_matrix3x3 *m, float3 in);
436
437/**
438 * \overload
439 */
440_RS_RUNTIME float3 __attribute__((overloadable))
441rsMatrixMultiply(rs_matrix3x3 *m, float2 in);
442
443/**
444 * \overload
445 */
446_RS_RUNTIME float2 __attribute__((overloadable))
447rsMatrixMultiply(rs_matrix2x2 *m, float2 in);
448#else
449/**
450 * Multiply a vector by a matrix.
451 *
452 * Returns the post-multiplication of the vector of the matrix, i.e. <em>m * in</em>.
453 *
454 * When multiplying a \e float3 to a \e rs_matrix4x4, the vector is expanded with (1).
455 *
456 * When multiplying a \e float2 to a \e rs_matrix4x4, the vector is expanded with (0, 1).
457 *
458 * When multiplying a \e float2 to a \e rs_matrix3x3, the vector is expanded with (0).
459 *
460 * This function is available starting with API version 14.
461 */
462_RS_RUNTIME float4 __attribute__((overloadable))
463rsMatrixMultiply(const rs_matrix4x4 *m, float4 in);
464
465/**
466 * \overload
467 */
468_RS_RUNTIME float4 __attribute__((overloadable))
469rsMatrixMultiply(const rs_matrix4x4 *m, float3 in);
470
471/**
472 * \overload
473 */
474_RS_RUNTIME float4 __attribute__((overloadable))
475rsMatrixMultiply(const rs_matrix4x4 *m, float2 in);
476
477/**
478 * \overload
479 */
480_RS_RUNTIME float3 __attribute__((overloadable))
481rsMatrixMultiply(const rs_matrix3x3 *m, float3 in);
482
483/**
484 * \overload
485 */
486_RS_RUNTIME float3 __attribute__((overloadable))
487rsMatrixMultiply(const rs_matrix3x3 *m, float2 in);
488
489/**
490 * \overload
491 */
492_RS_RUNTIME float2 __attribute__((overloadable))
493rsMatrixMultiply(const rs_matrix2x2 *m, float2 in);
494#endif
495
496
497/**
498 * Inverts a matrix in place.
499 *
500 * Returns true if the matrix was successfully inverted.
501 *
502 * @param m The matrix to invert.
503 */
504extern bool __attribute__((overloadable)) rsMatrixInverse(rs_matrix4x4 *m);
505
506/**
507 * Inverts and transpose a matrix in place.
508 *
509 * The matrix is first inverted then transposed.
510 * Returns true if the matrix was successfully inverted.
511 *
512 * @param m The matrix to modify.
513 */
514extern bool __attribute__((overloadable)) rsMatrixInverseTranspose(rs_matrix4x4 *m);
515
516/**
517 * Transpose the matrix m in place.
518 *
519 * @param m The matrix to transpose.
520 */
521extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix4x4 *m);
522/**
523 * \overload
524 */
525extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix3x3 *m);
526/**
527 * \overload
528 */
529extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix2x2 *m);
530
531
532#endif
533