void GLUTDisplay(const AffineSpace3f& camera, float s, Handle<Device::RTScene>& scene) { g_camSpace = camera; g_speed = s; g_render_scene = scene; scene = NULL; // GLUT will never end this function, thus cleanup scene by hand /* initialize orbit camera model */ Vector3f viewVec = normalize(g_camLookAt - g_camPos); theta = atan2f(-viewVec.x, -viewVec.z); phi = asinf(viewVec.y); Vector3f approxUp(0.0f, 1.0f, 0.0f); if (phi < -0.5f*float(pi) || phi > 0.5*float(pi)) approxUp = -approxUp; Vector3f rightVec = normalize(cross(viewVec, approxUp)); Vector3f upUnrotated = cross(rightVec, viewVec); psi = atan2f(dot(rightVec, g_camUp), dot(upUnrotated, g_camUp)); /* initialize GLUT */ int argc = 1; char* argv = (char*)""; glutInit(&argc, &argv); glutInitWindowSize((GLsizei)g_width, (GLsizei)g_height); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowPosition(0, 0); g_window = glutCreateWindow("Embree"); if (g_fullscreen) glutFullScreen(); //glutSetCursor(GLUT_CURSOR_NONE); glutDisplayFunc(displayFunc); glutIdleFunc(idleFunc); glutKeyboardFunc(keyboardFunc); glutSpecialFunc(specialFunc); glutMouseFunc(clickFunc); glutMotionFunc(motionFunc); glutReshapeFunc(reshapeFunc); glutMainLoop(); }
void motionFunc(int x, int y) { float dClickX = float(clickX - x), dClickY = float(clickY - y); clickX = x; clickY = y; // Rotate camera around look-at point (LMB + mouse move) if (mouseMode == 1) { #define ROTATE_WITH_FIXED_UPVECTOR 1 #if ROTATE_WITH_FIXED_UPVECTOR float angularSpeed = 0.05f / 180.0f * float(pi); float theta = dClickX * angularSpeed; float phi = dClickY * angularSpeed; const Vector3f viewVec = normalize(g_camLookAt - g_camPos); float dist = length(g_camLookAt - g_camPos); const Vector3f dX = normalize(cross(viewVec,g_camUp)); const Vector3f dY = normalize(cross(viewVec,dX)); AffineSpace3f rot_x = AffineSpace3f::rotate(g_camLookAt,dX,phi); g_camSpace = rot_x * g_camSpace; g_camSpace = AffineSpace3f::rotate(g_camLookAt,dY,theta) * g_camSpace; g_camPos = g_camLookAt-dist*xfmVector(g_camSpace,Vector3f(0,0,1)); #else float angularSpeed = 0.05f / 180.0f * float(pi); float mapping = 1.0f; if (g_camUp[1] < 0) mapping = -1.0f; theta -= mapping * dClickX * angularSpeed; phi += dClickY * angularSpeed; if (theta < 0) theta += 2.0f * float(pi); if (theta > 2.0f*float(pi)) theta -= 2.0f * float(pi); if (phi < -1.5f*float(pi)) phi += 2.0f*float(pi); if (phi > 1.5f*float(pi)) phi -= 2.0f*float(pi); float cosPhi = cosf(phi); float sinPhi = sinf(phi); float cosTheta = cosf(theta); float sinTheta = sinf(theta); float dist = length(g_camLookAt - g_camPos); g_camPos = g_camLookAt + dist * Vector3f(cosPhi * sinTheta, -sinPhi, cosPhi * cosTheta); Vector3f viewVec = normalize(g_camLookAt - g_camPos); Vector3f approxUp(0.0f, 1.0f, 0.0f); if (phi < -0.5f*float(pi) || phi > 0.5*float(pi)) approxUp = -approxUp; Vector3f rightVec = normalize(cross(viewVec, approxUp)); AffineSpace3f rotate = AffineSpace3f::rotate(viewVec, psi); g_camUp = xfmVector(rotate, cross(rightVec, viewVec)); #endif } // Pan camera (MMB + mouse move) if (mouseMode == 2) { float panSpeed = 0.00025f; float dist = length(g_camLookAt - g_camPos); Vector3f viewVec = normalize(g_camLookAt - g_camPos); Vector3f strafeVec = cross(g_camUp, viewVec); Vector3f deltaVec = strafeVec * panSpeed * dist * float(dClickX) + g_camUp * panSpeed * dist * float(-dClickY); g_camPos += deltaVec; g_camLookAt += deltaVec; } // Dolly camera (RMB + mouse move) if (mouseMode == 3) { float dollySpeed = 0.01f; float delta; if (fabsf(dClickX) > fabsf(dClickY)) delta = float(dClickX); else delta = float(-dClickY); float k = powf((1-dollySpeed), delta); float dist = length(g_camLookAt - g_camPos); Vector3f viewVec = normalize(g_camLookAt - g_camPos); g_camPos += dist * (1-k) * viewVec; } // Roll camera (ALT + LMB + mouse move) if (mouseMode == 4) { float angularSpeed = 0.1f / 180.0f * float(pi); psi -= dClickX * angularSpeed; Vector3f viewVec = normalize(g_camLookAt - g_camPos); Vector3f approxUp(0.0f, 1.0f, 0.0f); if (phi < -0.5f*float(pi) || phi > 0.5*float(pi)) approxUp = -approxUp; Vector3f rightVec = normalize(cross(viewVec, approxUp)); AffineSpace3f rotate = AffineSpace3f::rotate(viewVec, psi); g_camUp = xfmVector(rotate, cross(rightVec, viewVec)); } g_camSpace = AffineSpace3f::lookAtPoint(g_camPos, g_camLookAt, g_camUp); g_resetAccumulation = true; }