doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CamWnd.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "qe3.h"
33 #include "Radiant.h"
34 #include "XYWnd.h"
35 #include "CamWnd.h"
36 #include "splines.h"
37 #include <GL/glu.h>
38 
39 #include "../../renderer/tr_local.h"
40 #include "../../renderer/model_local.h" // for idRenderModelMD5
41 
42 #ifdef _DEBUG
43  #define new DEBUG_NEW
44  #undef THIS_FILE
45 static char THIS_FILE[] = __FILE__;
46 #endif
47 extern void DrawPathLines();
48 
49 int g_axialAnchor = -1;
50 int g_axialDest = -1;
51 bool g_bAxialMode = false;
52 
54  int faceCount = g_ptrSelectedFaces.GetSize();
55  if (faceCount > 0) {
56  face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(0));
57  if (g_axialAnchor >= selFace->face_winding->GetNumPoints()) {
58  g_axialAnchor = 0;
59  }
60  if (g_axialDest >= selFace->face_winding->GetNumPoints()) {
61  g_axialDest = 0;
62  }
63  } else {
64  g_axialDest = 0;
65  g_axialAnchor = 0;
66  }
67 }
68 
69 // CCamWnd
71 
72 /*
73  =======================================================================================================================
74  =======================================================================================================================
75  */
77  m_pXYFriend = NULL;
78  memset(&m_Camera, 0, sizeof(camera_t));
80  m_bClipMode = false;
81  worldDirty = true;
82  worldModel = NULL;
83  renderMode = false;
84  rebuildMode = false;
85  entityMode = false;
86  animationMode = false;
87  selectMode = false;
88  soundMode = false;
89  saveValid = false;
90  Cam_Init();
91 }
92 
93 /*
94  =======================================================================================================================
95  =======================================================================================================================
96  */
98 }
99 
100 BEGIN_MESSAGE_MAP(CCamWnd, CWnd)
101 //{{AFX_MSG_MAP(CCamWnd)
102  ON_WM_KEYDOWN()
103  ON_WM_PAINT()
104  ON_WM_DESTROY()
105  ON_WM_CLOSE()
106  ON_WM_MOUSEMOVE()
107  ON_WM_LBUTTONDOWN()
108  ON_WM_LBUTTONUP()
109  ON_WM_MBUTTONDOWN()
110  ON_WM_MBUTTONUP()
111  ON_WM_RBUTTONDOWN()
112  ON_WM_RBUTTONUP()
113  ON_WM_CREATE()
114  ON_WM_SIZE()
115  ON_WM_KEYUP()
116  ON_WM_NCCALCSIZE()
117  ON_WM_KILLFOCUS()
118  ON_WM_SETFOCUS()
119  ON_WM_TIMER()
120  //}}AFX_MSG_MAP
121 END_MESSAGE_MAP()
122 /*
123  =======================================================================================================================
124  =======================================================================================================================
125  */
126 LONG WINAPI CamWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
127  RECT rect;
128 
129  GetClientRect(hWnd, &rect);
130 
131  switch (uMsg)
132  {
133  case WM_KILLFOCUS:
134  case WM_SETFOCUS:
135  SendMessage(hWnd, WM_NCACTIVATE, uMsg == WM_SETFOCUS, 0);
136  return 0;
137 
138  case WM_NCCALCSIZE: // don't let windows copy pixels
139  DefWindowProc(hWnd, uMsg, wParam, lParam);
140  return WVR_REDRAW;
141  }
142 
143  return DefWindowProc(hWnd, uMsg, wParam, lParam);
144 }
145 
146 //
147 // =======================================================================================================================
148 // CCamWnd message handlers
149 // =======================================================================================================================
150 //
151 BOOL CCamWnd::PreCreateWindow(CREATESTRUCT &cs) {
152  WNDCLASS wc;
153  HINSTANCE hInstance = AfxGetInstanceHandle();
154  if (::GetClassInfo(hInstance, CAMERA_WINDOW_CLASS, &wc) == FALSE) {
155  // Register a new class
156  memset(&wc, 0, sizeof(wc));
157 
158  // wc.style = CS_NOCLOSE | CS_OWNDC;
159  wc.style = CS_NOCLOSE;
160  wc.lpszClassName = CAMERA_WINDOW_CLASS;
161  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
162  wc.lpfnWndProc = CamWndProc;
163  if (AfxRegisterClass(&wc) == FALSE) {
164  Error("CCamWnd RegisterClass: failed");
165  }
166  }
167 
168  cs.lpszClass = CAMERA_WINDOW_CLASS;
169  cs.lpszName = "CAM";
170  if (cs.style != QE3_CHILDSTYLE) {
171  cs.style = QE3_SPLITTER_STYLE;
172  }
173 
174  BOOL bResult = CWnd::PreCreateWindow(cs);
175 
176  //
177  // See if the class already exists and if not then we need to register our new
178  // window class.
179  //
180  return bResult;
181 }
182 
183 /*
184  =======================================================================================================================
185  =======================================================================================================================
186  */
187 void CCamWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
188  g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags);
189 }
190 
191 brush_t *g_pSplitList = NULL;
192 
193 /*
194  =======================================================================================================================
195  =======================================================================================================================
196  */
198  CPaintDC dc(this); // device context for painting
199  bool bPaint = true;
200 
201  if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) {
202  common->Printf("ERROR: wglMakeCurrent failed..\n ");
203  common->Printf("Please restart " EDITOR_WINDOWTEXT " if the camera view is not working\n");
204  }
205  else {
206  QE_CheckOpenGLForErrors();
207  g_pSplitList = NULL;
208  if (g_bClipMode) {
209  if (g_Clip1.Set() && g_Clip2.Set()) {
211  }
212  }
213 
214  Cam_Draw();
215  QE_CheckOpenGLForErrors();
216  qwglSwapBuffers(dc.m_hDC);
217  }
218 }
219 
220 /*
221  =======================================================================================================================
222  =======================================================================================================================
223  */
225  m_pXYFriend = pWnd;
226 }
227 
228 /*
229  =======================================================================================================================
230  =======================================================================================================================
231  */
233  CWnd::OnDestroy();
234 }
235 
236 /*
237  =======================================================================================================================
238  =======================================================================================================================
239  */
241  CWnd::OnClose();
242 }
243 
244 extern void Select_RotateTexture(float amt, bool absolute);
245 
246 /*
247  =======================================================================================================================
248  =======================================================================================================================
249  */
250 void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) {
251  CRect r;
252  GetClientRect(r);
253  if (GetCapture() == this && (GetAsyncKeyState(VK_MENU) & 0x8000) && !((GetAsyncKeyState(VK_SHIFT) & 0x8000) || (GetAsyncKeyState(VK_CONTROL) & 0x8000))) {
254  if (GetAsyncKeyState(VK_CONTROL) & 0x8000) {
255  Select_RotateTexture((float)point.y - m_ptLastCursor.y);
256  }
257  else if (GetAsyncKeyState(VK_SHIFT) & 0x8000) {
258  Select_ScaleTexture((float)point.x - m_ptLastCursor.x, (float)m_ptLastCursor.y - point.y);
259  }
260  else {
261  Select_ShiftTexture((float)point.x - m_ptLastCursor.x, (float)m_ptLastCursor.y - point.y);
262  }
263  }
264  else {
265  Cam_MouseMoved(point.x, r.bottom - 1 - point.y, nFlags);
266  }
267 
268  m_ptLastCursor = point;
269 }
270 
271 /*
272  =======================================================================================================================
273  =======================================================================================================================
274  */
275 void CCamWnd::OnLButtonDown(UINT nFlags, CPoint point) {
276  m_ptLastCursor = point;
277  OriginalMouseDown(nFlags, point);
278 }
279 
280 /*
281  =======================================================================================================================
282  =======================================================================================================================
283  */
284 void CCamWnd::OnLButtonUp(UINT nFlags, CPoint point) {
285  OriginalMouseUp(nFlags, point);
286 }
287 
288 /*
289  =======================================================================================================================
290  =======================================================================================================================
291  */
292 void CCamWnd::OnMButtonDown(UINT nFlags, CPoint point) {
293  OriginalMouseDown(nFlags, point);
294 }
295 
296 /*
297  =======================================================================================================================
298  =======================================================================================================================
299  */
300 void CCamWnd::OnMButtonUp(UINT nFlags, CPoint point) {
301  OriginalMouseUp(nFlags, point);
302 }
303 
304 /*
305  =======================================================================================================================
306  =======================================================================================================================
307  */
308 void CCamWnd::OnRButtonDown(UINT nFlags, CPoint point) {
309  OriginalMouseDown(nFlags, point);
310 }
311 
312 /*
313  =======================================================================================================================
314  =======================================================================================================================
315  */
316 void CCamWnd::OnRButtonUp(UINT nFlags, CPoint point) {
317  OriginalMouseUp(nFlags, point);
318 }
319 
320 /*
321  =======================================================================================================================
322  =======================================================================================================================
323  */
324 int CCamWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) {
325  if (CWnd::OnCreate(lpCreateStruct) == -1) {
326  return -1;
327  }
328 
329  CDC *pDC = GetDC();
330  HDC hDC = pDC->GetSafeHdc();
331 
332  QEW_SetupPixelFormat(hDC, true);
333 
334  HFONT hfont = CreateFont(
335  12, // logical height of font
336  0, // logical average character width
337  0, // angle of escapement
338  0, // base-line orientation angle
339  0, // font weight
340  0, // italic attribute flag
341  0, // underline attribute flag
342  0, // strikeout attribute flag
343  0, // character set identifier
344  0, // output precision
345  0, // clipping precision
346  0, // output quality
347  FIXED_PITCH | FF_MODERN, // pitch and family
348  "Lucida Console" // pointer to typeface name string
349  );
350 
351  if (!hfont) {
352  Error("couldn't create font");
353  }
354 
355  HFONT hOldFont = (HFONT)SelectObject(hDC, hfont);
356 
357  wglMakeCurrent (hDC, win32.hGLRC);
358 
359  if ((g_qeglobals.d_font_list = qglGenLists(256)) == 0) {
360  common->Warning( "couldn't create font dlists" );
361  }
362 
363  // create the bitmap display lists we're making images of glyphs 0 thru 255
364  if ( !qwglUseFontBitmaps(hDC, 0, 255, g_qeglobals.d_font_list) ) {
365  common->Warning( "wglUseFontBitmaps failed (%d). Trying again.", GetLastError() );
366 
367  // FIXME: This is really wacky, sometimes the first call fails, but calling it again makes it work
368  // This probably indicates there's something wrong somewhere else in the code, but I'm not sure what
369  if ( !qwglUseFontBitmaps(hDC, 0, 255, g_qeglobals.d_font_list) ) {
370  common->Warning( "wglUseFontBitmaps failed again (%d). Trying outlines.", GetLastError() );
371 
372  if (!qwglUseFontOutlines(hDC, 0, 255, g_qeglobals.d_font_list, 0.0f, 0.1f, WGL_FONT_LINES, NULL)) {
373  common->Warning( "wglUseFontOutlines also failed (%d), no coordinate text will be visible.", GetLastError() );
374  }
375  }
376  }
377 
378  SelectObject(hDC, hOldFont);
379  ReleaseDC(pDC);
380 
381  // indicate start of glyph display lists
382  qglListBase(g_qeglobals.d_font_list);
383 
384  // report OpenGL information
385  common->Printf("GL_VENDOR: %s\n", qglGetString(GL_VENDOR));
386  common->Printf("GL_RENDERER: %s\n", qglGetString(GL_RENDERER));
387  common->Printf("GL_VERSION: %s\n", qglGetString(GL_VERSION));
388  common->Printf("GL_EXTENSIONS: %s\n", qglGetString(GL_EXTENSIONS));
389 
390  return 0;
391 }
392 
393 /*
394  =======================================================================================================================
395  =======================================================================================================================
396  */
397 void CCamWnd::OriginalMouseUp(UINT nFlags, CPoint point) {
398  CRect r;
399  GetClientRect(r);
400  Cam_MouseUp(point.x, r.bottom - 1 - point.y, nFlags);
401  if (!(nFlags & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON))) {
402  ReleaseCapture();
403  }
404 }
405 
406 /*
407  =======================================================================================================================
408  =======================================================================================================================
409  */
410 void CCamWnd::OriginalMouseDown(UINT nFlags, CPoint point) {
411  // if (GetTopWindow()->GetSafeHwnd() != GetSafeHwnd()) BringWindowToTop();
412  CRect r;
413  GetClientRect(r);
414  SetFocus();
415  SetCapture();
416 
417  // if (!(GetAsyncKeyState(VK_MENU) & 0x8000))
418  Cam_MouseDown(point.x, r.bottom - 1 - point.y, nFlags);
419 }
420 
421 /*
422  =======================================================================================================================
423  =======================================================================================================================
424  */
426  // m_Camera.draw_mode = cd_texture;
427  m_Camera.origin[0] = 0.0f;
428  m_Camera.origin[1] = 20.0f;
429  m_Camera.origin[2] = 72.0f;
430  m_Camera.color[0] = 0.3f;
431  m_Camera.color[1] = 0.3f;
432  m_Camera.color[2] = 0.3f;
433 }
434 
435 /*
436  =======================================================================================================================
437  =======================================================================================================================
438  */
440  float xa, ya;
441  float matrix[4][4];
442  int i;
443 
446 
447  // the movement matrix is kept 2d
448  m_Camera.forward[0] = cos(ya);
449  m_Camera.forward[1] = sin(ya);
450  m_Camera.right[0] = m_Camera.forward[1];
451  m_Camera.right[1] = -m_Camera.forward[0];
452 
453  qglGetFloatv(GL_PROJECTION_MATRIX, &matrix[0][0]);
454 
455  for (i = 0; i < 3; i++) {
456  m_Camera.vright[i] = matrix[i][0];
457  m_Camera.vup[i] = matrix[i][1];
458  m_Camera.vpn[i] = matrix[i][2];
459  }
460 
464  InitCull();
465 }
466 
467 /*
468  =======================================================================================================================
469  =======================================================================================================================
470  */
471 
473  brush_t *b;
474  float d, bestd, current;
475  idVec3 start, dir;
476 
477  start[0] = m_Camera.origin[0];
478  start[1] = m_Camera.origin[1];
479  start[2] = HUGE_DISTANCE;
480  dir[0] = dir[1] = 0;
481  dir[2] = -1;
482 
483  current = HUGE_DISTANCE - (m_Camera.origin[2] - 72);
484  if (up) {
485  bestd = 0;
486  }
487  else {
488  bestd = HUGE_DISTANCE*2;
489  }
490 
491  for (b = active_brushes.next; b != &active_brushes; b = b->next) {
492  if (!Brush_Ray(start, dir, b, &d)) {
493  continue;
494  }
495 
496  if (up && d < current && d > bestd) {
497  bestd = d;
498  }
499 
500  if (!up && d > current && d < bestd) {
501  bestd = d;
502  }
503  }
504 
505  if (bestd == 0 || bestd == HUGE_DISTANCE*2) {
506  return;
507  }
508 
509  m_Camera.origin[2] += current - bestd;
510  Sys_UpdateWindows(W_CAMERA | W_Z_OVERLAY);
511 }
512 
513 /*
514  =======================================================================================================================
515  =======================================================================================================================
516  */
518  int x, y;
519  Sys_GetCursorPos(&x, &y);
520  if (x != m_ptCursor.x || y != m_ptCursor.y) {
521  x -= m_ptCursor.x;
523  y -= m_ptCursor.y;
524  m_Camera.origin[2] -= y;
525  SetCursorPos(m_ptCursor.x, m_ptCursor.y);
526  Sys_UpdateWindows(W_CAMERA | W_XY_OVERLAY);
527  }
528 }
529 
531  CPoint current;
532 
533  GetCursorPos(&current);
534  if (current.x != m_ptCursor.x || current.y != m_ptCursor.y) {
535 
536  current.x -= m_ptCursor.x;
537  current.y -= m_ptCursor.y;
538 
539  m_Camera.angles[PITCH] -= (float)((float)current.y * 0.25f);
540  m_Camera.angles[YAW] -= (float)((float)current.x * 0.25f);
541 
542  SetCursorPos(m_ptCursor.x, m_ptCursor.y);
543 
544  Cam_BuildMatrix();
545  }
546 }
547 
548 /*
549  =======================================================================================================================
550  =======================================================================================================================
551  */
552 void CCamWnd::Cam_MouseControl(float dtime) {
553  int xl, xh;
554  int yl, yh;
555  float xf, yf;
556  if (g_PrefsDlg.m_nMouseButtons == 2) {
557  if (m_nCambuttonstate != (MK_RBUTTON | MK_SHIFT)) {
558  return;
559  }
560  }
561  else {
562  if (m_nCambuttonstate != MK_RBUTTON) {
563  return;
564  }
565  }
566 
567  xf = (float)(m_ptButton.x - m_Camera.width / 2) / (m_Camera.width / 2);
568  yf = (float)(m_ptButton.y - m_Camera.height / 2) / (m_Camera.height / 2);
569 
570  xl = m_Camera.width / 3;
571  xh = xl * 2;
572  yl = m_Camera.height / 3;
573  yh = yl * 2;
574 
575  // common->Printf("xf-%f yf-%f xl-%i xh-i% yl-i% yh-i%\n",xf,yf,xl,xh,yl,yh);
576 #if 0
577 
578  // strafe
579  if (buttony < yl && (buttonx < xl || buttonx > xh)) {
580  VectorMA(camera.origin, xf * dtime * g_nMoveSpeed, camera.right, camera.origin);
581  }
582  else
583 #endif
584  {
585  xf *= 1.0f - idMath::Fabs(yf);
586  if ( xf < 0.0f ) {
587  xf += 0.1f;
588  if ( xf > 0.0f ) {
589  xf = 0.0f;
590  }
591  }
592  else {
593  xf -= 0.1f;
594  if ( xf < 0.0f ) {
595  xf = 0.0f;
596  }
597  }
598 
600  m_Camera.angles[YAW] += xf * -dtime * g_PrefsDlg.m_nAngleSpeed;
601  }
602 
603  Cam_BuildMatrix();
604  int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA);
605  Sys_UpdateWindows(nUpdate);
606  g_pParentWnd->PostMessage(WM_TIMER, 0, 0);
607 }
608 
609 /*
610  =======================================================================================================================
611  =======================================================================================================================
612  */
613 void CCamWnd::Cam_MouseDown(int x, int y, int buttons) {
614  idVec3 dir;
615  float f, r, u;
616  int i;
617 
618  // calc ray direction
619  u = (float)(y - m_Camera.height / 2) / (m_Camera.width / 2);
620  r = (float)(x - m_Camera.width / 2) / (m_Camera.width / 2);
621  f = 1;
622 
623  for (i = 0; i < 3; i++) {
624  dir[i] = m_Camera.vpn[i] * f + m_Camera.vright[i] * r + m_Camera.vup[i] * u;
625  }
626 
627  dir.Normalize();
628 
629  GetCursorPos(&m_ptCursor);
630 
631  m_nCambuttonstate = buttons;
632  m_ptButton.x = x;
633  m_ptButton.y = y;
634 
635  //
636  // LBUTTON = manipulate selection shift-LBUTTON = select middle button = grab
637  // texture ctrl-middle button = set entire brush to texture ctrl-shift-middle
638  // button = set single face to texture
639  //
640  int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
641  if
642  (
643  (buttons == MK_LBUTTON) ||
644  (buttons == (MK_LBUTTON | MK_SHIFT)) ||
645  (buttons == (MK_LBUTTON | MK_CONTROL)) ||
646  (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) ||
647  (buttons == nMouseButton) ||
648  (buttons == (nMouseButton | MK_SHIFT)) ||
649  (buttons == (nMouseButton | MK_CONTROL)) ||
650  (buttons == (nMouseButton | MK_SHIFT | MK_CONTROL))
651  ) {
652  if (g_PrefsDlg.m_nMouseButtons == 2 && (buttons == (MK_RBUTTON | MK_SHIFT))) {
653  Cam_MouseControl( 0.1f );
654  }
655  else {
656  // something global needs to track which window is responsible for stuff
657  Patch_SetView(W_CAMERA);
658  Drag_Begin(x, y, buttons, m_Camera.vright, m_Camera.vup, m_Camera.origin, dir);
659  }
660 
661  return;
662  }
663 
664  if ( buttons == MK_RBUTTON ) {
665  Cam_MouseControl( 0.1f );
666  return;
667  }
668 }
669 
670 /*
671  =======================================================================================================================
672  =======================================================================================================================
673  */
674 void CCamWnd::Cam_MouseUp(int x, int y, int buttons) {
675  m_nCambuttonstate = 0;
676  Drag_MouseUp(buttons);
677 }
678 
679 /*
680  =======================================================================================================================
681  =======================================================================================================================
682  */
683 void CCamWnd::Cam_MouseMoved(int x, int y, int buttons) {
684  m_nCambuttonstate = buttons;
685  if (!buttons) {
686  return;
687  }
688 
689  m_ptButton.x = x;
690  m_ptButton.y = y;
691 
692  if (buttons == (MK_RBUTTON | MK_CONTROL)) {
694  Sys_UpdateWindows(W_XY | W_CAMERA | W_Z);
695  return;
696  }
697  else if ( buttons == (MK_RBUTTON | MK_CONTROL | MK_SHIFT) ) {
698  Cam_MouseLook();
699  Sys_UpdateWindows(W_XY | W_CAMERA | W_Z);
700  return;
701  }
702 
703  GetCursorPos(&m_ptCursor);
704 
705  if (buttons & (MK_LBUTTON | MK_MBUTTON)) {
706  Drag_MouseMoved(x, y, buttons);
707  Sys_UpdateWindows(W_XY | W_CAMERA | W_Z);
708  }
709 }
710 
711 /*
712  =======================================================================================================================
713  =======================================================================================================================
714  */
716  int i;
717 
720 
721  for (i = 0; i < 3; i++) {
722  if (m_vCull1[i] > 0) {
723  m_nCullv1[i] = 3 + i;
724  }
725  else {
726  m_nCullv1[i] = i;
727  }
728 
729  if (m_vCull2[i] > 0) {
730  m_nCullv2[i] = 3 + i;
731  }
732  else {
733  m_nCullv2[i] = i;
734  }
735  }
736 }
737 
738 /*
739  =======================================================================================================================
740  =======================================================================================================================
741  */
742 bool CCamWnd::CullBrush(brush_t *b, bool cubicOnly) {
743  int i;
744  idVec3 point;
745  float d;
746 
747  if ( b->forceVisibile ) {
748  return false;
749  }
750 
752 
753  float distance = g_PrefsDlg.m_nCubicScale * 64;
754 
755  idVec3 mid;
756  for (int i = 0; i < 3; i++) {
757  mid[i] = (b->mins[i] + ((b->maxs[i] - b->mins[i]) / 2));
758  }
759 
760  point = mid - m_Camera.origin;
761  if (point.Length() > distance) {
762  return true;
763  }
764 
765  }
766 
767  if (cubicOnly) {
768  return false;
769  }
770 
771  for (i = 0; i < 3; i++) {
772  point[i] = b->mins[m_nCullv1[i]] - m_Camera.origin[i];
773  }
774 
775  d = DotProduct(point, m_vCull1);
776  if (d < -1) {
777  return true;
778  }
779 
780  for (i = 0; i < 3; i++) {
781  point[i] = b->mins[m_nCullv2[i]] - m_Camera.origin[i];
782  }
783 
784  d = DotProduct(point, m_vCull2);
785  if (d < -1) {
786  return true;
787  }
788 
789  return false;
790 }
791 
792 #if 0
793 
794 /*
795  =======================================================================================================================
796  =======================================================================================================================
797  */
798 void CCamWnd::DrawLightRadius(brush_t *pBrush) {
799  // if lighting
800  int nRadius = Brush_LightRadius(pBrush);
801  if (nRadius > 0) {
802  Brush_SetLightColor(pBrush);
803  qglEnable(GL_BLEND);
804  qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
805  qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
806  qglDisable(GL_BLEND);
807  qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
808  }
809 }
810 #endif
811 
812 /*
813  =======================================================================================================================
814  =======================================================================================================================
815  */
816 void setGLMode(int mode) {
817  switch (mode)
818  {
819  case cd_wire:
820  qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
822  qglDisable(GL_BLEND);
823  qglDisable(GL_DEPTH_TEST);
824  qglColor3f( 1.0f, 1.0f, 1.0f );
825  break;
826 
827  case cd_solid:
828  qglCullFace(GL_FRONT);
829  qglEnable(GL_CULL_FACE);
830  qglShadeModel(GL_FLAT);
831  qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
833  qglDisable(GL_BLEND);
834  qglEnable(GL_DEPTH_TEST);
835  qglDepthFunc(GL_LEQUAL);
836  break;
837 
838  case cd_texture:
839  qglCullFace(GL_FRONT);
840  qglEnable(GL_CULL_FACE);
841  qglShadeModel(GL_FLAT);
842  qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
843  qglDisable(GL_BLEND);
844  qglEnable(GL_DEPTH_TEST);
845  qglDepthFunc(GL_LEQUAL);
846  break;
847 
848  case cd_blend:
849  qglCullFace(GL_FRONT);
850  qglEnable(GL_CULL_FACE);
851  qglShadeModel(GL_FLAT);
852  qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
853  qglDisable(GL_DEPTH_TEST);
854  qglEnable(GL_BLEND);
855  qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
856  break;
857  }
858 }
859 
860 
861 extern void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label);
862 void DrawAxial(face_t *selFace) {
863  if (g_bAxialMode) {
864  idVec3 points[4];
865 
866  for (int j = 0; j < selFace->face_winding->GetNumPoints(); j++) {
867  glLabeledPoint(idVec4(1, 1, 1, 1), (*selFace->face_winding)[j].ToVec3(), 3, va("%i", j));
868  }
869 
871  points[0] = (*selFace->face_winding)[g_axialAnchor].ToVec3();
872  VectorMA (points[0], 1, selFace->plane, points[0]);
873  VectorMA (points[0], 4, selFace->plane, points[1]);
874  points[3] = (*selFace->face_winding)[g_axialDest].ToVec3();
875  VectorMA (points[3], 1, selFace->plane, points[3]);
876  VectorMA (points[3], 4, selFace->plane, points[2]);
877  glLabeledPoint(idVec4(1, 0, 0, 1), points[1], 3, "Anchor");
878  glLabeledPoint(idVec4(1, 1, 0, 1), points[2], 3, "Dest");
879  qglBegin (GL_LINE_STRIP);
880  qglVertex3fv( points[0].ToFloatPtr() );
881  qglVertex3fv( points[1].ToFloatPtr() );
882  qglVertex3fv( points[2].ToFloatPtr() );
883  qglVertex3fv( points[3].ToFloatPtr() );
884  qglEnd();
885  }
886 }
887 
888 
889 /*
890  =======================================================================================================================
891  Cam_Draw
892  =======================================================================================================================
893  */
895  float xfov = 90;
896  float yfov = 2 * atan((float)m_Camera.height / m_Camera.width) * idMath::M_RAD2DEG;
897 #if 0
898  float screenaspect = (float)m_Camera.width / m_Camera.height;
899  qglLoadIdentity();
900  gluPerspective(yfov, screenaspect, 2, 8192);
901 #else
902  float xmin, xmax, ymin, ymax;
903  float width, height;
904  float zNear;
905  float projectionMatrix[16];
906 
907  //
908  // set up projection matrix
909  //
910  zNear = r_znear.GetFloat();
911 
912  ymax = zNear * tan( yfov * idMath::PI / 360.0f );
913  ymin = -ymax;
914 
915  xmax = zNear * tan( xfov * idMath::PI / 360.0f );
916  xmin = -xmax;
917 
918  width = xmax - xmin;
919  height = ymax - ymin;
920 
921  projectionMatrix[0] = 2 * zNear / width;
922  projectionMatrix[4] = 0;
923  projectionMatrix[8] = ( xmax + xmin ) / width; // normally 0
924  projectionMatrix[12] = 0;
925 
926  projectionMatrix[1] = 0;
927  projectionMatrix[5] = 2 * zNear / height;
928  projectionMatrix[9] = ( ymax + ymin ) / height; // normally 0
929  projectionMatrix[13] = 0;
930 
931  // this is the far-plane-at-infinity formulation
932  projectionMatrix[2] = 0;
933  projectionMatrix[6] = 0;
934  projectionMatrix[10] = -1;
935  projectionMatrix[14] = -2 * zNear;
936 
937  projectionMatrix[3] = 0;
938  projectionMatrix[7] = 0;
939  projectionMatrix[11] = -1;
940  projectionMatrix[15] = 0;
941 
942  qglLoadMatrixf( projectionMatrix );
943 #endif
944 }
945 
947  brush_t *brush;
948  face_t *face;
949 
950  // float yfov;
951  int i;
952 
953  if (!active_brushes.next) {
954  return; // not valid yet
955  }
956 
957  // set the sound origin for both simple draw and rendered mode
958  // the editor uses opposite pitch convention
960  g_qeglobals.sw->PlaceListener( m_Camera.origin, axis, 0, Sys_Milliseconds(), "Undefined" );
961 
962  if (renderMode) {
963  Cam_Render();
964  }
965 
968  qglClearColor(g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1], g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0);
969 
970  if (!renderMode) {
971  qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
972  }
973 
974  qglDisable(GL_LIGHTING);
975  qglMatrixMode(GL_PROJECTION);
976 
978 
979  qglRotatef(-90, 1, 0, 0); // put Z going up
980  qglRotatef(90, 0, 0, 1); // put Z going up
981  qglRotatef(m_Camera.angles[0], 0, 1, 0);
982  qglRotatef(-m_Camera.angles[1], 0, 0, 1);
984 
985  Cam_BuildMatrix();
986 
987  for (brush = active_brushes.next; brush != &active_brushes; brush = brush->next) {
988 
989  if ( CullBrush(brush, false) ) {
990  continue;
991  }
992 
993  if ( FilterBrush(brush) ) {
994  continue;
995  }
996 
997  if (renderMode) {
998  if (!(entityMode && brush->owner->eclass->fixedsize)) {
999  continue;
1000  }
1001  }
1002 
1004  Brush_Draw(brush);
1005  }
1006 
1007 
1008  //qglDepthMask ( 1 ); // Ok, write now
1009  qglMatrixMode(GL_PROJECTION);
1010 
1011  qglTranslatef(g_qeglobals.d_select_translate[0],g_qeglobals.d_select_translate[1],g_qeglobals.d_select_translate[2]);
1012 
1013  brush_t *pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes;
1014 
1015  if (!renderMode) {
1016  // draw normally
1017  for (brush = pList->next; brush != pList; brush = brush->next) {
1018  if (brush->pPatch) {
1019  continue;
1020  }
1022  Brush_Draw(brush, true);
1023  }
1024  }
1025 
1026  // blend on top
1027 
1029  qglDisable(GL_LIGHTING);
1030  qglColor4f( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0],g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1],g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2], 0.25f );
1031  qglEnable(GL_BLEND);
1032  qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1033  qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1035  for (brush = pList->next; brush != pList; brush = brush->next) {
1036  if (brush->pPatch || brush->modelHandle > 0) {
1037  Brush_Draw(brush, true);
1038 
1039  // DHM - Nerve:: patch display lists/models mess with the state
1040  qglEnable(GL_BLEND);
1041  qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1042  qglColor4f( g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0],g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1],g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2], 0.25f );
1044  continue;
1045  }
1046 
1047  if ( brush->owner->eclass->entityModel ) {
1048  continue;
1049  }
1050 
1051  for (face = brush->brush_faces; face; face = face->next) {
1052  Face_Draw(face);
1053  }
1054  }
1055 
1056  int nCount = g_ptrSelectedFaces.GetSize();
1057 
1058  if (!renderMode) {
1059  for (int i = 0; i < nCount; i++) {
1060  face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i));
1061  Face_Draw(selFace);
1062  DrawAxial(selFace);
1063  }
1064  }
1065 
1066  // non-zbuffered outline
1067  qglDisable(GL_BLEND);
1068  qglDisable(GL_DEPTH_TEST);
1069  qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1070 
1071  if (renderMode) {
1072  qglColor3f(1, 0, 0);
1073  for (int i = 0; i < nCount; i++) {
1074  face_t *selFace = reinterpret_cast < face_t * > (g_ptrSelectedFaces.GetAt(i));
1075  Face_Draw(selFace);
1076  }
1077  }
1078 
1079  qglColor3f(1, 1, 1);
1080  for (brush = pList->next; brush != pList; brush = brush->next) {
1081  if (brush->pPatch || brush->modelHandle > 0) {
1082  continue;
1083  }
1084 
1085  for (face = brush->brush_faces; face; face = face->next) {
1086  Face_Draw(face);
1087  }
1088  }
1089  // edge / vertex flags
1090  if (g_qeglobals.d_select_mode == sel_vertex) {
1091  qglPointSize(4);
1092  qglColor3f(0, 1, 0);
1093  qglBegin(GL_POINTS);
1094  for (i = 0; i < g_qeglobals.d_numpoints; i++) {
1095  qglVertex3fv( g_qeglobals.d_points[i].ToFloatPtr() );
1096  }
1097 
1098  qglEnd();
1099  qglPointSize(1);
1100  }
1101  else if (g_qeglobals.d_select_mode == sel_edge) {
1102  float *v1, *v2;
1103 
1104  qglPointSize(4);
1105  qglColor3f(0, 0, 1);
1106  qglBegin(GL_POINTS);
1107  for (i = 0; i < g_qeglobals.d_numedges; i++) {
1108  v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1].ToFloatPtr();
1109  v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2].ToFloatPtr();
1110  qglVertex3f( (v1[0] + v2[0]) * 0.5f, (v1[1] + v2[1]) * 0.5f, (v1[2] + v2[2]) * 0.5f );
1111  }
1112 
1113  qglEnd();
1114  qglPointSize(1);
1115  }
1116 
1117  g_splineList->draw (static_cast<bool>(g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint));
1118 
1119  if ( g_qeglobals.selectObject && (g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint) ) {
1120  g_qeglobals.selectObject->drawSelection();
1121  }
1122 
1123  // draw pointfile
1124  qglEnable(GL_DEPTH_TEST);
1125 
1126  DrawPathLines();
1127 
1128  if (g_qeglobals.d_pointfile_display_list) {
1129  Pointfile_Draw();
1130  }
1131 
1132  //
1133  // bind back to the default texture so that we don't have problems elsewhere
1134  // using/modifying texture maps between contexts
1135  //
1137 
1138  qglFinish();
1139  QE_CheckOpenGLForErrors();
1140 
1141  if (!renderMode) {
1142  // clean up any deffered tri's
1143  R_ToggleSmpFrame();
1144  }
1145 }
1146 
1147 /*
1148  =======================================================================================================================
1149  =======================================================================================================================
1150  */
1151 void CCamWnd::OnSize(UINT nType, int cx, int cy) {
1152  CWnd::OnSize(nType, cx, cy);
1153 
1154  CRect rect;
1155  GetClientRect(rect);
1156  m_Camera.width = rect.right;
1157  m_Camera.height = rect.bottom;
1158  InvalidateRect(NULL, false);
1159 }
1160 
1161 
1162 /*
1163  =======================================================================================================================
1164  =======================================================================================================================
1165  */
1166 void CCamWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) {
1167  g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false);
1168 }
1169 
1170 //
1171 // =======================================================================================================================
1172 // Timo brush primitive texture shifting, using camera view to select translations::
1173 // =======================================================================================================================
1174 //
1175 void CCamWnd::ShiftTexture_BrushPrimit(face_t *f, int x, int y) {
1176 /*
1177  idVec3 texS, texT;
1178  idVec3 viewX, viewY;
1179  int XS, XT, YS, YT;
1180  int outS, outT;
1181 #ifdef _DEBUG
1182  if (!g_qeglobals.m_bBrushPrimitMode) {
1183  common->Printf("Warning : unexpected call to CCamWnd::ShiftTexture_BrushPrimit with brush primitive mode disbaled\n");
1184  return;
1185  }
1186 #endif
1187  // compute face axis base
1188  //ComputeAxisBase(f->plane.Normal(), texS, texT);
1189 
1190  // compute camera view vectors
1191  VectorCopy(m_Camera.vup, viewY);
1192  VectorCopy(m_Camera.vright, viewX);
1193 
1194  // compute best vectors
1195  //ComputeBest2DVector(viewX, texS, texT, XS, XT);
1196  //ComputeBest2DVector(viewY, texS, texT, YS, YT);
1197 
1198  // check this is not a degenerate case
1199  if ((XS == YS) && (XT == YT))
1200  {
1201 #ifdef _DEBUG
1202  common->Printf("Warning : degenerate best vectors axis base in CCamWnd::ShiftTexture_BrushPrimit\n");
1203 #endif
1204  // forget it
1205  Select_ShiftTexture_BrushPrimit(f, x, y, false);
1206  return;
1207  }
1208 
1209  // compute best fitted translation in face axis base
1210  outS = XS * x + YS * y;
1211  outT = XT * x + YT * y;
1212 
1213  // call actual texture shifting code
1214  Select_ShiftTexture_BrushPrimit(f, outS, outT, false);
1215 */
1216 }
1217 
1218 
1219 bool IsBModel(brush_t *b) {
1220  const char *v = ValueForKey( b->owner, "model" );
1221  if (v && *v) {
1222  const char *n = ValueForKey( b->owner, "name");
1223  return (stricmp( n, v ) == 0);
1224  }
1225  return false;
1226 }
1227 
1228 /*
1229 ================
1230 BuildEntityRenderState
1231 
1232 Creates or updates modelDef and lightDef for an entity
1233 ================
1234 */
1235 int Brush_ToTris(brush_t *brush, idTriList *tris, idMatList *mats, bool models, bool bmodel);
1236 
1237 void CCamWnd::BuildEntityRenderState( entity_t *ent, bool update) {
1238  const char *v;
1239  idDict spawnArgs;
1240  const char *name = NULL;
1241 
1243 
1244  // delete the existing def if we aren't creating a brand new world
1245  if ( !update ) {
1246  if ( ent->lightDef >= 0 ) {
1247  g_qeglobals.rw->FreeLightDef( ent->lightDef );
1248  ent->lightDef = -1;
1249  }
1250 
1251  if ( ent->modelDef >= 0 ) {
1252  g_qeglobals.rw->FreeEntityDef( ent->modelDef );
1253  ent->modelDef = -1;
1254  }
1255  }
1256 
1257  // if an entity doesn't have any brushes at all, don't do anything
1258  if ( ent->brushes.onext == &ent->brushes ) {
1259  return;
1260  }
1261 
1262  // if the brush isn't displayed (filtered or culled), don't do anything
1263  if (FilterBrush(ent->brushes.onext)) {
1264  return;
1265  }
1266 
1267  spawnArgs = ent->epairs;
1268  if (ent->eclass->defArgs.FindKey("model")) {
1269  spawnArgs.Set("model", ent->eclass->defArgs.GetString("model"));
1270  }
1271 
1272  // any entity can have a model
1273  name = ValueForKey( ent, "name" );
1274  v = spawnArgs.GetString("model");
1275  if ( v && *v ) {
1276  renderEntity_t refent;
1277 
1278  refent.referenceSound = ent->soundEmitter;
1279 
1280  if ( !stricmp( name, v ) ) {
1281  // build the model from brushes
1282  idTriList tris(1024);
1283  idMatList mats(1024);
1284 
1285  for (brush_t *b = ent->brushes.onext; b != &ent->brushes; b = b->onext) {
1286  Brush_ToTris( b, &tris, &mats, false, true);
1287  }
1288 
1289  if ( ent->modelDef >= 0 ) {
1290  g_qeglobals.rw->FreeEntityDef( ent->modelDef );
1291  ent->modelDef = -1;
1292  }
1293 
1294  idRenderModel *bmodel = renderModelManager->FindModel( name );
1295 
1296  if ( bmodel ) {
1297  renderModelManager->RemoveModel( bmodel );
1298  renderModelManager->FreeModel( bmodel );
1299  }
1300 
1301  bmodel = renderModelManager->AllocModel();
1302 
1303  bmodel->InitEmpty( name );
1304 
1305  // add the surfaces to the renderModel
1306  modelSurface_t surf;
1307  for ( int i = 0 ; i < tris.Num() ; i++ ) {
1308  surf.geometry = tris[i];
1309  surf.shader = mats[i];
1310  bmodel->AddSurface( surf );
1311  }
1312 
1313  bmodel->FinishSurfaces();
1314 
1315  renderModelManager->AddModel( bmodel );
1316 
1317  // FIXME: brush entities
1318  gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &refent );
1319 
1320  ent->modelDef = g_qeglobals.rw->AddEntityDef( &refent );
1321 
1322  } else {
1323  // use the game's epair parsing code so
1324  // we can use the same renderEntity generation
1325  gameEdit->ParseSpawnArgsToRenderEntity( &spawnArgs, &refent );
1326  idRenderModelMD5 *md5 = dynamic_cast<idRenderModelMD5 *>( refent.hModel );
1327  if (md5) {
1328  idStr str;
1329  spawnArgs.GetString("anim", "idle", str);
1330  refent.numJoints = md5->NumJoints();
1331  if ( update && refent.joints ) {
1332  Mem_Free16( refent.joints );
1333  }
1334  refent.joints = ( idJointMat * )Mem_Alloc16( refent.numJoints * sizeof( *refent.joints ) );
1335  const idMD5Anim *anim = gameEdit->ANIM_GetAnimFromEntityDef(spawnArgs.GetString("classname"), str);
1336  int frame = spawnArgs.GetInt("frame") + 1;
1337  if ( frame < 1 ) {
1338  frame = 1;
1339  }
1340  const idVec3 &offset = gameEdit->ANIM_GetModelOffsetFromEntityDef( spawnArgs.GetString("classname") );
1341  gameEdit->ANIM_CreateAnimFrame( md5, anim, refent.numJoints, refent.joints, ( frame * 1000 ) / 24, offset, false );
1342  }
1343  if (ent->modelDef >= 0) {
1344  g_qeglobals.rw->FreeEntityDef( ent->modelDef );
1345  }
1346  ent->modelDef = g_qeglobals.rw->AddEntityDef( &refent );
1347  }
1348  }
1349 
1350  // check for lightdefs
1351  if (!(ent->eclass->nShowFlags & ECLASS_LIGHT)) {
1352  return;
1353  }
1354 
1355  if ( spawnArgs.GetBool( "start_off" ) ) {
1356  return;
1357  }
1358  // use the game's epair parsing code so
1359  // we can use the same renderLight generation
1360 
1361  renderLight_t lightParms;
1362 
1363  gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &lightParms );
1364  lightParms.referenceSound = ent->soundEmitter;
1365 
1366  if (update && ent->lightDef >= 0) {
1367  g_qeglobals.rw->UpdateLightDef( ent->lightDef, &lightParms );
1368  } else {
1369  if (ent->lightDef >= 0) {
1370  g_qeglobals.rw->FreeLightDef(ent->lightDef);
1371  }
1372  ent->lightDef = g_qeglobals.rw->AddLightDef( &lightParms );
1373  }
1374 
1375 }
1376 
1377 void Tris_ToOBJ(const char *outFile, idTriList *tris, idMatList *mats) {
1378  idFile *f = fileSystem->OpenExplicitFileWrite( outFile );
1379  if ( f ) {
1380  char out[1024];
1381  strcpy(out, outFile);
1382  StripExtension(out);
1383 
1384  idList<idStr*> matNames;
1385  int i, j, k;
1386  int indexBase = 1;
1387  idStr lastMaterial("");
1388  int matCount = 0;
1389  //idStr basePath = cvarSystem->GetCVarString( "fs_savepath" );
1390  f->Printf( "mtllib %s.mtl\n", out );
1391  for (i = 0; i < tris->Num(); i++) {
1392  srfTriangles_t *tri = (*tris)[i];
1393  for (j = 0; j < tri->numVerts; j++) {
1394  f->Printf( "v %f %f %f\n", tri->verts[j].xyz.x, tri->verts[j].xyz.z, -tri->verts[j].xyz.y );
1395  }
1396  for (j = 0; j < tri->numVerts; j++) {
1397  f->Printf( "vt %f %f\n", tri->verts[j].st.x, 1.0f - tri->verts[j].st.y );
1398  }
1399  for (j = 0; j < tri->numVerts; j++) {
1400  f->Printf( "vn %f %f %f\n", tri->verts[j].normal.x, tri->verts[j].normal.y, tri->verts[j].normal.z );
1401  }
1402 
1403  if (stricmp( (*mats)[i]->GetName(), lastMaterial)) {
1404  lastMaterial = (*mats)[i]->GetName();
1405 
1406  bool found = false;
1407  for (k = 0; k < matNames.Num(); k++) {
1408  if ( idStr::Icmp(matNames[k]->c_str(), lastMaterial.c_str()) == 0 ) {
1409  found = true;
1410  // f->Printf( "usemtl m%i\n", k );
1411  f->Printf( "usemtl %s\n", lastMaterial.c_str() );
1412  break;
1413  }
1414  }
1415 
1416  if (!found) {
1417  // f->Printf( "usemtl m%i\n", matCount++ );
1418  f->Printf( "usemtl %s\n", lastMaterial.c_str() );
1419  matNames.Append(new idStr(lastMaterial));
1420  }
1421  }
1422 
1423  for (int j = 0; j < tri->numIndexes; j += 3) {
1424  int i1, i2, i3;
1425  i1 = tri->indexes[j+2] + indexBase;
1426  i2 = tri->indexes[j+1] + indexBase;
1427  i3 = tri->indexes[j] + indexBase;
1428  f->Printf( "f %i/%i/%i %i/%i/%i %i/%i/%i\n", i1,i1,i1, i2,i2,i2, i3,i3,i3 );
1429  }
1430 
1431  indexBase += tri->numVerts;
1432 
1433  }
1434  fileSystem->CloseFile( f );
1435 
1436  strcat(out, ".mtl");
1437  f = fileSystem->OpenExplicitFileWrite( out );
1438  if (f) {
1439  for (k = 0; k < matNames.Num(); k++) {
1440  // This presumes the diffuse tga name matches the material name
1441  f->Printf( "newmtl %s\n\tNs 0\n\td 1\n\tillum 2\n\tKd 0 0 0 \n\tKs 0.22 0.22 0.22 \n\tKa 0 0 0 \n\tmap_Kd %s/base/%s.tga\n\n\n", matNames[k]->c_str(), "z:/d3xp", matNames[k]->c_str() );
1442  }
1443  fileSystem->CloseFile( f );
1444  }
1445 
1446  }
1447 }
1448 
1449 int Brush_TransformModel(brush_t *brush, idTriList *tris, idMatList *mats) {
1450  int ret = 0;
1451  if (brush->modelHandle > 0 ) {
1452  idRenderModel *model = brush->modelHandle;
1453  if (model) {
1454  float a = FloatForKey(brush->owner, "angle");
1455  float s, c;
1456  //FIXME: support full rotation matrix
1457  bool matrix = false;
1458  if (a) {
1459  s = sin( DEG2RAD(a) );
1460  c = cos( DEG2RAD(a) );
1461  }
1462  idMat3 mat;
1463  if (GetMatrixForKey(brush->owner, "rotation", mat)) {
1464  matrix = true;
1465  }
1466 
1467 
1468  for (int i = 0; i < model->NumSurfaces() ; i++) {
1469  const modelSurface_t *surf = model->Surface( i );
1470  srfTriangles_t *tri = surf->geometry;
1471  srfTriangles_t *tri2 = R_CopyStaticTriSurf(tri);
1472  for (int j = 0; j < tri2->numVerts; j++) {
1473  idVec3 v;
1474  if (matrix) {
1475  v = tri2->verts[j].xyz * brush->owner->rotation + brush->owner->origin;
1476  } else {
1477  v = tri2->verts[j].xyz;
1478  VectorAdd(v, brush->owner->origin, v);
1479  float x = v[0];
1480  float y = v[1];
1481  if (a) {
1482  float x2 = (((x - brush->owner->origin[0]) * c) - ((y - brush->owner->origin[1]) * s)) + brush->owner->origin[0];
1483  float y2 = (((x - brush->owner->origin[0]) * s) + ((y - brush->owner->origin[1]) * c)) + brush->owner->origin[1];
1484  x = x2;
1485  y = y2;
1486  }
1487  v[0] = x;
1488  v[1] = y;
1489  }
1490  tri2->verts[j].xyz = v;
1491  }
1492  tris->Append(tri2);
1493  mats->Append( surf->shader );
1494  }
1495  return model->NumSurfaces();
1496  }
1497  }
1498  return ret;
1499 }
1500 
1501 
1502 #define MAX_TRI_SURFACES 16384
1503 int Brush_ToTris(brush_t *brush, idTriList *tris, idMatList *mats, bool models, bool bmodel) {
1504  int i, j;
1505  srfTriangles_t *tri;
1506  //
1507  // patches
1508  //
1509  if (brush->modelHandle > 0 ) {
1510  if (!models) {
1511  return 0;
1512  } else {
1513  return Brush_TransformModel(brush, tris, mats);
1514  }
1515  }
1516 
1517  int numSurfaces = 0;
1518 
1519  if ( brush->owner->eclass->fixedsize && !brush->entityModel) {
1520  return NULL;
1521  }
1522 
1523  if ( brush->pPatch ) {
1524  patchMesh_t *pm;
1525  int width, height;
1526 
1527  pm = brush->pPatch;
1528 
1529  // build a patch mesh
1530  idSurface_Patch *cp = new idSurface_Patch( pm->width * 6, pm->height * 6 );
1531  cp->SetSize( pm->width, pm->height );
1532  for ( i = 0; i < pm->width; i++ ) {
1533  for ( j = 0; j < pm->height; j++ ) {
1534  (*cp)[j*cp->GetWidth()+i].xyz = pm->ctrl(i, j).xyz;
1535  (*cp)[j*cp->GetWidth()+i].st = pm->ctrl(i, j).st;
1536  }
1537  }
1538 
1539  // subdivide it
1540  if ( pm->explicitSubdivisions ) {
1541  cp->SubdivideExplicit( pm->horzSubdivisions, pm->vertSubdivisions, true );
1542  } else {
1544  }
1545  width = cp->GetWidth();
1546  height = cp->GetHeight();
1547 
1548  // convert to srfTriangles
1549  tri = R_AllocStaticTriSurf();
1550  tri->numVerts = width * height;
1551  tri->numIndexes = 6 * ( width - 1 ) * ( height - 1 );
1552  R_AllocStaticTriSurfVerts( tri, tri->numVerts );
1554  for ( i = 0 ; i < tri->numVerts ; i++ ) {
1555  tri->verts[i] = (*cp)[i];
1556  if (bmodel) {
1557  tri->verts[i].xyz -= brush->owner->origin;
1558  }
1559  }
1560 
1561  tri->numIndexes = 0;
1562  for ( i = 1 ; i < width ; i++ ) {
1563  for ( j = 1 ; j < height ; j++ ) {
1564  tri->indexes[tri->numIndexes++] = ( j - 1 ) * width + i;
1565  tri->indexes[tri->numIndexes++] = ( j - 1 ) * width + i - 1;
1566  tri->indexes[tri->numIndexes++] = j * width + i - 1;
1567 
1568  tri->indexes[tri->numIndexes++] = j * width + i;
1569  tri->indexes[tri->numIndexes++] = ( j - 1 ) * width + i;
1570  tri->indexes[tri->numIndexes++] = j * width + i - 1;
1571  }
1572  }
1573 
1574  delete cp;
1575 
1576  tris->Append(tri);
1577  mats->Append(pm->d_texture);
1578  //surfaces[numSurfaces] = tri;
1579  //materials[numSurfaces] = pm->d_texture;
1580  return 1;
1581  }
1582 
1583  //
1584  // normal brush
1585  //
1586  for ( face_t *face = brush->brush_faces ; face; face = face->next ) {
1587  idWinding *w;
1588 
1589  w = face->face_winding;
1590  if (!w) {
1591  continue; // freed or degenerate face
1592  }
1593 
1594  tri = R_AllocStaticTriSurf();
1595  tri->numVerts = w->GetNumPoints();
1596  tri->numIndexes = ( w->GetNumPoints() - 2 ) * 3;
1597  R_AllocStaticTriSurfVerts( tri, tri->numVerts );
1599 
1600  for ( i = 0 ; i < tri->numVerts ; i++ ) {
1601 
1602  tri->verts[i].Clear();
1603 
1604  tri->verts[i].xyz[0] = (*w)[i][0];
1605  tri->verts[i].xyz[1] = (*w)[i][1];
1606  tri->verts[i].xyz[2] = (*w)[i][2];
1607 
1608  if ( bmodel ) {
1609  tri->verts[i].xyz -= brush->owner->origin;
1610  }
1611 
1612  tri->verts[i].st[0] = (*w)[i][3];
1613  tri->verts[i].st[1] = (*w)[i][4];
1614 
1615  tri->verts[i].normal = face->plane.Normal();
1616  }
1617 
1618  tri->numIndexes = 0;
1619  for ( i = 2 ; i < w->GetNumPoints() ; i++ ) {
1620  tri->indexes[tri->numIndexes++] = 0;
1621  tri->indexes[tri->numIndexes++] = i-1;
1622  tri->indexes[tri->numIndexes++] = i;
1623  }
1624 
1625  tris->Append(tri);
1626  mats->Append(face->d_texture);
1627  numSurfaces++;
1628  }
1629 
1630  return numSurfaces;
1631 }
1632 
1634  int i;
1635  CFileDialog dlgFile(FALSE, "obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Wavefront object files (*.obj)|*.obj||", g_pParentWnd);
1636  if (dlgFile.DoModal() == IDOK) {
1637  idTriList tris(1024);
1638  idMatList mats(1024);
1639 
1640  for (brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next) {
1641 
1642  if ( b->hiddenBrush ) {
1643  continue;
1644  }
1645 
1646  if (FilterBrush(b)) {
1647  continue;
1648  }
1649 
1650  Brush_ToTris(b, &tris, &mats, true, false);
1651  }
1652 
1653  Tris_ToOBJ(dlgFile.GetPathName().GetBuffer(0), &tris, &mats);
1654 
1655  for( i = 0; i < tris.Num(); i++ ) {
1656  R_FreeStaticTriSurf( tris[i] );
1657  }
1658  tris.Clear();
1659  }
1660 }
1661 
1662 void Select_ToCM() {
1663  CFileDialog dlgFile( FALSE, "lwo, ase", NULL, 0, "(*.lwo)|*.lwo|(*.ase)|*.ase|(*.ma)|*.ma||", g_pParentWnd );
1664 
1665  if ( dlgFile.DoModal() == IDOK ) {
1666  idMapEntity *mapEnt;
1667  idMapPrimitive *p;
1668  idStr name;
1669 
1670  name = fileSystem->OSPathToRelativePath( dlgFile.GetPathName() );
1671  name.BackSlashesToSlashes();
1672 
1673  mapEnt = new idMapEntity();
1674  mapEnt->epairs.Set( "name", name.c_str() );
1675 
1676  for ( brush_t *b = selected_brushes.next; b != &selected_brushes; b = b->next ) {
1677 
1678  if ( b->hiddenBrush ) {
1679  continue;
1680  }
1681 
1682  if ( FilterBrush( b ) ) {
1683  continue;
1684  }
1685 
1686  p = BrushToMapPrimitive( b, b->owner->origin );
1687  if ( p ) {
1688  mapEnt->AddPrimitive( p );
1689  }
1690  }
1691 
1693 
1694  delete mapEnt;
1695  }
1696 }
1697 
1698 
1699 /*
1700 =================
1701 BuildRendererState
1702 
1703 Builds models, lightdefs, and modeldefs for the current editor data
1704 so it can be rendered by the game renderSystem
1705 =================
1706 */
1708  renderEntity_t worldEntity;
1709  entity_t *ent;
1710  brush_t *brush;
1711 
1713 
1714  // the renderWorld holds all the references and defs
1715  g_qeglobals.rw->InitFromMap( NULL );
1716 
1717  // create the raw model for all the brushes
1718  int numBrushes = 0;
1719  int numSurfaces = 0;
1720 
1721  // the renderModel for the world holds all the geometry that isn't in an entity
1723  worldModel->InitEmpty( "EditorWorldModel" );
1724 
1725  for ( brush_t *brushList = &active_brushes ; brushList ;
1726  brushList = (brushList == &active_brushes) ? &selected_brushes : NULL ) {
1727 
1728  for (brush = brushList->next; brush != brushList; brush = brush->next) {
1729 
1730  if ( brush->hiddenBrush ) {
1731  continue;
1732  }
1733 
1734  if (FilterBrush(brush)) {
1735  continue;
1736  }
1737 
1738  if (CullBrush(brush, true)) {
1739  continue;
1740  }
1741 
1742  idTriList tris(1024);
1743  idMatList mats(1024);
1744 
1745  if (!IsBModel(brush)) {
1746  numSurfaces += Brush_ToTris( brush, &tris, &mats, false, false );
1747  }
1748 
1749  // add the surfaces to the renderModel
1750  modelSurface_t surf;
1751  for ( int i = 0 ; i < tris.Num() ; i++ ) {
1752  surf.geometry = tris[i];
1753  surf.shader = mats[i];
1754  worldModel->AddSurface( surf );
1755  }
1756 
1757  numBrushes++;
1758  }
1759  }
1760 
1761  // bound and clean the triangles
1763 
1764  // the worldEntity just has the handle for the worldModel
1765  memset( &worldEntity, 0, sizeof( worldEntity ) );
1766  worldEntity.hModel = worldModel;
1767  worldEntity.axis = mat3_default;
1768  worldEntity.shaderParms[0] = 1;
1769  worldEntity.shaderParms[1] = 1;
1770  worldEntity.shaderParms[2] = 1;
1771  worldEntity.shaderParms[3] = 1;
1772 
1773  worldModelDef = g_qeglobals.rw->AddEntityDef( &worldEntity );
1774 
1775  // create the light and model entities exactly the way the game code would
1776  for ( ent = entities.next ; ent != &entities ; ent = ent->next ) {
1777  if ( ent->brushes.onext == &ent->brushes ) {
1778  continue;
1779  }
1780 
1781  if (CullBrush(ent->brushes.onext, true)) {
1782  continue;
1783  }
1784 
1785  if (Map_IsBrushFiltered(ent->brushes.onext)) {
1786  continue;
1787  }
1788 
1789  BuildEntityRenderState( ent, false );
1790  }
1791 
1792  //common->Printf("Render data used %d brushes\n", numBrushes);
1793  worldDirty = false;
1794  UpdateCaption();
1795 }
1796 
1797 /*
1798 ===============================
1799 CCamWnd::UpdateRenderEntities
1800 
1801  Creates a new entity state list
1802  returns true if a repaint is needed
1803 ===============================
1804 */
1806 
1807  if (rebuildMode) {
1808  return false;
1809  }
1810 
1811  bool ret = false;
1812  for ( entity_t *ent = entities.next ; ent != &entities ; ent = ent->next ) {
1813  BuildEntityRenderState( ent, (ent->lightDef != -1 || ent->modelDef != -1 || ent->soundEmitter ) ? true : false );
1814  if (ret == false && ent->modelDef || ent->lightDef) {
1815  ret = true;
1816  }
1817  }
1818  return ret;
1819 }
1820 
1821 /*
1822 ============================
1823 CCamWnd::FreeRendererState
1824 
1825  Frees the render state data
1826 ============================
1827 */
1829 
1830  for ( entity_t *ent = entities.next ; ent != &entities ; ent = ent->next ) {
1831  if (ent->lightDef >= 0) {
1832  g_qeglobals.rw->FreeLightDef( ent->lightDef );
1833  ent->lightDef = -1;
1834  }
1835 
1836  if (ent->modelDef >= 0) {
1837  renderEntity_t *refent = const_cast<renderEntity_t *>(g_qeglobals.rw->GetRenderEntity( ent->modelDef ));
1838  if ( refent ) {
1839  if ( refent->callbackData ) {
1840  Mem_Free( refent->callbackData );
1841  refent->callbackData = NULL;
1842  }
1843  if ( refent->joints ) {
1844  Mem_Free16(refent->joints);
1845  refent->joints = NULL;
1846  }
1847  }
1848  g_qeglobals.rw->FreeEntityDef( ent->modelDef );
1849  ent->modelDef = -1;
1850  }
1851  }
1852 
1853  if ( worldModel ) {
1855  worldModel = NULL;
1856  }
1857 
1858 }
1859 
1860 
1861 /*
1862 ========================
1863 CCamWnd::UpdateCaption
1864 
1865  updates the caption based on rendermode and whether the render mode needs updated
1866 ========================
1867 */
1869 
1870  idStr strCaption;
1871 
1872  if (worldDirty) {
1873  strCaption = "*";
1874  }
1875  // FIXME:
1876  strCaption += (renderMode) ? "RENDER" : "CAM";
1877  if (renderMode) {
1878  strCaption += (rebuildMode) ? " (Realtime)" : "";
1879  strCaption += (entityMode) ? " +lights" : "";
1880  strCaption += (selectMode) ? " +selected" : "";
1881  strCaption += (animationMode) ? " +anim" : "";
1882  }
1883  strCaption += (soundMode) ? " +snd" : "";
1884  SetWindowText(strCaption);
1885 }
1886 
1887 /*
1888 ===========================
1889 CCamWnd::ToggleRenderMode
1890 
1891  Toggles the render mode
1892 ===========================
1893 */
1895  renderMode ^= 1;
1896  UpdateCaption();
1897 }
1898 
1899 /*
1900 ===========================
1901 CCamWnd::ToggleRebuildMode
1902 
1903  Toggles the rebuild mode
1904 ===========================
1905 */
1907  rebuildMode ^= 1;
1908  UpdateCaption();
1909 }
1910 
1911 /*
1912 ===========================
1913 CCamWnd::ToggleEntityMode
1914 
1915  Toggles the entity mode
1916 ===========================
1917 */
1919  entityMode ^= 1;
1920  UpdateCaption();
1921 }
1922 
1923 
1924 /*
1925 ===========================
1926 CCamWnd::ToggleRenderMode
1927 
1928  Toggles the render mode
1929 ===========================
1930 */
1932  animationMode ^= 1;
1933  if (animationMode) {
1934  SetTimer(0, 10, NULL);
1935  } else {
1936  KillTimer(0);
1937  }
1938  UpdateCaption();
1939 }
1940 
1941 /*
1942 ===========================
1943 CCamWnd::ToggleSoundMode
1944 
1945  Toggles the sound mode
1946 ===========================
1947 */
1949  soundMode ^= 1;
1950 
1951  UpdateCaption();
1952 
1953  for ( entity_t *ent = entities.next ; ent != &entities ; ent = ent->next ) {
1955  }
1956 }
1957 
1958 /*
1959 ===========================
1960 CCamWnd::ToggleRenderMode
1961 
1962  Toggles the render mode
1963 ===========================
1964 */
1966  selectMode ^= 1;
1967  UpdateCaption();
1968 }
1969 
1970 /*
1971 =========================
1972 CCamWnd::MarkWorldDirty
1973 
1974  marks the render world as dirty
1975 =========================
1976 */
1978  worldDirty = true;
1979  UpdateCaption();
1980 }
1981 
1982 
1983 /*
1984 =========================
1985 CCamWnd::DrawEntityData
1986 
1987  Draws entity data ( experimental )
1988 =========================
1989 */
1990 extern void glBox(idVec4 &color, idVec3 &point, float size);
1991 
1993 
1994  qglMatrixMode( GL_MODELVIEW );
1995  qglLoadIdentity();
1996  qglMatrixMode( GL_PROJECTION );
1997  qglLoadIdentity();
1998 
2000 
2001  qglRotatef(-90, 1, 0, 0); // put Z going up
2002  qglRotatef(90, 0, 0, 1); // put Z going up
2003  qglRotatef(m_Camera.angles[0], 0, 1, 0);
2004  qglRotatef(-m_Camera.angles[1], 0, 0, 1);
2006 
2007  Cam_BuildMatrix();
2008 
2009  if (!(entityMode || selectMode)) {
2010  return;
2011  }
2012 
2013  qglDisable(GL_BLEND);
2014  qglDisable(GL_DEPTH_TEST);
2015  qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2017  idVec3 color(0, 1, 0);
2018  qglColor3fv( color.ToFloatPtr() );
2019 
2020  brush_t *brushList = &active_brushes;
2021  int pass = 0;
2022  while (brushList) {
2023  for (brush_t *brush = brushList->next; brush != brushList; brush = brush->next) {
2024 
2025  if (CullBrush(brush, true)) {
2026  continue;
2027  }
2028 
2029  if (FilterBrush(brush)) {
2030  continue;
2031  }
2032 
2033  if ((pass == 1 && selectMode) || (entityMode && pass == 0 && brush->owner->lightDef >= 0)) {
2034  Brush_DrawXY(brush, 0, true, true);
2035  }
2036 
2037  }
2038  brushList = (brushList == &active_brushes) ? &selected_brushes : NULL;
2039  color.x = 1;
2040  color.y = 0;
2041  pass++;
2042  qglColor3fv( color.ToFloatPtr() );
2043  }
2044 
2045 }
2046 
2047 
2048 /*
2049  =======================================================================================================================
2050  Cam_Render
2051 
2052  This used the renderSystem to draw a fully lit view of the world
2053  =======================================================================================================================
2054  */
2056 
2057  renderView_t refdef;
2058  CPaintDC dc(this); // device context for painting
2059 
2060 
2061  if (!active_brushes.next) {
2062  return; // not valid yet
2063  }
2064 
2065  if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) {
2066  common->Printf("ERROR: wglMakeCurrent failed..\n ");
2067  common->Printf("Please restart " EDITOR_WINDOWTEXT " if the camera view is not working\n");
2068  return;
2069  }
2070 
2071  // save the editor state
2072  //qglPushAttrib( GL_ALL_ATTRIB_BITS );
2073  qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
2075  qglClear( GL_COLOR_BUFFER_BIT );
2076 
2077  // qwglSwapBuffers(dc.m_hDC);
2078 
2079  // create the model, using explicit normals
2080  if ( rebuildMode && worldDirty ) {
2082  }
2083 
2084  // render it
2086 
2087  memset( &refdef, 0, sizeof( refdef ) );
2088  refdef.vieworg = m_Camera.origin;
2089 
2090  // the editor uses opposite pitch convention
2092 
2093  refdef.width = SCREEN_WIDTH;
2094  refdef.height = SCREEN_HEIGHT;
2095  refdef.fov_x = 90;
2096  refdef.fov_y = 2 * atan((float)m_Camera.height / m_Camera.width) * idMath::M_RAD2DEG;
2097 
2098  // only set in animation mode to give a consistent look
2099  if (animationMode) {
2100  refdef.time = eventLoop->Milliseconds();
2101  }
2102 
2103  g_qeglobals.rw->RenderScene( &refdef );
2104 
2105  int frontEnd, backEnd;
2106 
2107  renderSystem->EndFrame( &frontEnd, &backEnd );
2108 //common->Printf( "front:%i back:%i\n", frontEnd, backEnd );
2109 
2110  //qglPopAttrib();
2111  //DrawEntityData();
2112 
2113  //qwglSwapBuffers(dc.m_hDC);
2114  // get back to the editor state
2115  qglMatrixMode( GL_MODELVIEW );
2116  qglLoadIdentity();
2117  Cam_BuildMatrix();
2118 }
2119 
2120 
2121 void CCamWnd::OnTimer(UINT nIDEvent)
2122 {
2123  if (animationMode || nIDEvent == 1) {
2124  Sys_UpdateWindows(W_CAMERA);
2125  }
2126  if (nIDEvent == 1) {
2127  KillTimer(1);
2128  }
2129 
2130  if (!animationMode ) {
2131  KillTimer(0);
2132  }
2133 }
2134 
2135 
2137  if (QE_SingleBrush(true, true)) {
2138  brush_t *b = selected_brushes.next;
2139  if (b->owner->eclass->nShowFlags & ECLASS_CAMERAVIEW) {
2140  // find the entity that targets this
2141  const char *name = ValueForKey(b->owner, "name");
2142  entity_t *ent = FindEntity("target", name);
2143  if (ent) {
2144  if (!saveValid) {
2147  saveValid = true;
2148  }
2149  idVec3 v = b->owner->origin - ent->origin;
2150  v.Normalize();
2151  idAngles ang = v.ToMat3().ToAngles();
2152  ang.pitch = -ang.pitch;
2153  ang.roll = 0.0f;
2154  SetView( ent->origin, ang );
2155  Cam_BuildMatrix();
2156  Sys_UpdateWindows( W_CAMERA );
2157  return;
2158  }
2159  }
2160  }
2161  if (saveValid) {
2163  Cam_BuildMatrix();
2164  Sys_UpdateWindows(W_CAMERA);
2165  saveValid = false;
2166  }
2167 }
2168 
CMainFrame * g_pParentWnd
Definition: MainFrm.cpp:73
bool FilterBrush(brush_t *pb)
Definition: XYWnd.cpp:3167
byte color[4]
Definition: MegaTexture.cpp:54
GLsizei const GLfloat * points
Definition: glext.h:3884
int m_nAngleSpeed
Definition: PrefsDlg.h:102
idMat3 ToMat3(void) const
Definition: Vector.cpp:195
#define stricmp
Definition: Str.h:64
#define qglLoadMatrixf
Definition: qgl_linked.h:188
void WINAPI Sys_UpdateWindows(int nBits)
Definition: MainFrm.cpp:3974
afx_msg void OnMButtonUp(UINT nFlags, CPoint point)
Definition: CamWnd.cpp:300
virtual void EndFrame(int *frontEndMsec, int *backEndMsec)=0
float Normalize(void)
Definition: Vector.h:646
#define qglScissor
Definition: qgl_linked.h:280
int GetInt(const char *key, const char *defaultString="0") const
Definition: Dict.h:252
void DrawAxial(face_t *selFace)
Definition: CamWnd.cpp:862
void AddPrimitive(idMapPrimitive *p)
Definition: MapFile.h:175
int m_nCambuttonstate
Definition: CamWnd.h:162
void Clear(void)
Definition: DrawVert.h:73
qhandle_t worldModelDef
Definition: CamWnd.h:146
#define qglDisable
Definition: qgl_linked.h:92
CCamWnd()
Definition: CamWnd.cpp:76
int numVerts
Definition: Model.h:98
idVec3 color
Definition: CamWnd.h:53
#define qglGenLists
Definition: qgl_linked.h:126
GLdouble GLdouble GLdouble GLdouble zNear
Definition: qgl.h:273
bool entityMode
Definition: CamWnd.h:151
bool IsBModel(brush_t *b)
Definition: CamWnd.cpp:1219
int m_nCubicScale
Definition: PrefsDlg.h:106
void Select_ToOBJ()
Definition: CamWnd.cpp:1633
brush_t selected_brushes
Definition: EditorMap.cpp:40
float y
Definition: Vector.h:55
CPoint m_ptLastCursor
Definition: CamWnd.h:165
CONST PIXELFORMATDESCRIPTOR UINT
Definition: win_qgl.cpp:47
float GetFloat(void) const
Definition: CVarSystem.h:144
idRenderModel * worldModel
Definition: CamWnd.h:147
brush_t active_brushes
Definition: EditorMap.cpp:39
const GLdouble * v
Definition: glext.h:2936
BOOL m_bCamXYUpdate
Definition: PrefsDlg.h:78
HGLRC hGLRC
Definition: win_local.h:122
GLuint GLenum matrix
Definition: glext.h:5179
GLdouble GLdouble x2
Definition: qgl.h:415
void Cam_Init()
Definition: CamWnd.cpp:425
void SetView(const idVec3 &origin, const idAngles &angles)
Definition: CamWnd.h:127
virtual void FinishSurfaces()=0
#define qglClearColor
Definition: qgl_linked.h:41
#define qglCullFace
Definition: qgl_linked.h:86
const float * ToFloatPtr(void) const
Definition: Vector.h:719
#define VectorSubtract(a, b, c)
Definition: Vector.h:1995
#define qglRotatef
Definition: qgl_linked.h:277
idVec3 vup
Definition: CamWnd.h:56
idVec3 xyz
Definition: DrawVert.h:42
static const float PI
Definition: Math.h:205
GLenum GLint GLint y
Definition: glext.h:2849
bool renderMode
Definition: CamWnd.h:149
const int SCREEN_HEIGHT
Definition: RenderSystem.h:154
GLenum GLsizei n
Definition: glext.h:3705
void Tris_ToOBJ(const char *outFile, idTriList *tris, idMatList *mats)
Definition: CamWnd.cpp:1377
idRenderSystem * renderSystem
float z
Definition: Vector.h:320
idVec3 vpn
Definition: CamWnd.h:56
int Sys_Milliseconds(void)
void BuildEntityRenderState(entity_t *ent, bool update)
Definition: CamWnd.cpp:1237
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
const idMaterial * shader
Definition: Model.h:146
void UpdateCaption()
Definition: CamWnd.cpp:1868
#define WINAPI
Definition: qgl.h:64
idVec3 origin
Definition: EditorEntity.h:37
bool UpdateRenderEntities()
Definition: CamWnd.cpp:1805
#define qglBegin
Definition: qgl_linked.h:33
virtual void AddSurface(modelSurface_t surface)=0
CXYWnd * ActiveXY()
Definition: MainFrm.cpp:4034
const char * ValueForKey(entity_t *ent, const char *key)
void glBox(idVec4 &color, idVec3 &point, float size)
Definition: splines.cpp:61
Definition: Vector.h:316
case const float
Definition: Callbacks.cpp:62
bool GetMatrixForKey(entity_t *ent, const char *key, idMat3 &mat)
virtual BOOL PreCreateWindow(CREATESTRUCT &cs)
Definition: CamWnd.cpp:151
#define qglVertex3fv
Definition: qgl_linked.h:350
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
Definition: CamWnd.cpp:187
#define VectorAdd(a, b, c)
Definition: Vector.h:1996
void SetProjectionMatrix()
Definition: CamWnd.cpp:894
static const float M_DEG2RAD
Definition: Math.h:214
idAngles angles
Definition: CamWnd.h:49
afx_msg void OnLButtonUp(UINT nFlags, CPoint point)
Definition: CamWnd.cpp:284
srfTriangles_t * R_AllocStaticTriSurf(void)
Definition: tr_trisurf.cpp:523
GLdouble s
Definition: glext.h:2935
#define qglViewport
Definition: qgl_linked.h:364
void Set(const char *key, const char *value)
Definition: Dict.cpp:275
void SetXYFriend(CXYWnd *pWnd)
Definition: CamWnd.cpp:224
float x
Definition: Vector.h:318
#define qglTranslatef
Definition: qgl_linked.h:338
void ShiftTexture_BrushPrimit(face_t *f, int x, int y)
Definition: CamWnd.cpp:1175
bool worldDirty
Definition: CamWnd.h:148
GLenum GLint x
Definition: glext.h:2849
bool Set()
Definition: XYWnd.h:57
virtual void BeginFrame(int windowWidth, int windowHeight)=0
int i
Definition: process.py:33
camera_t m_Camera
Definition: CamWnd.h:161
#define BOOL
Definition: mprintf.c:71
GLintptr offset
Definition: glext.h:3113
idVec3 m_vCull2
Definition: CamWnd.h:168
virtual ~CCamWnd()
Definition: CamWnd.cpp:97
brush_t brushes
Definition: EditorEntity.h:35
int Brush_TransformModel(brush_t *brush, idTriList *tris, idMatList *mats)
Definition: CamWnd.cpp:1449
virtual void ANIM_CreateAnimFrame(const idRenderModel *model, const idMD5Anim *anim, int numJoints, idJointMat *frame, int time, const idVec3 &offset, bool remove_origin_offset)
#define qglEnable
Definition: qgl_linked.h:101
srfTriangles_t * R_CopyStaticTriSurf(const srfTriangles_t *tri)
Definition: tr_trisurf.cpp:536
int Icmp(const char *text) const
Definition: Str.h:667
bool g_bSwitch
Definition: XYWnd.cpp:57
void SubdivideExplicit(int horzSubdivisions, int vertSubdivisions, bool genNormals, bool removeLinear=false)
void ToggleSelectMode()
Definition: CamWnd.cpp:1965
idStr & BackSlashesToSlashes(void)
Definition: Str.cpp:727
void Pointfile_Draw(void)
Definition: PointFile.cpp:137
afx_msg void OnSize(UINT nType, int cx, int cy)
Definition: CamWnd.cpp:1151
camera_draw_mode draw_mode
Definition: CamWnd.h:51
brush_t * g_pSplitList
Definition: CamWnd.cpp:191
idDict epairs
Definition: MapFile.h:166
idGameEdit * gameEdit
Definition: GameEdit.cpp:668
backEndState_t backEnd
Definition: tr_backend.cpp:35
int g_axialDest
Definition: CamWnd.cpp:50
virtual void InitEmpty(const char *name)=0
CPoint m_ptCursor
Definition: CamWnd.h:164
int GetHeight(void) const
virtual void AddModel(idRenderModel *model)=0
void Cam_PositionDrag()
Definition: CamWnd.cpp:517
Definition: File.h:50
void ToggleEntityMode()
Definition: CamWnd.cpp:1918
static const float M_RAD2DEG
Definition: Math.h:215
void Error(const char *pFormat,...)
Definition: cmdlib.cpp:45
Definition: CamWnd.h:64
idVec2 st
Definition: DrawVert.h:43
GLfloat GLfloat GLfloat v2
Definition: glext.h:3608
void BuildRendererState()
Definition: CamWnd.cpp:1707
brush_t g_brBackSplits
Definition: XYWnd.cpp:63
void Entity_UpdateSoundEmitter(entity_t *ent)
int m_nMouseButtons
Definition: PrefsDlg.h:101
const float DEFAULT_CURVE_MAX_ERROR
Definition: MapFile.h:49
void Subdivide(float maxHorizontalError, float maxVerticalError, float maxLength, bool genNormals=false)
bool m_bClipMode
Definition: CamWnd.h:171
qhandle_t lightDef
Definition: EditorEntity.h:38
int GetNumPoints(void) const
Definition: Winding.h:238
const GLubyte * c
Definition: glext.h:4677
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
Definition: Vector.h:808
float Length(void) const
Definition: Vector.h:631
void ToggleRenderMode()
Definition: CamWnd.cpp:1894
void ValidateAxialPoints()
Definition: CamWnd.cpp:53
idMapPrimitive * BrushToMapPrimitive(const brush_t *b, const idVec3 &origin)
Definition: EditorMap.cpp:559
void Cam_MouseLook()
Definition: CamWnd.cpp:530
void DrawPathLines()
Definition: XYWnd.cpp:3314
bool CullBrush(brush_t *b, bool cubicOnly)
Definition: CamWnd.cpp:742
void FreeRendererState()
Definition: CamWnd.cpp:1828
int Brush_ToTris(brush_t *brush, idTriList *tris, idMatList *mats, bool models, bool bmodel)
Definition: CamWnd.cpp:1503
static float Fabs(float f)
Definition: Math.h:779
#define qglPolygonMode
Definition: qgl_linked.h:229
idCommon * common
Definition: Common.cpp:206
idJointMat * joints
Definition: RenderWorld.h:135
void DrawEntityData()
Definition: CamWnd.cpp:1992
bool GetBool(const char *key, const char *defaultString="0") const
Definition: Dict.h:256
Definition: Dict.h:65
#define NULL
Definition: Lib.h:88
HDC hDC
Definition: wglext.h:383
srfTriangles_t * geometry
Definition: Model.h:147
#define qglListBase
Definition: qgl_linked.h:185
brush_t g_brFrontSplits
Definition: XYWnd.cpp:62
virtual idRenderModel * FindModel(const char *modelName)=0
float y
Definition: Vector.h:319
int m_nCullv2[3]
Definition: CamWnd.h:170
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
Definition: CamWnd.cpp:1166
#define qglEnd
Definition: qgl_linked.h:103
void * callbackData
Definition: RenderWorld.h:98
virtual const modelSurface_t * Surface(int surfaceNum) const =0
idImageManager * globalImages
Definition: Image_init.cpp:74
#define mat3_default
Definition: Matrix.h:413
#define qglColor3f
Definition: qgl_linked.h:50
CClipPoint g_Clip2
Definition: XYWnd.cpp:59
void * Mem_Alloc16(const int size)
Definition: Heap.cpp:1107
void Cam_MouseControl(float dtime)
Definition: CamWnd.cpp:552
void Select_RotateTexture(float amt, bool absolute)
struct entity_s * next
Definition: EditorEntity.h:34
CPtrArray & g_ptrSelectedFaces
#define qglGetFloatv
Definition: qgl_linked.h:132
GLint mode
Definition: glext.h:4165
bool selectMode
Definition: CamWnd.h:152
void R_FreeStaticTriSurf(srfTriangles_t *tri)
Definition: tr_trisurf.cpp:489
void setGLMode(int mode)
Definition: CamWnd.cpp:816
float x
Definition: Vector.h:54
float roll
Definition: Angles.h:55
void HandleKey(UINT nChar, UINT nRepCnt, UINT nFlags, bool bDown=true)
Definition: MainFrm.h:70
#define qglShadeModel
Definition: qgl_linked.h:282
face_t * m_pSide_select
Definition: CamWnd.h:166
int GetViewType()
Definition: XYWnd.h:154
void Mem_Free(void *ptr)
Definition: Heap.cpp:1087
idVec3 normal
Definition: DrawVert.h:44
idVec3 origin
Definition: CamWnd.h:48
Definition: CamWnd.h:37
GLenum GLsizei width
Definition: glext.h:2846
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(void)
float pitch
Definition: Angles.h:53
idRenderModel * hModel
Definition: RenderWorld.h:81
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
virtual void Printf(const char *fmt,...) id_attribute((format(printf
idCVar r_znear("r_znear","3", CVAR_RENDERER|CVAR_FLOAT,"near Z clip plane distance", 0.001f, 200.0f)
#define DEG2RAD(a)
Definition: Math.h:56
int m_nCullv1[3]
Definition: CamWnd.h:169
void Cam_MouseUp(int x, int y, int buttons)
Definition: CamWnd.cpp:674
void InitCull()
Definition: CamWnd.cpp:715
afx_msg void OnTimer(UINT nIDEvent)
Definition: CamWnd.cpp:2121
virtual const idMD5Anim * ANIM_GetAnimFromEntityDef(const char *classname, const char *animname)
void Select_ToCM()
Definition: CamWnd.cpp:1662
afx_msg void OnMButtonDown(UINT nFlags, CPoint point)
Definition: CamWnd.cpp:292
GLdouble GLdouble GLdouble y2
Definition: qgl.h:415
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)
Definition: CamWnd.cpp:324
qhandle_t modelDef
Definition: EditorEntity.h:39
afx_msg void OnRButtonDown(UINT nFlags, CPoint point)
Definition: CamWnd.cpp:308
void Cam_BuildMatrix()
Definition: CamWnd.cpp:439
virtual void FreeModel(idRenderModel *model)=0
#define qglPointSize
Definition: qgl_linked.h:228
GLfloat GLfloat v1
Definition: glext.h:3607
GLenum GLsizei GLsizei height
Definition: glext.h:2856
void ToggleAnimationMode()
Definition: CamWnd.cpp:1931
virtual bool WriteCollisionModelForMapEntity(const idMapEntity *mapEnt, const char *filename, const bool testTraceModel=true)=0
idVec3 m_vCull1
Definition: CamWnd.h:167
bool m_bCubicClipping
Definition: PrefsDlg.h:105
idEventLoop * eventLoop
Definition: EventLoop.cpp:35
#define YAW
Definition: Angles.h:42
void MarkWorldDirty()
Definition: CamWnd.cpp:1977
GLubyte GLubyte b
Definition: glext.h:4662
void Cam_MouseDown(int x, int y, int buttons)
Definition: CamWnd.cpp:613
idVec3 forward
Definition: CamWnd.h:55
void OriginalMouseDown(UINT nFlags, CPoint point)
Definition: CamWnd.cpp:410
idSoundEmitter * soundEmitter
Definition: EditorEntity.h:40
void Cam_Draw()
Definition: CamWnd.cpp:946
afx_msg void OnLButtonDown(UINT nFlags, CPoint point)
Definition: CamWnd.cpp:275
int height
Definition: CamWnd.h:46
idVec3 vieworg
Definition: RenderWorld.h:215
long LONG
bool g_bClipMode
Definition: XYWnd.cpp:55
LONG WINAPI CamWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: CamWnd.cpp:126
int Append(const type &obj)
Definition: List.h:646
void ToggleRebuildMode()
Definition: CamWnd.cpp:1906
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
idRenderModelManager * renderModelManager
Definition: Matrix.h:333
CClipPoint g_Clip1
Definition: XYWnd.cpp:58
bool saveValid
Definition: CamWnd.h:174
const int SCREEN_WIDTH
Definition: RenderSystem.h:153
float yaw
Definition: Angles.h:54
virtual idFile * OpenExplicitFileWrite(const char *OSPath)=0
void OriginalMouseUp(UINT nFlags, CPoint point)
Definition: CamWnd.cpp:397
void Cam_MouseMoved(int x, int y, int buttons)
Definition: CamWnd.cpp:683
bool soundMode
Definition: CamWnd.h:154
virtual void RemoveModel(idRenderModel *model)=0
IMPLEMENT_DYNCREATE(CCamWnd, CWnd)
tuple f
Definition: idal.py:89
int g_axialAnchor
Definition: CamWnd.cpp:49
GLint GLint i2
Definition: qgl.h:261
void Cam_Render()
Definition: CamWnd.cpp:2055
idAngles saveAng
Definition: CamWnd.h:173
int Num(void) const
Definition: List.h:265
const float DEFAULT_CURVE_MAX_LENGTH
Definition: MapFile.h:51
#define qglGetString
Definition: qgl_linked.h:146
idMat3 ToMat3(void) const
Definition: Angles.cpp:199
afx_msg void OnDestroy()
Definition: CamWnd.cpp:232
const GLcharARB * name
Definition: glext.h:3629
entity_t * FindEntity(const char *pszKey, const char *pszValue)
GLsizeiptr size
Definition: glext.h:3112
bool animationMode
Definition: CamWnd.h:153
CPrefsDlg & g_PrefsDlg
Definition: MainFrm.cpp:75
#define qglClear
Definition: qgl_linked.h:39
void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label)
Definition: splines.cpp:42
Definition: XYWnd.h:70
entity_t entities
Definition: EditorMap.cpp:47
void Mem_Free16(void *ptr)
Definition: Heap.cpp:1128
int width
Definition: CamWnd.h:46
#define qglColor4f
Definition: qgl_linked.h:66
Definition: Str.h:116
virtual const idVec3 & ANIM_GetModelOffsetFromEntityDef(const char *classname)
idDict epairs
Definition: EditorEntity.h:42
afx_msg void OnPaint()
Definition: CamWnd.cpp:197
class idSoundEmitter * referenceSound
Definition: RenderWorld.h:126
void Brush_Draw(brush_t *b, bool bSelected)
#define qglBlendFunc
Definition: qgl_linked.h:36
const char * c_str(void) const
Definition: Str.h:487
#define FALSE
Definition: mprintf.c:70
#define qglFinish
Definition: qgl_linked.h:118
GLint i1
Definition: qgl.h:261
#define DotProduct(a, b)
Definition: Vector.h:1994
virtual void ParseSpawnArgsToRenderLight(const idDict *args, renderLight_t *renderLight)
Definition: Light.cpp:80
glIndex_t * indexes
Definition: Model.h:102
void StripExtension(char *path)
Definition: cmdlib.cpp:222
virtual void ParseSpawnArgsToRenderEntity(const idDict *args, renderEntity_t *renderEntity)
Definition: Entity.cpp:229
idCameraDef * g_splineList
Definition: splines.cpp:35
afx_msg void OnRButtonUp(UINT nFlags, CPoint point)
Definition: CamWnd.cpp:316
idAngles ToAngles(void) const
Definition: Matrix.cpp:147
const idVec3 & ToVec3(void) const
Definition: Vector.h:1043
void Brush_DrawXY(brush_t *b, int nViewType, bool bSelected, bool ignoreViewType)
#define qglVertex3f
Definition: qgl_linked.h:349
void R_AllocStaticTriSurfIndexes(srfTriangles_t *tri, int numIndexes)
Definition: tr_trisurf.cpp:565
idVec3 saveOrg
Definition: CamWnd.h:172
void draw(bool editMode)
Definition: splines.cpp:862
#define EDITOR_WINDOWTEXT
Definition: Licensee.h:93
#define qglColor3fv
Definition: qgl_linked.h:51
CPoint m_ptButton
Definition: CamWnd.h:163
#define qglLoadIdentity
Definition: qgl_linked.h:186
void UpdateCameraView()
Definition: CamWnd.cpp:2136
GLint j
Definition: qgl.h:264
void Face_Draw(face_t *f)
#define VectorMA(v, s, b, o)
Definition: Vector.h:1998
int numIndexes
Definition: Model.h:101
bool rebuildMode
Definition: CamWnd.h:150
afx_msg void OnClose()
Definition: CamWnd.cpp:240
void Cam_ChangeFloor(bool up)
Definition: CamWnd.cpp:472
char * va(const char *fmt,...)
Definition: Str.cpp:1568
Win32Vars_t win32
Definition: win_main.cpp:65
face_t * Brush_Ray(idVec3 origin, idVec3 dir, brush_t *b, float *dist, bool testPrimitive)
virtual void CloseFile(idFile *f)=0
virtual const char * OSPathToRelativePath(const char *OSPath)=0
void R_ToggleSmpFrame(void)
Definition: tr_main.cpp:184
idSoundEmitter * referenceSound
Definition: RenderWorld.h:202
void ToggleSoundMode()
Definition: CamWnd.cpp:1948
GLfloat GLfloat p
Definition: glext.h:4674
Definition: List.h:84
idMat3 viewaxis
Definition: RenderWorld.h:216
CXYWnd * m_pXYFriend
Definition: CamWnd.h:87
float FloatForKey(entity_t *ent, const char *key)
virtual int NumJoints(void) const
Definition: Model_md5.cpp:827
void R_AllocStaticTriSurfVerts(srfTriangles_t *tri, int numVerts)
Definition: tr_trisurf.cpp:555
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
void SetSize(int patchWidth, int patchHeight)
float shaderParms[MAX_ENTITY_SHADER_PARMS]
Definition: RenderWorld.h:127
#define qglMatrixMode
Definition: qgl_linked.h:203
idVec3 vright
Definition: CamWnd.h:56
bool g_bAxialMode
Definition: CamWnd.cpp:51
virtual int Printf(const char *fmt,...) id_attribute((format(printf
Definition: File.cpp:260
idCollisionModelManager * collisionModelManager
GLuint start
Definition: glext.h:2845
eclass_t * eclass
Definition: EditorEntity.h:41
#define PITCH
Definition: Angles.h:41
idVec3 right
Definition: CamWnd.h:55
idDrawVert * verts
Definition: Model.h:99
int Milliseconds(void)
Definition: EventLoop.cpp:248
#define qglDepthFunc
Definition: qgl_linked.h:89
int GetWidth(void) const
int m_nMoveSpeed
Definition: PrefsDlg.h:103
virtual idRenderModel * AllocModel()=0
bool Map_IsBrushFiltered(brush_t *b)
Definition: EditorMap.cpp:924
afx_msg void OnMouseMove(UINT nFlags, CPoint point)
Definition: CamWnd.cpp:250
void Clear(void)
Definition: List.h:184
virtual int NumSurfaces() const =0