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 17 header: 18 summary: Matrix Functions 19 description: 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. 44 include: 45 #include "rs_vector_math.rsh" 46 end: 47 48 function: rsExtractFrustumPlanes 49 version: 9 23 50 ret: void 51 arg: const rs_matrix4x4* viewProj, "Matrix to extract planes from." 52 arg: float4* left, "Left plane." 53 arg: float4* right, "Right plane." 54 arg: float4* top, "Top plane." 55 arg: float4* bottom, "Bottom plane." 56 arg: float4* near, "Near plane." 57 arg: float4* far, "Far plane." 58 summary: Compute frustum planes 59 description: 60 Computes 6 frustum planes from the view projection matrix 61 inline: 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; 105 test: none 106 end: 107 108 # New version. Same signature but doesn't contain a body. 109 function: rsExtractFrustumPlanes 110 version: 24 111 ret: void 112 arg: const rs_matrix4x4* viewProj 113 arg: float4* left 114 arg: float4* righ 115 arg: float4* top 116 arg: float4* bottom 117 arg: float4* near 118 arg: float4* far 119 test: none 120 end: 121 122 function: rsIsSphereInFrustum 123 version: 9 23 124 attrib: always_inline 125 ret: bool 126 arg: float4* sphere, "float4 representing the sphere." 127 arg: float4* left, "Left plane." 128 arg: float4* right, "Right plane." 129 arg: float4* top, "Top plane." 130 arg: float4* bottom, "Bottom plane." 131 arg: float4* near, "Near plane." 132 arg: float4* far, "Far plane." 133 summary: Checks if a sphere is within the frustum planes 134 description: 135 Returns true if the sphere is within the 6 frustum planes. 136 inline: 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; 162 test: none 163 end: 164 165 # New version. Same signature but doesn't contain a body. 166 function: rsIsSphereInFrustum 167 version: 24 168 ret: bool 169 arg: float4* sphere 170 arg: float4* left 171 arg: float4* right 172 arg: float4* top 173 arg: float4* bottom 174 arg: float4* near 175 arg: float4* far 176 test: none 177 end: 178 179 function: rsMatrixGet 180 t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2 181 ret: float 182 arg: const #1* m, "Matrix to extract the element from." 183 arg: uint32_t col, "Zero-based column of the element to be extracted." 184 arg: uint32_t row, "Zero-based row of the element to extracted." 185 summary: Get one element 186 description: 187 Returns one element of a matrix. 188 189 <b>Warning:</b> The order of the column and row parameters may be unexpected. 190 test: none 191 end: 192 193 function: rsMatrixInverse 194 ret: bool 195 arg: rs_matrix4x4* m, "Matrix to invert." 196 summary: Inverts a matrix in place 197 description: 198 Returns true if the matrix was successfully inverted. 199 test: none 200 end: 201 202 function: rsMatrixInverseTranspose 203 ret: bool 204 arg: rs_matrix4x4* m, "Matrix to modify." 205 summary: Inverts and transpose a matrix in place 206 description: 207 The matrix is first inverted then transposed. Returns true if the matrix was 208 successfully inverted. 209 test: none 210 end: 211 212 function: rsMatrixLoad 213 t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2 214 ret: void 215 arg: #1* destination, "Matrix to set." 216 arg: 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." 217 summary: Load or copy a matrix 218 description: 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> 234 test: none 235 end: 236 237 function: rsMatrixLoad 238 t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2 239 ret: void 240 arg: #1* destination 241 arg: const #1* source, "Source matrix." 242 test: none 243 end: 244 245 function: rsMatrixLoad 246 t: rs_matrix3x3, rs_matrix2x2 247 ret: void 248 arg: rs_matrix4x4* destination 249 arg: const #1* source 250 test: none 251 end: 252 253 function: rsMatrixLoadFrustum 254 ret: void 255 arg: rs_matrix4x4* m, "Matrix to set." 256 arg: float left 257 arg: float right 258 arg: float bottom 259 arg: float top 260 arg: float near 261 arg: float far 262 summary: Load a frustum projection matrix 263 description: 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(). 269 test: none 270 end: 271 272 function: rsMatrixLoadIdentity 273 t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2 274 ret: void 275 arg: #1* m, "Matrix to set." 276 summary: Load identity matrix 277 description: 278 Set the elements of a matrix to the identity matrix. 279 test: none 280 end: 281 282 function: rsMatrixLoadMultiply 283 t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2 284 ret: void 285 arg: #1* m, "Matrix to set." 286 arg: const #1* lhs, "Left matrix of the product." 287 arg: const #1* rhs, "Right matrix of the product." 288 summary: Multiply two matrices 289 description: 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(&combined, &s2, &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 (&m2r, &m2r, &m2l), use rsMatrixMultiply (&m2r, &m2l). 299 rsMatrixLoadMultiply (&m2l, &m2r, &m2l) works as expected. 300 test: none 301 end: 302 303 function: rsMatrixLoadOrtho 304 ret: void 305 arg: rs_matrix4x4* m, "Matrix to set." 306 arg: float left 307 arg: float right 308 arg: float bottom 309 arg: float top 310 arg: float near 311 arg: float far 312 summary: Load an orthographic projection matrix 313 description: 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 . 322 test: none 323 end: 324 325 function: rsMatrixLoadPerspective 326 ret: void 327 arg: rs_matrix4x4* m, "Matrix to set." 328 arg: float fovy, "Field of view, in degrees along the Y axis." 329 arg: float aspect, "Ratio of x / y." 330 arg: float near, "Near clipping plane." 331 arg: float far, "Far clipping plane." 332 summary: Load a perspective projection matrix 333 description: 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(). 338 test: none 339 end: 340 341 function: rsMatrixLoadRotate 342 ret: void 343 arg: rs_matrix4x4* m, "Matrix to set." 344 arg: float rot, "How much rotation to do, in degrees." 345 arg: float x, "X component of the vector that is the axis of rotation." 346 arg: float y, "Y component of the vector that is the axis of rotation." 347 arg: float z, "Z component of the vector that is the axis of rotation." 348 summary: Load a rotation matrix 349 description: 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 . 355 test: none 356 end: 357 358 function: rsMatrixLoadScale 359 ret: void 360 arg: rs_matrix4x4* m, "Matrix to set." 361 arg: float x, "Multiple to scale the x components by." 362 arg: float y, "Multiple to scale the y components by." 363 arg: float z, "Multiple to scale the z components by." 364 summary: Load a scaling matrix 365 description: 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(). 370 test: none 371 end: 372 373 function: rsMatrixLoadTranslate 374 ret: void 375 arg: rs_matrix4x4* m, "Matrix to set." 376 arg: float x, "Number to add to each x component." 377 arg: float y, "Number to add to each y component." 378 arg: float z, "Number to add to each z component." 379 summary: Load a translation matrix 380 description: 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(). 386 test: none 387 end: 388 389 function: rsMatrixMultiply 390 t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2 391 ret: void 392 arg: #1* m, "Left matrix of the product and the matrix to be set." 393 arg: const #1* rhs, "Right matrix of the product." 394 summary: Multiply a matrix by a vector or another matrix 395 description: 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. 412 test: none 413 end: 414 415 function: rsMatrixMultiply 416 version: 9 13 417 ret: float4 418 arg: rs_matrix4x4* m 419 arg: float4 in 420 test: none 421 end: 422 423 function: rsMatrixMultiply 424 version: 9 13 425 ret: float4 426 arg: rs_matrix4x4* m 427 arg: float3 in 428 test: none 429 end: 430 431 function: rsMatrixMultiply 432 version: 9 13 433 ret: float4 434 arg: rs_matrix4x4* m 435 arg: float2 in 436 test: none 437 end: 438 439 function: rsMatrixMultiply 440 version: 9 13 441 ret: float3 442 arg: rs_matrix3x3* m 443 arg: float3 in 444 test: none 445 end: 446 447 function: rsMatrixMultiply 448 version: 9 13 449 ret: float3 450 arg: rs_matrix3x3* m 451 arg: float2 in 452 test: none 453 end: 454 455 function: rsMatrixMultiply 456 version: 9 13 457 ret: float2 458 arg: rs_matrix2x2* m 459 arg: float2 in 460 test: none 461 end: 462 463 function: rsMatrixMultiply 464 version: 14 465 ret: float4 466 arg: const rs_matrix4x4* m 467 arg: float4 in 468 test: none 469 end: 470 471 function: rsMatrixMultiply 472 version: 14 473 ret: float4 474 arg: const rs_matrix4x4* m 475 arg: float3 in 476 test: none 477 end: 478 479 function: rsMatrixMultiply 480 version: 14 481 ret: float4 482 arg: const rs_matrix4x4* m 483 arg: float2 in 484 test: none 485 end: 486 487 function: rsMatrixMultiply 488 version: 14 489 ret: float3 490 arg: const rs_matrix3x3* m 491 arg: float3 in 492 test: none 493 end: 494 495 function: rsMatrixMultiply 496 version: 14 497 ret: float3 498 arg: const rs_matrix3x3* m 499 arg: float2 in 500 test: none 501 end: 502 503 function: rsMatrixMultiply 504 version: 14 505 ret: float2 506 arg: const rs_matrix2x2* m 507 arg: float2 in 508 test: none 509 end: 510 511 function: rsMatrixRotate 512 ret: void 513 arg: rs_matrix4x4* m, "Matrix to modify." 514 arg: float rot, "How much rotation to do, in degrees." 515 arg: float x, "X component of the vector that is the axis of rotation." 516 arg: float y, "Y component of the vector that is the axis of rotation." 517 arg: float z, "Z component of the vector that is the axis of rotation." 518 summary: Apply a rotation to a transformation matrix 519 description: 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(). 527 test: none 528 end: 529 530 function: rsMatrixScale 531 ret: void 532 arg: rs_matrix4x4* m, "Matrix to modify." 533 arg: float x, "Multiple to scale the x components by." 534 arg: float y, "Multiple to scale the y components by." 535 arg: float z, "Multiple to scale the z components by." 536 summary: Apply a scaling to a transformation matrix 537 description: 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(). 545 test: none 546 end: 547 548 function: rsMatrixSet 549 t: rs_matrix4x4, rs_matrix3x3, rs_matrix2x2 550 ret: void 551 arg: #1* m, "Matrix that will be modified." 552 arg: uint32_t col, "Zero-based column of the element to be set." 553 arg: uint32_t row, "Zero-based row of the element to be set." 554 arg: float v, "Value to set." 555 summary: Set one element 556 description: 557 Set an element of a matrix. 558 559 <b>Warning:</b> The order of the column and row parameters may be unexpected. 560 test: none 561 end: 562 563 function: rsMatrixTranslate 564 ret: void 565 arg: rs_matrix4x4* m, "Matrix to modify." 566 arg: float x, "Number to add to each x component." 567 arg: float y, "Number to add to each y component." 568 arg: float z, "Number to add to each z component." 569 summary: Apply a translation to a transformation matrix 570 description: 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(). 578 test: none 579 end: 580 581 function: rsMatrixTranspose 582 t: rs_matrix4x4*, rs_matrix3x3*, rs_matrix2x2* 583 ret: void 584 arg: #1 m, "Matrix to transpose." 585 summary: Transpose a matrix place 586 description: 587 Transpose the matrix m in place. 588 test: none 589 end: 590