home *** CD-ROM | disk | FTP | other *** search
/ Quake++ for Quake / Quake++.iso / quake / qkview / 3dviewq.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-10  |  7.2 KB  |  317 lines

  1. #include <owlrc.h>
  2. #include <dialog.h>
  3. #include <applicat.h>
  4. #include <edit.h>
  5. #include <button.h>
  6. #include <mdi.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include <dir.h>
  11. #include <filedial.h>
  12.  
  13. #include "vector.h"
  14. #include "threedq.h"
  15. #include "3dview.h"
  16. #include "quake.h"
  17. #include "qbsp.h"
  18.  
  19. inline double MaxOf(double v1, double v2)
  20. {
  21.     return (v1 > v2) ? v1 : v2;
  22. }
  23.  
  24. inline long MinLong(long v1, long v2)
  25. {
  26.     return (v1 > v2) ? v2 : v1;
  27. }
  28.  
  29.  
  30. extern ARRAY<vertex_t> vertices;
  31. extern ARRAY<edge_t> edges;
  32. extern long numvertices,numedges;
  33.  
  34. class TThreeDMDIFrame : public TMDIFrame {
  35. public:
  36.     TThreeDMDIFrame(LPSTR title, LPSTR menu);
  37.     char Filename[MAXPATH];
  38. protected:
  39.     virtual PTWindowsObject CreateChild();
  40.     void CmPerspective() = [CM_FIRST + CM_PERSPECTIVE];
  41.     void CmMoveIn() = [CM_FIRST + CM_MOVEIN];
  42.     void CmMoveOut() = [CM_FIRST + CM_MOVEOUT];
  43.     void CmPrint() = [CM_FIRST + CM_PRINT];
  44. };
  45.  
  46. class TThreeDWindow : public TWindow {
  47. public:
  48.     TThreeD *ThreeD;
  49.     char Filename[MAXPATH];
  50.     int nUpdates;
  51.  
  52.     POINT MoveStart;
  53.     VECTOR FromStart, AtStart, UpStart;
  54.     BOOL Moving,Ldown,Shifted;
  55.     double Speed,RotSpeed;
  56.  
  57.     TThreeDWindow(PTWindow parent, LPSTR title);
  58.     virtual ~TThreeDWindow() { delete ThreeD; };
  59.     virtual void WMSize(RTMessage Msg) = [WM_FIRST + WM_SIZE] {
  60.                                                     TWindow::WMSize(Msg);
  61.                                                     ::InvalidateRect(HWindow, 0, FALSE); }
  62.     virtual void WMRButtonDown(RTMessage Msg) = [WM_FIRST + WM_RBUTTONDOWN];
  63.     virtual void WMLButtonDown(RTMessage Msg) = [WM_FIRST + WM_LBUTTONDOWN];
  64.     virtual void WMLButtonUp(RTMessage Msg) = [WM_FIRST + WM_LBUTTONUP];
  65.     virtual void WMMouseMove(RTMessage Msg) = [WM_FIRST + WM_MOUSEMOVE];
  66.     virtual void WMRButtonUp(RTMessage) = [WM_FIRST + WM_RBUTTONUP];
  67.  
  68.     void SaveCursor();
  69.     void Paint(HDC dc, PAINTSTRUCT _FAR &);
  70. };
  71.  
  72. TThreeDWindow::TThreeDWindow(PTWindow parent, LPSTR title)
  73.     :TWindow(parent,title)
  74. {
  75.  
  76.     ThreeD = new TThreeD;
  77.     Moving = Ldown = Shifted = FALSE;
  78.     Speed  = 4.0;
  79.     RotSpeed = 4.0;
  80.     nUpdates = 0;
  81.     _fstrcpy(Filename,title);
  82.  
  83.     if (ThreeD == NULL) ::MessageBox(HWindow,"Out of memory error","Error",MB_OK | MB_ICONEXCLAMATION);
  84.     else if (ThreeD->Read3DObject(Filename)) {
  85.         ThreeD->SetAt();
  86.         ThreeD->SetFrom();
  87.     }
  88.     else {
  89.         ::MessageBox(HWindow, "Failed to read file", "Error", MB_OK | MB_ICONEXCLAMATION);
  90.     }
  91. }
  92.  
  93.  
  94. void TThreeDWindow::Paint(HDC dc, PAINTSTRUCT _FAR &)
  95. {
  96.  
  97.     RECT rect;
  98.     ::GetClientRect(HWindow, &rect);
  99.     ::FillRect(dc, &rect, HBRUSH(GetStockObject(WHITE_BRUSH)));
  100.  
  101.     ThreeD->Display(dc,rect);
  102.  
  103. }
  104.  
  105.  
  106. inline void TThreeDWindow::SaveCursor()
  107. {
  108.     FromStart = ThreeD->From;
  109.     AtStart   = ThreeD->At;
  110.     UpStart   = ThreeD->Up;
  111.  
  112.     SetCursorPos(MoveStart.x,MoveStart.y);
  113.  
  114.     nUpdates = 0;
  115. }
  116.  
  117.  
  118. void TThreeDWindow::WMRButtonDown(RTMessage Msg)
  119. {
  120.     if (Msg.WParam & MK_LBUTTON) {
  121.         Ldown = TRUE;
  122.     }
  123.     GetCursorPos(&MoveStart);
  124.     SaveCursor();
  125.     Moving = TRUE;
  126.     nUpdates = 0;
  127.     SetCapture(HWindow);
  128.     ShowCursor(FALSE);
  129. }
  130.  
  131.  
  132. void TThreeDWindow::WMLButtonDown(RTMessage Msg)
  133. {
  134.     if (Moving) {
  135.         Ldown = TRUE;
  136.         SaveCursor();
  137.     }
  138. }
  139.  
  140.  
  141. void TThreeDWindow::WMLButtonUp(RTMessage Msg)
  142. {
  143.     Ldown = FALSE;
  144.     SaveCursor();
  145. }
  146.  
  147.  
  148.  
  149. void TThreeDWindow::WMMouseMove(RTMessage Msg)
  150. {
  151.     if (Moving) {
  152.         if (Ldown) {
  153.             POINT p;
  154.             GetCursorPos(&p);
  155.  
  156.             double x =   p.x - MoveStart.x;
  157.             double y = - p.y + MoveStart.y;
  158.  
  159.             VECTOR FtoAt = Subtract(AtStart, FromStart);
  160.             VECTOR Rotate = Cross(FtoAt,UpStart);
  161.  
  162.             Normalize(FtoAt);
  163.             double deg = y * RotSpeed / 360.0;
  164.             VECTOR delta = Add(Multiply(FtoAt,cos(deg)),Multiply(UpStart,sin(deg)));
  165.             ThreeD->At = Add(ThreeD->From,delta);
  166.  
  167.             deg = x *RotSpeed / 360.0;
  168.             delta = Cross(Rotate,delta);
  169.             Normalize(delta);
  170.             Normalize(Rotate);
  171.             ThreeD->Up = Add(Multiply(delta,cos(deg)),Multiply(Rotate,sin(deg)));
  172.         }
  173.         else {
  174.             if (Msg.WParam & MK_SHIFT) {
  175.                 // SHIFT = Strafe mode.
  176.                 if (!Shifted) {
  177.                     SaveCursor();
  178.                     Shifted = TRUE;
  179.                     return;
  180.                 }
  181.                 POINT p;
  182.                 GetCursorPos(&p);
  183.                 double x =   p.x - MoveStart.x;
  184.                 double y = - p.y + MoveStart.y;
  185.  
  186.                 VECTOR delta = Multiply(UpStart,y * Speed / Mag(UpStart));
  187.                 VECTOR AtUpCross = Cross(Subtract(AtStart, FromStart),UpStart);
  188.                 delta = Add(delta, Multiply(AtUpCross,x * Speed / Mag(AtUpCross)));
  189.                 ThreeD->From = Add(FromStart,delta);
  190.                 ThreeD->At = Add(AtStart, delta);
  191.             }
  192.             else {
  193.                 if (Shifted) {
  194.                     SaveCursor();
  195.                     Shifted = FALSE;
  196.                     return;
  197.                 }
  198.                 POINT p;
  199.                 GetCursorPos(&p);
  200.                 double x =   p.x - MoveStart.x;
  201.                 double y = - p.y + MoveStart.y;
  202.  
  203.                 VECTOR FtoAt = Subtract(AtStart, FromStart);
  204.                 VECTOR delta = Multiply(FtoAt,y*Speed/Mag(FtoAt));
  205.                 ThreeD->From = Add(FromStart,delta);
  206.  
  207.                 double deg = x * RotSpeed / 360.0;
  208.                 VECTOR Rotate = Cross(FtoAt,UpStart);
  209.                 delta = Add(Multiply(FtoAt,cos(deg)),Multiply(Rotate,sin(deg)));
  210.                 ThreeD->At = Add(ThreeD->From,delta);
  211.             }
  212.         }
  213.         ::InvalidateRect(HWindow, 0, FALSE);
  214.         if (nUpdates++ > 3) SaveCursor();
  215.     }
  216. }
  217.  
  218. void TThreeDWindow::WMRButtonUp(RTMessage)
  219. {
  220.     Moving = FALSE;
  221.     Ldown = FALSE;
  222.     ShowCursor(TRUE);
  223.     ReleaseCapture();
  224. }
  225.  
  226.  
  227. TThreeDMDIFrame::TThreeDMDIFrame(LPSTR title, LPSTR menu): TMDIFrame(title, menu) { }
  228.  
  229. PTWindowsObject TThreeDMDIFrame::CreateChild()
  230. {
  231.     char *Filename = (char *) malloc(MAXPATH);
  232.     strcpy(Filename,"*.bsp");
  233.     TFileDialog *tfd = new TFileDialog(this,SD_FILEOPEN,Filename);
  234.     if (tfd == NULL) OutOfMemory();
  235.     GetModule()->ExecDialog(tfd);
  236.  
  237.     LoadQuake(Filename);
  238.  
  239.     FILE *fp;
  240.     long i,nedge=0;
  241.     strcpy(Filename, "test.dat");
  242.  
  243.     if ((fp = fopen(Filename,"w")) == NULL) {
  244.         ::MessageBox(HWindow,"Couldn't open file",0,MB_OK);
  245.         return NULL;
  246.     }
  247.  
  248.     for(i=0;i<numedges;i++) {
  249.         if ((edges[i].startvertex+1 < NUMVERTICES) &&
  250.              (edges[i].endvertex+1 < NUMVERTICES) &&
  251.              (edges[i].startvertex != edges[i].endvertex))
  252.             nedge++;
  253.     }
  254.  
  255.     fprintf(fp,"0\n");
  256.     fprintf(fp,"%ld %ld\n",MinLong(numvertices,NUMVERTICES),nedge*3);
  257.  
  258.     for(i=0;i<MinLong(numvertices,NUMVERTICES);i++) {
  259.         fprintf(fp,"%f %f %f\n",vertices[i].x,vertices[i].y,vertices[i].z);
  260.     }
  261.  
  262.     for(i=0;i<numedges;i++) {
  263.         if ((edges[i].startvertex+1<NUMVERTICES) &&
  264.              (edges[i].endvertex+1 < NUMVERTICES) &&
  265.              (edges[i].startvertex != edges[i].endvertex))
  266.             fprintf(fp,"%u %u -1\n",edges[i].startvertex+1,
  267.                                             edges[i].endvertex+1);
  268.     }
  269.  
  270.     fclose(fp);
  271.  
  272.     return GetApplication()->MakeWindow(new TThreeDWindow(this, Filename));
  273.  
  274. }
  275.  
  276.  
  277. void TThreeDMDIFrame::CmPerspective()
  278. {
  279. }
  280.  
  281.  
  282. void TThreeDMDIFrame::CmMoveIn()
  283. {
  284. }
  285.  
  286.  
  287. void TThreeDMDIFrame::CmMoveOut()
  288. {
  289. }
  290.  
  291.  
  292. void TThreeDMDIFrame::CmPrint()
  293. {
  294. }
  295.  
  296.  
  297. class TThreeDApp : public TApplication {
  298. public:
  299.     TThreeDApp(LPSTR AName, HANDLE AnInstance, HANDLE APrevInstance, LPSTR ACmdLine, int ACmdShow):
  300.         TApplication(AName, AnInstance, APrevInstance, ACmdLine, ACmdShow) { };
  301.     void InitMainWindow();
  302. };
  303.  
  304. void TThreeDApp::InitMainWindow()
  305. {
  306.     MainWindow = new TThreeDMDIFrame("Tjoe","MENU_1");
  307. }
  308.  
  309.  
  310. int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance,
  311.                                   LPSTR lpCmdLine, int nCmdShow)
  312. {
  313.     TThreeDApp WinApp("Multiple views",hInstance,hPrevInstance,
  314.                                     lpCmdLine,nCmdShow);
  315.     WinApp.Run();
  316.     return WinApp.Status;
  317. }