Example #1
0
/* \brief calcualate view matrix */
static void _glhckCameraViewMatrix(glhckCamera *object)
{
   kmMat4 rotation, tmp;
   kmVec3 upvector;
   CALL(2, "%p", object);
   assert(object);

   /* build rotation for upvector */
   kmMat4RotationAxisAngle(&rotation, &(kmVec3){0,0,1},
	 kmDegreesToRadians(object->object->view.rotation.z));
   kmMat4RotationAxisAngle(&tmp, &(kmVec3){0,1,0},
	 kmDegreesToRadians(object->object->view.rotation.y));
   kmMat4Multiply(&rotation, &rotation, &tmp);
   kmMat4RotationAxisAngle(&tmp, &(kmVec3){1,0,0},
	 kmDegreesToRadians(object->object->view.rotation.x));
   kmMat4Multiply(&rotation, &rotation, &tmp);

   /* assuming upvector is normalized */
   kmVec3Transform(&upvector, &object->view.upVector, &rotation);

   /* build view matrix */
   kmMat4LookAt(&object->view.view, &object->object->view.translation,
	 &object->object->view.target, &upvector);
   kmMat4Multiply(&object->view.viewProj,
	 &object->view.projection, &object->view.view);
   glhckFrustumBuild(&object->frustum, &object->view.viewProj);
}
Example #2
0
///< Create a quaternion from yaw, pitch and roll
kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut,
												kmScalar yaw,
												kmScalar pitch,
												kmScalar roll)
{
	kmScalar	ex, ey, ez;		// temp half euler angles
	kmScalar	cr, cp, cy, sr, sp, sy, cpcy, spsy;		// temp vars in roll,pitch yaw

	ex = kmDegreesToRadians(pitch) / 2.0f;	// convert to rads and half them
	ey = kmDegreesToRadians(yaw) / 2.0f;
	ez = kmDegreesToRadians(roll) / 2.0f;

	cr = cosf(ex);
	cp = cosf(ey);
	cy = cosf(ez);

	sr = sinf(ex);
	sp = sinf(ey);
	sy = sinf(ez);

	cpcy = cp * cy;
	spsy = sp * sy;

	pOut->w = cr * cpcy + sr * spsy;

	pOut->x = sr * cpcy - cr * spsy;
	pOut->y = cr * sp * cy + sr * cp * sy;
	pOut->z = cr * cp * sy - sr * sp * cy;

	kmQuaternionNormalize(pOut, pOut);

	return pOut;
}
Example #3
0
static void dlUpdateMatrix( dlObject *object )
{
   kmMat4 translation,
          rotation,
          scale,
          temp;

   CALL("%p", object);

   /* translation */
   kmMat4Translation( &translation,
                      object->translation.x,
                      object->translation.y,
                      object->translation.z  );

   /* rotation */
   kmMat4RotationX( &rotation, kmDegreesToRadians(object->rotation.x) );
   kmMat4Multiply(  &rotation, &rotation,
                    kmMat4RotationY( &temp, kmDegreesToRadians(object->rotation.y) ) );
   kmMat4Multiply(  &rotation, &rotation,
                    kmMat4RotationZ( &temp, kmDegreesToRadians(object->rotation.z) ) );

   /* scale */
   kmMat4Scaling( &scale,
                  object->scale.x,
                  object->scale.y,
                  object->scale.z  );

   /* build matrix */
   kmMat4Multiply( &translation, &translation, &rotation );
   kmMat4Multiply( &object->matrix, &translation, &scale );
   object->transform_changed = 0;
}
Example #4
0
/**
 * Builds a direction vector from input vector.
 * Input vector is assumed to be rotation vector composed from 3 Euler angle rotations, in degrees.
 * The forwards vector will be rotated by the input vector
 *
 * Code ported from Irrlicht: http://irrlicht.sourceforge.net/
 */
kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards)
{
   const kmScalar xr = kmDegreesToRadians(pIn->x);
   const kmScalar yr = kmDegreesToRadians(pIn->y);
   const kmScalar zr = kmDegreesToRadians(pIn->z);
   const kmScalar cr = cos(xr), sr = sin(xr);
   const kmScalar cp = cos(yr), sp = sin(yr);
   const kmScalar cy = cos(zr), sy = sin(zr);

   const kmScalar srsp = sr*sp;
   const kmScalar crsp = cr*sp;

   const kmScalar pseudoMatrix[] = {
      (cp*cy), (cp*sy), (-sp),
      (srsp*cy-cr*sy), (srsp*sy+cr*cy), (sr*cp),
      (crsp*cy+sr*sy), (crsp*sy-sr*cy), (cr*cp)
   };

   pOut->x = forwards->x * pseudoMatrix[0] +
             forwards->y * pseudoMatrix[3] +
             forwards->z * pseudoMatrix[6];

   pOut->y = forwards->x * pseudoMatrix[1] +
             forwards->y * pseudoMatrix[4] +
             forwards->z * pseudoMatrix[7];

   pOut->z = forwards->x * pseudoMatrix[2] +
             forwards->y * pseudoMatrix[5] +
             forwards->z * pseudoMatrix[8];

   return pOut;
}
/**
 * Creates a perspective projection matrix in the
 * same way as gluPerspective
 */
kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY,
                                    kmScalar aspect, kmScalar zNear,
                                    kmScalar zFar)
{
	kmScalar r = kmDegreesToRadians(fovY / 2);
	kmScalar deltaZ = zFar - zNear;
	kmScalar s = sin(r);
    kmScalar cotangent = 0;

	if (deltaZ == 0 || s == 0 || aspect == 0) {
		return NULL;
	}

    //cos(r) / sin(r) = cot(r)
	cotangent = cos(r) / s;

	kmMat4Identity(pOut);
	pOut->mat[0] = cotangent / aspect;
	pOut->mat[5] = cotangent;
	pOut->mat[10] = -(zFar + zNear) / deltaZ;
	pOut->mat[11] = -1;
	pOut->mat[14] = -2 * zNear * zFar / deltaZ;
	pOut->mat[15] = 0;

	return pOut;
}
Example #6
0
static cxBool cxRotateXMLReadAttr(cxAny xmlAction,cxAny mAction, xmlTextReaderPtr reader)
{
    cxActionXMLReadAttr(xmlAction, mAction, reader);
    cxRotate this = mAction;
    cxChar *sx = cxXMLAttr("cxRotate.x");
    cxChar *sy = cxXMLAttr("cxRotate.y");
    cxChar *sz = cxXMLAttr("cxRotate.z");
    if(sx != NULL){
        this->raxis = cxVec3fv(1.0f, 0.0f, 0.0f);
        this->newRadians = kmDegreesToRadians(atof(sx));
    }else if(sy != NULL){
        this->raxis = cxVec3fv(0.0f, 1.0f, 0.0f);
        this->newRadians = kmDegreesToRadians(atof(sy));
    }else if(sz != NULL){
        this->raxis = cxVec3fv(0.0f, 0.0f, 1.0f);
        this->newRadians = kmDegreesToRadians(atof(sz));
    }
    xmlFree(sx);
    xmlFree(sy);
    xmlFree(sz);
    return true;
}
void kmGLRotatef(float angle, float x, float y, float z)
{
	kmVec3 axis;
	kmMat4 rotation;

	//Create an axis vector
	kmVec3Fill(&axis, x, y, z);

	//Create a rotation matrix using the axis and the angle
	kmMat4RotationAxisAngle(&rotation, &axis, kmDegreesToRadians(angle));

	//Multiply the rotation matrix by the current matrix
	kmMat4Multiply(current_stack->top, current_stack->top, &rotation);
}
Example #8
0
void kmGLRotatef(float angle, float x, float y, float z)
{
    km_mat4_stack_context *current_context = (km_mat4_stack_context *)pthread_getspecific(current_context_key);

	kmVec3 axis;
	kmMat4 rotation;

	/*Create an axis vector*/
	kmVec3Fill(&axis, x, y, z);

	/*Create a rotation matrix using the axis and the angle*/
	kmMat4RotationAxisAngle(&rotation, &axis, kmDegreesToRadians(angle));

	/*Multiply the rotation matrix by the current matrix*/
	kmMat4Multiply(current_context->current_stack->top, current_context->current_stack->top, &rotation);
}
Example #9
0
/**
 * Rotates the point anticlockwise around a center
 * by an amount of degrees.
 *
 * Code ported from Irrlicht: http://irrlicht.sourceforge.net/
 */
kmVec2* kmVec2RotateBy(kmVec2* pOut, const kmVec2* pIn,
      const kmScalar degrees, const kmVec2* center)
{
   kmScalar x, y;
   const kmScalar radians = kmDegreesToRadians(degrees);
   const kmScalar cs = cosf(radians), sn = sinf(radians);

   pOut->x = pIn->x - center->x;
   pOut->y = pIn->y - center->y;

   x = pOut->x * cs - pOut->y * sn;
   y = pOut->x * sn + pOut->y * cs;

   pOut->x = x + center->x;
   pOut->y = y + center->y;

   return pOut;
}
Example #10
0
Radians::Radians(const Degrees &rhs) {
    value_ = kmDegreesToRadians(rhs.value_);
}
Example #11
0
Radians to_radians(const Degrees& degrees) {
    return Radians(kmDegreesToRadians(degrees.value_));
}
Example #12
0
///< Creates a quaternion from a rotation matrix
kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut,
										const kmMat3* pIn)
{
/*
Note: The OpenGL matrices are transposed from the description below
taken from the Matrix and Quaternion FAQ

    if ( mat[0] > mat[5] && mat[0] > mat[10] )  {	// Column 0:
        S  = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
        X = 0.25 * S;
        Y = (mat[4] + mat[1] ) / S;
        Z = (mat[2] + mat[8] ) / S;
        W = (mat[9] - mat[6] ) / S;
    } else if ( mat[5] > mat[10] ) {			// Column 1:
        S  = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
        X = (mat[4] + mat[1] ) / S;
        Y = 0.25 * S;
        Z = (mat[9] + mat[6] ) / S;
        W = (mat[2] - mat[8] ) / S;
    } else {						// Column 2:
        S  = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
        X = (mat[2] + mat[8] ) / S;
        Y = (mat[9] + mat[6] ) / S;
        Z = 0.25 * S;
        W = (mat[4] - mat[1] ) / S;
    }
*/

	float x, y, z, w;
	float *pMatrix = NULL;
	float m4x4[16] = {0};
	float scale = 0.0f;
	float diagonal = 0.0f;

	if(!pIn) {
		return NULL;
	}

/*	0 3 6
	1 4 7
	2 5 8

	0 1 2 3
	4 5 6 7
	8 9 10 11
	12 13 14 15*/

	m4x4[0]  = pIn->mat[0];
	m4x4[1]  = pIn->mat[3];
	m4x4[2]  = pIn->mat[6];
	m4x4[4]  = pIn->mat[1];
	m4x4[5]  = pIn->mat[4];
	m4x4[6]  = pIn->mat[7];
	m4x4[8]  = pIn->mat[2];
	m4x4[9]  = pIn->mat[5];
	m4x4[10] = pIn->mat[8];
	m4x4[15] = 1;
	pMatrix = &m4x4[0];

	diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1;

	if(diagonal > kmEpsilon) {
		// Calculate the scale of the diagonal
		scale = (float)sqrt(diagonal ) * 2;

		// Calculate the x, y, x and w of the quaternion through the respective equation
		x = ( pMatrix[9] - pMatrix[6] ) / scale;
		y = ( pMatrix[2] - pMatrix[8] ) / scale;
		z = ( pMatrix[4] - pMatrix[1] ) / scale;
		w = 0.25f * scale;
	}
	else
	{
		// If the first element of the diagonal is the greatest value
		if ( pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10] )
		{
			// Find the scale according to the first element, and double that value
			scale = (float)sqrt( 1.0f + pMatrix[0] - pMatrix[5] - pMatrix[10] ) * 2.0f;

			// Calculate the x, y, x and w of the quaternion through the respective equation
			x = 0.25f * scale;
			y = (pMatrix[4] + pMatrix[1] ) / scale;
			z = (pMatrix[2] + pMatrix[8] ) / scale;
			w = (pMatrix[9] - pMatrix[6] ) / scale;
		}
		// Else if the second element of the diagonal is the greatest value
		else if (pMatrix[5] > pMatrix[10])
		{
			// Find the scale according to the second element, and double that value
			scale = (float)sqrt( 1.0f + pMatrix[5] - pMatrix[0] - pMatrix[10] ) * 2.0f;

			// Calculate the x, y, x and w of the quaternion through the respective equation
			x = (pMatrix[4] + pMatrix[1] ) / scale;
			y = 0.25f * scale;
			z = (pMatrix[9] + pMatrix[6] ) / scale;
			w = (pMatrix[2] - pMatrix[8] ) / scale;
		}
		// Else the third element of the diagonal is the greatest value
		else
		{
			// Find the scale according to the third element, and double that value
			scale  = (float)sqrt( 1.0f + pMatrix[10] - pMatrix[0] - pMatrix[5] ) * 2.0f;

			// Calculate the x, y, x and w of the quaternion through the respective equation
			x = (pMatrix[2] + pMatrix[8] ) / scale;
			y = (pMatrix[9] + pMatrix[6] ) / scale;
			z = 0.25f * scale;
			w = (pMatrix[4] - pMatrix[1] ) / scale;
		}
	}

	pOut->x = x;
	pOut->y = y;
	pOut->z = z;
	pOut->w = w;

	return pOut;

#if 0
	kmScalar T = pIn->mat[0] + pIn->mat[5] + pIn->mat[10];

	if (T > kmEpsilon) {
		//If the trace is greater than zero we always use this calculation:
		/*  S = sqrt(T) * 2;
		  X = ( mat[9] - mat[6] ) / S;
		  Y = ( mat[2] - mat[8] ) / S;
		  Z = ( mat[4] - mat[1] ) / S;
		  W = 0.25 * S;*/

/*		kmScalar s = sqrtf(T) * 2;
		pOut->x = (pIn->mat[9] - pIn->mat[6]) / s;
		pOut->y = (pIn->mat[8] - pIn->mat[2]) / s;
		pOut->z = (pIn->mat[1] - pIn->mat[4]) / s;
		pOut->w = 0.25f * s;

		kmQuaternionNormalize(pOut, pOut);
		return pOut;
	}

	//Otherwise the calculation depends on which major diagonal element has the greatest value.

	if (pIn->mat[0] > pIn->mat[5] && pIn->mat[0] > pIn->mat[10]) {
		kmScalar s = sqrtf(1 + pIn->mat[0] - pIn->mat[5] - pIn->mat[10]) * 2;
		pOut->x = 0.25f * s;
		pOut->y = (pIn->mat[1] + pIn->mat[4]) / s;
		pOut->z = (pIn->mat[8] + pIn->mat[2]) / s;
		pOut->w = (pIn->mat[9] - pIn->mat[6]) / s;
	}
	else if (pIn->mat[5] > pIn->mat[10]) {
		kmScalar s = sqrtf(1 + pIn->mat[5] - pIn->mat[0] - pIn->mat[10]) * 2;
		pOut->x = (pIn->mat[1] + pIn->mat[4]) / s;
		pOut->y = 0.25f * s;
		pOut->z = (pIn->mat[9] + pIn->mat[6]) / s;
		pOut->w = (pIn->mat[8] - pIn->mat[2]) / s;
	}
	else {
		kmScalar s = sqrt(1.0f + pIn->mat[10] - pIn->mat[0] - pIn->mat[5]) * 2.0f;
        pOut->x = (pIn->mat[8] + pIn->mat[2] ) / s;
        pOut->y = (pIn->mat[6] + pIn->mat[9] ) / s;
        pOut->z = 0.25f * s;
        pOut->w = (pIn->mat[1] - pIn->mat[4] ) / s;
	}

	kmQuaternionNormalize(pOut, pOut);
	return pOut;*/
#endif // 0
}

///< Create a quaternion from yaw, pitch and roll
kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut,
												kmScalar yaw,
												kmScalar pitch,
												kmScalar roll)
{
	kmScalar	ex, ey, ez;		// temp half euler angles
	kmScalar	cr, cp, cy, sr, sp, sy, cpcy, spsy;		// temp vars in roll,pitch yaw

	ex = kmDegreesToRadians(pitch) / 2.0f;	// convert to rads and half them
	ey = kmDegreesToRadians(yaw) / 2.0f;
	ez = kmDegreesToRadians(roll) / 2.0f;

	cr = cosf(ex);
	cp = cosf(ey);
	cy = cosf(ez);

	sr = sinf(ex);
	sp = sinf(ey);
	sy = sinf(ez);

	cpcy = cp * cy;
	spsy = sp * sy;

	pOut->w = cr * cpcy + sr * spsy;

	pOut->x = sr * cpcy - cr * spsy;
	pOut->y = cr * sp * cy + sr * cp * sy;
	pOut->z = cr * cp * sy - sr * sp * cy;

	kmQuaternionNormalize(pOut, pOut);

	return pOut;
}