blob: d69ad1ab879c5e1236c39edaea2755b7e3dd1d5c [file] [log] [blame]
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -07001#
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.
Jean-Luc Brouilletbe216382015-03-22 12:44:27 -070044include:
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:
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:
120description:
121 Checks if a sphere is withing 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
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700149end:
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
174
175function: rsMatrixInverseTranspose
176ret: bool
177arg: rs_matrix4x4* m, "The matrix to modify."
178summary: Inverts and transpose a matrix in place
179description:
180 The matrix is first inverted then transposed.
181 Returns true if the matrix was successfully inverted.
182test: none
183end:
184
185
186function: rsMatrixLoad
187t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
188ret: void
189arg: #1* destination, "The matrix to set."
190arg: 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."
191summary: Load or copy a matrix
192description:
193 Set the elements of a matrix from an array of floats or from another matrix.
194
195 If loading from an array, the floats should be in row-major order, i.e. the element a
196 <code>row 0, column 0</code> should be first, followed by the element at
197 <code>row 0, column 1</code>, etc.
198
199 If loading from a matrix and the source is smaller than the destination, the rest of the
200 destination is filled with elements of the identity matrix. E.g.
201 loading a rs_matrix2x2 into a rs_matrix4x4 will give:
202 <table style="max-width:300px">
203 <tr><td>m00</td> <td>m01</td> <td>0.0</td> <td>0.0</td></tr>
204 <tr><td>m10</td> <td>m11</td> <td>0.0</td> <td>0.0</td></tr>
205 <tr><td>0.0</td> <td>0.0</td> <td>1.0</td> <td>0.0</td></tr>
206 <tr><td>0.0</td> <td>0.0</td> <td>0.0</td> <td>1.0</td></tr>
207 </table>
208test: none
209end:
210
211function: rsMatrixLoad
212t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
213ret: void
214arg: #1* destination
215arg: const #1* source, "The source matrix."
216test: none
217end:
218
219function: rsMatrixLoad
220t: rs_matrix3x3, rs_matrix2x2
221ret: void
222arg: rs_matrix4x4* destination
223arg: const #1* source
224test: none
225end:
226
227function: rsMatrixLoadFrustum
228ret: void
229arg: rs_matrix4x4* m, "The matrix to set."
230arg: float left
231arg: float right
232arg: float bottom
233arg: float top
234arg: float near
235arg: float far
236summary: Load a frustum projection matrix
237description:
238 Constructs a frustum projection matrix, transforming the box
239 identified by the six clipping planes <code>left, right, bottom, top,
240 near, far</code>.
241
242 To apply this projection to a vector, multiply the vector by the
243 created matrix using @rsMatrixMultiply().
244test: none
245end:
246
247function: rsMatrixLoadIdentity
248t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
249ret: void
250arg: #1* m, "The matrix to set."
251summary: Load identity matrix
252description:
253 Set the elements of a matrix to the identity matrix.
254test: none
255end:
256
257function: rsMatrixLoadMultiply
258t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
259ret: void
260arg: #1* m, "The matrix to set."
261arg: const #1* lhs, "The left matrix of the product."
262arg: const #1* rhs, "The right matrix of the product."
263summary: Multiply two matrices
264description:
265 Sets m to the matrix product of <code>lhs * rhs</code>.
266
267 To combine two 4x4 transformaton matrices, multiply the second transformation matrix
268 by the first transformation matrix. E.g. to create a transformation matrix that applies
269 the transformation s1 followed by s2, call
270 <code>rsMatrixLoadMultiply(&combined, &s2, &s1)</code>.
271
272 <b>Warning:</b> Prior to version 21, storing the result back into right matrix is not supported and
273 will result in undefined behavior. Use rsMatrixMulitply instead. E.g. instead of doing
274 rsMatrixLoadMultiply (&m2r, &m2r, &m2l), use rsMatrixMultiply (&m2r, &m2l).
275 rsMatrixLoadMultiply (&m2l, &m2r, &m2l) works as expected.
276test: none
277end:
278
279function: rsMatrixLoadOrtho
280ret: void
281arg: rs_matrix4x4* m, "The matrix to set."
282arg: float left
283arg: float right
284arg: float bottom
285arg: float top
286arg: float near
287arg: float far
288summary: Load an orthographic projection matrix
289description:
290 Constructs an orthographic projection matrix, transforming the box
291 identified by the six clipping planes <code>left, right, bottom, top,
292 near, far</code> into a unit cube with a corner at
293 <code>(-1, -1, -1)</code> and the opposite at <code>(1, 1, 1)</code>.
294
295 To apply this projection to a vector, multiply the vector by the
296 created matrix using @rsMatrixMultiply().
297
298 See https://en.wikipedia.org/wiki/Orthographic_projection .
299test: none
300end:
301
302function: rsMatrixLoadPerspective
303ret: void
304arg: rs_matrix4x4* m, "The matrix to set."
305arg: float fovy, "Field of view, in degrees along the Y axis."
306arg: float aspect, "Ratio of x / y."
307arg: float near, "The near clipping plane."
308arg: float far, "The far clipping plane."
309summary: Load a perspective projection matrix
310description:
311 Constructs a perspective projection matrix, assuming a symmetrical field of view.
312
313 To apply this projection to a vector, multiply the vector by the
314 created matrix using @rsMatrixMultiply().
315test: none
316end:
317
318function: rsMatrixLoadRotate
319ret: void
320arg: rs_matrix4x4* m, "The matrix to set."
321arg: float rot, "How much rotation to do, in degrees."
322arg: float x, "The x component of the vector that is the axis of rotation."
323arg: float y, "The y component of the vector that is the axis of rotation."
324arg: float z, "The z component of the vector that is the axis of rotation."
325summary: Load a rotation matrix
326description:
327 This function creates a rotation matrix. The axis of rotation is the
328 <code>(x, y, z)</code> vector.
329
330 To rotate a vector, multiply the vector by the created matrix
331 using @rsMatrixMultiply().
332
333 See http://en.wikipedia.org/wiki/Rotation_matrix .
334test: none
335end:
336
337function: rsMatrixLoadScale
338ret: void
339arg: rs_matrix4x4* m, "The matrix to set."
340arg: float x, "The multiple to scale the x components by."
341arg: float y, "The multiple to scale the y components by."
342arg: float z, "The multiple to scale the z components by."
343summary: Load a scaling matrix
344description:
345 This function creates a scaling matrix, where each component of a
346 vector is multiplied by a number. This number can be negative.
347
348 To scale a vector, multiply the vector by the created matrix
349 using @rsMatrixMultiply().
350test: none
351end:
352
353function: rsMatrixLoadTranslate
354ret: void
355arg: rs_matrix4x4* m, "The matrix to set."
356arg: float x, "The number to add to each x component."
357arg: float y, "The number to add to each y component."
358arg: float z, "The number to add to each z component."
359summary: Load a translation matrix
360description:
361 This function creates a translation matrix, where a
362 number is added to each element of a vector.
363
364 To translate a vector, multiply the vector by the created matrix
365 using @rsMatrixMultiply().
366test: none
367end:
368
369function: rsMatrixMultiply
370t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
371ret: void
372arg: #1* m, "The left matrix of the product and the matrix to be set."
373arg: const #1* rhs, "The right matrix of the product."
374summary: Multiply a matrix by a vector or another matrix
375description:
376 For the matrix by matrix variant, sets m to the matrix product <code>m * rhs</code>.
377
378 When combining two 4x4 transformation matrices using this function, the resulting
379 matrix will correspond to performing the rhs transformation first followed by
380 the original m transformation.
381
382 For the matrix by vector variant, returns the post-multiplication of the vector
383 by the matrix, ie. <code>m * in</code>.
384
385 When multiplying a float3 to a @rs_matrix4x4, the vector is expanded with (1).
386
387 When multiplying a float2 to a @rs_matrix4x4, the vector is expanded with (0, 1).
388
389 When multiplying a float2 to a @rs_matrix3x3, the vector is expanded with (0).
390
391 Starting with API 14, this function takes a const matrix as the first argument.
392test: none
393end:
394
395function: rsMatrixMultiply
396version: 9 13
397ret: float4
398arg: rs_matrix4x4* m
399arg: float4 in
400test: none
401end:
402
403function: rsMatrixMultiply
404version: 9 13
405ret: float4
406arg: rs_matrix4x4* m
407arg: float3 in
408test: none
409end:
410
411function: rsMatrixMultiply
412version: 9 13
413ret: float4
414arg: rs_matrix4x4* m
415arg: float2 in
416test: none
417end:
418
419function: rsMatrixMultiply
420version: 9 13
421ret: float3
422arg: rs_matrix3x3* m
423arg: float3 in
424test: none
425end:
426
427function: rsMatrixMultiply
428version: 9 13
429ret: float3
430arg: rs_matrix3x3* m
431arg: float2 in
432test: none
433end:
434
435function: rsMatrixMultiply
436version: 9 13
437ret: float2
438arg: rs_matrix2x2* m
439arg: float2 in
440test: none
441end:
442
443function: rsMatrixMultiply
444version: 14
445ret: float4
446arg: const rs_matrix4x4* m
447arg: float4 in
448test: none
449end:
450
451function: rsMatrixMultiply
452version: 14
453ret: float4
454arg: const rs_matrix4x4* m
455arg: float3 in
456test: none
457end:
458
459function: rsMatrixMultiply
460version: 14
461ret: float4
462arg: const rs_matrix4x4* m
463arg: float2 in
464test: none
465end:
466
467function: rsMatrixMultiply
468version: 14
469ret: float3
470arg: const rs_matrix3x3* m
471arg: float3 in
472test: none
473end:
474
475function: rsMatrixMultiply
476version: 14
477ret: float3
478arg: const rs_matrix3x3* m
479arg: float2 in
480test: none
481end:
482
483function: rsMatrixMultiply
484version: 14
485ret: float2
486arg: const rs_matrix2x2* m
487arg: float2 in
488test: none
489end:
490
491function: rsMatrixRotate
492ret: void
493arg: rs_matrix4x4* m, "The matrix to modify."
494arg: float rot, "How much rotation to do, in degrees."
495arg: float x, "The x component of the vector that is the axis of rotation."
496arg: float y, "The y component of the vector that is the axis of rotation."
497arg: float z, "The z component of the vector that is the axis of rotation."
498summary: Apply a rotation to a transformation matrix
499description:
500 Multiply the matrix m with a rotation matrix.
501
502 This function modifies a transformation matrix to first do a rotation.
503 The axis of rotation is the <code>(x, y, z)</code> vector.
504
505 To apply this combined transformation to a vector, multiply
506 the vector by the created matrix using @rsMatrixMultiply().
507test: none
508end:
509
510function: rsMatrixScale
511ret: void
512arg: rs_matrix4x4* m, "The matrix to modify."
513arg: float x, "The multiple to scale the x components by."
514arg: float y, "The multiple to scale the y components by."
515arg: float z, "The multiple to scale the z components by."
516summary: Apply a scaling to a transformation matrix
517description:
518 Multiply the matrix m with a scaling matrix.
519
520 This function modifies a transformation matrix to first do a scaling.
521 When scaling, each component of a vector is multiplied by a number.
522 This number can be negative.
523
524 To apply this combined transformation to a vector, multiply
525 the vector by the created matrix using @rsMatrixMultiply().
526test: none
527end:
528
529function: rsMatrixSet
530t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2
531ret: void
532arg: #1* m, "The matrix that will be modified."
533arg: uint32_t col, "The zero-based column of the element to be set."
534arg: uint32_t row, "The zero-based row of the element to be set."
535arg: float v, "The value to set."
536summary: Set one element
537description:
538 Set an element of a matrix.
539
540 <b>Warning:</b> The order of the column and row parameters may be unexpected.
541test: none
542end:
543
544function: rsMatrixTranslate
545ret: void
546arg: rs_matrix4x4* m, "The matrix to modify."
547arg: float x, "The number to add to each x component."
548arg: float y, "The number to add to each y component."
549arg: float z, "The number to add to each z component."
550summary: Apply a translation to a transformation matrix
551description:
552 Multiply the matrix m with a translation matrix.
553
554 This function modifies a transformation matrix to first
555 do a translation. When translating, a number is added
556 to each component of a vector.
557
558 To apply this combined transformation to a vector, multiply
559 the vector by the created matrix using @rsMatrixMultiply().
560test: none
561end:
562
563function: rsMatrixTranspose
564t: rs_matrix4x4*, rs_matrix3x3*, rs_matrix2x2*
565ret: void
566arg: #1 m, "The matrix to transpose."
567summary: Transpose a matrix place
568description:
569 Transpose the matrix m in place.
570test: none
571end: