Home | History | Annotate | Download | only in include
      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