1 /*
2 * loadtri.c
3 * $Id: loadtri.c,v 1.14 2010-02-22 22:30:33 sezero Exp $
4 *
5 * Copyright (C) 1996-1997 Id Software, Inc.
6 * Copyright (C) 1997-1998 Raven Software Corp.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 * See the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 // HEADER FILES ------------------------------------------------------------
25
26 #include "q_stdinc.h"
27 #include "compiler.h"
28 #include "arch_def.h"
29 #include "cmdlib.h"
30 #include "pathutil.h"
31 #include "mathlib.h"
32 #include "loadtri.h"
33 #include "token.h"
34 #include "q_endian.h"
35
36 // MACROS ------------------------------------------------------------------
37
38 //#undef M_PI
39 //#define M_PI 3.14159265
40 #define MY_PI 3.14159265
41
42 // 3DS binary files
43 #define _3DS_MAIN3DS 0x4D4D
44 #define _3DS_EDIT3DS 0x3D3D
45 #define _3DS_EDIT_MATERIAL 0xAFFF
46 #define _3DS_EDIT_VIEW1 0x7001
47 #define _3DS_EDIT_BACKGR 0x1200
48 #define _3DS_EDIT_AMBIENT 0x2100
49 #define _3DS_EDIT_UNKNW01 0x1100
50 #define _3DS_EDIT_UNKNW02 0x1201
51 #define _3DS_EDIT_UNKNW03 0x1300
52 #define _3DS_EDIT_UNKNW04 0x1400
53 #define _3DS_EDIT_UNKNW05 0x1420
54 #define _3DS_EDIT_UNKNW06 0x1450
55 #define _3DS_EDIT_UNKNW07 0x1500
56 #define _3DS_EDIT_UNKNW08 0x2200
57 #define _3DS_EDIT_UNKNW09 0x2201
58 #define _3DS_EDIT_UNKNW10 0x2210
59 #define _3DS_EDIT_UNKNW11 0x2300
60 #define _3DS_EDIT_UNKNW12 0x2302
61 #define _3DS_EDIT_UNKNW13 0x3000
62 #define _3DS_EDIT_UNKNW14 0xAFFF
63 #define _3DS_EDIT_OBJECT 0x4000
64 #define _3DS_OBJ_LIGHT 0x4600
65 #define _3DS_OBJ_CAMERA 0x4700
66 #define _3DS_OBJ_UNKNWN01 0x4010
67 #define _3DS_OBJ_UNKNWN02 0x4012
68 #define _3DS_OBJ_TRIMESH 0x4100
69 #define _3DS_TRI_FACEL2 0x4111
70 #define _3DS_TRI_VISIBLE 0x4165
71 #define _3DS_TRI_VERTEXL 0x4110
72 #define _3DS_TRI_FACEL1 0x4120
73
74 // TRI binary files
75 #define FLOAT_START 99999.0
76 #define FLOAT_END -FLOAT_START
77 #define TRI_MAGIC 123322
78
79 // TYPES -------------------------------------------------------------------
80
81 typedef struct
82 {
83 float v[3];
84 } vector;
85
86 typedef struct
87 {
88 vector n; // normal
89 vector p; // point
90 vector c; // color
91 float u; // u
92 float v; // v
93 } aliaspoint_t;
94
95 typedef struct
96 {
97 aliaspoint_t pt[3];
98 } tf_triangle;
99
100 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
101
102 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
103
104 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
105
106 static void LoadHRC(char *fileName, triangle_t **triList, int *triangleCount);
107 static void LoadASC(char *fileName, triangle_t **triList, int *triangleCount);
108 static void LoadHTR(char *fileName, triangle_t **triList, int *triangleCount);
109 static void LoadTRI(FILE *input, triangle_t **triList, int *triangleCount);
110
111 static void ByteSwapTri(tf_triangle *tri);
112
113 #if 0 /* unused 3DS stuff */
114 static void Load3DS(FILE *input, triangle_t **triList, int *triangleCount);
115 static void _3DSError(char *message);
116
117 static float ReadFloat(void);
118 static unsigned long ReadLong(void);
119 static unsigned short ReadShort(void);
120 static unsigned char ReadByte(void);
121 static void SkipName(void);
122 static void SeekTo(int position);
123 static unsigned long FilePosition(void);
124 #endif
125
126 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
127
128 // PUBLIC DATA DEFINITIONS -------------------------------------------------
129
130 char InputFileName[1024];
131 FILE *InputFile;
132 float FixHTRRotateX = 0.0;
133 float FixHTRRotateY = 0.0;
134 float FixHTRRotateZ = 0.0;
135 float FixHTRTranslateX = 0.0;
136 float FixHTRTranslateY = 0.0;
137 float FixHTRTranslateZ = 0.0;
138
139 // PRIVATE DATA DEFINITIONS ------------------------------------------------
140
141 // CODE --------------------------------------------------------------------
142
143 //==========================================================================
144 //
145 // LoadTriangleList
146 //
147 //==========================================================================
148
LoadTriangleList(const char * fileName,triangle_t ** triList,int * triangleCount)149 void LoadTriangleList(const char *fileName, triangle_t **triList, int *triangleCount)
150 {
151 FILE *input;
152
153 q_strlcpy(InputFileName, fileName, sizeof(InputFileName));
154
155 StripExtension(InputFileName);
156 q_strlcat(InputFileName, ".asc", sizeof(InputFileName));
157 if ((input = fopen(InputFileName, "rb")) != NULL)
158 {
159 fclose(input);
160 LoadASC(InputFileName, triList, triangleCount);
161 return;
162 }
163
164 StripExtension(InputFileName);
165 q_strlcat(InputFileName, ".hrc", sizeof(InputFileName));
166 if ((input = fopen(InputFileName, "rb")) != NULL)
167 {
168 fclose(input);
169 LoadHRC(InputFileName, triList, triangleCount);
170 return;
171 }
172
173 StripExtension(InputFileName);
174 q_strlcat(InputFileName, ".htr", sizeof(InputFileName));
175 if ((input = fopen(InputFileName, "rb")) != NULL)
176 {
177 fclose(input);
178 LoadHTR(InputFileName, triList, triangleCount);
179 return;
180 }
181
182 StripExtension(InputFileName);
183 q_strlcat(InputFileName, ".tri", sizeof(InputFileName));
184 if ((input = fopen(InputFileName, "rb")) != NULL)
185 {
186 LoadTRI(input, triList, triangleCount);
187 fclose(input);
188 return;
189 }
190
191 COM_Error("Could not open file '%s':\n"
192 "No ASC, HRC, HTR, or TRI match.\n", fileName);
193 }
194
195 //==========================================================================
196 //
197 // LoadHRC
198 //
199 //==========================================================================
200
LoadHRC(char * fileName,triangle_t ** triList,int * triangleCount)201 static void LoadHRC(char *fileName, triangle_t **triList, int *triangleCount)
202 {
203 int i, j;
204 int vertexCount;
205 struct vList_s
206 {
207 float v[3];
208 } *vList;
209 int triCount;
210 triangle_t *tList;
211 float scaling[3];
212 float rotation[3];
213 float translation[3];
214 float x, y, z;
215 float x2, y2, z2;
216 float rx, ry, rz;
217
218 TK_Init();
219 TK_OpenSource(fileName);
220 TK_FetchRequire(TK_HRCH);
221 TK_FetchRequire(TK_COLON);
222 TK_FetchRequire(TK_SOFTIMAGE);
223 TK_Beyond(TK_MODEL);
224 TK_Beyond(TK_SCALING);
225 for (i = 0; i < 3; i++)
226 {
227 TK_Require(TK_FLOATNUMBER);
228 scaling[i] = tk_FloatNumber;
229 TK_Fetch();
230 }
231 TK_Beyond(TK_ROTATION);
232 for (i = 0; i < 3; i++)
233 {
234 TK_Require(TK_FLOATNUMBER);
235 rotation[i] = tk_FloatNumber;
236 TK_Fetch();
237 }
238 TK_Beyond(TK_TRANSLATION);
239 for (i = 0; i < 3; i++)
240 {
241 TK_Require(TK_FLOATNUMBER);
242 translation[i] = tk_FloatNumber;
243 TK_Fetch();
244 }
245
246 rx = (float)(((rotation[0]-90.0)/360.0)*2.0*MY_PI);
247 ry = (float)((rotation[1]/360.0)*2.0*MY_PI);
248 rz = (float)((rotation[2]/360.0)*2.0*MY_PI);
249
250 TK_Beyond(TK_MESH);
251 TK_BeyondRequire(TK_VERTICES, TK_INTNUMBER);
252 vertexCount = tk_IntNumber;
253 vList = (struct vList_s *) SafeMalloc(vertexCount * sizeof(vList[0]));
254 for (i = 0; i < vertexCount; i++)
255 {
256 TK_BeyondRequire(TK_LBRACKET, TK_INTNUMBER);
257 if (tk_IntNumber != i)
258 {
259 COM_Error("File '%s', line %d:\nVertex index mismatch.\n",
260 tk_SourceName, tk_Line);
261 }
262 TK_Beyond(TK_POSITION);
263 // Apply the scaling, rotation, and translation in the order
264 // specified in the HRC file. This could be wrong.
265 TK_Require(TK_FLOATNUMBER);
266 x = tk_FloatNumber*scaling[0];
267 TK_FetchRequire(TK_FLOATNUMBER);
268 y = tk_FloatNumber*scaling[1];
269 TK_FetchRequire(TK_FLOATNUMBER);
270 z = tk_FloatNumber*scaling[2];
271
272 y2 = (float)(y*cos(rx)+z*sin(rx));
273 z2 = (float)(-y*sin(rx)+z*cos(rx));
274 y = y2;
275 z = z2;
276
277 x2 = (float)(x*cos(ry)-z*sin(ry));
278 z2 = (float)(x*sin(ry)+z*cos(ry));
279 x = x2;
280 z = z2;
281
282 x2 = (float)(x*cos(rz)+y*sin(rz));
283 y2 = (float)(-x*sin(rz)+y*cos(rz));
284 x = x2;
285 y = y2;
286
287 vList[i].v[0] = x+translation[0];
288 vList[i].v[1] = y+translation[1];
289 vList[i].v[2] = z+translation[2];
290 }
291 TK_BeyondRequire(TK_POLYGONS, TK_INTNUMBER);
292 triCount = tk_IntNumber;
293 if (triCount >= MAXTRIANGLES)
294 {
295 COM_Error("Too many triangles in file %s\n", InputFileName);
296 }
297 *triangleCount = triCount;
298 tList = (triangle_t *) SafeMalloc(MAXTRIANGLES * sizeof(triangle_t));
299 *triList = tList;
300 for (i = 0; i < triCount; i++)
301 {
302 TK_BeyondRequire(TK_LBRACKET, TK_INTNUMBER);
303 if (tk_IntNumber != i)
304 {
305 COM_Error("File '%s', line %d:\nTriangle index mismatch.\n",
306 tk_SourceName, tk_Line);
307 }
308 TK_BeyondRequire(TK_NODES, TK_INTNUMBER);
309 if (tk_IntNumber != 3)
310 {
311 COM_Error("File '%s', line %d:\nBad polygon vertex count: %d.",
312 tk_SourceName, tk_Line, tk_IntNumber);
313 }
314 for (j = 0; j < 3; j++)
315 {
316 TK_BeyondRequire(TK_LBRACKET, TK_INTNUMBER);
317 if (tk_IntNumber != j)
318 {
319 COM_Error("File '%s', line %d:\nTriangle vertex index"
320 " mismatch. %d should be %d\n", tk_SourceName, tk_Line,
321 tk_IntNumber, j);
322 }
323 TK_BeyondRequire(TK_VERTEX, TK_INTNUMBER);
324 tList[i].verts[2-j][0] = vList[tk_IntNumber].v[0];
325 tList[i].verts[2-j][1] = vList[tk_IntNumber].v[1];
326 tList[i].verts[2-j][2] = vList[tk_IntNumber].v[2];
327 }
328
329 /* printf("Face %i:\n v0: %f, %f, %f\n v1: %f, %f, %f\n"
330 " v2: %f, %f, %f\n", i,
331 tList[i].verts[0][0],
332 tList[i].verts[0][1],
333 tList[i].verts[0][2],
334 tList[i].verts[1][0],
335 tList[i].verts[1][1],
336 tList[i].verts[1][2],
337 tList[i].verts[2][0],
338 tList[i].verts[2][1],
339 tList[i].verts[2][2]);
340 */
341 }
342 }
343
344 //==========================================================================
345 //
346 // LoadASC
347 //
348 //==========================================================================
349
LoadASC(char * fileName,triangle_t ** triList,int * triangleCount)350 static void LoadASC(char *fileName, triangle_t **triList, int *triangleCount)
351 {
352 int i, j;
353 int vertexCount;
354 struct vList_s
355 {
356 float v[3];
357 } *vList;
358 int triCount;
359 triangle_t *tList;
360 float x, y, z;
361 // float x2, y2, z2;
362 // float rx, ry, rz;
363 qboolean goodObject;
364
365 TK_Init();
366 TK_OpenSource(fileName);
367
368 goodObject = false;
369 while (goodObject == false)
370 {
371 TK_Beyond(TK_C_NAMED);
372 TK_Beyond(TK_OBJECT);
373 TK_Beyond(TK_C_TRI);
374 TK_Beyond(TK_MESH);
375 TK_BeyondRequire(TK_C_VERTICES, TK_COLON);
376 TK_FetchRequire(TK_INTNUMBER);
377 vertexCount = tk_IntNumber;
378 if (vertexCount > 0)
379 {
380 goodObject = true;
381 }
382 }
383 TK_BeyondRequire(TK_C_FACES, TK_COLON);
384 TK_FetchRequire(TK_INTNUMBER);
385 triCount = tk_IntNumber;
386 if (triCount >= MAXTRIANGLES)
387 {
388 COM_Error("Too many triangles in file %s\n", InputFileName);
389 }
390 *triangleCount = triCount;
391 tList = (triangle_t *) SafeMalloc(MAXTRIANGLES * sizeof(triangle_t));
392 *triList = tList;
393 TK_BeyondRequire(TK_C_VERTEX, TK_LIST);
394
395 /* rx = ((rotation[0]+90.0)/360.0)*2.0*MY_PI;
396 //rx = (rotation[0]/360.0)*2.0*MY_PI;
397 ry = (rotation[1]/360.0)*2.0*MY_PI;
398 rz = (rotation[2]/360.0)*2.0*MY_PI;
399 */
400 vList = (struct vList_s *) SafeMalloc(vertexCount * sizeof(vList[0]));
401 for (i = 0; i < vertexCount; i++)
402 {
403 TK_BeyondRequire(TK_C_VERTEX, TK_INTNUMBER);
404 if (tk_IntNumber != i)
405 {
406 COM_Error("File '%s', line %d:\nVertex index mismatch.\n",
407 tk_SourceName, tk_Line);
408 }
409 TK_FetchRequireFetch(TK_COLON);
410
411 TK_BeyondRequire(TK_COLON, TK_FLOATNUMBER);
412 x = tk_FloatNumber;
413 TK_BeyondRequire(TK_COLON, TK_FLOATNUMBER);
414 y = tk_FloatNumber;
415 TK_BeyondRequire(TK_COLON, TK_FLOATNUMBER);
416 z = tk_FloatNumber;
417
418 /* x2 = x*cos(rz)+y*sin(rz);
419 y2 = -x*sin(rz)+y*cos(rz);
420 x = x2;
421 y = y2;
422 y2 = y*cos(rx)+z*sin(rx);
423 z2 = -y*sin(rx)+z*cos(rx);
424 y = y2;
425 z = z2;
426 x2 = x*cos(ry)-z*sin(ry);
427 z2 = x*sin(ry)+z*cos(ry);
428 x = x2;
429 z = z2;
430 */
431 vList[i].v[0] = x;
432 vList[i].v[1] = y;
433 vList[i].v[2] = z;
434 }
435 TK_BeyondRequire(TK_C_FACE, TK_LIST);
436 for (i = 0; i < triCount; i++)
437 {
438 TK_BeyondRequire(TK_C_FACE, TK_INTNUMBER);
439 if (tk_IntNumber != i)
440 {
441 COM_Error("File '%s', line %d:\nTriangle index mismatch.\n",
442 tk_SourceName, tk_Line);
443 }
444 for (j = 0; j < 3; j++)
445 {
446 TK_BeyondRequire(TK_IDENTIFIER, TK_COLON);
447 TK_FetchRequire(TK_INTNUMBER);
448 if (tk_IntNumber >= vertexCount)
449 {
450 COM_Error("File '%s', line %d:\nVertex number"
451 " > vertexCount: %d\n", tk_SourceName, tk_Line,
452 tk_IntNumber);
453 }
454 tList[i].verts[2-j][0] = vList[tk_IntNumber].v[0];
455 tList[i].verts[2-j][1] = vList[tk_IntNumber].v[1];
456 tList[i].verts[2-j][2] = vList[tk_IntNumber].v[2];
457 }
458
459 /* printf("Face %i:\n v0: %f, %f, %f\n v1: %f, %f, %f\n"
460 " v2: %f, %f, %f\n", i,
461 tList[i].verts[0][0],
462 tList[i].verts[0][1],
463 tList[i].verts[0][2],
464 tList[i].verts[1][0],
465 tList[i].verts[1][1],
466 tList[i].verts[1][2],
467 tList[i].verts[2][0],
468 tList[i].verts[2][1],
469 tList[i].verts[2][2]);
470 */
471 }
472 }
473
474 //==========================================================================
475 //
476 // LoadHTR
477 //
478 //==========================================================================
479
LoadHTR(char * fileName,triangle_t ** triList,int * triangleCount)480 static void LoadHTR(char *fileName, triangle_t **triList, int *triangleCount)
481 {
482 int i, j;
483 int vertexCount;
484 int vertexNum;
485 struct vList_s
486 {
487 float v[3];
488 } *vList;
489 int triCount;
490 float origin[3];
491 triangle_t *tList;
492 float x, y, z;
493 float x2, y2, z2;
494 float rx, ry, rz;
495
496 TK_Init();
497 TK_OpenSource(fileName);
498
499 TK_Beyond(TK_C_HEXEN);
500 TK_Beyond(TK_C_TRIANGLES);
501 TK_BeyondRequire(TK_C_VERSION, TK_INTNUMBER);
502 if (tk_IntNumber != 1)
503 {
504 COM_Error("Unsupported version (%d) in file %s\n", tk_IntNumber,
505 InputFileName);
506 }
507
508 // Get vertex count
509 TK_BeyondRequire(TK_VERTICES, TK_INTNUMBER);
510 vertexCount = tk_IntNumber;
511 vList = (struct vList_s *) SafeMalloc(vertexCount * sizeof(vList[0]));
512
513 // Get triangle count
514 TK_BeyondRequire(TK_FACES, TK_INTNUMBER);
515 triCount = tk_IntNumber;
516 if (triCount >= MAXTRIANGLES)
517 {
518 COM_Error("Too many triangles in file %s\n", InputFileName);
519 }
520 *triangleCount = triCount;
521 tList = (triangle_t *) SafeMalloc(MAXTRIANGLES * sizeof(triangle_t));
522 *triList = tList;
523
524 // Get origin
525 TK_Beyond(TK_ORIGIN);
526 TK_Require(TK_FLOATNUMBER);
527 origin[0] = tk_FloatNumber;
528 TK_FetchRequire(TK_FLOATNUMBER);
529 origin[1] = tk_FloatNumber;
530 TK_FetchRequire(TK_FLOATNUMBER);
531 origin[2] = tk_FloatNumber;
532
533 //rx = 90.0/360.0*2.0*MY_PI;
534 rx =(float)(FixHTRRotateX/360.0*2.0*MY_PI);
535 ry =(float)(FixHTRRotateY/360.0*2.0*MY_PI);
536 rz =(float)(FixHTRRotateZ/360.0*2.0*MY_PI);
537
538 // Get vertex list
539 for (i = 0; i < vertexCount; i++)
540 {
541 TK_FetchRequire(TK_VERTEX);
542 TK_FetchRequire(TK_FLOATNUMBER);
543 x = tk_FloatNumber-origin[0];
544 TK_FetchRequire(TK_FLOATNUMBER);
545 y = tk_FloatNumber-origin[1];
546 TK_FetchRequire(TK_FLOATNUMBER);
547 z = tk_FloatNumber-origin[2];
548
549 x += FixHTRTranslateX;
550 y += FixHTRTranslateY;
551 z += FixHTRTranslateZ;
552
553 y2 = (float)(y*cos(rx)-z*sin(rx));
554 z2 = (float)(y*sin(rx)+z*cos(rx));
555 y = y2;
556 z = z2;
557 x2 = (float)(x*cos(ry)+z*sin(ry));
558 z2 = (float)(-x*sin(ry)+z*cos(ry));
559 x = x2;
560 z = z2;
561 x2 = (float)(x*cos(rz)-y*sin(rz));
562 y2 = (float)(x*sin(rz)+y*cos(rz));
563 x = x2;
564 y = y2;
565
566 vList[i].v[0] = x;
567 vList[i].v[1] = y;
568 vList[i].v[2] = z;
569 }
570
571 // Get face list
572 for (i = 0; i < triCount; i++)
573 {
574 TK_FetchRequire(TK_FACE);
575 TK_FetchRequire(TK_LPAREN);
576 for (j = 0; j < 3; j++)
577 {
578 TK_FetchRequire(TK_INTNUMBER);
579 vertexNum = tk_IntNumber-1;
580 if (vertexNum >= vertexCount)
581 {
582 COM_Error("File '%s', line %d:\nVertex number"
583 " >= vertexCount: %d\n", tk_SourceName, tk_Line,
584 tk_IntNumber);
585 }
586 tList[i].verts[2-j][0] = vList[vertexNum].v[0];
587 tList[i].verts[2-j][1] = vList[vertexNum].v[1];
588 tList[i].verts[2-j][2] = vList[vertexNum].v[2];
589 }
590 TK_FetchRequire(TK_RPAREN);
591
592 /* printf("Face %i:\n v0: %f, %f, %f\n v1: %f, %f, %f\n"
593 " v2: %f, %f, %f\n", i,
594 tList[i].verts[0][0],
595 tList[i].verts[0][1],
596 tList[i].verts[0][2],
597 tList[i].verts[1][0],
598 tList[i].verts[1][1],
599 tList[i].verts[1][2],
600 tList[i].verts[2][0],
601 tList[i].verts[2][1],
602 tList[i].verts[2][2]);
603 */
604 }
605 }
606
607 //==========================================================================
608 //
609 // Load3DS
610 //
611 //==========================================================================
612 #if 0 /* 3DS stuff is unused. don't even know whether it's working */
613 static void Load3DS(FILE *input, triangle_t **triList, int *triangleCount)
614 {
615 unsigned int i, j;
616 qboolean stop;
617 qboolean foundVertexList;
618 unsigned int chunkType, chunkPos, chunkSize;
619 unsigned int editChunkSize, editChunkPos;
620 unsigned int objectChunkSize, objectChunkPos;
621 unsigned int meshChunkSize, meshChunkPos;
622 unsigned int vertex;
623 unsigned int vertexCount;
624 struct vList_s
625 {
626 float v[3];
627 } *vList;
628 unsigned int triCount;
629 triangle_t *tList;
630
631 InputFile = input;
632 if (ReadShort() != _3DS_MAIN3DS)
633 {
634 _3DSError("Missing 3DS main chunk header.\n");
635 }
636 SeekTo(16);
637 if (ReadShort() != _3DS_EDIT3DS)
638 {
639 _3DSError("Missing 3DS edit chunk header.\n");
640 }
641
642 editChunkSize = ReadLong();
643 editChunkPos = FilePosition()-6;
644 stop = false;
645 while (stop == false)
646 {
647 chunkPos = FilePosition();
648 chunkType = ReadShort();
649 switch (chunkType)
650 {
651 case _3DS_EDIT_UNKNW01:
652 case _3DS_EDIT_UNKNW02:
653 case _3DS_EDIT_UNKNW03:
654 case _3DS_EDIT_UNKNW04:
655 case _3DS_EDIT_UNKNW05:
656 case _3DS_EDIT_UNKNW06:
657 case _3DS_EDIT_UNKNW07:
658 case _3DS_EDIT_UNKNW08:
659 case _3DS_EDIT_UNKNW09:
660 case _3DS_EDIT_UNKNW10:
661 case _3DS_EDIT_UNKNW11:
662 case _3DS_EDIT_UNKNW12:
663 case _3DS_EDIT_UNKNW13:
664 case _3DS_EDIT_MATERIAL:
665 case _3DS_EDIT_VIEW1:
666 case _3DS_EDIT_BACKGR:
667 case _3DS_EDIT_AMBIENT:
668 SeekTo(chunkPos+ReadLong());
669 break;
670 case _3DS_EDIT_OBJECT:
671 stop = true;
672 default:
673 break;
674 }
675 if (FilePosition()-editChunkPos >= editChunkSize)
676 {
677 _3DSError("Couldn't find OBJECT chunk.\n");
678 }
679 }
680
681 objectChunkSize = ReadLong();
682 objectChunkPos = FilePosition()-6;
683 SkipName();
684 stop = false;
685 while (stop == false)
686 {
687 chunkPos = FilePosition();
688 chunkType = ReadShort();
689 switch (chunkType)
690 {
691 case _3DS_OBJ_UNKNWN01:
692 case _3DS_OBJ_UNKNWN02:
693 case _3DS_OBJ_LIGHT:
694 case _3DS_OBJ_CAMERA:
695 SeekTo(chunkPos+ReadLong());
696 break;
697 case _3DS_OBJ_TRIMESH:
698 stop = true;
699 default:
700 break;
701 }
702 if (FilePosition()-objectChunkPos >= objectChunkSize)
703 {
704 _3DSError("Couldn't find TRIMESH chunk.\n");
705 }
706 }
707
708 meshChunkSize = ReadLong();
709 meshChunkPos = FilePosition()-6;
710 stop = false;
711 foundVertexList = false;
712 while (stop == false)
713 {
714 chunkPos = FilePosition();
715 chunkType = ReadShort();
716 switch (chunkType)
717 {
718 case _3DS_TRI_FACEL2:
719 case _3DS_TRI_VISIBLE:
720 SeekTo(chunkPos+ReadLong());
721 break;
722 case _3DS_TRI_VERTEXL:
723 chunkSize = ReadLong();
724 vertexCount = ReadShort();
725 vList = (struct vList_s *) SafeMalloc(vertexCount * sizeof(vList[0]));
726 for (i = 0; i < vertexCount; i++)
727 {
728 vList[i].v[0] = ReadFloat();
729 vList[i].v[1] = -ReadFloat();
730 vList[i].v[2] = ReadFloat();
731 }
732 SeekTo(chunkPos+chunkSize);
733 foundVertexList = true;
734 break;
735 case _3DS_TRI_FACEL1:
736 chunkSize = ReadLong();
737 triCount = ReadShort();
738 if (triCount >= MAXTRIANGLES)
739 {
740 COM_Error("Too many triangles in file %s\n",
741 InputFileName);
742 }
743 *triangleCount = triCount;
744 tList = (triangle_t *) SafeMalloc(MAXTRIANGLES * sizeof(triangle_t));
745 *triList = tList;
746 for (i = 0; i < triCount; i++)
747 {
748 for (j = 0; j < 3; j++)
749 {
750 vertex = ReadShort();
751 tList[i].verts[j][0] = vList[vertex].v[0];
752 tList[i].verts[j][1] = vList[vertex].v[1];
753 tList[i].verts[j][2] = vList[vertex].v[2];
754 }
755 ReadShort(); // Skip face flags
756 }
757 stop = true;
758 break;
759 default:
760 break;
761 }
762 if (FilePosition()-meshChunkPos >= meshChunkSize)
763 {
764 if (foundVertexList == false)
765 {
766 _3DSError("Couldn't find TRI_VERTEXL chunk.\n");
767 }
768 else
769 {
770 _3DSError("Couldn't find TRI_FACEL1 chunk.\n");
771 }
772 }
773 }
774 }
775
776 static void _3DSError(char *message)
777 {
778 COM_Error(message);
779 }
780
781 static float ReadFloat(void)
782 {
783 float t;
784
785 fread(&t, sizeof(float), 1, InputFile);
786 return t;
787 }
788
789 static unsigned long ReadLong(void)
790 {
791 unsigned long t;
792
793 fread(&t, sizeof(unsigned long), 1, InputFile);
794 return t;
795 }
796
797 static unsigned short ReadShort(void)
798 {
799 unsigned short t;
800
801 fread(&t, sizeof(unsigned short), 1, InputFile);
802 return t;
803 }
804
805 static unsigned char ReadByte(void)
806 {
807 unsigned char t;
808
809 fread(&t, sizeof(unsigned char), 1, InputFile);
810 return t;
811 }
812
813 static void SkipName(void)
814 {
815 int i;
816 int c;
817
818 for (i = 0, c = 1; i < 12 && c != 0; i++)
819 {
820 c = ReadByte();
821 }
822 }
823
824 static void SeekTo(int position)
825 {
826 fseek(InputFile, position, SEEK_SET);
827 }
828
829 static unsigned long FilePosition(void)
830 {
831 return ftell(InputFile);
832 }
833 #endif // end of unused 3DS stuff
834
835 //==========================================================================
836 //
837 // LoadTRI
838 //
839 //==========================================================================
840
LoadTRI(FILE * input,triangle_t ** triList,int * triangleCount)841 static void LoadTRI(FILE *input, triangle_t **triList, int *triangleCount)
842 {
843 int i, j, k;
844 char text[256];
845 int count;
846 int magic;
847 tf_triangle tri;
848 triangle_t *ptri;
849 int exitpattern;
850 float t;
851 union {
852 float _f;
853 int _i;
854 } start;
855
856 t = -FLOAT_START;
857 *((unsigned char *)&exitpattern + 0) = *((unsigned char *)&t + 3);
858 *((unsigned char *)&exitpattern + 1) = *((unsigned char *)&t + 2);
859 *((unsigned char *)&exitpattern + 2) = *((unsigned char *)&t + 1);
860 *((unsigned char *)&exitpattern + 3) = *((unsigned char *)&t + 0);
861
862 fread(&magic, sizeof(int), 1, input);
863 if (BigLong(magic) != TRI_MAGIC)
864 {
865 COM_Error("Bad .TRI file: %s\n", InputFileName);
866 }
867
868 ptri = (triangle_t *) SafeMalloc(MAXTRIANGLES * sizeof(triangle_t));
869 *triList = ptri;
870
871 count = 0; // make static analyzers happy
872 while (feof(input) == 0)
873 {
874 fread(&start._f, sizeof(float), 1, input);
875 start._i = BigLong(start._i);
876
877 if (start._i != exitpattern)
878 {
879 if (start._f == FLOAT_START)
880 { // Start of an object or group of objects
881 i = -1;
882 do
883 {
884 ++i;
885 fread(&(text[i]), sizeof(char), 1, input);
886 } while (text[i] != '\0');
887 //fprintf(stdout,"OBJECT START: %s\n", text);
888
889 fread(&count, sizeof(int), 1, input);
890 count = BigLong(count);
891 if (count != 0)
892 {
893 //fprintf(stdout,"NUMBER OF TRIANGLES: %d\n", count);
894 i = -1;
895 do
896 {
897 ++i;
898 fread(&(text[i]), sizeof( char ), 1, input);
899 } while (text[i] != '\0');
900 //fprintf(stdout," Object texture name: '%s'\n", text);
901 }
902 }
903 else if (start._f == FLOAT_END)
904 {
905 i = -1;
906 do
907 {
908 ++i;
909 fread(&(text[i]), sizeof(char), 1, input);
910 } while (text[i] != '\0');
911 //fprintf(stdout,"OBJECT END: %s\n", text);
912 continue;
913 }
914 }
915
916 // Read the triangles
917 for (i = 0; i < count; ++i)
918 {
919 fread(&tri, sizeof(tf_triangle), 1, input);
920 ByteSwapTri(&tri);
921 for (j = 0; j < 3; j++)
922 {
923 for (k = 0; k < 3; k++)
924 {
925 ptri->verts[j][k] = tri.pt[j].p.v[k];
926 }
927 }
928
929 /* printf("Face %i:\n v0: %f, %f, %f\n v1: %f, %f, %f\n"
930 " v2: %f, %f, %f\n", i,
931 ptri->verts[0][0],
932 ptri->verts[0][1],
933 ptri->verts[0][2],
934 ptri->verts[1][0],
935 ptri->verts[1][1],
936 ptri->verts[1][2],
937 ptri->verts[2][0],
938 ptri->verts[2][1],
939 ptri->verts[2][2]);
940 */
941 ptri++;
942 if ((ptri - *triList) >= MAXTRIANGLES)
943 {
944 COM_Error("Error: too many triangles; increase MAXTRIANGLES\n");
945 }
946 }
947 }
948 *triangleCount = ptri - *triList;
949 }
950
951 //==========================================================================
952 //
953 // ByteSwapTri
954 //
955 //==========================================================================
956
ByteSwapTri(tf_triangle * tri)957 static void ByteSwapTri(tf_triangle *tri)
958 {
959 int i;
960
961 for (i = 0; i < (int) sizeof(tf_triangle)/4; i++)
962 {
963 ((int *)tri)[i] = BigLong(((int *)tri)[i]);
964 }
965 }
966
967