world3.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 853 行 · 第 1/2 页
C
853 行
float x,z;
int curr_region;
cx = (x1 + x2) / 2;
cz = (z1 + z2) / 2;
h_sqr = (z2 - cz) * (z2 - cz);
w_sqr = (x2 - cx) * (x2 - cx);
/* set omega to angle of end then subtract angle of start and normalize */
if( all_pie ) {
alpha = 0;
omega = 2 * PI;
} else {
rect_to_polar( x4 - cx, z4 - cz, &dummy, &omega );
rect_to_polar( x3 - cx, z3 - cz, &dummy, &alpha );
}
omega -= alpha;
if (omega < 0.) {
omega += 2 * PI;
}
beta = alpha + omega/2.;
num_regions = resolution * omega / (2 * PI) + .5;
if (num_regions == 0) {
num_regions = 1;
}
/* the polygon will have num_regions + 2 pts. 1 for the centre and 1 */
/* for the last point on the outside */
*num_pts = num_regions + 2;
_new( pts, *num_pts );
for (curr_region = 0; curr_region < num_regions + 1; curr_region++) {
ellipse_pt( w_sqr, h_sqr, cx, cz, alpha, &x, &z );
pts[ num_regions - curr_region ].pt.p[0] = x;
pts[ num_regions - curr_region ].pt.p[1] = y;
pts[ num_regions - curr_region ].pt.p[2] = z;
pts[ num_regions - curr_region ].pt.p[3] = 1.;
/* set the edge and black face indicators to false */
pts[ num_regions - curr_region ].edge = FALSE;
pts[ num_regions - curr_region ].black_face = FALSE;
pts[ num_regions - curr_region ].face_rgn_iter = 0; //no markers on face
pts[ num_regions - curr_region ].force_rgn_pt = FALSE;
alpha += omega / num_regions;
}
/* set the centre into the points array */
pts[ num_regions + 1 ].pt.p[0] = cx;
pts[ num_regions + 1 ].pt.p[1] = y;
pts[ num_regions + 1 ].pt.p[2] = cz;
pts[ num_regions + 1 ].pt.p[3] = 1.;
/* set the edge indicator true for the first, last and centre edges */
pts[ 0 ].edge = TRUE;
pts[ 0 ].black_face = FALSE;
pts[ 0 ].face_rgn_iter = 0; // no markers on the swepted face
pts[ 0 ].force_rgn_pt = TRUE;
pts[ num_regions ].edge = TRUE;
pts[ num_regions ].black_face = FALSE;
pts[ num_regions ].face_rgn_iter = 0; // no markers on the swepted face
pts[ num_regions ].force_rgn_pt = TRUE;
pts[ num_regions + 1 ].edge = TRUE;
pts[ num_regions + 1 ].black_face = FALSE;
pts[ num_regions + 1 ].face_rgn_iter = 0; // no markers on the swepted face
pts[ num_regions + 1 ].force_rgn_pt = TRUE;
/* set the text points, if requested */
if( text != NULL ) {
text->centre.p[0] = cx;
text->centre.p[1] = y;
text->centre.p[2] = cz;
text->centre.p[3] = 1.;
ellipse_pt( w_sqr, h_sqr, cx, cz, beta, &x, &z );
text->pt1.p[0] = x;
text->pt1.p[1] = y;
text->pt1.p[2] = z;
text->pt1.p[3] = 1.;
}
return( pts );
}
extern void _w3pie(
/*****************/
/* This function adds a pie wedge to the 3d pipeline. The wedge will be in */
/* the 0-1 cube and will range from y=.5 - height/2 to y=.5 + height/2 */
/* NOTE: The bottom of the pie is layed out in new_obj.pts but */
/* rend_obj_add_sweep calls its input points the "top". */
float x1,
float z1,
float x2,
float z2,
float x3,
float z3,
float x4,
float z4,
float height,
text_pt * text,
bool above_view,
int resolution,
bool all_pie
) {
rend_obj_add new_obj;
float y_bottom;
text_info calc_text; // info for calculation text position
y_bottom = .5 - height / 2.; // centre of attention is at (.5,.5,.5)
new_obj.pts = pie_to_poly( x1, z1, x2, z2, x3, z3, x4, z4,
y_bottom, resolution, &new_obj.num_pts, &calc_text, all_pie );
if (new_obj.num_pts == 0) {
if( text != NULL ) {
/* set text to an arbitrary quantity */
text->pt.xcoord = 0.;
text->pt.ycoord = 0.;
text->direction.xcoord = 1.;
text->direction.ycoord = 1.;
}
return;
}
new_obj.top_edges = TRUE;
new_obj.top_rgn_iter = CGR_3D_PIE_RGN_ITER;
new_obj.bottom_edges = TRUE;
new_obj.bottom_rgn_iter = CGR_3D_PIE_RGN_ITER;
new_obj.height = height;
if( text != NULL ) {
calc_text.text = text;
new_obj.text = &calc_text;
} else {
new_obj.text = NULL;
}
new_obj.text_on_bottom = above_view; // bottom of solid which is top
// of pie.
new_obj.base = Curr_colour;
new_obj.black_edges = Black_edges;
new_obj.rgn = Region;
rend_obj_add_sweep( &new_obj );
_free( new_obj.pts );
}
static pt_edge * rect_to_poly(
/****************************/
/* Note: The points are layed out in counter clockwise order as seen from */
/* the positive z axis */
w3coord pt1,
w3coord pt2,
bool black1, // plane parallel to x-z at pt1.y black?
bool black2
) {
pt_edge * pts;
_new( pts, 4 );
pts[0].pt.p[0] = pt1.xcoord;
pts[0].pt.p[1] = pt1.ycoord;
pts[0].pt.p[2] = pt1.zcoord;
pts[0].pt.p[3] = 1.;
pts[0].edge = TRUE;
pts[0].black_face = FALSE;
pts[0].face_rgn_iter = 1;
pts[0].force_rgn_pt = FALSE;
pts[1].pt.p[0] = pt1.xcoord;
pts[1].pt.p[1] = pt2.ycoord;
pts[1].pt.p[2] = pt2.zcoord;
pts[1].pt.p[3] = 1.;
pts[1].edge = TRUE;
pts[1].black_face = black2;
pts[1].face_rgn_iter = 1;
pts[1].force_rgn_pt = FALSE;
pts[2].pt.p[0] = pt2.xcoord;
pts[2].pt.p[1] = pt2.ycoord;
pts[2].pt.p[2] = pt2.zcoord;
pts[2].pt.p[3] = 1.;
pts[2].edge = TRUE;
pts[2].black_face = FALSE;
pts[2].face_rgn_iter = 1;
pts[2].force_rgn_pt = FALSE;
pts[3].pt.p[0] = pt2.xcoord;
pts[3].pt.p[1] = pt1.ycoord;
pts[3].pt.p[2] = pt1.zcoord;
pts[3].pt.p[3] = 1.;
pts[3].edge = TRUE;
pts[3].black_face = black1;
pts[3].face_rgn_iter = 1;
pts[3].force_rgn_pt = FALSE;
return( pts );
}
static void add_zero_bar(
/***********************/
w3coord pt1,
w3coord pt2,
float depth
) {
point * pts;
rend_obj * new_obj;
_new( pts, 4 );
pts[0].p[0] = pt1.xcoord;
pts[0].p[1] = pt1.ycoord;
pts[0].p[2] = pt1.zcoord;
pts[0].p[3] = 1.;
pts[1].p[0] = pt2.xcoord;
pts[1].p[1] = pt1.ycoord;
pts[1].p[2] = pt1.zcoord;
pts[1].p[3] = 1.;
pts[2].p[0] = pt2.xcoord;
pts[2].p[1] = pt1.ycoord;
pts[2].p[2] = pt1.zcoord + depth;
pts[2].p[3] = 1.;
pts[3].p[0] = pt1.xcoord;
pts[3].p[1] = pt1.ycoord;
pts[3].p[2] = pt1.zcoord + depth;
pts[3].p[3] = 1.;
new_obj = rend_obj_create_poly( 4, pts, Curr_colour, Black_edges,
&Region, NULL, 1 );
pipe3d_add( new_obj, NULL, FALSE );
}
extern void _w3bar(
/*****************/
/* Adds a bar to the 3d pipeline whose front face is the rect with corners */
/* pt1 and pt2, and which has top and bottom edges parallel to the x axis */
w3coord pt1,
w3coord pt2,
float depth,
bool black1, // plane parallel to x-z at pt1.y black?
bool black2
) {
rend_obj_add new_obj;
if( fabs( pt1.ycoord - pt2.ycoord ) < FUZZY_ZERO ) {
if( fabs( pt1.xcoord - pt2.xcoord ) < FUZZY_ZERO &&
fabs( pt1.zcoord - pt1.zcoord ) < FUZZY_ZERO ) {
return;
} else {
add_zero_bar( pt1, pt2, depth );
return;
}
}
new_obj.pts = rect_to_poly( pt1, pt2, black1, black2 );
new_obj.num_pts = 4;
new_obj.top_edges = TRUE;
new_obj.top_rgn_iter = 1;
new_obj.bottom_edges = TRUE;
new_obj.bottom_rgn_iter = 1;
new_obj.height = depth;
new_obj.text = NULL;
new_obj.base = Curr_colour;
new_obj.black_edges = Black_edges;
new_obj.rgn = Region;
rend_obj_add_sweep( &new_obj );
_free( new_obj.pts );
}
extern void _w3moveto(
/********************/
w3coord pt
) {
Curr_line_pt = pt;
}
extern void _w3lineto(
/********************/
w3coord pt,
bool disp_now
) {
point start;
point end;
rend_obj * new_obj;
start.p[0] = Curr_line_pt.xcoord;
start.p[1] = Curr_line_pt.ycoord;
start.p[2] = Curr_line_pt.zcoord;
start.p[3] = 1.;
end.p[0] = pt.xcoord;
end.p[1] = pt.ycoord;
end.p[2] = pt.zcoord;
end.p[3] = 1.;
new_obj = rend_obj_create_line( start, end, Curr_colour,
Curr_line_style, &Region );
pipe3d_add( new_obj, NULL, disp_now );
Curr_line_pt = pt;
}
extern void _w3transformpoint(
/****************************/
const w3coord * pt_3d,
wcoord * pt_2d
) {
point homo_pt;
homo_pt.p[0] = pt_3d->xcoord;
homo_pt.p[1] = pt_3d->ycoord;
homo_pt.p[2] = pt_3d->zcoord;
homo_pt.p[3] = 1.;
pipe3d_trans_pt( &homo_pt );
project_pt( homo_pt, &(pt_2d->xcoord), &(pt_2d->ycoord) );
}
extern void _w3rgnon(
/*******************/
int major_id,
int minor_id,
int data_row,
int data_col,
int set_num,
bool use_group
) {
if( use_group ) {
Region.use_info = USE_RGN_GROUP;
} else {
Region.use_info = USE_RGN_SET;
}
Region.major_id = major_id;
Region.minor_id = minor_id;
Region.data_row = data_row;
Region.data_col = data_col;
Region.set_num = set_num;
}
extern void _w3rgnoff(
/********************/
void
) {
Region.use_info = USE_RGN_NONE;
}
extern void _w3rgnsetadd(
/***********************/
/* Adds the projection of a point to the current manual set, if there is one */
w3coord * pt_3
) {
wcoord pt_2;
if( Region.use_info == USE_RGN_SET ) {
_w3transformpoint( pt_3, &pt_2 );
rgn_man_set_begin( Region.set_num );
wrgn_set_add( &pt_2 );
rgn_man_set_end();
}
}
extern void _w3polygon(
/*********************/
int num_pts,
w3coord * pts,
bool * edges
) {
point * h_pts; // homogenous points
int pt_num;
rend_obj * new_obj;
_new( h_pts, num_pts );
if( h_pts != NULL ) {
for( pt_num = 0; pt_num < num_pts; pt_num++ ) {
h_pts[ pt_num ].p[0] = pts[ pt_num ].xcoord;
h_pts[ pt_num ].p[1] = pts[ pt_num ].ycoord;
h_pts[ pt_num ].p[2] = pts[ pt_num ].zcoord;
h_pts[ pt_num ].p[3] = 1.;
}
new_obj = rend_obj_create_poly( num_pts, h_pts, Curr_colour,
Black_edges, &Region, edges, 0 );
pipe3d_add( new_obj, NULL, FALSE );
}
}
extern void _w3area(
/*******************/
/*
The points are assumed to be in counter clockwise order as seen from
the outside of the solid.
NOTE: This routine requires some conditions on the points:
1. The points are not co-linear.
2. The points are co-plannar (within numerical limits).
3. The points define a simple polygon (doesn't cross itself).
*/
int num_pts,
const w3coord * pts,
float height,
int black_face // -1 for no black face
) {
rend_obj_add add;
int curr_pt;
_new( add.pts, num_pts );
for( curr_pt = 0; curr_pt < num_pts; curr_pt++ ) {
add.pts[ curr_pt ].pt.p[0] = pts[ curr_pt ].xcoord;
add.pts[ curr_pt ].pt.p[1] = pts[ curr_pt ].ycoord;
add.pts[ curr_pt ].pt.p[2] = pts[ curr_pt ].zcoord;
add.pts[ curr_pt ].pt.p[3] = 1.;
add.pts[ curr_pt ].edge = TRUE;
add.pts[ curr_pt ].black_face = (curr_pt == black_face);
add.pts[ curr_pt ].face_rgn_iter = 0;
add.pts[ curr_pt ].force_rgn_pt = FALSE;
}
add.num_pts = num_pts;
add.text = NULL;
add.height = height;
add.top_edges = TRUE;
add.top_rgn_iter = 1;
add.bottom_edges = TRUE;
add.bottom_rgn_iter = 1;
add.base = Curr_colour;
add.black_edges = Black_edges;
add.rgn = Region;
rend_obj_add_sweep( &add );
_free( add.pts );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?