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 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(&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. 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