/* ============= WindingFromFace ============= */ winding_t *WindingFromFace (dface_t *f) { int i; int se; dvertex_t *dv; int v; winding_t *w; w = AllocWinding (f->numedges); w->numpoints = f->numedges; for (i=0 ; i<f->numedges ; i++) { se = dsurfedges[f->firstedge + i]; if (se < 0) v = dedges[-se].v[1]; else v = dedges[se].v[0]; dv = &dvertexes[v]; VectorCopy (dv->point, w->p[i]); } RemoveColinearPoints (w); return w; }
/** * @brief */ winding_t *WindingForFace(const bsp_face_t *f) { int32_t i; bsp_vertex_t *dv; int32_t v; winding_t *w; w = AllocWinding(f->num_edges); w->num_points = f->num_edges; for (i = 0; i < f->num_edges; i++) { const int32_t se = bsp_file.face_edges[f->first_edge + i]; if (se < 0) { v = bsp_file.edges[-se].v[1]; } else { v = bsp_file.edges[se].v[0]; } dv = &bsp_file.vertexes[v]; VectorCopy(dv->point, w->points[i]); } RemoveColinearPoints(w); return w; }
Winding::Winding(const dface_t& face) { int se; dvertex_t* dv; int v; m_NumPoints = face.numedges; m_Points = new vec3_t[m_NumPoints]; unsigned i; for (i = 0; i < face.numedges; i++) { se = g_dsurfedges[face.firstedge + i]; if (se < 0) { v = g_dedges[-se].v[1]; } else { v = g_dedges[se].v[0]; } dv = &g_dvertexes[v]; VectorCopy(dv->point, m_Points[i]); } RemoveColinearPoints(); }
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void AAS_RemoveAreaFaceColinearPoints( void ) { int side; tmp_face_t *face; tmp_area_t *tmparea; //FIXME: loop over the faces instead of area->faces for ( tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next ) { for ( face = tmparea->tmpfaces; face; face = face->next[side] ) { side = face->frontarea != tmparea; RemoveColinearPoints( face->winding ); // RemoveEqualPoints(face->winding, 0.1); } //end for } //end for } //end of the function AAS_RemoveAreaFaceColinearPoints
static winding_t* WindingFromFace (const dBspSurface_t* f) { int i, v; winding_t* w; w = AllocWinding(f->numedges); w->numpoints = f->numedges; for (i = 0; i < f->numedges; i++) { const int se = curTile->surfedges[f->firstedge + i]; if (se < 0) v = curTile->edges[-se].v[1]; else v = curTile->edges[se].v[0]; dBspVertex_t* dv = &curTile->vertexes[v]; VectorCopy(dv->point, w->p[i]); } RemoveColinearPoints(w); return w; }
//#ifdef ME //=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== winding_t *MergeWindings( winding_t *w1, winding_t *w2, vec3_t planenormal ) { winding_t *neww; float dist; int i, j, n, found, insertafter; int sides[MAX_POINTS_ON_WINDING + 4]; vec3_t newp[MAX_POINTS_ON_WINDING + 4]; int numpoints; vec3_t edgevec, sepnormal, v; RemoveEqualPoints( w1, 0.2 ); numpoints = w1->numpoints; memcpy( newp, w1->p, w1->numpoints * sizeof( vec3_t ) ); // for ( i = 0; i < w2->numpoints; i++ ) { VectorCopy( w2->p[i], v ); for ( j = 0; j < numpoints; j++ ) { VectorSubtract( newp[( j + 1 ) % numpoints], newp[( j ) % numpoints], edgevec ); CrossProduct( edgevec, planenormal, sepnormal ); VectorNormalize( sepnormal ); if ( VectorLength( sepnormal ) < 0.9 ) { //remove the point from the new winding for ( n = j; n < numpoints - 1; n++ ) { VectorCopy( newp[n + 1], newp[n] ); sides[n] = sides[n + 1]; } //end for numpoints--; j--; Log_Print( "MergeWindings: degenerate edge on winding %f %f %f\n", sepnormal[0], sepnormal[1], sepnormal[2] ); continue; } //end if dist = DotProduct( newp[( j ) % numpoints], sepnormal ); if ( DotProduct( v, sepnormal ) - dist < -0.1 ) { sides[j] = SIDE_BACK; } else { sides[j] = SIDE_FRONT;} } //end for //remove all unnecesary points for ( j = 0; j < numpoints; ) { if ( sides[j] == SIDE_BACK && sides[( j + 1 ) % numpoints] == SIDE_BACK ) { //remove the point from the new winding for ( n = ( j + 1 ) % numpoints; n < numpoints - 1; n++ ) { VectorCopy( newp[n + 1], newp[n] ); sides[n] = sides[n + 1]; } //end for numpoints--; } //end if else { j++; } //end else } //end for // found = false; for ( j = 0; j < numpoints; j++ ) { if ( sides[j] == SIDE_FRONT && sides[( j + 1 ) % numpoints] == SIDE_BACK ) { if ( found ) { Log_Print( "Warning: MergeWindings: front to back found twice\n" ); } found = true; } //end if } //end for // for ( j = 0; j < numpoints; j++ ) { if ( sides[j] == SIDE_FRONT && sides[( j + 1 ) % numpoints] == SIDE_BACK ) { insertafter = ( j + 1 ) % numpoints; //insert the new point after j+1 for ( n = numpoints - 1; n > insertafter; n-- ) { VectorCopy( newp[n], newp[n + 1] ); } //end for numpoints++; VectorCopy( v, newp[( insertafter + 1 ) % numpoints] ); break; } //end if } //end for } //end for neww = AllocWinding( numpoints ); neww->numpoints = numpoints; memcpy( neww->p, newp, numpoints * sizeof( vec3_t ) ); RemoveColinearPoints( neww ); return neww; } //end of the function MergeWindings
bool Winding::Clip(const dplane_t& split, bool keepon) { vec_t dists[MAX_POINTS_ON_WINDING]; int sides[MAX_POINTS_ON_WINDING]; int counts[3]; vec_t dot; int i, j; counts[0] = counts[1] = counts[2] = 0; // determine sides for each point // do this exactly, with no epsilon so tiny portals still work for (i = 0; i < m_NumPoints; i++) { dot = DotProduct(m_Points[i], split.normal); dot -= split.dist; dists[i] = dot; if (dot > ON_EPSILON) { sides[i] = SIDE_FRONT; } else if (dot < ON_EPSILON) { sides[i] = SIDE_BACK; } else { sides[i] = SIDE_ON; } counts[sides[i]]++; } sides[i] = sides[0]; dists[i] = dists[0]; if (keepon && !counts[0] && !counts[1]) { return true; } if (!counts[0]) { delete[] m_Points; m_Points = NULL; m_NumPoints = 0; return false; } if (!counts[1]) { return true; } unsigned maxpts = m_NumPoints + 4; // can't use counts[0]+2 because of fp grouping errors unsigned newNumPoints = 0; vec3_t* newPoints = new vec3_t[maxpts]; memset(newPoints, 0, sizeof(vec3_t) * maxpts); for (i = 0; i < m_NumPoints; i++) { vec_t* p1 = m_Points[i]; if (sides[i] == SIDE_ON) { VectorCopy(p1, newPoints[newNumPoints]); newNumPoints++; continue; } else if (sides[i] == SIDE_FRONT) { VectorCopy(p1, newPoints[newNumPoints]); newNumPoints++; } if (sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i]) { continue; } // generate a split point vec3_t mid; unsigned int tmp = i + 1; if (tmp >= m_NumPoints) { tmp = 0; } vec_t* p2 = m_Points[tmp]; dot = dists[i] / (dists[i] - dists[i + 1]); for (j = 0; j < 3; j++) { // avoid round off error when possible if (split.normal[j] < 1.0 - NORMAL_EPSILON) { if (split.normal[j] > -1.0 + NORMAL_EPSILON) { mid[j] = p1[j] + dot * (p2[j] - p1[j]); } else { mid[j] = -split.dist; } } else { mid[j] = split.dist; } } VectorCopy(mid, newPoints[newNumPoints]); newNumPoints++; } if (newNumPoints > maxpts) { Error("Winding::Clip : points exceeded estimate"); } delete[] m_Points; m_Points = newPoints; m_NumPoints = newNumPoints; RemoveColinearPoints(); return true; }