2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../../../idlib/precompiled.h"
36 All triangle list functions should behave reasonably with NULL lists.
45 mapTri_t *AllocTri( void ) {
48 tri = (mapTri_t *)Mem_Alloc( sizeof( *tri ) );
49 memset( tri, 0, sizeof( *tri ) );
58 void FreeTri( mapTri_t *tri ) {
67 This does not copy any tris, it just relinks them
70 mapTri_t *MergeTriLists( mapTri_t *a, mapTri_t *b ) {
75 prev = &(*prev)->next;
89 void FreeTriList( mapTri_t *a ) {
92 for ( ; a ; a = next ) {
103 mapTri_t *CopyTriList( const mapTri_t *a ) {
108 for ( tri = a ; tri ; tri = tri->next ) {
111 copy = CopyMapTri( tri );
112 copy ->next = testList;
125 int CountTriList( const mapTri_t *tri ) {
143 mapTri_t *CopyMapTri( const mapTri_t *tri ) {
146 t = (mapTri_t *)Mem_Alloc( sizeof( *t ) );
157 float MapTriArea( const mapTri_t *tri ) {
158 return idWinding::TriangleArea( tri->v[0].xyz, tri->v[1].xyz, tri->v[2].xyz );
165 Return a new list with any zero or negative area triangles removed
168 mapTri_t *RemoveBadTris( const mapTri_t *list ) {
175 for ( tri = list ; tri ; tri = tri->next ) {
176 if ( MapTriArea( tri ) > 0 ) {
177 copy = CopyMapTri( tri );
178 copy->next = newList;
191 void BoundTriList( const mapTri_t *list, idBounds &b ) {
193 for ( ; list ; list = list->next ) {
194 b.AddPoint( list->v[0].xyz );
195 b.AddPoint( list->v[1].xyz );
196 b.AddPoint( list->v[2].xyz );
205 void DrawTri( const mapTri_t *tri ) {
209 VectorCopy( tri->v[0].xyz, w[0] );
210 VectorCopy( tri->v[1].xyz, w[1] );
211 VectorCopy( tri->v[2].xyz, w[2] );
220 Swaps the vertex order
223 void FlipTriList( mapTri_t *tris ) {
226 for ( tri = tris ; tri ; tri = tri->next ) {
228 const struct hashVert_s *hv;
229 struct optVertex_s *ov;
232 tri->v[0] = tri->v[2];
235 hv = tri->hashVert[0];
236 tri->hashVert[0] = tri->hashVert[2];
237 tri->hashVert[2] = hv;
239 ov = tri->optVert[0];
240 tri->optVert[0] = tri->optVert[2];
241 tri->optVert[2] = ov;
250 idWinding *WindingForTri( const mapTri_t *tri ) {
253 w = new idWinding( 3 );
254 w->SetNumPoints( 3 );
255 VectorCopy( tri->v[0].xyz, (*w)[0] );
256 VectorCopy( tri->v[1].xyz, (*w)[1] );
257 VectorCopy( tri->v[2].xyz, (*w)[2] );
266 Regenerate the texcoords and colors on a fragmented tri from the plane equations
269 void TriVertsFromOriginal( mapTri_t *tri, const mapTri_t *original ) {
273 denom = idWinding::TriangleArea( original->v[0].xyz, original->v[1].xyz, original->v[2].xyz );
275 return; // original was degenerate, so it doesn't matter
278 for ( i = 0 ; i < 3 ; i++ ) {
281 // find the barycentric coordinates
282 a = idWinding::TriangleArea( tri->v[i].xyz, original->v[1].xyz, original->v[2].xyz ) / denom;
283 b = idWinding::TriangleArea( tri->v[i].xyz, original->v[2].xyz, original->v[0].xyz ) / denom;
284 c = idWinding::TriangleArea( tri->v[i].xyz, original->v[0].xyz, original->v[1].xyz ) / denom;
286 // regenerate the interpolated values
287 tri->v[i].st[0] = a * original->v[0].st[0]
288 + b * original->v[1].st[0] + c * original->v[2].st[0];
289 tri->v[i].st[1] = a * original->v[0].st[1]
290 + b * original->v[1].st[1] + c * original->v[2].st[1];
292 for ( j = 0 ; j < 3 ; j++ ) {
293 tri->v[i].normal[j] = a * original->v[0].normal[j]
294 + b * original->v[1].normal[j] + c * original->v[2].normal[j];
296 tri->v[i].normal.Normalize();
304 Generates a new list of triangles with proper texcoords from a winding
305 created by clipping the originalTri
307 OriginalTri can be NULL if you don't care about texCoords
310 mapTri_t *WindingToTriList( const idWinding *w, const mapTri_t *originalTri ) {
321 for ( i = 2 ; i < w->GetNumPoints() ; i++ ) {
323 if ( !originalTri ) {
324 memset( tri, 0, sizeof( *tri ) );
331 for ( j = 0 ; j < 3 ; j++ ) {
333 vec = &((*w)[0]).ToVec3();
334 } else if ( j == 1 ) {
335 vec = &((*w)[i-1]).ToVec3();
337 vec = &((*w)[i]).ToVec3();
340 VectorCopy( *vec, tri->v[j].xyz );
343 TriVertsFromOriginal( tri, originalTri );
356 void ClipTriList( const mapTri_t *list, const idPlane &plane, float epsilon,
357 mapTri_t **front, mapTri_t **back ) {
360 idWinding *w, *frontW, *backW;
365 for ( tri = list ; tri ; tri = tri->next ) {
366 w = WindingForTri( tri );
367 w->Split( plane, epsilon, &frontW, &backW );
369 newList = WindingToTriList( frontW, tri );
370 *front = MergeTriLists( *front, newList );
372 newList = WindingToTriList( backW, tri );
373 *back = MergeTriLists( *back, newList );
385 void PlaneForTri( const mapTri_t *tri, idPlane &plane ) {
386 plane.FromPoints( tri->v[0].xyz, tri->v[1].xyz, tri->v[2].xyz );