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 "iscriplib.h"
27 #include "archivelib.h"
32 #define MD5_RETURN_FALSE_IF_FAIL( expression ) if ( !( expression ) ) { globalErrorStream() << "md5 parse failed: " # expression "\n"; return false; } else
34 bool MD5_parseToken( Tokeniser& tokeniser, const char* string ){
35 const char* token = tokeniser.getToken();
36 MD5_RETURN_FALSE_IF_FAIL( token != 0 );
37 return string_equal( token, string );
40 bool MD5_parseFloat( Tokeniser& tokeniser, float& f ){
41 const char* token = tokeniser.getToken();
42 MD5_RETURN_FALSE_IF_FAIL( token != 0 );
43 return string_parse_float( token, f );
46 bool MD5_parseString( Tokeniser& tokeniser, const char*& s ){
47 const char* token = tokeniser.getToken();
48 MD5_RETURN_FALSE_IF_FAIL( token != 0 );
53 bool MD5_parseInteger( Tokeniser& tokeniser, int& i ){
54 const char* token = tokeniser.getToken();
55 MD5_RETURN_FALSE_IF_FAIL( token != 0 );
56 return string_parse_int( token, i );
59 bool MD5_parseSize( Tokeniser& tokeniser, std::size_t& i ){
60 const char* token = tokeniser.getToken();
61 MD5_RETURN_FALSE_IF_FAIL( token != 0 );
62 return string_parse_size( token, i );
65 bool MD5_parseVector3( Tokeniser& tokeniser, Vector3& v ){
66 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "(" ) );
67 MD5_RETURN_FALSE_IF_FAIL( MD5_parseFloat( tokeniser, v.x() ) );
68 MD5_RETURN_FALSE_IF_FAIL( MD5_parseFloat( tokeniser, v.y() ) );
69 MD5_RETURN_FALSE_IF_FAIL( MD5_parseFloat( tokeniser, v.z() ) );
70 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, ")" ) );
74 template<typename Element>
75 inline Element float_squared( const Element& f ){
87 typedef Array<MD5Joint> MD5Joints;
95 std::size_t weight_index;
96 std::size_t weight_count;
99 typedef Array<MD5Vert> MD5Verts;
110 typedef Array<MD5Tri> MD5Tris;
121 typedef Array<MD5Weight> MD5Weights;
123 typedef float MD5Component;
124 typedef Array<MD5Component> MD5Components;
129 MD5Components m_components;
132 typedef Array<MD5Weight> MD5Weights;
134 bool MD5_parseVersion( Tokeniser& tokeniser ){
136 const char* versionKey = tokeniser.getToken();
137 if ( versionKey == 0 || !string_equal( versionKey, "MD5Version" ) ) {
138 globalErrorStream() << "not a valid md5 file\n";
143 const char* versionValue = tokeniser.getToken();
144 if ( versionValue == 0 || !string_equal( versionValue, "10" ) ) {
145 globalErrorStream() << "only md5 version 10 supported\n";
153 bool MD5Anim_parse( Tokeniser& tokeniser ){
154 MD5_RETURN_FALSE_IF_FAIL( MD5_parseVersion( tokeniser ) );
155 tokeniser.nextLine();
157 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "commandline" ) );
158 const char* commandline;
159 MD5_RETURN_FALSE_IF_FAIL( MD5_parseString( tokeniser, commandline ) );
160 tokeniser.nextLine();
162 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "numFrames" ) );
163 std::size_t numFrames;
164 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, numFrames ) );
165 tokeniser.nextLine();
167 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "numJoints" ) );
168 std::size_t numJoints;
169 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, numJoints ) );
170 tokeniser.nextLine();
172 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "frameRate" ) );
173 std::size_t frameRate;
174 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, frameRate ) );
175 tokeniser.nextLine();
177 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "numAnimatedComponents" ) );
178 std::size_t numAnimatedComponents;
179 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, numAnimatedComponents ) );
180 tokeniser.nextLine();
183 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "hierarchy" ) );
184 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "{" ) );
185 tokeniser.nextLine();
187 for ( std::size_t i = 0; i < numJoints; ++i )
190 MD5_RETURN_FALSE_IF_FAIL( MD5_parseString( tokeniser, name ) );
192 MD5_RETURN_FALSE_IF_FAIL( MD5_parseInteger( tokeniser, parent ) );
194 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, flags ) );
196 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, index ) );
197 tokeniser.nextLine();
200 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "}" ) );
201 tokeniser.nextLine();
204 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "bounds" ) );
205 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "{" ) );
206 tokeniser.nextLine();
208 for ( std::size_t i = 0; i < numFrames; ++i )
211 MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, mins ) );
213 MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, maxs ) );
214 tokeniser.nextLine();
217 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "}" ) );
218 tokeniser.nextLine();
221 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "baseframe" ) );
222 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "{" ) );
223 tokeniser.nextLine();
225 for ( std::size_t i = 0; i < numJoints; ++i )
228 MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, position ) );
230 MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, rotation ) );
231 tokeniser.nextLine();
234 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "}" ) );
235 tokeniser.nextLine();
238 for ( std::size_t i = 0; i < numFrames; ++i )
240 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "frame" ) );
241 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "{" ) );
242 tokeniser.nextLine();
244 for ( std::size_t i = 0; i < numAnimatedComponents; ++i )
247 MD5_RETURN_FALSE_IF_FAIL( MD5_parseFloat( tokeniser, component ) );
248 tokeniser.nextLine();
251 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "}" ) );
252 tokeniser.nextLine();
258 bool MD5Model_parse( Model& model, Tokeniser& tokeniser ){
259 MD5_RETURN_FALSE_IF_FAIL( MD5_parseVersion( tokeniser ) );
260 tokeniser.nextLine();
262 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "commandline" ) );
263 const char* commandline;
264 MD5_RETURN_FALSE_IF_FAIL( MD5_parseString( tokeniser, commandline ) );
265 tokeniser.nextLine();
267 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "numJoints" ) );
268 std::size_t numJoints;
269 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, numJoints ) );
270 tokeniser.nextLine();
272 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "numMeshes" ) );
273 std::size_t numMeshes;
274 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, numMeshes ) );
275 tokeniser.nextLine();
277 MD5Joints joints( numJoints );
279 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "joints" ) );
280 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "{" ) );
281 tokeniser.nextLine();
283 for ( MD5Joints::iterator i = joints.begin(); i != joints.end(); ++i )
285 const char* jointName;
286 MD5_RETURN_FALSE_IF_FAIL( MD5_parseString( tokeniser, jointName ) );
287 MD5_RETURN_FALSE_IF_FAIL( MD5_parseInteger( tokeniser, ( *i ).parent ) );
288 MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, ( *i ).position ) );
289 MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, vector4_to_vector3( ( *i ).rotation ) ) );
290 ( *i ).rotation.w() = -static_cast<float>( sqrt( 1.0f - ( float_squared( ( *i ).rotation.x() ) + float_squared( ( *i ).rotation.y() ) + float_squared( ( *i ).rotation.z() ) ) ) );
291 tokeniser.nextLine();
294 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "}" ) );
295 tokeniser.nextLine();
297 for ( std::size_t i = 0; i < numMeshes; ++i )
299 Surface& surface = model.newSurface();
301 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "mesh" ) );
302 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "{" ) );
303 tokeniser.nextLine();
305 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "shader" ) );
307 MD5_RETURN_FALSE_IF_FAIL( MD5_parseString( tokeniser, shader ) );
308 surface.setShader( shader );
309 tokeniser.nextLine();
311 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "numverts" ) );
312 std::size_t numVerts;
313 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, numVerts ) );
314 tokeniser.nextLine();
316 MD5Verts verts( numVerts );
318 for ( MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j )
320 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "vert" ) );
321 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, ( *j ).index ) );
322 MD5_RETURN_FALSE_IF_FAIL( ( *j ).index == std::size_t( j - verts.begin() ) );
323 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "(" ) );
324 MD5_RETURN_FALSE_IF_FAIL( MD5_parseFloat( tokeniser, ( *j ).u ) );
325 MD5_RETURN_FALSE_IF_FAIL( MD5_parseFloat( tokeniser, ( *j ).v ) );
326 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, ")" ) );
327 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, ( *j ).weight_index ) );
328 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, ( *j ).weight_count ) );
329 tokeniser.nextLine();
332 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "numtris" ) );
334 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, numTris ) );
335 tokeniser.nextLine();
337 MD5Tris tris( numTris );
339 for ( MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j )
341 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "tri" ) );
342 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, ( *j ).index ) );
343 MD5_RETURN_FALSE_IF_FAIL( ( *j ).index == std::size_t( j - tris.begin() ) );
344 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, ( *j ).a ) );
345 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, ( *j ).b ) );
346 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, ( *j ).c ) );
347 tokeniser.nextLine();
350 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "numweights" ) );
351 std::size_t numWeights;
352 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, numWeights ) );
353 tokeniser.nextLine();
355 MD5Weights weights( numWeights );
357 for ( MD5Weights::iterator j = weights.begin(); j != weights.end(); ++j )
359 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "weight" ) );
360 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, ( *j ).index ) );
361 MD5_RETURN_FALSE_IF_FAIL( ( *j ).index == std::size_t( j - weights.begin() ) );
362 MD5_RETURN_FALSE_IF_FAIL( MD5_parseSize( tokeniser, ( *j ).joint ) );
363 MD5_RETURN_FALSE_IF_FAIL( MD5_parseFloat( tokeniser, ( *j ).t ) );
364 MD5_RETURN_FALSE_IF_FAIL( MD5_parseVector3( tokeniser, ( *j ).v ) );
365 tokeniser.nextLine();
368 MD5_RETURN_FALSE_IF_FAIL( MD5_parseToken( tokeniser, "}" ) );
369 tokeniser.nextLine();
371 for ( MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j )
373 MD5Vert& vert = ( *j );
375 Vector3 skinned( 0, 0, 0 );
376 for ( std::size_t k = 0; k != vert.weight_count; ++k )
378 MD5Weight& weight = weights[vert.weight_index + k];
379 MD5Joint& joint = joints[weight.joint];
381 skinned += ( quaternion_transformed_point( joint.rotation, weight.v ) + joint.position ) * weight.t;
384 surface.vertices().push_back( ArbitraryMeshVertex( vertex3f_for_vector3( skinned ), Normal3f( 0, 0, 0 ), TexCoord2f( vert.u, vert.v ) ) );
387 for ( MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j )
389 MD5Tri& tri = ( *j );
390 surface.indices().insert( RenderIndex( tri.a ) );
391 surface.indices().insert( RenderIndex( tri.b ) );
392 surface.indices().insert( RenderIndex( tri.c ) );
395 for ( Surface::indices_t::iterator j = surface.indices().begin(); j != surface.indices().end(); j += 3 )
397 ArbitraryMeshVertex& a = surface.vertices()[*( j + 0 )];
398 ArbitraryMeshVertex& b = surface.vertices()[*( j + 1 )];
399 ArbitraryMeshVertex& c = surface.vertices()[*( j + 2 )];
400 Vector3 weightedNormal(
402 reinterpret_cast<const Vector3&>( c.vertex ) - reinterpret_cast<const Vector3&>( a.vertex ),
403 reinterpret_cast<const Vector3&>( b.vertex ) - reinterpret_cast<const Vector3&>( a.vertex )
406 reinterpret_cast<Vector3&>( a.normal ) += weightedNormal;
407 reinterpret_cast<Vector3&>( b.normal ) += weightedNormal;
408 reinterpret_cast<Vector3&>( c.normal ) += weightedNormal;
411 for ( Surface::vertices_t::iterator j = surface.vertices().begin(); j != surface.vertices().end(); ++j )
413 vector3_normalise( reinterpret_cast<Vector3&>( ( *j ).normal ) );
416 surface.updateAABB();
424 void MD5Model_construct( Model& model, TextInputStream& inputStream ){
425 Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser( inputStream );
426 MD5Model_parse( model, tokeniser );
430 scene::Node& MD5Model_new( TextInputStream& inputStream ){
431 ModelNode* modelNode = new ModelNode();
432 MD5Model_construct( modelNode->model(), inputStream );
433 return modelNode->node();
436 scene::Node& loadMD5Model( ArchiveFile& file ){
437 BinaryToTextInputStream<InputStream> inputStream( file.getInputStream() );
438 return MD5Model_new( inputStream );