]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake3/q3data/polyset.c
eol style
[xonotic/netradiant.git] / tools / quake3 / q3data / polyset.c
1 #include <assert.h>
2 #include "q3data.h"
3
4 polyset_t *Polyset_SplitSets( polyset_t *psets, int numpolysets, int *pNumNewPolysets, int maxTris )
5 {
6         int p, np, op;
7         int numNewPolysets = 0;
8         int numSplitPolysets = 0;
9         polyset_t *newpsets;
10         int sumTriangles = 0;
11
12         for ( p = 0; p < numpolysets; p++ )
13         {
14                 numNewPolysets += psets[p].numtriangles / maxTris + 1;
15         }
16
17         if ( numNewPolysets == numpolysets )
18                 return psets;
19
20         printf( "Warning: creating %d polysets from input of %d polysets\n", numNewPolysets, numpolysets );
21
22         newpsets = calloc( sizeof( polyset_t ) * numNewPolysets, 1 );
23
24         for ( np = 0, op = 0; op < numpolysets; op++ )
25         {
26                 numSplitPolysets = ( psets[op].numtriangles / ( maxTris + 1 ) ) + 1;
27                 if (  numSplitPolysets == 1 )
28                 {
29                         memcpy( &newpsets[np], &psets[op], sizeof( polyset_t ) );
30                         np++;
31                 }
32                 else
33                 {
34                         sumTriangles = 0;
35
36                         // split this pset into multiple smaller psets
37                         for ( p = 0; p < numSplitPolysets; p++, np++ )
38                         {
39                                 memcpy( &newpsets[np], &psets[op], sizeof( polyset_t ) );
40
41                                 newpsets[np].triangles = psets[op].triangles + sumTriangles;
42
43                                 if ( sumTriangles + maxTris > psets[op].numtriangles )
44                                         newpsets[np].numtriangles = psets[op].numtriangles - sumTriangles;
45                                 else
46                                         newpsets[np].numtriangles = maxTris;
47
48                                 sumTriangles += newpsets[np].numtriangles;
49                         }
50                 }
51         }
52
53         *pNumNewPolysets = numNewPolysets;
54
55         return newpsets;
56 }
57
58 polyset_t *Polyset_LoadSets( const char *file, int *numpolysets, int maxTrisPerSet )
59 {
60         polyset_t *psets;
61         polyset_t *finalpsets;
62
63         //
64         // load the frame
65         //
66         if ( strstr( file, ".3DS" ) || strstr( file, ".3ds" ) )
67                 _3DS_LoadPolysets( file, &psets, numpolysets, g_verbose );
68         else 
69                 Error( "TRI files no longer supported" );
70 //              TRI_LoadPolysets( file, &psets, numpolysets );
71
72 /*
73         //
74         // scale polysets
75         //
76         for ( i = 0; i < psets; i++ )
77         {
78                 int j;
79
80                 for ( j = 0; j < psets[i].numtriangles; j++ )
81                 {
82                 }
83         }
84 */
85
86         //
87         // split polysets if necessary
88         //
89         finalpsets = Polyset_SplitSets( psets, *numpolysets, numpolysets, maxTrisPerSet );
90
91         return finalpsets;
92 }
93
94 polyset_t *Polyset_CollapseSets( polyset_t *psets, int numpolysets )
95 {
96         int p;
97         int sumtriangles = 0;
98
99         polyset_t *oldpsets = psets;
100
101         //
102         // no tag checking because this is an $oldbase and thus shouldn't have any
103         // tags
104         //
105         for ( p = 0; p < numpolysets; p++ )
106         {
107                 sumtriangles += oldpsets[p].numtriangles;
108         }
109
110         psets = calloc( 1, sizeof( polyset_t ) );
111         psets[0].numtriangles = sumtriangles;
112         psets[0].triangles = malloc( MD3_MAX_TRIANGLES * sizeof( triangle_t ) );
113
114         // each call to "LoadPolysets" only allocates a single large chunk of
115         // triangle memory that is utilized by all the polysets loaded by
116         // that one call
117         memcpy( psets[0].triangles, oldpsets[0].triangles, sizeof( triangle_t ) * sumtriangles );
118
119         free( oldpsets[0].triangles );
120         free( oldpsets );
121
122         return psets;
123 }
124
125 static float SnapFloat( float x )
126 {
127         int ix;
128
129         x *= 1.0f / MD3_XYZ_SCALE;
130         ix = ( int ) x;
131         x = ( float ) ix;
132         x *= MD3_XYZ_SCALE;
133
134         return x;
135 }
136
137 void Polyset_SnapSets( polyset_t *psets, int numpolysets )
138 {
139         int p;
140
141         for ( p = 0; p < numpolysets; p++ )
142         {
143                 int t;
144
145                 for ( t = 0; t < psets[p].numtriangles; t++ )
146                 {
147                         int v;
148
149                         for ( v = 0; v < 3; v++ )
150                         {
151                                 psets[p].triangles[t].verts[v][0] = SnapFloat( psets[p].triangles[t].verts[v][0] );
152                                 psets[p].triangles[t].verts[v][1] = SnapFloat( psets[p].triangles[t].verts[v][1] );
153                                 psets[p].triangles[t].verts[v][2] = SnapFloat( psets[p].triangles[t].verts[v][2] );
154                         }
155                 }
156         }
157 }
158
159 void Polyset_ComputeNormals( polyset_t *psets, int numpolysets )
160 {
161         int p;
162         int i, t;
163         int vertexIndex[MD3_MAX_TRIANGLES][3];
164         vec3_t verts[MD3_MAX_VERTS];
165         vec3_t normals[MD3_MAX_VERTS];
166         vec3_t faceNormals[MD3_MAX_TRIANGLES];
167
168         //
169         // iterate through polysets
170         //
171         for ( p = 0; p < numpolysets; p++ )
172         {
173                 int numUniqueVertices = 0;
174
175                 assert( psets[p].numtriangles < MD3_MAX_TRIANGLES );
176
177                 memset( vertexIndex, 0xff, sizeof( vertexIndex ) );
178                 memset( verts, 0, sizeof( verts ) );
179                 memset( normals, 0, sizeof( normals ) );
180
181                 //
182                 // unique vertices
183                 //
184                 for ( t = 0; t < psets[p].numtriangles; t++ )
185                 {
186                         int j;
187
188                         for ( j = 0; j < 3; j++ )
189                         {
190                                 for ( i = 0; i < numUniqueVertices; i++ )
191                                 {
192                                         if ( VectorCompare( psets[p].triangles[t].verts[j], verts[i] ) )
193                                         {
194                                                 break;
195                                         }
196                                 }
197                                 if ( i == numUniqueVertices )
198                                 {
199                                         vertexIndex[t][j] = numUniqueVertices;
200                                         VectorCopy( (psets[p].triangles[t].verts[j]), (verts[numUniqueVertices]) );
201                                         numUniqueVertices++;
202                                 }
203                                 else
204                                 {
205                                         vertexIndex[t][j] = i;
206                                 }
207                         }
208                 }
209
210                 //
211                 // compute face normals
212                 //
213                 for ( t = 0; t < psets[p].numtriangles; t++ )
214                 {
215                         vec3_t side0, side1, facenormal;
216
217                         VectorSubtract( psets[p].triangles[t].verts[0], psets[p].triangles[t].verts[1], side0 );
218                         VectorSubtract( psets[p].triangles[t].verts[2], psets[p].triangles[t].verts[1], side1);
219
220                         CrossProduct( side0, side1, facenormal );
221                         VectorNormalize( facenormal, faceNormals[t] );
222                 }
223
224                 //
225                 // sum normals and copy them back
226                 //
227                 for ( i = 0; i < numUniqueVertices; i++ )
228                 {
229                         for ( t = 0; t < psets[p].numtriangles; t++ )
230                         {
231                                 if ( vertexIndex[t][0] == i ||
232                                          vertexIndex[t][1] == i ||
233                                          vertexIndex[t][2] == i )
234                                 {
235                                         normals[i][0] += faceNormals[t][0];
236                                         normals[i][1] += faceNormals[t][1];
237                                         normals[i][2] += faceNormals[t][2];
238                                 }
239                         }
240                         VectorNormalize( normals[i], normals[i] );
241                 }
242
243
244                 for ( t = 0; t < psets[p].numtriangles; t++ )
245                 {
246                         VectorCopy( normals[vertexIndex[t][0]], psets[p].triangles[t].normals[0] );
247                         VectorCopy( normals[vertexIndex[t][1]], psets[p].triangles[t].normals[1] );
248                         VectorCopy( normals[vertexIndex[t][2]], psets[p].triangles[t].normals[2] );
249                 }
250         }
251 }
252