void calculate_view(t_3dview *view) { #define SMALL 1e-6 mat4 To,Te,T1,T2,T3,T4,T5,N1,D1,D2,D3,D4,D5; real dx,dy,dz,l,r; /* eye center */ dx=view->eye[XX]; dy=view->eye[YY]; dz=view->eye[ZZ]; l = sqrt(dx*dx+dy*dy+dz*dz); r = sqrt(dx*dx+dy*dy); #ifdef DEBUG print_v4(debug,"eye",N,view->eye); printf("del: %10.5f%10.5f%10.5f l: %10.5f, r: %10.5f\n",dx,dy,dz,l,r); #endif if (l < SMALL) fatal_error(0,"Error: Zero Length Vector - No View Specified"); translate((real)(-view->origin[XX]), (real)(-view->origin[YY]),(real)(-view->origin[ZZ]),To); translate((real)(-view->eye[XX]), (real)(-view->eye[YY]),(real)(-view->eye[ZZ]),Te); unity_m4(T2); T2[YY][YY]=0, T2[YY][ZZ]=-1, T2[ZZ][YY]=1, T2[ZZ][ZZ]=0; unity_m4(T3); if (r > 0) T3[XX][XX]=-dy/r, T3[XX][ZZ]=dx/r, T3[ZZ][XX]=-dx/r, T3[ZZ][ZZ]=-dy/r; unity_m4(T4); T4[YY][YY]=r/l, T4[YY][ZZ]=dz/l, T4[ZZ][YY]=-dz/l, T4[ZZ][ZZ]=r/l; unity_m4(T5); T5[ZZ][ZZ]=-1; unity_m4(N1); /* N1[XX][XX]=4,N1[YY][YY]=4; */ mult_matrix(T1,To,view->Rot); mult_matrix(D1,Te,T2); mult_matrix(D2,T3,T4); mult_matrix(D3,T5,N1); mult_matrix(D4,T1,D1); mult_matrix(D5,D2,D3); mult_matrix(view->proj,D4,D5); #ifdef DEBUG print_m4(debug,"T1",T1); print_m4(debug,"T2",T2); print_m4(debug,"T3",T3); print_m4(debug,"T4",T4); print_m4(debug,"T5",T5); print_m4(debug,"N1",N1); print_m4(debug,"Rot",view->Rot); print_m4(debug,"Proj",view->proj); #endif }
void init_rotate_3d(t_3dview *view) { real rot = DEG2RAD*15; int i; for (i = 0; (i < DIM); i++) { rotate(i, rot, view->RotP[i]); rotate(i, (real)(-rot), view->RotM[i]); #ifdef DEBUG print_m4(debug, "RotP", view->RotP[i]); print_m4(debug, "RotM", view->RotM[i]); #endif } }
/* also sets restposition in armature (arm_mat) */ static void fix_bonelist_roll(ListBase *bonelist, ListBase *editbonelist) { Bone *curBone; EditBone *ebone; float premat[3][3]; float postmat[3][3]; float difmat[3][3]; float imat[3][3]; for (curBone = bonelist->first; curBone; curBone = curBone->next) { /* sets local matrix and arm_mat (restpos) */ BKE_armature_where_is_bone(curBone, curBone->parent); /* Find the associated editbone */ for (ebone = editbonelist->first; ebone; ebone = ebone->next) if (ebone->temp.bone == curBone) break; if (ebone) { /* Get the ebone premat */ ED_armature_ebone_to_mat3(ebone, premat); /* Get the bone postmat */ copy_m3_m4(postmat, curBone->arm_mat); invert_m3_m3(imat, premat); mul_m3_m3m3(difmat, imat, postmat); #if 0 printf("Bone %s\n", curBone->name); print_m4("premat", premat); print_m4("postmat", postmat); print_m4("difmat", difmat); printf("Roll = %f\n", RAD2DEGF(-atan2(difmat[2][0], difmat[2][2]))); #endif curBone->roll = -atan2f(difmat[2][0], difmat[2][2]); /* and set restposition again */ BKE_armature_where_is_bone(curBone, curBone->parent); } fix_bonelist_roll(&curBone->childbase, editbonelist); } }
void rotate_3d(t_3dview *view,int axis,bool bPositive) { static bool bFirst=TRUE; static mat4 RotP[DIM]; static mat4 RotM[DIM]; int i,j; mat4 m4; if (bFirst) { real rot=DEG2RAD*15; for(i=0; (i<DIM); i++) { rotate(i, rot ,RotP[i]); rotate(i,(real)(-rot),RotM[i]); #ifdef DEBUG print_m4(debug,"RotP",RotP[i]); print_m4(debug,"RotM",RotM[i]); #endif } } /* if (bPositive) m4_op(RotP[axis],view->eye,v4); else m4_op(RotM[axis],view->eye,v4); for(i=0; (i<DIM); i++) view->eye[i]=v4[i]; */ if (bPositive) mult_matrix(m4,view->Rot,RotP[axis]); else mult_matrix(m4,view->Rot,RotM[axis]); for(i=0; (i<N); i++) for(j=0; (j<N); j++) view->Rot[i][j]=m4[i][j]; calculate_view(view); }
static void rot_conf(t_atoms *atoms, rvec x[], rvec v[], real trans, real angle, rvec head, rvec tail, matrix box, int isize, atom_id index[], rvec xout[], rvec vout[]) { rvec arrow, center, xcm; real theta, phi, arrow_len; mat4 Rx, Ry, Rz, Rinvy, Rinvz, Mtot, Tcm, Tinvcm, Tx; mat4 temp1, temp2, temp3, temp4, temp21, temp43; vec4 xv; int i, j, ai; rvec_sub(tail, head, arrow); arrow_len = norm(arrow); if (debug) { fprintf(debug, "Arrow vector: %10.4f %10.4f %10.4f\n", arrow[XX], arrow[YY], arrow[ZZ]); fprintf(debug, "Effective translation %g nm\n", trans); } if (arrow_len == 0.0) { gmx_fatal(FARGS, "Arrow vector not given"); } /* Copy all aoms to output */ for (i = 0; (i < atoms->nr); i++) { copy_rvec(x[i], xout[i]); copy_rvec(v[i], vout[i]); } /* Compute center of mass and move atoms there */ clear_rvec(xcm); for (i = 0; (i < isize); i++) { rvec_inc(xcm, x[index[i]]); } for (i = 0; (i < DIM); i++) { xcm[i] /= isize; } if (debug) { fprintf(debug, "Center of mass: %10.4f %10.4f %10.4f\n", xcm[XX], xcm[YY], xcm[ZZ]); } for (i = 0; (i < isize); i++) { rvec_sub(x[index[i]], xcm, xout[index[i]]); } /* Compute theta and phi that describe the arrow */ theta = acos(arrow[ZZ]/arrow_len); phi = atan2(arrow[YY]/arrow_len, arrow[XX]/arrow_len); if (debug) { fprintf(debug, "Phi = %.1f, Theta = %.1f\n", RAD2DEG*phi, RAD2DEG*theta); } /* Now the total rotation matrix: */ /* Rotate a couple of times */ rotate(ZZ, -phi, Rz); rotate(YY, M_PI/2-theta, Ry); rotate(XX, angle*DEG2RAD, Rx); Rx[WW][XX] = trans; rotate(YY, theta-M_PI/2, Rinvy); rotate(ZZ, phi, Rinvz); mult_matrix(temp1, Ry, Rz); mult_matrix(temp2, Rinvy, Rx); mult_matrix(temp3, temp2, temp1); mult_matrix(Mtot, Rinvz, temp3); print_m4(debug, "Rz", Rz); print_m4(debug, "Ry", Ry); print_m4(debug, "Rx", Rx); print_m4(debug, "Rinvy", Rinvy); print_m4(debug, "Rinvz", Rinvz); print_m4(debug, "Mtot", Mtot); for (i = 0; (i < isize); i++) { ai = index[i]; m4_op(Mtot, xout[ai], xv); rvec_add(xv, xcm, xout[ai]); m4_op(Mtot, v[ai], xv); copy_rvec(xv, vout[ai]); } }
/* This function: * - sets local head/tail rest locations using parent bone's arm_mat. * - calls BKE_armature_where_is_bone() which uses parent's transform (arm_mat) to define this bone's transform. * - fixes (converts) EditBone roll into Bone roll. * - calls again BKE_armature_where_is_bone(), since roll fiddling may have changed things for our bone... * Note that order is crucial here, we can only handle child if all its parents in chain have already been handled * (this is ensured by recursive process). */ static void armature_finalize_restpose(ListBase *bonelist, ListBase *editbonelist) { Bone *curBone; EditBone *ebone; for (curBone = bonelist->first; curBone; curBone = curBone->next) { /* Set bone's local head/tail. * Note that it's important to use final parent's restpose (arm_mat) here, instead of setting those values * from editbone's matrix (see T46010). */ if (curBone->parent) { float parmat_inv[4][4]; invert_m4_m4(parmat_inv, curBone->parent->arm_mat); /* Get the new head and tail */ sub_v3_v3v3(curBone->head, curBone->arm_head, curBone->parent->arm_tail); sub_v3_v3v3(curBone->tail, curBone->arm_tail, curBone->parent->arm_tail); mul_mat3_m4_v3(parmat_inv, curBone->head); mul_mat3_m4_v3(parmat_inv, curBone->tail); } else { copy_v3_v3(curBone->head, curBone->arm_head); copy_v3_v3(curBone->tail, curBone->arm_tail); } /* Set local matrix and arm_mat (restpose). * Do not recurse into children here, armature_finalize_restpose() is already recursive. */ BKE_armature_where_is_bone(curBone, curBone->parent, false); /* Find the associated editbone */ for (ebone = editbonelist->first; ebone; ebone = ebone->next) { if (ebone->temp.bone == curBone) { float premat[3][3]; float postmat[3][3]; float difmat[3][3]; float imat[3][3]; /* Get the ebone premat and its inverse. */ ED_armature_ebone_to_mat3(ebone, premat); invert_m3_m3(imat, premat); /* Get the bone postmat. */ copy_m3_m4(postmat, curBone->arm_mat); mul_m3_m3m3(difmat, imat, postmat); #if 0 printf("Bone %s\n", curBone->name); print_m4("premat", premat); print_m4("postmat", postmat); print_m4("difmat", difmat); printf("Roll = %f\n", RAD2DEGF(-atan2(difmat[2][0], difmat[2][2]))); #endif curBone->roll = -atan2f(difmat[2][0], difmat[2][2]); /* and set restposition again */ BKE_armature_where_is_bone(curBone, curBone->parent, false); break; } } /* Recurse into children... */ armature_finalize_restpose(&curBone->childbase, editbonelist); } }
int main(void) { if(!glfwInit()) { printf("Could not init GLFW"); getchar(); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); //Opengl 2.1 //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); //Opengl 3.3 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // MacOS fix glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); if(window_init(&window, 640, 480, "Test")) { fprintf( stderr, "Failed to open window.\n" ); getchar(); glfwTerminate(); }; window_set_size_callback(&window, window_size_callback); glewExperimental = GL_TRUE; // Needed for core profile if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); getchar(); glfwTerminate(); return -1; } //#clear errors GLEW may trigger printError(); glClearColor(0.0f, 0.0f, 0.4f, 0.0f); GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); //Load model //---------- Model cube; model_init(&cube); model_set_data_length(&cube, sizeof(cube_vertex_data)); model_set_vertices(&cube, cube_vertex_data); model_set_colors(&cube, cube_color_data); model_set_uv_map(&cube, cube_uv_data); model_set_texture(&cube, "./textures/bricks.dds"); model_bind(&cube); //Create shaders //-------------- GLuint vertexShader, fragmentShader; loadShader(&vertexShader, GL_VERTEX_SHADER, mvpVertexShaderSource); loadShader(&fragmentShader, GL_FRAGMENT_SHADER, fragmentShaderSource); //Create program //-------------- GLuint program; createProgram(&program, vertexShader, fragmentShader); // Enable z-buffer // --------------- glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); // Enable culling // -------------- glEnable(GL_CULL_FACE); // Get MVP uniform // --------------- GLuint mvp_ul = glGetUniformLocation(program, "MVP"); // Model Matrix // ------------ Mat4 s; scale_m4(&s, 0.1f, 0.1f, 0.1f); printf("Scale:\n"); print_m4(&s); Mat4 r; rotate_m4(&r, 0.0f, 1.0f, 0.0f, 0.0f); printf("Rotate:\n"); print_m4(&r); Mat4 t; translate_m4(&t, 0.0f, 0.0f, 0.0f); printf("Translate:\n"); print_m4(&t); Mat4 rs; printf("Rotated*Scaled:\n"); mul_m4(&rs, &r, &s); print_m4(&rs); Mat4 model; printf("Model:\n"); mul_m4(&model, &t, &rs); print_m4(&model); // Camera // ------ Vec3 pos; Vec3 center; Vec3 up; Vec3 direction; Vec3 right; camera_init(&camera); camera_set_fov(&camera, 1.0f); camera_set_aspect(&camera, (float)window.width/(float)window.height); Input input; input_init(&input, &window, 0.5f, 0.5f, 0.8f, -5.7f, -2.7f); do { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glUseProgram(program); input_get_data(&input, &pos, &direction, &right); add_v3(¢er, &pos, &direction); cross_v3(&up, &direction, &right); camera_set_position(&camera, &pos); camera_set_center(&camera, ¢er); camera_set_up(&camera, &up); // Mvp Matrix // ---------- Mat4 vp; camera_get_matrix(&camera, &vp); Mat4 mvp; mul_m4(&mvp, &vp, &model); printf("Perspective:\n"); print_m4(&mvp); // Set MVP transform glUniformMatrix4fv(mvp_ul, 1, GL_TRUE, &mvp[0][0]); model_render(&cube); window_swap_buffers(&window); glfwPollEvents(); } while( glfwGetKey(window.handle, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window.handle) == 0 ); // Dispose // ------- model_dispose(&cube); glDeleteVertexArrays(1, &VertexArrayID); glDetachShader(program, fragmentShader); glDetachShader(program, vertexShader); glDeleteShader(fragmentShader); glDeleteShader(vertexShader); glDeleteProgram(program); glfwTerminate(); return 0; }