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(&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 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(&combined, &s2, &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 (&m2r, &m2r, &m2l), use rsMatrixMultiply (&m2r, &m2l). 271 rsMatrixLoadMultiply (&m2l, &m2r, &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