From: Rudolf Polzer Date: Tue, 22 Nov 2011 11:10:26 +0000 (+0100) Subject: try to fix the "-np surfaces disappear" bug X-Git-Tag: xonotic-v0.6.0~53 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=323c01a9834da9b91c695e4cd4c735a944d7608e;p=xonotic%2Fnetradiant.git try to fix the "-np surfaces disappear" bug --- diff --git a/tools/quake3/common/polylib.c b/tools/quake3/common/polylib.c index 34dd173e..af4b98e4 100644 --- a/tools/quake3/common/polylib.c +++ b/tools/quake3/common/polylib.c @@ -536,7 +536,7 @@ winding_t *ReverseWinding (winding_t *w) ClipWindingEpsilon ============= */ -void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist, +void ClipWindingEpsilonStrict (winding_t *in, vec3_t normal, vec_t dist, vec_t epsilon, winding_t **front, winding_t **back) { vec_t dists[MAX_POINTS_ON_WINDING+4]; @@ -573,6 +573,10 @@ void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist, *front = *back = NULL; + if (!counts[0] && !counts[1]) + { + return; + } if (!counts[0]) { *back = CopyWinding (in); @@ -643,6 +647,15 @@ void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist, Error ("ClipWinding: MAX_POINTS_ON_WINDING"); } +void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist, + vec_t epsilon, winding_t **front, winding_t **back) +{ + ClipWindingEpsilonStrict(in, normal, dist, epsilon, front, back); + /* apparently most code expects that in the winding-on-plane case, the back winding is the original winding */ + if(!*front && !*back) + *back = CopyWinding(in); +} + /* ============= diff --git a/tools/quake3/common/polylib.h b/tools/quake3/common/polylib.h index 1f4495d9..9750180e 100644 --- a/tools/quake3/common/polylib.h +++ b/tools/quake3/common/polylib.h @@ -38,6 +38,8 @@ vec_t WindingArea (winding_t *w); void WindingCenter (winding_t *w, vec3_t center); void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist, vec_t epsilon, winding_t **front, winding_t **back); +void ClipWindingEpsilonStrict (winding_t *in, vec3_t normal, vec_t dist, + vec_t epsilon, winding_t **front, winding_t **back); winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist); winding_t *CopyWinding (winding_t *w); winding_t *ReverseWinding (winding_t *w); diff --git a/tools/quake3/q3map2/surface.c b/tools/quake3/q3map2/surface.c index b5dd724e..5914c40f 100644 --- a/tools/quake3/q3map2/surface.c +++ b/tools/quake3/q3map2/surface.c @@ -2035,6 +2035,13 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ) si->mins[ 1 ] != 0.0f || si->maxs[ 1 ] != 0.0f || si->mins[ 2 ] != 0.0f || si->maxs[ 2 ] != 0.0f) ) { + static qboolean warned = qfalse; + if(!warned) + { + Sys_Printf( "WARNING: this map uses the deformVertexes move hack\n" ); + warned = qtrue; + } + /* 'fatten' the winding by the shader mins/maxs (parsed from vertexDeform move) */ /* note this winding is completely invalid (concave, nonplanar, etc) */ fat = AllocWinding( w->numpoints * 3 + 3 ); @@ -2077,7 +2084,9 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ) VectorCopy( p2->normal, plane2 ); plane2[ 3 ] = p2->dist; - #if 1 + #if 0 + /* div0: this is the plague (inaccurate) */ + /* invert surface plane */ VectorSubtract( vec3_origin, plane2, reverse ); reverse[ 3 ] = -plane2[ 3 ]; @@ -2088,6 +2097,8 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ) if( DotProduct( plane1, reverse ) > 0.999f && fabs( plane1[ 3 ] - reverse[ 3 ] ) < 0.001f ) return FilterWindingIntoTree_r( w, ds, node->children[ 1 ] ); #else + /* div0: this is the cholera (doesn't hit enough) */ + /* the drawsurf might have an associated plane, if so, force a filter here */ if( ds->planeNum == node->planenum ) return FilterWindingIntoTree_r( w, ds, node->children[ 0 ] ); @@ -2097,10 +2108,17 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ) } /* clip the winding by this plane */ - ClipWindingEpsilon( w, plane1, plane1[ 3 ], ON_EPSILON, &front, &back ); + ClipWindingEpsilonStrict( w, plane1, plane1[ 3 ], ON_EPSILON, &front, &back ); /* filter by this plane */ refs = 0; + if( front == NULL && back == NULL ) + { + /* same plane, this is an ugly hack */ + /* but better too many than too few refs */ + refs += FilterWindingIntoTree_r( CopyWinding(w), ds, node->children[ 0 ] ); + refs += FilterWindingIntoTree_r( CopyWinding(w), ds, node->children[ 1 ] ); + } if( front != NULL ) refs += FilterWindingIntoTree_r( front, ds, node->children[ 0 ] ); if( back != NULL )