rs_matrix.spec revision 20b27d602a4778ed50a83df2147416a35b7c92be
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
22 compatible with OpenGL.
23
24 We use a zero-based index for rows and columns.  E.g. the last element of
25 a @rs_matrix4x4 is found at (3, 3).
26
27 RenderScript uses column-major matrices and column-based vectors.
28 Transforming a vector is done by postmultiplying the vector,
29 e.g. <code>(matrix * vector)</code>, as provided by @rsMatrixMultiply().
30
31 To create a transformation matrix that performs two transformations at
32 once, multiply the two source matrices, with the first transformation as the
33 right argument.  E.g. to create a transformation matrix that applies the
34 transformation s1 followed by s2, call <code>rsMatrixLoadMultiply(&combined, &s2, &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
39 former style simply stores the transformation matrix in the first argument.
40 The latter modifies a pre-existing transformation matrix so that the new
41 transformation happens first.  E.g. if you call @rsMatrixTranslate()
42 on a matrix that already does a scaling, the resulting matrix when applied
43 to a vector will first do the 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, "The matrix to extract the element from."
155arg: uint32_t col, "The zero-based column of the element to be extracted."
156arg: uint32_t row, "The 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, "The 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, "The matrix to modify."
177summary: Inverts and transpose a matrix in place
178description:
179 The matrix is first inverted then transposed.
180 Returns true if the matrix was successfully inverted.
181test: none
182end:
183
184function: rsMatrixLoad
185t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
186ret: void
187arg: #1* destination, "The matrix to set."
188arg: const float* array, "The 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 of the
198 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, "The 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, "The 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
237 identified by the six clipping planes <code>left, right, bottom, top,
238 near, far</code>.
239
240 To apply this projection to a vector, multiply the vector by the
241 created matrix using @rsMatrixMultiply().
242test: none
243end:
244
245function: rsMatrixLoadIdentity
246t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
247ret: void
248arg: #1* m, "The matrix to set."
249summary: Load identity matrix
250description:
251 Set the elements of a matrix to the identity matrix.
252test: none
253end:
254
255function: rsMatrixLoadMultiply
256t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
257ret: void
258arg: #1* m, "The matrix to set."
259arg: const #1* lhs, "The left matrix of the product."
260arg: const #1* rhs, "The right matrix of the product."
261summary: Multiply two matrices
262description:
263 Sets m to the matrix product of <code>lhs * rhs</code>.
264
265 To combine two 4x4 transformaton matrices, multiply the second transformation matrix
266 by the first transformation matrix.  E.g. to create a transformation matrix that applies
267 the transformation s1 followed by s2, call
268 <code>rsMatrixLoadMultiply(&combined, &s2, &s1)</code>.
269
270 <b>Warning:</b> Prior to version 21, storing the result back into right matrix is not supported and
271 will result in undefined behavior.  Use rsMatrixMulitply instead.   E.g. instead of doing
272 rsMatrixLoadMultiply (&m2r, &m2r, &m2l), use rsMatrixMultiply (&m2r, &m2l).
273 rsMatrixLoadMultiply (&m2l, &m2r, &m2l) works as expected.
274test: none
275end:
276
277function: rsMatrixLoadOrtho
278ret: void
279arg: rs_matrix4x4* m, "The matrix to set."
280arg: float left
281arg: float right
282arg: float bottom
283arg: float top
284arg: float near
285arg: float far
286summary: Load an orthographic projection matrix
287description:
288 Constructs an orthographic projection matrix, transforming the box
289 identified by the six clipping planes <code>left, right, bottom, top,
290 near, far</code> into a unit cube with a corner at
291 <code>(-1, -1, -1)</code> and the opposite at <code>(1, 1, 1)</code>.
292
293 To apply this projection to a vector, multiply the vector by the
294 created matrix using @rsMatrixMultiply().
295
296 See https://en.wikipedia.org/wiki/Orthographic_projection .
297test: none
298end:
299
300function: rsMatrixLoadPerspective
301ret: void
302arg: rs_matrix4x4* m, "The matrix to set."
303arg: float fovy, "Field of view, in degrees along the Y axis."
304arg: float aspect, "Ratio of x / y."
305arg: float near, "The near clipping plane."
306arg: float far, "The far clipping plane."
307summary: Load a perspective projection matrix
308description:
309 Constructs a perspective projection matrix, assuming a symmetrical field of view.
310
311 To apply this projection to a vector, multiply the vector by the
312 created matrix using @rsMatrixMultiply().
313test: none
314end:
315
316function: rsMatrixLoadRotate
317ret: void
318arg: rs_matrix4x4* m, "The matrix to set."
319arg: float rot, "How much rotation to do, in degrees."
320arg: float x, "The x component of the vector that is the axis of rotation."
321arg: float y, "The y component of the vector that is the axis of rotation."
322arg: float z, "The z component of the vector that is the axis of rotation."
323summary: Load a rotation matrix
324description:
325 This function creates a rotation matrix.  The axis of rotation is the
326 <code>(x, y, z)</code> vector.
327
328 To rotate a vector, multiply the vector by the created matrix
329 using @rsMatrixMultiply().
330
331 See http://en.wikipedia.org/wiki/Rotation_matrix .
332test: none
333end:
334
335function: rsMatrixLoadScale
336ret: void
337arg: rs_matrix4x4* m, "The matrix to set."
338arg: float x, "The multiple to scale the x components by."
339arg: float y, "The multiple to scale the y components by."
340arg: float z, "The multiple to scale the z components by."
341summary: Load a scaling matrix
342description:
343 This function creates a scaling matrix, where each component of a
344 vector is multiplied by a number.  This number can be negative.
345
346 To scale a vector, multiply the vector by the created matrix
347 using @rsMatrixMultiply().
348test: none
349end:
350
351function: rsMatrixLoadTranslate
352ret: void
353arg: rs_matrix4x4* m, "The matrix to set."
354arg: float x, "The number to add to each x component."
355arg: float y, "The number to add to each y component."
356arg: float z, "The number to add to each z component."
357summary: Load a translation matrix
358description:
359 This function creates a translation matrix, where a
360 number is added to each element of a vector.
361
362 To translate a vector, multiply the vector by the created matrix
363 using @rsMatrixMultiply().
364test: none
365end:
366
367function: rsMatrixMultiply
368t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
369ret: void
370arg: #1* m, "The left matrix of the product and the matrix to be set."
371arg: const #1* rhs, "The right matrix of the product."
372summary: Multiply a matrix by a vector or another matrix
373description:
374 For the matrix by matrix variant, sets m to the matrix product <code>m * rhs</code>.
375
376 When combining two 4x4 transformation matrices using this function, the resulting
377 matrix will correspond to performing the rhs transformation first followed by
378 the original m transformation.
379
380 For the matrix by vector variant, returns the post-multiplication of the vector
381 by the matrix, ie. <code>m * in</code>.
382
383 When multiplying a float3 to a @rs_matrix4x4, the vector is expanded with (1).
384
385 When multiplying a float2 to a @rs_matrix4x4, the vector is expanded with (0, 1).
386
387 When multiplying a float2 to a @rs_matrix3x3, the vector is expanded with (0).
388
389 Starting with API 14, this function takes a const matrix as the first argument.
390test: none
391end:
392
393function: rsMatrixMultiply
394version: 9 13
395ret: float4
396arg: rs_matrix4x4* m
397arg: float4 in
398test: none
399end:
400
401function: rsMatrixMultiply
402version: 9 13
403ret: float4
404arg: rs_matrix4x4* m
405arg: float3 in
406test: none
407end:
408
409function: rsMatrixMultiply
410version: 9 13
411ret: float4
412arg: rs_matrix4x4* m
413arg: float2 in
414test: none
415end:
416
417function: rsMatrixMultiply
418version: 9 13
419ret: float3
420arg: rs_matrix3x3* m
421arg: float3 in
422test: none
423end:
424
425function: rsMatrixMultiply
426version: 9 13
427ret: float3
428arg: rs_matrix3x3* m
429arg: float2 in
430test: none
431end:
432
433function: rsMatrixMultiply
434version: 9 13
435ret: float2
436arg: rs_matrix2x2* m
437arg: float2 in
438test: none
439end:
440
441function: rsMatrixMultiply
442version: 14
443ret: float4
444arg: const rs_matrix4x4* m
445arg: float4 in
446test: none
447end:
448
449function: rsMatrixMultiply
450version: 14
451ret: float4
452arg: const rs_matrix4x4* m
453arg: float3 in
454test: none
455end:
456
457function: rsMatrixMultiply
458version: 14
459ret: float4
460arg: const rs_matrix4x4* m
461arg: float2 in
462test: none
463end:
464
465function: rsMatrixMultiply
466version: 14
467ret: float3
468arg: const rs_matrix3x3* m
469arg: float3 in
470test: none
471end:
472
473function: rsMatrixMultiply
474version: 14
475ret: float3
476arg: const rs_matrix3x3* m
477arg: float2 in
478test: none
479end:
480
481function: rsMatrixMultiply
482version: 14
483ret: float2
484arg: const rs_matrix2x2* m
485arg: float2 in
486test: none
487end:
488
489function: rsMatrixRotate
490ret: void
491arg: rs_matrix4x4* m, "The matrix to modify."
492arg: float rot, "How much rotation to do, in degrees."
493arg: float x, "The x component of the vector that is the axis of rotation."
494arg: float y, "The y component of the vector that is the axis of rotation."
495arg: float z, "The z component of the vector that is the axis of rotation."
496summary: Apply a rotation to a transformation matrix
497description:
498 Multiply the matrix m with a rotation matrix.
499
500 This function modifies a transformation matrix to first do a rotation.
501 The axis of rotation is the <code>(x, y, z)</code> vector.
502
503 To apply this combined transformation to a vector, multiply
504 the vector by the created matrix using @rsMatrixMultiply().
505test: none
506end:
507
508function: rsMatrixScale
509ret: void
510arg: rs_matrix4x4* m, "The matrix to modify."
511arg: float x, "The multiple to scale the x components by."
512arg: float y, "The multiple to scale the y components by."
513arg: float z, "The multiple to scale the z components by."
514summary: Apply a scaling to a transformation matrix
515description:
516 Multiply the matrix m with a scaling matrix.
517
518 This function modifies a transformation matrix to first do a scaling.
519 When scaling, each component of a vector is multiplied by a number.
520 This number can be negative.
521
522 To apply this combined transformation to a vector, multiply
523 the vector by the created matrix using @rsMatrixMultiply().
524test: none
525end:
526
527function: rsMatrixSet
528t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
529ret: void
530arg: #1* m, "The matrix that will be modified."
531arg: uint32_t col, "The zero-based column of the element to be set."
532arg: uint32_t row, "The zero-based row of the element to be set."
533arg: float v, "The value to set."
534summary: Set one element
535description:
536 Set an element of a matrix.
537
538 <b>Warning:</b> The order of the column and row parameters may be unexpected.
539test: none
540end:
541
542function: rsMatrixTranslate
543ret: void
544arg: rs_matrix4x4* m, "The matrix to modify."
545arg: float x, "The number to add to each x component."
546arg: float y, "The number to add to each y component."
547arg: float z, "The number to add to each z component."
548summary: Apply a translation to a transformation matrix
549description:
550 Multiply the matrix m with a translation matrix.
551
552 This function modifies a transformation matrix to first
553 do a translation.  When translating, a number is added
554 to each component of a vector.
555
556 To apply this combined transformation to a vector, multiply
557 the vector by the created matrix using @rsMatrixMultiply().
558test: none
559end:
560
561function: rsMatrixTranspose
562t: rs_matrix4x4*, rs_matrix3x3*, rs_matrix2x2*
563ret: void
564arg: #1 m, "The matrix to transpose."
565summary: Transpose a matrix place
566description:
567 Transpose the matrix m in place.
568test: none
569end:
570