void C3dCamera::ResetView(int w, int h) { // Save the screen width and height if(w || h) { m_iScreenWidth = (GLsizei)w; m_iScreenHeight = (GLsizei)h; } // calculate the aspect ratio of the screen if (m_iScreenHeight==0) m_fAspect = (GLdouble)m_iScreenWidth; else m_fAspect = (GLdouble)m_iScreenWidth/(GLdouble)m_iScreenHeight; // Calculate the clipping volume along the y-axis, then set our // right, left, top and bottom clipping volumn GLdouble viewDepth = (GLdouble)GetFocalLength(); GLdouble clipY = (GLdouble)tan(Radiansf(m_fFovY/2))*viewDepth; if(m_iScreenWidth <= m_iScreenHeight) { m_fLeft = -clipY; m_fRight = clipY; m_fBottom = -clipY*m_iScreenHeight/m_iScreenWidth; m_fTop = clipY*m_iScreenHeight/m_iScreenWidth; } else { m_fLeft = -clipY*m_iScreenWidth/m_iScreenHeight; m_fRight = clipY*m_iScreenWidth/m_iScreenHeight; m_fBottom = -clipY; m_fTop = clipY; } // Set Viewport to window dimensions glViewport(0, 0, m_iScreenWidth, m_iScreenHeight); // Reset the projection matrix (coordinate system) glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(m_bPerspective) { // Perspective transformations. gluPerspective(m_fFovY, m_fAspect, m_fNear, m_fFar); } else { // Orthographic transformations. glOrtho(m_fLeft, m_fRight, m_fBottom, m_fTop, m_fNear, m_fFar); } // Save the Projection matrix. This is used later for // conversion of mouse coordinates to world coordinates. glGetDoublev(GL_PROJECTION_MATRIX, m_dProjectionMatrix); // Save the Projection matrix. This is used later for // conversion of mouse coordinates to world coordinates. glGetIntegerv(GL_VIEWPORT, m_iViewport); // Reset the ModelView matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); }
void C3dCamera::GetScreenCoord(GLdouble wX, GLdouble wY, GLdouble wZ, double& scrX, double& scrY, double& scrZ) { gluProject(wX, wY, wZ, m_dModelViewMatrix,m_dProjectionMatrix,m_iViewport, &scrX,&scrY,&scrZ); scrY = (GLdouble)m_iViewport[3]-scrY; scrZ += GetFocalLength(); }
/** * Setup this camera according to the specified center, vector a, and the view direction. * * @param C the center of the camera * @param a the vector a (The horizontal direction of the screen) * @param vd the view direction of the camera */ void PPC::Set(const V3& C, const V3& a, const V3& vd) { this->C = C; this->a = a; b = (vd ^ a).UnitVector() * b.Length(); c = vd.UnitVector() * GetFocalLength() - a * ((float)w/2.0f) - b * ((float)h/2.0f); SetPMat(); }
/** * Setup this camera such that it looks at the specified point with the specified view direction, up direction, and the distance from the point. * * @param p the target point that this camera will look at * @param vd the view direction * @param up the up direction * @param d the distance between the center of this camera and the target */ void PPC::LookAt(const V3 &p, const V3 &vd, const V3 &up, float d) { float f = GetFocalLength(); C = p - vd.UnitVector() * d; a = (vd ^ up).UnitVector() * a.Length(); b = (vd ^ a).UnitVector() * b.Length(); c = vd.UnitVector() * f - a * ((float)w / 2.0f) - b * ((float)h / 2.0f); SetPMat(); }
void C3dCamera::GetWorldCoord(int ix, int iy, GLdouble fz, SG_VECTOR& coord) { GLdouble x, y, z, winX, winY, winZ; // Fix the yPos value. MS Windows origin 0,0 is upper left // while OpenGL windows origin 0,0 is lower left... winX = (GLdouble)ix; winY = (GLdouble)m_iViewport[3]-iy; // Add the camera's focal length, or distance from 'LookAt' to 'Eye' position // to the given 'z' coordinate. fz += GetFocalLength(); // Calculate the winZ coordinate: if(m_bPerspective) // Compensate for perspective view winZ = 0.5 + (((m_fFar+m_fNear)-(2*m_fFar*m_fNear)/fz))/(2*(m_fFar-m_fNear)); else // winZ is linearly interpolated between the Near_Far clipping plane winZ = (fz-m_fNear)/(m_fFar-m_fNear); // Unproject the point gluUnProject(winX, winY, winZ, m_dModelViewMatrix, m_dProjectionMatrix, m_iViewport, &x, &y, &z); // Copmensate for rounding errors if(fabs(x) < SMALL_NUMBER) x = 0; if(fabs(y) < SMALL_NUMBER) y = 0; if(fabs(z) < SMALL_NUMBER) z = 0; coord.x = x; coord.y = y; coord.z = z; }
/** * Get the horizontal field of view [degree]. * * @return the horizontal field of view [degree] */ float PPC::GetHFOV() const { return RAD2DEG(2.0f * atan2f((float)w / 2.0f * a.Length(), GetFocalLength())); }