/** This function should be called whenever a mouse button is pressed * and is automatically called by mousemove_glfwMouseButtonCallback() * and mousemove_glutMouseFunc() * * @param down 1 if the button is being pressed down or 0 if the button is being released. * @param leftMidRight 0=left button is pressed, 1=middle button is pressed, 2=right button is pressed, -1 no button is pressed. * @param x The x coordinate of the mouse cursor when the button is pressed. * @param y The y coordinate of the mouse cursor when the button is pressed. */ void mousemove_buttonPress(int down, int leftMidRight, int x, int y) { if(down) { cur_button = leftMidRight; last_x = x; last_y = y; // Store camera position & lookat when mouse button is pressed vec3f_copy(cam_lookat_down, cam_lookat); vec3f_copy(cam_position_down, cam_position); if(leftMidRight>2) { float lookAt[3]; // Calculate a new vector pointing from the camera to the // look at point and normalize it. vec3f_sub_new(lookAt,cam_lookat_down,cam_position_down); if(cur_button == 3) // scroll up (zoom in) mousemove_translate_inout(-2,lookAt); else // cur_button = 4 mousemove_translate_inout(2,lookAt); } } else cur_button = -1; }
/** This function should be called whenever a mouse cursor motion * occurs and is automatically called by * mousemove_glfwCursorPosCallback() and mousemove_glutMotionFunc() * * @param x The x coordinate of the mouse cursor. * @param y The y coordinate of the mouse cursor. * @return 1 if the scene needs to be redawn, 0 otherwise. */ int mousemove_movement(int x, int y) { if(cur_button == -1) return 0; /* Distance cursor has moved since last press. */ int dx = x-last_x; int dy = y-last_y; /* Vectors to store our orthonormal basis. */ float f[3], r[3], u[3]; // Calculate a new vector pointing from the camera to the // look at point and normalize it. vec3f_sub_new(f,cam_lookat_down,cam_position_down); vec3f_normalize(f); // Get our up vector vec3f_copy(u,cam_up); // Get a right vector based on the up and lookat vector. vec3f_cross_new(r, f, u); // If right vector was short, then look vector was pointing in // nearly the same direction as the up vector. if(vec3f_normSq(r) < EPSILON) { //printf("mousemove: whoops, pointed camera at up vector."); // move the up vector slightly and try again: u[0] += 0.05; vec3f_cross_new(r,f,u); } vec3f_normalize(r); // recalculate the up vector from the right vector and up vector // to ensure we have a an orthonormal basis. vec3f_cross_new(u, r, f); vec3f_normalize(u); switch(cur_button) { case 0: // left mouse button - translate left/right or up/down /* Translate the camera along the right and up vectors * appropriately depending on the type of mouse movement. */ for(int i=0; i<3; i++) { float offset = r[i]*dx*settings_trans_scale + -u[i]*dy*settings_trans_scale; cam_position[i] = cam_position_down[i] - offset; cam_lookat[i] = cam_lookat_down[i] - offset; } break; case 1: // middle mouse button - translate forward and back mousemove_translate_inout(dy, f); break; case 2: // right mouse button - rotate // If the mouse is moved left/right, rotate the facing // vector around the up vector. mousemove_private_rotate_point(dx*settings_rot_scale, u, f); // If the mouse is moved up/down, rotate the facing vector // around the right vector. mousemove_private_rotate_point(dy*settings_rot_scale, r, f); vec3f_normalize(f); // Add new facing vector to the position that the camera // was at when the button was first pressed to get a new // lookat point. vec3f_add_new(cam_lookat, cam_position_down, f); break; } return 1; }
/** Creates a cylinder geometry object. */ void init_geometryCylinder(kuhl_geometry *cyl, GLuint prog) { int numSides=50; GLfloat vertices[1024]; GLfloat normals[1024]; GLuint indices[1024]; GLfloat texcoords[1024]; int verticesIndex = 0; int normalsIndex = 0; int indicesIndex = 0; int texcoordsIndex = 0; // Bottom middle vertices[verticesIndex++] = 0; vertices[verticesIndex++] = -.5; vertices[verticesIndex++] = -0; normals[normalsIndex++] = 0; normals[normalsIndex++] = -1; normals[normalsIndex++] = 0; texcoords[texcoordsIndex++] = 0; texcoords[texcoordsIndex++] = 0; // For each vertex around bottom perimeter for(int i=0; i<numSides; i++) { vertices[verticesIndex++] = .5*sin(i*2*M_PI/numSides); vertices[verticesIndex++] = -.5; vertices[verticesIndex++] = .5*cos(i*2*M_PI/numSides); normals[normalsIndex++] = 0; normals[normalsIndex++] = -1; normals[normalsIndex++] = 0; texcoords[texcoordsIndex++] = 0; texcoords[texcoordsIndex++] = 0; } // For each face/triangle on bottom, what are the 3 vertices? for(int i=0; i<numSides; i++) { indices[indicesIndex++] = 0; // center point indices[indicesIndex++] = i+1; if(i+2 >= numSides+1) indices[indicesIndex++] = 1; else indices[indicesIndex++] = i+2; } int verticesIndexTopStart = verticesIndex; // Bottom middle vertices[verticesIndex++] = 0; vertices[verticesIndex++] = .5; vertices[verticesIndex++] = -0; normals[normalsIndex++] = 0; normals[normalsIndex++] = 1; normals[normalsIndex++] = 0; texcoords[texcoordsIndex++] = 1; texcoords[texcoordsIndex++] = 1; // For each vertex around bottom perimeter for(int i=0; i<numSides; i++) { vertices[verticesIndex++] = .5*sin(i*2*M_PI/numSides); vertices[verticesIndex++] = .5; vertices[verticesIndex++] = .5*cos(i*2*M_PI/numSides); normals[normalsIndex++] = 0; normals[normalsIndex++] = 1; normals[normalsIndex++] = 0; texcoords[texcoordsIndex++] = 1; texcoords[texcoordsIndex++] = 1; } // For each face/triangle on bottom for(int i=0; i<numSides; i++) { indices[indicesIndex++] = verticesIndexTopStart/3; // center point indices[indicesIndex++] = verticesIndexTopStart/3+i+1; if(i+2 >= numSides+1) indices[indicesIndex++] = verticesIndexTopStart/3+1; else indices[indicesIndex++] = verticesIndexTopStart/3+i+2; } // For each vertex on faces on the sides of the cylinder for(int i=0; i<numSides; i++) { vertices[verticesIndex++] = .5*sin(i*2*M_PI/numSides); vertices[verticesIndex++] = .5; vertices[verticesIndex++] = .5*cos(i*2*M_PI/numSides); vertices[verticesIndex++] = .5*sin(i*2*M_PI/numSides); vertices[verticesIndex++] = -.5; vertices[verticesIndex++] = .5*cos(i*2*M_PI/numSides); vertices[verticesIndex++] = .5*sin((i+1)*2*M_PI/numSides); vertices[verticesIndex++] = -.5; vertices[verticesIndex++] = .5*cos((i+1)*2*M_PI/numSides); vertices[verticesIndex++] = .5*sin((i+1)*2*M_PI/numSides); vertices[verticesIndex++] = .5; vertices[verticesIndex++] = .5*cos((i+1)*2*M_PI/numSides); for(int j=0; j<4; j++) { float pt1[] = { vertices[verticesIndex-3*4+0], vertices[verticesIndex-3*4+1], vertices[verticesIndex-3*4+2] }; float pt2[] = { vertices[verticesIndex-3*4+3], vertices[verticesIndex-3*4+4], vertices[verticesIndex-3*4+5] }; float pt3[] = { vertices[verticesIndex-3*4+6], vertices[verticesIndex-3*4+7], vertices[verticesIndex-3*4+8] }; float v1[3],v2[3],n[3]; vec3f_sub_new(v1, pt2,pt1); vec3f_sub_new(v2, pt3,pt1); vec3f_cross_new(n, v1, v2); normals[normalsIndex++] = n[0]; normals[normalsIndex++] = n[1]; normals[normalsIndex++] = n[2]; if(j < 2) texcoords[texcoordsIndex++] = (numSides-i)/(float)numSides; else texcoords[texcoordsIndex++] = (numSides-(i+1))/(float)numSides; if(j == 1 || j == 2) texcoords[texcoordsIndex++] = 0; // bottom else texcoords[texcoordsIndex++] = 1; // top } indices[indicesIndex++] = verticesIndex/3-4; indices[indicesIndex++] = verticesIndex/3-3; indices[indicesIndex++] = verticesIndex/3-2; indices[indicesIndex++] = verticesIndex/3-4; indices[indicesIndex++] = verticesIndex/3-2; indices[indicesIndex++] = verticesIndex/3-1; } kuhl_geometry_new(cyl, prog, verticesIndex/3, GL_TRIANGLES); kuhl_geometry_attrib(cyl, vertices, 3, "in_Position", 1); kuhl_geometry_attrib(cyl, normals, 3, "in_Normal", 1); kuhl_geometry_attrib(cyl, texcoords, 2, "in_TexCoord", 1); kuhl_geometry_indices(cyl, indices, indicesIndex); /* printf("v: %d\n", verticesIndex); printf("n: %d\n", normalsIndex); printf("t: %d\n", texcoordsIndex); printf("i: %d\n", indicesIndex); */ }