#include "Input.h" #include "utils.h" #include "Renderer.h" #include #include Input Input::m_instance; GLvoid Input::keyboard_event(GLubyte key, GLint x, GLint y) { switch ( key ) { case 'w': this->menu(ZOOM_IN_EVENT); break; case 's': this->menu(ZOOM_OUT_EVENT); break; case 'a': this->menu(ANIMATE_EVENT); break; case 'l': this->menu(LINES_EVENT); break; case 'f': this->menu(FULL_EVENT); break; default: break; } } GLvoid Input::menu( int value ) { switch ( value ) { case ZOOM_IN_EVENT: Renderer::getInstance()->divViewDist(1.2); break; case ZOOM_OUT_EVENT: Renderer::getInstance()->multViewDist(1.2); break; case LINES_EVENT: glDisable(GL_CULL_FACE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); Renderer::getInstance()->render(); break; case FULL_EVENT: glEnable(GL_CULL_FACE); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); Renderer::getInstance()->render(); break; case ANIMATE_EVENT: Renderer::getInstance()->animate = Renderer::getInstance()->animate ? false : true; Renderer::getInstance()->render(); break; default: break; } } GLvoid Input::passive_motion(GLint mx, GLint my) { } GLvoid Input::button_motion(GLint mx, GLint my) { /* First calculate P */ static Point v; Point p, w, a; //Give us the scaled p on the sphere scalePoint(p,mx,my); //get the unit vector of p GLfloat length = p.magnitude(); if (length==0) { return; } else { w.x = p.x / length; w.y = p.y / length; w.z = p.z / length; } //This is the first time the movement has been made if (oldPoint.z == -1) { scalePoint(oldPoint,(int)oldPoint.x,(int)oldPoint.y); length = oldPoint.magnitude(); if (length==0) { return; } else { v.x = oldPoint.x / length; v.y = oldPoint.y / length; v.z = oldPoint.z / length; } } cross(a,oldPoint,p); length = a.magnitude(); if (length==0) { return; } else { a.x /= length; a.y /= length; a.z /= length; } GLfloat angle = dot(v,w); if (angle > 1) { angle = 1; } else if (angle < -1) { angle = -1; } angle = acos(angle); /* Perform the rotation calculation */ GLfloat newMatrix[16]; calcAngle(newMatrix,angle,a); /* Make OpenGL do our work */ glPushMatrix(); glLoadMatrixf(newMatrix); glMultMatrixf(Renderer::getInstance()->currModelTransform); glGetFloatv(GL_MODELVIEW_MATRIX,Renderer::getInstance()->currModelTransform); glMatrixMode(GL_MODELVIEW); glPopMatrix(); oldPoint = p; v = w; glutPostRedisplay(); return; } GLvoid Input::mouse_button(GLint btn, GLint state, GLint mx, GLint my) { switch( btn ) { case GLUT_LEFT_BUTTON: switch( state ) { case GLUT_DOWN: oldPoint.x = mx; oldPoint.y = my; oldPoint.z = -1; break; case GLUT_UP: break; } break; case GLUT_MIDDLE_BUTTON: switch( state ) { case GLUT_DOWN: break; case GLUT_UP: break; } break; case GLUT_RIGHT_BUTTON: switch( state ) { case GLUT_DOWN: break; case GLUT_UP: break; } break; } } void Input::calcAngle(GLfloat *newMatrix, GLfloat angle, Point& a) { newMatrix[0] = 1.+(1.-cos(angle))*(pow(a.x,2)-1.); newMatrix[1] = a.z*sin(angle) + (1.-cos(angle)) * a.x * a.y; newMatrix[2] = -1. * a.y * sin(angle) + (1.-cos(angle))*a.x*a.z; newMatrix[3] = 0; newMatrix[4] = -1. * a.z * sin(angle) + (1.-cos(angle)) * a.x * a.y; newMatrix[5] = 1. + (1. - cos(angle))*(pow(a.y,2)-1.); newMatrix[6] = a.x * sin(angle) + (1.-cos(angle))*a.y*a.z; newMatrix[7] = 0; newMatrix[8] = a.y * sin(angle) + (1.-cos(angle))*a.x * a.z; newMatrix[9] = -1. * a.x * sin(angle) + (1.-cos(angle))*a.y*a.z; newMatrix[10] = 1. + (1.-cos(angle))*(pow(a.z,2)-1.); newMatrix[11] = newMatrix[12] = newMatrix[13] = newMatrix[14] = 0; newMatrix[15] = 1.; } void Input::scalePoint(Point& p, GLint mx, GLint my) { //scale to -1 and 1 float scale = ceil(Renderer::getInstance()->getVPD()/2.); p.x = (mx / scale) -1.; p.y = (my / scale) -1.; p.y*=-1.; //handle reversed y p.z = 1.-pow(p.x,2)-pow(p.y,2); if (p.z < 0) { float under = sqrt((p.x*p.x)+(p.y*p.y)); p.x /= under; p.y /= under; p.z = 0; } else { p.z = sqrt(p.z); } }