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