mat quat_rotation_mat(aquat q) { quat q2 = q*q; afloat4 v2; quat_store_aligned(q2, v2.a); const float x2 = v2.x; const float y2 = v2.y; const float z2 = v2.z; quat wq = _mm_shuffle_ps(q, q, VEC_SHUFFLE(3, 3, 3, 3)) * q; afloat4 wv; quat_store_aligned(wq, wv.a); const float wx = wv.x; const float wy = wv.y; const float wz = wv.z; afloat4 v; quat_store_aligned(q, v.a); const float xy = v.x*v.y; const float xz = v.x*v.z; const float yz = v.y*v.z; /* Specific to unit quaternion. */ return mat_load(1.0f-2.0f*(y2+z2), 2.0f*(xy-wz), 2.0f*(xz+wy), 0.0f, 2.0f*(xy+wz), 1.0f-2.0f*(x2+z2), 2.0f*(yz-wx), 0.0f, 2.0f*(xz-wy), 2.0f*(yz+wx), 1.0f-2.0f*(x2+y2), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }
int main(void) { mat *m; size_t dim[2]; m = mat_create(6,6); io_init(); io_set_fmt(IO_ASCII); mat_load(m,dim,"ex_io.dat:m"); printf("%dx%d matrix loaded from %s:\n",(int)(dim[0]),(int)(dim[1]),FNAME); mat_print(m,"% .15e"); io_set_fmt(IO_XML); mat_save("ex_io.xml:m",'w',m); io_finish(); mat_destroy(m); return EXIT_SUCCESS; }
int main (int argc, char *argv[]) { int cable_type; int quit = 0; float rot1 = 0.0, rot2 = 0.0, rot3 = 0.0; kos_img_t cubetxr; GLuint texture[2]; pvr_ptr_t texaddr; pvr_ptr_t bumpmap; /* Consider this as the vector from the object to the light, for now. */ GLfloat light_position[3] = { 0.7, 0.7, 2.0 }; vec_normalize (&light_position[0], &light_position[0]); cable_type = vid_check_cable (); printf ("KOS says M_PI is: %f\n", M_PI); if (cable_type == CT_VGA) vid_init (DM_640x480_VGA, PM_RGB565); else vid_init (DM_640x480_PAL_IL, PM_RGB565); init_pvr (); auto_orient (); png_to_img ("/rd/cube.png", PNG_NO_ALPHA, &cubetxr); texaddr = pvr_mem_malloc (cubetxr.w * cubetxr.h * 2); pvr_txr_load_kimg (&cubetxr, texaddr, PVR_TXRLOAD_INVERT_Y); kos_img_free (&cubetxr, 0); bumpmap = load_bumpmap ("/rd/bump.raw"); vid_border_color (0, 0, 0); pvr_set_bg_color (0.0, 0.0, 0.0); glKosInit (); glEnable (GL_DEPTH_TEST); glEnable (GL_CULL_FACE); glEnable (GL_TEXTURE_2D); glShadeModel (GL_SMOOTH); glClearDepth (1.0f); glDepthFunc (GL_LEQUAL); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (45.0, /* Field of view in degrees. */ 640.0 / 480.0, /* Aspect ratio. */ 1.0, /* Z near. */ 50.0); /* Z far. */ glMatrixMode (GL_MODELVIEW); glLoadIdentity (); gluLookAt (0.0, 0.0, -4.5, /* Eye position. */ 0.0, 0.0, 0.0, /* Centre. */ 0.0, 1.0, 0.0); /* Up. */ glGenTextures (2, &texture[0]); /* Ordinary texture. */ glBindTexture (GL_TEXTURE_2D, texture[0]); glKosTex2D (GL_RGB565_TWID, cubetxr.w, cubetxr.h, texaddr); /* Bump texture. */ glBindTexture (GL_TEXTURE_2D, texture[1]); /*pvr_poly_cxt_txr (cxt, PVR_LIST_OP_POLY, PVR_TXRFMT_BUMP | PVR_TXRFMT_TWIDDLED, 128, 128, bumpmap, PVR_FILTER_BILINEAR);*/ glKosTex2D (GL_BUMP_TWID, 128, 128, bumpmap); glTexEnvi (GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE); /* Break the nice abstraction. Tweak for bump mapping. */ /*cxt = (pvr_poly_cxt_t *) texture[1]; cxt->gen.specular = PVR_SPECULAR_ENABLE;*/ /*pvr_poly_compile (&bumphdr, cxt);*/ printf ("objmatrix at %p\n", objmatrix); while (!quit) { int faces; GLfloat transformed_normals [sizeof (face_normals) / (3 * sizeof (GLfloat))][3]; GLfloat transformed_orient [sizeof (face_orient) / (3 * sizeof (GLfloat))][3]; MAPLE_FOREACH_BEGIN (MAPLE_FUNC_CONTROLLER, cont_state_t, st) if (st->buttons & CONT_START) quit = 1; MAPLE_FOREACH_END () glKosBeginFrame (); glPushMatrix (); glRotatef (rot1, 1.0, 0.0, 0.0); glRotatef (rot2, 0.0, 1.0, 0.0); glRotatef (rot3, 0.0, 0.0, 1.0); rot1 += 0.1; rot2 += 0.2; rot3 += 0.3; /* Get the object's transformation matrix. */ glGetFloatv (GL_MODELVIEW_MATRIX, &objmatrix[0][0]); /* We care only about rotation for now. */ objmatrix[0][3] = objmatrix[1][3] = objmatrix[2][3] = 0.0; objmatrix[3][0] = objmatrix[3][1] = objmatrix[3][2] = 0.0; objmatrix[3][3] = 1.0; /*printf ("Got matrix:\n"); printf ("[ %f %f %f %f ]\n", objmatrix[0][0], objmatrix[0][1], objmatrix[0][2], objmatrix[0][3]); printf ("[ %f %f %f %f ]\n", objmatrix[1][0], objmatrix[1][1], objmatrix[1][2], objmatrix[1][3]); printf ("[ %f %f %f %f ]\n", objmatrix[2][0], objmatrix[2][1], objmatrix[2][2], objmatrix[2][3]); printf ("[ %f %f %f %f ]\n", objmatrix[3][0], objmatrix[3][1], objmatrix[3][2], objmatrix[3][3]);*/ /* Do these all in one go. */ mat_load ((matrix_t *) &objmatrix[0][0]); /* Note: mat_transform is only for 3D->2D (perspective) transformations! This won't be quite as quick, most likely. */ for (faces = 0; faces < 6; faces++) { GLfloat x = face_normals[faces][0]; GLfloat y = face_normals[faces][1]; GLfloat z = face_normals[faces][2]; GLfloat w = 1.0; mat_trans_nodiv (x, y, z, w); transformed_normals[faces][0] = x; transformed_normals[faces][1] = y; transformed_normals[faces][2] = z; x = face_orient[faces][0]; y = face_orient[faces][1]; z = face_orient[faces][2]; w = 1.0; mat_trans_nodiv (x, y, z, w); transformed_orient[faces][0] = x; transformed_orient[faces][1] = y; transformed_orient[faces][2] = z; } glKosMatrixDirty (); glDisable (GL_KOS_OFFSET_COLOR); glBindTexture (GL_TEXTURE_2D, texture[0]); glDisable (GL_TEXTURE_2D); //glBlendFunc (GL_DST_COLOR, GL_ZERO); glBlendFunc (GL_ONE, GL_ZERO); for (faces = 0; faces < 6; faces++) { int strip; glBegin (GL_TRIANGLE_STRIP); glColor4ub (colour[faces][0], colour[faces][1], colour[faces][2], colour[faces][3]); for (strip = 0; strip < 4; strip++) { glTexCoord2fv (texcoords[strip]); glVertex3fv (points[tristrips[faces][strip]]); } glEnd (); } /* Finish opaque list, start transparent list. */ glKosFinishList (); glBindTexture (GL_TEXTURE_2D, texture[1]); glEnable (GL_TEXTURE_2D); glEnable (GL_KOS_OFFSET_COLOR); glBlendFunc (GL_ZERO, GL_SRC_ALPHA); for (faces = 0; faces < 6; faces++) { int strip, over_pi, over_2pi; GLfloat s_dot_n, f[3], d[3], t, q; GLfloat d_cross_r[3], dxr_len, d_len; s_dot_n = vec_dot (&transformed_normals[faces][0], &light_position[0]); /* Elevation (T) angle: s.n = |s| |n| cos T T = acos (s.n / (|s| * |n|)) |s| and |n| are both 1. */ t = M_PI / 2 - acosf (s_dot_n); if (t < 0) t = 0; /* Rotation (Q) angle: d x r = (|d| |r| sin Q) n |d x r| / (|d| |r|) = sin Q. */ vec_scale (&f[0], &transformed_normals[faces][0], s_dot_n); vec_sub (&d[0], &light_position[0], &f[0]); vec_cross (&d_cross_r[0], &d[0], &transformed_orient[faces][0]); dxr_len = vec_length (&d_cross_r[0]); d_len = vec_length (&d[0]); q = asinf (dxr_len / d_len); over_pi = vec_dot (&d[0], &transformed_orient[faces][0]) < 0; if (over_pi) q = M_PI - q; over_2pi = vec_dot (&d_cross_r[0], &transformed_normals[faces][0]) < 0; if (over_2pi) q = 2 * M_PI - q; /*printf ("length of n: %f\n", length (&transformed_normals[faces][0])); printf ("%d: [ %f %f %f ]\n", faces, transformed_normals[faces][0], transformed_normals[faces][1], transformed_normals[faces][2]); printf ("length of r: %f\n", length (&transformed_orient[faces][0])); printf ("%d: [ %f %f %f ]\n", faces, transformed_orient[faces][0], transformed_orient[faces][1], transformed_orient[faces][2]);*/ glBegin (GL_TRIANGLE_STRIP); set_bump_direction (t, 2 * M_PI - q, 1.0); glColor4ub (255, 255, 255, 255); for (strip = 0; strip < 4; strip++) { glTexCoord2fv (texcoords[strip]); glVertex3fv (points[tristrips[faces][strip]]); } glEnd (); } /* Finish opaque polygon list, start translucent polygon list. */ /* glKosFinishList ();*/ glPopMatrix (); glKosFinishFrame (); } glKosShutdown (); pvr_shutdown (); vid_shutdown (); return 0; }