void GraphicCamera::MouseMotionEventHandler(int x, int y) { int mouse_dx, mouse_dy, d; double z; Vec3d mouse_pos, dir; Vec3d WndX, WndY, WndZ; float realy; double wx, wy, wz; if (CameraMode != kINACTIVE) { mouse_dx = x - MousePrevX; mouse_dy = y - MousePrevY; if (abs(mouse_dx) > abs(mouse_dy)) { d = mouse_dx; } else { d = mouse_dy; } switch(CameraMode) { case kZOOM: z = (double) d / 100.0; dir = aim_ - pos_; if (dir.Norm() < 0.1 && z > 0) { z *= 10.0; aim_ = aim_ + z * dir; } pos_ = pos_ + z * dir; break; case kROTATE: dt_azim = ((double) (x - MouseStartX)) / 5.0; dt_elev = ((double) (y - MouseStartY)) / 5.0; loc_dt_azim = ((double) mouse_dx) / 5.0; loc_dt_elev = ((double) mouse_dy) / 5.0; WndX = {1.0, 0.0, 0.0}; WndY = {0.0, 1.0, 0.0}; RotateX(WndX, current_elev + dt_elev); RotateY(WndX, current_azim + dt_azim); WndX.z() *= -1; RotateX(WndY, current_elev + dt_elev); RotateY(WndY, current_azim + dt_azim); WndY.z() *= -1; WndZ = (WndX % WndY).Normalization(); ArbitraryRotate(WndX, WndY, WndZ, loc_dt_elev, 0, pos_, aim_); ArbitraryRotate(Vec3d(1, 0, 0), Vec3d(0, 1, 0), Vec3d(0, 0, 1), 0, -loc_dt_azim, pos_, aim_); up_ = WndY.Normalization(); break; case kTRANSLATE: realy = ViewPort[3] - y - 1; gluProject(aim_.x(), aim_.y(), aim_.z(), MvMat.GetPtr(), ProjMat.GetPtr(), ViewPort, &wx, &wy, &wz); gluUnProject((GLdouble) x, (GLdouble) realy, wz, MvMat.GetPtr(), ProjMat.GetPtr(), ViewPort, &mouse_pos.x(), &mouse_pos.y(), &mouse_pos.z()); // move both the camera position and its aim coordinate dir = mouse_pos - PrevMousePos; pos_ = pos_ - dir; aim_ = aim_ - dir; PrevMousePos = mouse_pos; break; } MousePrevX = x; MousePrevY = y; } }
void draw_s2fishdome(CAMERA cam) { // draw a fisheye / warped projection of the geometry double r, near, far; XYZ vp, vd, vr, vl; XYZ vright, vleft, vup; // Calculate various view vectors vp = cam.vp; vd = cam.vd; vr = CrossProduct(vd,cam.vu); vl = CrossProduct(cam.vu,vd); vd = ArbitraryRotate(vd,cam.fishrotate,vr); vup = CrossProduct(vr,vd); vright = VectorAdd(vr,vd); vleft = VectorAdd(vl,vd); near = VectorLength(_s2priv_pmin(),_s2priv_pmax()) / 100; far = MAX(cam.focallength,VectorLength(_s2priv_pmin(), _s2priv_pmax())) * 20; // Left glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0,0,TEXTURESIZE,TEXTURESIZE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); s2Perspective(90.0,1.0,near,far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); s2LookAt(vp.x,vp.y,vp.z,vp.x+vleft.x,vp.y+vleft.y,vp.z+vleft.z,vup.x,vup.y,vup.z); MakeLighting(); MakeMaterial(); MakeGeometry(FALSE, FALSE); glBindTexture(GL_TEXTURE_2D,walltextureid[2]); glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,TEXTURESIZE,TEXTURESIZE); // Right glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0,0,TEXTURESIZE,TEXTURESIZE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); s2Perspective(90.0,1.0,near,far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); s2LookAt(vp.x,vp.y,vp.z,vp.x+vright.x,vp.y+vright.y,vp.z+vright.z,vup.x,vup.y,vup.z); MakeLighting(); MakeMaterial(); MakeGeometry(FALSE, FALSE); glBindTexture(GL_TEXTURE_2D,walltextureid[3]); glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,TEXTURESIZE,TEXTURESIZE); // Top glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0,0,TEXTURESIZE,TEXTURESIZE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); s2Perspective(90.0,1.0,near,far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); s2LookAt(vp.x,vp.y,vp.z,vp.x+vup.x,vp.y+vup.y,vp.z+vup.z,-vright.x,-vright.y,-vright.z); MakeLighting(); MakeMaterial(); MakeGeometry(FALSE, FALSE); glBindTexture(GL_TEXTURE_2D,walltextureid[0]); glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,TEXTURESIZE,TEXTURESIZE); // Bottom glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glViewport(0,0,TEXTURESIZE,TEXTURESIZE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); s2Perspective(90.0,1.0,near,far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); s2LookAt(vp.x,vp.y,vp.z,vp.x-vup.x,vp.y-vup.y,vp.z-vup.z,-vleft.x,-vleft.y,-vleft.z); MakeLighting(); MakeMaterial(); MakeGeometry(FALSE, FALSE); glBindTexture(GL_TEXTURE_2D,walltextureid[1]); glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,TEXTURESIZE,TEXTURESIZE); // Remember the graphics state and return it at the end glPushAttrib(GL_ALL_ATTRIB_BITS); glDisable(GL_LIGHTING); glDisable(GL_ALPHA_TEST); glDisable(GL_COLOR_MATERIAL); glDisable(GL_DITHER); //glDisable(GL_FOG); glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_STIPPLE); glDisable(GL_SCISSOR_TEST); glDisable(GL_STENCIL_TEST); // Setup projections for the dome glDrawBuffer(GL_BACK); if (_s2fd_options->dometype == WARPMAP) glClearColor(0.0,0.0,0.0,0.0); else glClearColor(0.05,0.05,0.05,0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0,0,_s2fd_options->screenwidth,_s2fd_options->screenheight); r = _s2fd_options->screenwidth / (double)_s2fd_options->screenheight; switch (_s2fd_options->dometype) { case TRUNCTOP: case TRUNCBOTTOM: glOrtho(-r*0.75,r*0.75,-0.75,0.75,0.1,10.0); break; case HSPHERICAL: glOrtho(-r*0.75,r*0.75,-0.75,0.75,0.1,10.0); break; case VSPHERICAL: case WARPMAP: default: glOrtho(-r,r,-1.0,1.0,0.1,10.0); break; } // Create camera projection for dome glMatrixMode(GL_MODELVIEW); glLoadIdentity(); switch (_s2fd_options->dometype) { case TRUNCBOTTOM: s2LookAt(0.0,-1.0,0.25,0.0,0.0,0.25,0.0,0.0,1.0); break; case TRUNCTOP: s2LookAt(0.0,-1.0,-0.25,0.0,0.0,-0.25,0.0,0.0,1.0); break; case HSPHERICAL: case VSPHERICAL: case WARPMAP: default: s2LookAt(0.0,-1.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0); break; } // Finally draw the dome geometry glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glColor3f(1.0,1.0,1.0); DrawDome(TRUE,FALSE); _s2_fadeinout(); DrawExtras(); glPopAttrib(); }