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