]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake3/q3data/md3lib.c
5bc90b108024a98dae417d89ef7a45c0bc654cdc
[xonotic/netradiant.git] / tools / quake3 / q3data / md3lib.c
1 #include <assert.h>\r
2 #ifdef _WIN32\r
3 #include <io.h>\r
4 #endif\r
5 #include "md3lib.h"\r
6 \r
7 #if defined (__linux__) || defined (__APPLE__)\r
8 #define filelength Q_filelength\r
9 #endif\r
10 \r
11 /*\r
12 ** MD3_ComputeTagFromTri\r
13 */\r
14 void MD3_ComputeTagFromTri( md3Tag_t *pTag, const float pTri[3][3] )\r
15 {\r
16         float   len[3];\r
17         vec3_t  axes[3], sides[3];\r
18         int             longestSide, shortestSide, hypotSide;\r
19         int             origin;\r
20         int             j;\r
21         float   d;\r
22 \r
23         memset( axes, 0, sizeof( axes ) );\r
24         memset( sides, 0, sizeof( sides ) );\r
25 \r
26         //\r
27         // compute sides\r
28         //\r
29         for ( j = 0; j < 3; j++ )\r
30         {\r
31                 sides[j][0] = pTri[(j+1)%3][0] - pTri[j][0];\r
32                 sides[j][1] = pTri[(j+1)%3][1] - pTri[j][1];\r
33                 sides[j][2] = pTri[(j+1)%3][2] - pTri[j][2];\r
34 \r
35                 len[j] = ( float ) sqrt( DotProduct( sides[j], sides[j] ) );\r
36         }\r
37 \r
38 #if 0\r
39         if ( len[0] > len[1] && len[0] > len[2] )\r
40         {\r
41                 longestSide = 0; shortestSide = 1; origin = 2;\r
42         }\r
43         else if ( len[1] > len[0] && len[1] > len[2] )\r
44         {\r
45                 longestSide = 1; shortestSide = 2; origin = 0;\r
46         }\r
47         else if ( len[2] > len[0] && len[2] > len[1] )\r
48         {\r
49                 longestSide = 2; shortestSide = 0; origin = 1;\r
50         }\r
51         else\r
52         {\r
53                 Error( "invalid tag triangle, must be a right triangle with unequal length sides" );\r
54         }\r
55 #endif\r
56         if ( len[0] > len[1] && len[0] > len[2] ) {\r
57                 hypotSide = 0;\r
58                 origin = 2;\r
59         } else if ( len[1] > len[0] && len[1] > len[2] ) {\r
60                 hypotSide = 1;\r
61                 origin = 0;\r
62         } else if ( len[2] > len[0] && len[2] > len[1] ) {\r
63                 hypotSide = 2;\r
64                 origin = 1;\r
65         }\r
66         len[hypotSide] = -1;\r
67 \r
68         if ( len[0] > len[1] && len[0] > len[2] ) {\r
69                 longestSide = 0;\r
70         } else if ( len[1] > len[0] && len[1] > len[2] ) {\r
71                 longestSide = 1;\r
72         } else if ( len[2] > len[0] && len[2] > len[1] ) {\r
73                 longestSide = 2;\r
74         }\r
75         len[longestSide] = -1;\r
76 \r
77         if ( len[0] > len[1] && len[0] > len[2] ) {\r
78                 shortestSide = 0;\r
79         } else if ( len[1] > len[0] && len[1] > len[2] ) {\r
80                 shortestSide = 1;\r
81         } else if ( len[2] > len[0] && len[2] > len[1] ) {\r
82                 shortestSide = 2;\r
83         }\r
84         len[shortestSide] = -1;\r
85 \r
86 \r
87 \r
88 //      VectorNormalize( sides[shortestSide], axes[0] );\r
89 //      VectorNormalize( sides[longestSide], axes[1] );\r
90         VectorNormalize( sides[longestSide], axes[0] );\r
91         VectorNormalize( sides[shortestSide], axes[1] );\r
92 \r
93         // project shortest side so that it is exactly 90 degrees to the longer side\r
94         d = DotProduct( axes[0], axes[1] );\r
95         VectorMA( axes[0], -d, axes[1], axes[0] );\r
96         VectorNormalize( axes[0], axes[0] );\r
97 \r
98         CrossProduct( sides[longestSide], sides[shortestSide], axes[2] );\r
99         VectorNormalize( axes[2], axes[2] );\r
100 \r
101         pTag->origin[0] = pTri[origin][0];\r
102         pTag->origin[1] = pTri[origin][1];\r
103         pTag->origin[2] = pTri[origin][2];\r
104 \r
105         VectorCopy( axes[0], pTag->axis[0] );\r
106         VectorCopy( axes[1], pTag->axis[1] );\r
107         VectorCopy( axes[2], pTag->axis[2] );\r
108 }\r
109 \r
110 /*\r
111 ==============\r
112 MD3_Dump\r
113 ==============\r
114 */\r
115 void MD3_Dump( const char *filename )\r
116 {\r
117         md3Header_t header;\r
118         md3Tag_t *pTag;\r
119         md3Surface_t *pSurface;\r
120         FILE *fp;\r
121         void *_buffer;\r
122         void *buffer;\r
123         long fileSize;\r
124         int i;\r
125 \r
126         if ( ( fp = fopen( filename, "rb" ) ) == 0 )\r
127         {\r
128                 Error( "Unable to open '%s'\n", filename );\r
129         }\r
130 \r
131         fileSize = filelength( fileno( fp ) );\r
132         _buffer = malloc( filelength( fileno( fp ) ) );\r
133         fread( _buffer, fileSize, 1, fp );\r
134         fclose( fp );\r
135 \r
136         buffer = ( char * ) _buffer;\r
137         header = *( md3Header_t * ) _buffer;\r
138 \r
139         if ( header.ident != MD3_IDENT )\r
140         {\r
141                 Error( "Incorrect ident for '%s'\n", filename );\r
142         }\r
143 \r
144         printf( "Contents of '%s'\n", filename );\r
145         printf( "  version:        %d\n", header.version );\r
146         printf( "  name:           %s\n", header.name );\r
147         printf( "  num frames:     %d\n", header.numFrames );\r
148         printf( "  num tags:       %d\n", header.numTags );\r
149         printf( "  num surfaces:   %d\n", header.numSurfaces );\r
150         printf( "  num skins:      %d\n", header.numSkins );\r
151         printf( "  file size:      %d\n", fileSize );\r
152 \r
153         printf( "--- TAGS ---\n" );\r
154         pTag = ( md3Tag_t * ) ( ( ( char * ) buffer ) + header.ofsTags );\r
155         for ( i = 0; i < header.numTags; i++, pTag++ )\r
156         {\r
157                 printf( "  tag %d ('%s')\n", i, pTag->name );\r
158                 printf( "    origin: %f,%f,%f\n", pTag->origin[0], pTag->origin[1], pTag->origin[2] );\r
159                 printf( "        vf: %f,%f,%f\n", pTag->axis[0][0], pTag->axis[0][1], pTag->axis[0][2] );\r
160                 printf( "        vr: %f,%f,%f\n", pTag->axis[1][0], pTag->axis[1][1], pTag->axis[1][2] );\r
161                 printf( "        vu: %f,%f,%f\n", pTag->axis[2][0], pTag->axis[2][1], pTag->axis[2][2] );\r
162         }\r
163 \r
164         printf( "--- SURFACES ---\n" );\r
165         pSurface = ( md3Surface_t * ) ( ( ( char * ) buffer ) + header.ofsSurfaces );\r
166 \r
167         for ( i = 0; i < header.numSurfaces; i++ )\r
168         {\r
169                 int j;\r
170 \r
171                 md3Shader_t *pShader = ( md3Shader_t * ) ( ( ( char * ) pSurface ) + pSurface->ofsShaders );\r
172 \r
173                 printf( "\n  surface %d ('%s')\n", i, pSurface->name );\r
174                 printf( "    num frames: %d\n", pSurface->numFrames );\r
175                 printf( "    num shaders: %d\n", pSurface->numShaders );\r
176                 printf( "    num tris: %d\n", pSurface->numTriangles );\r
177                 printf( "    num verts: %d\n", pSurface->numVerts );\r
178 \r
179                 if ( pSurface->numShaders > 0 )\r
180                 {\r
181                         printf( "    --- SHADERS ---\n" );\r
182 \r
183                         for ( j = 0; j < pSurface->numShaders; j++, pShader++ )\r
184                         {\r
185                                 printf( "    shader %d ('%s')\n", j, pShader->name );\r
186                         }\r
187                 }\r
188                 pSurface = ( md3Surface_t * ) ( ( ( char * ) pSurface ) + pSurface->ofsEnd );\r
189         }\r
190 \r
191         free( _buffer );\r
192 }\r
193 \r