示例#1
0
文件: bsp.c 项目: Jenco420/q2pro
/*
================
R_DrawSolidClippedSubmodelPolygons

Bmodel crosses multiple leafs
================
*/
void R_DrawSolidClippedSubmodelPolygons(mmodel_t *pmodel, mnode_t *topnode)
{
    int         i, j;
    vec_t       dot;
    mface_t     *psurf;
    int         numsurfaces;
    cplane_t    *pplane;
    mvertex_t   bverts[MAX_BMODEL_VERTS];
    bedge_t     bedges[MAX_BMODEL_EDGES], *pbedge;
    msurfedge_t *surfedge;

// FIXME: use bounding-box-based frustum clipping info?

    psurf = pmodel->firstface;
    numsurfaces = pmodel->numfaces;

    for (i = 0; i < numsurfaces; i++, psurf++) {
        // find which side of the node we are on
        pplane = psurf->plane;

        dot = PlaneDiff(modelorg, pplane);

        // draw the polygon
        if ((!(psurf->drawflags & DSURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
            ((psurf->drawflags & DSURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
            continue;

        // FIXME: use bounding-box-based frustum clipping info?

        // copy the edges to bedges, flipping if necessary so always
        // clockwise winding
        // FIXME: if edges and vertices get caches, these assignments must move
        // outside the loop, and overflow checking must be done here
        pbverts = bverts;
        pbedges = bedges;
        numbverts = numbedges = 0;
        pbedge = &bedges[numbedges];
        numbedges += psurf->numsurfedges;

        if (numbedges >= MAX_BMODEL_EDGES) {
            Com_Printf("Out of edges for bmodel\n");
            return;
        }

        surfedge = psurf->firstsurfedge;
        for (j = 0; j < psurf->numsurfedges; j++, surfedge++) {
            pbedge[j].v[0] = surfedge->edge->v[surfedge->vert    ];
            pbedge[j].v[1] = surfedge->edge->v[surfedge->vert ^ 1];
            pbedge[j].pnext = &pbedge[j + 1];
        }

        pbedge[j - 1].pnext = NULL; // mark end of edges

        if (!(psurf->texinfo->c.flags & SURF_TRANS_MASK))
            R_RecursiveClipBPoly(pbedge, topnode, psurf);
        else
            R_RenderBmodelFace(pbedge, psurf);
    }
}
示例#2
0
/*
================
R_DrawSolidClippedSubmodelPolygons
================
*/
void
R_DrawSolidClippedSubmodelPolygons(const entity_t *e, model_t *pmodel)
{
    int i, j, lindex;
    msurface_t *psurf;
    int numsurfaces;
    mvertex_t bverts[MAX_BMODEL_VERTS];
    bedge_t bedges[MAX_BMODEL_EDGES], *pbedge;
    medge_t *pedge, *pedges;

    psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
    numsurfaces = pmodel->nummodelsurfaces;
    pedges = pmodel->edges;

    for (i = 0; i < numsurfaces; i++, psurf++) {
	if (psurf->clipflags == BMODEL_FULLY_CLIPPED)
	    continue;

	// draw the polygon
	// copy the edges to bedges, flipping if necessary so always
	// clockwise winding

	/*
	 * FIXME: if edges and vertices get caches, these assignments must
	 * move outside the loop, and overflow checking must be done here
	 */
	pbverts = bverts;
	pbedges = bedges;
	numbverts = numbedges = 0;

	pbedge = &bedges[numbedges];
	numbedges += psurf->numedges;

	for (j = 0; j < psurf->numedges; j++) {
	    lindex = pmodel->surfedges[psurf->firstedge + j];

	    if (lindex > 0) {
		pedge = &pedges[lindex];
		pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]];
		pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]];
	    } else {
		lindex = -lindex;
		pedge = &pedges[lindex];
		pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]];
		pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]];
	    }
	    pbedge[j].pnext = &pbedge[j + 1];
	}
	pbedge[j - 1].pnext = NULL;	// mark end of edges

	R_RecursiveClipBPoly(e, pbedge, e->topnode, psurf);
    }
}
示例#3
0
文件: bsp.c 项目: Jenco420/q2pro
/*
================
R_RecursiveClipBPoly

Clip a bmodel poly down the world bsp tree
================
*/
static void R_RecursiveClipBPoly(bedge_t *pedges, mnode_t *pnode, mface_t *psurf)
{
    bedge_t     *psideedges[2], *pnextedge, *ptedge;
    int         i, side, lastside;
    float       dist, frac, lastdist;
    cplane_t    *splitplane, tplane;
    mvertex_t   *pvert, *plastvert, *ptvert;
    mnode_t     *pn;
    int         area;

    psideedges[0] = psideedges[1] = NULL;

    makeclippededge = qfalse;

// transform the BSP plane into model space
// FIXME: cache these?
    splitplane = pnode->plane;
    tplane.dist = -PlaneDiff(r_entorigin, splitplane);
    tplane.normal[0] = DotProduct(entity_rotation[0], splitplane->normal);
    tplane.normal[1] = DotProduct(entity_rotation[1], splitplane->normal);
    tplane.normal[2] = DotProduct(entity_rotation[2], splitplane->normal);

// clip edges to BSP plane
    for (; pedges; pedges = pnextedge) {
        pnextedge = pedges->pnext;

        // set the status for the last point as the previous point
        // FIXME: cache this stuff somehow?
        plastvert = pedges->v[0];
        lastdist = PlaneDiff(plastvert->point, &tplane);

        if (lastdist > 0)
            lastside = 0;
        else
            lastside = 1;

        pvert = pedges->v[1];
        dist = PlaneDiff(pvert->point, &tplane);

        if (dist > 0)
            side = 0;
        else
            side = 1;

        if (side != lastside) {
            // clipped
            if (numbverts >= MAX_BMODEL_VERTS)
                return;

            // generate the clipped vertex
            frac = lastdist / (lastdist - dist);
            ptvert = &pbverts[numbverts++];
            LerpVector(plastvert->point, pvert->point, frac, ptvert->point);

            // split into two edges, one on each side, and remember entering
            // and exiting points
            // FIXME: share the clip edge by having a winding direction flag?
            if (numbedges >= (MAX_BMODEL_EDGES - 1)) {
                Com_Printf("Out of edges for bmodel\n");
                return;
            }

            ptedge = &pbedges[numbedges];
            ptedge->pnext = psideedges[lastside];
            psideedges[lastside] = ptedge;
            ptedge->v[0] = plastvert;
            ptedge->v[1] = ptvert;

            ptedge = &pbedges[numbedges + 1];
            ptedge->pnext = psideedges[side];
            psideedges[side] = ptedge;
            ptedge->v[0] = ptvert;
            ptedge->v[1] = pvert;

            numbedges += 2;

            if (side == 0) {
                // entering for front, exiting for back
                pfrontenter = ptvert;
                makeclippededge = qtrue;
            } else {
                pfrontexit = ptvert;
                makeclippededge = qtrue;
            }
        } else {
            // add the edge to the appropriate side
            pedges->pnext = psideedges[side];
            psideedges[side] = pedges;
        }
    }

// if anything was clipped, reconstitute and add the edges along the clip
// plane to both sides (but in opposite directions)
    if (makeclippededge) {
        if (numbedges >= (MAX_BMODEL_EDGES - 2)) {
            Com_Error(ERR_DROP, "Out of edges for bmodel");
        }

        ptedge = &pbedges[numbedges];
        ptedge->pnext = psideedges[0];
        psideedges[0] = ptedge;
        ptedge->v[0] = pfrontexit;
        ptedge->v[1] = pfrontenter;

        ptedge = &pbedges[numbedges + 1];
        ptedge->pnext = psideedges[1];
        psideedges[1] = ptedge;
        ptedge->v[0] = pfrontenter;
        ptedge->v[1] = pfrontexit;

        numbedges += 2;
    }

// draw or recurse further
    for (i = 0; i < 2; i++) {
        if (psideedges[i]) {
            // draw if we've reached a non-solid leaf, done if all that's left is a
            // solid leaf, and continue down the tree if it's not a leaf
            pn = pnode->children[i];

            // we're done with this branch if the node or leaf isn't in the PVS
            if (pn->visframe == r_visframecount) {
                if (!pn->plane) {
                    mleaf_t *pl = (mleaf_t *)pn;
                    if (pl->contents != CONTENTS_SOLID) {
                        if (r_newrefdef.areabits) {
                            area = pl->area;
                            if (!Q_IsBitSet(r_newrefdef.areabits, area))
                                continue;       // not visible
                        }

                        r_currentbkey = pl->key;
                        R_RenderBmodelFace(psideedges[i], psurf);
                    }
                } else {
                    R_RecursiveClipBPoly(psideedges[i], pnode->children[i],
                                         psurf);
                }
            }
        }
    }
}
示例#4
0
/*
================
R_DrawSolidClippedSubmodelPolygons
================
*/
void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel)
{
	int			i, j, lindex;
	vec_t		dot;
	msurface_t	*psurf;
	int			numsurfaces;
	mplane_t	*pplane;
	mvertex_t	bverts[MAX_BMODEL_VERTS];
	bedge_t		bedges[MAX_BMODEL_EDGES], *pbedge;
	medge_t		*pedge, *pedges;

// FIXME: use bounding-box-based frustum clipping info?

	psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
	numsurfaces = pmodel->nummodelsurfaces;
	pedges = pmodel->edges;

	for (i=0 ; i<numsurfaces ; i++, psurf++)
	{
	// find which side of the node we are on
		pplane = psurf->plane;

		dot = DotProduct (modelorg, pplane->normal) - pplane->dist;

	// draw the polygon
		if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
			(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
		{
		// FIXME: use bounding-box-based frustum clipping info?

		// copy the edges to bedges, flipping if necessary so always
		// clockwise winding
		// FIXME: if edges and vertices get caches, these assignments must move
		// outside the loop, and overflow checking must be done here
			pbverts = bverts;
			pbedges = bedges;
			numbverts = numbedges = 0;

			if (psurf->numedges > 0)
			{
				pbedge = &bedges[numbedges];
				numbedges += psurf->numedges;

				for (j=0 ; j<psurf->numedges ; j++)
				{
				   lindex = pmodel->surfedges[psurf->firstedge+j];

					if (lindex > 0)
					{
						pedge = &pedges[lindex];
						pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]];
						pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]];
					}
					else
					{
						lindex = -lindex;
						pedge = &pedges[lindex];
						pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]];
						pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]];
					}

					pbedge[j].pnext = &pbedge[j+1];
				}

				pbedge[j-1].pnext = NULL;	// mark end of edges

				R_RecursiveClipBPoly (pbedge, currententity->topnode, psurf);
			}
			else
			{
				Sys_Error ("no edges in bmodel");
			}
		}
	}
}