Sei sulla pagina 1di 11

#include <windows.h> #include <C:\Users\12531\Desktop\CompGraphics Libs(x32)\glut.h> #include <C:\Users\12531\Desktop\CompGraphics Libs(x32)\glui.h> #include <stdio.h> #include <stdlib.h> #include <string.

h> #include <math.h> #include <windows.h> #include "keyframe.h" #include "timer.h" #include "vector.h" // ----- GLOBAL VARIABLES ----const float PI = 3.14159; const float SPINNER_SPEED = 0.1; // ----- USER INTERFACE VARIABLES ----int Win[2]; int windowID; GLUI *glui; GLUI *glui_keyframe; char msg[256]; GLUI_StaticText* status; // ----- CAMERA VARIABLES ----bool updateCamZPos = false; int lastX = 0; int lastY = 0; const float ZOOM_SCALE = 0.01; GLdouble camXPos = 0.0; GLdouble camYPos = 0.0; GLdouble camZPos = -30; const GLdouble CAMERA_FOVY = 100.0; const GLdouble NEAR_CLIP = 0.1; const GLdouble FAR_CLIP = 500.0; // ----- ANIMATION VARIABLES ----int animate_mode = 0; //file for loading & saving keyframes const char filenameKF[] = "keyframes.txt"; Keyframe* keyframes; // list of keyframes int maxValidKeyframe = 0; // index of max VALID keyframe (in keyframe list) const int KEYFRAME_MIN = 0; const int KEYFRAME_MAX = 32; // README: specifies the max number of keyframes // Frame settings char filenameF[128]; // storage for frame filename int frameNumber = 0; // current frame being dumped int frameToFile = 0; // flag for dumping frames to file const float DUMP_FRAME_PER_SEC = 24.0; // frame rate for dumped frames const float DUMP_SEC_PER_FRAME = 1.0 / DUMP_FRAME_PER_SEC; // Time settings Timer* animationTimer; Timer* frameRateTimer; const float TIME_MIN = 0.0; const float TIME_MAX = 20.0; const float SEC_PER_FRAME = 1.0 / 60.0; // This is the key data structure for // updating keyframes in the keyframe list and // for driving the animation. // i) When updating a keyframe, use the values // in this data structure to update the // appropriate keyframe in the keyframe list. // ii) When calculating the interpolated pose, // the resulting pose vector is placed into

// this data structure. (This code is already // in place - see the animate() function) // iii) When drawing the scene, use the values in // this data structure (which are set in the // animate() function as described above) to // specify the appropriate transformations. Keyframe* joint_ui_data; const float ROOT_TRANSLATE_X_MIN = -10.0; const float ROOT_TRANSLATE_X_MAX = 10.0; const float ROOT_TRANSLATE_Y_MIN = -10.0; const float ROOT_TRANSLATE_Y_MAX = 10.0; const float ROOT_TRANSLATE_Z_MIN = -10.0; const float ROOT_TRANSLATE_Z_MAX = 10.0; const float ROOT_ROTATE_X_MIN = -180.0; const float ROOT_ROTATE_X_MAX = 180.0; const float ROOT_ROTATE_Y_MIN = -180.0; const float ROOT_ROTATE_Y_MAX = 180.0; const float ROOT_ROTATE_Z_MIN = -180.0; const float ROOT_ROTATE_Z_MAX = 180.0; const float HEAD_MIN = -10.0; const float HEAD_MAX = 10.0; const float HEAD_PITCH_MIN = -45.0; const float HEAD_PITCH_MAX = 45.0; const float FLIPPER_X_MAX = 45.0; const float FLIPPER_X_MIN = -45.0; const float FLIPPER_Y_MAX = 180.0; const float FLIPPER_Y_MIN = -180.0; const float FLIPPER_Z_MAX = 180.0; const float FLIPPER_Z_MIN = -180.0; Vector getInterpolatedJointDOFS(float time); void display(void); void myReshape(int w, int h); void drawCube(); void initDS(); void drawTriangle(int x, int y, float width); void initGlui(); void initGlut(int argc, char** argv); void animate(); void mouse(int button, int state, int x, int y); void motion(int x, int y); void writeFrame(char* filename, bool pgm, bool frontBuffer); // main() function // Initializes the user interface (and any user variables) // then hands over control to the event handler, which calls // display() whenever the GL window needs to be redrawn. int main(int argc, char** argv) { // Process program arguments if(argc != 3) { printf("Usage: demo [width] [height]\n"); printf("Using 400x400 window by default...\n"); Win[0] = 400; Win[1] = 400; } else { Win[0] = atoi(argv[1]); Win[1] = atoi(argv[2]); } initDS();

initGlut(argc, argv); initGlui(); glClearColor(0.7f,0.7f,0.9f,1.0f); glEnable(GL_DEPTH_TEST); // Invoke the standard GLUT main event loop glutMainLoop(); return 0; } void initDS() { keyframes = new Keyframe[KEYFRAME_MAX]; for( int i = 0; i < KEYFRAME_MAX; i++ ) keyframes[i].setID(i); animationTimer = new Timer(); frameRateTimer = new Timer(); joint_ui_data = new Keyframe(); } void initGlut(int argc, char** argv) { // Init GLUT glutInit(&argc, argv); // Set video mode: double-buffered, color, depth-buffered glutInitDisplayMode (GLUT_DOUBLE GLUT_RGB GLUT_DEPTH); // Create window glutInitWindowPosition (0, 0); glutInitWindowSize(Win[0],Win[1]); windowID = glutCreateWindow(argv[0]); // Setup callback functions to handle events glutReshapeFunc(myReshape); // Call reshape whenever window resized glutDisplayFunc(display); // Call display whenever new frame needed } // Load Keyframe button handler. Called when the "load keyframe" button is press ed void loadKeyframeButton(int) { // Get the keyframe ID from the UI int keyframeID = joint_ui_data->getID(); // Update the 'joint_ui_data' variable with the appropriate // entry from the 'keyframes' array (the list of keyframes) *joint_ui_data = keyframes[keyframeID]; // Sync the UI with the 'joint_ui_data' values glui->sync_live(); glui_keyframe->sync_live(); // Let the user know the values have been loaded sprintf(msg, "Keyframe %d loaded successfully", keyframeID); status->set_text(msg); } // Update Keyframe button handler. Called when the "update keyframe" button is p ressed void updateKeyframeButton(int) { // Get the keyframe ID from the UI int keyframeID = joint_ui_data->getID(); if(keyframeID > maxValidKeyframe) maxValidKeyframe = keyframeID; keyframes[keyframeID] = *joint_ui_data; // Sync the UI with the 'joint_ui_data' values glui->sync_live(); glui_keyframe->sync_live(); sprintf(msg, "Keyframe %d updated successfully", keyframeID);

status->set_text(msg); } // Load Keyframes From File button handler. Called when the "load keyframes from file" button is pressed // ASSUMES THAT THE FILE FORMAT IS CORRECT, ie, there is no error checking! void loadKeyframesFromFileButton(int) { // Open file for reading FILE* file = fopen(filenameKF, "r"); if( file == NULL ) { sprintf(msg, "Failed to open file %s", filenameKF); status->set_text(msg); return; } // Read in maxValidKeyframe first fscanf(file, "%d", &maxValidKeyframe); // Now read in all keyframes in the format: // id // time // DOFs for( int i = 0; i <= maxValidKeyframe; i++ ) { fscanf(file, "%d", keyframes[i].getIDPtr()); fscanf(file, "%f", keyframes[i].getTimePtr()); for( int j = 0; j < Keyframe::NUM_JOINT_ENUM; j++ ) fscanf(file, "%f", keyframes[i].getDOFPtr(j)); } // Close file fclose(file); // Let the user know the keyframes have been loaded sprintf(msg, "Keyframes loaded successfully"); status->set_text(msg); } // Save Keyframes To File button handler. Called when the "save keyframes to fil e" button is pressed void saveKeyframesToFileButton(int) { // Open file for writing FILE* file = fopen(filenameKF, "w"); if( file == NULL ) { sprintf(msg, "Failed to open file %s", filenameKF); status->set_text(msg); return; } // Write out maxValidKeyframe first fprintf(file, "%d\n", maxValidKeyframe); fprintf(file, "\n"); // Now write out all keyframes in the format: // id // time // DOFs // for( int i = 0; i <= maxValidKeyframe; i++ ) { fprintf(file, "%d\n", keyframes[i].getID()); fprintf(file, "%f\n", keyframes[i].getTime()); for( int j = 0; j < Keyframe::NUM_JOINT_ENUM; j++ ) fprintf(file, "%f\n", keyframes[i].getDOF(j));

fprintf(file, "\n"); } // Close file fclose(file); // Let the user know the keyframes have been saved sprintf(msg, "Keyframes saved successfully"); status->set_text(msg); } void animateButton(int) { // synchronize variables that GLUT uses glui_keyframe->sync_live(); // toggle animation mode and set idle function appropriately if( animate_mode == 0 ) { // start animation frameRateTimer->reset(); animationTimer->reset(); animate_mode = 1; GLUI_Master.set_glutIdleFunc(animate); // Let the user know the animation is running sprintf(msg, "Animating..."); status->set_text(msg); } else { // stop animation animate_mode = 0; GLUI_Master.set_glutIdleFunc(NULL); // Let the user know the animation has stopped sprintf(msg, "Animation stopped"); status->set_text(msg); } } // Initialize GLUI and the user interface void initGlui() { GLUI_Panel* glui_panel; GLUI_Spinner* glui_spinner; GLUI_Master.set_glutIdleFunc(NULL); // Create GLUI window (joint controls) *************** // glui = GLUI_Master.create_glui("Joint Control", 0, Win[0]+12, 0); // Create controls to specify root position and orientation glui_panel = glui->add_panel("Root"); glui_spinner = glui->add_spinner_to_panel(glui_panel, "translate x:", GL UI_SPINNER_FLOAT, joint_ui_data->getDOFPtr(Keyframe::ROOT_TRANSLATE_X)); glui_spinner->set_float_limits(ROOT_TRANSLATE_X_MIN, ROOT_TRANSLATE_X_MA X, GLUI_LIMIT_CLAMP); glui_spinner->set_speed(SPINNER_SPEED); glui_spinner = glui->add_spinner_to_panel(glui_panel, "translate y:", GL UI_SPINNER_FLOAT, joint_ui_data->getDOFPtr(Keyframe::ROOT_TRANSLATE_Y)); glui_spinner->set_float_limits(ROOT_TRANSLATE_Y_MIN, ROOT_TRANSLATE_Y_MA X, GLUI_LIMIT_CLAMP); glui_spinner->set_speed(SPINNER_SPEED); glui_spinner = glui->add_spinner_to_panel(glui_panel, "translate z:", GL UI_SPINNER_FLOAT, joint_ui_data->getDOFPtr(Keyframe::ROOT_TRANSLATE_Z)); glui_spinner->set_float_limits(ROOT_TRANSLATE_Z_MIN, ROOT_TRANSLATE_Z_MA X, GLUI_LIMIT_CLAMP); glui_spinner->set_speed(SPINNER_SPEED);

glui_spinner = glui->add_spinner_to_panel(glui_panel, "rotate x:", GLUI_ SPINNER_FLOAT, joint_ui_data->getDOFPtr(Keyframe::ROOT_ROTATE_X)); glui_spinner->set_float_limits(ROOT_ROTATE_X_MIN, ROOT_ROTATE_X_MAX, GLU I_LIMIT_WRAP); glui_spinner->set_speed(SPINNER_SPEED); glui_spinner = glui->add_spinner_to_panel(glui_panel, "rotate y:", GLUI_ SPINNER_FLOAT, joint_ui_data->getDOFPtr(Keyframe::ROOT_ROTATE_Y)); glui_spinner->set_float_limits(ROOT_ROTATE_Y_MIN, ROOT_ROTATE_Y_MAX, GLU I_LIMIT_WRAP); glui_spinner->set_speed(SPINNER_SPEED); glui_spinner = glui->add_spinner_to_panel(glui_panel, "rotate z:", GLUI_ SPINNER_FLOAT, joint_ui_data->getDOFPtr(Keyframe::ROOT_ROTATE_Z)); glui_spinner->set_float_limits(ROOT_ROTATE_Z_MIN, ROOT_ROTATE_Z_MAX, GLU I_LIMIT_WRAP); glui_spinner->set_speed(SPINNER_SPEED); // Create controls to specify right arm glui_panel = glui->add_panel("flipper"); glui_spinner = glui->add_spinner_to_panel(glui_panel, "FLIPPER_X:", GLUI _SPINNER_FLOAT, joint_ui_data->getDOFPtr(Keyframe::FLIPPER_X)); glui_spinner->set_float_limits(FLIPPER_X_MIN,FLIPPER_X_MAX, GLUI_LIMIT_C LAMP); glui_spinner->set_speed(SPINNER_SPEED); glui_spinner = glui->add_spinner_to_panel(glui_panel, "FLIPEPR Y:", GLUI _SPINNER_FLOAT, joint_ui_data->getDOFPtr(Keyframe::FLIPPER_Y)); glui_spinner->set_float_limits(FLIPPER_Y_MIN, FLIPPER_Y_MAX, GLUI_LIMIT_ CLAMP); glui_spinner->set_speed(SPINNER_SPEED); glui_spinner = glui->add_spinner_to_panel(glui_panel, "flipper z:", GLUI _SPINNER_FLOAT, joint_ui_data->getDOFPtr(Keyframe::FLIPPER_Z)); glui_spinner->set_float_limits(FLIPPER_Z_MIN, FLIPPER_Z_MAX, GLUI_LIMIT_ CLAMP); glui_spinner->set_speed(SPINNER_SPEED); glui_keyframe = GLUI_Master.create_glui("Keyframe Control", 0, 0, Win[1] +64); // Create a control to specify the time (for setting a keyframe) glui_panel = glui_keyframe->add_panel("", GLUI_PANEL_NONE); glui_spinner = glui_keyframe->add_spinner_to_panel(glui_panel, "Time:", GLUI_SPINNER_FLOAT, joint_ui_data->getTimePtr()); glui_spinner->set_float_limits(TIME_MIN, TIME_MAX, GLUI_LIMIT_CLAMP); glui_spinner->set_speed(SPINNER_SPEED); // Create a control to specify a keyframe (for updating / loading a keyf rame) glui_keyframe->add_column_to_panel(glui_panel, false); glui_spinner = glui_keyframe->add_spinner_to_panel(glui_panel, "Keyframe ID:", GLUI_SPINNER_INT, joint_ui_data->getIDPtr()); glui_spinner->set_int_limits(KEYFRAME_MIN, KEYFRAME_MAX-1, GLUI_LIMIT_CL AMP); glui_spinner->set_speed(SPINNER_SPEED); glui_keyframe->add_separator(); // Add buttons to load and update keyframes // Add buttons to load and save keyframes from a file // Add buttons to start / stop animation and to render frames to file glui_panel = glui_keyframe->add_panel("", GLUI_PANEL_NONE); glui_keyframe->add_button_to_panel(glui_panel, "Load Keyframe", 0, loadK eyframeButton); glui_keyframe->add_button_to_panel(glui_panel, "Load Keyframes From File ", 0, loadKeyframesFromFileButton); glui_keyframe->add_column_to_panel(glui_panel, false);

glui_keyframe->add_button_to_panel(glui_panel, "Update Keyframe", 0, upd ateKeyframeButton); glui_keyframe->add_button_to_panel(glui_panel, "Save Keyframes To File", 0, saveKeyframesToFileButton); glui_keyframe->add_separator(); glui_panel = glui_keyframe->add_panel(""); glui_keyframe->add_button_to_panel(glui_panel, "Start/Stop Animation", 0 , animateButton); glui_keyframe->add_separator(); // Add status line glui_panel = glui_keyframe->add_panel(""); status = glui_keyframe->add_statictext_to_panel(glui_panel, "Status: Rea dy"); // Set the main window to be the "active" window glui->set_main_gfx_window(windowID); glui_keyframe->set_main_gfx_window(windowID); } // Calculates the interpolated joint DOF vector // using Catmull-Rom interpolation of the keyframes Vector getInterpolatedJointDOFS(float time) { // Need to find the keyframes bewteen which // the supplied time lies. // At the end of the loop we have: // keyframes[i-1].getTime() < time <= keyframes[i].getTime() // int i = 0; while( i <= maxValidKeyframe && keyframes[i].getTime() < time ) i++; // If time is before or at first defined keyframe, then // just use first keyframe pose if( i == 0 ) return keyframes[0].getDOFVector(); // If time is beyond last defined keyframe, then just // use last keyframe pose if( i > maxValidKeyframe ) return keyframes[maxValidKeyframe].getDOFVector(); // Need to normalize time to (0, 1] time = (time - keyframes[i-1].getTime()) / (keyframes[i].getTime() - key frames[i-1].getTime()); // Get appropriate data points and tangent vectors // for computing the interpolation Vector p0 = keyframes[i-1].getDOFVector(); Vector p1 = keyframes[i].getDOFVector(); Vector t0, t1; if( i == 1 ) // special case - at beginning of spline { t0 = keyframes[i].getDOFVector() - keyframes[i-1].getDOFVector() ; t1 = (keyframes[i+1].getDOFVector() - keyframes[i-1].getDOFVecto r()) * 0.5; } else if( i == maxValidKeyframe ) // special case - at end of spline { t0 = (keyframes[i].getDOFVector() - keyframes[i-2].getDOFVector( )) * 0.5; t1 = keyframes[i].getDOFVector() - keyframes[i-1].getDOFVector() ; } else

{ t0 = (keyframes[i].getDOFVector() - keyframes[i-2].getDOFVector( )) * 0.5; t1 = (keyframes[i+1].getDOFVector() - keyframes[i-1].getDOFVecto r()) * 0.5; } // Return the interpolated Vector Vector a0 = p0; Vector a1 = t0; Vector a2 = p0 * (-3) + p1 * 3 + t0 * (-2) + t1 * (-1); Vector a3 = p0 * 2 + p1 * (-2) + t0 + t1; return (((a3 * time + a2) * time + a1) * time + a0); } // Callback idle function for animating the scene void animate() { // Only update if enough time has passed // (This locks the display to a certain frame rate rather // than updating as fast as possible. The effect is that // the animation should run at about the same rate // whether being run on a fast machine or slow machine) if( frameRateTimer->elapsed() > SEC_PER_FRAME ) { // Tell glut window to update itself. This will cause the displa y() // callback to be called, which renders the object (once you've written // the callback). glutSetWindow(windowID); glutPostRedisplay(); // Restart the frame rate timer // for the next frame frameRateTimer->reset(); } } void myReshape(int w, int h) { // Update internal variables and OpenGL viewport Win[0] = w; Win[1] = h; glViewport(0, 0, (GLsizei)Win[0], (GLsizei)Win[1]); // Setup projection matrix for new window glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(CAMERA_FOVY, (GLdouble)Win[0]/(GLdouble)Win[1], NEAR_CLIP , FAR_CLIP); } // display callback // // This gets called by the event handler to draw the scene void display(void) { // Clear the screen with the background colour glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT); // Setup the model-view transformation matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Specify camera transformation glTranslatef(camXPos, camYPos, camZPos); // Get the time for the current animation step, if necessary

if(animate_mode) { float curTime = animationTimer->elapsed(); if( curTime >= keyframes[maxValidKeyframe].getTime() ) { // Restart the animation animationTimer->reset(); curTime = animationTimer->elapsed(); } // Get the interpolated joint DOFs joint_ui_data->setDOFVector( getInterpolatedJointDOFS(curTime) ) ; // Update user interface joint_ui_data->setTime(curTime); glui_keyframe->sync_live(); } //////////////////////body glPushMatrix(); glTranslatef(joint_ui_data->getDOF(Keyframe::ROOT_TRANSLATE_X), joint_ui_data->getDOF(Keyframe::ROOT_TRANSLATE_Y), joint_ui_data->getDOF(Keyframe::ROOT_TRANSLATE_Z)); glRotatef(joint_ui_data->getDOF(Keyframe::ROOT_ROTATE_X), 1.0, 0 .0, 0.0); glRotatef(joint_ui_data->getDOF(Keyframe::ROOT_ROTATE_Y), 0.0, 1 .0, 0.0); glRotatef(joint_ui_data->getDOF(Keyframe::ROOT_ROTATE_Z), 0.0, 0 .0, 1.0); glPushMatrix(); glTranslatef(0.0, 0.0, 0.0); glColor3f(0.0, 0.0, 0.7); glScalef(2.3, 0.7, 1.0); glutWireSphere(8, 30, 20); /* glColor3f(0.369, 0.369, 0.369); glRotated(10, 11.0, 5.0, 1.0); glRotatef(-15, 1.0, 1.0, 1.0); drawTriangle(-1, 6, 6); drawTriangle(3, 8, 2); drawTriangle(2,-4, 4); */ glPopMatrix(); // aeac 1 glPushMatrix(); glTranslatef(-13, 3, -3.3); glColor3f(1,1,0.0); glutSolidSphere(0.5, 20, 30); glPopMatrix(); // aeac 2 glPushMatrix(); glTranslatef(-13, 3, 3.3); glColor3f(1,1,0.0); glutSolidSphere(0.5, 20, 20); glPopMatrix();

//mouse glPushMatrix(); glTranslatef(-15, -2, 0); glColor3f(1,1,0.0); glScalef(4, 2, 5); glutSolidSphere(0.5, 20, 20); glPopMatrix(); //ycue glPushMatrix(); glTranslatef(-12, -2, 0); glColor3f(1.0,0.0,0.1); glScalef(11, 2, 5); glutSolidSphere(1, 1, 0.0); glPopMatrix(); ////////////////////pravaya ruka glPushMatrix(); glRotatef(joint_ui_data->getDOF(Keyframe::FLIPPER_Z), 0. 0, 0.0, 1.0); //glRotatef(joint_ui_data->getDOF(Keyframe::R_HAND_X), 1 .0, 0.0, 0.0); //glRotatef(joint_ui_data->getDOF(Keyframe::R_HAND_Y), 0 .0, 1.0, 0.0); //glRotatef(joint_ui_data->getDOF(Keyframe::R_HAND_Z), 1 .0, 0.0, 0.0); glColor3f(0.369, 0.369, 0.369); glRotated(10, 11.0, 5.0, 1.0); glRotatef(-15, 1.0, 1.0, 1.0); drawTriangle(-1, 6, 6); drawTriangle(3, 8, 2); drawTriangle(2,-4, 4); drawTriangle(5,-4,8); glPopMatrix(); glPopMatrix(); glFlush(); // Now, show the frame buffer that we just drew into. // (this prevents flickering). glutSwapBuffers(); } // Helper function that draws a square translated // to specified height // Draw a unit cube, centered at the current location // README: Helper code for drawing a cube void drawCube() { glBegin(GL_QUADS); // draw front face glVertex3f(-1.0, -1.0, 1.0); glVertex3f( 1.0, -1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); // draw back face glVertex3f( 1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, -1.0);

glVertex3f(-1.0, 1.0, -1.0); glVertex3f( 1.0, 1.0, -1.0); // draw left face glVertex3f(-1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); // draw right face glVertex3f( 1.0, -1.0, 1.0); glVertex3f( 1.0, -1.0, -1.0); glVertex3f( 1.0, 1.0, -1.0); glVertex3f( 1.0, 1.0, 1.0); // draw top glVertex3f(-1.0, 1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); glVertex3f(-1.0, 1.0, -1.0); // draw bottom glVertex3f(-1.0, -1.0, -1.0); glVertex3f( 1.0, -1.0, -1.0); glVertex3f( 1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glEnd(); } void drawTriangle(int x, int y, float width) { // Draw the triangle glBegin(GL_TRIANGLES); glVertex2d(-width + x, -width + y); glVertex2d(width + x, -width + y); glVertex2d(x, width + y); glEnd(); }

Potrebbero piacerti anche