void matrixMultiply (CompTransform *product, const CompTransform *transformA, const CompTransform *transformB) { matmul4 (product->m, transformA->m, transformB->m); }
/** * Multiply a matrix by an array of floats with known properties. * * \param mat pointer to a GLmatrix structure containing the left multiplication * matrix, and that will receive the product result. * \param m right multiplication matrix array. * \param flags flags of the matrix \p m. * * Joins both flags and marks the type and inverse as dirty. Calls matmul34() * if both matrices are 3D, or matmul4() otherwise. */ static void matrix_multf( GLmatrix *mat, const GLfloat *m, GLuint flags ) { mat->flags |= (flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE); if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) matmul34( mat->m, mat->m, m ); else matmul4( mat->m, mat->m, m ); }
/** * Matrix multiplication. * * \param dest left and destination matrix. * \param m right matrix array. * * Marks the matrix flags with general flag, and type and inverse dirty flags. * Calls matmul4() for the multiplication. */ void _math_matrix_mul_floats( GLmatrix *dest, const GLfloat *m ) { dest->flags |= (MAT_FLAG_GENERAL | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE | MAT_DIRTY_FLAGS); matmul4( dest->m, dest->m, m ); }
GLMatrix operator* (const GLMatrix& lhs, const GLMatrix& rhs) { GLMatrix result; matmul4 (result.m, lhs.m, rhs.m); return result; }
/** * Dumps the contents of a GLmatrix structure. * * \param m pointer to the GLmatrix structure. */ void _math_matrix_print( const GLmatrix *m ) { GLfloat prod[16]; _mesa_debug(NULL, "Matrix type: %s, flags: %x\n", types[m->type], m->flags); print_matrix_floats(m->m); _mesa_debug(NULL, "Inverse: \n"); print_matrix_floats(m->inv); matmul4(prod, m->m, m->inv); _mesa_debug(NULL, "Mat * Inverse:\n"); print_matrix_floats(prod); }
/** * Matrix multiplication. * * \param dest destination matrix. * \param a left matrix. * \param b right matrix. * * Joins both flags and marks the type and inverse as dirty. Calls matmul34() * if both matrices are 3D, or matmul4() otherwise. */ void _math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ) { dest->flags = (a->flags | b->flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE); if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D)) matmul34( dest->m, a->m, b->m ); else matmul4( dest->m, a->m, b->m ); }
void gl_Frustum2(GLdouble mat[16], GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval ) { GLdouble x, y, a, b, c, d; GLdouble m[16]; // GLmatrix *mat = 0; // GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glFrustrum" ); if ((nearval<=0.0 || farval<=0.0) || (nearval == farval) || (left == right) || (top == bottom)) { // gl_error( ctx, GL_INVALID_VALUE, "glFrustum(near or far)" ); return; } x = (2.0*nearval) / (right-left); y = (2.0*nearval) / (top-bottom); a = (right+left) / (right-left); b = (top+bottom) / (top-bottom); c = -(farval+nearval) / ( farval-nearval); d = -(2.0*farval*nearval) / (farval-nearval); /* error? */ #define M(row,col) m[col*4+row] M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; #undef M // gl_mat_mul_floats( mat, m, MAT_FLAG_PERSPECTIVE ); matmul4(mat, mat, m); #if 0 if (ctx->Transform.MatrixMode == GL_PROJECTION) { /* Need to keep a stack of near/far values in case the user push/pops * the projection matrix stack so that we can call Driver.NearFar() * after a pop. */ ctx->NearFarStack[ctx->ProjectionStackDepth][0] = nearval; ctx->NearFarStack[ctx->ProjectionStackDepth][1] = farval; if (ctx->Driver.NearFar) { (*ctx->Driver.NearFar)( ctx, nearval, farval ); } } #endif }
void fxGlideUpdateWindowTransform(CompScreen *s, CompWindow *w, CompTransform *wTransform) { ANIM_SCREEN(s); ANIM_WINDOW(w); if (fxGlideIsPolygonBased (as, aw)) return; // apply the transform matmul4 (wTransform->m, wTransform->m, aw->transform.m); }
/** * Generate a 4x4 transformation matrix from glRotate parameters, and * post-multiply the input matrix by it. * * \author * This function was contributed by Erich Boleyn ([email protected]). * Optimizations contributed by Rudolf Opalla ([email protected]). */ void GLMatrix::rotate (const float angle, const float xRot, const float yRot, const float zRot) { float x = xRot, y = yRot, z = zRot; float s, c; float matrix[16]; bool optimized; s = (float) sin (angle * DEG2RAD); c = (float) cos (angle * DEG2RAD); memcpy (matrix, identity, sizeof (matrix)); optimized = false; #define M(row, col) matrix[col * 4 + row] if (x == 0.0f) { if (y == 0.0f) { if (z != 0.0f) { optimized = true; /* rotate only around z-axis */ M(0,0) = c; M(1,1) = c; if (z < 0.0f) { M(0,1) = s; M(1,0) = -s; } else { M(0,1) = -s; M(1,0) = s; } } } else if (z == 0.0f) { optimized = true; /* rotate only around y-axis */ M(0,0) = c; M(2,2) = c; if (y < 0.0f) { M(0,2) = -s; M(2,0) = s; } else { M(0,2) = s; M(2,0) = -s; } } } else if (y == 0.0f) { if (z == 0.0f) { optimized = true; /* rotate only around x-axis */ M(1,1) = c; M(2,2) = c; if (x < 0.0f) { M(1,2) = s; M(2,1) = -s; } else { M(1,2) = -s; M(2,1) = s; } } } if (!optimized) { float xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c; const float mag = sqrtf (x * x + y * y + z * z); if (mag <= 1.0e-4) { /* no rotation, leave mat as-is */ return; } x /= mag; y /= mag; z /= mag; /* * Arbitrary axis rotation matrix. * * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation * (which is about the X-axis), and the two composite transforms * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary * from the arbitrary axis to the X-axis then back. They are * all elementary rotations. * * Rz' is a rotation about the Z-axis, to bring the axis vector * into the x-z plane. Then Ry' is applied, rotating about the * Y-axis to bring the axis vector parallel with the X-axis. The * rotation about the X-axis is then performed. Ry and Rz are * simply the respective inverse transforms to bring the arbitrary * axis back to it's original orientation. The first transforms * Rz' and Ry' are considered inverses, since the data from the * arbitrary axis gives you info on how to get to it, not how * to get away from it, and an inverse must be applied. * * The basic calculation used is to recognize that the arbitrary * axis vector (x, y, z), since it is of unit length, actually * represents the sines and cosines of the angles to rotate the * X-axis to the same orientation, with theta being the angle about * Z and phi the angle about Y (in the order described above) * as follows: * * cos ( theta ) = x / sqrt ( 1 - z^2 ) * sin ( theta ) = y / sqrt ( 1 - z^2 ) * * cos ( phi ) = sqrt ( 1 - z^2 ) * sin ( phi ) = z * * Note that cos ( phi ) can further be inserted to the above * formulas: * * cos ( theta ) = x / cos ( phi ) * sin ( theta ) = y / sin ( phi ) * * ...etc. Because of those relations and the standard trigonometric * relations, it is pssible to reduce the transforms down to what * is used below. It may be that any primary axis chosen will give the * same results (modulo a sign convention) using thie method. * * Particularly nice is to notice that all divisions that might * have caused trouble when parallel to certain planes or * axis go away with care paid to reducing the expressions. * After checking, it does perform correctly under all cases, since * in all the cases of division where the denominator would have * been zero, the numerator would have been zero as well, giving * the expected result. */ xx = x * x; yy = y * y; zz = z * z; xy = x * y; yz = y * z; zx = z * x; xs = x * s; ys = y * s; zs = z * s; one_c = 1.0f - c; /* We already hold the identity-matrix so we can skip some statements */ M(0,0) = (one_c * xx) + c; M(0,1) = (one_c * xy) - zs; M(0,2) = (one_c * zx) + ys; /* M(0,3) = 0.0F; */ M(1,0) = (one_c * xy) + zs; M(1,1) = (one_c * yy) + c; M(1,2) = (one_c * yz) - xs; /* M(1,3) = 0.0F; */ M(2,0) = (one_c * zx) - ys; M(2,1) = (one_c * yz) + xs; M(2,2) = (one_c * zz) + c; /* M(2,3) = 0.0F; */ /* M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F; */ } #undef M matmul4 (m, m, matrix); }