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