home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / MODEL / VIEW2.C < prev    next >
C/C++ Source or Header  |  1996-06-15  |  11KB  |  452 lines

  1. /*
  2.  *        表示
  3.  *
  4.  *        Copyright    Koabayashi    1993.9.11
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <math.h>
  11. #include <assert.h>
  12.  
  13. #define    VIEW_LOCAL
  14.  
  15. #include "matrix.h"
  16. #include "poly.h"
  17. #include "view.h"
  18. #include "event.h"
  19. #include "input.h"
  20. #include "graph.h"
  21.  
  22. static    int        GetLogicalXY( int*, int*, ViewWindow*, int*, int*, int, int, int );
  23. static    void    DrawCursor( int );
  24. static    void    _DrawCursor( int[3], int[3], int );
  25. static    void    Draw2DCursor( int, int );
  26. static    void    Conv3DCursor( int*, int*, int* );
  27. static    int        isScrollRegion(ViewWindow *win, int x, int y);
  28.  
  29. /*    3Dカーソル表示    */
  30. void    ViewCursor( sw )
  31. int        sw ;
  32. {
  33.     if ( ( sw == ON ) ^ ( Mstat == ON ) )
  34.     {
  35.         DrawCursor( TRUE );
  36.         Draw2DCursor( PersMx, PersMy );
  37.         Mstat = sw ;
  38.     }
  39. }
  40.  
  41. /*    透視図のカーソル表示    */
  42. void    ViewCursorPers( sw )
  43. int        sw ;
  44. {
  45.     if ( Mstat == ON )
  46.     {
  47.         if ( sw != PersMstat )
  48.         {
  49.             if ( PersMstat == PERS_CURSOR_2D )
  50.                 Draw2DCursor( PersMx, PersMy );
  51.             else if ( PersMstat == PERS_CURSOR_3D )
  52.                 DrawCursor( FALSE );
  53.             PersMstat = sw ;
  54.             if ( PersMstat == PERS_CURSOR_2D )
  55.                 Draw2DCursor( PersMx, PersMy );
  56.             else if ( PersMstat == PERS_CURSOR_3D )
  57.                 DrawCursor( FALSE );
  58.         }
  59.     }
  60.     else
  61.         PersMstat = sw ;
  62. }
  63.  
  64. /*    3D カーソルの位置設定    */
  65. void    ViewSet3DCursorPos( x, y, z )
  66. int        x, y, z ;
  67. {
  68.     if ( Mstat == ON )
  69.         DrawCursor( TRUE );
  70.  
  71.     if ( ConvFlag )
  72.     {
  73.         Mx =(( x * ConvMat[0][0]
  74.              + y * ConvMat[1][0]
  75.              + z * ConvMat[2][0]
  76.              +     ConvMat[4][0]) >> 16)
  77.              +     ConvMat[3][0];
  78.         My =(( x * ConvMat[0][1]
  79.              + y * ConvMat[1][1]
  80.              + z * ConvMat[2][1]
  81.              +     ConvMat[4][1]) >> 16)
  82.              +     ConvMat[3][1];
  83.         Mz =(( x * ConvMat[0][2]
  84.              + y * ConvMat[1][2]
  85.              + z * ConvMat[2][2]
  86.              +     ConvMat[4][2]) >> 16)
  87.              +     ConvMat[3][2];
  88.     }
  89.     else
  90.     {
  91.         Mx = x ;
  92.         My = y ;
  93.         Mz = z ;
  94.     }
  95.  
  96.     PersMstat = PERS_CURSOR_3D ;
  97.  
  98.     if ( Mstat == ON )
  99.         DrawCursor( TRUE );
  100. }
  101.  
  102. /*    マウスのあるウインドウを得る    */
  103. int        MouseWindow( x, y )
  104. int        x, y ;    /*    スクリーン座標    */
  105. {
  106.     if ( ( ViewMode & VIEW_XY ) &&
  107.         WinXY.x <= x && x < WinXY.x + WinXY.h &&
  108.         WinXY.y <= y && y < WinXY.y + WinXY.v )
  109.     {
  110.         return VIEW_XY ;
  111.     }
  112.     if ( ( ViewMode & VIEW_YZ ) &&
  113.         WinYZ.x <= x && x < WinYZ.x + WinYZ.h &&
  114.         WinYZ.y <= y && y < WinYZ.y + WinYZ.v )
  115.     {
  116.         return VIEW_YZ ;
  117.     }
  118.     if ( ( ViewMode & VIEW_ZX ) &&
  119.         WinZX.x <= x && x < WinZX.x + WinZX.h &&
  120.         WinZX.y <= y && y < WinZX.y + WinZX.v )
  121.     {
  122.         return VIEW_ZX ;
  123.     }
  124.     if ( ( ViewMode & VIEW_PERS ) &&
  125.         WinPers.x <= x && x < WinPers.x + WinPers.h &&
  126.         WinPers.y <= y && y < WinPers.y + WinPers.v )
  127.     {
  128.         return VIEW_PERS ;
  129.     }
  130.     return 0;
  131. }
  132.  
  133. /*    カーソル移動    */
  134. void    ViewCursorPos( x, y )
  135. int        x, y ;    /*    スクリーン座標    */
  136. {
  137.     int        mode ;
  138.     int        savemstat;
  139.     
  140.     savemstat = Mstat ;
  141.     if ( Mstat == ON )
  142.         ViewCursor( OFF );
  143.  
  144.     if ( ( ViewMode & VIEW_PERS ) &&
  145.             WinPers.x + FRAME_WIDTH <= x && x < WinPers.x + WinPers.h - FRAME_WIDTH &&
  146.             WinPers.y + FRAME_WIDTH <= y && y < WinPers.y + WinPers.v - FRAME_WIDTH )
  147.     {
  148.         int i;
  149.         double r[3];
  150.         double v[3];
  151.         PersMx =   (( x - WinPers.x - WinPers.h / 2 ) << CURSOR_2D_SHIFT) / WinPers.h ;
  152.         PersMy = - (( y - WinPers.y - WinPers.v / 2 ) << CURSOR_2D_SHIFT) / WinPers.h ;
  153.  
  154.         v[0] = (double)(((int)Mx* PersMat[0][0]
  155.                        + (int)My* PersMat[1][0]
  156.                        + (int)Mz* PersMat[2][0]
  157.                        +          PersMat[4][0]) >> 16) + (double)PersMat[3][0];
  158.         v[1] = (double)(PersOffsetX - x) * v[0] / (double)PersScaleX;
  159.         v[2] = (double)(PersOffsetY - y) * v[0] / (double)PersScaleX;
  160.  
  161.         for( i = 0 ; i < 3 ; i++ )
  162.         {
  163.             r[i] =    v[0] * PersMatInv[0][i] +
  164.                     v[1] * PersMatInv[1][i] +
  165.                     v[2] * PersMatInv[2][i] +
  166.                            PersMatInv[3][i] ;
  167.         }
  168.         Mx = r[0];
  169.         My = r[1];
  170.         Mz = r[2];
  171. /*        mode = PERS_CURSOR_2D ;*/
  172.         mode = PERS_CURSOR_3D;
  173.     }
  174.     else if ( ( ViewMode & VIEW_XY ) && GetLogicalXY( &Mx, &My, &WinXY, &Cx, &Cy, x, y, VIEW_XY ) )
  175.     {
  176.         mode = PERS_CURSOR_3D ;
  177.     }
  178.     else if ( ( ViewMode & VIEW_YZ ) && GetLogicalXY( &My, &Mz, &WinYZ, &Cy, &Cz, x, y, VIEW_YZ ) )
  179.     {
  180.         mode = PERS_CURSOR_3D ;
  181.     }
  182.     else if ( ( ViewMode & VIEW_ZX ) && GetLogicalXY( &Mx, &Mz, &WinZX, &Cx, &Cz, x, y, VIEW_ZX ) )
  183.     {
  184.         mode = PERS_CURSOR_3D ;
  185.     }
  186.     else
  187.         mode = PersMstat ;
  188.  
  189.     PersMstat = mode ;
  190.     ViewCursor( savemstat );
  191. }
  192.  
  193. int ScrollCheck(int x, int y)
  194. {
  195.     if ((( ViewMode & VIEW_XY ) && isScrollRegion( &WinXY, x, y ))
  196.      || (( ViewMode & VIEW_YZ ) && isScrollRegion( &WinYZ, x, y ))
  197.      || (( ViewMode & VIEW_ZX ) && isScrollRegion( &WinZX, x, y ))) {
  198.         return TRUE;
  199.     }
  200.     return FALSE;
  201. }
  202.  
  203. static    int        isScrollRegion(ViewWindow *win, int x, int y)
  204. {
  205.     x -= win->x;
  206.     y -= win->y;
  207.     if (x < 0 || x >= win->h || y < 0 || y >= win->v) {
  208.         return FALSE;
  209.     }
  210.     if ( FRAME_WIDTH < x && x < win->h - FRAME_WIDTH &&
  211.          FRAME_WIDTH < y && y < win->v - FRAME_WIDTH ) {
  212.         return FALSE;
  213.     }
  214.     return TRUE;
  215. }
  216.  
  217. static    int        GetLogicalXY( xp, yp, win, cxp, cyp, x, y, viewtype )
  218. int        *xp, *yp ;
  219. ViewWindow    *win ;
  220. int        *cxp, *cyp ;
  221. int        x, y ;
  222. int        viewtype;
  223. {
  224.     x -= win->x ;
  225.     y -= win->y ;
  226.  
  227.     if ( 0 <= x && x < win->h && 0 <= y && y < win->v )
  228.     {
  229.         if ( FRAME_WIDTH < x && x < win->h - FRAME_WIDTH &&
  230.              FRAME_WIDTH < y && y < win->v - FRAME_WIDTH )
  231.         {
  232.             x = ( ( x - win->h / 2 ) * ZoomMinus / ZoomPlus ) + *cxp ;
  233.             y = ( - ( y - win->v / 2 ) * ZoomMinus / ZoomPlus ) + *cyp ;
  234.             if ( x > 0 )
  235.                 *xp = ( x + GridCursor / 2 ) / GridCursor * GridCursor ;
  236.             else
  237.                 *xp = - ( ( - x + GridCursor / 2 ) / GridCursor * GridCursor );
  238.             if ( y > 0 )
  239.                 *yp = ( y + GridCursor / 2 ) / GridCursor * GridCursor ;
  240.             else
  241.                 *yp = - ( ( - y + GridCursor / 2 ) / GridCursor * GridCursor );
  242.  
  243.  
  244.             if (*xp >  32767) *xp =  32767;
  245.             if (*xp < -32767) *xp = -32767;
  246.             if (*yp >  32767) *yp =  32767;
  247.             if (*yp < -32767) *yp = -32767;
  248.  
  249.         }
  250.         else
  251.         {
  252. #if 0
  253.             do {
  254.                 int xflag = FALSE, yflag = FALSE;
  255.                 int drawflag = viewtype, orgflag;
  256.                 if ( x <= FRAME_WIDTH
  257.                  && *cxp - WinMove-(win->h/2)*ZoomMinus/ZoomPlus > -32767) {
  258.                     *cxp -= WinMove ;
  259.                     xflag = TRUE;
  260.                 }
  261.                 if ( win->h - FRAME_WIDTH <= x
  262.                  && *cxp + WinMove+(win->h/2)*ZoomMinus/ZoomPlus < 32767) {
  263.                     *cxp += WinMove ;
  264.                     xflag = TRUE;
  265.                 }
  266.                 if ( y <= FRAME_WIDTH
  267.                  && *cyp + WinMove+(win->v/2)*ZoomMinus/ZoomPlus < 32767) {
  268.                     *cyp += WinMove ;
  269.                     yflag = TRUE;
  270.                 }
  271.                 if ( win->v - FRAME_WIDTH <= y
  272.                  && *cyp - WinMove-(win->v/2)*ZoomMinus/ZoomPlus > -32767) {
  273.                     *cyp -= WinMove ;
  274.                     yflag = TRUE;
  275.                 }
  276.                 if (xflag) {
  277.                     switch (viewtype) {
  278.                     case VIEW_XY: drawflag |= VIEW_ZX; break;
  279.                     case VIEW_YZ: drawflag |= VIEW_XY; break;
  280.                     case VIEW_ZX: drawflag |= VIEW_XY; break;
  281.                     }
  282.                 }
  283.                 if (yflag) {
  284.                     switch (viewtype) {
  285.                     case VIEW_XY: drawflag |= VIEW_YZ; break;
  286.                     case VIEW_YZ: drawflag |= VIEW_ZX; break;
  287.                     case VIEW_ZX: drawflag |= VIEW_YZ; break;
  288.                     }
  289.                 }
  290. /*                WaitMouseOff();*/
  291.                 orgflag = ViewMode;
  292.                 ViewMode &= drawflag;
  293.                 ViewLineAll( 0, 0, 4096, 4096, TRUE );
  294.                 ViewMode = orgflag;
  295.                 PeekInput();
  296.             } while ((MouseRight || MouseLeft)
  297.              && MouseX > win->x && MouseX < win->x + win->h
  298.              && MouseY > win->y && MouseY < win->y + win->v
  299.              && (MouseX < win->x + FRAME_WIDTH || MouseX > win->x+win->h-FRAME_WIDTH)
  300.              && (MouseY < win->y + FRAME_WIDTH || MouseY > win->y+win->v-FRAME_WIDTH));
  301.             } while (MouseRight || MouseLeft);
  302. #else
  303.             int xflag = FALSE, yflag = FALSE;
  304.             int drawflag = viewtype, orgflag;
  305.             if ( x <= FRAME_WIDTH
  306.              && *cxp-WinMove-(win->h/2)*ZoomMinus/ZoomPlus > -32767) {
  307.                 *cxp -= WinMove ;
  308.                 xflag = TRUE;
  309.             }
  310.             if ( win->h - FRAME_WIDTH <= x
  311.              && *cxp+WinMove+(win->h/2)*ZoomMinus/ZoomPlus < 32767) {
  312.                 *cxp += WinMove ;
  313.                 xflag = TRUE;
  314.             }
  315.             if ( y <= FRAME_WIDTH
  316.              && *cyp+WinMove+(win->v/2)*ZoomMinus/ZoomPlus < 32767) {
  317.                 *cyp += WinMove ;
  318.                 yflag = TRUE;
  319.             }
  320.             if ( win->v - FRAME_WIDTH <= y
  321.              && *cyp-WinMove-(win->v/2)*ZoomMinus/ZoomPlus > -32767) {
  322.                 *cyp -= WinMove ;
  323.                 yflag = TRUE;
  324.             }
  325.             if (xflag) {
  326.                 switch (viewtype) {
  327.                 case VIEW_XY: drawflag |= VIEW_ZX; break;
  328.                 case VIEW_YZ: drawflag |= VIEW_XY; break;
  329.                 case VIEW_ZX: drawflag |= VIEW_XY; break;
  330.                 }
  331.             }
  332.             if (yflag) {
  333.                 switch (viewtype) {
  334.                 case VIEW_XY: drawflag |= VIEW_YZ; break;
  335.                 case VIEW_YZ: drawflag |= VIEW_ZX; break;
  336.                 case VIEW_ZX: drawflag |= VIEW_YZ; break;
  337.                 }
  338.             }
  339.             orgflag = ViewMode;
  340.             ViewMode &= drawflag;
  341.             ViewLineAll( 0, 0, 4096, 4096, TRUE );
  342.             ViewMode = orgflag;
  343. #endif
  344.         }
  345.         return TRUE ;
  346.     }
  347.     else
  348.         return FALSE ;
  349. }
  350.  
  351. /*    カーソルの表示    */
  352. static    void    DrawCursor( sw )
  353. int        sw ;
  354. {
  355.     int        a ;
  356.     int        pos1[3], pos2[3] ;
  357.  
  358.     a = WinXY.h > WinZX.h ? WinXY.h : WinZX.h ;
  359.     pos1[0] = Cx - ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos1[0] < -32767) pos1[0] = -32767;
  360.     pos2[0] = Cx + ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos2[0] >  32767) pos2[0] =  32767;
  361.     pos1[1] = pos2[1] = My ;
  362.     pos1[2] = pos2[2] = Mz ;
  363.     _DrawCursor( pos1, pos2, sw );
  364.  
  365.     a = WinYZ.h > WinXY.v ? WinYZ.h : WinXY.v ;
  366.     pos1[0] = pos2[0] = Mx ;
  367.     pos1[1] = Cy - ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos1[1] < -32767) pos1[1] = -32767;
  368.     pos2[1] = Cy + ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos2[1] >  32767) pos2[1] =  32767;
  369.     pos1[2] = pos2[2] = Mz ;
  370.     _DrawCursor( pos1, pos2, sw );
  371.  
  372.     a = WinZX.v > WinYZ.v ? WinZX.v : WinYZ.v ;
  373.     pos1[0] = pos2[0] = Mx ;
  374.     pos1[1] = pos2[1] = My ;
  375.     pos1[2] = Cz - ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos1[2] < -32767) pos1[2] = -32767;
  376.     pos2[2] = Cz + ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos2[2] >  32767) pos2[2] =  32767;
  377.     _DrawCursor( pos1, pos2, sw );
  378. }
  379.  
  380. static    void    _DrawCursor( pos1, pos2, sw )
  381. int        pos1[3], pos2[3] ;
  382. int        sw ;
  383. {
  384.     Vertex    v1, v2 ;
  385.  
  386.     if ( ConvFlag )
  387.     {
  388.         Conv3DCursor( &pos1[0], &pos1[1], &pos1[2] );
  389.         Conv3DCursor( &pos2[0], &pos2[1], &pos2[2] );
  390.     }
  391.     v1.x = pos1[0] ;
  392.     v1.y = pos1[1] ;
  393.     v1.z = pos1[2] ;
  394.     v2.x = pos2[0] ;
  395.     v2.y = pos2[1] ;
  396.     v2.z = pos2[2] ;
  397.     if ( sw )
  398.     {
  399.         ToScreen( pos1, &v1 );
  400.         ToScreen( pos2, &v2 );
  401.         DrawLineForWin( pos1, pos2, CURSOR_COLOR );
  402.     }
  403.     if ( PersMstat == PERS_CURSOR_3D )
  404.         DrawLineForPers( &v1, &v2, CURSOR_COLOR );
  405. }
  406.  
  407. /*    2D カーソルの表示    */
  408. static    void    Draw2DCursor( x, y )
  409. int        x, y ;
  410. {
  411.     x =   ((x * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.x + WinPers.h / 2 ;
  412.     y = - ((y * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.y + WinPers.v / 2 ;
  413.     if ( PersMstat == PERS_CURSOR_2D )
  414.     {
  415.         ClipLine( &WinPers, x, -32768, x, 32768, CURSOR_COLOR );
  416.         ClipLine( &WinPers, -32768, y, 32768, y, CURSOR_COLOR );
  417.     }
  418. }
  419.  
  420. /*    3Dカーソル位置の取得    */
  421. void    Get3DCursor( mxp, myp, mzp )
  422. int        *mxp, *myp, *mzp ;
  423. {
  424.     *mxp = Mx ;
  425.     *myp = My ;
  426.     *mzp = Mz ;
  427.  
  428.     Conv3DCursor( mxp, myp, mzp );
  429. }
  430.  
  431. /*    3Dカーソル変換    */
  432. static    void    Conv3DCursor( mxp, myp, mzp )
  433. int        *mxp, *myp, *mzp ;
  434. {
  435.     if ( ConvFlag )
  436.     {
  437.         int        i, cur[3] ;
  438.  
  439.         for( i = 0 ; i < 3 ; i++ )
  440.         {
  441.             cur[i] = (( *mxp * ConvInv[0][i]
  442.                       +  *myp * ConvInv[1][i]
  443.                      +  *mzp * ConvInv[2][i]
  444.                      +         ConvInv[4][i]) >> 16)
  445.                      +         ConvInv[3][i];
  446.         }
  447.         *mxp = cur[0] ;
  448.         *myp = cur[1] ;
  449.         *mzp = cur[2] ;
  450.     }
  451. }
  452.