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 >
Wrap
C/C++ Source or Header
|
1996-06-15
|
11KB
|
452 lines
/*
* 表示
*
* Copyright Koabayashi 1993.9.11
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#define VIEW_LOCAL
#include "matrix.h"
#include "poly.h"
#include "view.h"
#include "event.h"
#include "input.h"
#include "graph.h"
static int GetLogicalXY( int*, int*, ViewWindow*, int*, int*, int, int, int );
static void DrawCursor( int );
static void _DrawCursor( int[3], int[3], int );
static void Draw2DCursor( int, int );
static void Conv3DCursor( int*, int*, int* );
static int isScrollRegion(ViewWindow *win, int x, int y);
/* 3Dカーソル表示 */
void ViewCursor( sw )
int sw ;
{
if ( ( sw == ON ) ^ ( Mstat == ON ) )
{
DrawCursor( TRUE );
Draw2DCursor( PersMx, PersMy );
Mstat = sw ;
}
}
/* 透視図のカーソル表示 */
void ViewCursorPers( sw )
int sw ;
{
if ( Mstat == ON )
{
if ( sw != PersMstat )
{
if ( PersMstat == PERS_CURSOR_2D )
Draw2DCursor( PersMx, PersMy );
else if ( PersMstat == PERS_CURSOR_3D )
DrawCursor( FALSE );
PersMstat = sw ;
if ( PersMstat == PERS_CURSOR_2D )
Draw2DCursor( PersMx, PersMy );
else if ( PersMstat == PERS_CURSOR_3D )
DrawCursor( FALSE );
}
}
else
PersMstat = sw ;
}
/* 3D カーソルの位置設定 */
void ViewSet3DCursorPos( x, y, z )
int x, y, z ;
{
if ( Mstat == ON )
DrawCursor( TRUE );
if ( ConvFlag )
{
Mx =(( x * ConvMat[0][0]
+ y * ConvMat[1][0]
+ z * ConvMat[2][0]
+ ConvMat[4][0]) >> 16)
+ ConvMat[3][0];
My =(( x * ConvMat[0][1]
+ y * ConvMat[1][1]
+ z * ConvMat[2][1]
+ ConvMat[4][1]) >> 16)
+ ConvMat[3][1];
Mz =(( x * ConvMat[0][2]
+ y * ConvMat[1][2]
+ z * ConvMat[2][2]
+ ConvMat[4][2]) >> 16)
+ ConvMat[3][2];
}
else
{
Mx = x ;
My = y ;
Mz = z ;
}
PersMstat = PERS_CURSOR_3D ;
if ( Mstat == ON )
DrawCursor( TRUE );
}
/* マウスのあるウインドウを得る */
int MouseWindow( x, y )
int x, y ; /* スクリーン座標 */
{
if ( ( ViewMode & VIEW_XY ) &&
WinXY.x <= x && x < WinXY.x + WinXY.h &&
WinXY.y <= y && y < WinXY.y + WinXY.v )
{
return VIEW_XY ;
}
if ( ( ViewMode & VIEW_YZ ) &&
WinYZ.x <= x && x < WinYZ.x + WinYZ.h &&
WinYZ.y <= y && y < WinYZ.y + WinYZ.v )
{
return VIEW_YZ ;
}
if ( ( ViewMode & VIEW_ZX ) &&
WinZX.x <= x && x < WinZX.x + WinZX.h &&
WinZX.y <= y && y < WinZX.y + WinZX.v )
{
return VIEW_ZX ;
}
if ( ( ViewMode & VIEW_PERS ) &&
WinPers.x <= x && x < WinPers.x + WinPers.h &&
WinPers.y <= y && y < WinPers.y + WinPers.v )
{
return VIEW_PERS ;
}
return 0;
}
/* カーソル移動 */
void ViewCursorPos( x, y )
int x, y ; /* スクリーン座標 */
{
int mode ;
int savemstat;
savemstat = Mstat ;
if ( Mstat == ON )
ViewCursor( OFF );
if ( ( ViewMode & VIEW_PERS ) &&
WinPers.x + FRAME_WIDTH <= x && x < WinPers.x + WinPers.h - FRAME_WIDTH &&
WinPers.y + FRAME_WIDTH <= y && y < WinPers.y + WinPers.v - FRAME_WIDTH )
{
int i;
double r[3];
double v[3];
PersMx = (( x - WinPers.x - WinPers.h / 2 ) << CURSOR_2D_SHIFT) / WinPers.h ;
PersMy = - (( y - WinPers.y - WinPers.v / 2 ) << CURSOR_2D_SHIFT) / WinPers.h ;
v[0] = (double)(((int)Mx* PersMat[0][0]
+ (int)My* PersMat[1][0]
+ (int)Mz* PersMat[2][0]
+ PersMat[4][0]) >> 16) + (double)PersMat[3][0];
v[1] = (double)(PersOffsetX - x) * v[0] / (double)PersScaleX;
v[2] = (double)(PersOffsetY - y) * v[0] / (double)PersScaleX;
for( i = 0 ; i < 3 ; i++ )
{
r[i] = v[0] * PersMatInv[0][i] +
v[1] * PersMatInv[1][i] +
v[2] * PersMatInv[2][i] +
PersMatInv[3][i] ;
}
Mx = r[0];
My = r[1];
Mz = r[2];
/* mode = PERS_CURSOR_2D ;*/
mode = PERS_CURSOR_3D;
}
else if ( ( ViewMode & VIEW_XY ) && GetLogicalXY( &Mx, &My, &WinXY, &Cx, &Cy, x, y, VIEW_XY ) )
{
mode = PERS_CURSOR_3D ;
}
else if ( ( ViewMode & VIEW_YZ ) && GetLogicalXY( &My, &Mz, &WinYZ, &Cy, &Cz, x, y, VIEW_YZ ) )
{
mode = PERS_CURSOR_3D ;
}
else if ( ( ViewMode & VIEW_ZX ) && GetLogicalXY( &Mx, &Mz, &WinZX, &Cx, &Cz, x, y, VIEW_ZX ) )
{
mode = PERS_CURSOR_3D ;
}
else
mode = PersMstat ;
PersMstat = mode ;
ViewCursor( savemstat );
}
int ScrollCheck(int x, int y)
{
if ((( ViewMode & VIEW_XY ) && isScrollRegion( &WinXY, x, y ))
|| (( ViewMode & VIEW_YZ ) && isScrollRegion( &WinYZ, x, y ))
|| (( ViewMode & VIEW_ZX ) && isScrollRegion( &WinZX, x, y ))) {
return TRUE;
}
return FALSE;
}
static int isScrollRegion(ViewWindow *win, int x, int y)
{
x -= win->x;
y -= win->y;
if (x < 0 || x >= win->h || y < 0 || y >= win->v) {
return FALSE;
}
if ( FRAME_WIDTH < x && x < win->h - FRAME_WIDTH &&
FRAME_WIDTH < y && y < win->v - FRAME_WIDTH ) {
return FALSE;
}
return TRUE;
}
static int GetLogicalXY( xp, yp, win, cxp, cyp, x, y, viewtype )
int *xp, *yp ;
ViewWindow *win ;
int *cxp, *cyp ;
int x, y ;
int viewtype;
{
x -= win->x ;
y -= win->y ;
if ( 0 <= x && x < win->h && 0 <= y && y < win->v )
{
if ( FRAME_WIDTH < x && x < win->h - FRAME_WIDTH &&
FRAME_WIDTH < y && y < win->v - FRAME_WIDTH )
{
x = ( ( x - win->h / 2 ) * ZoomMinus / ZoomPlus ) + *cxp ;
y = ( - ( y - win->v / 2 ) * ZoomMinus / ZoomPlus ) + *cyp ;
if ( x > 0 )
*xp = ( x + GridCursor / 2 ) / GridCursor * GridCursor ;
else
*xp = - ( ( - x + GridCursor / 2 ) / GridCursor * GridCursor );
if ( y > 0 )
*yp = ( y + GridCursor / 2 ) / GridCursor * GridCursor ;
else
*yp = - ( ( - y + GridCursor / 2 ) / GridCursor * GridCursor );
if (*xp > 32767) *xp = 32767;
if (*xp < -32767) *xp = -32767;
if (*yp > 32767) *yp = 32767;
if (*yp < -32767) *yp = -32767;
}
else
{
#if 0
do {
int xflag = FALSE, yflag = FALSE;
int drawflag = viewtype, orgflag;
if ( x <= FRAME_WIDTH
&& *cxp - WinMove-(win->h/2)*ZoomMinus/ZoomPlus > -32767) {
*cxp -= WinMove ;
xflag = TRUE;
}
if ( win->h - FRAME_WIDTH <= x
&& *cxp + WinMove+(win->h/2)*ZoomMinus/ZoomPlus < 32767) {
*cxp += WinMove ;
xflag = TRUE;
}
if ( y <= FRAME_WIDTH
&& *cyp + WinMove+(win->v/2)*ZoomMinus/ZoomPlus < 32767) {
*cyp += WinMove ;
yflag = TRUE;
}
if ( win->v - FRAME_WIDTH <= y
&& *cyp - WinMove-(win->v/2)*ZoomMinus/ZoomPlus > -32767) {
*cyp -= WinMove ;
yflag = TRUE;
}
if (xflag) {
switch (viewtype) {
case VIEW_XY: drawflag |= VIEW_ZX; break;
case VIEW_YZ: drawflag |= VIEW_XY; break;
case VIEW_ZX: drawflag |= VIEW_XY; break;
}
}
if (yflag) {
switch (viewtype) {
case VIEW_XY: drawflag |= VIEW_YZ; break;
case VIEW_YZ: drawflag |= VIEW_ZX; break;
case VIEW_ZX: drawflag |= VIEW_YZ; break;
}
}
/* WaitMouseOff();*/
orgflag = ViewMode;
ViewMode &= drawflag;
ViewLineAll( 0, 0, 4096, 4096, TRUE );
ViewMode = orgflag;
PeekInput();
} while ((MouseRight || MouseLeft)
&& MouseX > win->x && MouseX < win->x + win->h
&& MouseY > win->y && MouseY < win->y + win->v
&& (MouseX < win->x + FRAME_WIDTH || MouseX > win->x+win->h-FRAME_WIDTH)
&& (MouseY < win->y + FRAME_WIDTH || MouseY > win->y+win->v-FRAME_WIDTH));
} while (MouseRight || MouseLeft);
#else
int xflag = FALSE, yflag = FALSE;
int drawflag = viewtype, orgflag;
if ( x <= FRAME_WIDTH
&& *cxp-WinMove-(win->h/2)*ZoomMinus/ZoomPlus > -32767) {
*cxp -= WinMove ;
xflag = TRUE;
}
if ( win->h - FRAME_WIDTH <= x
&& *cxp+WinMove+(win->h/2)*ZoomMinus/ZoomPlus < 32767) {
*cxp += WinMove ;
xflag = TRUE;
}
if ( y <= FRAME_WIDTH
&& *cyp+WinMove+(win->v/2)*ZoomMinus/ZoomPlus < 32767) {
*cyp += WinMove ;
yflag = TRUE;
}
if ( win->v - FRAME_WIDTH <= y
&& *cyp-WinMove-(win->v/2)*ZoomMinus/ZoomPlus > -32767) {
*cyp -= WinMove ;
yflag = TRUE;
}
if (xflag) {
switch (viewtype) {
case VIEW_XY: drawflag |= VIEW_ZX; break;
case VIEW_YZ: drawflag |= VIEW_XY; break;
case VIEW_ZX: drawflag |= VIEW_XY; break;
}
}
if (yflag) {
switch (viewtype) {
case VIEW_XY: drawflag |= VIEW_YZ; break;
case VIEW_YZ: drawflag |= VIEW_ZX; break;
case VIEW_ZX: drawflag |= VIEW_YZ; break;
}
}
orgflag = ViewMode;
ViewMode &= drawflag;
ViewLineAll( 0, 0, 4096, 4096, TRUE );
ViewMode = orgflag;
#endif
}
return TRUE ;
}
else
return FALSE ;
}
/* カーソルの表示 */
static void DrawCursor( sw )
int sw ;
{
int a ;
int pos1[3], pos2[3] ;
a = WinXY.h > WinZX.h ? WinXY.h : WinZX.h ;
pos1[0] = Cx - ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos1[0] < -32767) pos1[0] = -32767;
pos2[0] = Cx + ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos2[0] > 32767) pos2[0] = 32767;
pos1[1] = pos2[1] = My ;
pos1[2] = pos2[2] = Mz ;
_DrawCursor( pos1, pos2, sw );
a = WinYZ.h > WinXY.v ? WinYZ.h : WinXY.v ;
pos1[0] = pos2[0] = Mx ;
pos1[1] = Cy - ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos1[1] < -32767) pos1[1] = -32767;
pos2[1] = Cy + ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos2[1] > 32767) pos2[1] = 32767;
pos1[2] = pos2[2] = Mz ;
_DrawCursor( pos1, pos2, sw );
a = WinZX.v > WinYZ.v ? WinZX.v : WinYZ.v ;
pos1[0] = pos2[0] = Mx ;
pos1[1] = pos2[1] = My ;
pos1[2] = Cz - ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos1[2] < -32767) pos1[2] = -32767;
pos2[2] = Cz + ( a / 2 ) * ZoomMinus / ZoomPlus ; if (pos2[2] > 32767) pos2[2] = 32767;
_DrawCursor( pos1, pos2, sw );
}
static void _DrawCursor( pos1, pos2, sw )
int pos1[3], pos2[3] ;
int sw ;
{
Vertex v1, v2 ;
if ( ConvFlag )
{
Conv3DCursor( &pos1[0], &pos1[1], &pos1[2] );
Conv3DCursor( &pos2[0], &pos2[1], &pos2[2] );
}
v1.x = pos1[0] ;
v1.y = pos1[1] ;
v1.z = pos1[2] ;
v2.x = pos2[0] ;
v2.y = pos2[1] ;
v2.z = pos2[2] ;
if ( sw )
{
ToScreen( pos1, &v1 );
ToScreen( pos2, &v2 );
DrawLineForWin( pos1, pos2, CURSOR_COLOR );
}
if ( PersMstat == PERS_CURSOR_3D )
DrawLineForPers( &v1, &v2, CURSOR_COLOR );
}
/* 2D カーソルの表示 */
static void Draw2DCursor( x, y )
int x, y ;
{
x = ((x * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.x + WinPers.h / 2 ;
y = - ((y * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.y + WinPers.v / 2 ;
if ( PersMstat == PERS_CURSOR_2D )
{
ClipLine( &WinPers, x, -32768, x, 32768, CURSOR_COLOR );
ClipLine( &WinPers, -32768, y, 32768, y, CURSOR_COLOR );
}
}
/* 3Dカーソル位置の取得 */
void Get3DCursor( mxp, myp, mzp )
int *mxp, *myp, *mzp ;
{
*mxp = Mx ;
*myp = My ;
*mzp = Mz ;
Conv3DCursor( mxp, myp, mzp );
}
/* 3Dカーソル変換 */
static void Conv3DCursor( mxp, myp, mzp )
int *mxp, *myp, *mzp ;
{
if ( ConvFlag )
{
int i, cur[3] ;
for( i = 0 ; i < 3 ; i++ )
{
cur[i] = (( *mxp * ConvInv[0][i]
+ *myp * ConvInv[1][i]
+ *mzp * ConvInv[2][i]
+ ConvInv[4][i]) >> 16)
+ ConvInv[3][i];
}
*mxp = cur[0] ;
*myp = cur[1] ;
*mzp = cur[2] ;
}
}