DWinding* DWinding::CopyWinding() { DWinding* c = new DWinding; c->AllocWinding(numpoints); memcpy (c->p, p, numpoints*sizeof(vec3_t)); return c; }
DWinding* DWinding::ReverseWinding() { DWinding* c = new DWinding; c->AllocWinding(numpoints); for (int i = 0; i < numpoints ; i++) VectorCopy (p[numpoints-1-i], c->p[i]); return c; }
void AddCluster( std::list<DWinding*> *pointlist, dleaf_t *cl, bool* repeatlist, vec3_t clr ){ DWinding* w; int* leafsurf = &dleafsurfaces[cl->firstLeafSurface]; for ( int k = 0; k < cl->numLeafSurfaces; k++, leafsurf++ ) { if ( repeatlist[*leafsurf] ) { continue; } dsurface_t* surf = &drawSurfaces[*leafsurf]; if ( surf->surfaceType != MST_PLANAR ) { continue; } qdrawVert_t* vert = &drawVerts[surf->firstVert]; if ( surf->firstVert + surf->numVerts > numDrawVerts ) { DoMessageBox( "Warning", "Warning", eMB_OK ); } w = new DWinding(); w->AllocWinding( surf->numVerts ); for ( int l = 0; l < surf->numVerts; l++, vert++ ) { ( w->p[l] )[0] = vert->xyz[0]; ( w->p[l] )[1] = vert->xyz[1]; ( w->p[l] )[2] = vert->xyz[2]; w->clr[0] = clr[0]; w->clr[1] = clr[1]; w->clr[2] = clr[2]; } pointlist->push_back( w ); repeatlist[*leafsurf] = true; } }
void DWinding::ClipWindingEpsilon(DPlane* chopPlane, vec_t epsilon, DWinding **front, DWinding **back) { vec_t dists[MAX_POINTS_ON_WINDING+4]; int sides[MAX_POINTS_ON_WINDING+4]; int counts[3]; vec_t *p1, *p2; vec3_t mid; counts[0] = counts[1] = counts[2] = 0; // determine sides for each point int i; for (i = 0; i < numpoints; i++) { vec_t dot = -chopPlane->DistanceToPoint(p[i]); dists[i] = dot; if (dot > epsilon) sides[i] = SIDE_FRONT; else if (dot < -epsilon) sides[i] = SIDE_BACK; else sides[i] = SIDE_ON; counts[sides[i]]++; } sides[i] = sides[0]; dists[i] = dists[0]; *front = *back = NULL; if (!counts[0]) { *back = CopyWinding(); return; } if (!counts[1]) { *front = CopyWinding(); return; } int maxpts = numpoints+4; // cant use counts[0]+2 because // of fp grouping errors DWinding* f = new DWinding; DWinding* b = new DWinding; f->AllocWinding(maxpts); f->numpoints = 0; b->AllocWinding(maxpts); b->numpoints = 0; *front = f; *back = b; for (i = 0; i < numpoints ; i++) { p1 = p[i]; if (sides[i] == SIDE_ON) { VectorCopy (p1, f->p[f->numpoints]); f->numpoints++; VectorCopy (p1, b->p[b->numpoints]); b->numpoints++; continue; } if (sides[i] == SIDE_FRONT) { VectorCopy (p1, f->p[f->numpoints]); f->numpoints++; } if (sides[i] == SIDE_BACK) { VectorCopy (p1, b->p[b->numpoints]); b->numpoints++; } if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) continue; // generate a split point p2 = p[(i+1)%numpoints]; vec_t dot = dists[i] / (dists[i]-dists[i+1]); for (int j = 0; j < 3; j++) { if (chopPlane->normal[j] == 1) mid[j] = chopPlane->_d; else if (chopPlane->normal[j] == -1) mid[j] = -chopPlane->_d; else mid[j] = p1[j] + dot*(p2[j]-p1[j]); } VectorCopy (mid, f->p[f->numpoints]); f->numpoints++; VectorCopy (mid, b->p[b->numpoints]); b->numpoints++; } if (f->numpoints > maxpts || b->numpoints > maxpts) Sys_Printf ("ClipWinding: points exceeded estimate"); if (f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING) Sys_Printf ("ClipWinding: MAX_POINTS_ON_WINDING"); }
bool DWinding::ChopWindingInPlace(DPlane* chopPlane, vec_t epsilon) { vec_t dists[MAX_POINTS_ON_WINDING+4]; int sides[MAX_POINTS_ON_WINDING+4]; int counts[3]; vec_t *p1, *p2; vec3_t mid; counts[0] = counts[1] = counts[2] = 0; // determine sides for each point int i; for (i = 0; i < numpoints; i++) { vec_t dot = DotProduct (p[i], chopPlane->normal); dot -= chopPlane->_d; dists[i] = dot; if (dot > epsilon) sides[i] = SIDE_FRONT; else if (dot < -epsilon) sides[i] = SIDE_BACK; else sides[i] = SIDE_ON; counts[sides[i]]++; } sides[i] = sides[0]; dists[i] = dists[0]; if (!counts[0]) { delete this; return FALSE; } if (!counts[1]) return TRUE; int maxpts = numpoints+4; // cant use counts[0]+2 because // of fp grouping errors DWinding* f = new DWinding; f->AllocWinding(maxpts); f->numpoints = 0; for (i = 0; i < numpoints; i++) { p1 = p[i]; if (sides[i] == SIDE_ON) { VectorCopy (p1, f->p[f->numpoints]); f->numpoints++; continue; } if (sides[i] == SIDE_FRONT) { VectorCopy (p1, f->p[f->numpoints]); f->numpoints++; } if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) continue; // generate a split point p2 = p[(i+1)%numpoints]; vec_t dot = dists[i] / (dists[i]-dists[i+1]); for (int j = 0; j < 3; j++) { if (chopPlane->normal[j] == 1) mid[j] = chopPlane->_d; else if (chopPlane->normal[j] == -1) mid[j] = -chopPlane->_d; else mid[j] = p1[j] + dot*(p2[j]-p1[j]); } VectorCopy (mid, f->p[f->numpoints]); f->numpoints++; } if (f->numpoints > maxpts) Sys_Printf ("ClipWinding: points exceeded estimate"); if (f->numpoints > MAX_POINTS_ON_WINDING) Sys_Printf ("ClipWinding: MAX_POINTS_ON_WINDING"); delete[] p; p = f->p; f->p = NULL; delete f; return TRUE; }