Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
MagicView.cpp
Go to the documentation of this file.
1 /* Project Magic 2.0
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Magic.exe
6  FILE: MagicView.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Implementation of the MagicView class
13 */
14 
15 #include "stdafx.h"
16 #include "Magic.h"
17 
18 #include "MagicDoc.h"
19 #include "MagicView.h"
20 #include "MainFrm.h"
21 #include "MaterialDialog.h"
23 #include "TextureMapDialog.h"
24 #include "Editor.h"
25 #include "Grid.h"
26 #include "GridProps.h"
27 #include "Selection.h"
28 #include "Selector.h"
29 #include "UVMapView.h"
30 
31 #include "ActiveWindow.h"
32 #include "Color.h"
33 #include "Layout.h"
34 #include "Light.h"
35 #include "Scene.h"
36 #include "Screen.h"
37 #include "Shadow.h"
38 #include "Solid.h"
39 #include "Video.h"
40 #include "VideoDX9.h"
41 #include "VideoSettings.h"
42 
43 #include "ModelView.h"
44 
45 DWORD GetRealTime();
46 
47 #ifdef _DEBUG
48 #define new DEBUG_NEW
49 #undef THIS_FILE
50 static char THIS_FILE[] = __FILE__;
51 #endif
52 
53 extern PALETTEENTRY standard_palette[256];
54 extern BYTE inverse_palette[32768];
55 
56 // +--------------------------------------------------------------------+
57 
58 IMPLEMENT_DYNCREATE(MagicView, CView)
59 
60 BEGIN_MESSAGE_MAP(MagicView, CView)
61  //{{AFX_MSG_MAP(MagicView)
62  ON_WM_SIZE()
63  ON_COMMAND(ID_VIEW_RENDER, OnRender)
64  ON_WM_PAINT()
65  ON_COMMAND(ID_VIEW_ALL, OnViewAll)
66  ON_UPDATE_COMMAND_UI(ID_VIEW_ALL, OnUpdateViewAll)
67  ON_COMMAND(ID_VIEW_FRONT, OnViewFront)
68  ON_UPDATE_COMMAND_UI(ID_VIEW_FRONT, OnUpdateViewFront)
69  ON_COMMAND(ID_VIEW_PERSPECTIVE, OnViewPerspective)
70  ON_UPDATE_COMMAND_UI(ID_VIEW_PERSPECTIVE, OnUpdateViewPerspective)
71  ON_COMMAND(ID_VIEW_SIDE, OnViewSide)
72  ON_UPDATE_COMMAND_UI(ID_VIEW_SIDE, OnUpdateViewSide)
73  ON_COMMAND(ID_VIEW_TOP, OnViewTop)
74  ON_UPDATE_COMMAND_UI(ID_VIEW_TOP, OnUpdateViewTop)
75  ON_COMMAND(ID_MODIFY_TEXTURE_MAP, OnTextureMap)
76  ON_COMMAND(ID_MODIFY_MATERIAL, OnModifyMaterial)
77  ON_WM_LBUTTONDOWN()
78  ON_WM_LBUTTONUP()
79  ON_WM_LBUTTONDBLCLK()
80  ON_WM_RBUTTONDOWN()
81  ON_WM_RBUTTONUP()
82  ON_WM_MOUSEMOVE()
83  ON_WM_MOUSEWHEEL()
84  ON_COMMAND(ID_VIEW_ZOOM_NORMAL, OnViewZoomNormal)
85  ON_COMMAND(ID_VIEW_ZOOM_IN, OnViewZoomIn)
86  ON_COMMAND(ID_VIEW_ZOOM_OUT, OnViewZoomOut)
87  ON_COMMAND(ID_VIEW_MODE_WIREFRAME, OnViewModeWireframe)
88  ON_COMMAND(ID_VIEW_MODE_SOLID, OnViewModeSolid)
89  ON_COMMAND(ID_VIEW_MODE_TEXTURED, OnViewModeTextured)
90  ON_WM_RBUTTONDBLCLK()
91  ON_COMMAND(ID_PROP_GRID, OnGridProperties)
92  ON_COMMAND(ID_GRID_SHOW, OnGridShow)
93  ON_COMMAND(ID_GRID_SNAP, OnGridSnap)
94  ON_UPDATE_COMMAND_UI(ID_GRID_SNAP, OnUpdateGridSnap)
95  ON_COMMAND(ID_VIEW_BACK_COLOR, OnViewBackColor)
96  ON_COMMAND(ID_FILE_IMPORT, OnFileImport)
97  ON_COMMAND(ID_FILE_EXPORT, OnFileExport)
98  ON_COMMAND(ID_EDIT_SELECT_ALL, OnSelectAll)
99  ON_COMMAND(ID_EDIT_SELECT_NONE, OnSelectNone)
100  ON_UPDATE_COMMAND_UI(ID_MODIFY_TEXTURE_MAP, OnUpdateTextureMap)
101  ON_UPDATE_COMMAND_UI(ID_MODIFY_MATERIAL, OnUpdateModifyMaterial)
102  ON_COMMAND(ID_EDIT_SELECT_INVERSE, OnSelectInverse)
103  ON_COMMAND(ID_MODIFY_UV_MAP, OnModifyUVMap)
104  ON_UPDATE_COMMAND_UI(ID_MODIFY_UV_MAP, OnUpdateModifyUVMap)
105  ON_COMMAND(ID_VIEW_SHADOWS, OnViewShadows)
106  ON_UPDATE_COMMAND_UI(ID_VIEW_SHADOWS, OnUpdateViewShadows)
107  ON_COMMAND(ID_VIEW_ANIMATELIGHT, OnViewAnimatelight)
108  ON_UPDATE_COMMAND_UI(ID_VIEW_ANIMATELIGHT, OnUpdateViewAnimatelight)
109  ON_COMMAND(ID_VIEW_BUMPMAPS, OnViewBumpmaps)
110  ON_UPDATE_COMMAND_UI(ID_VIEW_BUMPMAPS, OnUpdateViewBumpmaps)
111  ON_COMMAND(ID_VIEW_VERTEXSHADER, OnViewVertexshader)
112  ON_UPDATE_COMMAND_UI(ID_VIEW_VERTEXSHADER, OnUpdateViewVertexshader)
113  ON_COMMAND(ID_VIEW_PIXELSHADER, OnViewPixelshader)
114  ON_UPDATE_COMMAND_UI(ID_VIEW_PIXELSHADER, OnUpdateViewPixelshader)
115  ON_COMMAND(ID_VIEW_VISIBLESHADOWS, OnViewVisibleshadows)
116  ON_UPDATE_COMMAND_UI(ID_VIEW_VISIBLESHADOWS, OnUpdateViewVisibleshadows)
117  ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
118  ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
119  ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
120  ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)
121  ON_COMMAND(ID_PROP_SURFACE, OnSurfaceProperties)
122  ON_UPDATE_COMMAND_UI(ID_PROP_SURFACE, OnUpdateSurfaceProperties)
123  //}}AFX_MSG_MAP
124  // Standard printing commands
125  ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
126  ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
127  ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
128 END_MESSAGE_MAP()
129 
130 // +--------------------------------------------------------------------+
131 
132 static MagicView* magic_view = 0;
133 
134 MagicView::MagicView()
135  : video(0), video_settings(0), screen(0), scene(0),
136  drag_left(false), drag_right(false), grid(0),
137  main_light(0), back_light(0), view_shadows(true), view_bumpmaps(true),
138  animate_light(false)
139 {
140  window_style = 0;
141  is_minimized = false;
142  is_maximized = false;
143  is_sizing = false;
144  view_mode = VIEW_ALL;
145 
146  main_win = 0;
147  view_win[0] = 0;
148  view_win[1] = 0;
149  view_win[2] = 0;
150  view_win[3] = 0;
151  model_view[0] = 0;
152  model_view[1] = 0;
153  model_view[2] = 0;
154  model_view[3] = 0;
155  uvmap_win = 0;
156 
157  grid = new Grid;
158  magic_view = this;
159 
160  Solid::EnableCollision(false);
161 }
162 
164 {
165  if (grid) {
166  delete grid;
167  }
168 
169  if (scene) {
170  scene->Graphics().clear();
171  delete scene;
172  }
173 
174  if (screen) delete screen;
175  if (video) delete video;
176  if (video_settings) delete video_settings;
177 
178  if (magic_view == this)
179  magic_view = 0;
180 }
181 
183 {
184  return magic_view;
185 }
186 
187 BOOL MagicView::PreCreateWindow(CREATESTRUCT& cs)
188 {
189  return CView::PreCreateWindow(cs);
190 }
191 
192 // +--------------------------------------------------------------------+
193 //
194 // MagicView diagnostics
195 
196 #ifdef _DEBUG
197 void MagicView::AssertValid() const
198 {
199  CView::AssertValid();
200 }
201 
202 void MagicView::Dump(CDumpContext& dc) const
203 {
204  CView::Dump(dc);
205 }
206 
207 MagicDoc* MagicView::GetDocument() // non-debug version is inline
208 {
209  ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(MagicDoc)));
210  return (MagicDoc*)m_pDocument;
211 }
212 #endif //_DEBUG
213 
214 
215 // +--------------------------------------------------------------------+
216 
218 {
221 
222  if (!video_settings)
224 
225  GetClientRect(&client_rect);
226 
227  // Use client area to set video window size
228  int w = client_rect.right - client_rect.left;
229  int h = client_rect.bottom - client_rect.top;
230 
231  video_settings->is_windowed = true;
234 
235  if (!video) {
236  video = new VideoDX9(GetSafeHwnd(), video_settings);
238 
239  if (video) {
241  video->UseXFont("System", 12, false, false);
242 
243  screen = new Screen(video);
244  if (!screen) {
245  ::Print("ERROR: Could not create Screen object.\n");
246  return;
247  }
248 
249  ::Print(" Created screen object (%d x %d).\n", w, h);
250 
252  ::Print(" WARNING: could not set video background color to Black\n");
253 
254  screen->ClearAllFrames(true);
255 
256  ::Print(" Established requested video parameters.\n");
257  ::Print(" ---------------------------------------\n\n");
258 
259  if (!scene) {
260  scene = new Scene;
261 
262  scene->SetAmbient(Color(60,60,60));
263 
264  Point light_pos(3e6, 5e6, 4e6);
265 
266  main_light = new Light(1.0f); //1.25f);
267  main_light->MoveTo(light_pos);
270  main_light->SetShadow(true);
271 
273 
274  back_light = new Light(0.5f);
275  back_light->MoveTo(light_pos * -1);
278 
280 
281  Selection* seln = GetDocument()->GetSelection();
282  Selector* selector = GetDocument()->GetSelector();
283 
284  if (seln && selector) {
285  scene->Graphics().clear();
286  scene->AddGraphic(seln);
287  scene->AddGraphic(selector);
288 
289  selector->UseModel(0);
290  }
291  }
292 
293  int mins[2] = { 0, 0 };
294  float weights[2] = { 1, 1 };
295 
296  main_win = new ActiveWindow(screen, 0, 0, w, h, 100, 0);
297  main_win->UseLayout(2, 2, mins, mins, weights, weights);
299 
301 
302  DWORD view_types[] = {
307  };
308 
309  for (int row = 0; row < 2; row++) {
310  for (int col = 0; col < 2; col++) {
311  int index = 2*row + col;
312 
313  ActiveWindow* win = new ActiveWindow(screen,
314  col*w/2,
315  row*h/2,
316  w/2,
317  h/2,
318  101+index,
320  main_win);
321 
322  win->SetCells(col, row, 1, 1);
323  win->SetCellInsets(Insets(1,1,1,1));
324  win->SetBackColor(Color(160,160,160));
325 
326  ModelView* mv = new ModelView(win, scene, view_types[index]);
327 
328  if (view_types[index] == ModelView::VIEW_PROJECT)
330 
331  mv->UseGrid(grid);
332  win->AddView(mv);
333 
334  view_win[index] = win;
335  model_view[index] = mv;
336  }
337  }
338 
340 
341  uvmap_win = new ActiveWindow(screen, 0, 0, w, h, 110, WIN_BLACK_FRAME, main_win);
344 
345  main_win->DoLayout();
346  }
347 
348  else {
349  ::Print(" Could not establish requested video parameters.\n");
350  ::Print(" -----------------------------------------------\n\n");
351  }
352  }
353 }
354 
355 // +--------------------------------------------------------------------+
356 
357 void
359 {
360  switch (view_mode) {
361  case VIEW_ALL: {
362  for (int row = 0; row < 2; row++) {
363  for (int col = 0; col < 2; col++) {
364  int index = 2*row + col;
365 
366  ActiveWindow* win = view_win[index];
367 
368  win->Show();
369  win->SetCells(col, row, 1, 1);
370  win->SetCellInsets(Insets(1,1,1,1));
371  }
372  }
373 
374  uvmap_win->Hide();
375  uvmap_win->SetCells(0,0,0,0);
376  }
377  break;
378 
379  case VIEW_TOP:
380  case VIEW_SIDE:
381  case VIEW_FRONT:
382  case VIEW_PERSPECTIVE: {
384 
385  for (int i = 0; i < 4; i++) {
386  ActiveWindow* win = view_win[i];
387 
388  if (i == view_mode) {
389  win->Show();
390  win->SetCells(0,0,2,2);
392  }
393 
394  else {
395  win->Hide();
396  win->SetCells(0,0,0,0);
398  }
399  }
400 
401  uvmap_win->Hide();
402  uvmap_win->SetCells(0,0,0,0);
403  }
404  break;
405 
406  case VIEW_UV_MAP: {
408 
409  for (int i = 0; i < 4; i++) {
410  ActiveWindow* win = view_win[i];
411  win->Hide();
412  win->SetCells(0,0,0,0);
414  }
415 
416  uvmap_win->Show();
417  uvmap_win->SetCells(0,0,2,2);
418  }
419  break;
420 
421  default:
422  break;
423  }
424 
425  main_win->DoLayout();
426 }
427 
428 void
430 {
431  if (view_mode == VIEW_ALL) {
432  view_focus = f;
433 
434  for (int row = 0; row < 2; row++) {
435  for (int col = 0; col < 2; col++) {
436  int index = 2*row + col;
437 
438  ActiveWindow* win = view_win[index];
439 
440  win->Show();
441  win->SetCells(col, row, 1, 1);
442  win->SetCellInsets(Insets(1,1,1,1));
443 
444  if (index == view_focus) {
446  }
447  else {
449  }
450  }
451  }
452  }
453  else if (IsUVEdit()) {
455  }
456  else {
457  view_mode = f;
458  view_focus = f;
459 
460  for (int i = 0; i < 4; i++) {
461  ActiveWindow* win = view_win[i];
462 
463  if (i == view_mode) {
464  win->Show();
465  win->SetCells(0,0,2,2);
467  }
468 
469  else {
470  win->Hide();
471  win->SetCells(0,0,0,0);
473  }
474  }
475  }
476 
477  main_win->DoLayout();
478 }
479 
480 int
482 {
483  if (view_mode == VIEW_ALL) {
484  for (int row = 0; row < 2; row++) {
485  for (int col = 0; col < 2; col++) {
486  int index = 2*row + col;
487 
488  ActiveWindow* win = view_win[index];
489  if (win->GetRect().Contains(x, y))
490  return index;
491  }
492  }
493  }
494 
495  return view_mode;
496 }
497 
498 ModelView*
500 {
501  if (index >= 0 && index < 4) {
502  return model_view[index];
503  }
504 
505  return model_view[0];
506 }
507 
508 // +--------------------------------------------------------------------+
509 
511 {
512  ValidateRect(0);
513  OnRender();
514 }
515 
516 void MagicView::OnDraw(CDC* dc)
517 {
518 }
519 
520 // +--------------------------------------------------------------------+
521 
523 {
524  if (!video || !video_settings) return;
525 
526  HRESULT hr = S_OK;
527  RECT client_old;
528 
529  client_old = client_rect;
530 
531  // Update window properties
532  GetClientRect(&client_rect);
533 
534  if (client_old.right - client_old.left !=
535  client_rect.right - client_rect.left ||
536  client_old.bottom - client_old.top !=
537  client_rect.bottom - client_rect.top) {
538 
539  // A new window size will require a new backbuffer
540  // size, so the 3D structures must be changed accordingly.
541 
542  video_settings->is_windowed = true;
545 
546  ::Print("ResizeVideo() %d x %d\n", video_settings->window_width, video_settings->window_height);
547 
548  if (video) {
550  }
551  }
552 
553  // save a copy of the device-specific video settings:
554  if (video->GetVideoSettings()) {
556  }
557 
558  if (screen)
561 
565 }
566 
567 // +--------------------------------------------------------------------+
568 
569 void MagicView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
570 {
571  CView::OnUpdate(pSender, lHint, pHint);
572 
573  Solid* solid = GetDocument()->GetSolid();
574  Selection* seln = GetDocument()->GetSelection();
575  Selector* selector = GetDocument()->GetSelector();
576 
577  if (solid && scene) {
578  scene->Graphics().clear();
579  scene->AddGraphic(solid);
580  scene->AddGraphic(seln);
581  scene->AddGraphic(selector);
582  }
583 
584  if (selector)
585  selector->UseModel(solid->GetModel());
586 }
587 
588 CPoint
589 MagicView::LPtoWP(const CPoint& p)
590 {
591  CPoint result;
593  CPoint origin = view->ProjectPoint(Vec3(0,0,0));
594  double scale = view->GetFieldOfView() / 2;
595 
596  result.x = (LONG) (( p.x - origin.x) / scale);
597  result.y = (LONG) ((-p.y + origin.y) / scale);
598 
599  return result;
600 }
601 
602 // +--------------------------------------------------------------------+
603 //
604 // MagicView message handlers
605 
607 {
608  is_sizing = true;
609 }
610 
612 {
613  is_sizing = false;
614  ResizeVideo();
615 }
616 
617 void MagicView::OnSize(UINT nType, int cx, int cy)
618 {
619  CView::OnSize(nType, cx, cy);
620 
621  window_style = GetWindowLong(m_hWnd, GWL_STYLE);
622 
623  if (nType == SIZE_MINIMIZED) {
624  is_minimized = true;
625  is_maximized = false;
626  }
627 
628  else if (nType == SIZE_MAXIMIZED) {
629  is_minimized = false;
630  is_maximized = true;
631  ResizeVideo();
632  }
633 
634  else if (nType == SIZE_RESTORED) {
635  if (is_maximized) {
636  is_maximized = false;
637  ResizeVideo();
638  }
639 
640  else if (is_minimized) {
641  is_minimized = false;
642  ResizeVideo();
643  }
644  else if (!is_sizing) {
645  // if this is not a resize due to dragging...
646  ResizeVideo();
647  }
648  else {
649  // If we're neither maximized nor minimized, the window size
650  // is changing by the user dragging the window edges. In this
651  // case, we don't reset the device yet -- we wait until the
652  // user stops dragging, and a WM_EXITSIZEMOVE message comes.
653  }
654  }
655 }
656 
657 // +--------------------------------------------------------------------+
658 
660 {
661  if (!screen || !video)
662  return;
663 
664  double s = sin(timeGetTime() * 0.001);
665  double c = cos(timeGetTime() * 0.001);
666 
667  // IF LIGHTS ANIMATED:
668  if (animate_light) {
669  Point light_pos(3e6*s, 5e6*c, 4e6*s);
670 
671  if (main_light) {
673  main_light->MoveTo(light_pos);
675  }
676 
677  if (back_light) {
679  back_light->MoveTo(light_pos * -1);
681  }
682  }
683 
684  if (screen->Refresh()) {
685  video->Present();
686  }
687  else {
688  ::Print("ERROR: Screen refresh failed.\n");
689  }
690 }
691 
693 {
694  if (IsUVEdit()) {
695  MagicDoc* doc = GetDocument();
696  Editor* editor = doc->GetEditor();
697  Solid* solid = doc->GetSolid();
698 
699  if (editor && solid) {
700  editor->UseModel(solid->GetModel());
701  editor->Resegment();
702  }
703  }
704 }
705 
706 // +--------------------------------------------------------------------+
707 
709 {
710  CloseUVEditor();
712  SetupModelViews();
713 }
714 
715 void MagicView::OnUpdateViewAll(CCmdUI* pCmdUI)
716 {
717  if (pCmdUI)
718  pCmdUI->SetCheck(view_mode == VIEW_ALL);
719 }
720 
722 {
723  CloseUVEditor();
725  SetupModelViews();
726 }
727 
728 void MagicView::OnUpdateViewFront(CCmdUI* pCmdUI)
729 {
730  if (pCmdUI)
731  pCmdUI->SetCheck(view_mode == VIEW_FRONT);
732 }
733 
735 {
736  CloseUVEditor();
738  SetupModelViews();
739 }
740 
742 {
743  if (pCmdUI)
744  pCmdUI->SetCheck(view_mode == VIEW_PERSPECTIVE);
745 }
746 
748 {
749  CloseUVEditor();
751  SetupModelViews();
752 }
753 
754 void MagicView::OnUpdateViewSide(CCmdUI* pCmdUI)
755 {
756  if (pCmdUI)
757  pCmdUI->SetCheck(view_mode == VIEW_SIDE);
758 }
759 
761 {
762  CloseUVEditor();
764  SetupModelViews();
765 }
766 
767 void MagicView::OnUpdateViewTop(CCmdUI* pCmdUI)
768 {
769  if (pCmdUI)
770  pCmdUI->SetCheck(view_mode == VIEW_TOP);
771 }
772 
773 // +--------------------------------------------------------------------+
774 
776 {
777  DWORD err = 0;
778  char filename[256];
779  filename[0] = '\0';
780  CFileDialog ofd(TRUE, "mag");
781 
782  ofd.m_ofn.lpstrFilter = "All 3D Files\0*.mag; *.obj; *.3ds\0Magic Files (*.mag)\0*.mag\0Wavefront/OBJ Files (*.obj)\0*.obj\0003DS MAX Files (*.3ds)\0*.3ds\0\0";
783  ofd.m_ofn.lpstrFile = filename;
784  ofd.m_ofn.nMaxFile = sizeof(filename);
785 
786  if (ofd.DoModal() != IDOK)
787  return;
788 
789  char mag_name[256];
790  sprintf_s(mag_name, "%s", ofd.GetFileName().GetBuffer(0));
791 
792  MagicDoc* pDoc = GetDocument();
793  ASSERT_VALID(pDoc);
794 
795  if (pDoc->ImportFile(mag_name)) {
796  Invalidate();
797  pDoc->SetModifiedFlag(TRUE);
798  pDoc->UpdateAllViews(this);
799  }
800 }
801 
803 {
804  DWORD err = 0;
805  char filename[256];
806  filename[0] = '\0';
807  CFileDialog ofd(FALSE, "mag");
808 
809  ofd.m_ofn.lpstrFilter = "All 3D Files\0*.mag; *.obj; *.3ds\0Magic Files (*.mag)\0*.mag\0Wavefront/OBJ Files (*.obj)\0*.obj\0003DS MAX Files (*.3ds)\0*.3ds\0\0";
810  ofd.m_ofn.lpstrFile = filename;
811  ofd.m_ofn.nMaxFile = sizeof(filename);
812 
813  if (ofd.DoModal() != IDOK)
814  return;
815 
816  char mag_name[256];
817  sprintf_s(mag_name, "%s", ofd.GetFileName().GetBuffer(0));
818 
819  MagicDoc* pDoc = GetDocument();
820  ASSERT_VALID(pDoc);
821 
822  if (pDoc->ExportFile(mag_name)) {
823  pDoc->SetModifiedFlag(FALSE);
824  pDoc->UpdateAllViews(this);
825  }
826 }
827 
828 // +--------------------------------------------------------------------+
829 
831 {
832  SurfacePropertiesDialog dlg(this);
833  dlg.DoModal();
834 }
835 
837 {
838  Solid* solid = GetDocument()->GetSolid();
839  pCmdUI->Enable(solid && solid->GetModel());
840 }
841 
842 // +--------------------------------------------------------------------+
843 
845 {
846  TextureMapDialog dlg(this);
847  if (dlg.DoModal() == IDOK) {
848  MagicDoc* doc = GetDocument();
849  Solid* solid = doc->GetSolid();
850  Selection* seln = doc->GetSelection();
851  Selector* selector = doc->GetSelector();
852  Editor* editor = doc->GetEditor();
853  Material* mtl = 0;
854 
855  if (dlg.mMaterialIndex >= 0) {
856  mtl = solid->GetModel()->GetMaterials()[dlg.mMaterialIndex];
857  }
858 
859  editor->UseModel(solid->GetModel());
860  editor->ApplyMaterial(mtl, seln->GetPolys(),
861  dlg.mMapType, 2-dlg.mAxis, (float) dlg.mScaleU, (float) dlg.mScaleV,
862  dlg.mFlip, dlg.mMirror, dlg.mRotate);
863 
864  selector->Reselect();
865 
866  Invalidate();
867  doc->SetModifiedFlag(TRUE);
868  doc->UpdateAllViews(this);
869  }
870 }
871 
872 void MagicView::OnUpdateTextureMap(CCmdUI* pCmdUI)
873 {
874  Solid* solid = GetDocument()->GetSolid();
875  Selection* seln = GetDocument()->GetSelection();
876 
877  pCmdUI->Enable(solid && solid->GetModel() && seln && seln->GetPolys().size() > 0);
878 }
879 
881 {
882  MaterialDialog dlg(this);
883  dlg.DoModal();
884 
885  Invalidate();
886  GetDocument()->SetModifiedFlag(TRUE);
887  GetDocument()->UpdateAllViews(this);
888 }
889 
891 {
892  Solid* solid = GetDocument()->GetSolid();
893  pCmdUI->Enable(solid && solid->GetModel());
894 }
895 
897 {
898  Selection* seln = GetDocument()->GetSelection();
899 
901  SetupModelViews();
902 
903  if (seln && uvmap_view) {
904  Poly* p = seln->GetPolys().first();
905 
906  if (p) {
908  uvmap_view->UsePolys(seln->GetPolys());
909  }
910  }
911 }
912 
913 void MagicView::OnUpdateModifyUVMap(CCmdUI* pCmdUI)
914 {
915  OnUpdateTextureMap(pCmdUI);
916 }
917 
918 // +--------------------------------------------------------------------+
919 
921 {
922  GridProps dlg(grid, this);
923  dlg.DoModal();
924 }
925 
927 {
928  if (grid)
929  grid->SetShow(!grid->IsShow());
930 }
931 
933 {
934  if (grid)
935  grid->SetSnap(!grid->IsSnap());
936 }
937 
938 void MagicView::OnUpdateGridSnap(CCmdUI* pCmdUI)
939 {
940  if (grid)
941  pCmdUI->SetCheck(grid->IsSnap());
942 }
943 
944 // +--------------------------------------------------------------------+
945 
946 void MagicView::OnLButtonDown(UINT nFlags, CPoint point)
947 {
948  CView::OnLButtonDown(nFlags, point);
949  SetCapture();
950 
951  // set focus to the view that was clicked:
952  int index = GetWinIndexByPoint(point.x, point.y);
953  SetFocusModelView(index);
954 
955  drag_start = point;
956  drag_left = true;
957  drag_right = false;
958 
959  ModelView* mv = GetModelViewByIndex(index);
960  MagicDoc* pDoc = GetDocument();
961  Model* model = pDoc->GetSolid()->GetModel();
962  Selector* selector = pDoc->GetSelector();
963 
964  if (IsUVEdit()) {
965  int select_mode = UVMapView::SELECT_APPEND;
966 
967  if (nFlags & MK_CONTROL)
968  select_mode = UVMapView::SELECT_REMOVE;
969 
970  if (!uvmap_view->WillSelect(point)) {
971  uvmap_view->Begin(select_mode);
972  uvmap_view->AddMark(point);
973  }
974  }
975 
976  else if (mv && selector) {
977  int select_mode = Selector::SELECT_APPEND;
978 
979  if (nFlags & MK_CONTROL)
980  select_mode = Selector::SELECT_REMOVE;
981 
982  selector->Begin(model, mv->GetViewMode(), select_mode);
983  selector->AddMark(point);
984  }
985 }
986 
987 void MagicView::OnLButtonUp(UINT nFlags, CPoint point)
988 {
989  CView::OnLButtonUp(nFlags, point);
990  ReleaseCapture();
991 
992  drag_left = false;
993 
994  MagicDoc* pDoc = GetDocument();
995  Selector* selector = pDoc->GetSelector();
996 
997  if (IsUVEdit())
998  uvmap_view->End();
999 
1000  else if (selector && selector->IsActive())
1001  selector->End();
1002 }
1003 
1004 void MagicView::OnLButtonDblClk(UINT nFlags, CPoint point)
1005 {
1006  CView::OnLButtonDblClk(nFlags, point);
1007 
1008  drag_left = false;
1009 
1010  MagicDoc* pDoc = GetDocument();
1011  Selector* selector = pDoc->GetSelector();
1012 
1013  if (IsUVEdit())
1014  uvmap_view->Clear();
1015 
1016  else if (selector)
1017  selector->Clear();
1018 }
1019 
1020 void MagicView::OnRButtonDown(UINT nFlags, CPoint point)
1021 {
1022  CView::OnRButtonDown(nFlags, point);
1023  SetCapture();
1024 
1025  // set focus to the view that was clicked:
1026  int index = GetWinIndexByPoint(point.x, point.y);
1027  SetFocusModelView(index);
1028 
1029  drag_start = point;
1030  drag_left = false;
1031  drag_right = true;
1032 }
1033 
1034 void MagicView::OnRButtonUp(UINT nFlags, CPoint point)
1035 {
1036  CView::OnRButtonUp(nFlags, point);
1037  ReleaseCapture();
1038 
1039  drag_right = false;
1040 }
1041 
1042 void MagicView::OnRButtonDblClk(UINT nFlags, CPoint point)
1043 {
1044  CView::OnRButtonDblClk(nFlags, point);
1045  ReleaseCapture();
1046 
1047  drag_right = false;
1048 
1049  if (view_mode == VIEW_ALL) {
1051  }
1052  else if (IsUVEdit()) {
1053  CloseUVEditor();
1054  view_mode = VIEW_ALL;
1055  SetupModelViews();
1056  }
1057  else {
1058  view_mode = VIEW_ALL;
1059  }
1060 
1062 }
1063 
1064 void MagicView::OnMouseMove(UINT nFlags, CPoint point)
1065 {
1066  if (drag_right) {
1067  CPoint offset = point - drag_start;
1068 
1069  if (view_focus == VIEW_PERSPECTIVE) {
1071  view->SpinBy(offset.x * 0.5 * DEGREES,
1072  offset.y * 0.5 * DEGREES);
1073  }
1074 
1075  else if (IsUVEdit()) {
1076  uvmap_view->MoveBy(offset.x, offset.y);
1077  }
1078 
1079  else {
1081  view->MoveBy(offset.x, offset.y);
1082  }
1083 
1084  drag_start = point;
1085  Invalidate();
1086  }
1087 
1088  else if (drag_left) {
1089  CPoint offset = point - drag_start;
1090  MagicDoc* pDoc = GetDocument();
1091  Selector* selector = pDoc->GetSelector();
1092 
1093  if (IsUVEdit()) {
1094  if (uvmap_view->IsActive()) {
1095  uvmap_view->AddMark(point);
1096  }
1097  else {
1098  uvmap_view->DragBy(offset.x, offset.y);
1099  drag_start = point;
1100  }
1101  }
1102 
1103  else if (selector && selector->IsActive()) {
1104  selector->AddMark(point);
1105  }
1106  }
1107 
1108  // xy status message:
1109  if (view_focus != VIEW_PERSPECTIVE) {
1110  char xy[80];
1111  CPoint mouse = LPtoWP(point);
1112  Selection* seln = GetDocument()->GetSelection();
1113 
1114  int nv = seln ? seln->GetVerts().size() : 0;
1115  int np = seln ? seln->GetPolys().size() : 0;
1116 
1117  if (np || nv)
1118  sprintf_s(xy, "(%05d,%05d) Verts:%d Polys:%d", mouse.x, mouse.y, nv, np);
1119  else
1120  sprintf_s(xy, "(%05d,%05d)", mouse.x, mouse.y);
1121  MainFrame::StatusXY(xy);
1122  }
1123 
1124  CView::OnMouseMove(nFlags, point);
1125 }
1126 
1127 BOOL MagicView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
1128 {
1129  if (view_focus == VIEW_PERSPECTIVE) {
1131 
1132  if (view) {
1133  Camera* cam = view->GetCamera();
1134  Point pos = cam->Pos();
1135  double len = pos.length();
1136 
1137  if (zDelta < 0) {
1138  if (len < 10000)
1139  pos *= 1.15;
1140  }
1141  else {
1142  if (len > 0.10)
1143  pos *= 0.85;
1144  }
1145 
1146  cam->MoveTo(pos);
1147  }
1148  }
1149 
1150  else if (IsUVEdit()) {
1151  if (zDelta < 0) {
1152  uvmap_view->ZoomOut();
1153  }
1154  else {
1155  uvmap_view->ZoomIn();
1156  }
1157  }
1158 
1159  else {
1160  if (zDelta > 0)
1161  OnViewZoomIn();
1162  else
1163  OnViewZoomOut();
1164  }
1165 
1166  return 0;
1167 }
1168 
1169 // +--------------------------------------------------------------------+
1170 
1172 {
1173  for (int i = 0; i < 4; i++) {
1174  ModelView* view = GetModelViewByIndex(i);
1175 
1176  if (view) {
1177  view->ZoomNormal();
1178  }
1179  }
1180 }
1181 
1183 {
1184  for (int i = 0; i < 4; i++) {
1185  ModelView* view = GetModelViewByIndex(i);
1186 
1187  if (view && view->GetViewMode() != ModelView::VIEW_PROJECT) {
1188  double fov = view->GetFieldOfView() * 1.15;
1189  view->SetFieldOfView(fov);
1190  }
1191  }
1192 }
1193 
1195 {
1196  for (int i = 0; i < 4; i++) {
1197  ModelView* view = GetModelViewByIndex(i);
1198 
1199  if (view && view->GetViewMode() != ModelView::VIEW_PROJECT) {
1200  double fov = view->GetFieldOfView() * 0.85;
1201  view->SetFieldOfView(fov);
1202  }
1203  }
1204 }
1205 
1206 // +--------------------------------------------------------------------+
1207 
1209 {
1211 
1212  if (view) {
1214  }
1215 }
1216 
1218 {
1220 
1221  if (view) {
1223  }
1224 }
1225 
1227 {
1229 
1230  if (view) {
1232  }
1233 }
1234 
1236 {
1238 
1239  if (view) {
1240  ActiveWindow* win = (ActiveWindow*) view->GetWindow();
1241  Color c = win->GetBackColor();
1242  COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
1243  CColorDialog chooser(crgb);
1244 
1245  if (chooser.DoModal() == IDOK) {
1246  crgb = chooser.GetColor();
1247  win->SetBackColor( Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb)) );
1248  }
1249  }
1250 }
1251 
1252 // +--------------------------------------------------------------------+
1253 
1255 {
1256  Solid* solid = GetDocument()->GetSolid();
1257  Selector* selector = GetDocument()->GetSelector();
1258 
1259  if (IsUVEdit()) {
1260  uvmap_view->SelectAll();
1261  }
1262 
1263  else if (solid && selector) {
1264  selector->UseModel(solid->GetModel());
1266  }
1267 }
1268 
1270 {
1271  Solid* solid = GetDocument()->GetSolid();
1272  Selector* selector = GetDocument()->GetSelector();
1273 
1274  if (IsUVEdit()) {
1276  }
1277 
1278  else if (solid && selector) {
1279  selector->UseModel(solid->GetModel());
1281  }
1282 }
1283 
1285 {
1286  Solid* solid = GetDocument()->GetSolid();
1287  Selector* selector = GetDocument()->GetSelector();
1288 
1289  if (IsUVEdit()) {
1291  }
1292 
1293  else if (solid && selector) {
1294  selector->UseModel(solid->GetModel());
1295  selector->SelectInverse();
1296  }
1297 }
1298 
1300 {
1302 
1303  if (video)
1305 }
1306 
1307 void MagicView::OnUpdateViewShadows(CCmdUI* pCmdUI)
1308 {
1309  pCmdUI->SetCheck(view_shadows);
1310 }
1311 
1313 {
1315 }
1316 
1318 {
1319  pCmdUI->SetCheck(animate_light);
1320 }
1321 
1323 {
1325 
1326  if (video)
1328 }
1329 
1330 void MagicView::OnUpdateViewBumpmaps(CCmdUI* pCmdUI)
1331 {
1332  pCmdUI->SetCheck(view_bumpmaps);
1333 }
1334 
1336 {
1337  if (video) {
1339  vs->enable_vs = !vs->enable_vs;
1340  }
1341 }
1342 
1344 {
1345  if (video)
1346  pCmdUI->SetCheck(video->GetVideoSettings()->enable_vs);
1347 }
1348 
1350 {
1351  if (video) {
1353  vs->enable_ps = !vs->enable_ps;
1354  }
1355 }
1356 
1358 {
1359  if (video)
1360  pCmdUI->SetCheck(video->GetVideoSettings()->enable_ps);
1361 }
1362 
1364 {
1366 }
1367 
1369 {
1370  pCmdUI->SetCheck(Shadow::GetVisibleShadowVolumes());
1371 }
1372 
1374 {
1375  MagicDoc* pDoc = GetDocument();
1376  ASSERT_VALID(pDoc);
1377  pDoc->Undo();
1378 
1379  Solid* solid = GetDocument()->GetSolid();
1380  Selector* selector = GetDocument()->GetSelector();
1381 
1382  if (selector) {
1383  selector->UseModel(solid->GetModel());
1384  selector->Reselect();
1385  }
1386 
1387  Invalidate();
1388  pDoc->SetModifiedFlag(TRUE);
1389  pDoc->UpdateAllViews(this);
1390 }
1391 
1392 void MagicView::OnUpdateEditUndo(CCmdUI* pCmdUI)
1393 {
1394  MagicDoc* pDoc = GetDocument();
1395 
1396  if (pDoc->NumUndo() > 0) {
1397  pCmdUI->Enable(TRUE);
1398  pCmdUI->SetText(CString("Undo ") + pDoc->GetUndoName() + CString("\tCtrl+Z"));
1399  }
1400  else {
1401  pCmdUI->Enable(FALSE);
1402  pCmdUI->SetText("Can't Undo\tCtrl+Z");
1403  }
1404 }
1405 
1407 {
1408  MagicDoc* pDoc = GetDocument();
1409  ASSERT_VALID(pDoc);
1410  pDoc->Redo();
1411 
1412  Solid* solid = GetDocument()->GetSolid();
1413  Selector* selector = GetDocument()->GetSelector();
1414 
1415  if (selector) {
1416  selector->UseModel(solid->GetModel());
1417  selector->Reselect();
1418  }
1419 
1420  Invalidate();
1421  pDoc->SetModifiedFlag(TRUE);
1422  pDoc->UpdateAllViews(this);
1423 }
1424 
1425 void MagicView::OnUpdateEditRedo(CCmdUI* pCmdUI)
1426 {
1427  MagicDoc* pDoc = GetDocument();
1428 
1429  if (pDoc->NumRedo() > 0) {
1430  pCmdUI->Enable(TRUE);
1431  pCmdUI->SetText(CString("Redo ") + pDoc->GetRedoName() + CString("\tCtrl+Y"));
1432  }
1433  else {
1434  pCmdUI->Enable(FALSE);
1435  pCmdUI->SetText("Can't Redo");
1436  }
1437 }