4 polyset_t *Polyset_SplitSets( polyset_t *psets, int numpolysets, int *pNumNewPolysets, int maxTris )
\r
7 int numNewPolysets = 0;
\r
8 int numSplitPolysets = 0;
\r
10 int sumTriangles = 0;
\r
12 for ( p = 0; p < numpolysets; p++ )
\r
14 numNewPolysets += psets[p].numtriangles / maxTris + 1;
\r
17 if ( numNewPolysets == numpolysets )
\r
20 printf( "Warning: creating %d polysets from input of %d polysets\n", numNewPolysets, numpolysets );
\r
22 newpsets = calloc( sizeof( polyset_t ) * numNewPolysets, 1 );
\r
24 for ( np = 0, op = 0; op < numpolysets; op++ )
\r
26 numSplitPolysets = ( psets[op].numtriangles / ( maxTris + 1 ) ) + 1;
\r
27 if ( numSplitPolysets == 1 )
\r
29 memcpy( &newpsets[np], &psets[op], sizeof( polyset_t ) );
\r
36 // split this pset into multiple smaller psets
\r
37 for ( p = 0; p < numSplitPolysets; p++, np++ )
\r
39 memcpy( &newpsets[np], &psets[op], sizeof( polyset_t ) );
\r
41 newpsets[np].triangles = psets[op].triangles + sumTriangles;
\r
43 if ( sumTriangles + maxTris > psets[op].numtriangles )
\r
44 newpsets[np].numtriangles = psets[op].numtriangles - sumTriangles;
\r
46 newpsets[np].numtriangles = maxTris;
\r
48 sumTriangles += newpsets[np].numtriangles;
\r
53 *pNumNewPolysets = numNewPolysets;
\r
58 polyset_t *Polyset_LoadSets( const char *file, int *numpolysets, int maxTrisPerSet )
\r
61 polyset_t *finalpsets;
\r
66 if ( strstr( file, ".3DS" ) || strstr( file, ".3ds" ) )
\r
67 _3DS_LoadPolysets( file, &psets, numpolysets, g_verbose );
\r
69 Error( "TRI files no longer supported" );
\r
70 // TRI_LoadPolysets( file, &psets, numpolysets );
\r
76 for ( i = 0; i < psets; i++ )
\r
80 for ( j = 0; j < psets[i].numtriangles; j++ )
\r
87 // split polysets if necessary
\r
89 finalpsets = Polyset_SplitSets( psets, *numpolysets, numpolysets, maxTrisPerSet );
\r
94 polyset_t *Polyset_CollapseSets( polyset_t *psets, int numpolysets )
\r
97 int sumtriangles = 0;
\r
99 polyset_t *oldpsets = psets;
\r
102 // no tag checking because this is an $oldbase and thus shouldn't have any
\r
105 for ( p = 0; p < numpolysets; p++ )
\r
107 sumtriangles += oldpsets[p].numtriangles;
\r
110 psets = calloc( 1, sizeof( polyset_t ) );
\r
111 psets[0].numtriangles = sumtriangles;
\r
112 psets[0].triangles = malloc( MD3_MAX_TRIANGLES * sizeof( triangle_t ) );
\r
114 // each call to "LoadPolysets" only allocates a single large chunk of
\r
115 // triangle memory that is utilized by all the polysets loaded by
\r
117 memcpy( psets[0].triangles, oldpsets[0].triangles, sizeof( triangle_t ) * sumtriangles );
\r
119 free( oldpsets[0].triangles );
\r
125 static float SnapFloat( float x )
\r
129 x *= 1.0f / MD3_XYZ_SCALE;
\r
132 x *= MD3_XYZ_SCALE;
\r
137 void Polyset_SnapSets( polyset_t *psets, int numpolysets )
\r
141 for ( p = 0; p < numpolysets; p++ )
\r
145 for ( t = 0; t < psets[p].numtriangles; t++ )
\r
149 for ( v = 0; v < 3; v++ )
\r
151 psets[p].triangles[t].verts[v][0] = SnapFloat( psets[p].triangles[t].verts[v][0] );
\r
152 psets[p].triangles[t].verts[v][1] = SnapFloat( psets[p].triangles[t].verts[v][1] );
\r
153 psets[p].triangles[t].verts[v][2] = SnapFloat( psets[p].triangles[t].verts[v][2] );
\r
159 void Polyset_ComputeNormals( polyset_t *psets, int numpolysets )
\r
163 int vertexIndex[MD3_MAX_TRIANGLES][3];
\r
164 vec3_t verts[MD3_MAX_VERTS];
\r
165 vec3_t normals[MD3_MAX_VERTS];
\r
166 vec3_t faceNormals[MD3_MAX_TRIANGLES];
\r
169 // iterate through polysets
\r
171 for ( p = 0; p < numpolysets; p++ )
\r
173 int numUniqueVertices = 0;
\r
175 assert( psets[p].numtriangles < MD3_MAX_TRIANGLES );
\r
177 memset( vertexIndex, 0xff, sizeof( vertexIndex ) );
\r
178 memset( verts, 0, sizeof( verts ) );
\r
179 memset( normals, 0, sizeof( normals ) );
\r
184 for ( t = 0; t < psets[p].numtriangles; t++ )
\r
188 for ( j = 0; j < 3; j++ )
\r
190 for ( i = 0; i < numUniqueVertices; i++ )
\r
192 if ( VectorCompare( psets[p].triangles[t].verts[j], verts[i] ) )
\r
197 if ( i == numUniqueVertices )
\r
199 vertexIndex[t][j] = numUniqueVertices;
\r
200 VectorCopy( (psets[p].triangles[t].verts[j]), (verts[numUniqueVertices]) );
\r
201 numUniqueVertices++;
\r
205 vertexIndex[t][j] = i;
\r
211 // compute face normals
\r
213 for ( t = 0; t < psets[p].numtriangles; t++ )
\r
215 vec3_t side0, side1, facenormal;
\r
217 VectorSubtract( psets[p].triangles[t].verts[0], psets[p].triangles[t].verts[1], side0 );
\r
218 VectorSubtract( psets[p].triangles[t].verts[2], psets[p].triangles[t].verts[1], side1);
\r
220 CrossProduct( side0, side1, facenormal );
\r
221 VectorNormalize( facenormal, faceNormals[t] );
\r
225 // sum normals and copy them back
\r
227 for ( i = 0; i < numUniqueVertices; i++ )
\r
229 for ( t = 0; t < psets[p].numtriangles; t++ )
\r
231 if ( vertexIndex[t][0] == i ||
\r
232 vertexIndex[t][1] == i ||
\r
233 vertexIndex[t][2] == i )
\r
235 normals[i][0] += faceNormals[t][0];
\r
236 normals[i][1] += faceNormals[t][1];
\r
237 normals[i][2] += faceNormals[t][2];
\r
240 VectorNormalize( normals[i], normals[i] );
\r
244 for ( t = 0; t < psets[p].numtriangles; t++ )
\r
246 VectorCopy( normals[vertexIndex[t][0]], psets[p].triangles[t].normals[0] );
\r
247 VectorCopy( normals[vertexIndex[t][1]], psets[p].triangles[t].normals[1] );
\r
248 VectorCopy( normals[vertexIndex[t][2]], psets[p].triangles[t].normals[2] );
\r