/* This subroutine defines a viewing transformation with the eye at the point * (vx,vy,vz) looking at the point (px,py,pz). Twist is the right-hand * rotation about this line. The resultant matrix is multiplied with * the top of the transformation stack and then replaces it. Precisely, * lookat does: * lookat = trans(-vx,-vy,-vz)*rotate(theta,y)*rotate(phi,x)*rotate(-twist,z) */ void Matrix4::lookat(float vx, float vy, float vz, float px, float py, float pz, short twist) { Matrix4 m(0.0); float tmp; /* pre multiply stack by rotate(-twist,z) */ rot(-twist / 10.0f,'z'); tmp = sqrtf((px-vx)*(px-vx) + (py-vy)*(py-vy) + (pz-vz)*(pz-vz)); m.mat[0] = 1.0; m.mat[5] = sqrtf((px-vx)*(px-vx) + (pz-vz)*(pz-vz)) / tmp; m.mat[6] = (vy-py) / tmp; m.mat[9] = -m.mat[6]; m.mat[10] = m.mat[5]; m.mat[15] = 1.0; multmatrix(m); /* premultiply by rotate(theta,y) */ m.constant(0.0); tmp = sqrtf((px-vx)*(px-vx) + (pz-vz)*(pz-vz)); m.mat[0] = (vz-pz) / tmp; m.mat[5] = 1.0; m.mat[10] = m.mat[0]; m.mat[15] = 1.0; m.mat[2] = -(px-vx) / tmp; m.mat[8] = -m.mat[2]; multmatrix(m); /* premultiply by trans(-vx,-vy,-vz) */ translate(-vx,-vy,-vz); }
// performs scaling void Matrix4::scale(float x, float y, float z) { Matrix4 m; // create identity matrix m.mat[0] = x; m.mat[5] = y; m.mat[10] = z; multmatrix(m); }
// performs a translation void Matrix4::translate(float x, float y, float z) { Matrix4 m; // create identity matrix m.mat[12] = x; m.mat[13] = y; m.mat[14] = z; multmatrix(m); }
// performs a rotation around an axis (char == 'x', 'y', or 'z') // angle is in degrees void Matrix4::rot(float a, char axis) { Matrix4 m; // create identity matrix double angle; angle = (double)DEGTORAD(a); if (axis == 'x') { m.mat[ 0] = 1.0; m.mat[ 5] = cosf(angle); m.mat[10] = m.mat[5]; m.mat[ 6] = sinf(angle); m.mat[ 9] = -m.mat[6]; } else if (axis == 'y') { m.mat[ 0] = cosf(angle); m.mat[ 5] = 1.0; m.mat[10] = m.mat[0]; m.mat[ 2] = -sinf(angle); m.mat[ 8] = -m.mat[2]; } else if (axis == 'z') { m.mat[ 0] = cosf(angle); m.mat[ 5] = m.mat[0]; m.mat[10] = 1.0; m.mat[ 1] = sinf(angle); m.mat[ 4] = -m.mat[1]; } // If there was an error, m is identity so we can multiply anyway. multmatrix(m); }
void R4Matrix:: Draw(void) const { // Multiply top of stack by matrix #if ((RN_3D_GRFX == RN_IRISGL) && (RN_MATH_PRECISION == RN_FLOAT_PRECISION)) R4Matrix matrix(Transpose()); multmatrix((Matrix) matrix.m); #elif ((RN_3D_GRFX == RN_OPENGL) && (RN_MATH_PRECISION == RN_FLOAT_PRECISION)) R4Matrix matrix(Transpose()); glMultMatrixf((const GLfloat *) matrix.m); #elif ((RN_3D_GRFX == RN_OPENGL) && (RN_MATH_PRECISION == RN_DOUBLE_PRECISION)) R4Matrix matrix(Transpose()); glMultMatrixd((const GLdouble *) matrix.m); #elif ((RN_3D_GRFX == RN_3DR) && (RN_MATH_PRECISION == RN_FLOAT_PRECISION)) G3dPreMultTransform(R3dr_gc, m); #else RNAbort("Not Implemented"); #endif }
int main() { int i,j; int mat1[M][N]={{1,2,2,2},{2,-3,6,4},{8,1,0,-3}}; int mat2[N][P]={{1,1,1,0,3},{2,3,1,6,2},{1,-1,-1,8,3},{0,1,2,3,4}}; int matprod[M][P]; /* do the multiplication */ multmatrix(mat1,mat2,matprod); /* display the resulting matrix */ for(i=0; i<M; ++i) { for(j=0; j<P; ++j) printf("%4d ",matprod[i][j]); printf("\n"); } return (0); }
// special render routine to check for graphics initialization void CaveDisplayDevice::render(const VMDDisplayList *cmdlist) { if(!doneGLInit) { cave_gl_init_fn(); } // prepare for rendering glPushMatrix(); multmatrix((transMat.top())); // add our CAVE adjustment transformation // update the cached transformation matrices for use in text display, etc. // In the CAVE, we have to do this separately for all of the processors. // Would be nice to do this outside of the render routine however, // amortized over several Displayables. glGetFloatv(GL_PROJECTION_MATRIX, ogl_pmatrix); glGetFloatv(GL_MODELVIEW_MATRIX, ogl_mvmatrix); ogl_textMat.identity(); ogl_textMat.multmatrix(ogl_pmatrix); ogl_textMat.multmatrix(ogl_mvmatrix); // call OpenGLRenderer to do the rest of the rendering the normal way OpenGLRenderer::render(cmdlist); glPopMatrix(); }