3dCamera.cpp
资源名称:gloop.zip [点击查看]
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:12k
源码类别:
OpenGL
开发平台:
Visual C++
- /////////////////////////////////////////////////////////////////////////////
- // C3dCamera.cpp : implementation file
- //
- // glOOP (OpenGL Object Oriented Programming library)
- // Copyright (c) Craig Fahrnbach 1997, 1998
- //
- // OpenGL is a registered trademark of Silicon Graphics
- //
- //
- // This program is provided for educational and personal use only and
- // is provided without guarantee or warrantee expressed or implied.
- //
- // Commercial use is strickly prohibited without written permission
- // from ImageWare Development.
- //
- // This program is -not- in the public domain.
- //
- /////////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "glOOP.h"
- #include "AnimationDialog.h"
- #include "3dObjectDialog.h"
- #include "3dCameraDialog.h"
- #include "math.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // C3dCamera
- IMPLEMENT_DYNAMIC(C3dCamera, CObject)
- /////////////////////////////////////////////////////////////////////////////
- // C3dCamera construction
- C3dCamera::C3dCamera()
- {
- // Initialize our cameras' member variables
- m_szName = _T("Camera");
- m_fOrigin[0] = 0.0f;
- m_fOrigin[1] = 2.0f;
- m_fOrigin[2] = 15.0f;
- m_fRotation[0] = -75.0f;
- m_fRotation[1] = 0.0f;
- m_fRotation[2] = -15.0f;
- m_fFovY = 45.0f;
- m_fNear = 1.0f;
- m_fFar = 5000.0f;
- m_bPerspective = TRUE;
- m_iViewType = VIEW_ISO;
- m_bBuildLists = TRUE;
- m_iDisplayLists = 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dCamera Destructor
- C3dCamera::~C3dCamera()
- {
- // Delete the DisplayLists
- if(m_iDisplayLists)
- {
- glDeleteLists(m_iDisplayLists, 1);
- m_iDisplayLists = 0;
- }
- // Delete all animation procedures attached to
- // this camera
- m_AnimList.DeleteAll();
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dLight serialization
- void C3dCamera::Serialize(CArchive& ar, int iVersion)
- {
- CString szBuffer;
- if (ar.IsStoring())
- {
- // Save the Camera member variables
- szBuffer.Format("C3dCamera {n");
- ar.WriteString(szBuffer);
- szBuffer.Format("tOrigin < %f %f %f >n", m_fOrigin[0], m_fOrigin[1], m_fOrigin[2]);
- ar.WriteString(szBuffer);
- szBuffer.Format("tRotation < %f %f %f >n", m_fRotation[0], m_fRotation[1], m_fRotation[2]);
- ar.WriteString(szBuffer);
- szBuffer.Format("tPerspective View < %d >n", m_bPerspective);
- ar.WriteString(szBuffer);
- szBuffer.Format("tField of View 'Y' < %f >n", m_fFovY);
- ar.WriteString(szBuffer);
- szBuffer.Format("tNear clip Plane < %f >n", m_fNear);
- ar.WriteString(szBuffer);
- szBuffer.Format("tFar clip Plane < %f >n", m_fFar);
- ar.WriteString(szBuffer);
- // Save any CAnimation derived class procedure(s)
- m_AnimList.Serialize(ar, iVersion);
- szBuffer.Format("}nn"); // end of camera def
- ar.WriteString(szBuffer);
- }
- else
- {
- // Read the Camera member variables
- ar.ReadString(szBuffer);
- if(iVersion > 101)
- sscanf(szBuffer, "tOrigin < %f %f %f >n", &m_fOrigin[0], &m_fOrigin[1], &m_fOrigin[2]);
- else
- sscanf(szBuffer, "tPosition < %f %f %f >n", &m_fOrigin[0], &m_fOrigin[1], &m_fOrigin[2]);
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tRotation < %f %f %f >n", &m_fRotation[0], &m_fRotation[1], &m_fRotation[2]);
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tPerspective View < %d >n", &m_bPerspective);
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tField of View 'Y' < %f >n", &m_fFovY);
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tNear clip Plane < %f >n", &m_fNear);
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tFar clip Plane < %f >n", &m_fFar);
- if(iVersion > 101)
- {
- // Load any CAnimation derived class procedure(s)
- m_AnimList.Serialize(ar, iVersion);
- }
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "}nn");
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dCamera Procedures
- void C3dCamera::PositionCamera()
- {
- // Translate to the camera position. We invert the sign
- // of the camera positions because we are actually moving
- // the World coordinates, not the cameras..
- glTranslated(-m_fOrigin[X], -m_fOrigin[Y], -m_fOrigin[Z]);
- // Rotate the camera
- glRotatef(m_fRotation[X], 1.0f, 0.0f, 0.0f);
- glRotatef(m_fRotation[Y], 0.0f, 1.0f, 0.0f);
- glRotatef(m_fRotation[Z], 0.0f, 0.0f, 1.0f);
- // Save the Model view matrix. This is used later for
- // conversion of mouse coordinates to world coordinates.
- glGetDoublev(GL_MODELVIEW_MATRIX, m_dModelViewMatrix);
- }
- void C3dCamera::GetOrigin(GLfloat *x, GLfloat *y, GLfloat *z)
- {
- *x = m_fOrigin[X];
- *y = m_fOrigin[Y];
- *z = m_fOrigin[Z];
- }
- void C3dCamera::GetRotation(GLfloat *x, GLfloat *y, GLfloat *z)
- {
- *x = m_fRotation[X];
- *y = m_fRotation[Y];
- *z = m_fRotation[Z];
- }
- void C3dCamera::SetOrigin(GLfloat x, GLfloat y, GLfloat z)
- {
- m_fOrigin[X] = x;
- m_fOrigin[Y] = y;
- m_fOrigin[Z] = z;
- }
- void C3dCamera::SetRotation(GLfloat x, GLfloat y, GLfloat z)
- {
- m_fRotation[X] = x;
- m_fRotation[Y] = y;
- m_fRotation[Z] = z;
- }
- 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 = (GLfloat)m_iScreenWidth;
- else
- m_fAspect = (GLfloat)m_iScreenWidth/(GLfloat)m_iScreenHeight;
- // Calculate the clipping volume along the y-axis, then set our
- // right, left, top and bottom clipping volumn
- GLfloat viewDepth = fabs(m_fOrigin[2]);
- GLfloat clipY = 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_fOrigin[2], m_fFar);
- }
- // Reset the ModelView matrix
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
- void C3dCamera::GetWorldCoord(int ix, int iy, GLfloat fz, VECTORF coord)
- {
- float fx, fy = 0.0f;
- float fMouseZScale = 0.01f;
- // Calculate the mouse screen coordinates sx & sy
- // relative to the center of the screen
- float centerX = (float)m_iScreenWidth/2;
- float centerY = (float)m_iScreenHeight/2;
- float sx = ix - centerX;
- float sy = centerY - iy;
- // Calculate the mouse position mx & my along the screen
- // axis (results from 1.0 to 0.0 to -1.0)
- float mx = sx/centerX;
- float my = sy/centerY;
- // Correct for perspective?
- if(m_bPerspective) {
- // Calculate the distance from the viewer to the
- // mouse "z" depth position
- float fDz;
- fDz = m_fOrigin[2]-fz;
- fx=mx*fDz*(float)tan(m_fFovY/2*PiOver180)*m_fAspect;
- fy=my*fDz*(float)tan(m_fFovY/2*PiOver180);
- }
- else {
- fx=mx*fabs(m_fRight);
- fy=my*fabs(m_fTop);
- }
- // Compensate for camera X & Y position
- fx += m_fOrigin[0];
- fy += m_fOrigin[1];
- // Compensate for camera rotation by transformation
- // to the ModelView matrix
- VECTORF Source;
- Vec3f(fx, fy, fz, Source);
- Transformf(Source, coord, m_dModelViewMatrix);
- }
- int C3dCamera::EditAttributes(CWnd* pParentWnd, C3dWorld* pWorld)
- {
- char szName[80];
- sprintf(szName, "Edit Attributes of 3dWorld camera '%s'", m_szName);
- C3dCameraPropSheet* pCameraPropSheet = new C3dCameraPropSheet(szName, pParentWnd, this, pWorld);
- // Create and display the modal dialog box
- return( pCameraPropSheet->DoModal() );
- }
- int C3dCamera::EditAnimation(CWnd* pParentWnd, C3dWorld* pWorld)
- {
- char szName[80];
- sprintf(szName, "Edit Animation Attributes of Camera");
- CAnimPropSheet* pAnimPropSheet = new CAnimPropSheet(szName, pParentWnd, NULL, this, pWorld);
- // Create and display the modal dialog box
- return( pAnimPropSheet->DoModal() );
- }
- void C3dCamera::AddAnimationPages(C3dWorld* pWorld, LPVOID pSht)
- {
- CAnimPropSheet* pSheet = (CAnimPropSheet*)pSht;
- ASSERT(pSheet);
- // Load all animation pages for this object
- CAnimation* pAnimation = NULL;
- // walk the list
- POSITION Pos = m_AnimList.GetHeadPosition();
- while (Pos) {
- pAnimation = m_AnimList.GetAt(Pos);
- pAnimation->AddAnimationPage(pSht, NULL, this, NULL);
- pAnimation = m_AnimList.GetNext(Pos);
- }
- }
- void C3dCamera::Animate(double time)
- {
- // Animate the camera based on its animation procedures
- CAnimation* pAnimation = NULL;
- // walk the list
- POSITION Pos = m_AnimList.GetHeadPosition();
- while (Pos) {
- pAnimation = m_AnimList.GetAt(Pos);
- pAnimation->AnimateCamera(this, time);
- pAnimation = m_AnimList.GetNext(Pos);
- }
- }
- void C3dCamera::ResetAnimation()
- {
- // Reset the animation variables
- CAnimation* pAnimation = NULL;
- // walk the list
- POSITION Pos = m_AnimList.GetHeadPosition();
- while (Pos) {
- pAnimation = m_AnimList.GetAt(Pos);
- pAnimation->RestoreCameraAttributes(this);
- pAnimation = m_AnimList.GetNext(Pos);
- }
- }
- int C3dCamera::LoadBitMapImage(CImageList* pList)
- {
- CBitmap bitmap;
- // If the image index has been stored in the camera,
- // return the index.
- if(m_iBMImage > -1)
- return m_iBMImage;
- // If the image index for this camera type has been
- // created, store the index for this camera and
- // return the index.
- if( iCameraBMImage > -1) {
- m_iBMImage = iCameraBMImage;
- return m_iBMImage;
- }
- // The image index for this camera type has not been
- // loaded and the camera image index has not been
- // stored.
- //
- // Load the bitmap for the non-selected camera
- bitmap.LoadBitmap(IDB_CAMERA);
- m_iBMImage = pList->Add(&bitmap, (COLORREF)0xFFFFFF);
- bitmap.DeleteObject();
- // Load the bitmap for the selected light
- bitmap.LoadBitmap(IDB_CAMERA_SELECTED);
- pList->Add(&bitmap, (COLORREF)0xFFFFFF);
- bitmap.DeleteObject();
- iCameraBMImage = m_iBMImage;
- return m_iBMImage;
- }
- void C3dCamera::GetTransformMatrix(Matx4x4 XformMatrix)
- {
- // Calculate the objects' transformation matrix
- PrepareMatrix(m_fOrigin[X], m_fOrigin[Y], m_fOrigin[Z],
- 1.0f, 1.0f, 1.0f, // Scale
- m_fRotation[X], m_fRotation[Y], m_fRotation[Z],
- 0.0f, 0.0f, 0.0f, // Translation
- XformMatrix);
- }
- void C3dCamera::GetInvTransformMatrix(Matx4x4 XformMatrix)
- {
- // Calculate the objects' transformation matrix
- PrepareInvMatrix(m_fOrigin[X], m_fOrigin[Y], m_fOrigin[Z],
- 1.0f, 1.0f, 1.0f, // Scale
- m_fRotation[X], m_fRotation[Y], m_fRotation[Z],
- 0.0f, 0.0f, 0.0f, // Translation
- XformMatrix);
- }
- void C3dCamera::GetRotationMatrix(Matx4x4 XformMatrix)
- {
- // Calculate the objects' rotation matrix
- PrepareMatrix(0.0f, 0.0f, 0.0f, // Origin
- 1.0f, 1.0f, 1.0f, // Scale
- m_fRotation[X], m_fRotation[Y], m_fRotation[Z],
- 0.0f, 0.0f, 0.0f, // Translation
- XformMatrix);
- }
- void C3dCamera::GetInvRotationMatrix(Matx4x4 XformMatrix)
- {
- // Calculate the objects' transformation matrix
- PrepareInvMatrix(0.0f, 0.0f, 0.0f, // Origin
- 1.0f, 1.0f, 1.0f, // Scale
- m_fRotation[X], m_fRotation[Y], m_fRotation[Z],
- 0.0f, 0.0f, 0.0f, // Translation
- XformMatrix);
- }