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__) || defined (__FreeBSD__)
29 #define filelength Q_filelength
30 #endif
31 
32 /*
33 ** MD3_ComputeTagFromTri
34 */
MD3_ComputeTagFromTri(md3Tag_t * pTag,const float pTri[3][3])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 */
MD3_Dump(const char * filename)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 
215