2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
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.
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.
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
24 #include "ifilesystem.h"
28 #include "bytestreamutils.h"
32 #include "md3normals.h"
34 // the maximum size of game reletive pathnames
35 const int MAX_QPATH = 64;
38 ========================================================================
40 .MD3 triangle model file format
42 ========================================================================
45 const unsigned char MD3_IDENT[4] = { 'I', 'D', 'P', '3', };
46 const int MD3_VERSION = 15;
49 const int MD3_MAX_LODS = 4;
50 const int MD3_MAX_TRIANGLES = 8192; // per surface
51 const int MD3_MAX_VERTS = 4096; // per surface
52 const int MD3_MAX_SHADERS = 256; // per surface
53 const int MD3_MAX_FRAMES = 1024; // per model
54 const int MD3_MAX_SURFACES = 32; // per model
55 const int MD3_MAX_TAGS = 16; // per frame
58 const float MD3_XYZ_SCALE = ( 1.f / 64 );
60 typedef float float3[3];
62 void istream_read_float3( PointerInputStream& inputStream, float3 f ){
63 f[0] = istream_read_float32_le( inputStream );
64 f[1] = istream_read_float32_le( inputStream );
65 f[2] = istream_read_float32_le( inputStream );
68 typedef struct md3Frame_s {
75 void istream_read_md3Frame( PointerInputStream& inputStream, md3Frame_t& frame ){
76 istream_read_float3( inputStream, frame.bounds[0] );
77 istream_read_float3( inputStream, frame.bounds[1] );
78 istream_read_float3( inputStream, frame.localOrigin );
79 frame.radius = istream_read_float32_le( inputStream );
80 inputStream.read( reinterpret_cast<unsigned char*>( frame.name ), 16 );
83 typedef struct md3Tag_s {
84 char name[MAX_QPATH]; // tag name
89 void istream_read_md3Shader( PointerInputStream& inputStream, md3Tag_t& tag ){
90 inputStream.read( reinterpret_cast<unsigned char*>( tag.name ), MAX_QPATH );
91 istream_read_float3( inputStream, tag.origin );
92 istream_read_float3( inputStream, tag.axis[0] );
93 istream_read_float3( inputStream, tag.axis[1] );
94 istream_read_float3( inputStream, tag.axis[2] );
101 ** header sizeof( md3Surface_t )
102 ** shaders sizeof( md3Shader_t ) * numShaders
103 ** triangles[0] sizeof( md3Triangle_t ) * numTriangles
104 ** st sizeof( md3St_t ) * numVerts
105 ** XyzNormals sizeof( md3XyzNormal_t ) * numVerts * numFrames
110 char name[MAX_QPATH]; // polyset name
113 int numFrames; // all surfaces in a model should have the same
115 int numShaders; // all surfaces in a model should have the same
121 int ofsShaders; // offset from start of md3Surface_t
122 int ofsSt; // texture coords are common for all frames
123 int ofsXyzNormals; // numVerts * numFrames
125 int ofsEnd; // next surface follows
128 void istream_read_md3Surface( PointerInputStream& inputStream, md3Surface_t& surface ){
129 inputStream.read( reinterpret_cast<unsigned char*>( surface.ident ), 4 );
130 inputStream.read( reinterpret_cast<unsigned char*>( surface.name ), MAX_QPATH );
131 surface.flags = istream_read_int32_le( inputStream );
132 surface.numFrames = istream_read_int32_le( inputStream );
133 surface.numShaders = istream_read_int32_le( inputStream );
134 surface.numVerts = istream_read_int32_le( inputStream );
135 surface.numTriangles = istream_read_int32_le( inputStream );
136 surface.ofsTriangles = istream_read_int32_le( inputStream );
137 surface.ofsShaders = istream_read_int32_le( inputStream );
138 surface.ofsSt = istream_read_int32_le( inputStream );
139 surface.ofsXyzNormals = istream_read_int32_le( inputStream );
140 surface.ofsEnd = istream_read_int32_le( inputStream );
144 char name[MAX_QPATH];
145 int shaderIndex; // for in-game use
148 void istream_read_md3Shader( PointerInputStream& inputStream, md3Shader_t& shader ){
149 inputStream.read( reinterpret_cast<unsigned char*>( shader.name ), MAX_QPATH );
150 shader.shaderIndex = istream_read_int32_le( inputStream );
157 void istream_read_md3Triangle( PointerInputStream& inputStream, md3Triangle_t& triangle ){
158 triangle.indexes[0] = istream_read_int32_le( inputStream );
159 triangle.indexes[1] = istream_read_int32_le( inputStream );
160 triangle.indexes[2] = istream_read_int32_le( inputStream );
167 void istream_read_md3St( PointerInputStream& inputStream, md3St_t& st ){
168 st.st[0] = istream_read_float32_le( inputStream );
169 st.st[1] = istream_read_float32_le( inputStream );
177 void istream_read_md3XyzNormal( PointerInputStream& inputStream, md3XyzNormal_t& xyz ){
178 xyz.xyz[0] = istream_read_int16_le( inputStream );
179 xyz.xyz[1] = istream_read_int16_le( inputStream );
180 xyz.xyz[2] = istream_read_int16_le( inputStream );
181 xyz.normal = istream_read_int16_le( inputStream );
188 char name[MAX_QPATH]; // model name
198 int ofsFrames; // offset for first frame
199 int ofsTags; // numFrames * numTags
200 int ofsSurfaces; // first surface, others follow
202 int ofsEnd; // end of file
205 void istream_read_md3Header( PointerInputStream& inputStream, md3Header_t& header ){
206 inputStream.read( reinterpret_cast<unsigned char*>( header.ident ), 4 );
207 header.version = istream_read_int32_le( inputStream );
208 inputStream.read( reinterpret_cast<unsigned char*>( header.name ), MAX_QPATH );
209 header.flags = istream_read_int32_le( inputStream );
210 header.numFrames = istream_read_int32_le( inputStream );
211 header.numTags = istream_read_int32_le( inputStream );
212 header.numSurfaces = istream_read_int32_le( inputStream );
213 header.numSkins = istream_read_int32_le( inputStream );
214 header.ofsFrames = istream_read_int32_le( inputStream );
215 header.ofsTags = istream_read_int32_le( inputStream );
216 header.ofsSurfaces = istream_read_int32_le( inputStream );
217 header.ofsEnd = istream_read_int32_le( inputStream );
220 int MD3Surface_read( Surface& surface, unsigned char* buffer ){
221 md3Surface_t md3Surface;
223 PointerInputStream inputStream( buffer );
224 istream_read_md3Surface( inputStream, md3Surface );
228 surface.vertices().reserve( md3Surface.numVerts );
230 PointerInputStream xyzNormalStream( buffer + md3Surface.ofsXyzNormals );
231 PointerInputStream stStream( buffer + md3Surface.ofsSt );
233 // read verts into vertex array - xyz, st, normal
234 for ( int i = 0; i < md3Surface.numVerts; i++ )
236 md3XyzNormal_t md3Xyz;
237 istream_read_md3XyzNormal( xyzNormalStream, md3Xyz );
240 istream_read_md3St( stStream, md3St );
242 surface.vertices().push_back(
244 Vertex3f( md3Xyz.xyz[0] * MD3_XYZ_SCALE, md3Xyz.xyz[1] * MD3_XYZ_SCALE, md3Xyz.xyz[2] * MD3_XYZ_SCALE ),
245 DecodeNormal( reinterpret_cast<byte*>( &md3Xyz.normal ) ),
246 TexCoord2f( md3St.st[0], md3St.st[1] )
253 surface.indices().reserve( md3Surface.numTriangles * 3 );
255 PointerInputStream inputStream( buffer + md3Surface.ofsTriangles );
256 for ( int i = 0; i < md3Surface.numTriangles; i++ )
258 md3Triangle_t md3Triangle;
259 istream_read_md3Triangle( inputStream, md3Triangle );
260 surface.indices().insert( md3Triangle.indexes[0] );
261 surface.indices().insert( md3Triangle.indexes[1] );
262 surface.indices().insert( md3Triangle.indexes[2] );
267 md3Shader_t md3Shader;
269 PointerInputStream inputStream( buffer + md3Surface.ofsShaders );
270 istream_read_md3Shader( inputStream, md3Shader );
272 surface.setShader( md3Shader.name );
275 surface.updateAABB();
277 return md3Surface.ofsEnd;
280 void MD3Model_read( Model& model, unsigned char* buffer ){
281 md3Header_t md3Header;
283 PointerInputStream inputStream( buffer );
284 istream_read_md3Header( inputStream, md3Header );
287 unsigned char* surfacePosition = buffer + md3Header.ofsSurfaces;
289 for ( int i = 0; i != md3Header.numSurfaces; ++i )
291 surfacePosition += MD3Surface_read( model.newSurface(), surfacePosition );
297 scene::Node& MD3Model_new( unsigned char* buffer ){
298 ModelNode* modelNode = new ModelNode();
299 MD3Model_read( modelNode->model(), buffer );
300 return modelNode->node();
303 scene::Node& MD3Model_default(){
304 ModelNode* modelNode = new ModelNode();
305 Model_constructNull( modelNode->model() );
306 return modelNode->node();
309 scene::Node& MD3Model_fromBuffer( unsigned char* buffer ){
310 if ( !ident_equal( buffer, MD3_IDENT ) ) {
311 globalErrorStream() << "MD3 read error: incorrect ident\n";
312 return MD3Model_default();
316 return MD3Model_new( buffer );
320 scene::Node& loadMD3Model( ArchiveFile& file ){
321 ScopedArchiveBuffer buffer( file );
322 return MD3Model_fromBuffer( buffer.buffer );