Exemple #1
0
static void testMultiply() {
	Matrix matrix;
	
	matrix = Matrix_multiplied(Matrix_init(2.0f, 0.0f, 0.0f, 0.0f,
	                                       0.0f, 2.0f, 0.0f, 0.0f,
	                                       0.0f, 0.0f, 2.0f, 0.0f,
	                                       0.0f, 0.0f, 0.0f, 2.0f),
	                           Matrix_init(2.0f, 0.0f, 0.0f, 0.0f,
	                                       0.0f, 2.0f, 0.0f, 0.0f,
	                                       0.0f, 0.0f, 2.0f, 0.0f,
	                                       0.0f, 0.0f, 0.0f, 2.0f));
	assertMatrixApproximate(matrix, 4.0f, 0.0f, 0.0f, 0.0f,
	                                0.0f, 4.0f, 0.0f, 0.0f,
	                                0.0f, 0.0f, 4.0f, 0.0f,
	                                0.0f, 0.0f, 0.0f, 4.0f, EPSILON);
	
	matrix = Matrix_multiplied(Matrix_init(0.0f, 4.0f, 8.0f,  12.0f,
	                                       1.0f, 5.0f, 9.0f,  13.0f,
	                                       2.0f, 6.0f, 10.0f, 14.0f,
	                                       3.0f, 7.0f, 11.0f, 15.0f),
	                           Matrix_init(1.0f, 7.0f,  19.0f, 37.0f,
	                                       2.0f, 11.0f, 23.0f, 41.0f,
	                                       3.0f, 13.0f, 29.0f, 43.0f,
	                                       5.0f, 17.0f, 31.0f, 47.0f));
	assertMatrixApproximate(matrix, 92.0f,  352.0f, 696.0f,  1072.0f,
	                                103.0f, 400.0f, 798.0f,  1240.0f,
	                                114.0f, 448.0f, 900.0f,  1408.0f,
	                                125.0f, 496.0f, 1002.0f, 1576.0f, EPSILON);
	
	matrix = Matrix_init(2.0f, 0.0f, 0.0f, 0.0f,
	                     0.0f, 2.0f, 0.0f, 0.0f,
	                     0.0f, 0.0f, 2.0f, 0.0f,
	                     0.0f, 0.0f, 0.0f, 2.0f),
	Matrix_multiply(&matrix, Matrix_init(2.0f, 0.0f, 0.0f, 0.0f,
	                                     0.0f, 2.0f, 0.0f, 0.0f,
	                                     0.0f, 0.0f, 2.0f, 0.0f,
	                                     0.0f, 0.0f, 0.0f, 2.0f));
	assertMatrixApproximate(matrix, 4.0f, 0.0f, 0.0f, 0.0f,
	                                0.0f, 4.0f, 0.0f, 0.0f,
	                                0.0f, 0.0f, 4.0f, 0.0f,
	                                0.0f, 0.0f, 0.0f, 4.0f, EPSILON);
	
	matrix = Matrix_init(0.0f, 4.0f, 8.0f,  12.0f,
	                     1.0f, 5.0f, 9.0f,  13.0f,
	                     2.0f, 6.0f, 10.0f, 14.0f,
	                     3.0f, 7.0f, 11.0f, 15.0f),
	Matrix_multiply(&matrix, Matrix_init(1.0f, 7.0f,  19.0f, 37.0f,
	                                     2.0f, 11.0f, 23.0f, 41.0f,
	                                     3.0f, 13.0f, 29.0f, 43.0f,
	                                     5.0f, 17.0f, 31.0f, 47.0f));
	assertMatrixApproximate(matrix, 92.0f,  352.0f, 696.0f,  1072.0f,
	                                103.0f, 400.0f, 798.0f,  1240.0f,
	                                114.0f, 448.0f, 900.0f,  1408.0f,
	                                125.0f, 496.0f, 1002.0f, 1576.0f, EPSILON);
}
Exemple #2
0
void Matrix_frustum(Matrix* result, float left, float right, float bottom, float top, float nearZ, float farZ)
{
    float deltaX = right - left;
    float deltaY = top - bottom;
    float deltaZ = farZ - nearZ;
    Matrix frust;

    if ((nearZ <= 0.0f) || (farZ <= 0.0f) || (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f))
    {
        return;
    }

    frust.m[0][0] = 2.0f * nearZ / deltaX;
    frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f;

    frust.m[1][1] = 2.0f * nearZ / deltaY;
    frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f;

    frust.m[2][0] = (right + left) / deltaX;
    frust.m[2][1] = (top + bottom) / deltaY;
    frust.m[2][2] = -(nearZ + farZ) / deltaZ;
    frust.m[2][3] = -1.0f;

    frust.m[3][2] = -2.0f * nearZ * farZ / deltaZ;
    frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f;

    Matrix_multiply(result, &frust, result);
}
Exemple #3
0
void Matrix_shearZ(Matrix * matrix, float x, float y) {
	Matrix shearingMatrix;
	
	Matrix_loadIdentity(&shearingMatrix);
	shearingMatrix.m[8] = x;
	shearingMatrix.m[9] = y;
	Matrix_multiply(matrix, shearingMatrix);
}
Exemple #4
0
void Matrix_shearX(Matrix * matrix, float y, float z) {
	Matrix shearingMatrix;
	
	Matrix_loadIdentity(&shearingMatrix);
	shearingMatrix.m[1] = y;
	shearingMatrix.m[2] = z;
	Matrix_multiply(matrix, shearingMatrix);
}
Exemple #5
0
void Matrix_shearY(Matrix * matrix, float x, float z) {
	Matrix shearingMatrix;
	
	Matrix_loadIdentity(&shearingMatrix);
	shearingMatrix.m[4] = x;
	shearingMatrix.m[6] = z;
	Matrix_multiply(matrix, shearingMatrix);
}
Exemple #6
0
void Matrix_rotate(Matrix * matrix, Vector3 axis, float angle) {
	Matrix rotationMatrix;
	Quaternion quaternion;
	
	quaternion = Quaternion_fromAxisAngle(axis, angle);
	rotationMatrix = Quaternion_toMatrix(quaternion);
	Matrix_multiply(matrix, rotationMatrix);
}
Exemple #7
0
void Matrix_scale(Matrix * matrix, float x, float y, float z) {
	Matrix scalingMatrix;
	
	Matrix_loadIdentity(&scalingMatrix);
	scalingMatrix.m[0] = x;
	scalingMatrix.m[5] = y;
	scalingMatrix.m[10] = z;
	Matrix_multiply(matrix, scalingMatrix);
}
Exemple #8
0
void Matrix_translate(Matrix * matrix, float x, float y, float z) {
	Matrix translationMatrix;
	
	Matrix_loadIdentity(&translationMatrix);
	translationMatrix.m[12] = x;
	translationMatrix.m[13] = y;
	translationMatrix.m[14] = z;
	Matrix_multiply(matrix, translationMatrix);
}
Exemple #9
0
void Matrix_applyOrtho(Matrix * matrix, float left, float right, float bottom, float top, float zNear, float zFar) {
	Matrix orthoMatrix;
	
	Matrix_loadIdentity(&orthoMatrix);
	orthoMatrix.m[0] = 2.0f / (right - left);
	orthoMatrix.m[5] = 2.0f / (top - bottom);
	orthoMatrix.m[10] = -2.0f / (zFar - zNear);
	orthoMatrix.m[12] = -((right + left) / (right - left));
	orthoMatrix.m[13] = -((top + bottom) / (top - bottom));
	orthoMatrix.m[14] = -((zFar + zNear) / (zFar - zNear));
	Matrix_multiply(matrix, orthoMatrix);
}
Exemple #10
0
void Matrix_rotate(Matrix* result, float angle, float x, float y, float z)
{
    float sinAngle, cosAngle;
    float mag = sqrtf(x * x + y * y + z * z);

    sinAngle = sinf(angle * PI / 180.0f);
    cosAngle = cosf(angle * PI / 180.0f);

    if (mag > 0.0f)
    {
        float xx, yy, zz, xy, yz, zx, xs, ys, zs;
        float oneMinusCos;
        Matrix rotMat;

        x /= mag;
        y /= mag;
        z /= mag;

        xx = x * x;
        yy = y * y;
        zz = z * z;
        xy = x * y;
        yz = y * z;
        zx = z * x;
        xs = x * sinAngle;
        ys = y * sinAngle;
        zs = z * sinAngle;
        oneMinusCos = 1.0f - cosAngle;

        rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle;
        rotMat.m[0][1] = (oneMinusCos * xy) - zs;
        rotMat.m[0][2] = (oneMinusCos * zx) + ys;
        rotMat.m[0][3] = 0.0F;

        rotMat.m[1][0] = (oneMinusCos * xy) + zs;
        rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle;
        rotMat.m[1][2] = (oneMinusCos * yz) - xs;
        rotMat.m[1][3] = 0.0F;

        rotMat.m[2][0] = (oneMinusCos * zx) - ys;
        rotMat.m[2][1] = (oneMinusCos * yz) + xs;
        rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle;
        rotMat.m[2][3] = 0.0F;

        rotMat.m[3][0] = 0.0F;
        rotMat.m[3][1] = 0.0F;
        rotMat.m[3][2] = 0.0F;
        rotMat.m[3][3] = 1.0F;

        Matrix_multiply(result, &rotMat, result);
    }
}
Exemple #11
0
void Matrix_applyPerspective(Matrix * matrix, float fovY, float aspect, float zNear, float zFar) {
	Matrix perspectiveMatrix;
	float sine, cotangent, deltaZ;
	
	fovY = (degreesToRadians(fovY) / 2.0f);
	deltaZ = (zFar - zNear);
	sine = sin(fovY);
	if (deltaZ == 0.0f || sine == 0.0f || aspect == 0.0f) {
		return;
	}
	cotangent = (cos(fovY) / sine);
	
	Matrix_loadIdentity(&perspectiveMatrix);
	perspectiveMatrix.m[0] = (cotangent / aspect);
	perspectiveMatrix.m[5] = cotangent;
	perspectiveMatrix.m[10] = (-(zFar + zNear) / deltaZ);
	perspectiveMatrix.m[11] = -1.0f;
	perspectiveMatrix.m[14] = ((-2.0f * zNear * zFar) / deltaZ);
	perspectiveMatrix.m[15] = 0.0f;
	Matrix_multiply(matrix, perspectiveMatrix);
}
Exemple #12
0
void Matrix_applyPerspective(Matrix * matrix, float fovYDegrees, float aspect, float zNear, float zFar) {
	Matrix perspectiveMatrix;
	float sine, cotangent, deltaZ;
	
	fovYDegrees = fovYDegrees * M_PI / 360.0f;
	deltaZ = zFar - zNear;
	sine = sin(fovYDegrees);
	if (deltaZ == 0.0f || sine == 0.0f || aspect == 0.0f) {
		return;
	}
	cotangent = cos(fovYDegrees) / sine;
	
	Matrix_loadIdentity(&perspectiveMatrix);
	perspectiveMatrix.m[0] = cotangent / aspect;
	perspectiveMatrix.m[5] = cotangent;
	perspectiveMatrix.m[10] = -(zFar + zNear) / deltaZ;
	perspectiveMatrix.m[11] = -1.0f;
	perspectiveMatrix.m[14] = -2.0f * zNear * zFar / deltaZ;
	perspectiveMatrix.m[15] = 0.0f;
	Matrix_multiply(matrix, perspectiveMatrix);
}
Exemple #13
0
void Matrix_ortho(Matrix* result, float left, float right, float bottom, float top, float nearZ, float farZ)
{
    float deltaX = right - left;
    float deltaY = top - bottom;
    float deltaZ = farZ - nearZ;
    Matrix ortho;

    if ((deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f))
    {
        return;
    }

    Matrix_loadIdentity(&ortho);
    ortho.m[0][0] = 2.0f / deltaX;
    ortho.m[3][0] = -(right + left) / deltaX;
    ortho.m[1][1] = 2.0f / deltaY;
    ortho.m[3][1] = -(top + bottom) / deltaY;
    ortho.m[2][2] = -2.0f / deltaZ;
    ortho.m[3][2] = -(nearZ + farZ) / deltaZ;

    Matrix_multiply(result, &ortho, result);
}
Exemple #14
0
/*
 * Draw the module into the image using the given view transformation
 * matrix [VTM], Lighting and DrawState by traversing the list of
 * Elements. (For now, Lighting can be an empty structure.)
 */
void Module_draw(Module *md, Matrix *VTM, Matrix *GTM, DrawState *ds,
				Lighting *lighting, Image *src) {

  printf("module draw\n");

  // set the matrix LTM to identity
  Matrix LTM;
  Matrix_identity(&LTM);
  Line l;
  Point x;
  Polyline pl;
  Polygon pg;
  Circle circle;
  Matrix TM;  
  DrawState *tempDS = DrawState_create();

  Polygon_setNULL(&pg);
  Polyline_setNULL(&pl);
  
  // for each element E in the module md
  Element *e;
  e = md->head;
  
  while (e) {

    //if (e->type >= 13)
    //printf("e->type is NULL X_X\n");
    switch (e->type)
    {
      case ObjNone:
        printf("objNone\n");
        break;
        
      case ObjLine:
        printf("objline\n");
        // copy the line data in E to L
        memcpy(&l, &(e->obj.line), sizeof(Line));
        
        // transform L by the LTM, GTM, VTM
        Matrix_xformLine(&LTM, &l);
        Matrix_xformLine(GTM, &l);
        Matrix_xformLine(VTM, &l);
        
        // normalize L by the homogeneous coord
        Line_normalize(&l);
        
        // draw L using DS->color
        Line_draw(&l, src, ds->color);
        break;
        
      case ObjPoint:
        printf("objpoint\n");
        // copy the line data in E to X
        memcpy(&x, &(e->obj.point), sizeof(Point));
        
        //transform X by the LTM, GTM, VTM        
        Matrix_xformPoint(&LTM, &x, &x);
        Matrix_xformPoint(GTM, &x, &x);
        Matrix_xformPoint(VTM, &x, &x);
        
        // normalize X by the homogeneous coord
        Point_normalize(&x);
        
        // draw X using DS->color (if X is in the image)
        Point_draw(&x, src, ds->color);
        break;
        
      case ObjPolyline:
        printf("objpolyline\n");
        // copy the polyline data in E to P
        Polyline_copy(&pl, &(e->obj.polyline));
        
        //transform P by the LTM, GTM, VTM
        Matrix_xformPolyline(&LTM, &pl);
        Matrix_xformPolyline(GTM, &pl);
        Matrix_xformPolyline(VTM, &pl);
        
        //normalize P by the homogeneous coord
        Polyline_normalize(&pl);
        
        // draw P using DS->color
        Polyline_drawFrame(&pl, src, ds->color);
        break;
        
      case ObjPolygon:
        printf("objpolygon\n");
        // copy the polygon data in E to P
        Polygon_copy(&pg, &(e->obj.polygon));
        //transform P by the LTM, GTM,
        Matrix_xformPolygon(&LTM, &pg);
        Matrix_xformPolygon(GTM, &pg);
        
        // if shadePhong, store world coordinate into appropriate fields     
        if (ds->shade == ShadePhong) {
          printf("before setworld \n");
          Polygon_setWorld(&pg,pg.nVertex);
          printf("after setworld \n");
        }
	    //printf("l->nLights %d \n", lighting->nLights);
        if ((ds->shade == ShadeGouraud) || (ds->shade == ShadeFlat)) {
          // call Polygon_shade to calculate color at each vertex using p
          printf("before polygon shade \n");
          Polygon_shade(&pg, lighting, ds);
          printf("after polygon shade \n");
        }
        
        // transform by VTM
        Matrix_xformPolygon(VTM, &pg);        
        
        //Homogenize the X and Y coordinates
        Polygon_normalize(&pg);
		
		//Polygon_drawFrame(&pg,src,ds->color);
        printf("before drawshade \n");
		Polygon_drawShade(&pg, src, ds, lighting);
		printf("after drawshade \n");
		
        break;
        
        
    case ObjCircle:
        printf("objcircle\n");
        // copy the polyline data in E to P
        memcpy(&circle, &(e->obj.circle), sizeof(Circle));        
        
        //Matrix temp;
        //Matrix_identity(&temp);
        //Matrix_multiply(GTM,&LTM,&temp);
        //Matrix_multiply(&temp,VTM,&temp);
        
        Circle_drawXForm(&circle, src, ds->color, VTM);
        //Circle_draw(&circle,src,ds->color);
        break;
        
      case ObjIdentity:
        printf("identity\n");
        // LTM = I
        Matrix_identity(&LTM);
        break;
        
      case ObjMatrix:
      	printf("objmatrix\n");
        //LTM = (Matrix field of E) * LTM
        Matrix_multiply(&(e->obj.matrix), &LTM, &LTM);
        break;
        
      case ObjColor:
        printf("objcolor\n");
        Color_copy(&(ds->color),&(e->obj.color));
        break;
        
      case ObjBodyColor:
        printf("objbodycolor\n");
        Color_copy(&(ds->body),&(e->obj.color));
        //ds->body = e->obj.color;
        break;
        
      case ObjSurfaceColor:
        printf("objsurfacecolor\n");
        Color_copy(&(ds->surface),&(e->obj.color));
        //ds->surface = e->obj.color;
        break;
        
      case ObjSurfaceCoeff:
        printf("objsurfacecoeff\n");
        ds->surfaceCoeff = e->obj.coeff;
        break;
        
      case ObjLight:
      	printf("objlight\n");
        //memcpy(&(e->obj.????), (char*)obj, sizeof(????));
        break;
        
      case ObjTexture:
        printf("objtexture\n");
        ds->tex = e->obj.tex;
        break;
        
      case ObjModule:
        printf("objmodule\n");
        //TM = GTM * LTM
        Matrix_multiply(GTM, &LTM, &TM);
        
        //tempDS = DS
        DrawState_copy(tempDS, ds);
        //Module_draw( (Module field of E), VTM, TM, tempDS, Light, src );
        
        Module_draw(e->obj.module, VTM, &TM, tempDS, lighting, src);
        break;
        
      default:
        printf("default\n");
        break;
    }
    
    e = e->next;
  }
}
Exemple #15
0
Matrix Matrix_multiplied(Matrix matrix1, Matrix matrix2) {
	Matrix_multiply(&matrix1, matrix2);
	return matrix1;
}