home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
MODEL
/
VIEW3.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-05
|
32KB
|
1,291 lines
/*
* 表示
*
* Copyright Koabayashi 1993.10.24
*/
#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 "model.h"
#include "graph.h"
#include "input.h"
static short UpArrow[] = {
0xCC00, 0xCC00, 0x8400, 0x8400, 0x0000, 0x0000,
};
static short DownArrow[] = {
0x0000, 0x0000, 0x8400, 0x8400, 0xCC00, 0xCC00,
};
static short LeftArrow[] = {
0xF000, 0xC000, 0x0000, 0x0000, 0xC000, 0xF000,
};
static short RightArrow[] = {
0x3C00, 0x0C00, 0x0000, 0x0000, 0x0C00, 0x3C00,
};
static int ViewX1 = 0 ; /* ビューポート */
static int ViewY1 = 0 ;
static int ViewX2 = 4096;
static int ViewY2 = 4096 ;
#ifdef X68K
static int TmpClear = TRUE ;
#elif defined(PC98) || defined(PC) || defined(WINDOWS)
static int TmpClear = FALSE ;
#else
#error "X68K or PC98 or PC or WINDOWS must be defined"
#endif
#define swap( a, b ) { int _w ; _w = a ; a = b ; b = _w ; }
#define MAXTEMPLINE 4096
typedef struct {
short x1, y1, z1;
short x2, y2, z2;
short px1, py1, pz1;
short px2, py2, pz2;
} TempEdge;
TempEdge tempedge[MAXTEMPLINE];
static int tempedgecount;
typedef struct {
short x, y, z;
short px, py, pz;
} TempVertex;
TempVertex tempvertex[MAXTEMPLINE];
static int tempvertexcount;
static void DisplayFrame( ViewWindow*, int );
static void DisplayGrid( ViewWindow*, int, int, int );
static void ClearWin( ViewWindow*, int );
static int ViewIn( ViewWindow*, int, int, int, int );
static void DrawVertexWin( Polygon*, int );
static void DrawVertexPers( Polygon*, int );
static void DrawVector( Polygon*, int );
static void DrawPolyVector( Polygon*, int );
extern int viewbox_drawflag;
extern Vertex viewbox_p1, viewbox_p2;
extern Matrix viewbox_mat;
extern int viewbox2d_x1, viewbox2d_y1, viewbox2d_x2, viewbox2d_y2;
extern int viewbox2d_drawflag ;
/* フレーム表示 */
void ViewFrame()
{
/*graph_cls( 0 );*/
if ( ViewMode & VIEW_XY )
DisplayFrame( &WinXY, TRUE );
if ( ViewMode & VIEW_YZ )
DisplayFrame( &WinYZ, TRUE );
if ( ViewMode & VIEW_ZX )
DisplayFrame( &WinZX, TRUE );
if ( ViewMode & VIEW_PERS )
DisplayFrame( &WinPers, FALSE );
}
static void DisplayFrame( win, sw )
ViewWindow *win ;
int sw ;
{
int x1, y1, x2, y2 ;
x1 = win->x ;
y1 = win->y ;
x2 = win->x + win->h - 1 ;
y2 = win->y + win->v - 1 ;
graph_fill( x1, y1, x2, y1+(FRAME_WIDTH-2), FRAME_COLOR );
graph_fill( x1, y2-(FRAME_WIDTH-2), x2, y2, FRAME_COLOR );
graph_fill( x1, y1, x1+(FRAME_WIDTH-2), y2, FRAME_COLOR );
graph_fill( x2-(FRAME_WIDTH-2), y1, x2, y2, FRAME_COLOR );
if ( sw )
{
graph_pattern( ( x1 + x2 ) / 2 - 3, y1 + 3, FRAME_COLOR, UpArrow, 6, 6 );
graph_pattern( ( x1 + x2 ) / 2 - 3, y2 - 9, FRAME_COLOR, DownArrow, 6, 6 );
graph_pattern( x1 + 3, ( y1 + y2 ) / 2 - 3, FRAME_COLOR, LeftArrow, 6, 6 );
graph_pattern( x2 - 9, ( y1 + y2 ) / 2 - 3, FRAME_COLOR, RightArrow, 6, 6 );
}
graph_box( x1, y1, x2, y2, TRUE );
x1 += FRAME_WIDTH - 1 ;
y1 += FRAME_WIDTH - 1 ;
x2 -= FRAME_WIDTH - 1 ;
y2 -= FRAME_WIDTH - 1 ;
graph_box( x1, y1, x2, y2, FALSE );
}
static void DisplayGrid( win, cx, cy, col )
ViewWindow *win ;
int cx, cy ;
int col ;
{
int x, y, size, grid ;
int start, end, sx, sy ;
ClearWin( win, BG_COLOR );
#ifdef X68K
ClearWin( win, TMP_COLOR );
#endif
grid = GridDisplay * ZoomPlus / ZoomMinus ;
if ( grid <= 2 )
return ;
size = ( win->h - FRAME_WIDTH * 2 ) / grid
+ ( win->v - FRAME_WIDTH * 2 ) / grid + 4 ;
start = ( ( - win->h / 2 + FRAME_WIDTH ) * ZoomMinus / ZoomPlus ) + cx ;
start = start / GridDisplay * GridDisplay ;
end = ( ( win->h / 2 - FRAME_WIDTH ) * ZoomMinus / ZoomPlus ) + cx ;
for( x = start ; x < end ; x += GridDisplay )
{
sx = ( ( x - cx ) * ZoomPlus / ZoomMinus ) + win->x + win->h / 2 ;
/* ClipLine( win, sx, win->y+FRAME_WIDTH, sx, win->y+win->v-FRAME_WIDTH-1, col );*/
if (win->x + FRAME_WIDTH <= sx && sx < win->x + win->h - FRAME_WIDTH) {
if (x == 0) {
graph_line(sx, win->y+FRAME_WIDTH, sx, win->y+win->v-FRAME_WIDTH-1, col );
} else {
graph_dashline(sx, win->y+FRAME_WIDTH, sx, win->y+win->v-FRAME_WIDTH-1, col );
}
}
}
start = ( ( - win->v / 2 + FRAME_WIDTH ) * ZoomMinus / ZoomPlus ) + cy ;
start = start / GridDisplay * GridDisplay ;
end = ( ( win->v / 2 - FRAME_WIDTH ) * ZoomMinus / ZoomPlus ) + cy ;
for( y = start ; y < end ; y += GridDisplay )
{
sy = ( -( y - cy ) * ZoomPlus / ZoomMinus ) + win->y + win->v / 2 ;
/* ClipLine( win, win->x+FRAME_WIDTH, sy, win->x+win->h-FRAME_WIDTH-1, sy, col );*/
if (win->y + FRAME_WIDTH <= sy && sy < win->y + win->v - FRAME_WIDTH) {
if (y == 0) {
graph_line(win->x+FRAME_WIDTH, sy, win->x+win->h-FRAME_WIDTH-1, sy, col );
} else {
graph_dashline(win->x+FRAME_WIDTH, sy, win->x+win->h-FRAME_WIDTH-1, sy, col );
}
}
}
}
static void ViewTempLine(int pos)
{
int i;
int fxy, fyz, fzx;
int px1, px2, py1, py2, pz1, pz2;
px1 = tempedge[pos].px1;
py1 = tempedge[pos].py1;
pz1 = tempedge[pos].pz1;
px2 = tempedge[pos].px2;
py2 = tempedge[pos].py2;
pz2 = tempedge[pos].pz2;
fxy = fyz = fzx = TRUE;
for (i = 0; i < pos; ++i) {
if (fxy) {
if ((tempedge[i].px1 == px1 && tempedge[i].py1 == py1
&& tempedge[i].px2 == px2 && tempedge[i].py2 == py2)
|| (tempedge[i].px1 == px2 && tempedge[i].py1 == py2
&& tempedge[i].px2 == px1 && tempedge[i].py2 == py1)) {
fxy = FALSE;
}
}
if (fyz) {
if ((tempedge[i].py1 == py1 && tempedge[i].pz1 == pz1
&& tempedge[i].py2 == py2 && tempedge[i].pz2 == pz2)
|| (tempedge[i].py1 == py2 && tempedge[i].pz1 == pz2
&& tempedge[i].py2 == py1 && tempedge[i].pz2 == pz1)) {
fyz = FALSE;
}
}
if (fzx) {
if ((tempedge[i].px1 == px1 && tempedge[i].pz1 == pz1
&& tempedge[i].px2 == px2 && tempedge[i].pz2 == pz2)
|| (tempedge[i].px1 == px2 && tempedge[i].pz1 == pz2
&& tempedge[i].px2 == px1 && tempedge[i].pz2 == pz1)) {
fzx = FALSE;
}
}
if (fxy == FALSE && fyz == FALSE && fzx == FALSE) {
return;
}
}
if (fxy && (ViewMode & VIEW_XY) != 0) {
ClipLine( &WinXY, px1+WinXY.offx, -py1+WinXY.offy,
px2+WinXY.offx, -py2+WinXY.offy, CURSOR_COLOR );
}
if (fyz && (ViewMode & VIEW_YZ) != 0) {
ClipLine( &WinYZ, py1+WinYZ.offx, -pz1+WinYZ.offy,
py2+WinYZ.offx, -pz2+WinYZ.offy, CURSOR_COLOR );
}
if (fzx && (ViewMode & VIEW_ZX) != 0) {
ClipLine( &WinZX, px1+WinZX.offx, -pz1+WinZX.offy,
px2+WinZX.offx, -pz2+WinZX.offy, CURSOR_COLOR );
}
}
static void ViewTempVertex(int pos)
{
int i;
int fxy, fyz, fzx;
int px, py, pz;
px = tempvertex[pos].px;
py = tempvertex[pos].py;
pz = tempvertex[pos].pz;
fxy = (ViewMode & VIEW_XY) != 0;
fyz = (ViewMode & VIEW_YZ) != 0;
fzx = (ViewMode & VIEW_ZX) != 0;
for (i = 0; i < pos; ++i) {
if (fxy && tempvertex[i].px == px && tempvertex[i].py == py) {
fxy = FALSE;
}
if (fyz && tempvertex[i].py == py && tempvertex[i].pz == pz) {
fyz = FALSE;
}
if (fzx && tempvertex[i].px == px && tempvertex[i].pz == pz) {
fzx = FALSE;
}
if (fxy == FALSE && fyz == FALSE && fzx == FALSE) {
return;
}
}
if (fxy) {
ClipBox( &WinXY,
px+WinXY.offx - VisibleVertex, - py+WinXY.offy - VisibleVertex,
px+WinXY.offx + VisibleVertex, - py+WinXY.offy + VisibleVertex, CURSOR_COLOR );
}
if (fyz) {
ClipBox( &WinYZ,
py+WinYZ.offx - VisibleVertex, - pz+WinYZ.offy - VisibleVertex,
py+WinYZ.offx + VisibleVertex, - pz+WinYZ.offy + VisibleVertex, CURSOR_COLOR );
}
if (fzx) {
ClipBox( &WinZX,
px+WinZX.offx - VisibleVertex, - pz+WinZX.offy - VisibleVertex,
px+WinZX.offx + VisibleVertex, - pz+WinZX.offy + VisibleVertex, CURSOR_COLOR );
}
}
void ViewTempForWin(void)
{
int i;
int ov;
int pos1[3], pos2[3] ;
Vertex p1, p2;
for (i = 0; i < tempedgecount; ++i) {
p1.x = tempedge[i].x1;p1.y = tempedge[i].y1;p1.z = tempedge[i].z1;
p2.x = tempedge[i].x2;p2.y = tempedge[i].y2;p2.z = tempedge[i].z2;
ToScreen( pos1, &p1 );
ToScreen( pos2, &p2 );
tempedge[i].px1 = pos1[0]; tempedge[i].py1 = pos1[1]; tempedge[i].pz1 = pos1[2];
tempedge[i].px2 = pos2[0]; tempedge[i].py2 = pos2[1]; tempedge[i].pz2 = pos2[2];
ViewTempLine(i);
}
ov = VisibleVertex;
if (VisibleVertex < 1) VisibleVertex = 1;
for (i = 0; i < tempvertexcount; ++i) {
p1.x = tempvertex[i].x;
p1.y = tempvertex[i].y;
p1.z = tempvertex[i].z;
ToScreen( pos1, &p1 );
tempvertex[i].px = pos1[0];
tempvertex[i].py = pos1[1];
tempvertex[i].pz = pos1[2];
ViewTempVertex(i);
}
VisibleVertex = ov;
}
void ViewTempForPers(void)
{
int i;
int ov;
Vertex p1, p2;
if ( ( ViewMode & VIEW_PERS ) == 0) {
return;
}
for (i = 0; i < tempedgecount; ++i) {
p1.x = tempedge[i].x1;p1.y = tempedge[i].y1;p1.z = tempedge[i].z1;
p2.x = tempedge[i].x2;p2.y = tempedge[i].y2;p2.z = tempedge[i].z2;
DrawLineForPers( &p1, &p2, CURSOR_COLOR);
}
ov = VisibleVertex;
if (ov < 1) ov = 1;
for (i = 0; i < tempvertexcount; ++i) {
int scr[2] ;
p1.x = tempvertex[i].x;
p1.y = tempvertex[i].y;
p1.z = tempvertex[i].z;
if (ToScreenPers( scr, &p1 )) {
ClipBox( &WinPers, scr[0] - ov, scr[1] - ov, scr[0] + ov, scr[1] + ov, CURSOR_COLOR );
}
}
}
static int AddTemp(Vertex *p1, Vertex *p2)
{
int i;
for (i = 0; i < tempedgecount; ++i) {
if ((tempedge[i].x1 == p1->x
&& tempedge[i].y1 == p1->y
&& tempedge[i].z1 == p1->z
&& tempedge[i].x2 == p2->x
&& tempedge[i].y2 == p2->y
&& tempedge[i].z2 == p2->z)
|| (tempedge[i].x1 == p2->x
&& tempedge[i].y1 == p2->y
&& tempedge[i].z1 == p2->z
&& tempedge[i].x2 == p1->x
&& tempedge[i].y2 == p1->y
&& tempedge[i].z2 == p1->z)) {
if (i != tempedgecount-1) {
tempedge[i] = tempedge[tempedgecount-1];
}
tempedgecount--;
return -1;
}
}
if (tempedgecount < MAXTEMPLINE-1) {
tempedge[tempedgecount].x1 = p1->x;
tempedge[tempedgecount].y1 = p1->y;
tempedge[tempedgecount].z1 = p1->z;
tempedge[tempedgecount].x2 = p2->x;
tempedge[tempedgecount].y2 = p2->y;
tempedge[tempedgecount].z2 = p2->z;
tempedgecount++;
return tempedgecount-1;
}
return -1;
}
static int AddTempVertex(Vertex *p1)
{
int i;
for (i = 0; i < tempvertexcount; ++i) {
if (tempvertex[i].x == p1->x
&& tempvertex[i].y == p1->y
&& tempvertex[i].z == p1->z) {
if (i != tempvertexcount-1) {
tempvertex[i] = tempvertex[tempvertexcount-1];
}
tempvertexcount--;
return -1;
}
}
if (tempvertexcount < MAXTEMPLINE-1) {
tempvertex[tempvertexcount].x = p1->x;
tempvertex[tempvertexcount].y = p1->y;
tempvertex[tempvertexcount].z = p1->z;
tempvertexcount++;
return tempvertexcount-1;
}
return -1;
}
/* ウインドウのクリア */
void ViewClear( color )
int color ;
{
int savemstat ;
if (color < 0) {
ViewTempForWin();
ViewTempForPers();
tempedgecount = 0;
tempvertexcount = 0;
if (viewbox_drawflag) {
ViewBox(&viewbox_p1, &viewbox_p2, viewbox_mat);
viewbox_drawflag = FALSE;
}
if (viewbox2d_drawflag) {
ViewBox2D(viewbox2d_x1, viewbox2d_y1, viewbox2d_x2, viewbox2d_y2);
viewbox2d_drawflag = FALSE;
}
return;
}
savemstat = Mstat ;
if ( Mstat == ON )
ViewCursor( OFF );
tempedgecount = 0;
tempvertexcount = 0;
viewbox_drawflag = FALSE;
viewbox2d_drawflag = FALSE;
if ( TmpClear == FALSE && color == TMP_COLOR )
{
ViewFrame();
ViewLineAll( 0, 0, DISPLAY_X, DISPLAY_Y, TRUE );
}
else
{
if ( ViewMode & VIEW_XY )
ClearWin( &WinXY, color );
if ( ViewMode & VIEW_YZ )
ClearWin( &WinYZ, color );
if ( ViewMode & VIEW_ZX )
ClearWin( &WinZX, color );
if ( ViewMode & VIEW_PERS )
ClearWin( &WinPers, color );
}
ViewCursor( savemstat );
}
static void ClearWin( win, color )
ViewWindow *win ;
int color ;
{
int vx1, vy1, vx2, vy2 ;
vx1 = win->x + FRAME_WIDTH ;
vy1 = win->y + FRAME_WIDTH ;
vx2 = win->x + win->h - FRAME_WIDTH - 1 ;
vy2 = win->y + win->v - FRAME_WIDTH - 1 ;
if ( vx1 < ViewX1 )
vx1 = ViewX1 ;
if ( vy1 < ViewY1 )
vy1 = ViewY1 ;
if ( vx2 > ViewX2 )
vx2 = ViewX2 ;
if ( vy2 > ViewY2 )
vy2 = ViewY2 ;
if ( vx1 > vx2 || vy1 > vy2 )
return ;
graph_fill( vx1, vy1, vx2, vy2, color );
}
/* 全データ描画 */
void ViewLineAll( minx, miny, maxx, maxy, sw )
int minx, miny, maxx, maxy ;
int sw ;
{
int i, code, flag ;
int vmode ;
int pos[2][3] ;
int vx1, vy1, vx2, vy2 ;
int sflag ;
Polygon *poly ;
int savemstat ;
savemstat = Mstat ;
if ( Mstat == ON )
ViewCursor( OFF );
vmode = ViewMode ;
flag = ViewIn( &WinXY, minx, miny, maxx, maxy ) ? VIEW_XY : 0 ;
flag |= ViewIn( &WinYZ, minx, miny, maxx, maxy ) ? VIEW_YZ : 0 ;
flag |= ViewIn( &WinZX, minx, miny, maxx, maxy ) ? VIEW_ZX : 0 ;
flag |= ViewIn( &WinPers, minx, miny, maxx, maxy ) ? VIEW_PERS : 0 ;
ViewMode &= flag ;
vx1 = ViewX1 ;
vy1 = ViewY1 ;
vx2 = ViewX2 ;
vy2 = ViewY2 ;
ViewX1 = minx ;
ViewY1 = miny ;
ViewX2 = maxx ;
ViewY2 = maxy ;
graph_buffer_start();
if ( ViewMode & ( VIEW_XY | VIEW_YZ | VIEW_ZX ) )
{
if ( sw )
{
if ( ViewMode & VIEW_XY )
DisplayGrid( &WinXY, Cx, Cy, GRID_COLOR );
if ( ViewMode & VIEW_YZ )
DisplayGrid( &WinYZ, Cy, Cz, GRID_COLOR );
if ( ViewMode & VIEW_ZX )
DisplayGrid( &WinZX, Cx, Cz, GRID_COLOR );
}
sflag = FALSE ;
if (InvisibleDraw) {
poly = BufferTop();
while( poly != NULL )
{
if ( poly->mode & MODE_INVISIBLE) {
code = INVISIBLE_COLOR ;
ToScreen( pos[0], &poly->ver[0] );
for( i = 1 ; i < poly->vers ; i++ )
{
ToScreen( pos[i&1], &poly->ver[i] );
DrawLineForWin( pos[0], pos[1], code );
}
ToScreen( pos[i&1], &poly->ver[0] );
DrawLineForWin( pos[0], pos[1], code );
}
poly = BufferNext( poly );
}
}
poly = BufferTop();
while( poly != NULL )
{
if ( poly->select == ON )
sflag = TRUE ;
else if ( ( poly->mode & MODE_INVISIBLE ) == 0 )
{
code = AttrData[poly->atr].code ;
ToScreen( pos[0], &poly->ver[0] );
for( i = 1 ; i < poly->vers ; i++ )
{
ToScreen( pos[i&1], &poly->ver[i] );
DrawLineForWin( pos[0], pos[1], code );
}
ToScreen( pos[i&1], &poly->ver[0] );
DrawLineForWin( pos[0], pos[1], code );
if (VisibleVertex > 0) {
DrawVertexWin( poly, code);
}
}
poly = BufferNext( poly );
}
if ( sflag )
{
poly = BufferTop();
while( poly != NULL )
{
if ( poly->select == ON )
{
code = SELECT_COLOR ;
ToScreen( pos[0], &poly->ver[0] );
for( i = 1 ; i < poly->vers ; i++ )
{
ToScreen( pos[i&1], &poly->ver[i] );
DrawLineForWin( pos[0], pos[1], code );
}
ToScreen( pos[i&1], &poly->ver[0] );
DrawLineForWin( pos[0], pos[1], code );
if (VisibleVertex > 0) {
DrawVertexWin( poly, code);
}
}
poly = BufferNext( poly );
}
}
ViewTempForWin();
if (viewbox_drawflag) {
int oldview;
oldview = ViewMode;
ViewMode &= (VIEW_XY | VIEW_YZ | VIEW_ZX);
ViewBox(&viewbox_p1, &viewbox_p2, viewbox_mat);
ViewMode = oldview;
viewbox_drawflag = TRUE;
}
}
if ( ViewMode & VIEW_PERS )
ViewLinePersAll( sw );
graph_buffer_end();
ViewMode = vmode ;
ViewX1 = vx1 ;
ViewY1 = vy1 ;
ViewX2 = vx2 ;
ViewY2 = vy2 ;
ViewCursor( savemstat );
}
/* 全データ描画 */
void ViewLineSelectAll(void)
{
int i, code, flag ;
int pos[2][3] ;
int scr[2][2] ;
Polygon *poly ;
int savemstat ;
savemstat = Mstat ;
if ( Mstat == ON )
ViewCursor( OFF );
graph_buffer_start();
ViewTempForWin();
ViewTempForPers();
if (viewbox_drawflag) {
ViewBox(&viewbox_p1, &viewbox_p2, viewbox_mat);
viewbox_drawflag = TRUE;
}
if ( ViewMode & ( VIEW_XY | VIEW_YZ | VIEW_ZX ) )
{
poly = BufferTop();
while( poly != NULL )
{
if ( poly->select == ON )
{
code = SELECT_COLOR ;
ToScreen( pos[0], &poly->ver[0] );
for( i = 1 ; i < poly->vers ; i++ )
{
ToScreen( pos[i&1], &poly->ver[i] );
DrawLineForWin( pos[0], pos[1], code );
}
ToScreen( pos[i&1], &poly->ver[0] );
DrawLineForWin( pos[0], pos[1], code );
if (VisibleVertex > 0) {
DrawVertexWin( poly, code);
}
poly = BufferNext( poly );
}
}
}
if ( ViewMode & VIEW_PERS ) {
poly = BufferTop();
while( poly != NULL )
{
if ( poly->select == ON )
{
int f1, f2;
f2 = ToScreenPers( scr[0], &poly->ver[0] );
for( i = 1 ; i < poly->vers ; i++ )
{
f1 = f2;
f2 = ToScreenPers( scr[i&1], &poly->ver[i] );
if (f1 && f2) {
ClipLine( &WinPers, scr[0][0], scr[0][1],
scr[1][0], scr[1][1], SELECT_COLOR );
}
}
if (f2 && ToScreenPers( scr[i&1], &poly->ver[0] )) {
ClipLine( &WinPers, scr[0][0], scr[0][1], scr[1][0], scr[1][1], SELECT_COLOR );
}
if ( VisibleVertex > 0 )
DrawVertexPers( poly, SELECT_COLOR );
if ( VisibleVector )
DrawVector( poly, SELECT_COLOR );
if ( VisiblePolyVector )
DrawPolyVector( poly, SELECT_COLOR );
}
poly = BufferNext( poly );
}
}
ViewTempForWin();
ViewTempForPers();
if (viewbox_drawflag) {
ViewBox(&viewbox_p1, &viewbox_p2, viewbox_mat);
viewbox_drawflag = TRUE;
}
graph_buffer_end();
ViewCursor( savemstat );
}
static int ViewIn( win, minx, miny, maxx, maxy )
ViewWindow *win ;
int minx, miny, maxx, maxy ;
{
return win->x <= maxx && minx < win->x+win->h && win->y <= maxy && miny < win->y+win->v ;
}
void ViewCurrent()
{
int i, code ;
int old_viewmode;
old_viewmode = ViewMode;
if (DrawFrontOnlyFlag && ScreenFront(CurrentPoly->vec) == FALSE) {
ViewMode &= ~VIEW_PERS;
}
if ( CurrentPoly->select )
code = SELECT_COLOR ;
else
code = AttrData[CurrentPoly->atr].code ;
graph_buffer_start();
for( i = 0 ; i < CurrentPoly->vers - 1 ; i++ )
ViewLine3D( &CurrentPoly->ver[i], &CurrentPoly->ver[i+1], code );
ViewLine3D( &CurrentPoly->ver[i], &CurrentPoly->ver[0], code );
if ( VisibleVertex > 0 ) {
DrawVertexWin( CurrentPoly, code );
if (ViewMode & VIEW_PERS) {
DrawVertexPers( CurrentPoly, code );
}
}
if ( VisibleVector )
DrawVector( CurrentPoly, code );
if ( VisiblePolyVector )
DrawPolyVector( CurrentPoly, code);
if ( VisibleVector )
DrawVector( CurrentPoly, code );
if ( VisiblePolyVector )
DrawPolyVector( CurrentPoly, code);
graph_buffer_end();
ViewMode = old_viewmode;
}
/* 直線描画 */
void ViewLine3D( p1, p2, color )
Vertex *p1, *p2 ;
int color ;
{
int pos1[3], pos2[3] ;
int pos;
if (p1->x == p2->x && p1->y == p2->y && p1->z == p2->z) {
return;
}
ToScreen( pos1, p1 );
ToScreen( pos2, p2 );
if (color == CURSOR_COLOR) {
if ((pos = AddTemp(p1, p2)) < 0) {
pos = tempedgecount;
}
tempedge[pos].px1 = pos1[0]; tempedge[pos].py1 = pos1[1]; tempedge[pos].pz1 = pos1[2];
tempedge[pos].px2 = pos2[0]; tempedge[pos].py2 = pos2[1]; tempedge[pos].pz2 = pos2[2];
ViewTempLine(pos);
} else {
DrawLineForWin( pos1, pos2, color );
}
DrawLineForPers( p1, p2, color );
}
/* 頂点描画 */
void ViewVertex(Vertex *p1, int color)
{
int pos1[3];
int scr[2];
int pos;
int ov;
ToScreen( pos1, p1 );
ov = VisibleVertex;
if (VisibleVertex < 1) VisibleVertex = 1;
if (color == CURSOR_COLOR) {
if ((pos = AddTempVertex(p1)) < 0) {
pos = tempvertexcount;
}
tempvertex[pos].px = pos1[0];
tempvertex[pos].py = pos1[1];
tempvertex[pos].pz = pos1[2];
ViewTempVertex(pos);
} else {
if ( ViewMode & VIEW_XY )
{
ClipBox( &WinXY,
pos1[0]+WinXY.offx - VisibleVertex, - pos1[1]+WinXY.offy - VisibleVertex,
pos1[0]+WinXY.offx + VisibleVertex, - pos1[1]+WinXY.offy + VisibleVertex,color);
}
if ( ViewMode & VIEW_YZ )
{
ClipBox( &WinYZ,
pos1[1]+WinYZ.offx - VisibleVertex, - pos1[2]+WinYZ.offy - VisibleVertex,
pos1[1]+WinYZ.offx + VisibleVertex, - pos1[2]+WinYZ.offy + VisibleVertex, color );
}
if ( ViewMode & VIEW_ZX )
{
ClipBox( &WinZX,
pos1[0]+WinZX.offx - VisibleVertex, - pos1[2]+WinZX.offy - VisibleVertex,
pos1[0]+WinZX.offx + VisibleVertex, - pos1[2]+WinZX.offy + VisibleVertex, color);
}
}
if ((ViewMode & VIEW_PERS ) && ToScreenPers( scr, p1 )) {
ClipBox( &WinPers,
scr[0] - VisibleVertex, scr[1] - VisibleVertex,
scr[0] + VisibleVertex, scr[1] + VisibleVertex, color );
}
VisibleVertex = ov;
}
/* 透視図描画 */
void ViewLinePersAll( sw )
int sw ;
{
int i, code ;
int scr[2][2] ;
Polygon *poly ;
int savemstat ;
int sflag ;
if ((ViewMode & VIEW_PERS) == 0) {
return;
}
savemstat = PersMstat ;
if ( PersMstat != PERS_CURSOR_OFF )
ViewCursorPers( PERS_CURSOR_OFF );
graph_buffer_start();
if ( sw )
{
if ( ViewMode & VIEW_PERS )
{
ClearWin( &WinPers, BG_COLOR );
#ifdef X68K
ClearWin( &WinPers, TMP_COLOR );
#endif
#ifdef PC98
/* ClearWin( &WinPers, 16 );*/
#endif
}
}
if (InvisibleDraw)
{
poly = BufferTop();
while( poly != NULL )
{
if ( poly->mode & MODE_INVISIBLE
&& (!DrawFrontOnlyFlag || ScreenFront(poly->vec)))
{
int f1, f2;
f2 = ToScreenPers( scr[0], &poly->ver[0] );
for( i = 1 ; i < poly->vers ; i++ )
{
f1 = f2;
f2 = ToScreenPers( scr[i&1], &poly->ver[i] );
if (f1 && f2) {
ClipLine( &WinPers, scr[0][0], scr[0][1],
scr[1][0], scr[1][1], INVISIBLE_COLOR );
}
}
if (f2 && ToScreenPers( scr[i&1], &poly->ver[0] )) {
ClipLine( &WinPers, scr[0][0], scr[0][1], scr[1][0], scr[1][1], INVISIBLE_COLOR );
}
}
poly = BufferNext( poly );
}
}
sflag = FALSE ;
poly = BufferTop();
while( poly != NULL )
{
if ( poly->select == ON )
{
sflag = TRUE ;
}
else if ( (poly->mode & MODE_INVISIBLE ) == 0
&& (!DrawFrontOnlyFlag || ScreenFront(poly->vec)))
{
int f1, f2;
code = AttrData[poly->atr].code ;
f2 = ToScreenPers( scr[0], &poly->ver[0] );
for( i = 1 ; i < poly->vers ; i++ )
{
f1 = f2;
f2 = ToScreenPers( scr[i&1], &poly->ver[i] );
if (f1 && f2) {
ClipLine( &WinPers, scr[0][0], scr[0][1],
scr[1][0], scr[1][1], code );
}
}
if (f2 && ToScreenPers( scr[i&1], &poly->ver[0] )) {
ClipLine( &WinPers, scr[0][0], scr[0][1], scr[1][0], scr[1][1], code );
}
if ( VisibleVertex > 0 )
DrawVertexPers( poly, code );
if ( VisibleVector )
DrawVector( poly, code );
if ( VisiblePolyVector )
DrawPolyVector( poly, code );
}
poly = BufferNext( poly );
}
if ( sflag )
{
poly = BufferTop();
while( poly != NULL )
{
if ( poly->select == ON
&& (!DrawFrontOnlyFlag || ScreenFront(poly->vec) ))
{
int f1, f2;
f2 = ToScreenPers( scr[0], &poly->ver[0] );
for( i = 1 ; i < poly->vers ; i++ )
{
f1 = f2;
f2 = ToScreenPers( scr[i&1], &poly->ver[i] );
if (f1 && f2) {
ClipLine( &WinPers, scr[0][0], scr[0][1],
scr[1][0], scr[1][1], SELECT_COLOR );
}
}
if (f2 && ToScreenPers( scr[i&1], &poly->ver[0] )) {
ClipLine( &WinPers, scr[0][0], scr[0][1], scr[1][0], scr[1][1], SELECT_COLOR );
}
if ( VisibleVertex > 0 )
DrawVertexPers( poly, SELECT_COLOR );
if ( VisibleVector )
DrawVector( poly, SELECT_COLOR );
if ( VisiblePolyVector )
DrawPolyVector( poly, SELECT_COLOR );
}
poly = BufferNext( poly );
}
}
ViewTempForPers();
if (viewbox_drawflag) {
int oldview;
oldview = ViewMode;
ViewMode &= VIEW_PERS;
ViewBox(&viewbox_p1, &viewbox_p2, viewbox_mat);
ViewMode = oldview;
viewbox_drawflag = TRUE;
}
if (viewbox2d_drawflag) {
ViewBox2D(viewbox2d_x1, viewbox2d_y1, viewbox2d_x2, viewbox2d_y2);
viewbox2d_drawflag = TRUE;
}
graph_buffer_end();
ViewCursorPers( savemstat );
}
static void DrawVertexWin( poly, code )
Polygon *poly ;
int code ;
{
int i ;
int pos[3] ;
for( i = 0 ; i < poly->vers ; i++ )
{
ToScreen( pos, &poly->ver[i] );
if ( ViewMode & VIEW_XY )
{
ClipBox( &WinXY,
pos[0]+WinXY.offx - VisibleVertex, - pos[1]+WinXY.offy - VisibleVertex,
pos[0]+WinXY.offx + VisibleVertex, - pos[1]+WinXY.offy + VisibleVertex,code);
}
if ( ViewMode & VIEW_YZ )
{
ClipBox( &WinYZ,
pos[1]+WinYZ.offx - VisibleVertex, - pos[2]+WinYZ.offy - VisibleVertex,
pos[1]+WinYZ.offx + VisibleVertex, - pos[2]+WinYZ.offy + VisibleVertex, code );
}
if ( ViewMode & VIEW_ZX )
{
ClipBox( &WinZX,
pos[0]+WinZX.offx - VisibleVertex, - pos[2]+WinZX.offy - VisibleVertex,
pos[0]+WinZX.offx + VisibleVertex, - pos[2]+WinZX.offy + VisibleVertex, code );
}
}
}
static void DrawVertexPers( poly, code )
Polygon *poly ;
int code ;
{
int i ;
int scr[2] ;
if ((!DrawFrontOnlyFlag || ScreenFront(poly->vec)) == FALSE) {
return;
}
for( i = 0 ; i < poly->vers ; i++ )
{
if (ToScreenPers( scr, &poly->ver[i] )) {
ClipBox( &WinPers,
scr[0] - VisibleVertex, scr[1] - VisibleVertex,
scr[0] + VisibleVertex, scr[1] + VisibleVertex, code);
}
}
}
static void DrawVector( poly, code )
Polygon *poly ;
int code ;
{
int i ;
int scr[2][2] ;
Vertex nvec ;
if ( (poly->type & POLY_SHADE)
&& (!DrawFrontOnlyFlag || ScreenFront(poly->vec)) )
{
for( i = 0 ; i < poly->vers ; i++ )
{
if (ToScreenPers( scr[0], &poly->ver[i] )) {
nvec.x = poly->ver[i].x + poly->ver[i].vx * VisibleVector / 256 ;
nvec.y = poly->ver[i].y + poly->ver[i].vy * VisibleVector / 256 ;
nvec.z = poly->ver[i].z + poly->ver[i].vz * VisibleVector / 256 ;
if (ToScreenPers( scr[1], &nvec )) {
ClipLine( &WinPers, scr[0][0], scr[0][1], scr[1][0], scr[1][1], code );
}
}
}
}
}
static void DrawPolyVector( poly, code )
Polygon *poly ;
int code ;
{
int i ;
int scr[2][2] ;
int add[3];
Vertex nvec ;
add[0] = poly->vec[0] * VisiblePolyVector / 256;
add[1] = poly->vec[1] * VisiblePolyVector / 256;
add[2] = poly->vec[2] * VisiblePolyVector / 256;
if (!DrawFrontOnlyFlag || ScreenFront(poly->vec) )
{
for( i = 0 ; i < poly->vers ; i++ )
{
if (ToScreenPers( scr[0], &poly->ver[i] )) {
nvec.x = poly->ver[i].x + add[0] ;
nvec.y = poly->ver[i].y + add[1] ;
nvec.z = poly->ver[i].z + add[2] ;
if (ToScreenPers( scr[1], &nvec )) {
ClipLine( &WinPers, scr[0][0], scr[0][1], scr[1][0], scr[1][1], code );
}
}
}
}
}
/* 透視図のみ表示 */
void ViewLinePers( p1, p2, color )
Vertex *p1, *p2 ;
int color ;
{
DrawLineForPers( p1, p2, color );
}
void DrawLineForWin( pos1, pos2, code )
int pos1[3], pos2[3] ;
int code ;
{
if ( ViewMode & VIEW_XY )
{
ClipLine( &WinXY, pos1[0]+WinXY.offx, - pos1[1]+WinXY.offy,
pos2[0]+WinXY.offx, - pos2[1]+WinXY.offy, code );
}
if ( ViewMode & VIEW_YZ )
{
ClipLine( &WinYZ, pos1[1]+WinYZ.offx, - pos1[2]+WinYZ.offy,
pos2[1]+WinYZ.offx, - pos2[2]+WinYZ.offy, code );
}
if ( ViewMode & VIEW_ZX )
{
ClipLine( &WinZX, pos1[0]+WinZX.offx, - pos1[2]+WinZX.offy,
pos2[0]+WinZX.offx, - pos2[2]+WinZX.offy, code );
}
}
void DrawLineForPers( p1, p2, color )
Vertex *p1, *p2 ;
int color ;
{
int sp1[2], sp2[2] ;
if ( ( ViewMode & VIEW_PERS ) && ToScreenPers( sp1, p1 ) && ToScreenPers( sp2, p2 ) )
ClipLine( &WinPers, sp1[0], sp1[1], sp2[0], sp2[1], color );
}
/* クリッピング */
void ClipLine( win, x1, y1, x2, y2, color )
ViewWindow *win ;
int x1, y1, x2, y2 ;
int color ;
{
int vx1, vy1, vx2, vy2 ;
vx1 = win->x + FRAME_WIDTH ;
vy1 = win->y + FRAME_WIDTH ;
vx2 = win->x + win->h - (FRAME_WIDTH+1) ;
vy2 = win->y + win->v - (FRAME_WIDTH+1) ;
if ( vx1 < ViewX1 )
vx1 = ViewX1 ;
if ( vy1 < ViewY1 )
vy1 = ViewY1 ;
if ( vx2 > ViewX2 )
vx2 = ViewX2 ;
if ( vy2 > ViewY2 )
vy2 = ViewY2 ;
if ( vx1 > vx2 || vy1 > vy2 )
return ;
if ( y1 > y2 )
{
swap( x1, x2 );
swap( y1, y2 );
}
if ( y2 < vy1 || vy2 < y1 )
return ;
if ( y1 < vy1 )
{
x1 = ( x1 - x2 ) * ( vy1 - y2 ) / ( y1 - y2 ) + x2 ;
y1 = vy1 ;
}
if ( vy2 < y2 )
{
x2 = ( x2 - x1 ) * ( vy2 - y1 ) / ( y2 - y1 ) + x1 ;
y2 = vy2 ;
}
if ( x1 > x2 )
{
swap( x1, x2 );
swap( y1, y2 );
}
if ( x2 < vx1 || vx2 < x1 )
return ;
if ( x1 < vx1 )
{
y1 = ( y1 - y2 ) * ( vx1 - x2 ) / ( x1 - x2 ) + y2 ;
x1 = vx1 ;
}
if ( vx2 < x2 )
{
y2 = ( y2 - y1 ) * ( vx2 - x1 ) / ( x2 - x1 ) + y1 ;
x2 = vx2 ;
}
graph_line( x1, y1, x2, y2, color );
}
/* 透視図に表示 */
void ViewLine2D( x1, y1, x2, y2, color )
int x1, y1, x2, y2 ;
int color ;
{
x1 = ((x1 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.x + WinPers.h / 2 ;
y1 = - ((y1 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.y + WinPers.v / 2 ;
x2 = ((x2 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.x + WinPers.h / 2 ;
y2 = - ((y2 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.y + WinPers.v / 2 ;
ClipLine( &WinPers, x1, y1, x2, y2, color );
}
void DrawBoxForWin( pos, code )
int pos[3];
int code ;
{
if (VisibleVertex <= 0) {
return;
}
if ( ViewMode & VIEW_XY )
{
ClipBox( &WinXY,
pos[0]+WinXY.offx - VisibleVertex, - pos[1]+WinXY.offy - VisibleVertex,
pos[0]+WinXY.offx + VisibleVertex, - pos[1]+WinXY.offy + VisibleVertex,code);
}
if ( ViewMode & VIEW_YZ )
{
ClipBox( &WinYZ,
pos[1]+WinYZ.offx - VisibleVertex, - pos[2]+WinYZ.offy - VisibleVertex,
pos[1]+WinYZ.offx + VisibleVertex, - pos[2]+WinYZ.offy + VisibleVertex, code );
}
if ( ViewMode & VIEW_ZX )
{
ClipBox( &WinZX,
pos[0]+WinZX.offx - VisibleVertex, - pos[2]+WinZX.offy - VisibleVertex,
pos[0]+WinZX.offx + VisibleVertex, - pos[2]+WinZX.offy + VisibleVertex, code );
}
}
void DrawBoxForPers( p, color )
Vertex *p ;
int color ;
{
if (VisibleVertex <= 0) {
return;
}
if ( ViewMode & VIEW_PERS ) {
int sp[2];
if (ToScreenPers( sp, p ))
ClipBox( &WinPers,
sp[0] - VisibleVertex, sp[1] - VisibleVertex,
sp[0] + VisibleVertex, sp[1] + VisibleVertex, color );
}
}
/* クリッピング */
void ClipBox( win, x1, y1, x2, y2, color )
ViewWindow *win ;
int x1, y1, x2, y2 ;
int color ;
{
int vx1, vy1, vx2, vy2 ;
vx1 = win->x + FRAME_WIDTH ;
vy1 = win->y + FRAME_WIDTH ;
vx2 = win->x + win->h - (FRAME_WIDTH+1) ;
vy2 = win->y + win->v - (FRAME_WIDTH+1) ;
if ( vx1 < ViewX1 )
vx1 = ViewX1 ;
if ( vy1 < ViewY1 )
vy1 = ViewY1 ;
if ( vx2 > ViewX2 )
vx2 = ViewX2 ;
if ( vy2 > ViewY2 )
vy2 = ViewY2 ;
if ( vx1 > vx2 || vy1 > vy2 )
return ;
if (x1 < vx1 || x2 > vx2 || y1 < vy1 || y2 > vy2) {
return;
}
graph_fill( x1, y1, x2, y2, color );
/*
graph_line(x1, y1, x2, y1, color);
graph_line(x2, y1, x2, y2, color);
graph_line(x2, y2, x1, y2, color);
graph_line(x1, y2, x1, y1, color);
*/
}