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