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 + -
显示快捷键?