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)
36 const char* token = tokeniser.getToken();
37 MD5_RETURN_FALSE_IF_FAIL(token != 0);
38 return string_equal(token, string);
41 bool MD5_parseFloat(Tokeniser& tokeniser, float& f)
43 const char* token = tokeniser.getToken();
44 MD5_RETURN_FALSE_IF_FAIL(token != 0);
45 return string_parse_float(token, f);
48 bool MD5_parseString(Tokeniser& tokeniser, const char*& s)
50 const char* token = tokeniser.getToken();
51 MD5_RETURN_FALSE_IF_FAIL(token != 0);
56 bool MD5_parseInteger(Tokeniser& tokeniser, int& i)
58 const char* token = tokeniser.getToken();
59 MD5_RETURN_FALSE_IF_FAIL(token != 0);
60 return string_parse_int(token, i);
63 bool MD5_parseSize(Tokeniser& tokeniser, std::size_t& i)
65 const char* token = tokeniser.getToken();
66 MD5_RETURN_FALSE_IF_FAIL(token != 0);
67 return string_parse_size(token, i);
70 bool MD5_parseVector3(Tokeniser& tokeniser, Vector3& v)
72 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "("));
73 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.x()));
74 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.y()));
75 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.z()));
76 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, ")"));
80 template<typename Element>
81 inline Element float_squared(const Element& f)
94 typedef Array<MD5Joint> MD5Joints;
102 std::size_t weight_index;
103 std::size_t weight_count;
106 typedef Array<MD5Vert> MD5Verts;
117 typedef Array<MD5Tri> MD5Tris;
128 typedef Array<MD5Weight> MD5Weights;
130 typedef float MD5Component;
131 typedef Array<MD5Component> MD5Components;
136 MD5Components m_components;
139 typedef Array<MD5Weight> MD5Weights;
141 bool MD5_parseVersion(Tokeniser& tokeniser)
144 const char* versionKey = tokeniser.getToken();
145 if(versionKey == 0 || !string_equal(versionKey, "MD5Version"))
147 globalErrorStream() << "not a valid md5 file\n";
152 const char* versionValue = tokeniser.getToken();
153 if(versionValue == 0 || !string_equal(versionValue, "10"))
155 globalErrorStream() << "only md5 version 10 supported\n";
163 bool MD5Anim_parse(Tokeniser& tokeniser)
165 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVersion(tokeniser));
166 tokeniser.nextLine();
168 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "commandline"));
169 const char* commandline;
170 MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, commandline));
171 tokeniser.nextLine();
173 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numFrames"));
174 std::size_t numFrames;
175 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numFrames));
176 tokeniser.nextLine();
178 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numJoints"));
179 std::size_t numJoints;
180 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numJoints));
181 tokeniser.nextLine();
183 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "frameRate"));
184 std::size_t frameRate;
185 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, frameRate));
186 tokeniser.nextLine();
188 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numAnimatedComponents"));
189 std::size_t numAnimatedComponents;
190 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numAnimatedComponents));
191 tokeniser.nextLine();
194 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "hierarchy"));
195 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
196 tokeniser.nextLine();
198 for(std::size_t i = 0; i < numJoints; ++i)
201 MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, name));
203 MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, parent));
205 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, flags));
207 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, index));
208 tokeniser.nextLine();
211 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
212 tokeniser.nextLine();
215 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "bounds"));
216 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
217 tokeniser.nextLine();
219 for(std::size_t i = 0; i < numFrames; ++i)
222 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, mins));
224 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, maxs));
225 tokeniser.nextLine();
228 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
229 tokeniser.nextLine();
232 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "baseframe"));
233 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
234 tokeniser.nextLine();
236 for(std::size_t i = 0; i < numJoints; ++i)
239 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, position));
241 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, rotation));
242 tokeniser.nextLine();
245 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
246 tokeniser.nextLine();
249 for(std::size_t i = 0; i < numFrames; ++i)
251 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "frame"));
252 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
253 tokeniser.nextLine();
255 for(std::size_t i = 0; i < numAnimatedComponents; ++i)
258 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, component));
259 tokeniser.nextLine();
262 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
263 tokeniser.nextLine();
269 bool MD5Model_parse(Model& model, Tokeniser& tokeniser)
271 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVersion(tokeniser));
272 tokeniser.nextLine();
274 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "commandline"));
275 const char* commandline;
276 MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, commandline));
277 tokeniser.nextLine();
279 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numJoints"));
280 std::size_t numJoints;
281 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numJoints));
282 tokeniser.nextLine();
284 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numMeshes"));
285 std::size_t numMeshes;
286 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numMeshes));
287 tokeniser.nextLine();
289 MD5Joints joints(numJoints);
291 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "joints"));
292 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
293 tokeniser.nextLine();
295 for(MD5Joints::iterator i = joints.begin(); i != joints.end(); ++i)
297 const char* jointName;
298 MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, jointName));
299 MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, (*i).parent));
300 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*i).position));
301 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, vector4_to_vector3((*i).rotation)));
302 (*i).rotation.w() = -static_cast<float>(sqrt(1.0f - (float_squared((*i).rotation.x()) + float_squared((*i).rotation.y()) + float_squared((*i).rotation.z()))));
303 tokeniser.nextLine();
306 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
307 tokeniser.nextLine();
309 for(std::size_t i = 0; i < numMeshes; ++i)
311 Surface& surface = model.newSurface();
313 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "mesh"));
314 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
315 tokeniser.nextLine();
317 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "shader"));
319 MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, shader));
320 surface.setShader(shader);
321 tokeniser.nextLine();
323 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numverts"));
324 std::size_t numVerts;
325 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numVerts));
326 tokeniser.nextLine();
328 MD5Verts verts(numVerts);
330 for(MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j)
332 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "vert"));
333 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
334 MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - verts.begin()));
335 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "("));
336 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).u));
337 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).v));
338 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, ")"));
339 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_index));
340 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_count));
341 tokeniser.nextLine();
344 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numtris"));
346 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numTris));
347 tokeniser.nextLine();
349 MD5Tris tris(numTris);
351 for(MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j)
353 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "tri"));
354 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
355 MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - tris.begin()));
356 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).a));
357 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).b));
358 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).c));
359 tokeniser.nextLine();
362 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numweights"));
363 std::size_t numWeights;
364 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numWeights));
365 tokeniser.nextLine();
367 MD5Weights weights(numWeights);
369 for(MD5Weights::iterator j = weights.begin(); j != weights.end(); ++j)
371 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "weight"));
372 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
373 MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - weights.begin()));
374 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).joint));
375 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).t));
376 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*j).v));
377 tokeniser.nextLine();
380 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
381 tokeniser.nextLine();
383 for(MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j)
385 MD5Vert& vert = (*j);
387 Vector3 skinned(0, 0, 0);
388 for(std::size_t k = 0; k != vert.weight_count; ++k)
390 MD5Weight& weight = weights[vert.weight_index + k];
391 MD5Joint& joint = joints[weight.joint];
393 skinned += (quaternion_transformed_point(joint.rotation, weight.v) + joint.position) * weight.t;
396 surface.vertices().push_back(ArbitraryMeshVertex(vertex3f_for_vector3(skinned), Normal3f(0, 0, 0), TexCoord2f(vert.u, vert.v)));
399 for(MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j)
402 surface.indices().insert(RenderIndex(tri.a));
403 surface.indices().insert(RenderIndex(tri.b));
404 surface.indices().insert(RenderIndex(tri.c));
407 for(Surface::indices_t::iterator j = surface.indices().begin(); j != surface.indices().end(); j += 3)
409 ArbitraryMeshVertex& a = surface.vertices()[*(j + 0)];
410 ArbitraryMeshVertex& b = surface.vertices()[*(j + 1)];
411 ArbitraryMeshVertex& c = surface.vertices()[*(j + 2)];
412 Vector3 weightedNormal(
414 reinterpret_cast<const Vector3&>(c.vertex) - reinterpret_cast<const Vector3&>(a.vertex),
415 reinterpret_cast<const Vector3&>(b.vertex) - reinterpret_cast<const Vector3&>(a.vertex)
418 reinterpret_cast<Vector3&>(a.normal) += weightedNormal;
419 reinterpret_cast<Vector3&>(b.normal) += weightedNormal;
420 reinterpret_cast<Vector3&>(c.normal) += weightedNormal;
423 for(Surface::vertices_t::iterator j = surface.vertices().begin(); j != surface.vertices().end(); ++j)
425 vector3_normalise(reinterpret_cast<Vector3&>((*j).normal));
428 surface.updateAABB();
436 void MD5Model_construct(Model& model, TextInputStream& inputStream)
438 Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(inputStream);
439 MD5Model_parse(model, tokeniser);
443 scene::Node& MD5Model_new(TextInputStream& inputStream)
445 ModelNode* modelNode = new ModelNode();
446 MD5Model_construct(modelNode->model(), inputStream);
447 return modelNode->node();
450 scene::Node& loadMD5Model(ArchiveFile& file)
452 BinaryToTextInputStream<InputStream> inputStream(file.getInputStream());
453 return MD5Model_new(inputStream);