]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/qdata_heretic2/common/trilib.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / common / trilib.c
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 //\r
23 // trilib.c: library for loading triangles from an Alias triangle file\r
24 //\r
25 \r
26 #include <stdio.h>\r
27 #include "cmdlib.h"\r
28 #include "inout.h"\r
29 #include "mathlib.h"\r
30 #include "trilib.h"\r
31 #include "token.h"\r
32 #include "l3dslib.h"\r
33 #include "fmodel.h"\r
34 #if 1\r
35 #include "qd_skeletons.h"\r
36 #endif\r
37 \r
38 // on disk representation of a face\r
39 #define FLOAT_START     99999.0\r
40 #define FLOAT_END       -FLOAT_START\r
41 #define MAGIC       123322\r
42 #ifndef M_PI\r
43   #define M_PI          3.14159265\r
44 #endif\r
45 \r
46 float FixHTRRotateX = 0.0;\r
47 float FixHTRRotateY = 0.0;\r
48 float FixHTRRotateZ = 0.0;\r
49 float FixHTRTranslateX = 0.0;\r
50 float FixHTRTranslateY = 0.0;\r
51 float FixHTRTranslateZ = 0.0;\r
52 \r
53 //#define NOISY 1\r
54 \r
55 typedef struct {\r
56         float v[3];\r
57 } vector;\r
58 \r
59 typedef struct\r
60 {\r
61         vector n;    /* normal */\r
62         vector p;    /* point */\r
63         vector c;    /* color */\r
64         float  u;    /* u */\r
65         float  v;    /* v */\r
66 } aliaspoint_t;\r
67 \r
68 typedef struct {\r
69         aliaspoint_t    pt[3];\r
70 } tf_triangle;\r
71 \r
72 \r
73 void ByteSwapTri (tf_triangle *tri)\r
74 {\r
75         int             i;\r
76         \r
77         for (i=0 ; i<sizeof(tf_triangle)/4 ; i++)\r
78         {\r
79                 ((int *)tri)[i] = BigLong (((int *)tri)[i]);\r
80         }\r
81 }\r
82 \r
83 void LoadTRI (char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **nodesList, int *num_mesh_nodes)\r
84 {\r
85         FILE        *input;\r
86         float       start;\r
87         char        name[256], tex[256];\r
88         int         i, count, magic;\r
89         tf_triangle     tri;\r
90         triangle_t      *ptri;\r
91         int                     iLevel;\r
92         int                     exitpattern;\r
93         float           t;\r
94 \r
95         if (nodesList)\r
96         {\r
97                 *num_mesh_nodes = 0;\r
98                 *nodesList = (mesh_node_t *) SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");\r
99         }\r
100 \r
101         t = -FLOAT_START;\r
102         *((unsigned char *)&exitpattern + 0) = *((unsigned char *)&t + 3);\r
103         *((unsigned char *)&exitpattern + 1) = *((unsigned char *)&t + 2);\r
104         *((unsigned char *)&exitpattern + 2) = *((unsigned char *)&t + 1);\r
105         *((unsigned char *)&exitpattern + 3) = *((unsigned char *)&t + 0);\r
106 \r
107         if ((input = fopen(filename, "rb")) == 0)\r
108                 Error ("reader: could not open file '%s'", filename);\r
109 \r
110         iLevel = 0;\r
111 \r
112         fread(&magic, sizeof(int), 1, input);\r
113         if (BigLong(magic) != MAGIC)\r
114                 Error ("%s is not a Alias object separated triangle file, magic number is wrong.", filename);\r
115 \r
116         ptri = malloc (MAXTRIANGLES * sizeof(triangle_t));\r
117 \r
118         *pptri = ptri;\r
119 \r
120         while (feof(input) == 0) {\r
121                 if (fread(&start,  sizeof(float), 1, input) < 1)\r
122                         break;\r
123                 *(int *)&start = BigLong(*(int *)&start);\r
124                 if (*(int *)&start != exitpattern)\r
125                 {\r
126                         if (start == FLOAT_START) {\r
127                                 /* Start of an object or group of objects. */\r
128                                 i = -1;\r
129                                 do {\r
130                                         /* There are probably better ways to read a string from */\r
131                                         /* a file, but this does allow you to do error checking */\r
132                                         /* (which I'm not doing) on a per character basis.      */\r
133                                         ++i;\r
134                                         fread( &(name[i]), sizeof( char ), 1, input);\r
135                                 } while( name[i] != '\0' );\r
136         \r
137 //                              indent();\r
138 //                              fprintf(stdout,"OBJECT START: %s\n",name);\r
139                                 fread( &count, sizeof(int), 1, input);\r
140                                 count = BigLong(count);\r
141                                 ++iLevel;\r
142                                 if (count != 0) {\r
143 //                                      indent();\r
144 //                                      fprintf(stdout,"NUMBER OF TRIANGLES: %d\n",count);\r
145         \r
146                                         i = -1;\r
147                                         do {\r
148                                                 ++i;\r
149                                                 fread( &(tex[i]), sizeof( char ), 1, input);\r
150                                         } while( tex[i] != '\0' );\r
151         \r
152 //                                      indent();\r
153 //                                      fprintf(stdout,"  Object texture name: '%s'\n",tex);\r
154                                 }\r
155         \r
156                                 /* Else (count == 0) this is the start of a group, and */\r
157                                 /* no texture name is present. */\r
158                         }\r
159                         else if (start == FLOAT_END) {\r
160                                 /* End of an object or group. Yes, the name should be */\r
161                                 /* obvious from context, but it is in here just to be */\r
162                                 /* safe and to provide a little extra information for */\r
163                                 /* those who do not wish to write a recursive reader. */\r
164                                 /* Mia culpa. */\r
165                                 --iLevel;\r
166                                 i = -1;\r
167                                 do {\r
168                                         ++i;\r
169                                         fread( &(name[i]), sizeof( char ), 1, input);\r
170                                 } while( name[i] != '\0' );\r
171         \r
172 //                              indent();\r
173 //                              fprintf(stdout,"OBJECT END: %s\n",name);\r
174                                 continue;\r
175                         }\r
176                 }\r
177 \r
178 //\r
179 // read the triangles\r
180 //              \r
181                 for (i = 0; i < count; ++i) {\r
182                         int             j;\r
183 \r
184                         fread( &tri, sizeof(tf_triangle), 1, input );\r
185                         ByteSwapTri (&tri);\r
186                         for (j=0 ; j<3 ; j++)\r
187                         {\r
188                                 int             k;\r
189 \r
190                                 for (k=0 ; k<3 ; k++)\r
191                                 {\r
192                                         ptri->verts[j][k] = tri.pt[j].p.v[k];\r
193                                 }\r
194                         }\r
195 \r
196                         ptri++;\r
197 \r
198                         if ((ptri - *pptri) >= MAXTRIANGLES)\r
199                                 Error ("Error: too many triangles; increase MAXTRIANGLES\n");\r
200                 }\r
201         }\r
202 \r
203         *numtriangles = ptri - *pptri;\r
204 \r
205         fclose (input);\r
206 \r
207         DefaultNodesList(nodesList,num_mesh_nodes,numtriangles);\r
208 }\r
209 \r
210 \r
211 //==========================================================================\r
212 //\r
213 // LoadHRC\r
214 //\r
215 //==========================================================================\r
216 \r
217 float   scaling[3];\r
218 float   rotation[3];\r
219 float   translation[3];\r
220 static char             *hrc_name;\r
221 \r
222 struct\r
223 {\r
224         float v[3];\r
225 } vList[8192];\r
226 \r
227 void HandleHRCModel(triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes,\r
228                                                    int ActiveNode, int Depth, int numVerts)\r
229 {\r
230         void ReadHRCClusterList(mesh_node_t *meshNode, int baseIndex);\r
231 \r
232         int                     i, j;\r
233         int                     vertexCount;\r
234         int                     triCount;\r
235         triangle_t      *tList;\r
236         mesh_node_t *meshNode;\r
237         float           x, y, z;\r
238         float           x2, y2, z2;\r
239         float           rx, ry, rz;\r
240         tokenType_t nextToken;\r
241         float           orig_scaling[3];\r
242         float           orig_rotation[3];\r
243         float           orig_translation[3];\r
244         int                     start_tri;\r
245         int                     pos,bit;\r
246         int                     vertIndexBase;\r
247 \r
248         // Update Node Info\r
249         if (nodesList)\r
250         {\r
251                 TK_BeyondRequire(TK_NAME, TK_STRING);\r
252 \r
253                 if (Depth == 0 || tk_String[0] == '_')\r
254                 {       // Root\r
255                         ActiveNode = *num_mesh_nodes;\r
256                         (*num_mesh_nodes)++;\r
257                         if ((*num_mesh_nodes) > MAX_FM_MESH_NODES)\r
258                         {\r
259                                 Error("Too many mesh nodes in file %s\n", hrc_name);\r
260                         }\r
261                         meshNode = &(*nodesList)[ActiveNode];\r
262 \r
263 //                      memset(meshNode, 0, sizeof(mesh_node_t));\r
264                         strcpy(meshNode->name, tk_String);\r
265 \r
266                         memset(meshNode->tris, 0, sizeof(meshNode->tris));\r
267                         memset(meshNode->verts, 0, sizeof(meshNode->verts));\r
268 \r
269                         meshNode->start_glcmds = 0;\r
270                         meshNode->num_glcmds = 0;\r
271                         vertIndexBase = 0;\r
272                 }\r
273                 else\r
274                 {       // Childs under the children\r
275                         meshNode = &(*nodesList)[ActiveNode];\r
276                         vertIndexBase = numVerts;\r
277                 }\r
278         }\r
279         else \r
280         {\r
281                 meshNode = NULL;\r
282         }\r
283 \r
284 \r
285         // Get the scaling, rotation, and translation values\r
286         TK_Beyond(TK_SCALING);\r
287         for(i = 0; i < 3; i++)\r
288         {\r
289                 orig_scaling[i] = scaling[i];\r
290 \r
291                 TK_Require(TK_FLOATNUMBER);\r
292                 scaling[i] *= tk_FloatNumber;\r
293 \r
294                 TK_Fetch();\r
295         }\r
296         TK_Beyond(TK_ROTATION);\r
297         for(i = 0; i < 3; i++)\r
298         {\r
299                 orig_rotation[i] = rotation[i];\r
300 \r
301                 TK_Require(TK_FLOATNUMBER);\r
302                 rotation[i] = tk_FloatNumber;\r
303 \r
304                 TK_Fetch();\r
305         }\r
306         TK_Beyond(TK_TRANSLATION);\r
307         for(i = 0; i < 3; i++)\r
308         {\r
309                 orig_translation[i] = translation[i];\r
310 \r
311                 TK_Require(TK_FLOATNUMBER);\r
312                 translation[i] += tk_FloatNumber;\r
313 \r
314                 TK_Fetch();\r
315         }\r
316 \r
317         rx = ((rotation[0]-90.0)/360.0)*2.0*M_PI;\r
318         ry = (rotation[2]/360.0)*2.0*M_PI;\r
319         rz = (rotation[1]/360.0)*2.0*M_PI;\r
320 \r
321         // rjr - might not work if there an item doesn't have a mesh\r
322         nextToken = tk_Token;\r
323         if (nextToken == TK_ACTOR_DATA)\r
324         {\r
325                 while (nextToken != TK_MODEL && nextToken != TK_RBRACE)\r
326                 {\r
327                         nextToken = TK_Fetch();\r
328                 }\r
329         }\r
330 \r
331         while (nextToken == TK_SPLINE)\r
332         {       // spline node has two right braces\r
333                 nextToken = TK_Beyond(TK_RBRACE);\r
334                 nextToken = TK_Beyond(TK_RBRACE);\r
335         }\r
336 \r
337         while (nextToken == TK_MATERIAL)\r
338         {\r
339                 nextToken = TK_Beyond(TK_RBRACE);\r
340         }\r
341 \r
342         while(nextToken == TK_MODEL)\r
343         {\r
344                 HandleHRCModel(triList,triangleCount,nodesList,num_mesh_nodes,ActiveNode, Depth+1, 0);\r
345 \r
346                 nextToken = TK_Fetch();\r
347         }\r
348 \r
349         if (nextToken == TK_MESH)\r
350         {\r
351                 // Get all the tri and vertex info\r
352                 TK_BeyondRequire(TK_VERTICES, TK_INTNUMBER);\r
353                 vertexCount = tk_IntNumber;\r
354                 for(i = 0; i < vertexCount; i++)\r
355                 {\r
356                         TK_BeyondRequire(TK_LBRACKET, TK_INTNUMBER);\r
357                         if(tk_IntNumber != i)\r
358                         {\r
359                                 Error("File '%s', line %d:\nVertex index mismatch.\n",\r
360                                         tk_SourceName, tk_Line);\r
361                         }\r
362                         TK_Beyond(TK_POSITION);\r
363                         // Apply the scaling, rotation, and translation in the order\r
364                         // specified in the HRC file.  This could be wrong.\r
365                         TK_Require(TK_FLOATNUMBER);\r
366                         x = tk_FloatNumber*scaling[0];\r
367                         TK_FetchRequire(TK_FLOATNUMBER);\r
368                         y = tk_FloatNumber*scaling[1];\r
369                         TK_FetchRequire(TK_FLOATNUMBER);\r
370                         z = tk_FloatNumber*scaling[2];\r
371 \r
372                         y2 = y*cos(rx)+z*sin(rx);\r
373                         z2 = -y*sin(rx)+z*cos(rx);\r
374                         y = y2;\r
375                         z = z2;\r
376 \r
377                         x2 = x*cos(ry)-z*sin(ry);\r
378                         z2 = x*sin(ry)+z*cos(ry);\r
379                         x = x2;\r
380                         z = z2;\r
381 \r
382                         x2 = x*cos(rz)+y*sin(rz);\r
383                         y2 = -x*sin(rz)+y*cos(rz);\r
384                         x = x2;\r
385                         y = y2;\r
386 \r
387                         vList[i].v[0] = x+translation[0];\r
388                         vList[i].v[1] = y-translation[2];\r
389                         vList[i].v[2] = z+translation[1];\r
390                 }\r
391                 TK_BeyondRequire(TK_POLYGONS, TK_INTNUMBER);\r
392                 triCount = tk_IntNumber;\r
393                 if(triCount >= MAXTRIANGLES)\r
394                 {\r
395                         Error("Too many triangles in file %s\n", hrc_name);\r
396                 }\r
397 \r
398                 start_tri = *triangleCount;\r
399                 *triangleCount += triCount;\r
400 \r
401                 tList = *triList;\r
402 \r
403                 for(i = 0; i < triCount; i++)\r
404                 {\r
405                         if (meshNode)\r
406                         {       // Update the node\r
407                                 pos = (i + start_tri) >> 3;\r
408                                 bit = 1 << ((i + start_tri) & 7 );\r
409                                 meshNode->tris[pos] |= bit;\r
410                         }\r
411 \r
412                         TK_BeyondRequire(TK_LBRACKET, TK_INTNUMBER);\r
413                         if(tk_IntNumber != i)\r
414                         {\r
415                                 Error("File '%s', line %d:\nTriangle index mismatch.\n",\r
416                                         tk_SourceName, tk_Line);\r
417                         }\r
418                         TK_BeyondRequire(TK_NODES, TK_INTNUMBER);\r
419                         if(tk_IntNumber != 3)\r
420                         {\r
421                                 Error("File '%s', line %d:\nBad polygon vertex count: %d.",\r
422                                         tk_SourceName, tk_Line, tk_IntNumber);\r
423                         }\r
424                         tList[i+start_tri].HasUV = true;\r
425                         for(j = 0; j < 3; j++)\r
426                         {\r
427                                 TK_BeyondRequire(TK_LBRACKET, TK_INTNUMBER);\r
428                                 if(tk_IntNumber != j)\r
429                                 {\r
430                                         Error("File '%s', line %d:\nTriangle vertex index"\r
431                                                 " mismatch.  %d should be %d\n", tk_SourceName, tk_Line,\r
432                                                 tk_IntNumber, j);\r
433                                 }\r
434                                 TK_BeyondRequire(TK_VERTEX, TK_INTNUMBER);\r
435 \r
436                                 tList[i+start_tri].verts[2-j][0] = vList[tk_IntNumber].v[0];\r
437                                 tList[i+start_tri].verts[2-j][1] = vList[tk_IntNumber].v[1];\r
438                                 tList[i+start_tri].verts[2-j][2] = vList[tk_IntNumber].v[2];\r
439 #if 1\r
440                                 tList[i+start_tri].indicies[2-j] = tk_IntNumber+vertIndexBase;\r
441 #endif\r
442                                 TK_BeyondRequire(TK_UVTEXTURE, TK_FLOATNUMBER);\r
443                                 tList[i+start_tri].uv[2-j][0] = tk_FloatNumber;\r
444                                 TK_Fetch();\r
445                                 TK_Require(TK_FLOATNUMBER);\r
446                                 tList[i+start_tri].uv[2-j][1] = tk_FloatNumber;\r
447                         }\r
448 \r
449         /*              printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"\r
450                                 "  v2: %f, %f, %f\n", i,\r
451                                 tList[i].verts[0][0],\r
452                                 tList[i].verts[0][1],\r
453                                 tList[i].verts[0][2],\r
454                                 tList[i].verts[1][0],\r
455                                 tList[i].verts[1][1],\r
456                                 tList[i].verts[1][2],\r
457                                 tList[i].verts[2][0],\r
458                                 tList[i].verts[2][1],\r
459                                 tList[i].verts[2][2]);\r
460         */\r
461                 }\r
462 \r
463                 TK_Beyond(TK_RBRACE);\r
464                 TK_Beyond(TK_RBRACE);\r
465 \r
466                 if (tk_Token == TK_EDGES)\r
467                 {\r
468                 //      TK_Beyond(TK_EDGES);\r
469                         TK_Beyond(TK_RBRACE);\r
470                 }\r
471 \r
472                 scaling[0] = scaling[1] = scaling[2] = 1.0;\r
473         //      rotation[0] = rotation[1] = rotation[2] = 0.0;\r
474         //      translation[0] = translation[1] = translation[2] = 0.0;\r
475 \r
476                 // See if there are any other models belonging to this node\r
477 \r
478 #if 1\r
479                 TK_Fetch();\r
480 \r
481                 nextToken = tk_Token;\r
482                 if(nextToken == TK_CLUSTERS)\r
483                 {\r
484                         if(g_skelModel.clustered == -1)\r
485                         {\r
486                                 ReadHRCClusterList(meshNode, vertIndexBase);\r
487                         }\r
488                         else\r
489                         {\r
490                                 nextToken = TK_Get(TK_CLUSTER_NAME);\r
491 \r
492                                 while (nextToken == TK_CLUSTER_NAME)\r
493                                 {\r
494                                         TK_BeyondRequire(TK_CLUSTER_STATE, TK_INTNUMBER);\r
495                                         nextToken = TK_Fetch();\r
496                                 }\r
497                         }\r
498 \r
499                         // one right brace follow the list of clusters\r
500                         nextToken = TK_Beyond(TK_RBRACE);\r
501                 }\r
502                 else\r
503                 {\r
504                         if(g_skelModel.clustered == -1 && !vertIndexBase)\r
505                         {\r
506                                 meshNode->clustered = false;\r
507                         }\r
508                 }\r
509 #endif\r
510 \r
511                 nextToken = tk_Token;\r
512                 if(nextToken == TK_SPLINE)\r
513                 {\r
514                         while (nextToken == TK_SPLINE)\r
515                         {       // spline node has two right braces\r
516                                 nextToken = TK_Beyond(TK_RBRACE);\r
517                                 nextToken = TK_Beyond(TK_RBRACE);\r
518                         }\r
519 \r
520                         nextToken = TK_Beyond(TK_RBRACE);\r
521                 }\r
522 \r
523                 while (nextToken == TK_MATERIAL)\r
524                 {\r
525                         nextToken = TK_Beyond(TK_RBRACE);\r
526                 }\r
527 \r
528                 while(nextToken == TK_MODEL)\r
529                 {\r
530                         HandleHRCModel(triList,triangleCount,nodesList, num_mesh_nodes, ActiveNode, Depth+1, vertexCount+vertIndexBase);\r
531 \r
532                         nextToken = TK_Fetch();\r
533                 }\r
534         }\r
535 \r
536         for(i=0;i<3;i++)\r
537         {\r
538                 scaling[i] = orig_scaling[i];\r
539                 rotation[i] = orig_rotation[i];\r
540                 translation[i] = orig_translation[i];\r
541         }\r
542 }\r
543 \r
544 static void LoadHRC(char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes)\r
545 {\r
546         if (nodesList)\r
547         {\r
548                 *num_mesh_nodes = 0;\r
549 \r
550                 if(!*nodesList)\r
551                 {\r
552                         *nodesList = (mesh_node_t *) SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");\r
553                 }\r
554         }\r
555 \r
556         hrc_name = fileName;\r
557 \r
558         scaling[0] = scaling[1] = scaling[2] = 1.0;\r
559         rotation[0] = rotation[1] = rotation[2] = 0.0;\r
560         translation[0] = translation[1] = translation[2] = 0.0;\r
561 \r
562         *triangleCount = 0;\r
563         *triList = (triangle_t *) SafeMalloc(MAXTRIANGLES*sizeof(triangle_t), "Triangle list");\r
564         memset(*triList,0,MAXTRIANGLES*sizeof(triangle_t));\r
565 \r
566         TK_OpenSource(fileName);\r
567         TK_FetchRequire(TK_HRCH);\r
568         TK_FetchRequire(TK_COLON);\r
569         TK_FetchRequire(TK_SOFTIMAGE);\r
570 \r
571         // prime it\r
572         TK_Beyond(TK_MODEL);\r
573 \r
574         HandleHRCModel(triList, triangleCount, nodesList, num_mesh_nodes, 0, 0, 0);\r
575         TK_CloseSource();\r
576 }\r
577 \r
578 //==========================================================================\r
579 //\r
580 // LoadHTR\r
581 //\r
582 //==========================================================================\r
583 /*\r
584 static int Version2;\r
585 \r
586 void HandleHTRModel(triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes,\r
587                                                    int ActiveNode, int Depth, int numVerts)\r
588 {\r
589         int                     i, j;\r
590         int                     vertexCount;\r
591         int                     vertexNum;\r
592         int                     triCount;\r
593         float           origin[3];\r
594         triangle_t      *tList;\r
595         float           x, y, z;\r
596         float           x2, y2, z2;\r
597         float           rx, ry, rz;\r
598         mesh_node_t *meshNode;\r
599         int                     pos,bit;\r
600         int                     vertIndexBase;\r
601         int                     start_tri;\r
602 \r
603         if (nodesList)\r
604         {\r
605                 TK_BeyondRequire(TK_NAME, TK_STRING);\r
606 \r
607                 if (Depth == 0 || tk_String[0] == '_')\r
608                 {       // Root\r
609                         ActiveNode = *num_mesh_nodes;\r
610                         (*num_mesh_nodes)++;\r
611                         if ((*num_mesh_nodes) > MAX_FM_MESH_NODES)\r
612                         {\r
613                                 Error("Too many mesh nodes in file %s\n", hrc_name);\r
614                         }\r
615                         meshNode = &(*nodesList)[ActiveNode];\r
616 \r
617 //                      memset(meshNode, 0, sizeof(mesh_node_t));\r
618                         strcpy(meshNode->name, tk_String);\r
619 \r
620                         memset(meshNode->tris, 0, sizeof(meshNode->tris));\r
621                         memset(meshNode->verts, 0, sizeof(meshNode->verts));\r
622 \r
623                         meshNode->start_glcmds = 0;\r
624                         meshNode->num_glcmds = 0;\r
625                         vertIndexBase = 0;\r
626                 }\r
627                 else\r
628                 {       // Childs under the children\r
629                         meshNode = &(*nodesList)[ActiveNode];\r
630                         vertIndexBase = numVerts;\r
631                 }\r
632         }\r
633         else \r
634         {\r
635                 meshNode = NULL;\r
636         }\r
637 \r
638         // Get vertex count\r
639         TK_BeyondRequire(TK_VERTICES, TK_INTNUMBER);\r
640         vertexCount = tk_IntNumber;\r
641         \r
642         // Get triangle count\r
643         TK_BeyondRequire(TK_FACES, TK_INTNUMBER);\r
644         triCount = tk_IntNumber;\r
645         if(triCount >= MAXTRIANGLES)\r
646         {\r
647                 Error("Too many triangles in file %s\n", hrc_name);\r
648         }\r
649 \r
650         // Get origin\r
651         TK_Beyond(TK_ORIGIN);\r
652         TK_Require(TK_FLOATNUMBER);\r
653         origin[0] = tk_FloatNumber;\r
654         TK_FetchRequire(TK_FLOATNUMBER);\r
655         origin[1] = tk_FloatNumber;\r
656         TK_FetchRequire(TK_FLOATNUMBER);\r
657         origin[2] = tk_FloatNumber;\r
658 \r
659         //rx = 90.0/360.0*2.0*M_PI;\r
660         rx = FixHTRRotateX/360.0*2.0*M_PI;\r
661         ry = FixHTRRotateY/360.0*2.0*M_PI;\r
662         rz = FixHTRRotateZ/360.0*2.0*M_PI;\r
663 \r
664         // Get vertex list\r
665         for(i = 0; i < vertexCount; i++)\r
666         {\r
667                 TK_FetchRequire(TK_VERTEX);\r
668                 TK_FetchRequire(TK_FLOATNUMBER);\r
669                 x = tk_FloatNumber-origin[0];\r
670                 TK_FetchRequire(TK_FLOATNUMBER);\r
671                 y = tk_FloatNumber-origin[1];\r
672                 TK_FetchRequire(TK_FLOATNUMBER);\r
673                 z = tk_FloatNumber-origin[2];\r
674 \r
675                 x += FixHTRTranslateX;\r
676                 y += FixHTRTranslateY;\r
677                 z += FixHTRTranslateZ;\r
678 \r
679                 y2 = y*cos(rx)-z*sin(rx);\r
680                 z2 = y*sin(rx)+z*cos(rx);\r
681                 y = y2;\r
682                 z = z2;\r
683                 x2 = x*cos(ry)+z*sin(ry);\r
684                 z2 = -x*sin(ry)+z*cos(ry);\r
685                 x = x2;\r
686                 z = z2;\r
687                 x2 = x*cos(rz)-y*sin(rz);\r
688                 y2 = x*sin(rz)+y*cos(rz);\r
689                 x = x2;\r
690                 y = y2;\r
691 \r
692                 vList[i].v[0] = x;\r
693                 vList[i].v[1] = y;\r
694                 vList[i].v[2] = z;\r
695         }\r
696 \r
697         start_tri = *triangleCount;\r
698         *triangleCount += triCount;\r
699 \r
700         tList = *triList;\r
701 \r
702         // Get face list\r
703         for(i = 0; i < triCount; i++)\r
704         {\r
705                 if (meshNode)\r
706                 {       // Update the node\r
707                         pos = (i + start_tri) >> 3;\r
708                         bit = 1 << ((i + start_tri) & 7 );\r
709                         meshNode->tris[pos] |= bit;\r
710                 }\r
711 \r
712                 TK_FetchRequire(TK_FACE);\r
713                 TK_FetchRequire(TK_LPAREN);\r
714                 for(j = 0; j < 3; j++)\r
715                 {\r
716                         TK_FetchRequire(TK_INTNUMBER);\r
717                         vertexNum = tk_IntNumber-1;\r
718                         if(vertexNum >= vertexCount)\r
719                         {\r
720                                 Error("File '%s', line %d:\nVertex number"\r
721                                         " >= vertexCount: %d\n", tk_SourceName, tk_Line,\r
722                                         tk_IntNumber);\r
723                         }\r
724                         tList[i+start_tri].verts[2-j][0] = vList[vertexNum].v[0];\r
725                         tList[i+start_tri].verts[2-j][1] = vList[vertexNum].v[1];\r
726                         tList[i+start_tri].verts[2-j][2] = vList[vertexNum].v[2];\r
727                 }\r
728                 TK_FetchRequire(TK_RPAREN);\r
729 #ifdef _QDATA\r
730                 if (Version2)\r
731                 {\r
732                         TK_FetchRequire(TK_FLOATNUMBER);\r
733                         tList[i+start_tri].uv[0][0]=tk_FloatNumber;\r
734                         TK_FetchRequire(TK_FLOATNUMBER);\r
735                         tList[i+start_tri].uv[0][1]=tk_FloatNumber;\r
736                         TK_FetchRequire(TK_FLOATNUMBER);\r
737                         tList[i+start_tri].uv[1][0]=tk_FloatNumber;\r
738                         TK_FetchRequire(TK_FLOATNUMBER);\r
739                         tList[i+start_tri].uv[1][1]=tk_FloatNumber;\r
740                         TK_FetchRequire(TK_FLOATNUMBER);\r
741                         tList[i+start_tri].uv[2][0]=tk_FloatNumber;\r
742                         TK_FetchRequire(TK_FLOATNUMBER);\r
743                         tList[i+start_tri].uv[2][1]=tk_FloatNumber;\r
744                         tList[i+start_tri].HasUV=1;\r
745                 }\r
746                 else\r
747                         tList[i+start_tri].HasUV=0;\r
748 #endif\r
749 //              printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"\r
750 //                      "  v2: %f, %f, %f\n", i,\r
751 //                      tList[i].verts[0][0],\r
752 //                      tList[i].verts[0][1],\r
753 //                      tList[i].verts[0][2],\r
754 //                      tList[i].verts[1][0],\r
755 //                      tList[i].verts[1][1],\r
756 //                      tList[i].verts[1][2],\r
757 //                      tList[i].verts[2][0],\r
758 //                      tList[i].verts[2][1],\r
759 //                      tList[i].verts[2][2]);\r
760 \r
761         }\r
762 \r
763         TK_Fetch();\r
764 \r
765         if (tk_Token == TK_VERTICES) \r
766         {\r
767                 HandleHTRModel(triList,triangleCount,nodesList, num_mesh_nodes, ActiveNode, Depth+1, vertexCount+vertIndexBase);\r
768         }\r
769 }\r
770 \r
771 static void LoadHTR(char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes)\r
772 {\r
773         if (nodesList)\r
774         {\r
775                 *num_mesh_nodes = 0;\r
776 \r
777                 if(!*nodesList)\r
778                 {\r
779                         *nodesList = SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");\r
780                 }\r
781         }\r
782 \r
783         hrc_name = fileName;\r
784 \r
785         scaling[0] = scaling[1] = scaling[2] = 1.0;\r
786         rotation[0] = rotation[1] = rotation[2] = 0.0;\r
787         translation[0] = translation[1] = translation[2] = 0.0;\r
788 \r
789         *triangleCount = 0;\r
790         *triList = SafeMalloc(MAXTRIANGLES*sizeof(triangle_t), "Triangle list");\r
791         memset(*triList,0,MAXTRIANGLES*sizeof(triangle_t));\r
792 \r
793         TK_OpenSource(fileName);\r
794 \r
795         TK_Beyond(TK_C_HEXEN);\r
796         TK_Beyond(TK_C_TRIANGLES);\r
797         TK_BeyondRequire(TK_C_VERSION, TK_INTNUMBER);\r
798         if(tk_IntNumber != 1&&tk_IntNumber != 2)\r
799         {\r
800                 Error("Unsupported version (%d) in file %s\n", tk_IntNumber,\r
801                         fileName);\r
802         }\r
803         Version2=(tk_IntNumber==2);\r
804 \r
805 \r
806         HandleHTRModel(triList, triangleCount, nodesList, num_mesh_nodes, 0, 0, 0);\r
807 }\r
808 \r
809 */\r
810 \r
811 static void LoadHTR(char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes)\r
812 {\r
813         int Version2=0;\r
814         int                     i, j;\r
815         int                     vertexCount;\r
816         int                     vertexNum;\r
817         struct\r
818         {\r
819                 float v[3];\r
820         }                       *vList;\r
821         int                     triCount;\r
822         float           origin[3];\r
823         triangle_t      *tList;\r
824         float           x, y, z;\r
825         float           x2, y2, z2;\r
826         float           rx, ry, rz;\r
827 \r
828         if (nodesList)\r
829         {\r
830                 *num_mesh_nodes = 0;\r
831                 *nodesList = (mesh_node_t *) SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");\r
832         }\r
833 \r
834         TK_OpenSource(fileName);\r
835 \r
836         TK_Beyond(TK_C_HEXEN);\r
837         TK_Beyond(TK_C_TRIANGLES);\r
838         TK_BeyondRequire(TK_C_VERSION, TK_INTNUMBER);\r
839         if(tk_IntNumber != 1&&tk_IntNumber != 2)\r
840         {\r
841                 Error("Unsupported version (%d) in file %s\n", tk_IntNumber,\r
842                         fileName);\r
843         }\r
844         Version2=(tk_IntNumber==2);\r
845 \r
846 \r
847         // Get vertex count\r
848         TK_BeyondRequire(TK_VERTICES, TK_INTNUMBER);\r
849         vertexCount = tk_IntNumber;\r
850         vList = (void *) SafeMalloc(vertexCount*sizeof vList[0], "Vertex list");\r
851         \r
852         // Get triangle count\r
853         TK_BeyondRequire(TK_FACES, TK_INTNUMBER);\r
854         triCount = tk_IntNumber;\r
855         if(triCount >= MAXTRIANGLES)\r
856         {\r
857                 Error("Too many triangles in file %s\n", fileName);\r
858         }\r
859         *triangleCount = triCount;\r
860         tList = (triangle_t *) SafeMalloc(MAXTRIANGLES*sizeof(triangle_t), "Triangle list");\r
861         *triList = tList;\r
862         memset(*triList,0,MAXTRIANGLES*sizeof(triangle_t));\r
863 \r
864         // Get origin\r
865         TK_Beyond(TK_ORIGIN);\r
866         TK_Require(TK_FLOATNUMBER);\r
867         origin[0] = tk_FloatNumber;\r
868         TK_FetchRequire(TK_FLOATNUMBER);\r
869         origin[1] = tk_FloatNumber;\r
870         TK_FetchRequire(TK_FLOATNUMBER);\r
871         origin[2] = tk_FloatNumber;\r
872 \r
873         //rx = 90.0/360.0*2.0*M_PI;\r
874         rx = FixHTRRotateX/360.0*2.0*M_PI;\r
875         ry = FixHTRRotateY/360.0*2.0*M_PI;\r
876         rz = FixHTRRotateZ/360.0*2.0*M_PI;\r
877 \r
878         // Get vertex list\r
879         for(i = 0; i < vertexCount; i++)\r
880         {\r
881                 TK_FetchRequire(TK_VERTEX);\r
882                 TK_FetchRequire(TK_FLOATNUMBER);\r
883                 x = tk_FloatNumber-origin[0];\r
884                 TK_FetchRequire(TK_FLOATNUMBER);\r
885                 y = tk_FloatNumber-origin[1];\r
886                 TK_FetchRequire(TK_FLOATNUMBER);\r
887                 z = tk_FloatNumber-origin[2];\r
888 \r
889                 x += FixHTRTranslateX;\r
890                 y += FixHTRTranslateY;\r
891                 z += FixHTRTranslateZ;\r
892 \r
893                 y2 = y*cos(rx)-z*sin(rx);\r
894                 z2 = y*sin(rx)+z*cos(rx);\r
895                 y = y2;\r
896                 z = z2;\r
897                 x2 = x*cos(ry)+z*sin(ry);\r
898                 z2 = -x*sin(ry)+z*cos(ry);\r
899                 x = x2;\r
900                 z = z2;\r
901                 x2 = x*cos(rz)-y*sin(rz);\r
902                 y2 = x*sin(rz)+y*cos(rz);\r
903                 x = x2;\r
904                 y = y2;\r
905 \r
906                 vList[i].v[0] = x;\r
907                 vList[i].v[1] = y;\r
908                 vList[i].v[2] = z;\r
909         }\r
910 \r
911         // Get face list\r
912         for(i = 0; i < triCount; i++)\r
913         {\r
914                 TK_FetchRequire(TK_FACE);\r
915                 TK_FetchRequire(TK_LPAREN);\r
916                 for(j = 0; j < 3; j++)\r
917                 {\r
918                         TK_FetchRequire(TK_INTNUMBER);\r
919                         vertexNum = tk_IntNumber-1;\r
920                         if(vertexNum >= vertexCount)\r
921                         {\r
922                                 Error("File '%s', line %d:\nVertex number"\r
923                                         " >= vertexCount: %d\n", tk_SourceName, tk_Line,\r
924                                         tk_IntNumber);\r
925                         }\r
926                         tList[i].verts[2-j][0] = vList[vertexNum].v[0];\r
927                         tList[i].verts[2-j][1] = vList[vertexNum].v[1];\r
928                         tList[i].verts[2-j][2] = vList[vertexNum].v[2];\r
929                 }\r
930                 TK_FetchRequire(TK_RPAREN);\r
931 #if 1\r
932                 if (Version2)\r
933                 {\r
934                         TK_FetchRequire(TK_FLOATNUMBER);\r
935                         tList[i].uv[2][0]= fmod(1000+tk_FloatNumber,1);\r
936                         TK_FetchRequire(TK_FLOATNUMBER);\r
937                         tList[i].uv[2][1]=fmod(1000+tk_FloatNumber,1);\r
938                         TK_FetchRequire(TK_FLOATNUMBER);\r
939                         tList[i].uv[1][0]=fmod(1000+tk_FloatNumber,1);\r
940                         TK_FetchRequire(TK_FLOATNUMBER);\r
941                         tList[i].uv[1][1]=fmod(1000+tk_FloatNumber,1);\r
942                         TK_FetchRequire(TK_FLOATNUMBER);\r
943                         tList[i].uv[0][0]=fmod(1000+tk_FloatNumber,1);\r
944                         TK_FetchRequire(TK_FLOATNUMBER);\r
945                         tList[i].uv[0][1]=fmod(1000+tk_FloatNumber,1);\r
946                         tList[i].HasUV=1;\r
947                 }\r
948                 else\r
949                         tList[i].HasUV=0;\r
950 #endif\r
951 /*              printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"\r
952                         "  v2: %f, %f, %f\n", i,\r
953                         tList[i].verts[0][0],\r
954                         tList[i].verts[0][1],\r
955                         tList[i].verts[0][2],\r
956                         tList[i].verts[1][0],\r
957                         tList[i].verts[1][1],\r
958                         tList[i].verts[1][2],\r
959                         tList[i].verts[2][0],\r
960                         tList[i].verts[2][1],\r
961                         tList[i].verts[2][2]);\r
962 */\r
963         }\r
964 \r
965         free(vList);\r
966         TK_CloseSource();\r
967         DefaultNodesList(nodesList,num_mesh_nodes,triangleCount);\r
968 }\r
969 \r
970 //==========================================================================\r
971 //\r
972 // LoadTriangleList\r
973 //\r
974 //==========================================================================\r
975 \r
976 void LoadTriangleList(char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **ppmnodes, int *num_mesh_nodes)\r
977 {\r
978         FILE    *file1;\r
979     int         dot = '.';\r
980         char    *dotstart;\r
981         char    InputFileName[256];\r
982 \r
983         dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?\r
984 \r
985         if (!dotstart)\r
986         {\r
987                 strcpy(InputFileName, fileName);\r
988                 strcat(InputFileName, ".hrc");\r
989                 if((file1 = fopen(InputFileName, "rb")) != NULL)\r
990                 {\r
991                         fclose(file1);\r
992                         LoadHRC(InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
993                         printf(" - assuming .HRC\n");\r
994                         return;\r
995                 }\r
996 \r
997                 strcpy(InputFileName, fileName);\r
998                 strcat(InputFileName, ".asc");\r
999                 if((file1 = fopen(InputFileName, "rb")) != NULL)\r
1000                 {\r
1001                         fclose(file1);\r
1002                         LoadASC(InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
1003                         printf(" - assuming .ASC\n");\r
1004                         return;\r
1005                 }\r
1006 \r
1007                 strcpy(InputFileName, fileName);\r
1008                 strcat(InputFileName, ".tri");\r
1009                 if((file1 = fopen(InputFileName, "rb")) != NULL)\r
1010                 {                       \r
1011                         fclose(file1);\r
1012                         LoadTRI(InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
1013                         printf(" - assuming .TRI\n");\r
1014                         return;\r
1015                 }\r
1016 \r
1017                 strcpy(InputFileName, fileName);\r
1018                 strcat(InputFileName, ".3ds");\r
1019                 if((file1 = fopen(InputFileName, "rb")) != NULL)\r
1020                 {                       \r
1021                         fclose(file1);\r
1022                         Load3DSTriangleList (InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
1023                         printf(" - assuming .3DS\n");\r
1024                         return;\r
1025                 }\r
1026 \r
1027                 strcpy(InputFileName, fileName);\r
1028                 strcat(InputFileName, ".htr");\r
1029                 if((file1 = fopen(InputFileName, "rb")) != NULL)\r
1030                 {                       \r
1031                         fclose(file1);\r
1032                         LoadHTR (InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
1033                         printf(" - assuming .HTR\n");\r
1034                         return;\r
1035                 }\r
1036                 Error("\n Could not open file '%s':\n"\r
1037                         "No HRC, ASC, 3DS, HTR, or TRI match.\n", fileName);\r
1038         }\r
1039         else\r
1040         {\r
1041                 if((file1 = fopen(fileName, "rb")) != NULL)\r
1042                 {\r
1043                         printf("\n");\r
1044                         fclose(file1);\r
1045                         if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)\r
1046                         {\r
1047                                 LoadHRC(fileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
1048                         }\r
1049                         else if (strcmp(dotstart,".asc") == 0 || strcmp(dotstart,".ASC") == 0)\r
1050                         {\r
1051                                 LoadASC(fileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
1052                         }\r
1053                         else if (strcmp(dotstart,".tri") == 0 || strcmp(dotstart,".TRI") == 0)\r
1054                         {\r
1055                                 LoadTRI(fileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
1056                         }\r
1057                         else if (strcmp(dotstart,".3ds") == 0 || strcmp(dotstart,".3DS") == 0)\r
1058                         {\r
1059                                 Load3DSTriangleList (fileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
1060                         }\r
1061                         else if (strcmp(dotstart,".htr") == 0 || strcmp(dotstart,".HTR") == 0)\r
1062                         {\r
1063                                 LoadHTR (fileName, triList, triangleCount, ppmnodes, num_mesh_nodes);\r
1064                         }\r
1065                         else\r
1066                         {\r
1067                                 Error("Could not open file '%s':\n",fileName);\r
1068                                 return;\r
1069                         }\r
1070                 }\r
1071                 else    //failed to load file\r
1072                 {\r
1073                                 Error("Could not open file '%s':\n",fileName);\r
1074                 }\r
1075 \r
1076         }\r
1077 }\r