/* ================== ClipTriList ================== */ void ClipTriList( const mapTri_t *list, const idPlane &plane, float epsilon, mapTri_t **front, mapTri_t **back ) { const mapTri_t *tri; mapTri_t *newList; idWinding *w, *frontW, *backW; *front = NULL; *back = NULL; for ( tri = list ; tri ; tri = tri->next ) { w = WindingForTri( tri ); w->Split( plane, epsilon, &frontW, &backW ); newList = WindingToTriList( frontW, tri ); *front = MergeTriLists( *front, newList ); newList = WindingToTriList( backW, tri ); *back = MergeTriLists( *back, newList ); delete w; } }
/* ==================== ClipTriIntoTree_r This is used for adding curve triangles The winding will be freed before it returns ==================== */ void ClipTriIntoTree_r( idWinding* w, mapTri_t* originalTri, uEntity_t* e, node_t* node ) { idWinding* front, *back; if( !w ) { return; } if( node->planenum != PLANENUM_LEAF ) { //common->Printf( "ClipTriIntoTree_r: splitting triangle with splitplane %i\n", node->nodeNumber ); w->Split( dmapGlobals.mapPlanes[ node->planenum ], ON_EPSILON, &front, &back ); delete w; ClipTriIntoTree_r( front, originalTri, e, node->children[0] ); ClipTriIntoTree_r( back, originalTri, e, node->children[1] ); return; } //common->Printf( "ClipTriIntoTree_r: leaf area = %i, opaque = %i, occupied = %i\n", node->area, node->occupied ); // if opaque leaf, don't add if( !node->opaque && node->area >= 0 ) { mapTri_t* list; int planeNum; idPlane plane; textureVectors_t texVec; list = WindingToTriList( w, originalTri ); PlaneForTri( originalTri, plane ); planeNum = FindFloatPlane( plane ); TexVecForTri( &texVec, originalTri ); AddTriListToArea( e, list, planeNum, node->area, &texVec ); } delete w; return; }
/* ================= ClipTriByLight Carves a triangle by the frustom planes of a light, producing a (possibly empty) list of triangles on the inside and outside. The original triangle is not modified. If no clipping is required, the result will be a copy of the original. If clipping was required, the outside fragments will be planar clips, which will benefit from re-optimization. ================= */ static void ClipTriByLight( const mapLight_t *light, const mapTri_t *tri, mapTri_t **in, mapTri_t **out ) { idWinding *inside, *oldInside; idWinding *outside[6]; bool hasOutside; int i; *in = NULL; *out = NULL; // clip this winding to the light inside = WindingForTri( tri ); hasOutside = false; for ( i = 0 ; i < 6 ; i++ ) { oldInside = inside; if ( oldInside ) { oldInside->Split( light->def.frustum[i], 0, &outside[i], &inside ); delete oldInside; } else { outside[i] = NULL; } if ( outside[i] ) { hasOutside = true; } } if ( !inside ) { // the entire winding is outside this light // free the clipped fragments for ( i = 0 ; i < 6 ; i++ ) { if ( outside[i] ) { delete outside[i]; } } *out = CopyMapTri( tri ); (*out)->next = NULL; return; } if ( !hasOutside ) { // the entire winding is inside this light // free the inside copy delete inside; *in = CopyMapTri( tri ); (*in)->next = NULL; return; } // the winding is split *in = WindingToTriList( inside, tri ); delete inside; // combine all the outside fragments for ( i = 0 ; i < 6 ; i++ ) { if ( outside[i] ) { mapTri_t *list; list = WindingToTriList( outside[i], tri ); delete outside[i]; *out = MergeTriLists( *out, list ); } } }