/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Don't edit this file! It is auto-generated by frameworks/rs/api/generate.sh. /* * rs_matrix.rsh: Matrix Functions * * These functions let you manipulate square matrices of rank 2x2, 3x3, and 4x4. * They are particularly useful for graphical transformations and are compatible * with OpenGL. * * We use a zero-based index for rows and columns. E.g. the last element of a * rs_matrix4x4 is found at (3, 3). * * RenderScript uses column-major matrices and column-based vectors. Transforming * a vector is done by postmultiplying the vector, e.g. (matrix * vector), * as provided by rsMatrixMultiply(). * * To create a transformation matrix that performs two transformations at once, * multiply the two source matrices, with the first transformation as the right * argument. E.g. to create a transformation matrix that applies the * transformation s1 followed by s2, call rsMatrixLoadMultiply(&combined, &s2, &s1). * This derives from s2 * (s1 * v), which is (s2 * s1) * v. * * We have two style of functions to create transformation matrices: * rsMatrixLoadTransformation and rsMatrixTransformation. The former * style simply stores the transformation matrix in the first argument. The latter * modifies a pre-existing transformation matrix so that the new transformation * happens first. E.g. if you call rsMatrixTranslate() on a matrix that already * does a scaling, the resulting matrix when applied to a vector will first do the * translation then the scaling. */ #ifndef RENDERSCRIPT_RS_MATRIX_RSH #define RENDERSCRIPT_RS_MATRIX_RSH #include "rs_vector_math.rsh" /* * rsExtractFrustumPlanes: Compute frustum planes * * Computes 6 frustum planes from the view projection matrix * * Parameters: * viewProj: Matrix to extract planes from. * left: Left plane. * right: Right plane. * top: Top plane. * bottom: Bottom plane. * near: Near plane. * far: Far plane. */ static inline void __attribute__((always_inline, overloadable)) rsExtractFrustumPlanes(const rs_matrix4x4* viewProj, float4* left, float4* right, float4* top, float4* bottom, float4* near, float4* far) { // x y z w = a b c d in the plane equation left->x = viewProj->m[3] + viewProj->m[0]; left->y = viewProj->m[7] + viewProj->m[4]; left->z = viewProj->m[11] + viewProj->m[8]; left->w = viewProj->m[15] + viewProj->m[12]; right->x = viewProj->m[3] - viewProj->m[0]; right->y = viewProj->m[7] - viewProj->m[4]; right->z = viewProj->m[11] - viewProj->m[8]; right->w = viewProj->m[15] - viewProj->m[12]; top->x = viewProj->m[3] - viewProj->m[1]; top->y = viewProj->m[7] - viewProj->m[5]; top->z = viewProj->m[11] - viewProj->m[9]; top->w = viewProj->m[15] - viewProj->m[13]; bottom->x = viewProj->m[3] + viewProj->m[1]; bottom->y = viewProj->m[7] + viewProj->m[5]; bottom->z = viewProj->m[11] + viewProj->m[9]; bottom->w = viewProj->m[15] + viewProj->m[13]; near->x = viewProj->m[3] + viewProj->m[2]; near->y = viewProj->m[7] + viewProj->m[6]; near->z = viewProj->m[11] + viewProj->m[10]; near->w = viewProj->m[15] + viewProj->m[14]; far->x = viewProj->m[3] - viewProj->m[2]; far->y = viewProj->m[7] - viewProj->m[6]; far->z = viewProj->m[11] - viewProj->m[10]; far->w = viewProj->m[15] - viewProj->m[14]; float len = length(left->xyz); *left /= len; len = length(right->xyz); *right /= len; len = length(top->xyz); *top /= len; len = length(bottom->xyz); *bottom /= len; len = length(near->xyz); *near /= len; len = length(far->xyz); *far /= len; } /* * rsIsSphereInFrustum: Checks if a sphere is within the frustum planes * * Returns true if the sphere is within the 6 frustum planes. * * Parameters: * sphere: float4 representing the sphere. * left: Left plane. * right: Right plane. * top: Top plane. * bottom: Bottom plane. * near: Near plane. * far: Far plane. */ static inline bool __attribute__((always_inline, overloadable)) rsIsSphereInFrustum(float4* sphere, float4* left, float4* right, float4* top, float4* bottom, float4* near, float4* far) { float distToCenter = dot(left->xyz, sphere->xyz) + left->w; if (distToCenter < -sphere->w) { return false; } distToCenter = dot(right->xyz, sphere->xyz) + right->w; if (distToCenter < -sphere->w) { return false; } distToCenter = dot(top->xyz, sphere->xyz) + top->w; if (distToCenter < -sphere->w) { return false; } distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w; if (distToCenter < -sphere->w) { return false; } distToCenter = dot(near->xyz, sphere->xyz) + near->w; if (distToCenter < -sphere->w) { return false; } distToCenter = dot(far->xyz, sphere->xyz) + far->w; if (distToCenter < -sphere->w) { return false; } return true; } /* * rsMatrixGet: Get one element * * Returns one element of a matrix. * * Warning: The order of the column and row parameters may be unexpected. * * Parameters: * m: Matrix to extract the element from. * col: Zero-based column of the element to be extracted. * row: Zero-based row of the element to extracted. */ extern float __attribute__((overloadable)) rsMatrixGet(const rs_matrix4x4* m, uint32_t col, uint32_t row); extern float __attribute__((overloadable)) rsMatrixGet(const rs_matrix3x3* m, uint32_t col, uint32_t row); extern float __attribute__((overloadable)) rsMatrixGet(const rs_matrix2x2* m, uint32_t col, uint32_t row); /* * rsMatrixInverse: Inverts a matrix in place * * Returns true if the matrix was successfully inverted. * * Parameters: * m: Matrix to invert. */ extern bool __attribute__((overloadable)) rsMatrixInverse(rs_matrix4x4* m); /* * rsMatrixInverseTranspose: Inverts and transpose a matrix in place * * The matrix is first inverted then transposed. Returns true if the matrix was * successfully inverted. * * Parameters: * m: Matrix to modify. */ extern bool __attribute__((overloadable)) rsMatrixInverseTranspose(rs_matrix4x4* m); /* * rsMatrixLoad: Load or copy a matrix * * Set the elements of a matrix from an array of floats or from another matrix. * * If loading from an array, the floats should be in row-major order, i.e. the element a * row 0, column 0 should be first, followed by the element at * row 0, column 1, etc. * * If loading from a matrix and the source is smaller than the destination, the rest * of the destination is filled with elements of the identity matrix. E.g. * loading a rs_matrix2x2 into a rs_matrix4x4 will give: * * m00 m01 0.0 0.0 * m10 m11 0.0 0.0 * 0.0 0.0 1.0 0.0 * 0.0 0.0 0.0 1.0 * * * Parameters: * destination: Matrix to set. * array: Array of values to set the matrix to. These arrays should be 4, 9, or 16 floats long, depending on the matrix size. * source: Source matrix. */ extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4* destination, const float* array); extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3* destination, const float* array); extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2* destination, const float* array); extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4* destination, const rs_matrix4x4* source); extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3* destination, const rs_matrix3x3* source); extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2* destination, const rs_matrix2x2* source); extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4* destination, const rs_matrix3x3* source); extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4* destination, const rs_matrix2x2* source); /* * rsMatrixLoadFrustum: Load a frustum projection matrix * * Constructs a frustum projection matrix, transforming the box identified by * the six clipping planes left, right, bottom, top, near, far. * * To apply this projection to a vector, multiply the vector by the created * matrix using rsMatrixMultiply(). * * Parameters: * m: Matrix to set. */ extern void __attribute__((overloadable)) rsMatrixLoadFrustum(rs_matrix4x4* m, float left, float right, float bottom, float top, float near, float far); /* * rsMatrixLoadIdentity: Load identity matrix * * Set the elements of a matrix to the identity matrix. * * Parameters: * m: Matrix to set. */ extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix4x4* m); extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix3x3* m); extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix2x2* m); /* * rsMatrixLoadMultiply: Multiply two matrices * * Sets m to the matrix product of lhs * rhs. * * To combine two 4x4 transformaton matrices, multiply the second transformation matrix * by the first transformation matrix. E.g. to create a transformation matrix that applies * the transformation s1 followed by s2, call rsMatrixLoadMultiply(&combined, &s2, &s1). * * Warning: Prior to version 21, storing the result back into right matrix is not supported and * will result in undefined behavior. Use rsMatrixMulitply instead. E.g. instead of doing * rsMatrixLoadMultiply (&m2r, &m2r, &m2l), use rsMatrixMultiply (&m2r, &m2l). * rsMatrixLoadMultiply (&m2l, &m2r, &m2l) works as expected. * * Parameters: * m: Matrix to set. * lhs: Left matrix of the product. * rhs: Right matrix of the product. */ extern void __attribute__((overloadable)) rsMatrixLoadMultiply(rs_matrix4x4* m, const rs_matrix4x4* lhs, const rs_matrix4x4* rhs); extern void __attribute__((overloadable)) rsMatrixLoadMultiply(rs_matrix3x3* m, const rs_matrix3x3* lhs, const rs_matrix3x3* rhs); extern void __attribute__((overloadable)) rsMatrixLoadMultiply(rs_matrix2x2* m, const rs_matrix2x2* lhs, const rs_matrix2x2* rhs); /* * rsMatrixLoadOrtho: Load an orthographic projection matrix * * Constructs an orthographic projection matrix, transforming the box identified by the * six clipping planes left, right, bottom, top, near, far into a unit cube * with a corner at (-1, -1, -1) and the opposite at (1, 1, 1). * * To apply this projection to a vector, multiply the vector by the created matrix * using rsMatrixMultiply(). * * See https://en.wikipedia.org/wiki/Orthographic_projection . * * Parameters: * m: Matrix to set. */ extern void __attribute__((overloadable)) rsMatrixLoadOrtho(rs_matrix4x4* m, float left, float right, float bottom, float top, float near, float far); /* * rsMatrixLoadPerspective: Load a perspective projection matrix * * Constructs a perspective projection matrix, assuming a symmetrical field of view. * * To apply this projection to a vector, multiply the vector by the created matrix * using rsMatrixMultiply(). * * Parameters: * m: Matrix to set. * fovy: Field of view, in degrees along the Y axis. * aspect: Ratio of x / y. * near: Near clipping plane. * far: Far clipping plane. */ extern void __attribute__((overloadable)) rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far); /* * rsMatrixLoadRotate: Load a rotation matrix * * This function creates a rotation matrix. The axis of rotation is the (x, y, z) vector. * * To rotate a vector, multiply the vector by the created matrix using rsMatrixMultiply(). * * See http://en.wikipedia.org/wiki/Rotation_matrix . * * Parameters: * m: Matrix to set. * rot: How much rotation to do, in degrees. * x: X component of the vector that is the axis of rotation. * y: Y component of the vector that is the axis of rotation. * z: Z component of the vector that is the axis of rotation. */ extern void __attribute__((overloadable)) rsMatrixLoadRotate(rs_matrix4x4* m, float rot, float x, float y, float z); /* * rsMatrixLoadScale: Load a scaling matrix * * This function creates a scaling matrix, where each component of a vector is multiplied * by a number. This number can be negative. * * To scale a vector, multiply the vector by the created matrix using rsMatrixMultiply(). * * Parameters: * m: Matrix to set. * x: Multiple to scale the x components by. * y: Multiple to scale the y components by. * z: Multiple to scale the z components by. */ extern void __attribute__((overloadable)) rsMatrixLoadScale(rs_matrix4x4* m, float x, float y, float z); /* * rsMatrixLoadTranslate: Load a translation matrix * * This function creates a translation matrix, where a number is added to each element of * a vector. * * To translate a vector, multiply the vector by the created matrix using * rsMatrixMultiply(). * * Parameters: * m: Matrix to set. * x: Number to add to each x component. * y: Number to add to each y component. * z: Number to add to each z component. */ extern void __attribute__((overloadable)) rsMatrixLoadTranslate(rs_matrix4x4* m, float x, float y, float z); /* * rsMatrixMultiply: Multiply a matrix by a vector or another matrix * * For the matrix by matrix variant, sets m to the matrix product m * rhs. * * When combining two 4x4 transformation matrices using this function, the resulting * matrix will correspond to performing the rhs transformation first followed by * the original m transformation. * * For the matrix by vector variant, returns the post-multiplication of the vector * by the matrix, ie. m * in. * * When multiplying a float3 to a rs_matrix4x4, the vector is expanded with (1). * * When multiplying a float2 to a rs_matrix4x4, the vector is expanded with (0, 1). * * When multiplying a float2 to a rs_matrix3x3, the vector is expanded with (0). * * Starting with API 14, this function takes a const matrix as the first argument. * * Parameters: * m: Left matrix of the product and the matrix to be set. * rhs: Right matrix of the product. */ extern void __attribute__((overloadable)) rsMatrixMultiply(rs_matrix4x4* m, const rs_matrix4x4* rhs); extern void __attribute__((overloadable)) rsMatrixMultiply(rs_matrix3x3* m, const rs_matrix3x3* rhs); extern void __attribute__((overloadable)) rsMatrixMultiply(rs_matrix2x2* m, const rs_matrix2x2* rhs); #if !defined(RS_VERSION) || (RS_VERSION <= 13) extern float4 __attribute__((overloadable)) rsMatrixMultiply(rs_matrix4x4* m, float4 in); #endif #if !defined(RS_VERSION) || (RS_VERSION <= 13) extern float4 __attribute__((overloadable)) rsMatrixMultiply(rs_matrix4x4* m, float3 in); #endif #if !defined(RS_VERSION) || (RS_VERSION <= 13) extern float4 __attribute__((overloadable)) rsMatrixMultiply(rs_matrix4x4* m, float2 in); #endif #if !defined(RS_VERSION) || (RS_VERSION <= 13) extern float3 __attribute__((overloadable)) rsMatrixMultiply(rs_matrix3x3* m, float3 in); #endif #if !defined(RS_VERSION) || (RS_VERSION <= 13) extern float3 __attribute__((overloadable)) rsMatrixMultiply(rs_matrix3x3* m, float2 in); #endif #if !defined(RS_VERSION) || (RS_VERSION <= 13) extern float2 __attribute__((overloadable)) rsMatrixMultiply(rs_matrix2x2* m, float2 in); #endif #if (defined(RS_VERSION) && (RS_VERSION >= 14)) extern float4 __attribute__((overloadable)) rsMatrixMultiply(const rs_matrix4x4* m, float4 in); #endif #if (defined(RS_VERSION) && (RS_VERSION >= 14)) extern float4 __attribute__((overloadable)) rsMatrixMultiply(const rs_matrix4x4* m, float3 in); #endif #if (defined(RS_VERSION) && (RS_VERSION >= 14)) extern float4 __attribute__((overloadable)) rsMatrixMultiply(const rs_matrix4x4* m, float2 in); #endif #if (defined(RS_VERSION) && (RS_VERSION >= 14)) extern float3 __attribute__((overloadable)) rsMatrixMultiply(const rs_matrix3x3* m, float3 in); #endif #if (defined(RS_VERSION) && (RS_VERSION >= 14)) extern float3 __attribute__((overloadable)) rsMatrixMultiply(const rs_matrix3x3* m, float2 in); #endif #if (defined(RS_VERSION) && (RS_VERSION >= 14)) extern float2 __attribute__((overloadable)) rsMatrixMultiply(const rs_matrix2x2* m, float2 in); #endif /* * rsMatrixRotate: Apply a rotation to a transformation matrix * * Multiply the matrix m with a rotation matrix. * * This function modifies a transformation matrix to first do a rotation. The axis of * rotation is the (x, y, z) vector. * * To apply this combined transformation to a vector, multiply the vector by the created * matrix using rsMatrixMultiply(). * * Parameters: * m: Matrix to modify. * rot: How much rotation to do, in degrees. * x: X component of the vector that is the axis of rotation. * y: Y component of the vector that is the axis of rotation. * z: Z component of the vector that is the axis of rotation. */ extern void __attribute__((overloadable)) rsMatrixRotate(rs_matrix4x4* m, float rot, float x, float y, float z); /* * rsMatrixScale: Apply a scaling to a transformation matrix * * Multiply the matrix m with a scaling matrix. * * This function modifies a transformation matrix to first do a scaling. When scaling, * each component of a vector is multiplied by a number. This number can be negative. * * To apply this combined transformation to a vector, multiply the vector by the created * matrix using rsMatrixMultiply(). * * Parameters: * m: Matrix to modify. * x: Multiple to scale the x components by. * y: Multiple to scale the y components by. * z: Multiple to scale the z components by. */ extern void __attribute__((overloadable)) rsMatrixScale(rs_matrix4x4* m, float x, float y, float z); /* * rsMatrixSet: Set one element * * Set an element of a matrix. * * Warning: The order of the column and row parameters may be unexpected. * * Parameters: * m: Matrix that will be modified. * col: Zero-based column of the element to be set. * row: Zero-based row of the element to be set. * v: Value to set. */ extern void __attribute__((overloadable)) rsMatrixSet(rs_matrix4x4* m, uint32_t col, uint32_t row, float v); extern void __attribute__((overloadable)) rsMatrixSet(rs_matrix3x3* m, uint32_t col, uint32_t row, float v); extern void __attribute__((overloadable)) rsMatrixSet(rs_matrix2x2* m, uint32_t col, uint32_t row, float v); /* * rsMatrixTranslate: Apply a translation to a transformation matrix * * Multiply the matrix m with a translation matrix. * * This function modifies a transformation matrix to first do a translation. When * translating, a number is added to each component of a vector. * * To apply this combined transformation to a vector, multiply the vector by the * created matrix using rsMatrixMultiply(). * * Parameters: * m: Matrix to modify. * x: Number to add to each x component. * y: Number to add to each y component. * z: Number to add to each z component. */ extern void __attribute__((overloadable)) rsMatrixTranslate(rs_matrix4x4* m, float x, float y, float z); /* * rsMatrixTranspose: Transpose a matrix place * * Transpose the matrix m in place. * * Parameters: * m: Matrix to transpose. */ extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix4x4* m); extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix3x3* m); extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix2x2* m); #endif // RENDERSCRIPT_RS_MATRIX_RSH