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) do { if (!(expression)) { globalErrorStream() << "md5 parse failed: " #expression "\n"; return false; } } while (0)
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)
93 typedef Array<MD5Joint> MD5Joints;
100 std::size_t weight_index;
101 std::size_t weight_count;
104 typedef Array<MD5Vert> MD5Verts;
114 typedef Array<MD5Tri> MD5Tris;
124 typedef Array<MD5Weight> MD5Weights;
126 typedef float MD5Component;
127 typedef Array<MD5Component> MD5Components;
131 MD5Components m_components;
134 typedef Array<MD5Weight> MD5Weights;
136 bool MD5_parseVersion(Tokeniser &tokeniser)
139 const char *versionKey = tokeniser.getToken();
140 if (versionKey == 0 || !string_equal(versionKey, "MD5Version")) {
141 globalErrorStream() << "not a valid md5 file\n";
146 const char *versionValue = tokeniser.getToken();
147 if (versionValue == 0 || !string_equal(versionValue, "10")) {
148 globalErrorStream() << "only md5 version 10 supported\n";
156 bool MD5Anim_parse(Tokeniser &tokeniser)
158 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVersion(tokeniser));
159 tokeniser.nextLine();
161 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "commandline"));
162 const char *commandline;
163 MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, commandline));
164 tokeniser.nextLine();
166 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numFrames"));
167 std::size_t numFrames;
168 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numFrames));
169 tokeniser.nextLine();
171 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numJoints"));
172 std::size_t numJoints;
173 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numJoints));
174 tokeniser.nextLine();
176 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "frameRate"));
177 std::size_t frameRate;
178 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, frameRate));
179 tokeniser.nextLine();
181 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numAnimatedComponents"));
182 std::size_t numAnimatedComponents;
183 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numAnimatedComponents));
184 tokeniser.nextLine();
187 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "hierarchy"));
188 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
189 tokeniser.nextLine();
191 for (std::size_t i = 0; i < numJoints; ++i) {
193 MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, name));
195 MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, parent));
197 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, flags));
199 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, index));
200 tokeniser.nextLine();
203 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
204 tokeniser.nextLine();
207 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "bounds"));
208 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
209 tokeniser.nextLine();
211 for (std::size_t i = 0; i < numFrames; ++i) {
213 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, mins));
215 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, maxs));
216 tokeniser.nextLine();
219 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
220 tokeniser.nextLine();
223 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "baseframe"));
224 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
225 tokeniser.nextLine();
227 for (std::size_t i = 0; i < numJoints; ++i) {
229 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, position));
231 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, rotation));
232 tokeniser.nextLine();
235 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
236 tokeniser.nextLine();
239 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) {
246 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, component));
247 tokeniser.nextLine();
250 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
251 tokeniser.nextLine();
257 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) {
284 const char *jointName;
285 MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, jointName));
286 MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, (*i).parent));
287 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*i).position));
288 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, vector4_to_vector3((*i).rotation)));
289 (*i).rotation.w() = -static_cast<float>( sqrt(1.0f - (float_squared((*i).rotation.x()) +
290 float_squared((*i).rotation.y()) +
291 float_squared((*i).rotation.z()))));
292 tokeniser.nextLine();
295 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
296 tokeniser.nextLine();
298 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) {
319 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "vert"));
320 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
321 MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - verts.begin()));
322 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "("));
323 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).u));
324 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).v));
325 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, ")"));
326 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_index));
327 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_count));
328 tokeniser.nextLine();
331 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numtris"));
333 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numTris));
334 tokeniser.nextLine();
336 MD5Tris tris(numTris);
338 for (MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j) {
339 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "tri"));
340 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
341 MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - tris.begin()));
342 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).a));
343 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).b));
344 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).c));
345 tokeniser.nextLine();
348 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numweights"));
349 std::size_t numWeights;
350 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numWeights));
351 tokeniser.nextLine();
353 MD5Weights weights(numWeights);
355 for (MD5Weights::iterator j = weights.begin(); j != weights.end(); ++j) {
356 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "weight"));
357 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
358 MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - weights.begin()));
359 MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).joint));
360 MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).t));
361 MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*j).v));
362 tokeniser.nextLine();
365 MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
366 tokeniser.nextLine();
368 for (MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j) {
369 MD5Vert &vert = (*j);
371 Vector3 skinned(0, 0, 0);
372 for (std::size_t k = 0; k != vert.weight_count; ++k) {
373 MD5Weight &weight = weights[vert.weight_index + k];
374 MD5Joint &joint = joints[weight.joint];
376 skinned += (quaternion_transformed_point(joint.rotation, weight.v) + joint.position) * weight.t;
379 surface.vertices().push_back(
380 ArbitraryMeshVertex(vertex3f_for_vector3(skinned), Normal3f(0, 0, 0), TexCoord2f(vert.u, vert.v)));
383 for (MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j) {
385 surface.indices().insert(RenderIndex(tri.a));
386 surface.indices().insert(RenderIndex(tri.b));
387 surface.indices().insert(RenderIndex(tri.c));
390 for (Surface::indices_t::iterator j = surface.indices().begin(); j != surface.indices().end(); j += 3) {
391 ArbitraryMeshVertex &a = surface.vertices()[*(j + 0)];
392 ArbitraryMeshVertex &b = surface.vertices()[*(j + 1)];
393 ArbitraryMeshVertex &c = surface.vertices()[*(j + 2)];
394 Vector3 weightedNormal(
396 reinterpret_cast<const Vector3 &>( c.vertex ) -
397 reinterpret_cast<const Vector3 &>( a.vertex ),
398 reinterpret_cast<const Vector3 &>( b.vertex ) -
399 reinterpret_cast<const Vector3 &>( a.vertex )
402 reinterpret_cast<Vector3 &>( a.normal ) += weightedNormal;
403 reinterpret_cast<Vector3 &>( b.normal ) += weightedNormal;
404 reinterpret_cast<Vector3 &>( c.normal ) += weightedNormal;
407 for (Surface::vertices_t::iterator j = surface.vertices().begin(); j != surface.vertices().end(); ++j) {
408 vector3_normalise(reinterpret_cast<Vector3 &>((*j).normal ));
411 surface.updateAABB();
419 void MD5Model_construct(Model &model, TextInputStream &inputStream)
421 Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(inputStream);
422 MD5Model_parse(model, tokeniser);
426 scene::Node &MD5Model_new(TextInputStream &inputStream)
428 ModelNode *modelNode = new ModelNode();
429 MD5Model_construct(modelNode->model(), inputStream);
430 return modelNode->node();
433 scene::Node &loadMD5Model(ArchiveFile &file)
435 BinaryToTextInputStream<InputStream> inputStream(file.getInputStream());
436 return MD5Model_new(inputStream);