3dCamera.cpp
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:12k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // C3dCamera.cpp : implementation file
  3. //
  4. // glOOP (OpenGL Object Oriented Programming library)
  5. // Copyright (c) Craig Fahrnbach 1997, 1998
  6. //
  7. // OpenGL is a registered trademark of Silicon Graphics
  8. //
  9. //
  10. // This program is provided for educational and personal use only and
  11. // is provided without guarantee or warrantee expressed or implied.
  12. //
  13. // Commercial use is strickly prohibited without written permission
  14. // from ImageWare Development.
  15. //
  16. // This program is -not- in the public domain.
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "glOOP.h"
  21. #include "AnimationDialog.h"
  22. #include "3dObjectDialog.h"
  23. #include "3dCameraDialog.h"
  24. #include "math.h"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. /////////////////////////////////////////////////////////////////////////////
  31. // C3dCamera
  32. IMPLEMENT_DYNAMIC(C3dCamera, CObject)
  33. /////////////////////////////////////////////////////////////////////////////
  34. // C3dCamera construction
  35. C3dCamera::C3dCamera()
  36. {
  37. // Initialize our cameras' member variables
  38. m_szName = _T("Camera");
  39. m_fOrigin[0] =   0.0f;
  40. m_fOrigin[1] =   2.0f;
  41. m_fOrigin[2] =  15.0f;
  42. m_fRotation[0] = -75.0f;
  43. m_fRotation[1] =   0.0f;
  44. m_fRotation[2] = -15.0f;
  45. m_fFovY = 45.0f;
  46. m_fNear =    1.0f;
  47. m_fFar  = 5000.0f;
  48. m_bPerspective = TRUE;
  49. m_iViewType = VIEW_ISO;
  50. m_bBuildLists = TRUE;
  51. m_iDisplayLists = 0;
  52. }
  53. /////////////////////////////////////////////////////////////////////////////
  54. // C3dCamera Destructor
  55. C3dCamera::~C3dCamera()
  56. {
  57. // Delete the DisplayLists
  58. if(m_iDisplayLists)
  59. {
  60. glDeleteLists(m_iDisplayLists, 1);
  61. m_iDisplayLists = 0;
  62. }
  63. // Delete all animation procedures attached to
  64. // this camera
  65. m_AnimList.DeleteAll();
  66. }
  67. /////////////////////////////////////////////////////////////////////////////
  68. // C3dLight serialization
  69. void C3dCamera::Serialize(CArchive& ar, int iVersion)
  70. {
  71. CString szBuffer;
  72. if (ar.IsStoring())
  73. {
  74. // Save the Camera member variables
  75. szBuffer.Format("C3dCamera {n");
  76. ar.WriteString(szBuffer);
  77. szBuffer.Format("tOrigin    < %f %f %f >n", m_fOrigin[0], m_fOrigin[1], m_fOrigin[2]);
  78. ar.WriteString(szBuffer);
  79. szBuffer.Format("tRotation  < %f %f %f >n", m_fRotation[0], m_fRotation[1], m_fRotation[2]);
  80. ar.WriteString(szBuffer);
  81. szBuffer.Format("tPerspective View  < %d >n", m_bPerspective);
  82. ar.WriteString(szBuffer);
  83. szBuffer.Format("tField of View 'Y' < %f >n", m_fFovY);
  84. ar.WriteString(szBuffer);
  85. szBuffer.Format("tNear clip Plane   < %f >n", m_fNear);
  86. ar.WriteString(szBuffer);
  87. szBuffer.Format("tFar clip Plane    < %f >n", m_fFar);
  88. ar.WriteString(szBuffer);
  89. // Save any CAnimation derived class procedure(s)
  90. m_AnimList.Serialize(ar, iVersion);
  91. szBuffer.Format("}nn"); // end of camera def
  92. ar.WriteString(szBuffer);
  93. }
  94. else
  95. {
  96. // Read the Camera member variables
  97. ar.ReadString(szBuffer);
  98. if(iVersion > 101)
  99. sscanf(szBuffer, "tOrigin    < %f %f %f >n", &m_fOrigin[0], &m_fOrigin[1], &m_fOrigin[2]);
  100. else
  101. sscanf(szBuffer, "tPosition  < %f %f %f >n", &m_fOrigin[0], &m_fOrigin[1], &m_fOrigin[2]);
  102. ar.ReadString(szBuffer);
  103. sscanf(szBuffer, "tRotation  < %f %f %f >n", &m_fRotation[0], &m_fRotation[1], &m_fRotation[2]);
  104. ar.ReadString(szBuffer);
  105. sscanf(szBuffer, "tPerspective View  < %d >n", &m_bPerspective);
  106. ar.ReadString(szBuffer);
  107. sscanf(szBuffer, "tField of View 'Y' < %f >n", &m_fFovY);
  108. ar.ReadString(szBuffer);
  109. sscanf(szBuffer, "tNear clip Plane   < %f >n", &m_fNear);
  110. ar.ReadString(szBuffer);
  111. sscanf(szBuffer, "tFar clip Plane    < %f >n", &m_fFar);
  112. if(iVersion > 101)
  113. {
  114. // Load any CAnimation derived class procedure(s)
  115. m_AnimList.Serialize(ar, iVersion);
  116. }
  117. ar.ReadString(szBuffer);
  118. sscanf(szBuffer, "}nn");
  119. }
  120. }
  121. /////////////////////////////////////////////////////////////////////////////
  122. // C3dCamera Procedures
  123. void C3dCamera::PositionCamera()
  124. {
  125. // Translate to the camera position.  We invert the sign
  126. // of the camera positions because we are actually moving
  127. // the World coordinates, not the cameras..
  128. glTranslated(-m_fOrigin[X], -m_fOrigin[Y], -m_fOrigin[Z]);
  129. // Rotate the camera
  130. glRotatef(m_fRotation[X], 1.0f, 0.0f, 0.0f);
  131. glRotatef(m_fRotation[Y], 0.0f, 1.0f, 0.0f);
  132. glRotatef(m_fRotation[Z], 0.0f, 0.0f, 1.0f);
  133. // Save the Model view matrix.  This is used later for
  134. // conversion of mouse coordinates to world coordinates.
  135. glGetDoublev(GL_MODELVIEW_MATRIX, m_dModelViewMatrix);
  136. }
  137. void C3dCamera::GetOrigin(GLfloat *x, GLfloat *y, GLfloat *z)
  138. {
  139. *x = m_fOrigin[X];
  140. *y = m_fOrigin[Y];
  141. *z = m_fOrigin[Z];
  142. }
  143. void C3dCamera::GetRotation(GLfloat *x, GLfloat *y, GLfloat *z)
  144. {
  145. *x = m_fRotation[X];
  146. *y = m_fRotation[Y];
  147. *z = m_fRotation[Z];
  148. }
  149. void C3dCamera::SetOrigin(GLfloat x, GLfloat y, GLfloat z)
  150. {
  151. m_fOrigin[X] = x;
  152. m_fOrigin[Y] = y;
  153. m_fOrigin[Z] = z;
  154. }
  155. void C3dCamera::SetRotation(GLfloat x, GLfloat y, GLfloat z)
  156. {
  157. m_fRotation[X] = x;
  158. m_fRotation[Y] = y;
  159. m_fRotation[Z] = z;
  160. }
  161. void C3dCamera::ResetView(int w, int h)
  162. {
  163. // Save the screen width and height
  164. if(w || h) {
  165. m_iScreenWidth  = (GLsizei)w;
  166. m_iScreenHeight = (GLsizei)h;
  167. }
  168. // calculate the aspect ratio of the screen
  169. if (m_iScreenHeight==0)
  170. m_fAspect = (GLfloat)m_iScreenWidth;
  171. else
  172. m_fAspect = (GLfloat)m_iScreenWidth/(GLfloat)m_iScreenHeight;
  173. // Calculate the clipping volume along the y-axis, then set our
  174. // right, left, top and bottom clipping volumn
  175. GLfloat viewDepth = fabs(m_fOrigin[2]);
  176. GLfloat clipY = tan(Radiansf(m_fFovY/2))*viewDepth;
  177. if(m_iScreenWidth <= m_iScreenHeight) {
  178. m_fLeft   = -clipY;
  179. m_fRight  =  clipY;
  180. m_fBottom = -clipY*m_iScreenHeight/m_iScreenWidth;
  181. m_fTop    =  clipY*m_iScreenHeight/m_iScreenWidth;
  182. }
  183. else {
  184. m_fLeft   = -clipY*m_iScreenWidth/m_iScreenHeight;
  185. m_fRight  =  clipY*m_iScreenWidth/m_iScreenHeight;
  186. m_fBottom = -clipY;
  187. m_fTop    =  clipY;
  188. }
  189. // Set Viewport to window dimensions
  190. glViewport(0, 0, m_iScreenWidth, m_iScreenHeight);
  191. // Reset the projection matrix (coordinate system)
  192. glMatrixMode(GL_PROJECTION);
  193. glLoadIdentity();
  194. if(m_bPerspective) {
  195. // Perspective transformations.
  196. gluPerspective(m_fFovY, m_fAspect, m_fNear, m_fFar);
  197. }
  198. else {
  199. // Orthographic transformations.
  200. glOrtho(m_fLeft, m_fRight, m_fBottom, m_fTop, -m_fOrigin[2], m_fFar);
  201. }
  202. // Reset the ModelView matrix
  203. glMatrixMode(GL_MODELVIEW);
  204. glLoadIdentity();
  205. }
  206. void C3dCamera::GetWorldCoord(int ix, int iy, GLfloat fz, VECTORF coord)
  207. {
  208. float fx, fy = 0.0f;
  209. float fMouseZScale = 0.01f;
  210. // Calculate the mouse screen coordinates sx & sy
  211. // relative to the center of the screen
  212. float centerX = (float)m_iScreenWidth/2;
  213.     float centerY = (float)m_iScreenHeight/2;
  214. float sx = ix - centerX;
  215. float sy = centerY - iy;
  216. // Calculate the mouse position mx & my along the screen
  217. // axis (results from 1.0 to 0.0 to -1.0)
  218. float mx = sx/centerX;
  219. float my = sy/centerY;
  220. // Correct for perspective?
  221. if(m_bPerspective) {
  222. // Calculate the distance from the viewer to the
  223. // mouse "z" depth position
  224. float fDz;
  225. fDz = m_fOrigin[2]-fz;
  226. fx=mx*fDz*(float)tan(m_fFovY/2*PiOver180)*m_fAspect;
  227. fy=my*fDz*(float)tan(m_fFovY/2*PiOver180);
  228. }
  229. else {
  230. fx=mx*fabs(m_fRight);
  231. fy=my*fabs(m_fTop);
  232. }
  233. // Compensate for camera X & Y position  
  234. fx += m_fOrigin[0];
  235. fy += m_fOrigin[1];
  236. // Compensate for camera rotation by transformation 
  237. // to the ModelView matrix
  238. VECTORF Source;
  239. Vec3f(fx, fy, fz, Source);
  240. Transformf(Source, coord, m_dModelViewMatrix);
  241. }
  242. int C3dCamera::EditAttributes(CWnd* pParentWnd, C3dWorld* pWorld)
  243. {
  244. char szName[80];
  245. sprintf(szName, "Edit Attributes of 3dWorld camera '%s'", m_szName);
  246. C3dCameraPropSheet* pCameraPropSheet = new C3dCameraPropSheet(szName, pParentWnd, this, pWorld);
  247. // Create and display the modal dialog box
  248. return( pCameraPropSheet->DoModal() );
  249. }
  250. int C3dCamera::EditAnimation(CWnd* pParentWnd, C3dWorld* pWorld)
  251. {
  252. char szName[80];
  253. sprintf(szName, "Edit Animation Attributes of Camera");
  254. CAnimPropSheet* pAnimPropSheet = new CAnimPropSheet(szName, pParentWnd, NULL, this, pWorld);
  255. // Create and display the modal dialog box
  256. return( pAnimPropSheet->DoModal() );
  257. }
  258. void C3dCamera::AddAnimationPages(C3dWorld* pWorld, LPVOID pSht)
  259. {
  260. CAnimPropSheet* pSheet = (CAnimPropSheet*)pSht;
  261. ASSERT(pSheet);
  262. // Load all animation pages for this object
  263. CAnimation* pAnimation = NULL;
  264. // walk the list
  265. POSITION Pos = m_AnimList.GetHeadPosition();
  266. while (Pos) {
  267. pAnimation = m_AnimList.GetAt(Pos);
  268. pAnimation->AddAnimationPage(pSht, NULL, this, NULL);
  269. pAnimation = m_AnimList.GetNext(Pos);
  270. }
  271. }
  272. void C3dCamera::Animate(double time)
  273. {
  274. // Animate the camera based on its animation procedures
  275. CAnimation* pAnimation = NULL;
  276. // walk the list
  277. POSITION Pos = m_AnimList.GetHeadPosition();
  278. while (Pos) {
  279. pAnimation = m_AnimList.GetAt(Pos);
  280. pAnimation->AnimateCamera(this, time);
  281. pAnimation = m_AnimList.GetNext(Pos);
  282. }
  283. }
  284. void C3dCamera::ResetAnimation()
  285. {
  286. // Reset the animation variables
  287. CAnimation* pAnimation = NULL;
  288. // walk the list
  289. POSITION Pos = m_AnimList.GetHeadPosition();
  290. while (Pos) {
  291. pAnimation = m_AnimList.GetAt(Pos);
  292. pAnimation->RestoreCameraAttributes(this);
  293. pAnimation = m_AnimList.GetNext(Pos);
  294. }
  295. }
  296. int C3dCamera::LoadBitMapImage(CImageList* pList)
  297. {
  298. CBitmap bitmap;
  299. // If the image index has been stored in the camera,
  300. // return the index.
  301. if(m_iBMImage > -1)
  302. return m_iBMImage;
  303. // If the image index for this camera type has been
  304. // created, store the index for this camera and
  305. // return the index.
  306. if( iCameraBMImage > -1) {
  307. m_iBMImage = iCameraBMImage;
  308. return m_iBMImage;
  309. }
  310. // The image index for this camera type has not been
  311. // loaded and the camera image index has not been
  312. // stored.
  313. //
  314. // Load the bitmap for the non-selected camera
  315. bitmap.LoadBitmap(IDB_CAMERA);
  316. m_iBMImage = pList->Add(&bitmap, (COLORREF)0xFFFFFF);
  317. bitmap.DeleteObject();
  318. // Load the bitmap for the selected light
  319. bitmap.LoadBitmap(IDB_CAMERA_SELECTED);
  320. pList->Add(&bitmap, (COLORREF)0xFFFFFF);
  321. bitmap.DeleteObject();
  322. iCameraBMImage = m_iBMImage;
  323. return m_iBMImage;
  324. }
  325. void C3dCamera::GetTransformMatrix(Matx4x4 XformMatrix)
  326. {
  327. // Calculate the objects' transformation matrix
  328. PrepareMatrix(m_fOrigin[X],    m_fOrigin[Y],    m_fOrigin[Z],
  329.   1.0f, 1.0f, 1.0f, // Scale 
  330.   m_fRotation[X],  m_fRotation[Y],  m_fRotation[Z],
  331.   0.0f, 0.0f, 0.0f, // Translation
  332.   XformMatrix);
  333. }
  334. void C3dCamera::GetInvTransformMatrix(Matx4x4 XformMatrix)
  335. {
  336. // Calculate the objects' transformation matrix
  337. PrepareInvMatrix(m_fOrigin[X],    m_fOrigin[Y],    m_fOrigin[Z],
  338.  1.0f, 1.0f, 1.0f, // Scale 
  339.  m_fRotation[X],  m_fRotation[Y],  m_fRotation[Z],
  340.  0.0f, 0.0f, 0.0f, // Translation
  341.  XformMatrix);
  342. }
  343. void C3dCamera::GetRotationMatrix(Matx4x4 XformMatrix)
  344. {
  345. // Calculate the objects' rotation matrix
  346. PrepareMatrix(0.0f, 0.0f, 0.0f, // Origin
  347.   1.0f, 1.0f, 1.0f, // Scale 
  348.   m_fRotation[X],  m_fRotation[Y],  m_fRotation[Z],
  349.   0.0f, 0.0f, 0.0f, // Translation
  350.   XformMatrix);
  351. }
  352. void C3dCamera::GetInvRotationMatrix(Matx4x4 XformMatrix)
  353. {
  354. // Calculate the objects' transformation matrix
  355. PrepareInvMatrix(0.0f, 0.0f, 0.0f, // Origin
  356.  1.0f, 1.0f, 1.0f, // Scale 
  357.  m_fRotation[X], m_fRotation[Y], m_fRotation[Z],
  358.  0.0f, 0.0f, 0.0f, // Translation
  359.  XformMatrix);
  360. }