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