Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ModelView.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: ModelView.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Implementation of the ModelView class
13 */
14 
15 #include "stdafx.h"
16 #include "Magic.h"
17 
18 #include "MagicDoc.h"
19 #include "ModelView.h"
20 #include "Grid.h"
21 #include "Selector.h"
22 #include "Selection.h"
23 
24 #include "ActiveWindow.h"
25 #include "Color.h"
26 #include "Light.h"
27 #include "Scene.h"
28 #include "Screen.h"
29 #include "Shadow.h"
30 #include "Solid.h"
31 #include "Video.h"
32 
33 DWORD GetRealTime();
34 
35 #ifdef _DEBUG
36 #define new DEBUG_NEW
37 #undef THIS_FILE
38 static char THIS_FILE[] = __FILE__;
39 #endif
40 
41 static ModelView* views[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
42 
43 // +--------------------------------------------------------------------+
44 
46  : CameraView(c, 0, s), view_mode(100), fill_mode(FILL_WIRE),
47  grid(0), az(-PI/4), el(PI/4)
48 {
49  UseCamera(&cam);
50  SetViewMode(m);
51 }
52 
54 {
55  if (views[view_mode] == this)
56  views[view_mode] = 0;
57 }
58 
59 // +--------------------------------------------------------------------+
60 
61 void
63 {
64  if (view_mode != m) {
65  view_mode = m;
66 
67  double x = 1e3 * sin(az) * cos(el);
68  double y = 1e3 * cos(az) * cos(el);
69  double z = 1e3 * sin(el);
70 
71  switch (view_mode) {
72  case VIEW_PLAN:
73  cam.LookAt(Point(0,0,0),
74  Point(0,1e3,0),
75  Point(0,0,1));
77  SetFieldOfView(1.75);
78  break;
79 
80  case VIEW_FRONT:
81  cam.LookAt(Point(0,0,0),
82  Point(0,0,1e3),
83  Point(0,1,0));
85  SetFieldOfView(1.75);
86  break;
87 
88  case VIEW_SIDE:
89  cam.LookAt(Point(0,0,0),
90  Point(1e3,0,0),
91  Point(0,1,0));
93  SetFieldOfView(1.75);
94  break;
95 
96  case VIEW_PROJECT:
97  cam.LookAt(Point(0,0,0),
98  Point(x,z,y),
99  Point(0,1,0));
101  SetFieldOfView(1.75);
102  break;
103  }
104 
105  views[view_mode] = this;
106  }
107 }
108 
109 ModelView*
111 {
112  if (mode >= 0 && mode < 8)
113  return views[mode];
114 
115  return 0;
116 }
117 
118 // +--------------------------------------------------------------------+
119 
120 void
122 {
123  switch (view_mode) {
124  case VIEW_PLAN:
125  cam.LookAt( pos - Point(0,1e3,0),
126  pos,
127  Point(0,0,1));
128  break;
129 
130  case VIEW_FRONT:
131  cam.LookAt( pos - Point(0,0,1e3),
132  pos,
133  Point(0,1,0));
134  break;
135 
136  case VIEW_SIDE:
137  cam.LookAt( pos - Point(1e3,0,0),
138  pos,
139  Point(0,1,0));
140  break;
141  }
142 }
143 
144 void
145 ModelView::MoveBy(double dx, double dy)
146 {
147  Point pos = cam.Pos();
148 
149  dx *= 2.00/GetFieldOfView();
150  dy *= 2.00/GetFieldOfView();
151 
152  switch (view_mode) {
153  case VIEW_PLAN:
154  pos.x -= dx;
155  pos.z += dy;
156 
157  cam.LookAt( pos - Point(0,1e3,0),
158  pos,
159  Point(0,0,1));
160  break;
161 
162  case VIEW_FRONT:
163  pos.x += dx;
164  pos.y += dy;
165 
166  cam.LookAt( pos - Point(0,0,1e3),
167  pos,
168  Point(0,1,0));
169  break;
170 
171  case VIEW_SIDE:
172  pos.z -= dx;
173  pos.y += dy;
174 
175  cam.LookAt( pos - Point(1e3,0,0),
176  pos,
177  Point(0,1,0));
178  break;
179  }
180 }
181 
182 void
183 ModelView::SpinBy(double phi, double theta)
184 {
185  const double limit = (0.43 * PI);
186 
187  Point pos = cam.Pos();
188  double len = pos.length();
189 
190  az += phi;
191  el += theta;
192 
193  if (az > PI)
194  az = -2*PI + az;
195 
196  else if (az < -PI)
197  az = 2*PI + az;
198 
199  if (el > limit)
200  el = limit;
201  else if (el < -limit)
202  el = -limit;
203 
204  double x = len * sin(az) * cos(el);
205  double y = len * cos(az) * cos(el);
206  double z = len * sin(el);
207 
208  cam.LookAt(Point(0,0,0), Point(x,z,y), Point(0,1,0));
209 }
210 
211 void
213 {
214  grid = g;
215 }
216 
217 void
219 {
220  DWORD v = view_mode; // remember current view mode
221  view_mode = 100; // force set view mode to setup the view
222  az = -PI/4; // if this happens to be a perspective view,
223  el = PI/4; // reset the spin to the original 3/4ths view
224 
225  SetViewMode(v); // restore default view params for this mode
226 }
227 
228 // +--------------------------------------------------------------------+
229 
230 void
232 {
233  // activate all lights:
234  ListIter<Light> light_iter = scene->Lights();
235 
236  while (++light_iter) {
237  Light* light = light_iter.value();
238  light->SetActive(true);
239  }
240 
242 
243  RenderGrid();
244 
245 
246  bool old_shadows = video->IsShadowEnabled();
247  bool old_bumps = video->IsBumpMapEnabled();
248 
249  if (fill_mode != FILL_TEXTURE) {
250  video->SetShadowEnabled(false);
251  video->SetBumpMapEnabled(false);
253  }
254 
255  else {
257  }
258 
259  const char* title = "ModelView";
260  switch (view_mode) {
261  case VIEW_PLAN: title = "Top"; break;
262  case VIEW_FRONT: title = "Front"; break;
263  case VIEW_SIDE: title = "Right Side"; break;
264  case VIEW_PROJECT: title = "Perspective"; break;
265  }
266 
267  int len = strlen(title);
268  Rect r(6,4,200,20);
269 
270  r.x += window->GetRect().x;
271  r.y += window->GetRect().y;
272 
273  video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::Black);
274 
275  r.x--;
276  r.y--;
277 
278  video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::White);
279  video->SetShadowEnabled(old_shadows);
280  video->SetBumpMapEnabled(old_bumps);
281 }
282 
283 // +--------------------------------------------------------------------+
284 
285 void
286 ModelView::Render(Graphic* g, DWORD flags)
287 {
288  if (!g)
289  return;
290 
291  if (!strcmp(g->Name(), "Selector")) {
292  Selector* selector = (Selector*) g;
293 
294  if (selector->GetViewMode() != (int) view_mode)
295  return;
296  }
297 
298  else if (!strcmp(g->Name(), "Selection")) {
299  Selection* selection = (Selection*) g;
300  selection->UseView(this);
301  }
302 
303  if (fill_mode == FILL_WIRE) {
304  Material m;
305  video->UseMaterial(&m);
307 
308  if (g->IsSolid()) {
309  m.Kd = ColorValue(0.0f, 0.0f, 0.0f, 0.5f);
310  m.Ke = ColorValue(0.8f, 0.8f, 0.9f, 1.0f);
312  m.luminous = true;
313 
315  g->Render(video, flags);
316  }
317 
318  m.Ka = Color::Black;
319  m.Kd = Color::Black;
320  m.Ks = Color::Black;
321  m.Ke = Color::Black;
323 
325 
326  g->Render(video, flags);
327  video->UseMaterial(0);
328  }
329 
330  else if (fill_mode == FILL_SOLID) {
331  if (g->IsSolid() && flags != Graphic::RENDER_SOLID)
332  return;
333 
334  Material m;
335  video->UseMaterial(&m);
337 
338  m.Kd = ColorValue(0.5f, 0.5f, 0.5f, 1.0f);
340 
342 
343  if (g->IsSolid()) {
344  MarkVisibleLights(g, flags);
346  }
347 
348  g->Render(video, flags);
349  video->UseMaterial(0);
350  }
351 
352  else if (fill_mode == FILL_TEXTURE) {
354  video->UseMaterial(0);
355 
356  if (g->IsSolid()) {
357  MarkVisibleLights(g, flags);
359  }
360 
361  g->Render(video, flags);
362  }
363 }
364 
365 void
367 {
368  if (!grid || !grid->IsShow())
369  return;
370 
371  int plane = Grid::GRID_XZ;
372 
373  if (view_mode == VIEW_FRONT)
374  plane = Grid::GRID_XY;
375 
376  else if (view_mode == VIEW_SIDE)
377  plane = Grid::GRID_YZ;
378 
379  grid->ShowPlane(plane);
380  grid->MoveTo(camera_loc * -1);
383 
386  video->UseMaterial(0);
387 }
388 
389 // +--------------------------------------------------------------------+
390 
391 CPoint
393 {
394  CPoint result;
395 
396  switch (view_mode) {
397  case VIEW_PLAN:
398  case VIEW_FRONT:
399  case VIEW_SIDE:
400  case VIEW_PROJECT: {
401  Vec3 pt = p;
402  projector.Transform(pt);
403  projector.Project(pt, false);
404 
405  result.x = (LONG) (pt.x + GetWindow()->X());
406  result.y = (LONG) (pt.y + GetWindow()->Y());
407  }
408  break;
409 
410  default:
411  result.x = 0;
412  result.y = 0;
413  break;
414  }
415 
416  return result;
417 }