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