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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }
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); }
/* * 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(<M); 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(<M, &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(<M, &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(<M, &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(<M, &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,<M,&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(<M); break; case ObjMatrix: printf("objmatrix\n"); //LTM = (Matrix field of E) * LTM Matrix_multiply(&(e->obj.matrix), <M, <M); 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, <M, &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; } }
Matrix Matrix_multiplied(Matrix matrix1, Matrix matrix2) { Matrix_multiply(&matrix1, matrix2); return matrix1; }