static void testInvert() { Matrix matrix; matrix = Matrix_inverted(Matrix_identity()); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_inverted(Matrix_init(0.0f, 0.0f, 2.0f, 2.0f, 2.0f, 0.0f, 0.0f, 3.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f)); assertMatrixApproximate(matrix, 0.0f, 0.5f, 0.0f, -1.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_identity(); Matrix_invert(&matrix); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_init(0.0f, 0.0f, 2.0f, 2.0f, 2.0f, 0.0f, 0.0f, 3.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); Matrix_invert(&matrix); assertMatrixApproximate(matrix, 0.0f, 0.5f, 0.0f, -1.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); }
static void testPerspective() { Matrix matrix; matrix = Matrix_perspective(Matrix_identity(), 90.0f, 1.0f, 1.0f, 2.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -3.0f, -4.0f, 0.0f, 0.0f, -1.0f, 0.0f, EPSILON); matrix = Matrix_perspective(Matrix_identity(), 45.0f, 2.0f, 0.5f, 4.0f); assertMatrixApproximate(matrix, 1.20710678118655f, 0.0f, 0.0f, 0.0f, 0.0f, 2.41421356237309f, 0.0f, 0.0f, 0.0f, 0.0f, -1.28571428571429f, -1.14285714285714f, 0.0f, 0.0f, -1.0f, 0.0f, EPSILON); matrix = Matrix_identity(); Matrix_applyPerspective(&matrix, 90.0f, 1.0f, 1.0f, 2.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -3.0f, -4.0f, 0.0f, 0.0f, -1.0f, 0.0f, EPSILON); matrix = Matrix_identity(); Matrix_applyPerspective(&matrix, 45.0f, 2.0f, 0.5f, 4.0f); assertMatrixApproximate(matrix, 1.20710678118655f, 0.0f, 0.0f, 0.0f, 0.0f, 2.41421356237309f, 0.0f, 0.0f, 0.0f, 0.0f, -1.28571428571429f, -1.14285714285714f, 0.0f, 0.0f, -1.0f, 0.0f, EPSILON); }
static void testRotate() { Matrix matrix; matrix = Matrix_rotated(Matrix_identity(), Vector3_init(0.0f, 1.0f, 0.0f), M_PI); assertMatrixApproximate(matrix, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_rotated(Matrix_scaled(Matrix_identity(), 2.0f, 2.0f, 2.0f), Vector3_init(-1.0f, 0.0f, 0.0f), M_PI * 0.5f); assertMatrixApproximate(matrix, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.0f, -2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_identity(); Matrix_rotate(&matrix, Vector3_init(0.0f, 1.0f, 0.0f), M_PI); assertMatrixApproximate(matrix, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_scaled(Matrix_identity(), 2.0f, 2.0f, 2.0f); Matrix_rotate(&matrix, Vector3_init(-1.0f, 0.0f, 0.0f), M_PI * 0.5f); assertMatrixApproximate(matrix, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.0f, -2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); }
static void testTranslate() { Matrix matrix; matrix = Matrix_translated(Matrix_identity(), 3.0f, -1.5f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 3.0f, 0.0f, 1.0f, 0.0f, -1.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_translated(Matrix_fromDirectionVectors(Vector3_init(0.0f, 1.0f, 0.0f), Vector3_init(0.0f, 0.0f, 1.0f), Vector3_init(1.0f, 0.0f, 0.0f)), 2.0f, 3.0f, -1.0f); assertMatrixApproximate(matrix, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_identity(); Matrix_translate(&matrix, 3.0f, -1.5f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 3.0f, 0.0f, 1.0f, 0.0f, -1.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_fromDirectionVectors(Vector3_init(0.0f, 1.0f, 0.0f), Vector3_init(0.0f, 0.0f, 1.0f), Vector3_init(1.0f, 0.0f, 0.0f)); Matrix_translate(&matrix, 2.0f, 3.0f, -1.0f); assertMatrixApproximate(matrix, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); }
static void testOrtho() { Matrix matrix; matrix = Matrix_ortho(Matrix_identity(), -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_ortho(Matrix_identity(), 0.0f, 4.0f, 8.0f, 0.0f, 0.0f, 10.0f); assertMatrixApproximate(matrix, 0.5f, 0.0f, 0.0f, -1.0f, 0.0f, -0.25f, 0.0f, 1.0f, 0.0f, 0.0f, -0.2f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_identity(); Matrix_applyOrtho(&matrix, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_identity(); Matrix_applyOrtho(&matrix, 0.0f, 4.0f, 8.0f, 0.0f, 0.0f, 10.0f); assertMatrixApproximate(matrix, 0.5f, 0.0f, 0.0f, -1.0f, 0.0f, -0.25f, 0.0f, 1.0f, 0.0f, 0.0f, -0.2f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); }
static void drawControl(float x, float y, float scale, int parameter) { struct vertex_p2f vertices[] = { {{0.5f, 0.0f}}, {{1.0f, 0.5f}}, {{0.5f, 1.0f}}, {{0.0f, 0.5f}} }; Matrix matrix; matrix = Matrix_scaled(Matrix_translated(Matrix_identity(), x, y, 0.0f), scale, scale, 1.0f); glLoadMatrixf(matrix.m); switch (parameter) { case 0: glColor4ub(0xFF, 0x00, 0x00, 0xFF); break; case 1: glColor4ub(0x00, 0xFF, 0x00, 0xFF); break; case 2: glColor4ub(0x00, 0x00, 0xFF, 0xFF); break; case 3: glColor4ub(0xFF, 0xFF, 0x00, 0xFF); break; case 4: glColor4ub(0xFF, 0x00, 0xFF, 0xFF); break; case 5: glColor4ub(0x00, 0xFF, 0xff, 0xFF); break; } glVertexPointer(2, GL_FLOAT, sizeof(struct vertex_p2f), vertices[0].position); glDrawArrays(GL_TRIANGLE_FAN, 0, sizeof(vertices) / sizeof(struct vertex_p2f)); }
static void testMultiplyVector() { Matrix matrix; Vector2 vector2; Vector3 vector3; Vector4 vector4; matrix = Matrix_identity(); vector2 = Matrix_multiplyVector2(matrix, Vector2_init(1.0f, 0.0f)); assertVector2Approximate(vector2, 1.0f, 0.0f, EPSILON); vector3 = Matrix_multiplyVector3(matrix, Vector3_init(0.0f, 1.0f, 0.0f)); assertVector3Approximate(vector3, 0.0f, 1.0f, 0.0f, EPSILON); vector3 = Matrix_multiplyVector3_rotationOnly(matrix, Vector3_init(0.0f, 1.0f, 0.0f)); assertVector3Approximate(vector3, 0.0f, 1.0f, 0.0f, EPSILON); vector4 = Matrix_multiplyVector4(matrix, Vector4_init(0.0f, 0.0f, 1.0f, 0.0f)); assertVector4Approximate(vector4, 0.0f, 0.0f, 1.0f, 0.0f, EPSILON); matrix = Matrix_init(0.0f, 2.0f, 0.0f, -1.0f, 2.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 1.0f); vector2 = Matrix_multiplyVector2(matrix, Vector2_init(-1.0f, 0.0f)); assertVector2Approximate(vector2, -1.0f, -1.0f, EPSILON); vector3 = Matrix_multiplyVector3(matrix, Vector3_init(0.0f, -1.0f, 0.0f)); assertVector3Approximate(vector3, -3.0f, 1.0f, 2.0f, EPSILON); vector3 = Matrix_multiplyVector3_rotationOnly(matrix, Vector3_init(0.0f, -1.0f, 0.0f)); assertVector3Approximate(vector3, -2.0f, 0.0f, 0.0f, EPSILON); vector4 = Matrix_multiplyVector4(matrix, Vector4_init(0.0f, 0.0f, -1.0f, 1.0f)); assertVector4Approximate(vector4, -1.0f, 1.0f, 4.0f, 1.0f, EPSILON); }
/* * Matrix operand to add a 2D shear matrix to the tail of * the module’s list. */ void Module_shear2D(Module *md, double shx, double shy) { Matrix m; Element *e; Matrix_identity(&m); Matrix_translate2D(&m, shx, shy); e = Element_init(ObjMatrix, &m); Module_insert(md, e); }
// Matrix operand to add a 3D translation to the Module. void Module_translate(Module *md, double tx, double ty, double tz) { Matrix m; Element *e; Matrix_identity(&m); Matrix_translate(&m, tx, ty, tz); e = Element_init(ObjMatrix, &m); Module_insert(md, e); }
// Matrix operand to add a 3D scale to the Module. void Module_scale(Module *md, double sx, double sy, double sz) { Matrix m; Element *e; Matrix_identity(&m); Matrix_scale(&m, sx, sy, sz); e = Element_init(ObjMatrix, &m); Module_insert(md, e); }
// Matrix operand to add a rotation about the Y-axis to the Module. void Module_rotateY(Module *md, double cth, double sth) { Matrix m; Element *e; Matrix_identity(&m); Matrix_rotateY(&m, cth, sth); e = Element_init(ObjMatrix, &m); Module_insert(md, e); }
// Matrix operand to add a rotation that orients to the orthonormal axes u,v,w void Module_rotateXYZ(Module *md, Vector *u, Vector *v, Vector *w) { Matrix m; Element *e; Matrix_identity(&m); Matrix_rotateXYZ(&m, u, v, w); e = Element_init(ObjMatrix, &m); Module_insert(md, e); }
static void testDeterminant() { float determinant; determinant = Matrix_determinant(Matrix_identity()); TestCase_assert(fabs(determinant - 1.0f) < EPSILON, "Expected 1.0 but got %f", determinant); determinant = Matrix_determinant(Matrix_init(0.0f, 0.0f, 2.0f, 2.0f, 2.0f, 0.0f, 0.0f, 3.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f)); TestCase_assert(fabs(determinant - 8.0f) < EPSILON, "Expected 8.0 but got %f", determinant); }
static void testScale() { Matrix matrix; matrix = Matrix_scaled(Matrix_identity(), 2.0f, -1.0f, 0.5f); assertMatrixApproximate(matrix, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_scaled(Matrix_init(0.0f, 0.0f, -1.0f, 1.0f, 2.0f, 0.0f, 0.0f, 2.0f, 0.0f, 1.5f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 1.0f), 3.0f, 1.5f, -0.5f); assertMatrixApproximate(matrix, 0.0f, 0.0f, 0.5f, 1.0f, 6.0f, 0.0f, 0.0f, 2.0f, 0.0f, 2.25f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_identity(); Matrix_scale(&matrix, 2.0f, -1.0f, 0.5f); assertMatrixApproximate(matrix, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_init(0.0f, 0.0f, -1.0f, 1.0f, 2.0f, 0.0f, 0.0f, 2.0f, 0.0f, 1.5f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 1.0f); Matrix_scale(&matrix, 3.0f, 1.5f, -0.5f); assertMatrixApproximate(matrix, 0.0f, 0.0f, 0.5f, 1.0f, 6.0f, 0.0f, 0.0f, 2.0f, 0.0f, 2.25f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); }
static void testIdentity() { Matrix matrix; matrix = Matrix_identity(); assertMatrixExact(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); memset(matrix.m, sizeof(float) * 16, 0); Matrix_loadIdentity(&matrix); assertMatrixExact(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }
void Target_draw() { Matrix projectionMatrix; float ratio; float stringWidth; char indexString[32]; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); ratio = (float) viewportWidth / viewportHeight; projectionMatrix = Matrix_ortho(Matrix_identity(), -ratio, ratio, -1.0f, 1.0f, -1.0f, 1.0f); if (GLGraphics_getOpenGLAPIVersion() == GL_API_VERSION_ES2) { glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, projectionMatrix.m); glUniform1i(textureUniform, 0); glVertexAttrib4f(2, 1.0f, 1.0f, 1.0f, 1.0f); } else { glMatrixMode(GL_PROJECTION); glLoadMatrixf(projectionMatrix.m); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } stringWidth = font->measureString(font, "Hello, world!", 13); font->drawString(font, "Hello, world!", 13, 0.1f, stringWidth * -0.05f, 0.0f, 0.0f); stringWidth = font->measureString(font, freeformText, strlen(freeformText)); font->drawString(font, freeformText, strlen(freeformText), 0.0625f, stringWidth * -0.03125f, -0.0625f, 0.0f); if (GLGraphics_getOpenGLAPIVersion() == GL_API_VERSION_ES2) { glVertexAttrib4f(2, 0.875f, 0.875f, 0.5f, 1.0f); } else { glColor4f(0.875f, 0.875f, 0.5f, 1.0f); } snprintf(indexString, 32, "%u, %s", (unsigned int) lastIndexAtWidth, lastLeadingEdge ? "true" : "false"); stringWidth = font->measureString(font, indexString, strlen(indexString)); font->drawString(font, indexString, strlen(indexString), 0.05f, stringWidth * -0.025f, 0.1f, 0.0f); }
void Target_draw() { float ratio = textureImages[textureIndex].ratio; float minTexCoordX = (ratio > 1.0f ? -0.5f : -0.5f / ratio) * (extendedTexCoords ? 2.0f : 1.0f) + 0.5f; float maxTexCoordX = (ratio > 1.0f ? 0.5f : 0.5f / ratio) * (extendedTexCoords ? 2.0f : 1.0f) + 0.5f; float minTexCoordY = (ratio < 1.0f ? -0.5f : -0.5f * ratio) * (extendedTexCoords ? 2.0f : 1.0f) + 0.5f; float maxTexCoordY = (ratio < 1.0f ? 0.5f : 0.5f * ratio) * (extendedTexCoords ? 2.0f : 1.0f) + 0.5f; struct vertex_p3f_t2f vertices[] = { {{-0.5f, -0.5f, 0.0f}, {minTexCoordX, minTexCoordY}}, {{ 0.5f, -0.5f, 0.0f}, {maxTexCoordX, minTexCoordY}}, {{ 0.5f, 0.5f, 0.0f}, {maxTexCoordX, maxTexCoordY}}, {{ 0.5f, 0.5f, 0.0f}, {maxTexCoordX, maxTexCoordY}}, {{-0.5f, 0.5f, 0.0f}, {minTexCoordX, maxTexCoordY}}, {{-0.5f, -0.5f, 0.0f}, {minTexCoordX, minTexCoordY}}, {{-0.5f, -0.75f, -0.5f}, {minTexCoordX, minTexCoordY}}, {{ 0.5f, -0.75f, -0.5f}, {maxTexCoordX, minTexCoordY}}, {{ 0.5f, -0.75f, 0.5f}, {maxTexCoordX, maxTexCoordY}}, {{ 0.5f, -0.75f, 0.5f}, {maxTexCoordX, maxTexCoordY}}, {{-0.5f, -0.75f, 0.5f}, {minTexCoordX, maxTexCoordY}}, {{-0.5f, -0.75f, -0.5f}, {minTexCoordX, minTexCoordY}}, {{-0.5f, 0.75f, -0.5f}, {minTexCoordX, minTexCoordY}}, {{ 0.5f, 0.75f, -0.5f}, {maxTexCoordX, minTexCoordY}}, {{ 0.5f, 0.75f, 0.5f}, {maxTexCoordX, maxTexCoordY}}, {{ 0.5f, 0.75f, 0.5f}, {maxTexCoordX, maxTexCoordY}}, {{-0.5f, 0.75f, 0.5f}, {minTexCoordX, maxTexCoordY}}, {{-0.5f, 0.75f, -0.5f}, {minTexCoordX, minTexCoordY}} }; Matrix matrix; if (whiteBackground) { glClearColor(1.0f, 1.0f, 1.0f, 0.0f); } else { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); } glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); matrix = Matrix_perspective(Matrix_identity(), 60.0f, (float) viewportWidth / viewportHeight, 0.25f, 100.0f); glMultMatrixf(matrix.m); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f, 0.0f, zoomedOut ? -5.0f : -2.0f); texture->activate(texture); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glColor4ub(0xFF, 0xFF, 0xFF, 0xFF); glVertexPointer(3, GL_FLOAT, sizeof(struct vertex_p3f_t2f), vertices[0].position); glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex_p3f_t2f), vertices[0].texCoords); glDrawArrays(GL_TRIANGLES, 0, sizeof(vertices) / sizeof(struct vertex_p3f_t2f)); glDisableClientState(GL_TEXTURE_COORD_ARRAY); texture->deactivate(texture); if (iPhoneMode) { float viewRatio = (float) viewportWidth / viewportHeight; glMatrixMode(GL_PROJECTION); glLoadIdentity(); matrix = Matrix_ortho(Matrix_identity(), 0.0f, viewRatio, 0.0f, 1.0f, -1.0f, 1.0f); glMultMatrixf(matrix.m); glMatrixMode(GL_MODELVIEW); drawControl(0.0f, 0.0f / 6.0f, 1.0f / 6.0f, textureIndex); drawControl(0.0f, 1.0f / 6.0f, 1.0f / 6.0f, autoBlendModeIndex); drawControl(0.0f, 2.0f / 6.0f, 1.0f / 6.0f, minFilterIndex); drawControl(0.0f, 3.0f / 6.0f, 1.0f / 6.0f, magFilterIndex); drawControl(0.0f, 4.0f / 6.0f, 1.0f / 6.0f, wrapSModeIndex); drawControl(0.0f, 5.0f / 6.0f, 1.0f / 6.0f, wrapTModeIndex); drawControl(viewRatio - 1.0f / 6.0f, 0.0f / 6.0f, 1.0f / 6.0f, autoMipmap); drawControl(viewRatio - 1.0f / 6.0f, 1.0f / 6.0f, 1.0f / 6.0f, anisotropicFilter); drawControl(viewRatio - 1.0f / 6.0f, 2.0f / 6.0f, 1.0f / 6.0f, extendedTexCoords); drawControl(viewRatio - 1.0f / 6.0f, 3.0f / 6.0f, 1.0f / 6.0f, whiteBackground); drawControl(viewRatio - 1.0f / 6.0f, 4.0f / 6.0f, 1.0f / 6.0f, zoomedOut); drawControl(viewRatio - 1.0f / 6.0f, 5.0f / 6.0f, 1.0f / 6.0f, 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(<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; } }
static void testShear() { Matrix matrix; matrix = Matrix_shearedX(Matrix_identity(), 1.0f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_shearedX(Matrix_fromDirectionVectors(Vector3_init(0.0f, 1.0f, 0.0f), Vector3_init(0.0f, 0.0f, 1.0f), Vector3_init(1.0f, 0.0f, 0.0f)), 0.5f, -0.5f); assertMatrixApproximate(matrix, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_shearedY(Matrix_identity(), 1.0f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_shearedY(Matrix_fromDirectionVectors(Vector3_init(0.0f, 1.0f, 0.0f), Vector3_init(0.0f, 0.0f, 1.0f), Vector3_init(1.0f, 0.0f, 0.0f)), 0.5f, -0.5f); assertMatrixApproximate(matrix, 0.0f, -0.5f, 1.0f, 0.0f, 1.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_shearedZ(Matrix_identity(), 1.0f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_shearedZ(Matrix_fromDirectionVectors(Vector3_init(0.0f, 1.0f, 0.0f), Vector3_init(0.0f, 0.0f, 1.0f), Vector3_init(1.0f, 0.0f, 0.0f)), 0.5f, -0.5f); assertMatrixApproximate(matrix, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_identity(); Matrix_shearX(&matrix, 1.0f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_fromDirectionVectors(Vector3_init(0.0f, 1.0f, 0.0f), Vector3_init(0.0f, 0.0f, 1.0f), Vector3_init(1.0f, 0.0f, 0.0f)); Matrix_shearX(&matrix, 0.5f, -0.5f); assertMatrixApproximate(matrix, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_identity(); Matrix_shearY(&matrix, 1.0f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_fromDirectionVectors(Vector3_init(0.0f, 1.0f, 0.0f), Vector3_init(0.0f, 0.0f, 1.0f), Vector3_init(1.0f, 0.0f, 0.0f)); Matrix_shearY(&matrix, 0.5f, -0.5f); assertMatrixApproximate(matrix, 0.0f, -0.5f, 1.0f, 0.0f, 1.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_identity(); Matrix_shearZ(&matrix, 1.0f, 1.0f); assertMatrixApproximate(matrix, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); matrix = Matrix_fromDirectionVectors(Vector3_init(0.0f, 1.0f, 0.0f), Vector3_init(0.0f, 0.0f, 1.0f), Vector3_init(1.0f, 0.0f, 0.0f)); Matrix_shearZ(&matrix, 0.5f, -0.5f); assertMatrixApproximate(matrix, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, EPSILON); }
/* * Object that sets the current transform to the identity, * placed at the tail of the module’s list. */ void Module_identity(Module *md) { Matrix m; Matrix_identity(&m); Element *e = Element_init(ObjIdentity, &m); Module_insert(md, e); }
/** * Eliminates all the equalities in a set of constraints and returns the set of * constraints defining a full-dimensional polyhedron, such that there is a * bijection between integer points of the original polyhedron and these of the * resulting (projected) polyhedron). * If VL is set to NULL, this funciton allocates it. Else, it assumes that * (*VL) points to a matrix of the right size. * <p> The following things are done: * <ol> * <li> remove equalities involving only parameters, and remove as many * parameters as there are such equalities. From that, the list of * eliminated parameters <i>elimParms</i> is built. * <li> remove equalities that involve variables. This requires a compression * of the parameters and of the other variables that are not eliminated. * The affine compresson is represented by matrix VL (for <i>validity * lattice</i>) and is such that (N I 1)^T = VL.(N' I' 1), where N', I' * are integer (they are the parameters and variables after compression). *</ol> *</p> */ void Constraints_fullDimensionize(Matrix ** M, Matrix ** C, Matrix ** VL, Matrix ** Eqs, Matrix ** ParmEqs, unsigned int ** elimVars, unsigned int ** elimParms, int maxRays) { unsigned int i, j; Matrix * A=NULL, *B=NULL; Matrix * Ineqs=NULL; unsigned int nbVars = (*M)->NbColumns - (*C)->NbColumns; unsigned int nbParms; int nbElimVars; Matrix * fullDim = NULL; /* variables for permutations */ unsigned int * permutation; Matrix * permutedEqs=NULL, * permutedIneqs=NULL; /* 1- Eliminate the equalities involving only parameters. */ (*ParmEqs) = Constraints_removeParmEqs(M, C, 0, elimParms); /* if the polyehdron is empty, return now. */ if ((*M)->NbColumns==0) return; /* eliminate the columns corresponding to the eliminated parameters */ if (elimParms[0]!=0) { Constraints_removeElimCols(*M, nbVars, (*elimParms), &A); Matrix_Free(*M); (*M) = A; Constraints_removeElimCols(*C, 0, (*elimParms), &B); Matrix_Free(*C); (*C) = B; if (dbgCompParm) { printf("After false parameter elimination: \n"); show_matrix(*M); show_matrix(*C); } } nbParms = (*C)->NbColumns-2; /* 2- Eliminate the equalities involving variables */ /* a- extract the (remaining) equalities from the poyhedron */ split_constraints((*M), Eqs, &Ineqs); nbElimVars = (*Eqs)->NbRows; /* if the polyhedron is already full-dimensional, return */ if ((*Eqs)->NbRows==0) { Matrix_identity(nbParms+1, VL); return; } /* b- choose variables to be eliminated */ permutation = find_a_permutation((*Eqs), nbParms); if (dbgCompParm) { printf("Permuting the vars/parms this way: [ "); for (i=0; i< (*Eqs)->NbColumns-2; i++) { printf("%d ", permutation[i]); } printf("]\n"); } Constraints_permute((*Eqs), permutation, &permutedEqs); Equalities_validityLattice(permutedEqs, (*Eqs)->NbRows, VL); if (dbgCompParm) { printf("Validity lattice: "); show_matrix(*VL); } Constraints_compressLastVars(permutedEqs, (*VL)); Constraints_permute(Ineqs, permutation, &permutedIneqs); if (dbgCompParmMore) { show_matrix(permutedIneqs); show_matrix(permutedEqs); } Matrix_Free(*Eqs); Matrix_Free(Ineqs); Constraints_compressLastVars(permutedIneqs, (*VL)); if (dbgCompParm) { printf("After compression: "); show_matrix(permutedIneqs); } /* c- eliminate the first variables */ assert(Constraints_eliminateFirstVars(permutedEqs, permutedIneqs)); if (dbgCompParmMore) { printf("After elimination of the variables: "); show_matrix(permutedIneqs); } /* d- get rid of the first (zero) columns, which are now useless, and put the parameters back at the end */ fullDim = Matrix_Alloc(permutedIneqs->NbRows, permutedIneqs->NbColumns-nbElimVars); for (i=0; i< permutedIneqs->NbRows; i++) { value_set_si(fullDim->p[i][0], 1); for (j=0; j< nbParms; j++) { value_assign(fullDim->p[i][j+fullDim->NbColumns-nbParms-1], permutedIneqs->p[i][j+nbElimVars+1]); } for (j=0; j< permutedIneqs->NbColumns-nbParms-2-nbElimVars; j++) { value_assign(fullDim->p[i][j+1], permutedIneqs->p[i][nbElimVars+nbParms+j+1]); } value_assign(fullDim->p[i][fullDim->NbColumns-1], permutedIneqs->p[i][permutedIneqs->NbColumns-1]); } Matrix_Free(permutedIneqs); } /* Constraints_fullDimensionize */