home *** CD-ROM | disk | FTP | other *** search
/ 3D Graphics Programming for Windows 95 / 3D_Graphics_Programming_for_Windows_95_Microsoft_1996.iso / samples / blobs / mainfrm.cpp < prev    next >
C/C++ Source or Header  |  1996-07-17  |  10KB  |  423 lines

  1. // MainFrm.cpp : implementation of the CMainFrame class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Stage.h"
  6. #include "MainFrm.h"
  7. #include "indevdlg.h"
  8.  
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14.  
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CMainFrame
  17.  
  18. IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
  19.  
  20. BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  21.     //{{AFX_MSG_MAP(CMainFrame)
  22.     ON_WM_CREATE()
  23.     ON_WM_DESTROY()
  24.     ON_WM_ACTIVATEAPP()
  25.     ON_WM_PALETTECHANGED()
  26.     ON_WM_MOVE()
  27.     ON_COMMAND(ID_FILE_NEW, OnFileNew)
  28.     ON_WM_SETFOCUS()
  29.     ON_COMMAND(ID_EDIT_CONTROL, OnEditControl)
  30.     ON_UPDATE_COMMAND_UI(ID_EDIT_CONTROL, OnUpdateEditControl)
  31.     ON_COMMAND(ID_EDIT_INPUTDEV, OnEditInputdev)
  32.     //}}AFX_MSG_MAP
  33. END_MESSAGE_MAP()
  34.  
  35. static UINT indicators[] =
  36. {
  37.     ID_SEPARATOR,           // status line indicator
  38.     ID_INDICATOR_CAPS,
  39.     ID_INDICATOR_NUM,
  40.     ID_INDICATOR_SCRL,
  41. };
  42.  
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CMainFrame construction/destruction
  45.  
  46. CMainFrame::CMainFrame()
  47. {
  48.     m_pScene = NULL;
  49.     m_pCurShape = FALSE;
  50.     m_pController = NULL;
  51.     m_iObjCtrlDev = 0;
  52.     m_iControlObj = 0;
  53.     m_iControlType = 0;
  54. }
  55.  
  56. CMainFrame::~CMainFrame()
  57. {
  58. }
  59.  
  60. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  61. {
  62.     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  63.         return -1;
  64.     
  65.     if (!m_wndToolBar.Create(this) ||
  66.         !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
  67.     {
  68.         TRACE0("Failed to create toolbar\n");
  69.         return -1;      // fail to create
  70.     }
  71.  
  72.     if (!m_wndStatusBar.Create(this) ||
  73.         !m_wndStatusBar.SetIndicators(indicators,
  74.           sizeof(indicators)/sizeof(UINT)))
  75.     {
  76.         TRACE0("Failed to create status bar\n");
  77.         return -1;      // fail to create
  78.     }
  79.  
  80.     // Create the 3D window
  81.     if (!m_wnd3d.Create(this, IDC_3DWND)) {
  82.         return -1;
  83.     }
  84.  
  85.     // TODO: Remove this if you don't want tool tips or a resizeable toolbar
  86.     m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
  87.         CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  88.  
  89.     // TODO: Delete these three lines if you don't want the toolbar to
  90.     //  be dockable
  91.     m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
  92.     EnableDocking(CBRS_ALIGN_ANY);
  93.     DockControlBar(&m_wndToolBar);
  94.  
  95.     NewScene();
  96.     ASSERT(m_pScene);
  97.  
  98.     // Create the controller object
  99.     if (m_iControlType == 0) {
  100.         m_pController = new C3dPosCtlr;
  101.     } else {
  102.         m_pController = new C3dFlyCtlr;
  103.     }
  104.     m_pController->Create(&m_wnd3d,
  105.                           OnGetCtrlFrame,
  106.                           this);
  107.  
  108.     // restore the controller settings
  109.     m_pController->SelectDevice(m_iObjCtrlDev);
  110.  
  111.     // enable mouse selection of objects
  112.     m_wnd3d.EnableMouseSelection(OnSelChange, this);
  113.     
  114.     return 0;
  115. }
  116.  
  117. BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  118. {
  119.     // Restore any saved settings
  120.     RestoreSettings();
  121.  
  122.     // Restore the window size and position
  123.     cs.x = m_rcWnd.left;
  124.     cs.y = m_rcWnd.top;
  125.     cs.cx = m_rcWnd.Width();
  126.     cs.cy = m_rcWnd.Height();
  127.  
  128.     return CFrameWnd::PreCreateWindow(cs);
  129. }
  130.  
  131. BOOL CMainFrame::NewScene()
  132. {
  133.     // Delete any scene we might have
  134.     if (m_pScene) {
  135.         m_wnd3d.SetScene(NULL);
  136.         delete m_pScene;
  137.         m_pScene = NULL;
  138.     }
  139.  
  140.     // Create an initial scene
  141.     m_pScene = new C3dScene;
  142.     if (!m_pScene->Create()) return FALSE;
  143.  
  144.     // Create a shape to add
  145.     m_pCurShape = new C3dShape;
  146.     m_pCurShape->CreateSphere(0.5, 4);
  147.     m_pScene->AddChild(m_pCurShape);
  148.     m_pScene->m_ShapeList.Append(m_pCurShape);
  149.  
  150.     // Set up the lighting
  151.     C3dDirLight dl;
  152.     dl.Create(0.8, 0.8, 0.8);
  153.     m_pScene->AddChild(&dl);
  154.     dl.SetPosition(-2, 2, -5);
  155.     dl.SetDirection(1, -1, 1);
  156.     m_pScene->SetAmbientLight(0.4, 0.4, 0.4);
  157.  
  158.     // reset the camera position and direction
  159.     m_pScene->SetCameraPosition(C3dVector(0, 0, -10));
  160.     m_pScene->SetCameraDirection(C3dVector(0, 0, 1), C3dVector(0, 1, 0));
  161.  
  162.     m_wnd3d.SetScene(m_pScene);
  163.     return TRUE;
  164. }
  165.  
  166. /////////////////////////////////////////////////////////////////////////////
  167. // CMainFrame diagnostics
  168.  
  169. #ifdef _DEBUG
  170. void CMainFrame::AssertValid() const
  171. {
  172.     CFrameWnd::AssertValid();
  173. }
  174.  
  175. void CMainFrame::Dump(CDumpContext& dc) const
  176. {
  177.     CFrameWnd::Dump(dc);
  178. }
  179.  
  180. #endif //_DEBUG
  181.  
  182. void CMainFrame::OnDestroy() 
  183. {
  184.     CFrameWnd::OnDestroy();
  185.  
  186.     // Save the current settings
  187.     SaveSettings();
  188.     
  189.     // destroy the controller
  190.     if (m_pController) {
  191.         delete m_pController;
  192.         m_pController = NULL;
  193.     }
  194.  
  195.     // Delete any scene we might have
  196.     m_wnd3d.SetScene(NULL);
  197.     if (m_pScene) {
  198.         delete m_pScene;
  199.         m_pScene = NULL;
  200.     }
  201. }
  202.  
  203. /////////////////////////////////////////////////////////////////////////////
  204. // window layout handler
  205.  
  206. void CMainFrame::RecalcLayout(BOOL bNotify) 
  207. {
  208.     // Rearrange the control bars and fit the 3D window in the middle
  209.     // Let the frame rearrange the control bars
  210.     CFrameWnd::RecalcLayout(bNotify);
  211.  
  212.     // Find the space that's left over
  213.     CRect rc;
  214.     RepositionBars(0,
  215.                    0xFFFF,
  216.                    IDC_3DWND,
  217.                    CWnd::reposQuery,
  218.                    &rc);
  219.     if (IsWindow(m_wnd3d.GetSafeHwnd())) {
  220.         m_wnd3d.MoveWindow(&rc, FALSE);
  221.     }
  222. }
  223.  
  224.  
  225. ///////////////////////////////////////////////////////////////
  226. // Windows messages we need to handle
  227.  
  228. void CMainFrame::OnActivateApp(BOOL bActive, HTASK hTask) 
  229. {
  230.     CFrameWnd::OnActivateApp(bActive, hTask);
  231.     
  232.     // Tell the 3D window about the new state
  233.     m_wnd3d.SendMessage(WM_ACTIVATEAPP,
  234.                         (WPARAM)bActive,
  235.                         (LPARAM)hTask);
  236. }
  237.  
  238. void CMainFrame::OnPaletteChanged(CWnd* pFocusWnd) 
  239. {
  240.     // Let the 3D window know
  241.     m_wnd3d.SendMessage(WM_PALETTECHANGED,
  242.                        pFocusWnd ? (WPARAM)pFocusWnd->GetSafeHwnd() : 0);
  243. }
  244.  
  245. void CMainFrame::OnMove(int x, int y) 
  246. {
  247.     CFrameWnd::OnMove(x, y);
  248.     
  249.     // Let the 3D window know the frame has moved
  250.     m_wnd3d.SendMessage(WM_MOVE, 0, MAKELPARAM(0, 0));
  251. }
  252.  
  253. void CMainFrame::OnSetFocus(CWnd* pOldWnd) 
  254. {
  255.     CFrameWnd::OnSetFocus(pOldWnd);
  256.     
  257.     // Give the focus to the 3D window so it can process
  258.     // keystrokes for the key input device
  259.     m_wnd3d.SetFocus();
  260. }
  261.  
  262. ///////////////////////////////////////////////////////////////
  263. // Adding new objects
  264.  
  265. void CMainFrame::OnFileNew() 
  266. {
  267.     NewScene();
  268. }
  269.  
  270. BOOL CMainFrame::OpenFile(const char* pszPath)
  271. {
  272.         return FALSE;
  273. }
  274.  
  275. ///////////////////////////////////////////////////////////////
  276. // Format a string for the status bar
  277.  
  278. void CMainFrame::Status(const char* pszFormat, ...)
  279. {
  280.     char buf[256];
  281.     va_list arglist;
  282.     va_start(arglist, pszFormat);
  283.     vsprintf(buf, pszFormat, arglist);
  284.     va_end(arglist);
  285.     m_wndStatusBar.SetWindowText(buf);
  286.     m_wndStatusBar.UpdateWindow();
  287. }
  288.  
  289. //////////////////////////////////////////////////////////////
  290. // Control device selection
  291.  
  292. // callback from the dialog to get a frame to control
  293. // static
  294. C3dFrame* CMainFrame::OnGetCtrlFrame(void* pArg)
  295. {
  296.     CMainFrame* pThis = (CMainFrame*) pArg;
  297.     ASSERT(pThis);
  298.     ASSERT(pThis->IsKindOf(RUNTIME_CLASS(CMainFrame)));
  299.     if (pThis->m_iControlObj == 1) {
  300.         return pThis->m_wnd3d.GetCamera();
  301.     }
  302.     return pThis->m_pCurShape;
  303. }
  304.  
  305. void CMainFrame::OnEditControl() 
  306. {
  307.     CInpDevDlg dlg;
  308.     dlg.m_iObject = m_iControlObj;
  309.     dlg.m_iType = m_iControlType;
  310.     dlg.m_iDevice = m_iObjCtrlDev;
  311.     if (dlg.DoModal() != IDOK) return;
  312.     m_iControlObj = dlg.m_iObject;
  313.  
  314.     // set up the controller type
  315.     if (dlg.m_iType != m_iControlType) {
  316.  
  317.         if (m_pController) delete m_pController;
  318.  
  319.         // create a new controller
  320.         m_iControlType = dlg.m_iType;
  321.         if (m_iControlType == 0) {
  322.             m_pController = new C3dPosCtlr;
  323.         } else {
  324.             m_pController = new C3dFlyCtlr;
  325.         }
  326.         m_pController->Create(&m_wnd3d,
  327.                               OnGetCtrlFrame,
  328.                               this);
  329.     }
  330.  
  331.     ASSERT(m_pController);
  332.     m_pController->SelectDevice(dlg.m_iDevice);
  333.      m_iObjCtrlDev = m_pController->GetCurDevice();
  334.     Status("Control is now via: %s", 
  335.            m_pController->GetDeviceName(m_iObjCtrlDev));
  336. }
  337.  
  338. void CMainFrame::OnUpdateEditControl(CCmdUI* pCmdUI) 
  339. {
  340.     pCmdUI->Enable(m_pController ? TRUE : FALSE);
  341. }
  342.  
  343. void CMainFrame::OnEditInputdev() 
  344. {
  345.     ASSERT(m_pController);
  346.     C3dInputDevice* pDev = m_pController->GetInputDevice();
  347.     ASSERT(pDev);
  348.     pDev->ShowConfigDlg();
  349. }
  350.  
  351. //////////////////////////////////////////////////////////////////
  352. // Save and Restore Settings
  353.  
  354. void CMainFrame::SaveSettings()
  355. {
  356.     CWinApp* pa = AfxGetApp();
  357.     pa->WriteProfileInt("Settings","ControlDevice", m_iObjCtrlDev);
  358.     CRect rc;
  359.     GetWindowRect(&rc);
  360.     pa->WriteProfileInt("Settings\\Window","Top", rc.top);
  361.     pa->WriteProfileInt("Settings\\Window","Left", rc.left);
  362.     pa->WriteProfileInt("Settings\\Window","Width", rc.Width());
  363.     pa->WriteProfileInt("Settings\\Window","Height", rc.Height());
  364. }
  365.  
  366. void CMainFrame::RestoreSettings()
  367. {
  368.     CWinApp* pa = AfxGetApp();
  369.     m_iObjCtrlDev = pa->GetProfileInt("Settings","ControlDevice", 0);
  370.     m_rcWnd.top = pa->GetProfileInt("Settings\\Window","Top", 50);
  371.     m_rcWnd.left = pa->GetProfileInt("Settings\\Window","Left", 50);
  372.     m_rcWnd.right = m_rcWnd.left + pa->GetProfileInt("Settings\\Window","Width", 300); 
  373.     m_rcWnd.bottom = m_rcWnd.top + pa->GetProfileInt("Settings\\Window","Height", 350);
  374. }
  375.  
  376. //////////////////////////////////////////////////////////////////////////
  377. // object selection
  378.  
  379. // callback notification function
  380. // called by m_wnd3d when the object selection changes
  381. // static
  382. void CMainFrame::OnSelChange(C3dShape* pShape, CPoint pt,
  383.                              void* pArg)
  384. {
  385.     // Get pointer to the class
  386.     CMainFrame* pThis = (CMainFrame*) pArg;
  387.     ASSERT(pThis);
  388.     ASSERT(pThis->IsKindOf(RUNTIME_CLASS(CMainFrame)));
  389.  
  390.     if (pShape) {
  391.  
  392.         // Find which face was hit
  393.         C3dViewport* pViewport = pThis->m_wnd3d.GetStage()->GetViewport();
  394.         int iFace;
  395.         C3dVector vHit;
  396.         if (pShape->HitTest(pt, pViewport, &iFace, &vHit)) {
  397.             pThis->AddBlob(pShape, vHit);
  398.         }
  399.     }
  400. }
  401.  
  402. void CMainFrame::AddBlob(C3dShape* pShape, C3dVector& vHit)
  403. {
  404.     // Get hit point on shape and
  405.     // convert from local to world coordinates
  406.     ASSERT(pShape);
  407.     C3dVector vh = pShape->Transform(vHit);
  408.  
  409.     // Create a blob to add
  410.     C3dShape* pBlob = new C3dShape;
  411.     pBlob->CreateSphere(0.5, 4);
  412.  
  413.     // Center it on hit point
  414.     pBlob->SetPosition(vh);
  415.  
  416.     // Attach it to shape
  417.     pShape->AddChild(pBlob);
  418.  
  419.     // Keep track of new blob so we can hit test it
  420.     m_pScene->m_ShapeList.Append(pBlob);
  421. }
  422.  
  423.