+
+ /* filter by this plane */
+ refs = 0;
+ if ( dmax >= -ON_EPSILON ) {
+ refs += FilterPointConvexHullIntoTree_r( points, npoints, ds, node->children[ 0 ] );
+ }
+ if ( dmin <= ON_EPSILON ) {
+ refs += FilterPointConvexHullIntoTree_r( points, npoints, ds, node->children[ 1 ] );
+ }
+
+ /* return */
+ return refs;
+ }
+
+ /* add a reference */
+ return AddReferenceToLeaf( ds, node );
+}
+
+
+/*
+ FilterWindingIntoTree_r() - ydnar
+ filters a winding from a drawsurface into the tree
+ */
+
+int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){
+ int i, refs = 0;
+ plane_t *p1, *p2;
+ vec4_t plane1, plane2;
+ winding_t *fat, *front, *back;
+ shaderInfo_t *si;
+
+
+ /* get shaderinfo */
+ si = ds->shaderInfo;
+
+ /* ydnar: is this the head node? */
+ if ( node->parent == NULL && si != NULL &&
+ ( si->mins[ 0 ] != 0.0f || si->maxs[ 0 ] != 0.0f ||
+ 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_FPrintf( SYS_WRN, "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 );
+ fat->numpoints = w->numpoints * 3 + 3;
+ for ( i = 0; i < w->numpoints; i++ )
+ {
+ VectorCopy( w->p[ i ], fat->p[ i ] );
+ VectorAdd( w->p[ i ], si->mins, fat->p[ i + ( w->numpoints + 1 ) ] );
+ VectorAdd( w->p[ i ], si->maxs, fat->p[ i + ( w->numpoints + 1 ) * 2 ] );
+ }
+ VectorCopy( w->p[ 0 ], fat->p[ i ] );
+ VectorAdd( w->p[ 0 ], si->mins, fat->p[ i + w->numpoints ] );
+ VectorAdd( w->p[ 0 ], si->maxs, fat->p[ i + w->numpoints * 2 ] );
+
+ /*
+ * note: this winding is STILL not suitable for ClipWindingEpsilon, and
+ * also does not really fulfill the intention as it only contains
+ * origin, +mins, +maxs, but thanks to the "closing" points I just
+ * added to the three sub-windings, the fattening at least doesn't make
+ * it worse
+ */
+
+ FreeWinding( w );
+ w = fat;
+ }
+
+ /* is this a decision node? */
+ if ( node->planenum != PLANENUM_LEAF ) {
+ /* get node plane */
+ p1 = &mapplanes[ node->planenum ];
+ VectorCopy( p1->normal, plane1 );
+ plane1[ 3 ] = p1->dist;
+
+ /* check if surface is planar */
+ if ( ds->planeNum >= 0 ) {
+ /* get surface plane */
+ p2 = &mapplanes[ ds->planeNum ];
+ VectorCopy( p2->normal, plane2 );
+ plane2[ 3 ] = p2->dist;
+
+ #if 0
+ /* div0: this is the plague (inaccurate) */
+ vec4_t reverse;
+
+ /* invert surface plane */
+ VectorSubtract( vec3_origin, plane2, reverse );
+ reverse[ 3 ] = -plane2[ 3 ];
+
+ /* compare planes */
+ if ( DotProduct( plane1, plane2 ) > 0.999f && fabs( plane1[ 3 ] - plane2[ 3 ] ) < 0.001f ) {
+ return FilterWindingIntoTree_r( w, ds, node->children[ 0 ] );
+ }
+ if ( DotProduct( plane1, reverse ) > 0.999f && fabs( plane1[ 3 ] - reverse[ 3 ] ) < 0.001f ) {
+ return FilterWindingIntoTree_r( w, ds, node->children[ 1 ] );
+ }
+ #else
+ (void) plane2;
+ /* 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 ] );
+ }
+ if ( ds->planeNum == ( node->planenum ^ 1 ) ) {
+ return FilterWindingIntoTree_r( w, ds, node->children[ 1 ] );
+ }
+ #endif
+ }
+
+ /* clip the winding by this plane */
+ ClipWindingEpsilonStrict( w, plane1, plane1[ 3 ], ON_EPSILON, &front, &back ); /* strict; we handle the "winding disappeared" case */
+