Beispiel #1
0
void
matrixMultiply (CompTransform       *product,
                const CompTransform *transformA,
                const CompTransform *transformB)
{
	matmul4 (product->m, transformA->m, transformB->m);
}
Beispiel #2
0
/**
 * 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 );
}
Beispiel #3
0
/**
 * 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 );
}
Beispiel #4
0
GLMatrix
operator* (const GLMatrix& lhs,
	   const GLMatrix& rhs)
{
    GLMatrix result;

    matmul4 (result.m, lhs.m, rhs.m);

    return result;
}
Beispiel #5
0
/**
 * 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);
}
Beispiel #6
0
/**
 * 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 );
}
Beispiel #7
0
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
}
Beispiel #8
0
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);
}
Beispiel #9
0
/**
 * 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);
}