/* ===================== ClipSidesByTree Creates side->visibleHull for all visible sides The visible hull for a side will consist of the convex hull of all points in non-opaque clusters, which allows overlaps to be trimmed off automatically. ===================== */ void ClipSidesByTree( uEntity_t *e ) { uBrush_t *b; int i; idWinding *w; side_t *side; primitive_t *prim; common->Printf( "----- ClipSidesByTree -----\n"); for ( prim = e->primitives ; prim ; prim = prim->next ) { b = prim->brush; if ( !b ) { // FIXME: other primitives! continue; } for ( i = 0 ; i < b->numsides ; i++ ) { side = &b->sides[i]; if ( !side->winding) { continue; } w = side->winding->Copy(); side->visibleHull = NULL; ClipSideByTree_r( w, side, e->tree->headnode ); // for debugging, we can choose to use the entire original side // but we skip this if the side was completely clipped away if ( side->visibleHull && dmapGlobals.noClipSides ) { delete side->visibleHull; side->visibleHull = side->winding->Copy(); } } } }
/* ==================== ClipSideByTree_r Adds non-opaque leaf fragments to the convex hull ==================== */ static void ClipSideByTree_r( idWinding* w, side_t* side, node_t* node ) { idWinding* front, *back; if( !w ) { return; } if( node->planenum != PLANENUM_LEAF ) { if( side->planenum == node->planenum ) { ClipSideByTree_r( w, side, node->children[0] ); return; } if( side->planenum == ( node->planenum ^ 1 ) ) { ClipSideByTree_r( w, side, node->children[1] ); return; } w->Split( dmapGlobals.mapPlanes[ node->planenum ], ON_EPSILON, &front, &back ); delete w; ClipSideByTree_r( front, side, node->children[0] ); ClipSideByTree_r( back, side, node->children[1] ); return; } // if opaque leaf, don't add if( !node->opaque ) { if( !side->visibleHull ) { side->visibleHull = w->Copy(); } else { side->visibleHull->AddToConvexHull( w, dmapGlobals.mapPlanes[ side->planenum ].Normal() ); } } delete w; return; }