MyglView.cpp
上传用户:cding2008
上传日期:2007-01-03
资源大小:1812k
文件大小:57k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // MyglView.cpp : implementation of the CMyglView class
  3. //
  4. // ModelMagic 3D and 'glOOP' (OpenGL Object Oriented Programming library)
  5. // Copyright (c) Craig Fahrnbach 1997, 1999
  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. /////////////////////////////////////////////////////////////////////////////
  17. #include "stdafx.h"
  18. #include "ModelMagic3D.h"
  19. #include <math.h>
  20. #include <wingdi.h>
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CMyglView local variables
  28. //
  29. static Matx4x4 g_SelctedObjMatrix; // User selected object transform matrix
  30. // (used for object point transfomation)
  31. static BOOL g_bStretchBlt  = FALSE; // Printer device capability flags
  32. static BOOL g_bStretchDIBits = FALSE;
  33. static CTextureDibImage g_DibImage; // DIB image for screen print
  34. static BITMAPINFO* g_pBitmapInfo = NULL; // CMyglView global DIB pointers
  35. static GLubyte* g_pBitmapBits = NULL; // Bitmap pits
  36. static float g_fMarginTop = 0.75f; // CMyglView global margin settings
  37. static float g_fMarginBottom = 0.75f;
  38. static float g_fMarginLeft = 0.75f;
  39. static float g_fMarginRight = 0.75f;
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CMyglView
  42. IMPLEMENT_DYNCREATE(CMyglView, CView)
  43. BEGIN_MESSAGE_MAP(CMyglView, CView)
  44. //{{AFX_MSG_MAP(CMyglView)
  45. ON_WM_ERASEBKGND()
  46. ON_WM_SIZE()
  47. ON_WM_CREATE()
  48. ON_WM_PALETTECHANGED()
  49. ON_WM_QUERYNEWPALETTE()
  50. ON_WM_DESTROY()
  51. ON_WM_MOUSEMOVE()
  52. ON_COMMAND(ID_VIEW_PERSPECTIVE, OnViewPerspective)
  53. ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomIn)
  54. ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomOut)
  55. ON_UPDATE_COMMAND_UI(ID_VIEW_PERSPECTIVE, OnUpdateViewPerspective)
  56. ON_COMMAND(ID_ANIMATE_SCEEN, OnAnimateSceen)
  57. ON_UPDATE_COMMAND_UI(ID_ANIMATE_SCEEN, OnUpdateAnimateSceen)
  58. ON_COMMAND(ID_VIEW_WIREFRAME, OnViewWireFrame)
  59. ON_UPDATE_COMMAND_UI(ID_VIEW_WIREFRAME, OnUpdateViewWireFrame)
  60. ON_COMMAND(ID_VIEW_FLATSHADE, OnViewFlatShade)
  61. ON_UPDATE_COMMAND_UI(ID_VIEW_FLATSHADE, OnUpdateViewFlatShade)
  62. ON_COMMAND(ID_VIEW_DISPLAYAXIS, OnViewDisplayAxis)
  63. ON_UPDATE_COMMAND_UI(ID_VIEW_DISPLAYAXIS, OnUpdateViewDisplayAxis)
  64. ON_COMMAND(ID_VIEW_DISPLAYGRID, OnViewDisplayGrid)
  65. ON_UPDATE_COMMAND_UI(ID_VIEW_DISPLAYGRID, OnUpdateViewDisplayGrid)
  66. ON_COMMAND(ID_VIEW_ISO, OnViewIso)
  67. ON_UPDATE_COMMAND_UI(ID_VIEW_ISO, OnUpdateViewIso)
  68. ON_COMMAND(ID_VIEW_FRONT, OnViewFront)
  69. ON_UPDATE_COMMAND_UI(ID_VIEW_FRONT, OnUpdateViewFront)
  70. ON_COMMAND(ID_VIEW_SIDE, OnViewSide)
  71. ON_UPDATE_COMMAND_UI(ID_VIEW_SIDE, OnUpdateViewSide)
  72. ON_COMMAND(ID_VIEW_TOP, OnViewTop)
  73. ON_UPDATE_COMMAND_UI(ID_VIEW_TOP, OnUpdateViewTop)
  74. ON_COMMAND(ID_VIEW_SMOOTHSHADE, OnViewSmoothShade)
  75. ON_UPDATE_COMMAND_UI(ID_VIEW_SMOOTHSHADE, OnUpdateViewSmoothShade)
  76. ON_WM_KEYDOWN()
  77. ON_COMMAND(ID_CAMERA_EDIT, OnCameraEdit)
  78. ON_WM_LBUTTONDOWN()
  79. ON_COMMAND(ID_VIEW_CULLFACES, OnViewCullfaces)
  80. ON_UPDATE_COMMAND_UI(ID_VIEW_CULLFACES, OnUpdateViewCullfaces)
  81. ON_WM_LBUTTONDBLCLK()
  82. ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
  83. ON_COMMAND(ID_FILE_PAGE_SETUP, OnFilePageSetup)
  84. ON_COMMAND(ID_FILE_SAVE_IMAGE, OnFileSaveImage)
  85. ON_WM_RBUTTONDOWN()
  86. ON_WM_LBUTTONUP()
  87. ON_WM_SETCURSOR()
  88. ON_COMMAND(ID_VIEW_OUTLINE, OnViewOutline)
  89. ON_UPDATE_COMMAND_UI(ID_VIEW_OUTLINE, OnUpdateViewOutline)
  90. //}}AFX_MSG_MAP
  91. // Standard printing commands
  92. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  93. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  94. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  95. END_MESSAGE_MAP()
  96. /////////////////////////////////////////////////////////////////////////////
  97. // CMyglView construction/destruction
  98. CMyglView::CMyglView()
  99. {
  100. // Initialize our member variables
  101. m_pDC = NULL;
  102. m_hRC = NULL;
  103. m_nMouseZ = 0;
  104. m_CPointLeftButtonDown.x = 0;
  105. m_CPointLeftButtonDown.y = 0;
  106. m_fMouseZCoord = 0.0f;
  107. VecClear3f(m_fSelectedCoord);
  108. VecClear3f(m_fSelectedCoord2);
  109. VecClear3f(m_fLeftButtonDownCoord);
  110. }
  111. CMyglView::~CMyglView()
  112. {
  113. }
  114. /////////////////////////////////////////////////////////////////////////////
  115. // CMyglView Camera view functions
  116. void CMyglView::ViewIso() 
  117. {
  118. // Set the camera view type
  119. m_Camera.m_iViewType = VIEW_ISO;
  120. // Rotate about the X & Z-Axis 
  121. m_Camera.SetRotation(-75.0f, 0.0f, -15.0f);
  122. }
  123. void CMyglView::ViewFront() 
  124. {
  125. // Set the camera view type
  126. m_Camera.m_iViewType = VIEW_FRONT;
  127. // Rotate about the X-Axis
  128. m_Camera.SetRotation(-90.0f, 0.0f, 0.0f);
  129. }
  130. void CMyglView::ViewSide() 
  131. {
  132. // Set the camera view type
  133. m_Camera.m_iViewType = VIEW_SIDE;
  134. // Rotate about the X & Z-Axis 
  135. m_Camera.SetRotation(-90.0f, 0.0f, -90.0f);
  136. }
  137. void CMyglView::ViewTop() 
  138. {
  139. // Set the camera view type
  140. m_Camera.m_iViewType = VIEW_TOP;
  141. // No Rotation 
  142. m_Camera.SetRotation(0.0f, 0.0f, 0.0f);
  143. // No X or Y-Axis offsets 
  144. m_Camera.m_fOrigin[X] = 0.0f;
  145. m_Camera.m_fOrigin[Y] = 0.0f;
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. // CMyglView drawing
  149. void CMyglView::OnDraw(CDC* pDC)
  150. {
  151. // Get a pointer to our view's document
  152. CMyglDoc* pDoc = GetDocument();
  153. ASSERT_VALID(pDoc);
  154. // Get a pointer to our document's 3dWorld
  155. C3dWorld* pWorld = pDoc->m_pWorld;
  156. ASSERT_VALID(pWorld);
  157. // Make this view the current OpenGL rendering context...
  158. if(!the3dEngine.EnableRC(pDC->GetSafeHdc(), m_hRC, TRUE))
  159. return;
  160. // Display the world
  161. pWorld->DisplayWorld(pDC->GetSafeHdc(), &m_Camera, pDoc->m_dTime);
  162. // Releases the device context that is used by the rendering context
  163. // to allow other rendering contexts to co-exist.
  164. the3dEngine.EnableRC(NULL, NULL, FALSE);
  165. }
  166. /////////////////////////////////////////////////////////////////////////////
  167. // CMyglView printing
  168. BOOL CMyglView::OnPreparePrinting(CPrintInfo* pInfo) 
  169. {
  170. // default preparation
  171. return DoPreparePrinting(pInfo);
  172. }
  173. void CMyglView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
  174. {
  175. // TODO: Add your specialized code here and/or call the base class
  176. CView::OnPrepareDC(pDC, pInfo);
  177. }
  178. void CMyglView::OnFilePrintPreview() 
  179. {
  180. // Since the default initialization of CView::OnFilePrintPreview() modifies
  181. // the window viewport and sends a WM_SIZE command, we capture the screen
  182. // DIB information BEFORE it is modified..
  183. // Make this view the current OpenGL rendering context...
  184. if(!the3dEngine.EnableRC(m_pDC->GetSafeHdc(), m_hRC, TRUE))
  185. return;
  186. // Read the window bits
  187. g_pBitmapBits = (GLubyte*)g_DibImage.ReadDIBitmap(&g_pBitmapInfo);
  188. // Releases the device context that is used by the rendering context
  189. // to allow other rendering contexts to co-exist.
  190. the3dEngine.EnableRC(NULL, NULL, FALSE);
  191. // Now that we have the screen information, do the default initialization
  192. CView::OnFilePrintPreview();
  193. }
  194. void CMyglView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
  195. {
  196.     // Gather some general information about the printer the
  197. // user selected..
  198. // Lock the handle to the structure to get a pointer
  199. LPDEVMODE pMode = (LPDEVMODE)::GlobalLock(pInfo->m_pPD->m_pd.hDevMode);
  200. // Get the printer name
  201. CString szPtrName;
  202. szPtrName.Format("%s", pMode->dmDeviceName);
  203. // Unlock the handles
  204. ::GlobalUnlock(pInfo->m_pPD->m_pd.hDevMode);
  205. int nBitsPerPixel = pDC->GetDeviceCaps(BITSPIXEL);
  206. int nColors = pDC->GetDeviceCaps(NUMCOLORS);
  207. int nBitPlanes = pDC->GetDeviceCaps(PLANES);
  208. int nColorRes = pDC->GetDeviceCaps(COLORRES);
  209. int nRasterCaps = pDC->GetDeviceCaps(RASTERCAPS);
  210. // Does the device support raster operations?
  211. if(nRasterCaps & RC_STRETCHBLT)
  212. g_bStretchBlt = TRUE;
  213. if(nRasterCaps & RC_STRETCHDIB)
  214. g_bStretchDIBits = TRUE;
  215. // Display in the debug window the information gathered
  216. TRACE("You selected printer '%s'n", szPtrName);
  217. TRACE("BitsPerPixel = %dn", nBitsPerPixel);
  218. TRACE("NumColors    = %dn", nColors);
  219. TRACE("NumBitPlanes = %dn", nBitPlanes);
  220. TRACE("ColorResolution        = %dn", nColorRes);
  221. TRACE("Supports StretchBlt    = %dn", g_bStretchBlt);
  222. TRACE("Supports StretchDIBits = %dn", g_bStretchDIBits);
  223. if(!g_bStretchBlt && !g_bStretchDIBits)
  224. {
  225. char szError[100];
  226. sprintf(szError, "Printer '%s' does not support required functions!", szPtrName);
  227. AfxMessageBox( szError, MB_OK);
  228. }
  229. }
  230. void CMyglView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
  231. {
  232. HBRUSH brush; // Background brush for page
  233. POINT ImageSize; // Size of printed image
  234. POINT ImageOffset; // Offset from edges for image
  235. CRect rectPageMax; // Maximum usable Page rectangle
  236. CRect rectMargins; // Page margins, in device units
  237. CRect rectPageAdj; // Adjusted page area, in device units
  238. if(!pInfo->m_bPreview)
  239. {
  240. // Since we are not doing a print preview, go ahead and capture the screen
  241. // DIB information.
  242. // Make this view the current OpenGL rendering context...
  243. if(!the3dEngine.EnableRC(m_pDC->GetSafeHdc(), m_hRC, TRUE))
  244. return;
  245. // Read the window bits
  246. g_pBitmapBits = (GLubyte*)g_DibImage.ReadDIBitmap(&g_pBitmapInfo);
  247. // Releases the device context that is used by the rendering context
  248. // to allow other rendering contexts to co-exist.
  249. the3dEngine.EnableRC(NULL, NULL, FALSE);
  250. }
  251. // Set our device context mapping mode.
  252. // Each logical unit is converted to 1 device pixel. Positive x is to
  253. // the right; positive y is down.
  254. pDC->SetMapMode (MM_TEXT);
  255. // Get our page margin size, in device units
  256. CalculateMargins(pDC, &rectMargins);
  257. // Get the maximum usable size of the page (in printer device points)
  258. rectPageMax.top    = 0;
  259. rectPageMax.left   = 0;
  260. rectPageMax.right  = pDC->GetDeviceCaps(HORZRES);
  261. rectPageMax.bottom = pDC->GetDeviceCaps(VERTRES);
  262. // Create a white brush and clear the page
  263. brush = CreateSolidBrush(0x00ffffff);
  264. FillRect(pDC->GetSafeHdc(), &rectPageMax, brush);
  265. // Calculate the adjusted page area, in device units
  266. rectPageAdj.top    = 0;
  267. rectPageAdj.left   = 0;
  268. rectPageAdj.right  = rectPageMax.right  - (rectMargins.left + rectMargins.right);
  269. rectPageAdj.bottom = rectPageMax.bottom - (rectMargins.top  + rectMargins.bottom);
  270. // Calculate the new image size and the image offset with image
  271. // centered on page
  272. ImageSize.x = rectPageAdj.right;
  273. ImageSize.y = (ImageSize.x * g_pBitmapInfo->bmiHeader.biHeight / g_pBitmapInfo->bmiHeader.biWidth);
  274. if (ImageSize.y > rectPageAdj.bottom)
  275. {
  276. ImageSize.y = rectPageAdj.bottom;
  277. ImageSize.x = ImageSize.y * g_pBitmapInfo->bmiHeader.biWidth / g_pBitmapInfo->bmiHeader.biHeight;
  278. }
  279. // Calculate the image offset
  280. ImageOffset.x = rectMargins.left + ((rectPageAdj.right  - ImageSize.x)/2);
  281. ImageOffset.y = rectMargins.top   + ((rectPageAdj.bottom - ImageSize.y)/2);
  282. // Set the bitmap stretching mode in the device context. 
  283. // Note:  The COLORONCOLOR mode is typically used to preserve
  284. //        color in color bitmaps. 
  285. SetStretchBltMode(pDC->GetSafeHdc(), COLORONCOLOR);
  286. // Does our device context support StretchDIBits?
  287. if(g_bStretchDIBits)
  288. {
  289. BOOL bRet = StretchDIBits(pDC->GetSafeHdc(),
  290.   ImageOffset.x, ImageOffset.y,
  291.   ImageSize.x, ImageSize.y,
  292.   0, 0,
  293.   g_pBitmapInfo->bmiHeader.biWidth,
  294.   g_pBitmapInfo->bmiHeader.biHeight,
  295.   g_pBitmapBits,
  296.   g_pBitmapInfo,
  297.   DIB_RGB_COLORS,
  298.   SRCCOPY);
  299. }
  300. else if(!g_bStretchBlt)
  301. {
  302. HDC hdc;
  303. HBITMAP bitmap;
  304. hdc    = CreateCompatibleDC(pDC->GetSafeHdc());
  305. bitmap = CreateDIBitmap(hdc,
  306. &(g_pBitmapInfo->bmiHeader),
  307. CBM_INIT,
  308. g_pBitmapBits,
  309. g_pBitmapInfo,
  310. DIB_RGB_COLORS);
  311. HGDIOBJ temp = SelectObject(hdc, bitmap);
  312. BOOL bRet = StretchBlt(pDC->GetSafeHdc(),
  313.    ImageOffset.x, ImageOffset.y,
  314.    ImageSize.x, ImageSize.y,
  315.    hdc,
  316.    0, 0,
  317.    g_pBitmapInfo->bmiHeader.biWidth,
  318.    g_pBitmapInfo->bmiHeader.biHeight,
  319.    SRCCOPY);
  320. // Free our bitmap and bitmap device context
  321. DeleteObject(bitmap);
  322. DeleteDC(hdc);
  323. }
  324. // That's it.  End the print job and free anything we allocated...
  325. // Delete our brush
  326. DeleteObject(brush);
  327. }
  328. void CMyglView::CalculateMargins(CDC* pDC, CRect* pRectMargins)
  329. {
  330. POINT pt;
  331. CRect rectUnPrintable;
  332. // Start by getting the dimensions of the unprintable part of the
  333. // page (in device units). GETPRINTINGOFFSET will tell us the left
  334. // and upper unprintable area.
  335. pDC->Escape(GETPRINTINGOFFSET, 0, NULL, &pt);
  336. rectUnPrintable.left = pt.x;
  337. rectUnPrintable.top  = pt.y;
  338. // To get the right and lower unprintable area, we need to take
  339. // the entire width and height of the paper (GETPHYSPAGESIZE) and
  340. // subtract everything else.
  341. pDC->Escape(GETPHYSPAGESIZE, 0, NULL, &pt);
  342. rectUnPrintable.right  = pt.x // total paper width
  343.    - pDC->GetDeviceCaps(HORZRES)// printable width
  344.    - rectUnPrintable.left; // left unprtable margin
  345.  
  346. rectUnPrintable.bottom = pt.y // total paper height
  347.    - pDC->GetDeviceCaps(VERTRES)// printable ht
  348.    - rectUnPrintable.top; // rt unprtable margin
  349.  
  350. // Convert the margin values from the Page Setup dialog
  351. // to device units and subtract the unprintable part we just
  352. // calculated.
  353. pt.x = pDC->GetDeviceCaps(LOGPIXELSX); // dpi in X directPageMaxion
  354. pt.y = pDC->GetDeviceCaps(LOGPIXELSY); // dpi in Y directPageMaxion
  355. pRectMargins->top    = (long)(g_fMarginTop * pt.y)    - rectUnPrintable.top;
  356. pRectMargins->bottom = (long)(g_fMarginBottom * pt.y) - rectUnPrintable.bottom;
  357. pRectMargins->right  = (long)(g_fMarginRight * pt.x)  - rectUnPrintable.right;
  358. pRectMargins->left   = (long)(g_fMarginLeft * pt.x)   - rectUnPrintable.left;
  359. // Ensure that our margins are in the printable range..
  360. if(pRectMargins->left < 0)
  361. pRectMargins->left = 0;
  362. if(pRectMargins->top < 0)
  363. pRectMargins->top = 0;
  364. if(pRectMargins->right < 0)
  365. pRectMargins->right = 0;
  366. if(pRectMargins->bottom < 0)
  367. pRectMargins->bottom = 0;
  368. // pRectMargins now contains the values used to shrink the
  369. // printable area of the page.
  370. // Convert to logical units and we're done!
  371. pDC->DPtoLP(pRectMargins);
  372. }
  373. void CMyglView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  374. {
  375. // Free the DIB bits
  376. if(g_pBitmapBits)
  377. free(g_pBitmapBits);
  378. // Free the DIB header info
  379. if(g_pBitmapInfo)
  380. free(g_pBitmapInfo);
  381. }
  382. /////////////////////////////////////////////////////////////////////////////
  383. // CMyglView page setup
  384. void CMyglView::OnFilePageSetup() 
  385. {
  386. float scale; // Our Page Setup margin scaling factor
  387. CPageSetupDialog psdlg; // Allocate the structure for our Page Setup dialog
  388. PRINTDLG printDlg; // Allocate the structure to store the returned printer info
  389. // Get the printer information
  390. AfxGetApp()->GetPrinterDeviceDefaults(&printDlg);
  391. // Lock the handles to the structures to get pointers
  392. LPDEVNAMES pDevNames = (LPDEVNAMES)::GlobalLock(printDlg.hDevNames);
  393. LPDEVMODE  pDevMode  = (LPDEVMODE)::GlobalLock(printDlg.hDevMode);
  394. // Allocate space for the Page Setup printer info structures
  395. psdlg.m_psd.hDevNames = ::GlobalAlloc(GPTR, ::GlobalSize(printDlg.hDevNames));
  396. psdlg.m_psd.hDevMode = ::GlobalAlloc(GPTR, ::GlobalSize(printDlg.hDevMode));
  397. // Lock the new handles
  398. LPDEVNAMES m_pDevNames = (LPDEVNAMES)::GlobalLock(psdlg.m_psd.hDevNames);
  399. LPDEVMODE  m_pDevMode  = (LPDEVMODE)::GlobalLock(psdlg.m_psd.hDevMode);
  400. // Copy the printer information into page setup dialog
  401. memcpy(m_pDevNames, pDevNames,
  402. (size_t)::GlobalSize(printDlg.hDevNames));
  403. memcpy(m_pDevMode, pDevMode,
  404. (size_t)::GlobalSize(printDlg.hDevMode));
  405. // Unlock the handles
  406. ::GlobalUnlock(printDlg.hDevNames);
  407. ::GlobalUnlock(printDlg.hDevMode);
  408. ::GlobalUnlock(psdlg.m_psd.hDevNames);
  409. ::GlobalUnlock(psdlg.m_psd.hDevMode);
  410. // Done initializing the CPageSetupDialog.  This dialog will now
  411. // display the system default printer info
  412. // Determine the scaling factor of the Page Setup margins
  413. if(psdlg.m_psd.Flags & PSD_INTHOUSANDTHSOFINCHES)
  414. scale = 1000.0f;
  415. else if(psdlg.m_psd.Flags & PSD_INHUNDREDTHSOFMILLIMETERS)
  416. scale = 2540.0f; // 100*25.4mm/inch
  417. else
  418. scale = 1000.0f; // Default setting
  419. // Initialize our Page Setup dialog margin settings with
  420. // our CMyglView global margin settings
  421. psdlg.m_psd.rtMargin.top = (int)(g_fMarginTop*scale);
  422. psdlg.m_psd.rtMargin.bottom = (int)(g_fMarginBottom*scale);
  423. psdlg.m_psd.rtMargin.left = (int)(g_fMarginLeft*scale);
  424. psdlg.m_psd.rtMargin.right = (int)(g_fMarginRight*scale);
  425. // Display the Page Setup dialog..
  426. if(psdlg.DoModal() == IDOK)
  427. {
  428. // Select this printer as our default configuration
  429. AfxGetApp()->SelectPrinter(psdlg.m_psd.hDevNames, psdlg.m_psd.hDevMode);
  430. // Save the Page Setup dialog margin settings
  431. g_fMarginTop = (float)(psdlg.m_psd.rtMargin.top)/scale;
  432. g_fMarginBottom = (float)(psdlg.m_psd.rtMargin.bottom)/scale;
  433. g_fMarginLeft = (float)(psdlg.m_psd.rtMargin.left)/scale;
  434. g_fMarginRight = (float)(psdlg.m_psd.rtMargin.right)/scale;
  435. }
  436. }
  437. /////////////////////////////////////////////////////////////////////////////
  438. // CMyglView diagnostics
  439. #ifdef _DEBUG
  440. void CMyglView::AssertValid() const
  441. {
  442. CView::AssertValid();
  443. }
  444. void CMyglView::Dump(CDumpContext& dc) const
  445. {
  446. CView::Dump(dc);
  447. }
  448. CMyglDoc* CMyglView::GetDocument() // non-debug version is inline
  449. {
  450. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyglDoc)));
  451. return (CMyglDoc*)m_pDocument;
  452. }
  453. #endif //_DEBUG
  454. /////////////////////////////////////////////////////////////////////////////
  455. // CMyglView message handlers
  456. BOOL CMyglView::PreCreateWindow(CREATESTRUCT& cs)
  457. {
  458. // OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGS and must not
  459.     // include CS_PARENTDC for the class style. Refer to SetPixelFormat
  460.     // documentation in the "Comments" section for further information.
  461. cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
  462. // Register a class with its own device context and the 'arrow' cursor
  463. cs.lpszClass = AfxRegisterWndClass(CS_OWNDC | CS_DBLCLKS |
  464.    CS_HREDRAW | CS_VREDRAW,
  465.    ::LoadCursor(NULL, IDC_ARROW));
  466. return CView::PreCreateWindow(cs);
  467. }
  468. int CMyglView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  469. {
  470. if (CView::OnCreate(lpCreateStruct) == -1)
  471. return -1;
  472. // Get the Device context to our window
  473. m_pDC = new CClientDC (this);
  474. if (m_pDC == NULL)
  475. return (-1);
  476. // Set our window pixel format for openGL rendering
  477. if(!the3dEngine.SetWindowPixelFormat(m_pDC->GetSafeHdc(),
  478.  PFD_DRAW_TO_WINDOW | // Draw to Window (not bitmap)
  479.  PFD_SUPPORT_OPENGL | // Support OpenGL calls in window
  480.  PFD_DOUBLEBUFFER)) // Double buffered mode
  481. return -1;
  482. // Create the rendering context
  483. m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
  484. if (!m_hRC)
  485. return -1;
  486. return 0;
  487. }
  488. BOOL CMyglView::OnEraseBkgnd(CDC* pDC) 
  489. {
  490. // Override to keep the background from being erased everytime
  491. // the window is repainted
  492. return TRUE;
  493. // return CView::OnEraseBkgnd(pDC);
  494. }
  495. void CMyglView::OnSize(UINT nType, int cx, int cy) 
  496. {
  497. CView::OnSize(nType, cx, cy);
  498. if(!m_pDocument)
  499. return;
  500. // Make this view the current OpenGL rendering context...
  501. if(!the3dEngine.EnableRC(m_pDC->GetSafeHdc(), m_hRC, TRUE))
  502. return;
  503. // Reset our camera view
  504. m_Camera.ResetView(cx, cy);
  505. // Releases the device context that is used by the rendering context
  506. // to allow other rendering contexts to co-exist.
  507. the3dEngine.EnableRC(NULL, NULL, FALSE);
  508. // Force a window repaint
  509. InvalidateRect(NULL, FALSE);
  510. }
  511. void CMyglView::OnPaletteChanged(CWnd* pFocusWnd) 
  512. {
  513. if((the3dEngine.GetPalette() != NULL) && (pFocusWnd != this))
  514. {
  515. // Select the palette into the device context
  516. SelectPalette(m_pDC->GetSafeHdc(), the3dEngine.GetPalette(), FALSE);
  517. // Map entries to system palette
  518. RealizePalette(m_pDC->GetSafeHdc());
  519. // Remap the current colors to the newly realized palette
  520. UpdateColors(m_pDC->GetSafeHdc());
  521. return;
  522. }
  523. CView::OnPaletteChanged(pFocusWnd);
  524. }
  525. BOOL CMyglView::OnQueryNewPalette() 
  526. {
  527. int iNumEntries; // Number of entries in the logical palette were
  528. // mapped to different entries in the system palette.
  529. // If the palette was created.
  530. if(the3dEngine.GetPalette())
  531. {
  532. // Selects the palette into the current device context
  533. SelectPalette(m_pDC->GetSafeHdc(), the3dEngine.GetPalette(), FALSE);
  534. // Map entries from the currently selected palette to
  535. // the system palette.  The return value is the number 
  536. // of palette entries modified.
  537. iNumEntries = RealizePalette(m_pDC->GetSafeHdc());
  538. // Repaint, forces remap of palette in current window
  539. InvalidateRect(NULL, FALSE);
  540. return iNumEntries;
  541. }
  542. return CView::OnQueryNewPalette();
  543. }
  544. void CMyglView::OnDestroy() 
  545. {
  546. CView::OnDestroy();
  547. if(m_pDC)
  548. // Clean up rendering context stuff
  549. delete m_pDC;
  550. if(m_hRC)
  551. // Clean up rendering context stuff
  552. wglDeleteContext(m_hRC);
  553. }
  554. void CMyglView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
  555. {
  556. // Get a pointer to our Main Frame
  557. CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
  558. ASSERT_VALID(pFrame);
  559. // Let the MainFrame know that we have changed views..
  560. pFrame->SendMessage(WM_REFRESH_DLG_BAR, RDB_NEW_USER_VIEW, 0L);
  561. CView::OnActivateView(bActivate, pActivateView, pDeactiveView);
  562. }
  563. void CMyglView::OnLButtonDown(UINT nFlags, CPoint point) 
  564. {
  565. // Get a pointer to our Main Frame
  566. CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
  567. ASSERT_VALID(pFrame);
  568. // Get a pointer to our view's document
  569. CMyglDoc* pDoc = GetDocument();
  570. ASSERT_VALID(pDoc);
  571. // Get a pointer to our document's 3dWorld
  572. C3dWorld* pWorld = pDoc->m_pWorld;
  573. ASSERT_VALID(pWorld);
  574. // Get a pointer to our worlds' selected object
  575. C3dObject* pObj =  pWorld->m_pSelectedObj;
  576. // Get a pointer to our worlds' selected point
  577. C3dPoint* pPoint =  pWorld->m_pSelectedPnt;
  578. // Calculate a new Mouse 'Z' value.  Mouse 'Z' is mapped to 
  579. // the mouse y position if the Right Mouse button is down
  580. // Save the mouse left button down screen position
  581. m_CPointLeftButtonDown = point;
  582. // Scale the mouse 'z' screen position to simulate a 'Z' world
  583. // coordinate.
  584. m_fMouseZCoord = (float)m_nMouseZ * g_fMouseZMult;
  585. // Convert the mouse left button down position to world
  586. m_Camera.GetWorldCoord(point.x, point.y, m_fMouseZCoord, m_fLeftButtonDownCoord);
  587. // Are we creating points?
  588. if(pDoc->m_bCreatePoints)
  589. {
  590. // Create a new C3dPoint and append to list
  591. C3dPoint* pPoint = new C3dPoint;
  592. ASSERT(pPoint);
  593. if(pDoc->m_bSnapToGrid)
  594. pWorld->m_pGrid->PointToGrid(&m_fLeftButtonDownCoord[X],
  595.  &m_fLeftButtonDownCoord[Y],
  596.  &m_fLeftButtonDownCoord[Z]); 
  597. pPoint->SetOrigin(m_fLeftButtonDownCoord[X],
  598.   m_fLeftButtonDownCoord[Y],
  599.   m_fLeftButtonDownCoord[Z]);
  600. pWorld->m_PointList.Append(pPoint);
  601. // Save the pointer
  602. pWorld->m_pSelectedPnt = pPoint;
  603. // Update the Coordinate Dialog Toolbar
  604. pFrame->m_wndCoordDlgBar.UpdateDialogData();
  605. }
  606. // Selecting World Points?
  607. else if(pDoc->m_bSelectPoint)
  608. {
  609. GLfloat fMouseCoordinate[4];
  610. C3dPoint* pPoint;
  611. // Convert our point to 3D coordinates
  612. m_Camera.GetWorldCoord(point.x, point.y, m_fMouseZCoord, fMouseCoordinate);
  613. // Find the point from the point list.
  614. pPoint = pWorld->m_PointList.Find(m_fLeftButtonDownCoord[X],
  615.   m_fLeftButtonDownCoord[Y],
  616.   m_fLeftButtonDownCoord[Z],
  617.   0.1f);
  618. if(pPoint)
  619. // Save the point pointer
  620. pWorld->m_pSelectedPnt = pPoint;
  621. if(pWorld->m_pSelectedPnt)
  622. {
  623. // Set the selected coordinates
  624. m_fSelectedCoord[X] = pWorld->m_pSelectedPnt->m_fOrigin[X];
  625. m_fSelectedCoord[Y] = pWorld->m_pSelectedPnt->m_fOrigin[Y];
  626. m_fSelectedCoord[Z] = pWorld->m_pSelectedPnt->m_fOrigin[Z];
  627. }
  628. // Update the Coordinate Dialog Toolbar
  629. pFrame->m_wndCoordDlgBar.UpdateDialogData();
  630. }
  631. // Selecting Object Points?
  632. else if(pWorld->m_pSelectedObj && pDoc->m_bSelectObjPoints)
  633. {
  634. GLfloat fMouseCoordinate[4];
  635. C3dPoint* pPoint;
  636. // Convert our point to 3D coordinates
  637. m_Camera.GetWorldCoord(point.x, point.y, m_fMouseZCoord, fMouseCoordinate);
  638. // Find a point from the selected object
  639. pPoint = pWorld->m_pSelectedObj->FindPoint(&m_Camera,
  640. m_fLeftButtonDownCoord[X],
  641. m_fLeftButtonDownCoord[Y],
  642. m_fLeftButtonDownCoord[Z]);
  643. if(pPoint)
  644. {
  645. // Save the selected point and set the selected coordinates
  646. pWorld->m_pSelectedPnt = pPoint;
  647. pWorld->m_pSelectedObj->GetObjPointOrigin(pPoint,
  648.   &m_fSelectedCoord[X],
  649.   &m_fSelectedCoord[Y],
  650.   &m_fSelectedCoord[Z]);
  651. // Save the inverse rotation transformation matrix of the
  652. // object.  We will use this value in the OnMouseMove() function.
  653. // (We saved this matrix because an object, ie. light objects,
  654. // may modify their rotation values.  Its also saves more
  655. // processing time, as we need this matrix to calcualte the 
  656. // object coordinates.)
  657. pWorld->m_pSelectedObj->GetInvRotationMatrix(g_SelctedObjMatrix);
  658. }
  659. else if(pWorld->m_pSelectedPnt)
  660. {
  661. // Set the selected coordinates
  662. m_fSelectedCoord[X] = pWorld->m_pSelectedPnt->m_fOrigin[X];
  663. m_fSelectedCoord[Y] = pWorld->m_pSelectedPnt->m_fOrigin[Y];
  664. m_fSelectedCoord[Z] = pWorld->m_pSelectedPnt->m_fOrigin[Z];
  665. }
  666. // Update the Coordinate Dialog Toolbar
  667. pFrame->m_wndCoordDlgBar.UpdateDialogData();
  668. }
  669. // Selecting an Object?
  670. else if((pDoc->m_bSelectParentObj && pDoc->m_bSelect) ||
  671. (pDoc->m_bSelectChildObj  && pDoc->m_bSelect))
  672. {
  673. // Make this view the current OpenGL rendering context...
  674. if(!the3dEngine.EnableRC(m_pDC->GetSafeHdc(), m_hRC, TRUE))
  675. return;
  676. // Did we select and object?
  677. C3dObject* pObject = pWorld->ProcessSelection(&m_Camera, point.x, point.y, pDoc->m_bSelectParentObj);
  678. if(pObject)
  679. {
  680. // Find the object in the tree view.
  681. HTREEITEM hItem = pFrame->m_wndTreeDlgBar.FindObject(pObject);
  682. if(hItem)
  683.  pFrame->m_wndTreeDlgBar.SelectItem(hItem);
  684. // Save the pointer 
  685. pWorld->m_pSelectedObj = pObject;
  686. pWorld->m_pSelectedPnt = NULL;
  687. // Update the Coordinate Dialog Toolbar
  688. pFrame->m_wndCoordDlgBar.UpdateDialogData();
  689. }
  690. else
  691. {
  692. pFrame->m_wndTreeDlgBar.SelectItem(NULL);
  693. pWorld->m_pSelectedObj = NULL;
  694. }
  695. // Releases the device context that is used by the rendering context
  696. // to allow other rendering contexts to co-exist.
  697. the3dEngine.EnableRC(NULL, NULL, FALSE);
  698. }
  699. // Save the appropriate selected Object's origin or translation value,
  700. // or the selected Points origin.  This value will be used in the CMyglView::
  701. // OnMouseMove() function for later modification.
  702. if(pObj)
  703. {
  704. if(pDoc->m_bSelectParentObj || pDoc->m_bSelectChildObj)
  705. // Save the object's original origin
  706. pObj->GetOrigin(&m_fSelectedCoord[X],
  707. &m_fSelectedCoord[Y],
  708. &m_fSelectedCoord[Z]);
  709. if(pDoc->m_bSelectObjAxis)
  710. {
  711. // Save the object's original axis origin (Translation)
  712. pObj->GetTranslation(&m_fSelectedCoord[X],
  713.  &m_fSelectedCoord[Y],
  714.  &m_fSelectedCoord[Z]);
  715. // Save the object's original origin
  716. pObj->GetOrigin(&m_fSelectedCoord2[X],
  717. &m_fSelectedCoord2[Y],
  718. &m_fSelectedCoord2[Z]);
  719. }
  720. if(pDoc->m_bSelectObjTextureAxis)
  721. {
  722. if(pObj->m_pTexture)
  723. // Save the object's original texture axis origin
  724. pObj->m_pTexture->GetTextureOrigin3f(&m_fSelectedCoord[X],
  725.  &m_fSelectedCoord[Y],
  726.  &m_fSelectedCoord[Z]);
  727. }
  728. }
  729. // Save the camera origin coordinates.  This value will be used in the CMyglView::
  730. // OnMouseMove() function for later modification.
  731. if(pDoc->m_bSelectCamera)
  732. // Save the object's original origin
  733. m_Camera.GetOrigin(&m_fSelectedCoord[X],
  734.    &m_fSelectedCoord[Y],
  735.    &m_fSelectedCoord[Z]);
  736. // Are we painting?
  737. if(pDoc->m_bPaint)
  738. {
  739. if(pDoc->m_bSelectParentObj || pDoc->m_bSelectChildObj)
  740. {
  741. // Paint the object
  742. if(pWorld->m_pSelectedObj)
  743. {
  744. pWorld->m_pSelectedObj->SetColor4fv(&pFrame->m_wndColorDlgBar.m_Color);
  745. pWorld->m_pSelectedObj->m_bBuildLists = TRUE;
  746. pWorld->m_pSelectedObj->m_bSolidColor = TRUE;
  747. }
  748. }
  749. if(pDoc->m_bSelectObjPoints)
  750. {
  751. if(pWorld->m_pSelectedPnt)
  752. {
  753. // Paint the point
  754. pWorld->m_pSelectedPnt->m_Color.SetColor4fv(&pFrame->m_wndColorDlgBar.m_Color);
  755. // If the point belongs to an object, force a rebuild of its
  756. // display list.
  757. if(pWorld->m_pSelectedObj)
  758. {
  759. pWorld->m_pSelectedObj->m_bBuildLists = TRUE;
  760. pWorld->m_pSelectedObj->m_bSolidColor = FALSE;
  761. }
  762. }
  763. }
  764. }
  765. // Force a repaint of the window
  766. pDoc->UpdateAllViews(NULL);
  767. CView::OnLButtonDown(nFlags, point);
  768. }
  769. void CMyglView::OnLButtonUp(UINT nFlags, CPoint point) 
  770. {
  771. // Reset the last Left button down mouse screen position an its
  772. // 3d coordinate.
  773. m_CPointLeftButtonDown.x = 0;
  774. m_CPointLeftButtonDown.y = 0;
  775. VecClear3f(&m_fLeftButtonDownCoord[0]);
  776. CView::OnLButtonUp(nFlags, point);
  777. }
  778. void CMyglView::OnLButtonDblClk(UINT nFlags, CPoint point) 
  779. {
  780. // Get a pointer to our main window frame
  781. CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
  782. ASSERT_VALID(pFrame);
  783. // Get a pointer to our view's document
  784. CMyglDoc* pDoc = GetDocument();
  785. ASSERT_VALID(pDoc);
  786. // Get a pointer to our document's 3dWorld
  787. C3dWorld* pWorld = pDoc->m_pWorld;
  788. ASSERT_VALID(pWorld);
  789. // Make the rendering context current
  790. if(!the3dEngine.EnableRC(m_pDC->GetSafeHdc(), m_hRC, TRUE))
  791. return;
  792. // Did we select and object?
  793. C3dObject* pObject = pWorld->ProcessSelection(&m_Camera, point.x, point.y, pDoc->m_bSelectParentObj);
  794. // Releases the device context that is used by the rendering context
  795. // to allow other rendering contexts to co-exist.
  796. the3dEngine.EnableRC(NULL, NULL, FALSE);
  797. if(pObject)
  798. {
  799. // Save the object pointer
  800. pWorld->m_pSelectedObj = pObject;
  801. // Update the Coordinate Dialog Toolbar
  802. pFrame->m_wndCoordDlgBar.UpdateDialogData();
  803. // Update the TreeView Dialog Toolbar
  804. pFrame->m_wndTreeDlgBar.DisplaySelected(pObject);
  805. // Display the Object's attributes dialog box
  806. pWorld->m_pSelectedObj->EditAttributes(this, pWorld);
  807. // Force selection of parent objects
  808. pDoc->UserSelectedAnObject();
  809. // Force a repaint of the window
  810. pDoc->UpdateAllViews(NULL);
  811. }
  812. else
  813. pWorld->m_pSelectedObj = NULL;
  814. CView::OnLButtonDblClk(nFlags, point);
  815. }
  816. void CMyglView::OnRButtonDown(UINT nFlags, CPoint point) 
  817. {
  818. m_nInitMouseZ = point.y;
  819. CView::OnRButtonDown(nFlags, point);
  820. }
  821. void CMyglView::OnMouseMove(UINT nFlags, CPoint point) 
  822. {
  823. VECTORF fMouseCoordinate;
  824. CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
  825. ASSERT_VALID(pFrame);
  826. // Get a pointer to our view's document
  827. CMyglDoc* pDoc = GetDocument();
  828. ASSERT_VALID(pDoc);
  829. // Get a pointer to our document's 3dWorld
  830. C3dWorld* pWorld = pDoc->m_pWorld;
  831. ASSERT_VALID(pWorld);
  832. // Get a pointer to our worlds' selected object and
  833. // selected light
  834. C3dObject* pObj =  pWorld->m_pSelectedObj;
  835. // Calculate a new Mouse Z value.  Mouse 'Z' is mapped to 
  836. // the mouse y position if the Right Mouse button is down
  837. if(nFlags & MK_RBUTTON) {
  838. int deltaY = m_nInitMouseZ - point.y;
  839. m_nInitMouseZ = point.y;
  840. m_nMouseZ += deltaY;
  841. }
  842. // Convert the mouse point into world coordinates
  843. m_Camera.GetWorldCoord(point.x,
  844.    point.y,
  845.    m_fMouseZCoord,
  846.    fMouseCoordinate);
  847. // Now that we have the mouse coordinate, subtract the Left button down
  848. // coordinate.
  849. if(nFlags & MK_LBUTTON)
  850. VecSubf(fMouseCoordinate, m_fLeftButtonDownCoord, fMouseCoordinate);
  851. // Lock the mouse coordinates?
  852. fMouseCoordinate[X] *= (float)pDoc->m_bUnLockXAxis;
  853. fMouseCoordinate[Y] *= (float)pDoc->m_bUnLockYAxis;
  854. fMouseCoordinate[Z] *= (float)pDoc->m_bUnLockZAxis;
  855. if(pDoc->m_bSnapToGrid)
  856. {
  857. // Round the 3d point to the nearest grid point
  858. pWorld->m_pGrid->PointToGrid(&fMouseCoordinate[X],
  859.  &fMouseCoordinate[Y],
  860.  &fMouseCoordinate[Z]); 
  861. }
  862. // Object selected & left button down?
  863. if(pObj && (nFlags & MK_LBUTTON) )
  864. {
  865. // Modify Object?
  866. if(pDoc->m_bSelectParentObj || pDoc->m_bSelectChildObj)
  867. {
  868. // Move the selected object?
  869. if(pDoc->m_bMove)
  870. {
  871. GLfloat x, y, z;
  872. // Does this object have a parent?
  873. if(pObj->m_pParent)
  874. {
  875. Matx4x4 ObjRotationMatrix;
  876. // Get the inverse transformation matrix of the parent 
  877. // object and multiply the mouse coordinate so that we
  878. // move the object in World coordinate space.
  879. pObj->m_pParent->GetInvRotationMatrix(ObjRotationMatrix);
  880. VecTransformf(fMouseCoordinate,
  881.   fMouseCoordinate,
  882.   ObjRotationMatrix);
  883. }
  884. // Note:  We saved the Selected coordinate in the 
  885. //   WM_LBUTTONDOWN message handler.
  886. x = fMouseCoordinate[X]+m_fSelectedCoord[X];
  887. y = fMouseCoordinate[Y]+m_fSelectedCoord[Y];
  888. z = fMouseCoordinate[Z]+m_fSelectedCoord[Z];
  889. pObj->SetOrigin(x, y, z);
  890. }
  891. // Rotate the selected object?
  892. else if(pDoc->m_bRotate)
  893. {
  894. CSize rotate = m_CPointLeftButtonDown - point;
  895. m_CPointLeftButtonDown = point;
  896. if(m_Camera.m_iViewType == VIEW_ISO) {
  897. pObj->m_fRotation[Z] -= rotate.cx*g_fMouseRotateMult*pDoc->m_bUnLockZAxis;
  898. pObj->m_fRotation[X] -= rotate.cy*g_fMouseRotateMult*pDoc->m_bUnLockXAxis;
  899. }
  900. else if(m_Camera.m_iViewType == VIEW_SIDE) {
  901. pObj->m_fRotation[Z] -= rotate.cx*g_fMouseRotateMult*pDoc->m_bUnLockZAxis;
  902. pObj->m_fRotation[Y] -= rotate.cy*g_fMouseRotateMult*pDoc->m_bUnLockYAxis;
  903. }
  904. else if(m_Camera.m_iViewType == VIEW_TOP) {
  905. pObj->m_fRotation[Y] -= rotate.cx*g_fMouseRotateMult*pDoc->m_bUnLockYAxis;
  906. pObj->m_fRotation[X] -= rotate.cy*g_fMouseRotateMult*pDoc->m_bUnLockXAxis;
  907. }
  908. else if(m_Camera.m_iViewType == VIEW_FRONT) {
  909. pObj->m_fRotation[Z] -= rotate.cx*g_fMouseRotateMult*pDoc->m_bUnLockZAxis;
  910. pObj->m_fRotation[X] -= rotate.cy*g_fMouseRotateMult*pDoc->m_bUnLockXAxis;
  911. }
  912.     }
  913. // Scale the selected object?
  914. else if(pDoc->m_bScale)
  915. {
  916. CSize scale = m_CPointLeftButtonDown - point;
  917. m_CPointLeftButtonDown = point;
  918. if(m_Camera.m_iViewType == VIEW_ISO) {
  919. pObj->m_fScale[X] -= (float)scale.cx*g_fMouseScaleMult*pDoc->m_bUnLockXAxis;
  920. pObj->m_fScale[Y] -= (float)scale.cx*g_fMouseScaleMult*pDoc->m_bUnLockYAxis;
  921. pObj->m_fScale[Z] -= (float)scale.cy*g_fMouseScaleMult*pDoc->m_bUnLockZAxis;
  922. }
  923. else if(m_Camera.m_iViewType == VIEW_SIDE) {
  924. pObj->m_fScale[Y] -= (float)scale.cx*g_fMouseScaleMult*pDoc->m_bUnLockYAxis;
  925. pObj->m_fScale[Z] -= (float)scale.cy*g_fMouseScaleMult*pDoc->m_bUnLockZAxis;
  926. }
  927. else if(m_Camera.m_iViewType == VIEW_TOP) {
  928. pObj->m_fScale[X] -= (float)scale.cx*g_fMouseScaleMult*pDoc->m_bUnLockXAxis;
  929. pObj->m_fScale[Y] -= (float)scale.cy*g_fMouseScaleMult*pDoc->m_bUnLockYAxis;
  930. }
  931. else if(m_Camera.m_iViewType == VIEW_FRONT) {
  932. pObj->m_fScale[X] -= (float)scale.cx*g_fMouseScaleMult*pDoc->m_bUnLockXAxis;
  933. pObj->m_fScale[Z] -= (float)scale.cy*g_fMouseScaleMult*pDoc->m_bUnLockZAxis;
  934. }
  935.     }
  936. }
  937. // Modify Object point?
  938. if(pDoc->m_bSelectObjPoints)
  939. {
  940. // The object point was 'Selected' OnLButtonDown()
  941. C3dPoint* pPnt = pWorld->m_pSelectedPnt;
  942. // Do we have an object and point selected?
  943. if(pPnt && pObj)
  944. {
  945. // Move the Selected Point?
  946. if(pDoc->m_bMove)
  947. {
  948. // Matx4x4 ObjInvRotationMatrix;
  949. GLfloat x, y, z;
  950. // We saved the object inverse rotation matrix in the 
  951. // OnLButtonDown() function.  (We saved this matrix because
  952. // an object, ie. light objects, may modify their rotation
  953. // values.  Its also saves more processing time..)
  954. // Use the inverse rotation transformation matrix of the
  955. // object and multiply it by the mouse coordinate so that
  956. // we move the point in the World coordinate space
  957. // pObj->GetInvRotationMatrix(ObjInvRotationMatrix);
  958. VecTransformf(fMouseCoordinate,
  959.   fMouseCoordinate,
  960.   g_SelctedObjMatrix);
  961. //   ObjInvRotationMatrix);
  962. // Note:  We saved the Selected coordinate in the 
  963. //   WM_LBUTTONDOWN message handler.
  964. x = fMouseCoordinate[X]+m_fSelectedCoord[X];
  965. y = fMouseCoordinate[Y]+m_fSelectedCoord[Y];
  966. z = fMouseCoordinate[Z]+m_fSelectedCoord[Z];
  967. pObj->SetObjPointOrigin(pPnt, x, y, z);
  968. // Rebuild the object
  969. pObj->m_bBuildLists = TRUE;
  970. }
  971. }
  972. // Update the Coordinate Dialog Toolbar
  973. pFrame->m_wndCoordDlgBar.UpdateDialogData();
  974. // Force a repaint of the window
  975. pDoc->UpdateAllViews(NULL);
  976. }
  977. // Translate the selected objects' axis?
  978. if(pDoc->m_bSelectObjAxis)
  979. {
  980. // Move the selected object?
  981. if(pDoc->m_bMove)
  982. {
  983. GLfloat x, y, z;
  984. Matx4x4 ObjRotationMatrix;
  985. // Does this object have a parent?
  986. if(pObj->m_pParent)
  987. {
  988. VECTORF fMousePosn;
  989. // Get the inverse rotation matrix of the parent object
  990. // and multiply the mouse coordinate so that we move the
  991. // object's origin in World coordinate space.
  992. pObj->m_pParent->GetInvRotationMatrix(ObjRotationMatrix);
  993. VecTransformf(fMouseCoordinate,
  994.   fMousePosn,
  995.   ObjRotationMatrix);
  996. // Note:  We saved the Selected coordinate in the 
  997. //   WM_LBUTTONDOWN message handler.
  998. pObj->m_fOrigin[X] = m_fSelectedCoord2[X]+fMousePosn[X];
  999. pObj->m_fOrigin[Y] = m_fSelectedCoord2[Y]+fMousePosn[Y];
  1000. pObj->m_fOrigin[Z] = m_fSelectedCoord2[Z]+fMousePosn[Z];
  1001. }
  1002. else
  1003. {
  1004. // Object does not have a parent, mouse coordinates are already
  1005. // in world coordinate space
  1006. pObj->m_fOrigin[X] = m_fSelectedCoord2[X]+fMouseCoordinate[X];
  1007. pObj->m_fOrigin[Y] = m_fSelectedCoord2[Y]+fMouseCoordinate[Y];
  1008. pObj->m_fOrigin[Z] = m_fSelectedCoord2[Z]+fMouseCoordinate[Z];
  1009. }
  1010. // Get the inverse rotation matrix of this object, (with new origin)
  1011. // and multiply the mouse coordinate so that we move the object 
  1012. // origin offset in World coordinate space.
  1013. pObj->GetInvRotationMatrix(ObjRotationMatrix);
  1014. VecTransformf(fMouseCoordinate,
  1015.   fMouseCoordinate,
  1016.   ObjRotationMatrix);
  1017. // Note:  We saved the Selected coordinate in the 
  1018. //   WM_LBUTTONDOWN message handler.
  1019. x = m_fSelectedCoord[X]-fMouseCoordinate[X];
  1020. y = m_fSelectedCoord[Y]-fMouseCoordinate[Y];
  1021. z = m_fSelectedCoord[Z]-fMouseCoordinate[Z];
  1022. pObj->SetTranslation(x, y, z);
  1023. }
  1024. }
  1025. // Translate the selected objects' texture axis?
  1026. else if(pDoc->m_bSelectObjTextureAxis)
  1027. {
  1028. if(pObj->m_pTexture)
  1029. {
  1030. // Move the selected object?
  1031. if(pDoc->m_bMove)
  1032. {
  1033. GLfloat x, y, z;
  1034. Matx4x4 ObjRotationMatrix;
  1035. /*
  1036. // Does this object have a parent?
  1037. if(pObj->m_pParent)
  1038. {
  1039. VECTORF fMousePosn;
  1040. // Get the inverse rotation matrix of the parent object
  1041. // and multiply the mouse coordinate so that we move the
  1042. // object's origin in World coordinate space.
  1043. pObj->m_pParent->GetInvRotationMatrix(ObjRotationMatrix);
  1044. VecTransformf(fMouseCoordinate,
  1045.   fMousePosn,
  1046.   ObjRotationMatrix);
  1047. // Note:  We saved the Selected coordinate in the 
  1048. //   WM_LBUTTONDOWN message handler.
  1049. pObj->m_fOrigin[X] = m_fSelectedCoord2[X]+fMousePosn[X];
  1050. pObj->m_fOrigin[Y] = m_fSelectedCoord2[Y]+fMousePosn[Y];
  1051. pObj->m_fOrigin[Z] = m_fSelectedCoord2[Z]+fMousePosn[Z];
  1052. }
  1053. else
  1054. {
  1055. // Object does not have a parent, mouse coordinates are already
  1056. // in world coordinate space
  1057. pObj->m_fOrigin[X] = m_fSelectedCoord2[X]+fMouseCoordinate[X];
  1058. pObj->m_fOrigin[Y] = m_fSelectedCoord2[Y]+fMouseCoordinate[Y];
  1059. pObj->m_fOrigin[Z] = m_fSelectedCoord2[Z]+fMouseCoordinate[Z];
  1060. }
  1061. */
  1062. // Get the inverse rotation matrix of this object, (with new origin)
  1063. // and multiply the mouse coordinate so that we move the object 
  1064. // origin offset in World coordinate space.
  1065. pObj->GetInvRotationMatrix(ObjRotationMatrix);
  1066. VecTransformf(fMouseCoordinate,
  1067.   fMouseCoordinate,
  1068.   ObjRotationMatrix);
  1069. // Note:  We saved the Selected coordinate in the 
  1070. //   WM_LBUTTONDOWN message handler.
  1071. x = m_fSelectedCoord[X]-fMouseCoordinate[X];
  1072. y = m_fSelectedCoord[Y]-fMouseCoordinate[Y];
  1073. z = m_fSelectedCoord[Z]-fMouseCoordinate[Z];
  1074. pObj->m_pTexture->SetTextureOrigin3f(x, y, z);
  1075. pObj->m_bBuildLists = TRUE;
  1076. }
  1077. }
  1078. }
  1079. // Update the Coordinate Dialog Toolbar
  1080. pFrame->m_wndCoordDlgBar.UpdateDialogData();
  1081. // Force a repaint of the window
  1082. pDoc->UpdateAllViews(NULL);
  1083. }
  1084. // World point selected & left button down?
  1085. C3dPoint* pPnt = pWorld->m_pSelectedPnt;
  1086. if(pPnt && (nFlags & MK_LBUTTON) )
  1087. {
  1088. if(pDoc->m_bSelectPoint)
  1089. {
  1090. // Move the Selected Point?
  1091. if(pDoc->m_bMove)
  1092. {
  1093. GLfloat x, y, z;
  1094. // Note:  We saved the Selected coordinate in the 
  1095. //   WM_LBUTTONDOWN message handler.
  1096. x = fMouseCoordinate[X]+m_fSelectedCoord[X];
  1097. y = fMouseCoordinate[Y]+m_fSelectedCoord[Y];
  1098. z = fMouseCoordinate[Z]+m_fSelectedCoord[Z];
  1099. pPnt->SetOrigin(x, y, z);
  1100. }
  1101. }
  1102. // Update the Coordinate Dialog Toolbar
  1103. pFrame->m_wndCoordDlgBar.UpdateDialogData();
  1104. // Force a repaint of the window
  1105. pDoc->UpdateAllViews(NULL);
  1106. }
  1107. if(pDoc->m_bSelectCamera && (nFlags & MK_LBUTTON))
  1108. {
  1109. // Move the camera?
  1110. if(pDoc->m_bMove)
  1111. {
  1112. GLfloat x, y, z;
  1113. VECTORF temp, mousePosn;
  1114. Matx4x4 RotationMatrix;
  1115. // Transform the mouse coordinates to camera coordinates
  1116. Vec4f(fMouseCoordinate[X],
  1117.   fMouseCoordinate[Y],
  1118.   fMouseCoordinate[Z],
  1119.   1.0f,
  1120.   temp);
  1121. m_Camera.GetRotationMatrix(RotationMatrix);
  1122. VecTransformf(temp, mousePosn, RotationMatrix);
  1123. // Subtract the transformed mouse move coordinates from
  1124. // the user selected OnLButtonDown coordinate and set
  1125. // the camera origin accordinly.
  1126. //
  1127. // Note:  We saved the initial camera coordinates
  1128. //   m_fSelectedCoord values in the
  1129. //   WM_LBUTTONDOWN message handler.
  1130. VecSubf(m_fSelectedCoord, mousePosn, m_fSelectedCoord);
  1131. UnVec3f(m_fSelectedCoord, &x, &y, &z);
  1132. m_Camera.SetOrigin(x, y, z);
  1133. }
  1134. // Rotate the camera?
  1135. if(pDoc->m_bRotate)
  1136. {
  1137. CSize rotate = m_CPointLeftButtonDown - point;
  1138. m_CPointLeftButtonDown = point;
  1139. if(m_Camera.m_iViewType == VIEW_ISO) {
  1140. m_Camera.m_fRotation[Z] -= rotate.cx*g_fMouseRotateMult*pDoc->m_bUnLockZAxis;
  1141. m_Camera.m_fRotation[X] -= rotate.cy*g_fMouseRotateMult*pDoc->m_bUnLockXAxis;
  1142. }
  1143. else if(m_Camera.m_iViewType == VIEW_SIDE) {
  1144. m_Camera.m_fRotation[Y] -= rotate.cx*g_fMouseRotateMult*pDoc->m_bUnLockZAxis;
  1145. m_Camera.m_fRotation[X] -= rotate.cy*g_fMouseRotateMult*pDoc->m_bUnLockYAxis;
  1146. }
  1147. else if(m_Camera.m_iViewType == VIEW_TOP) {
  1148. m_Camera.m_fRotation[Z] -= rotate.cx*g_fMouseRotateMult*pDoc->m_bUnLockYAxis;
  1149. m_Camera.m_fRotation[X] -= rotate.cy*g_fMouseRotateMult*pDoc->m_bUnLockXAxis;
  1150. }
  1151. else if(m_Camera.m_iViewType == VIEW_FRONT) {
  1152. m_Camera.m_fRotation[Y] -= rotate.cx*g_fMouseRotateMult*pDoc->m_bUnLockZAxis;
  1153. m_Camera.m_fRotation[X] -= rotate.cy*g_fMouseRotateMult*pDoc->m_bUnLockXAxis;
  1154. }
  1155.     }
  1156. // Update the Coordinate Dialog Toolbar
  1157. pFrame->m_wndCoordDlgBar.UpdateDialogData();
  1158. // Force a repaint of the window
  1159. pDoc->UpdateAllViews(NULL);
  1160. }
  1161. // Display the world coordinates on the status bar if we
  1162. // are not animating the world..
  1163. if(!pWorld->m_bAnimate)
  1164. DisplayWorldCoord(fMouseCoordinate);
  1165. CView::OnMouseMove(nFlags, point);
  1166. }
  1167. void CMyglView::OnViewPerspective() 
  1168. {
  1169. if(m_Camera.m_bPerspective)
  1170. m_Camera.m_bPerspective = FALSE;
  1171. else
  1172. m_Camera.m_bPerspective = TRUE;
  1173. // Make this view the current OpenGL rendering context...
  1174. if(!the3dEngine.EnableRC(GetDC()->m_hDC, m_hRC, TRUE))
  1175. return;
  1176. // Reset our camera view
  1177. m_Camera.ResetView(NULL, NULL);
  1178. // Releases the device context that is used by the rendering context
  1179. // to allow other rendering contexts to co-exist.
  1180. the3dEngine.EnableRC(NULL, NULL, FALSE);
  1181. // Force a repaint of the window
  1182. InvalidateRect(NULL, FALSE);
  1183. }
  1184. void CMyglView::OnUpdateViewPerspective(CCmdUI* pCmdUI) 
  1185. {
  1186. pCmdUI->SetCheck(m_Camera.m_bPerspective);
  1187. }
  1188. void CMyglView::OnViewZoomIn() 
  1189. {
  1190. m_Camera.m_fOrigin[Z] = m_Camera.m_fOrigin[Z]/2;
  1191. // Make this view the current OpenGL rendering context...
  1192. if(!the3dEngine.EnableRC(GetDC()->m_hDC, m_hRC, TRUE))
  1193. return;
  1194. // Reset our camera view
  1195. m_Camera.ResetView(NULL, NULL);
  1196. // Releases the device context that is used by the rendering context
  1197. // to allow other rendering contexts to co-exist.
  1198. the3dEngine.EnableRC(NULL, NULL, FALSE);
  1199. // Force a repaint of the window
  1200. InvalidateRect(NULL, FALSE);
  1201. }
  1202. void CMyglView::OnViewZoomOut() 
  1203. {
  1204. m_Camera.m_fOrigin[Z] = m_Camera.m_fOrigin[Z]*2;
  1205. // Make this view the current OpenGL rendering context...
  1206. if(!the3dEngine.EnableRC(GetDC()->m_hDC, m_hRC, TRUE))
  1207. return;
  1208. // Reset our camera view
  1209. m_Camera.ResetView(NULL, NULL);
  1210. // Releases the device context that is used by the rendering context
  1211. // to allow other rendering contexts to co-exist.
  1212. the3dEngine.EnableRC(NULL, NULL, FALSE);
  1213. // Force a repaint of the window
  1214. InvalidateRect(NULL, FALSE);
  1215. }
  1216. void CMyglView::OnAnimateSceen() 
  1217. {
  1218. // Get a pointer to our view's document
  1219. CMyglDoc* pDoc = GetDocument();
  1220. ASSERT_VALID(pDoc);
  1221. // Get a pointer to our document's 3dWorld
  1222. C3dWorld* pWorld = pDoc->m_pWorld;
  1223. ASSERT_VALID(pWorld);
  1224. // Toggle the animation flag
  1225. pWorld->m_bAnimate = !pWorld->m_bAnimate;
  1226. if(!pWorld->m_bAnimate)
  1227. pDoc->m_dTime = 0.0; // Reset the time index
  1228. }
  1229. void CMyglView::OnUpdateAnimateSceen(CCmdUI* pCmdUI) 
  1230. {
  1231. // Get a pointer to our view's document
  1232. CMyglDoc* pDoc = GetDocument();
  1233. ASSERT_VALID(pDoc);
  1234. // Get a pointer to our document's 3dWorld
  1235. C3dWorld* pWorld = pDoc->m_pWorld;
  1236. ASSERT_VALID(pWorld);
  1237. pCmdUI->SetCheck(pWorld->m_bAnimate);
  1238. }
  1239. void CMyglView::OnViewWireFrame() 
  1240. {
  1241. // Get a pointer to our view's document
  1242. CMyglDoc* pDoc = GetDocument();
  1243. ASSERT_VALID(pDoc);
  1244. // Get a pointer to our document's 3dWorld
  1245. C3dWorld* pWorld = pDoc->m_pWorld;
  1246. ASSERT_VALID(pWorld);
  1247. // Set the rendering mode flag and force a 
  1248. // rebuild of all object display lists
  1249. pWorld->m_iRenderMode = RENDER_WIREFRAME;
  1250. pWorld->RebuildAllObjects();
  1251. // Force a repaint of the window
  1252. pDoc->UpdateAllViews(NULL);
  1253. }
  1254. void CMyglView::OnUpdateViewWireFrame(CCmdUI* pCmdUI) 
  1255. {
  1256. // Get a pointer to our view's document
  1257. CMyglDoc* pDoc = GetDocument();
  1258. ASSERT_VALID(pDoc);
  1259. // Get a pointer to our document's 3dWorld
  1260. C3dWorld* pWorld = pDoc->m_pWorld;
  1261. ASSERT_VALID(pWorld);
  1262. pCmdUI->SetCheck(pWorld->m_iRenderMode == RENDER_WIREFRAME);
  1263. }
  1264. void CMyglView::OnViewFlatShade() 
  1265. {
  1266. // Get a pointer to our view's document
  1267. CMyglDoc* pDoc = GetDocument();
  1268. ASSERT_VALID(pDoc);
  1269. // Get a pointer to our document's 3dWorld
  1270. C3dWorld* pWorld = pDoc->m_pWorld;
  1271. ASSERT_VALID(pWorld);
  1272. // Set the rendering mode flag and force a 
  1273. // rebuild of all object display lists
  1274. pWorld->m_iRenderMode = RENDER_FLAT;
  1275. pWorld->RebuildAllObjects();
  1276. // Force a repaint of the window
  1277. pDoc->UpdateAllViews(NULL);
  1278. }
  1279. void CMyglView::OnUpdateViewFlatShade(CCmdUI* pCmdUI) 
  1280. {
  1281. // Get a pointer to our view's document
  1282. CMyglDoc* pDoc = GetDocument();
  1283. ASSERT_VALID(pDoc);
  1284. // Get a pointer to our document's 3dWorld
  1285. C3dWorld* pWorld = pDoc->m_pWorld;
  1286. ASSERT_VALID(pWorld);
  1287. pCmdUI->SetCheck(pWorld->m_iRenderMode == RENDER_FLAT);
  1288. }
  1289. void CMyglView::OnViewSmoothShade() 
  1290. {
  1291. // Get a pointer to our view's document
  1292. CMyglDoc* pDoc = GetDocument();
  1293. ASSERT_VALID(pDoc);
  1294. // Get a pointer to our document's 3dWorld
  1295. C3dWorld* pWorld = pDoc->m_pWorld;
  1296. ASSERT_VALID(pWorld);
  1297. // Set the rendering mode flag and force a 
  1298. // rebuild of all object display lists
  1299. pWorld->m_iRenderMode = RENDER_SMOOTH;
  1300. pWorld->RebuildAllObjects();
  1301. // Force a repaint of the window
  1302. pDoc->UpdateAllViews(NULL);
  1303. }
  1304. void CMyglView::OnUpdateViewSmoothShade(CCmdUI* pCmdUI) 
  1305. {
  1306. // Get a pointer to our view's document
  1307. CMyglDoc* pDoc = GetDocument();
  1308. ASSERT_VALID(pDoc);
  1309. // Get a pointer to our document's 3dWorld
  1310. C3dWorld* pWorld = pDoc->m_pWorld;
  1311. ASSERT_VALID(pWorld);
  1312. pCmdUI->SetCheck(pWorld->m_iRenderMode == RENDER_SMOOTH);
  1313. }
  1314. void CMyglView::OnViewOutline() 
  1315. {
  1316. // Get a pointer to our view's document
  1317. CMyglDoc* pDoc = GetDocument();
  1318. ASSERT_VALID(pDoc);
  1319. // Get a pointer to our document's 3dWorld
  1320. C3dWorld* pWorld = pDoc->m_pWorld;
  1321. ASSERT_VALID(pWorld);
  1322. // Set the rendering mode flag and force a 
  1323. // rebuild of all object display lists
  1324. pWorld->m_iRenderMode = RENDER_OUTLINE;
  1325. pWorld->RebuildAllObjects();
  1326. // Force a repaint of the window
  1327. pDoc->UpdateAllViews(NULL);
  1328. }
  1329. void CMyglView::OnUpdateViewOutline(CCmdUI* pCmdUI) 
  1330. {
  1331. // Get a pointer to our view's document
  1332. CMyglDoc* pDoc = GetDocument();
  1333. ASSERT_VALID(pDoc);
  1334. // Get a pointer to our document's 3dWorld
  1335. C3dWorld* pWorld = pDoc->m_pWorld;
  1336. ASSERT_VALID(pWorld);
  1337. pCmdUI->SetCheck(pWorld->m_iRenderMode == RENDER_OUTLINE);
  1338. }
  1339. void CMyglView::OnViewDisplayAxis() 
  1340. {
  1341. // Get a pointer to our view's document
  1342. CMyglDoc* pDoc = GetDocument();
  1343. ASSERT_VALID(pDoc);
  1344. // Get a pointer to our document's 3dWorld
  1345. C3dWorld* pWorld = pDoc->m_pWorld;
  1346. ASSERT_VALID(pWorld);
  1347. if(pWorld->m_bDisplayAxis)
  1348. pWorld->m_bDisplayAxis = FALSE;
  1349. else
  1350. pWorld->m_bDisplayAxis = TRUE;
  1351. // Force a repaint of the window
  1352. pDoc->UpdateAllViews(NULL);
  1353. }
  1354. void CMyglView::OnUpdateViewDisplayAxis(CCmdUI* pCmdUI) 
  1355. {
  1356. // Get a pointer to our view's document
  1357. CMyglDoc* pDoc = GetDocument();
  1358. ASSERT_VALID(pDoc);
  1359. // Get a pointer to our document's 3dWorld
  1360. C3dWorld* pWorld = pDoc->m_pWorld;
  1361. ASSERT_VALID(pWorld);
  1362. pCmdUI->SetCheck(pWorld->m_bDisplayAxis);
  1363. }
  1364. void CMyglView::OnViewDisplayGrid() 
  1365. {
  1366. // Get a pointer to our view's document
  1367. CMyglDoc* pDoc = GetDocument();
  1368. ASSERT_VALID(pDoc);
  1369. // Get a pointer to our document's 3dWorld
  1370. C3dWorld* pWorld = pDoc->m_pWorld;
  1371. ASSERT_VALID(pWorld);
  1372. if(pWorld->m_bDisplayGrid)
  1373. pWorld->m_bDisplayGrid = FALSE;
  1374. else
  1375. pWorld->m_bDisplayGrid = TRUE;
  1376. // Force a repaint of the window
  1377. pDoc->UpdateAllViews(NULL);
  1378. }
  1379. void CMyglView::OnUpdateViewDisplayGrid(CCmdUI* pCmdUI) 
  1380. {
  1381. // Get a pointer to our view's document
  1382. CMyglDoc* pDoc = GetDocument();
  1383. ASSERT_VALID(pDoc);
  1384. // Get a pointer to our document's 3dWorld
  1385. C3dWorld* pWorld = pDoc->m_pWorld;
  1386. ASSERT_VALID(pWorld);
  1387. pCmdUI->SetCheck(pWorld->m_bDisplayGrid);
  1388. }
  1389. void CMyglView::OnViewIso() 
  1390. {
  1391. // Set the camera position
  1392. ViewIso();
  1393. // Force a repaint of the window
  1394. InvalidateRect(NULL, FALSE);
  1395. }
  1396. void CMyglView::OnUpdateViewIso(CCmdUI* pCmdUI) 
  1397. {
  1398. if(m_Camera.m_iViewType == VIEW_ISO)
  1399. pCmdUI->SetCheck(TRUE);
  1400. else
  1401. pCmdUI->SetCheck(FALSE);
  1402. }
  1403. void CMyglView::OnViewFront() 
  1404. {
  1405. // Set the camera position
  1406. ViewFront();
  1407. // Force a repaint of the window
  1408. InvalidateRect(NULL, FALSE);
  1409. }
  1410. void CMyglView::OnUpdateViewFront(CCmdUI* pCmdUI) 
  1411. {
  1412. if(m_Camera.m_iViewType == VIEW_FRONT)
  1413. pCmdUI->SetCheck(TRUE);
  1414. else
  1415. pCmdUI->SetCheck(FALSE);
  1416. }
  1417. void CMyglView::OnViewSide() 
  1418. {
  1419. // Set the camera position
  1420. ViewSide();
  1421. // Force a repaint of the window
  1422. InvalidateRect(NULL, FALSE);
  1423. }
  1424. void CMyglView::OnUpdateViewSide(CCmdUI* pCmdUI) 
  1425. {
  1426. if(m_Camera.m_iViewType == VIEW_SIDE)
  1427. pCmdUI->SetCheck(TRUE);
  1428. else
  1429. pCmdUI->SetCheck(FALSE);
  1430. }
  1431. void CMyglView::OnViewTop() 
  1432. {
  1433. // Set the camera position
  1434. ViewTop();
  1435. // Force a repaint of the window
  1436. InvalidateRect(NULL, FALSE);
  1437. }
  1438. void CMyglView::OnUpdateViewTop(CCmdUI* pCmdUI) 
  1439. {
  1440. if(m_Camera.m_iViewType == VIEW_TOP)
  1441. pCmdUI->SetCheck(TRUE);
  1442. else
  1443. pCmdUI->SetCheck(FALSE);
  1444. }
  1445. void CMyglView::DisplayWorldCoord(VECTORF fMouseCoordinate)
  1446. {
  1447. // Display the world coordinates on the status bar
  1448. char buf[80];
  1449. float x = fMouseCoordinate[X];
  1450. float y = fMouseCoordinate[Y];
  1451. float z = fMouseCoordinate[Z];
  1452. CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
  1453. ASSERT(pFrame);
  1454. CStatusBar* pStatus = &pFrame->m_wndStatusBar;
  1455. ASSERT(pStatus);
  1456. sprintf(buf, "'X'= %5.2f  'Y'= %5.2f  'Z'= %5.2fn", x, y, z);
  1457. pStatus->SetPaneText(0, buf);
  1458. }
  1459. void CMyglView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  1460. {
  1461. // Get a pointer to our view's document
  1462. CMyglDoc* pDoc = GetDocument();
  1463. ASSERT_VALID(pDoc);
  1464. // Get a pointer to our document's 3dWorld
  1465. C3dWorld* pWorld = pDoc->m_pWorld;
  1466. ASSERT_VALID(pWorld);
  1467. if(pWorld->m_bFly)
  1468. {
  1469. switch (nChar)
  1470. {
  1471. case VK_UP:
  1472. m_Camera.m_fOrigin[Z] -=2.0f;
  1473. break;
  1474. case VK_DOWN:
  1475. m_Camera.m_fOrigin[Z] +=2.0f;
  1476. break;
  1477. case VK_LEFT:
  1478. m_Camera.m_fRotation[Z] -=2.0f;
  1479. break;
  1480. case VK_RIGHT:
  1481. m_Camera.m_fRotation[Z] +=2.0f;
  1482. break;
  1483. default:
  1484. break;
  1485. }
  1486. // Force a repaint of the window
  1487. InvalidateRect(NULL, FALSE);
  1488. }
  1489. if(!pWorld->m_bFly && nChar == VK_DELETE) // DELETE KEY PRESSED
  1490. {
  1491. if(pWorld->m_pSelectedObj)
  1492. {
  1493. // Get a pointer to the MainFrame
  1494. CMyglApp* pApp = (CMyglApp *)AfxGetApp();
  1495. ASSERT(pApp);
  1496. if(pApp->m_bConfirmObjectDeletion)
  1497. {
  1498. char buf[80];
  1499. sprintf(buf, "Do you want to delete object '%s'?n", pWorld->m_pSelectedObj->m_szName);
  1500. if(AfxMessageBox(buf, MB_OKCANCEL) == IDOK)
  1501. pWorld->DeleteObject(pWorld->m_pSelectedObj);
  1502. else
  1503. return;
  1504. }
  1505. else
  1506. pWorld->DeleteObject(pWorld->m_pSelectedObj);
  1507. pWorld->m_pSelectedObj = NULL;
  1508. // Get a pointer to the MainFrame
  1509. CMainFrame* pMainFrame = (CMainFrame*)pApp->m_pMainWnd;
  1510. ASSERT(pMainFrame);
  1511. // Force a refresh of the mainframe's dialog bars (TreeView, ..)
  1512. pMainFrame->SendMessage(WM_REFRESH_DLG_BAR, RDB_FORCE_REFRESH, 0L);
  1513. // Force a repaint of the documents views
  1514. pDoc->UpdateAllViews(NULL);
  1515. }
  1516. }
  1517. CView::OnKeyDown(nChar, nRepCnt, nFlags);
  1518. }
  1519. void CMyglView::OnCameraEdit() 
  1520. {
  1521. // Get a pointer to our view's document
  1522. CMyglDoc* pDoc = GetDocument();
  1523. ASSERT_VALID(pDoc);
  1524. // Get a pointer to our document's 3dWorld
  1525. C3dWorld* pWorld = pDoc->m_pWorld;
  1526. ASSERT_VALID(pWorld);
  1527. // Edit the camera attributes
  1528. if(m_Camera.EditAttributes(this, pWorld) == IDOK)
  1529. {
  1530. // Make this view the current OpenGL rendering context...
  1531. if(!the3dEngine.EnableRC(m_pDC->GetSafeHdc(), m_hRC, TRUE))
  1532. return;
  1533. // Reset our camera view
  1534. m_Camera.ResetView(NULL, NULL);
  1535. // Releases the device context that is used by the rendering context
  1536. // to allow other rendering contexts to co-exist.
  1537. the3dEngine.EnableRC(NULL, NULL, FALSE);
  1538. // Force a repaint of the window
  1539. InvalidateRect(NULL, FALSE);
  1540. }
  1541. return;
  1542. }
  1543. void CMyglView::OnViewCullfaces() 
  1544. {
  1545. // Get a pointer to our view's document
  1546. CMyglDoc* pDoc = GetDocument();
  1547. ASSERT_VALID(pDoc);
  1548. // Get a pointer to our document's 3dWorld
  1549. C3dWorld* pWorld = pDoc->m_pWorld;
  1550. ASSERT_VALID(pWorld);
  1551. if(pWorld->m_bCullFaces)
  1552. pWorld->m_bCullFaces = FALSE;
  1553. else
  1554. pWorld->m_bCullFaces = TRUE;
  1555. // Force a repaint of the window
  1556. pDoc->UpdateAllViews(NULL);
  1557. }
  1558. void CMyglView::OnUpdateViewCullfaces(CCmdUI* pCmdUI) 
  1559. {
  1560. // Get a pointer to our view's document
  1561. CMyglDoc* pDoc = GetDocument();
  1562. ASSERT_VALID(pDoc);
  1563. // Get a pointer to our document's 3dWorld
  1564. C3dWorld* pWorld = pDoc->m_pWorld;
  1565. ASSERT_VALID(pWorld);
  1566. if(pWorld->m_bCullFaces)
  1567. pCmdUI->SetCheck(TRUE);
  1568. else
  1569. pCmdUI->SetCheck(FALSE);
  1570. }
  1571. void CMyglView::OnFileSaveImage() 
  1572. {
  1573. CFileDialog fileDlg(FALSE, NULL, NULL);
  1574. fileDlg.m_ofn.lpstrFilter = "Bitmap Files (*.bmp)*.bmp";
  1575. fileDlg.m_ofn.lpstrTitle = "Save Image As";
  1576. int retn = fileDlg.DoModal();
  1577. if(retn == IDOK) {
  1578. CString szFile = fileDlg.GetFileName();
  1579. CString szPath = fileDlg.GetPathName();
  1580. CString szFileExt = fileDlg.GetFileExt();
  1581. if(szFileExt.Compare("") == 0)
  1582. {
  1583. // Assign the default 'bmp' extension
  1584. szFileExt = _T("bmp");
  1585. szFile += _T(".bmp");
  1586. szPath += _T(".bmp");
  1587. }
  1588. if(szFileExt.Compare("bmp") == 0)
  1589. {
  1590. // Make this view the current OpenGL rendering context...
  1591. if(!the3dEngine.EnableRC(m_pDC->GetSafeHdc(), m_hRC, TRUE))
  1592. return;
  1593. g_pBitmapBits = (GLubyte*)g_DibImage.ReadDIBitmap(&g_pBitmapInfo);
  1594. g_DibImage.SaveDIBFile(szPath.GetBuffer(128), g_pBitmapInfo, g_pBitmapBits);
  1595. // Releases the device context that is used by the rendering context
  1596. // to allow other rendering contexts to co-exist.
  1597. the3dEngine.EnableRC(NULL, NULL, FALSE);
  1598. }
  1599. else
  1600. AfxMessageBox("Invalid File Extension!  Select files with 'bmp' extension.", MB_OK, NULL);
  1601. }
  1602. }
  1603. BOOL CMyglView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  1604. {
  1605. // Get a pointer to our view's document
  1606. CMyglDoc* pDoc = GetDocument();
  1607. ASSERT_VALID(pDoc);
  1608. if(pDoc->m_bPaint)
  1609. {
  1610. // Set our cursor and save the previous 
  1611. pDoc->m_hCursorPrev = ::SetCursor(pDoc->m_hPaintCursor);
  1612. ::ShowCursor(TRUE);
  1613. return TRUE;
  1614. }
  1615. return CView::OnSetCursor(pWnd, nHitTest, message);
  1616. }