//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void AAS_FlipAreaFaces(tmp_area_t *tmparea) { int side; tmp_face_t *face; plane_t *plane; vec3_t wcenter, acenter = {0, 0, 0}; //winding_t *w; float n; for (n = 0, face = tmparea->tmpfaces; face; face = face->next[side]) { if (!face->frontarea) Error("face %d has no front area\n", face->num); //side of the face the area is on side = face->frontarea != tmparea; WindingCenter(face->winding, wcenter); VectorAdd(acenter, wcenter, acenter); n++; } //end for n = 1 / n; VectorScale(acenter, n, acenter); for (face = tmparea->tmpfaces; face; face = face->next[side]) { //side of the face the area is on side = face->frontarea != tmparea; plane = &mapplanes[face->planenum ^ side]; if (DotProduct(plane->normal, acenter) - plane->dist < 0) { Log_Print("area %d face %d flipped: front area %d, back area %d\n", tmparea->areanum, face->num, face->frontarea ? face->frontarea->areanum : 0, face->backarea ? face->backarea->areanum : 0); /* face->planenum = face->planenum ^ 1; w = face->winding; face->winding = ReverseWinding(w); FreeWinding(w); */ } //end if #ifdef L_DEBUG { float dist; vec3_t normal; //check if the winding plane is the same as the face plane WindingPlane(face->winding, normal, &dist); plane = &mapplanes[face->planenum]; if (fabs(dist - plane->dist) > 0.4 || fabs(normal[0] - plane->normal[0]) > 0.0001 || fabs(normal[1] - plane->normal[1]) > 0.0001 || fabs(normal[2] - plane->normal[2]) > 0.0001) { Log_Write("area %d face %d winding plane unequal to face plane\r\n", tmparea->areanum, face->num); } //end if } #endif } //end for } //end of the function AAS_FlipAreaFaces
/* ================= CheckWinding ================= */ void CheckWinding(winding_t * w) { int i, j; vec_t *p1, *p2, d, edgedist, area, facedist; vec3_t dir, edgenormal, facenormal; if(w->numpoints < 3) { Com_Error(ERR_DROP, "CheckWinding: %i points", w->numpoints); } area = WindingArea(w); if(area < 1) { Com_Error(ERR_DROP, "CheckWinding: %f area", area); } WindingPlane(w, facenormal, &facedist); for(i = 0; i < w->numpoints; i++) { p1 = w->p[i]; for(j = 0; j < 3; j++) if(p1[j] > MAX_MAP_BOUNDS || p1[j] < -MAX_MAP_BOUNDS) { Com_Error(ERR_DROP, "CheckFace: MAX_MAP_BOUNDS: %f", p1[j]); } j = i + 1 == w->numpoints ? 0 : i + 1; // check the point is on the face plane d = DotProduct(p1, facenormal) - facedist; if(d < -ON_EPSILON || d > ON_EPSILON) { Com_Error(ERR_DROP, "CheckWinding: point off plane"); } // check the edge isnt degenerate p2 = w->p[j]; VectorSubtract(p2, p1, dir); if(VectorLength(dir) < ON_EPSILON) { Com_Error(ERR_DROP, "CheckWinding: degenerate edge"); } CrossProduct(facenormal, dir, edgenormal); VectorNormalize2(edgenormal, edgenormal); edgedist = DotProduct(p1, edgenormal); edgedist += ON_EPSILON; // all other points must be on front side for(j = 0; j < w->numpoints; j++) { if(j == i) { continue; } d = DotProduct(w->p[j], edgenormal); if(d > edgedist) { Com_Error(ERR_DROP, "CheckWinding: non-convex"); } } } }
/* ================= CheckWinding ================= */ void CheckWinding (winding_t *w) { int i, j; vec_t d, edgedist; Vector dir, edgenormal, facenormal; vec_t area; vec_t facedist; if (w->numpoints < 3) Error ("CheckWinding: %i points",w->numpoints); area = WindingArea(w); if (area < 1) Error ("CheckWinding: %f area", area); WindingPlane (w, facenormal, &facedist); for (i=0 ; i<w->numpoints ; i++) { Vector& p1 = w->p[i]; for (j=0 ; j<3 ; j++) { if (p1[j] > MAX_COORD_INTEGER || p1[j] < MIN_COORD_INTEGER) Error ("CheckFace: out of range: %f",p1[j]); } j = i+1 == w->numpoints ? 0 : i+1; // check the point is on the face plane d = DotProduct (p1, facenormal) - facedist; if (d < -ON_EPSILON || d > ON_EPSILON) Error ("CheckWinding: point off plane"); // check the edge isnt degenerate Vector& p2 = w->p[j]; VectorSubtract (p2, p1, dir); if (VectorLength (dir) < ON_EPSILON) Error ("CheckWinding: degenerate edge"); CrossProduct (facenormal, dir, edgenormal); VectorNormalize (edgenormal); edgedist = DotProduct (p1, edgenormal); edgedist += ON_EPSILON; // all other points must be on front side for (j=0 ; j<w->numpoints ; j++) { if (j == i) continue; d = DotProduct (w->p[j], edgenormal); if (d > edgedist) Error ("CheckWinding: non-convex"); } } }
/* ================= WritePortalFile_r ================= */ void WritePortalFile_r (node_t *node) { int i, s; portal_t *p; winding_t *w; vec3_t normal; vec_t dist; // decision node if (node->planenum != PLANENUM_LEAF) { WritePortalFile_r (node->children[0]); WritePortalFile_r (node->children[1]); return; } if (node->opaque) { return; } for (p = node->portals ; p ; p=p->next[s]) { w = p->winding; s = (p->nodes[1] == node); if (w && p->nodes[0] == node) { if (!Portal_Passable(p)) continue; // write out to the file // sometimes planes get turned around when they are very near // the changeover point between different axis. interpret the // plane the same way vis will, and flip the side orders if needed // FIXME: is this still relevent? WindingPlane (w, normal, &dist); if ( DotProduct (p->plane.normal, normal) < 0.99 ) { // backwards... fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster); } else fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster); if (p->hint) fprintf (pf, "1 "); else fprintf (pf, "0 "); for (i=0 ; i<w->numpoints ; i++) { fprintf (pf,"("); WriteFloat (pf, w->p[i][0]); WriteFloat (pf, w->p[i][1]); WriteFloat (pf, w->p[i][2]); fprintf (pf,") "); } fprintf (pf,"\n"); } } }
void DWinding::CheckWinding() { vec_t *p1, *p2; vec_t edgedist; vec3_t dir, edgenormal; if (numpoints < 3) Sys_Printf ("CheckWinding: %i points", numpoints); vec_t area = WindingArea(); if (area < 1) Sys_Printf ("CheckWinding: %f area", area); DPlane* wPlane = WindingPlane (); int i; for (i = 0; i < numpoints; i++) { p1 = p[i]; int j; for (j = 0; j < 3; j++) if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE) Sys_Printf ("CheckFace: BUGUS_RANGE: %f", p1[j]); j = i + 1 == numpoints ? 0 : i + 1; // check the point is on the face plane vec_t d = DotProduct (p1, wPlane->normal) - wPlane->_d; if (d < -ON_EPSILON || d > ON_EPSILON) Sys_Printf ("CheckWinding: point off plane"); // check the edge isnt degenerate p2 = p[j]; VectorSubtract (p2, p1, dir); if (VectorLength (dir) < ON_EPSILON) Sys_Printf ("CheckWinding: degenerate edge"); CrossProduct (wPlane->normal, dir, edgenormal); VectorNormalize (edgenormal, edgenormal); edgedist = DotProduct (p1, edgenormal); // all other points must be on front side for (j = 0 ; j < numpoints ; j++) { if (j == i) continue; d = DotProduct (p[j], edgenormal); if (d > (edgedist + ON_EPSILON)) Sys_Printf ("CheckWinding: non-convex"); } } delete wPlane; }
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void AAS_CheckArea(tmp_area_t *tmparea) { int side; tmp_face_t *face; plane_t *plane; vec3_t wcenter, acenter = {0, 0, 0}; vec3_t normal; float n, dist; if (tmparea->invalid) Log_Print("AAS_CheckArea: invalid area\n"); for (n = 0, face = tmparea->tmpfaces; face; face = face->next[side]) { //side of the face the area is on side = face->frontarea != tmparea; WindingCenter(face->winding, wcenter); VectorAdd(acenter, wcenter, acenter); n++; } //end for n = 1 / n; VectorScale(acenter, n, acenter); for (face = tmparea->tmpfaces; face; face = face->next[side]) { //side of the face the area is on side = face->frontarea != tmparea; #ifdef L_DEBUG if (WindingError(face->winding)) { Log_Write("AAS_CheckArea: area %d face %d: %s\r\n", tmparea->areanum, face->num, WindingErrorString()); } //end if #endif plane = &mapplanes[face->planenum ^ side]; if (DotProduct(plane->normal, acenter) - plane->dist < 0) { Log_Print("AAS_CheckArea: area %d face %d is flipped\n", tmparea->areanum, face->num); Log_Print("AAS_CheckArea: area %d center is %f %f %f\n", tmparea->areanum, acenter[0], acenter[1], acenter[2]); } //end if //check if the winding plane is the same as the face plane WindingPlane(face->winding, normal, &dist); plane = &mapplanes[face->planenum]; #ifdef L_DEBUG if (fabs(dist - plane->dist) > 0.4 || fabs(normal[0] - plane->normal[0]) > 0.0001 || fabs(normal[1] - plane->normal[1]) > 0.0001 || fabs(normal[2] - plane->normal[2]) > 0.0001) { Log_Write("AAS_CheckArea: area %d face %d winding plane unequal to face plane\r\n", tmparea->areanum, face->num); } //end if #endif } //end for } //end of the function AAS_CheckArea
/* * ================= * CheckWinding * ================= */ void CheckWinding(winding_t * w) { int i, j; vec_t *p1, *p2; vec_t d, edgedist; vec3_t dir, edgenormal, facenormal; vec_t area; vec_t facedist; if (w->numpoints < 3) Error("%s: %i points", __func__, w->numpoints); area = WindingArea(w); if (area < 1) Error("%s: %f area", __func__, area); WindingPlane(w, facenormal, &facedist); for (i = 0; i < w->numpoints; i++) { p1 = w->p[i]; for (j = 0; j < 3; j++) if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE) Error("%s: BUGUS_RANGE: %f", __func__, p1[j]); j = i + 1 == w->numpoints ? 0 : i + 1; /* check the point is on the face plane */ d = DotProduct(p1, facenormal) - facedist; if (d < -ON_EPSILON || d > ON_EPSILON) Error("%s: point off plane", __func__); /* check the edge isn't degenerate */ p2 = w->p[j]; VectorSubtract(p2, p1, dir); if (VectorLength(dir) < ON_EPSILON) Error("%s: degenerate edge", __func__); CrossProduct(facenormal, dir, edgenormal); VectorNormalize(edgenormal); edgedist = DotProduct(p1, edgenormal); edgedist += ON_EPSILON; /* all other points must be on front side */ for (j = 0; j < w->numpoints; j++) { if (j == i) continue; d = DotProduct(w->p[j], edgenormal); if (d > edgedist) Error("%s: non-convex", __func__); } } }
void CheckWinding (winding_t *w) { int i, j; vector3 *p1, *p2; number d, edgedist; vector3 dir, edgenormal, facenormal; number area; number facedist; if (w->numpoints < 3) Com_Error (ERR_DROP, "CheckWinding: %i points",w->numpoints); area = WindingArea(w); if (area < 1) Com_Error (ERR_DROP, "CheckWinding: %f area", area); WindingPlane (w, &facenormal, &facedist); for (i=0 ; i<w->numpoints ; i++) { p1 = &w->p[i]; for (j=0 ; j<3 ; j++) if (p1->data[j] > MAX_MAP_BOUNDS || p1->data[j] < -MAX_MAP_BOUNDS) Com_Error (ERR_DROP, "CheckFace: BUGUS_RANGE: %f",p1->data[j]); j = i+1 == w->numpoints ? 0 : i+1; // check the point is on the face plane d = DotProduct (p1, &facenormal) - facedist; if (d < -ON_EPSILON || d > ON_EPSILON) Com_Error (ERR_DROP, "CheckWinding: point off plane"); // check the edge isnt degenerate p2 = &w->p[j]; VectorSubtract (p2, p1, &dir); if (VectorLength (&dir) < ON_EPSILON) Com_Error (ERR_DROP, "CheckWinding: degenerate edge"); CrossProduct (&facenormal, &dir, &edgenormal); VectorNormalize2 (&edgenormal, &edgenormal); edgedist = DotProduct (p1, &edgenormal); edgedist += ON_EPSILON; // all other points must be on front side for (j=0 ; j<w->numpoints ; j++) { if (j == i) continue; d = DotProduct (&w->p[j], &edgenormal); if (d > edgedist) Com_Error (ERR_DROP, "CheckWinding: non-convex"); } } }
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void AAS_CheckFaceWindingPlane(tmp_face_t *face) { float dist, sign1, sign2; vec3_t normal; plane_t *plane; winding_t *w; //check if the winding plane is the same as the face plane WindingPlane(face->winding, normal, &dist); plane = &mapplanes[face->planenum]; // sign1 = DotProduct(plane->normal, normal); // if(fabs(dist - plane->dist) > 0.4 || fabs(normal[0] - plane->normal[0]) > 0.0001 || fabs(normal[1] - plane->normal[1]) > 0.0001 || fabs(normal[2] - plane->normal[2]) > 0.0001) { VectorInverse(normal); dist = -dist; if(fabs(dist - plane->dist) > 0.4 || fabs(normal[0] - plane->normal[0]) > 0.0001 || fabs(normal[1] - plane->normal[1]) > 0.0001 || fabs(normal[2] - plane->normal[2]) > 0.0001) { Log_Write("AAS_CheckFaceWindingPlane: face %d winding plane unequal to face plane\r\n", face->num); // sign2 = DotProduct(plane->normal, normal); if((sign1 < 0 && sign2 > 0) || (sign1 > 0 && sign2 < 0)) { Log_Write("AAS_CheckFaceWindingPlane: face %d winding reversed\r\n", face->num); w = face->winding; face->winding = ReverseWinding(w); FreeWinding(w); } //end if } //end if else { Log_Write("AAS_CheckFaceWindingPlane: face %d winding reversed\r\n", face->num); w = face->winding; face->winding = ReverseWinding(w); FreeWinding(w); } //end else } //end if } //end of the function AAS_CheckFaceWindingPlane
qboolean WindingIsTiny2 (winding_t *w) { int i, j; vec_t len; Vector delta; int edges; vec_t maxLen = 0; Vector maxEdge = vec3_origin; edges = 0; for (i=0 ; i<w->numpoints ; i++) { j = i == w->numpoints - 1 ? 0 : i+1; VectorSubtract (w->p[j], w->p[i], delta); len = VectorLength (delta); if (len > maxLen) { maxEdge = delta; maxLen = len; } } Vector normal; vec_t dist; WindingPlane (w, normal, &dist); // normal can come back vec3_origin in some cases VectorNormalize(maxEdge); Vector cross = CrossProduct(normal, maxEdge); VectorNormalize(cross); Vector mins, maxs; ClearBounds( mins, maxs ); for (i=0 ; i<w->numpoints ; i++) { Vector point; point.x = DotProduct( w->p[i], maxEdge ); point.y = DotProduct( w->p[i], cross ); point.z = DotProduct( w->p[i], normal ); AddPointToBounds( point, mins, maxs ); } // check to see if the size in the plane is too small in either dimension Vector size = maxs - mins; for ( i = 0; i < 2; i++ ) { if ( size[i] < EDGE_LENGTH ) return true; } return false; }
/* * @brief */ static void WritePortalFile_r(node_t *node) { int32_t i, s; portal_t *p; winding_t *w; vec3_t normal; vec_t dist; // decision node if (node->plane_num != PLANENUM_LEAF && !node->detail_seperator) { WritePortalFile_r(node->children[0]); WritePortalFile_r(node->children[1]); return; } if (node->contents & CONTENTS_SOLID) return; for (p = node->portals; p; p = p->next[s]) { w = p->winding; s = (p->nodes[1] == node); if (w && p->nodes[0] == node) { if (!Portal_VisFlood(p)) continue; // write out to the file // sometimes planes get turned around when they are very near // the changeover point between different axis. interpret the // plane the same way vis will, and flip the side orders if needed // FIXME: is this still relevent? WindingPlane(w, normal, &dist); if (DotProduct(p->plane.normal, normal) < 0.99) { // backwards... Fs_Print(prtfile, "%i %i %i ", w->num_points, p->nodes[1]->cluster, p->nodes[0]->cluster); } else Fs_Print(prtfile, "%i %i %i ", w->num_points, p->nodes[0]->cluster, p->nodes[1]->cluster); for (i = 0; i < w->num_points; i++) { Fs_Print(prtfile, "("); WriteFloat(prtfile, w->points[i][0]); WriteFloat(prtfile, w->points[i][1]); WriteFloat(prtfile, w->points[i][2]); Fs_Print(prtfile, ") "); } Fs_Print(prtfile, "\n"); } } }
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WindingError( winding_t *w ) { int i, j; vec_t *p1, *p2; vec_t d, edgedist; vec3_t dir, edgenormal, facenormal; vec_t area; vec_t facedist; if ( w->numpoints < 3 ) { sprintf( windingerror, "winding %i points", w->numpoints ); return WE_NOTENOUGHPOINTS; } //end if area = WindingArea( w ); if ( area < 1 ) { sprintf( windingerror, "winding %f area", area ); return WE_SMALLAREA; } //end if WindingPlane( w, facenormal, &facedist ); for ( i = 0 ; i < w->numpoints ; i++ ) { p1 = w->p[i]; for ( j = 0 ; j < 3 ; j++ ) { if ( p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE ) { sprintf( windingerror, "winding point %d BUGUS_RANGE \'%f %f %f\'", j, p1[0], p1[1], p1[2] ); return WE_POINTBOGUSRANGE; } //end if } //end for j = i + 1 == w->numpoints ? 0 : i + 1; // check the point is on the face plane d = DotProduct( p1, facenormal ) - facedist; if ( d < -ON_EPSILON || d > ON_EPSILON ) { sprintf( windingerror, "winding point %d off plane", i ); return WE_POINTOFFPLANE; } //end if // check the edge isnt degenerate p2 = w->p[j]; VectorSubtract( p2, p1, dir ); if ( VectorLength( dir ) < ON_EPSILON ) { sprintf( windingerror, "winding degenerate edge %d-%d", i, j ); return WE_DEGENERATEEDGE; } //end if CrossProduct( facenormal, dir, edgenormal ); VectorNormalize( edgenormal ); edgedist = DotProduct( p1, edgenormal ); edgedist += ON_EPSILON; // all other points must be on front side for ( j = 0 ; j < w->numpoints ; j++ ) { if ( j == i ) { continue; } d = DotProduct( w->p[j], edgenormal ); if ( d > edgedist ) { sprintf( windingerror, "winding non-convex" ); return WE_NONCONVEX; } //end if } //end for } //end for return WE_NONE; } //end of the function WindingError
/* ================= CheckWinding ================= */ void CheckWinding( winding_t *w ) { int i, j; vec_t *p1, *p2; vec_t d, edgedist; vec3_t dir, edgenormal, facenormal; vec_t area; vec_t facedist; if ( w->numpoints < 3 ) { Com_Error( ERR_DROP, "CheckWinding: %i points",w->numpoints ); } area = WindingArea( w ); if ( area < 1 ) { Com_Error( ERR_DROP, "CheckWinding: %f area", area ); } WindingPlane( w, facenormal, &facedist ); for ( i = 0 ; i < w->numpoints ; i++ ) { p1 = w->p[i]; for ( j = 0 ; j < 3 ; j++ ) #if !defined RTCW_MP if ( p1[j] > MAX_MAP_BOUNDS || p1[j] < -MAX_MAP_BOUNDS ) { #else if ( p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE ) { #endif // RTCW_XX #if !defined RTCW_ET Com_Error( ERR_DROP, "CheckFace: BUGUS_RANGE: %f",p1[j] ); #else Com_Error( ERR_DROP, "CheckFace: MAX_MAP_BOUNDS: %f",p1[j] ); #endif // RTCW_XX } j = i + 1 == w->numpoints ? 0 : i + 1; // check the point is on the face plane d = DotProduct( p1, facenormal ) - facedist; if ( d < -ON_EPSILON || d > ON_EPSILON ) { Com_Error( ERR_DROP, "CheckWinding: point off plane" ); } // check the edge isnt degenerate p2 = w->p[j]; VectorSubtract( p2, p1, dir ); if ( VectorLength( dir ) < ON_EPSILON ) { Com_Error( ERR_DROP, "CheckWinding: degenerate edge" ); } CrossProduct( facenormal, dir, edgenormal ); VectorNormalize2( edgenormal, edgenormal ); edgedist = DotProduct( p1, edgenormal ); edgedist += ON_EPSILON; // all other points must be on front side for ( j = 0 ; j < w->numpoints ; j++ ) { if ( j == i ) { continue; } d = DotProduct( w->p[j], edgenormal ); if ( d > edgedist ) { Com_Error( ERR_DROP, "CheckWinding: non-convex" ); } } } } /* ============ WindingOnPlaneSide ============ */ int WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ) { qboolean front, back; int i; vec_t d; front = qfalse; back = qfalse; for ( i = 0 ; i < w->numpoints ; i++ ) { d = DotProduct( w->p[i], normal ) - dist; if ( d < -ON_EPSILON ) { if ( front ) { return SIDE_CROSS; } back = qtrue; continue; } if ( d > ON_EPSILON ) { if ( back ) { return SIDE_CROSS; } front = qtrue; continue; } } if ( back ) { return SIDE_BACK; } if ( front ) { return SIDE_FRONT; } return SIDE_ON; }