1 /* 2 * Copyright (C) 2011 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 /** @file rs_matrix.rsh 18 * \brief Matrix functions. 19 * 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 * A few general notes: 25 * 26 * \li We use a zero-based index for rows and columns. E.g. the last element of 27 * a \ref rs_matrix4x4 is found at (3, 3). 28 * 29 * \li RenderScript uses column-based vectors. Transforming a vector is done by 30 * postmultiplying the vector, e.g. <em>(matrix * vector)</em>, as provided by 31 * \ref rsMatrixMultiply. 32 * 33 * \li To create a transformation matrix that performs two transformations at 34 * once, multiply the two source matrices, with the first transformation as the 35 * right argument. E.g. to create a transformation matrix that applies the 36 * transformation \e s1 followed by \e s2, call 37 * </c>rsMatrixLoadMultiply(&combined, &s2, &s1)</c>. 38 * This derives from <em>s2 * (s1 * v)</em>, which is <em>(s2 * s1) * v</em>. 39 * 40 * \li We have two style of functions to create transformation matrices: 41 * rsMatrixLoad<em>Transformation</em> and rsMatrix<em>Transformation</em>. The 42 * former style simply stores the transformation matrix in the first argument. 43 * The latter modifies a pre-existing transformation matrix so that the new 44 * transformation happens first. E.g. if you call \ref rsMatrixTranslate 45 * on a matrix that already does a scaling, the resulting matrix when applied 46 * to a vector will first do the translation then the scaling. 47 * 48 */ 49 50 #ifndef __RS_MATRIX_RSH__ 51 #define __RS_MATRIX_RSH__ 52 53 /** 54 * Set an element of a matrix. 55 * 56 * @param m The matrix that will be modified. 57 * @param col The zero-based column of the element to be set. 58 * @param row The zero-based row of the element to be set. 59 * @param v The value to set. 60 * 61 * \warning The order of the column and row parameters may be 62 * unexpected. 63 * 64 * @return void 65 */ 66 _RS_RUNTIME void __attribute__((overloadable)) 67 rsMatrixSet(rs_matrix4x4 *m, uint32_t col, uint32_t row, float v); 68 /** 69 * \overload 70 */ 71 _RS_RUNTIME void __attribute__((overloadable)) 72 rsMatrixSet(rs_matrix3x3 *m, uint32_t col, uint32_t row, float v); 73 /** 74 * \overload 75 */ 76 _RS_RUNTIME void __attribute__((overloadable)) 77 rsMatrixSet(rs_matrix2x2 *m, uint32_t col, uint32_t row, float v); 78 79 /** 80 * Returns one element of a matrix. 81 * 82 * @param m The matrix to extract the element from. 83 * @param col The zero-based column of the element to be extracted. 84 * @param row The zero-based row of the element to extracted. 85 * 86 * \warning The order of the column and row parameters may be 87 * unexpected. 88 * 89 * @return float 90 */ 91 _RS_RUNTIME float __attribute__((overloadable)) 92 rsMatrixGet(const rs_matrix4x4 *m, uint32_t col, uint32_t row); 93 /** 94 * \overload 95 */ 96 _RS_RUNTIME float __attribute__((overloadable)) 97 rsMatrixGet(const rs_matrix3x3 *m, uint32_t col, uint32_t row); 98 /** 99 * \overload 100 */ 101 _RS_RUNTIME float __attribute__((overloadable)) 102 rsMatrixGet(const rs_matrix2x2 *m, uint32_t col, uint32_t row); 103 104 /** 105 * Set the elements of a matrix to the identity matrix. 106 * 107 * @param m The matrix to set. 108 */ 109 extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix4x4 *m); 110 /** 111 * \overload 112 */ 113 extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix3x3 *m); 114 /** 115 * \overload 116 */ 117 extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix2x2 *m); 118 119 /** 120 * Set the elements of a matrix from an array of floats. 121 * 122 * The array of floats should be in row-major order, i.e. the element a 123 * <em>row 0, column 0</em> should be first, followed by the element at 124 * <em>row 0, column 1</em>, etc. 125 * 126 * @param m The matrix to set. 127 * @param v The array of values to set the matrix to. These arrays should be 128 * 4, 9, or 16 floats long, depending on the matrix size. 129 */ 130 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const float *v); 131 /** 132 * \overload 133 */ 134 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const float *v); 135 /** 136 * \overload 137 */ 138 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const float *v); 139 /** 140 * Set the elements of a matrix from another matrix. 141 * 142 * If the source matrix is smaller than the destination, the rest of the 143 * destination is filled with elements of the identity matrix. E.g. 144 * loading a rs_matrix2x2 into a rs_matrix4x4 will give: 145 * 146 * \htmlonly<table> 147 * <tr><td>m00</td><td>m01</td><td>0.0</td><td>0.0</td></tr> 148 * <tr><td>m10</td><td>m11</td><td>0.0</td><td>0.0</td></tr> 149 * <tr><td>0.0</td><td>0.0</td><td>1.0</td><td>0.0</td></tr> 150 * <tr><td>0.0</td><td>0.0</td><td>0.0</td><td>1.0</td></tr> 151 * </table>\endhtmlonly 152 * 153 * @param m The matrix to set. 154 * @param v The source matrix. 155 */ 156 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v); 157 /** 158 * \overload 159 */ 160 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v); 161 /** 162 * \overload 163 */ 164 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v); 165 /** 166 * \overload 167 */ 168 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v); 169 /** 170 * \overload 171 */ 172 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v); 173 174 /** 175 * Load a rotation matrix. 176 * 177 * This function creates a rotation matrix. The axis of rotation is the 178 * <em>(x, y, z)</em> vector. 179 * 180 * To rotate a vector, multiply the vector by the created matrix 181 * using \ref rsMatrixMultiply. 182 * 183 * See http://en.wikipedia.org/wiki/Rotation_matrix . 184 * 185 * @param m The matrix to set. 186 * @param rot How much rotation to do, in degrees. 187 * @param x The x component of the vector that is the axis of rotation. 188 * @param y The y component of the vector that is the axis of rotation. 189 * @param z The z component of the vector that is the axis of rotation. 190 */ 191 extern void __attribute__((overloadable)) 192 rsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z); 193 194 /** 195 * Load a scale matrix. 196 * 197 * This function creates a scaling matrix, where each component of a 198 * vector is multiplied by a number. This number can be negative. 199 * 200 * To scale a vector, multiply the vector by the created matrix 201 * using \ref rsMatrixMultiply. 202 * 203 * @param m The matrix to set. 204 * @param x The multiple to scale the x components by. 205 * @param y The multiple to scale the y components by. 206 * @param z The multiple to scale the z components by. 207 */ 208 extern void __attribute__((overloadable)) 209 rsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z); 210 211 /** 212 * Load a translation matrix. 213 * 214 * This function creates a translation matrix, where a 215 * number is added to each element of a vector. 216 * 217 * To translate a vector, multiply the vector by the created matrix 218 * using \ref rsMatrixMultiply. 219 * 220 * @param m The matrix to set. 221 * @param x The number to add to each x component. 222 * @param y The number to add to each y component. 223 * @param z The number to add to each z component. 224 */ 225 extern void __attribute__((overloadable)) 226 rsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z); 227 228 /** 229 * Multiply two matrices. 230 * 231 * Sets \e m to the matrix product of <em>lhs * rhs</em>. 232 * 233 * To combine two 4x4 transformaton matrices, multiply the second transformation matrix 234 * by the first transformation matrix. E.g. to create a transformation matrix that applies 235 * the transformation \e s1 followed by \e s2, call 236 * </c>rsMatrixLoadMultiply(&combined, &s2, &s1)</c>. 237 * 238 * \warning Prior to version 21, storing the result back into right matrix is not supported and 239 * will result in undefined behavior. Use rsMatrixMulitply instead. E.g. instead of doing 240 * rsMatrixLoadMultiply (&m2r, &m2r, &m2l), use rsMatrixMultiply (&m2r, &m2l). 241 * rsMatrixLoadMultiply (&m2l, &m2r, &m2l) works as expected. 242 * 243 * @param m The matrix to set. 244 * @param lhs The left matrix of the product. 245 * @param rhs The right matrix of the product. 246 */ 247 extern void __attribute__((overloadable)) 248 rsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs); 249 /** 250 * \overload 251 */ 252 extern void __attribute__((overloadable)) 253 rsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs); 254 /** 255 * \overload 256 */ 257 extern void __attribute__((overloadable)) 258 rsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs); 259 260 /** 261 * Multiply a matrix into another one. 262 * 263 * Sets \e m to the matrix product <em>m * rhs</em>. 264 * 265 * When combining two 4x4 transformation matrices using this function, the resulting 266 * matrix will correspond to performing the \e rhs transformation first followed by 267 * the original \e m transformation. 268 * 269 * @param m The left matrix of the product and the matrix to be set. 270 * @param rhs The right matrix of the product. 271 */ 272 extern void __attribute__((overloadable)) 273 rsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs); 274 /** 275 * \overload 276 */ 277 extern void __attribute__((overloadable)) 278 rsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs); 279 /** 280 * \overload 281 */ 282 extern void __attribute__((overloadable)) 283 rsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs); 284 285 /** 286 * Multiply the matrix \e m with a rotation matrix. 287 * 288 * This function modifies a transformation matrix to first do a rotation. 289 * The axis of rotation is the <em>(x, y, z)</em> vector. 290 * 291 * To apply this combined transformation to a vector, multiply 292 * the vector by the created matrix using \ref rsMatrixMultiply. 293 * 294 * @param m The matrix to modify. 295 * @param rot How much rotation to do, in degrees. 296 * @param x The x component of the vector that is the axis of rotation. 297 * @param y The y component of the vector that is the axis of rotation. 298 * @param z The z component of the vector that is the axis of rotation. 299 */ 300 extern void __attribute__((overloadable)) 301 rsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z); 302 303 /** 304 * Multiply the matrix \e m with a scaling matrix. 305 * 306 * This function modifies a transformation matrix to first do a scaling. 307 * When scaling, each component of a vector is multiplied by a number. 308 * This number can be negative. 309 * 310 * To apply this combined transformation to a vector, multiply 311 * the vector by the created matrix using \ref rsMatrixMultiply. 312 * 313 * @param m The matrix to modify. 314 * @param x The multiple to scale the x components by. 315 * @param y The multiple to scale the y components by. 316 * @param z The multiple to scale the z components by. 317 */ 318 extern void __attribute__((overloadable)) 319 rsMatrixScale(rs_matrix4x4 *m, float x, float y, float z); 320 321 /** 322 * Multiply the matrix \e m with a translation matrix. 323 * 324 * This function modifies a transformation matrix to first 325 * do a translation. When translating, a number is added 326 * to each component of a vector. 327 * 328 * To apply this combined transformation to a vector, multiply 329 * the vector by the created matrix using \ref rsMatrixMultiply. 330 * 331 * @param m The matrix to modify. 332 * @param x The number to add to each x component. 333 * @param y The number to add to each y component. 334 * @param z The number to add to each z component. 335 */ 336 extern void __attribute__((overloadable)) 337 rsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z); 338 339 /** 340 * Load an orthographic projection matrix. 341 * 342 * Constructs an orthographic projection matrix, transforming the box 343 * identified by the six clipping planes <em>left, right, bottom, top, 344 * near, far</em> into a unit cube with a corner at 345 * <em>(-1, -1, -1)</em> and the opposite at <em>(1, 1, 1)</em>. 346 * 347 * To apply this projection to a vector, multiply the vector by the 348 * created matrix using \ref rsMatrixMultiply. 349 * 350 * See https://en.wikipedia.org/wiki/Orthographic_projection . 351 * 352 * @param m The matrix to set. 353 * @param left 354 * @param right 355 * @param bottom 356 * @param top 357 * @param near 358 * @param far 359 */ 360 extern void __attribute__((overloadable)) 361 rsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far); 362 363 /** 364 * Load a frustum projection matrix. 365 * 366 * Constructs a frustum projection matrix, transforming the box 367 * identified by the six clipping planes <em>left, right, bottom, top, 368 * near, far</em>. 369 * 370 * To apply this projection to a vector, multiply the vector by the 371 * created matrix using \ref rsMatrixMultiply. 372 * 373 * @param m The matrix to set. 374 * @param left 375 * @param right 376 * @param bottom 377 * @param top 378 * @param near 379 * @param far 380 */ 381 extern void __attribute__((overloadable)) 382 rsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far); 383 384 /** 385 * Load a perspective projection matrix. 386 * 387 * Constructs a perspective projection matrix, assuming a symmetrical field of view. 388 * 389 * To apply this projection to a vector, multiply the vector by the 390 * created matrix using \ref rsMatrixMultiply. 391 * 392 * @param m The matrix to set. 393 * @param fovy Field of view, in degrees along the Y axis. 394 * @param aspect Ratio of x / y. 395 * @param near The near clipping plane. 396 * @param far The far clipping plane. 397 */ 398 extern void __attribute__((overloadable)) 399 rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far); 400 401 #if !defined(RS_VERSION) || (RS_VERSION < 14) 402 /** 403 * Multiply a vector by a matrix. 404 * 405 * Returns the post-multiplication of the vector by the matrix, ie. <em>m * in</em>. 406 * 407 * When multiplying a \e float3 to a \e rs_matrix4x4, the vector is expanded with (1). 408 * 409 * When multiplying a \e float2 to a \e rs_matrix4x4, the vector is expanded with (0, 1). 410 * 411 * When multiplying a \e float2 to a \e rs_matrix3x3, the vector is expanded with (0). 412 * 413 * This function is available in API version 10-13. Starting with API 14, 414 * the function takes a const matrix as the first argument. 415 */ 416 _RS_RUNTIME float4 __attribute__((overloadable)) 417 rsMatrixMultiply(rs_matrix4x4 *m, float4 in); 418 419 /** 420 * \overload 421 */ 422 _RS_RUNTIME float4 __attribute__((overloadable)) 423 rsMatrixMultiply(rs_matrix4x4 *m, float3 in); 424 425 /** 426 * \overload 427 */ 428 _RS_RUNTIME float4 __attribute__((overloadable)) 429 rsMatrixMultiply(rs_matrix4x4 *m, float2 in); 430 431 /** 432 * \overload 433 */ 434 _RS_RUNTIME float3 __attribute__((overloadable)) 435 rsMatrixMultiply(rs_matrix3x3 *m, float3 in); 436 437 /** 438 * \overload 439 */ 440 _RS_RUNTIME float3 __attribute__((overloadable)) 441 rsMatrixMultiply(rs_matrix3x3 *m, float2 in); 442 443 /** 444 * \overload 445 */ 446 _RS_RUNTIME float2 __attribute__((overloadable)) 447 rsMatrixMultiply(rs_matrix2x2 *m, float2 in); 448 #else 449 /** 450 * Multiply a vector by a matrix. 451 * 452 * Returns the post-multiplication of the vector of the matrix, i.e. <em>m * in</em>. 453 * 454 * When multiplying a \e float3 to a \e rs_matrix4x4, the vector is expanded with (1). 455 * 456 * When multiplying a \e float2 to a \e rs_matrix4x4, the vector is expanded with (0, 1). 457 * 458 * When multiplying a \e float2 to a \e rs_matrix3x3, the vector is expanded with (0). 459 * 460 * This function is available starting with API version 14. 461 */ 462 _RS_RUNTIME float4 __attribute__((overloadable)) 463 rsMatrixMultiply(const rs_matrix4x4 *m, float4 in); 464 465 /** 466 * \overload 467 */ 468 _RS_RUNTIME float4 __attribute__((overloadable)) 469 rsMatrixMultiply(const rs_matrix4x4 *m, float3 in); 470 471 /** 472 * \overload 473 */ 474 _RS_RUNTIME float4 __attribute__((overloadable)) 475 rsMatrixMultiply(const rs_matrix4x4 *m, float2 in); 476 477 /** 478 * \overload 479 */ 480 _RS_RUNTIME float3 __attribute__((overloadable)) 481 rsMatrixMultiply(const rs_matrix3x3 *m, float3 in); 482 483 /** 484 * \overload 485 */ 486 _RS_RUNTIME float3 __attribute__((overloadable)) 487 rsMatrixMultiply(const rs_matrix3x3 *m, float2 in); 488 489 /** 490 * \overload 491 */ 492 _RS_RUNTIME float2 __attribute__((overloadable)) 493 rsMatrixMultiply(const rs_matrix2x2 *m, float2 in); 494 #endif 495 496 497 /** 498 * Inverts a matrix in place. 499 * 500 * Returns true if the matrix was successfully inverted. 501 * 502 * @param m The matrix to invert. 503 */ 504 extern bool __attribute__((overloadable)) rsMatrixInverse(rs_matrix4x4 *m); 505 506 /** 507 * Inverts and transpose a matrix in place. 508 * 509 * The matrix is first inverted then transposed. 510 * Returns true if the matrix was successfully inverted. 511 * 512 * @param m The matrix to modify. 513 */ 514 extern bool __attribute__((overloadable)) rsMatrixInverseTranspose(rs_matrix4x4 *m); 515 516 /** 517 * Transpose the matrix m in place. 518 * 519 * @param m The matrix to transpose. 520 */ 521 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix4x4 *m); 522 /** 523 * \overload 524 */ 525 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix3x3 *m); 526 /** 527 * \overload 528 */ 529 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix2x2 *m); 530 531 532 #endif 533