//deal with a clipped line bool must_clip_line(g3s_point *p0,g3s_point *p1,ubyte codes_or) { bool ret; if ((p0->p3_flags&PF_TEMP_POINT) || (p1->p3_flags&PF_TEMP_POINT)) ret = 0; //line has already been clipped, so give up else { clip_line(&p0,&p1,codes_or); ret = g3_draw_line(p0,p1); } //free temp points if (p0->p3_flags & PF_TEMP_POINT) free_temp_point(p0); if (p1->p3_flags & PF_TEMP_POINT) free_temp_point(p1); return ret; }
//clips a line to the viewing pyramid. void clip_line(g3s_point **p0,g3s_point **p1,ubyte codes_or) { int plane_flag; g3s_point *old_p1; //might have these left over (*p0)->p3_flags &= ~(PF_UVS|PF_LS); (*p1)->p3_flags &= ~(PF_UVS|PF_LS); for (plane_flag=1; plane_flag<16; plane_flag<<=1) if (codes_or & plane_flag) { if ((*p0)->p3_codes & plane_flag) { g3s_point *t=*p0; //swap! *p0=*p1; *p1=t; } old_p1 = *p1; *p1 = clip_edge(plane_flag,*p0,*p1); if (old_p1->p3_flags & PF_TEMP_POINT) free_temp_point(old_p1); } }
//clips a line to the viewing pyramid. void clip_line(vertex** p0, vertex** p1, ubyte codes_or, uint flags) { int plane_flag; vertex* old_p1; for (plane_flag = 1; plane_flag <= CC_OFF_USER; plane_flag <<= 1) if (codes_or & plane_flag) { if ((*p0)->codes & plane_flag) { vertex* t = *p0; *p0 = *p1; *p1 = t; } //swap! old_p1 = *p1; *p1 = clip_edge(plane_flag, *p0, *p1, flags); codes_or = (unsigned char)((*p0)->codes | (*p1)->codes); //get new codes if (old_p1->flags & PF_TEMP_POINT) free_temp_point(old_p1); } }
int clip_plane(int plane_flag, vertex** src, vertex** dest, int* nv, ccodes* cc, uint flags) { int i; vertex** save_dest = dest; //copy first two verts to end src[*nv] = src[0]; src[*nv + 1] = src[1]; cc->cc_and = 0xff; cc->cc_or = 0; for (i = 1; i <= *nv; i++) { if (src[i]->codes & plane_flag) { //cur point off? if (!(src[i - 1]->codes & plane_flag)) { //prev not off? *dest = clip_edge(plane_flag, src[i - 1], src[i], flags); cc->cc_or |= (*dest)->codes; cc->cc_and &= (*dest)->codes; dest++; } if (!(src[i + 1]->codes & plane_flag)) { *dest = clip_edge(plane_flag, src[i + 1], src[i], flags); cc->cc_or |= (*dest)->codes; cc->cc_and &= (*dest)->codes; dest++; } //see if must free discarded point if (src[i]->flags & PF_TEMP_POINT) free_temp_point(src[i]); } else { //cur not off, copy to dest buffer *dest++ = src[i]; cc->cc_or |= src[i]->codes; cc->cc_and &= src[i]->codes; } } return (dest - save_dest); }
int clip_plane(int planeFlag,g3sPoint **src,g3sPoint **dest,int *nv,g3sCodes *cc) { int i; g3sPoint **save_dest=dest; //copy first two verts to end src[*nv] = src[0]; src[*nv+1] = src[1]; cc->and = 0xff; cc->or = 0; for (i=1;i<=*nv;i++) { if (src[i]->p3_codes & planeFlag) { //cur point off? if (! (src[i-1]->p3_codes & planeFlag)) { //prev not off? *dest = clip_edge(planeFlag,src[i-1],src[i]); cc->or |= (*dest)->p3_codes; cc->and &= (*dest)->p3_codes; dest++; } if (! (src[i+1]->p3_codes & planeFlag)) { *dest = clip_edge(planeFlag,src[i+1],src[i]); cc->or |= (*dest)->p3_codes; cc->and &= (*dest)->p3_codes; dest++; } //see if must D2_FREE discarded point if (src[i]->p3_flags & PF_TEMP_POINT) free_temp_point(src[i]); } else { //cur not off, copy to dest buffer *dest++ = src[i]; cc->or |= src[i]->p3_codes; cc->and &= src[i]->p3_codes; } } return (int) (dest - save_dest); }
//deal with face that must be clipped bool must_clip_flat_face(int nv,g3s_codes cc) { int i; bool ret=0; g3s_point **bufptr; bufptr = clip_polygon(Vbuf0,Vbuf1,&nv,&cc); if (nv>0 && !(cc.uor&CC_BEHIND) && !cc.uand) { for (i=0;i<nv;i++) { g3s_point *p = bufptr[i]; if (!(p->p3_flags&PF_PROJECTED)) g3_project_point(p); if (p->p3_flags&PF_OVERFLOW) { ret = 1; goto free_points; } Vertex_list[i*2] = p->p3_sx; Vertex_list[i*2+1] = p->p3_sy; } (*flat_drawer_ptr)(nv,(int *)Vertex_list); } else ret=1; //free temp points free_points: ; for (i=0;i<nv;i++) if (Vbuf1[i]->p3_flags & PF_TEMP_POINT) free_temp_point(Vbuf1[i]); // Assert(free_point_num==0); return ret; }
//------------------------------------------------------------------------------ //deal with face that must be clipped bool MustClipFlatFace (int nv, g3sCodes cc) { int i; bool ret=0; g3sPoint **bufptr; bufptr = clip_polygon (Vbuf0, Vbuf1, &nv, &cc); if (nv>0 && ! (cc.or&CC_BEHIND) && !cc.and) { for (i=0;i<nv;i++) { g3sPoint *p = bufptr[i]; if (! (p->p3_flags & PF_PROJECTED)) G3ProjectPoint (p); if (p->p3_flags & PF_OVERFLOW) { ret = 1; goto free_points; } polyVertList[i*2] = p->p3_screen.x; polyVertList[i*2+1] = p->p3_screen.y; } (*flat_drawer_ptr) (nv, (int *)polyVertList); } else ret=1; //D2_FREE temp points free_points: ; for (i=0;i<nv;i++) if (Vbuf1[i]->p3_flags & PF_TEMP_POINT) free_temp_point (Vbuf1[i]); // Assert (free_point_num==0); return ret; }
bool must_clip_tmap_face(int nv,g3s_codes cc,grs_bitmap *bm) { g3s_point **bufptr; int i; bufptr = clip_polygon(Vbuf0,Vbuf1,&nv,&cc); if (nv && !(cc.uor&CC_BEHIND) && !cc.uand) { for (i=0;i<nv;i++) { g3s_point *p = bufptr[i]; if (!(p->p3_flags&PF_PROJECTED)) g3_project_point(p); if (p->p3_flags&PF_OVERFLOW) { Int3(); //should not overflow after clip goto free_points; } } (*tmap_drawer_ptr)(bm,nv,bufptr); } free_points: ; for (i=0;i<nv;i++) if (bufptr[i]->p3_flags & PF_TEMP_POINT) free_temp_point(bufptr[i]); // Assert(free_point_num==0); return 0; }