/*
-Copyright (C) 2001-2006, William Joseph.
-All Rights Reserved.
+ Copyright (C) 2001-2006, William Joseph.
+ All Rights Reserved.
-This file is part of GtkRadiant.
+ This file is part of GtkRadiant.
-GtkRadiant is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ GtkRadiant is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-GtkRadiant is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GtkRadiant is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ You should have received a copy of the GNU General Public License
+ along with GtkRadiant; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
#include "md5.h"
#include "model.h"
-#define MD5_RETURN_FALSE_IF_FAIL(expression) if(!(expression)) { globalErrorStream() << "md5 parse failed: " #expression "\n"; return false; } else
+#define MD5_RETURN_FALSE_IF_FAIL(expression) do { if (!(expression)) { globalErrorStream() << "md5 parse failed: " #expression "\n"; return false; } } while (0)
-bool MD5_parseToken(Tokeniser& tokeniser, const char* string)
+bool MD5_parseToken(Tokeniser &tokeniser, const char *string)
{
- const char* token = tokeniser.getToken();
- MD5_RETURN_FALSE_IF_FAIL(token != 0);
- return string_equal(token, string);
+ const char *token = tokeniser.getToken();
+ MD5_RETURN_FALSE_IF_FAIL(token != 0);
+ return string_equal(token, string);
}
-bool MD5_parseFloat(Tokeniser& tokeniser, float& f)
+bool MD5_parseFloat(Tokeniser &tokeniser, float &f)
{
- const char* token = tokeniser.getToken();
- MD5_RETURN_FALSE_IF_FAIL(token != 0);
- return string_parse_float(token, f);
+ const char *token = tokeniser.getToken();
+ MD5_RETURN_FALSE_IF_FAIL(token != 0);
+ return string_parse_float(token, f);
}
-bool MD5_parseString(Tokeniser& tokeniser, const char*& s)
+bool MD5_parseString(Tokeniser &tokeniser, const char *&s)
{
- const char* token = tokeniser.getToken();
- MD5_RETURN_FALSE_IF_FAIL(token != 0);
- s = token;
- return true;
+ const char *token = tokeniser.getToken();
+ MD5_RETURN_FALSE_IF_FAIL(token != 0);
+ s = token;
+ return true;
}
-bool MD5_parseInteger(Tokeniser& tokeniser, int& i)
+bool MD5_parseInteger(Tokeniser &tokeniser, int &i)
{
- const char* token = tokeniser.getToken();
- MD5_RETURN_FALSE_IF_FAIL(token != 0);
- return string_parse_int(token, i);
+ const char *token = tokeniser.getToken();
+ MD5_RETURN_FALSE_IF_FAIL(token != 0);
+ return string_parse_int(token, i);
}
-bool MD5_parseSize(Tokeniser& tokeniser, std::size_t& i)
+bool MD5_parseSize(Tokeniser &tokeniser, std::size_t &i)
{
- const char* token = tokeniser.getToken();
- MD5_RETURN_FALSE_IF_FAIL(token != 0);
- return string_parse_size(token, i);
+ const char *token = tokeniser.getToken();
+ MD5_RETURN_FALSE_IF_FAIL(token != 0);
+ return string_parse_size(token, i);
}
-bool MD5_parseVector3(Tokeniser& tokeniser, Vector3& v)
+bool MD5_parseVector3(Tokeniser &tokeniser, Vector3 &v)
{
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "("));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.x()));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.y()));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.z()));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, ")"));
- return true;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "("));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.x()));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.y()));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.z()));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, ")"));
+ return true;
}
template<typename Element>
-inline Element float_squared(const Element& f)
+inline Element float_squared(const Element &f)
{
- return f * f;
+ return f * f;
}
-class MD5Joint
-{
+class MD5Joint {
public:
- int parent;
- Vector3 position;
- Vector4 rotation;
+ int parent;
+ Vector3 position;
+ Vector4 rotation;
};
typedef Array<MD5Joint> MD5Joints;
-class MD5Vert
-{
+class MD5Vert {
public:
- std::size_t index;
- float u;
- float v;
- std::size_t weight_index;
- std::size_t weight_count;
+ std::size_t index;
+ float u;
+ float v;
+ std::size_t weight_index;
+ std::size_t weight_count;
};
typedef Array<MD5Vert> MD5Verts;
-class MD5Tri
-{
+class MD5Tri {
public:
- std::size_t index;
- std::size_t a;
- std::size_t b;
- std::size_t c;
+ std::size_t index;
+ std::size_t a;
+ std::size_t b;
+ std::size_t c;
};
typedef Array<MD5Tri> MD5Tris;
-class MD5Weight
-{
+class MD5Weight {
public:
- std::size_t index;
- std::size_t joint;
- float t;
- Vector3 v;
+ std::size_t index;
+ std::size_t joint;
+ float t;
+ Vector3 v;
};
typedef Array<MD5Weight> MD5Weights;
typedef float MD5Component;
typedef Array<MD5Component> MD5Components;
-class MD5Frame
-{
+class MD5Frame {
public:
- MD5Components m_components;
+ MD5Components m_components;
};
typedef Array<MD5Weight> MD5Weights;
-bool MD5_parseVersion(Tokeniser& tokeniser)
+bool MD5_parseVersion(Tokeniser &tokeniser)
{
- {
- const char* versionKey = tokeniser.getToken();
- if(versionKey == 0 || !string_equal(versionKey, "MD5Version"))
{
- globalErrorStream() << "not a valid md5 file\n";
- return false;
+ const char *versionKey = tokeniser.getToken();
+ if (versionKey == 0 || !string_equal(versionKey, "MD5Version")) {
+ globalErrorStream() << "not a valid md5 file\n";
+ return false;
+ }
}
- }
- {
- const char* versionValue = tokeniser.getToken();
- if(versionValue == 0 || !string_equal(versionValue, "10"))
{
- globalErrorStream() << "only md5 version 10 supported\n";
- return false;
+ const char *versionValue = tokeniser.getToken();
+ if (versionValue == 0 || !string_equal(versionValue, "10")) {
+ globalErrorStream() << "only md5 version 10 supported\n";
+ return false;
+ }
}
- }
- return true;
+ return true;
}
-bool MD5Anim_parse(Tokeniser& tokeniser)
+bool MD5Anim_parse(Tokeniser &tokeniser)
{
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseVersion(tokeniser));
- tokeniser.nextLine();
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "commandline"));
- const char* commandline;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, commandline));
- tokeniser.nextLine();
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numFrames"));
- std::size_t numFrames;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numFrames));
- tokeniser.nextLine();
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numJoints"));
- std::size_t numJoints;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numJoints));
- tokeniser.nextLine();
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "frameRate"));
- std::size_t frameRate;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, frameRate));
- tokeniser.nextLine();
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numAnimatedComponents"));
- std::size_t numAnimatedComponents;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numAnimatedComponents));
- tokeniser.nextLine();
-
- // parse heirarchy
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "hierarchy"));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
- tokeniser.nextLine();
-
- for(std::size_t i = 0; i < numJoints; ++i)
- {
- const char* name;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, name));
- int parent;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, parent));
- std::size_t flags;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, flags));
- std::size_t index;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, index));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseVersion(tokeniser));
tokeniser.nextLine();
- }
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
- tokeniser.nextLine();
-
- // parse bounds
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "bounds"));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
- tokeniser.nextLine();
-
- for(std::size_t i = 0; i < numFrames; ++i)
- {
- Vector3 mins;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, mins));
- Vector3 maxs;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, maxs));
+
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "commandline"));
+ const char *commandline;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, commandline));
tokeniser.nextLine();
- }
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
- tokeniser.nextLine();
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numFrames"));
+ std::size_t numFrames;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numFrames));
+ tokeniser.nextLine();
- // parse baseframe
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "baseframe"));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
- tokeniser.nextLine();
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numJoints"));
+ std::size_t numJoints;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numJoints));
+ tokeniser.nextLine();
- for(std::size_t i = 0; i < numJoints; ++i)
- {
- Vector3 position;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, position));
- Vector3 rotation;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, rotation));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "frameRate"));
+ std::size_t frameRate;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, frameRate));
tokeniser.nextLine();
- }
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
- tokeniser.nextLine();
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numAnimatedComponents"));
+ std::size_t numAnimatedComponents;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numAnimatedComponents));
+ tokeniser.nextLine();
- // parse frames
- for(std::size_t i = 0; i < numFrames; ++i)
- {
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "frame"));
+ // parse heirarchy
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "hierarchy"));
MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
tokeniser.nextLine();
- for(std::size_t i = 0; i < numAnimatedComponents; ++i)
- {
- float component;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, component));
- tokeniser.nextLine();
+ for (std::size_t i = 0; i < numJoints; ++i) {
+ const char *name;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, name));
+ int parent;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, parent));
+ std::size_t flags;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, flags));
+ std::size_t index;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, index));
+ tokeniser.nextLine();
}
MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
tokeniser.nextLine();
- }
- return true;
-}
-
-bool MD5Model_parse(Model& model, Tokeniser& tokeniser)
-{
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseVersion(tokeniser));
- tokeniser.nextLine();
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "commandline"));
- const char* commandline;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, commandline));
- tokeniser.nextLine();
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numJoints"));
- std::size_t numJoints;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numJoints));
- tokeniser.nextLine();
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numMeshes"));
- std::size_t numMeshes;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numMeshes));
- tokeniser.nextLine();
-
- MD5Joints joints(numJoints);
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "joints"));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
- tokeniser.nextLine();
-
- for(MD5Joints::iterator i = joints.begin(); i != joints.end(); ++i)
- {
- const char* jointName;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, jointName));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, (*i).parent));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*i).position));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, vector4_to_vector3((*i).rotation)));
- (*i).rotation.w() = -static_cast<float>(sqrt(1.0f - (float_squared((*i).rotation.x()) + float_squared((*i).rotation.y()) + float_squared((*i).rotation.z()))));
+ // parse bounds
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "bounds"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
tokeniser.nextLine();
- }
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
- tokeniser.nextLine();
- for(std::size_t i = 0; i < numMeshes; ++i)
- {
- Surface& surface = model.newSurface();
+ for (std::size_t i = 0; i < numFrames; ++i) {
+ Vector3 mins;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, mins));
+ Vector3 maxs;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, maxs));
+ tokeniser.nextLine();
+ }
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "mesh"));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
tokeniser.nextLine();
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "shader"));
- const char* shader;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, shader));
- surface.setShader(shader);
- tokeniser.nextLine();
-
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numverts"));
- std::size_t numVerts;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numVerts));
+ // parse baseframe
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "baseframe"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
tokeniser.nextLine();
- MD5Verts verts(numVerts);
-
- for(MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j)
- {
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "vert"));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
- MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - verts.begin()));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "("));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).u));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).v));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, ")"));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_index));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_count));
- tokeniser.nextLine();
+ for (std::size_t i = 0; i < numJoints; ++i) {
+ Vector3 position;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, position));
+ Vector3 rotation;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, rotation));
+ tokeniser.nextLine();
}
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numtris"));
- std::size_t numTris;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numTris));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
tokeniser.nextLine();
- MD5Tris tris(numTris);
+ // parse frames
+ for (std::size_t i = 0; i < numFrames; ++i) {
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "frame"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
+ tokeniser.nextLine();
- for(MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j)
- {
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "tri"));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
- MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - tris.begin()));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).a));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).b));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).c));
- tokeniser.nextLine();
+ for (std::size_t i = 0; i < numAnimatedComponents; ++i) {
+ float component;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, component));
+ tokeniser.nextLine();
+ }
+
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
+ tokeniser.nextLine();
}
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numweights"));
- std::size_t numWeights;
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numWeights));
+ return true;
+}
+
+bool MD5Model_parse(Model &model, Tokeniser &tokeniser)
+{
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseVersion(tokeniser));
tokeniser.nextLine();
- MD5Weights weights(numWeights);
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "commandline"));
+ const char *commandline;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, commandline));
+ tokeniser.nextLine();
- for(MD5Weights::iterator j = weights.begin(); j != weights.end(); ++j)
- {
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "weight"));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
- MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - weights.begin()));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).joint));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).t));
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*j).v));
- tokeniser.nextLine();
- }
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numJoints"));
+ std::size_t numJoints;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numJoints));
+ tokeniser.nextLine();
- MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numMeshes"));
+ std::size_t numMeshes;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numMeshes));
tokeniser.nextLine();
- for(MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j)
- {
- MD5Vert& vert = (*j);
-
- Vector3 skinned(0, 0, 0);
- for(std::size_t k = 0; k != vert.weight_count; ++k)
- {
- MD5Weight& weight = weights[vert.weight_index + k];
- MD5Joint& joint = joints[weight.joint];
-
- skinned += (quaternion_transformed_point(joint.rotation, weight.v) + joint.position) * weight.t;
- }
-
- surface.vertices().push_back(ArbitraryMeshVertex(vertex3f_for_vector3(skinned), Normal3f(0, 0, 0), TexCoord2f(vert.u, vert.v)));
- }
+ MD5Joints joints(numJoints);
- for(MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j)
- {
- MD5Tri& tri = (*j);
- surface.indices().insert(RenderIndex(tri.a));
- surface.indices().insert(RenderIndex(tri.b));
- surface.indices().insert(RenderIndex(tri.c));
- }
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "joints"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
+ tokeniser.nextLine();
- for(Surface::indices_t::iterator j = surface.indices().begin(); j != surface.indices().end(); j += 3)
- {
- ArbitraryMeshVertex& a = surface.vertices()[*(j + 0)];
- ArbitraryMeshVertex& b = surface.vertices()[*(j + 1)];
- ArbitraryMeshVertex& c = surface.vertices()[*(j + 2)];
- Vector3 weightedNormal(
- vector3_cross(
- reinterpret_cast<const Vector3&>(c.vertex) - reinterpret_cast<const Vector3&>(a.vertex),
- reinterpret_cast<const Vector3&>(b.vertex) - reinterpret_cast<const Vector3&>(a.vertex)
- )
- );
- reinterpret_cast<Vector3&>(a.normal) += weightedNormal;
- reinterpret_cast<Vector3&>(b.normal) += weightedNormal;
- reinterpret_cast<Vector3&>(c.normal) += weightedNormal;
+ for (MD5Joints::iterator i = joints.begin(); i != joints.end(); ++i) {
+ const char *jointName;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, jointName));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, (*i).parent));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*i).position));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, vector4_to_vector3((*i).rotation)));
+ (*i).rotation.w() = -static_cast<float>( sqrt(1.0f - (float_squared((*i).rotation.x()) +
+ float_squared((*i).rotation.y()) +
+ float_squared((*i).rotation.z()))));
+ tokeniser.nextLine();
}
- for(Surface::vertices_t::iterator j = surface.vertices().begin(); j != surface.vertices().end(); ++j)
- {
- vector3_normalise(reinterpret_cast<Vector3&>((*j).normal));
- }
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
+ tokeniser.nextLine();
- surface.updateAABB();
- }
+ for (std::size_t i = 0; i < numMeshes; ++i) {
+ Surface &surface = model.newSurface();
+
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "mesh"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
+ tokeniser.nextLine();
+
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "shader"));
+ const char *shader;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, shader));
+ surface.setShader(shader);
+ tokeniser.nextLine();
+
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numverts"));
+ std::size_t numVerts;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numVerts));
+ tokeniser.nextLine();
+
+ MD5Verts verts(numVerts);
+
+ for (MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j) {
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "vert"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
+ MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - verts.begin()));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "("));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).u));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).v));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, ")"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_index));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_count));
+ tokeniser.nextLine();
+ }
+
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numtris"));
+ std::size_t numTris;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numTris));
+ tokeniser.nextLine();
+
+ MD5Tris tris(numTris);
+
+ for (MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j) {
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "tri"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
+ MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - tris.begin()));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).a));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).b));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).c));
+ tokeniser.nextLine();
+ }
+
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numweights"));
+ std::size_t numWeights;
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numWeights));
+ tokeniser.nextLine();
+
+ MD5Weights weights(numWeights);
+
+ for (MD5Weights::iterator j = weights.begin(); j != weights.end(); ++j) {
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "weight"));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
+ MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - weights.begin()));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).joint));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).t));
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*j).v));
+ tokeniser.nextLine();
+ }
+
+ MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
+ tokeniser.nextLine();
+
+ for (MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j) {
+ MD5Vert &vert = (*j);
+
+ Vector3 skinned(0, 0, 0);
+ for (std::size_t k = 0; k != vert.weight_count; ++k) {
+ MD5Weight &weight = weights[vert.weight_index + k];
+ MD5Joint &joint = joints[weight.joint];
+
+ skinned += (quaternion_transformed_point(joint.rotation, weight.v) + joint.position) * weight.t;
+ }
+
+ surface.vertices().push_back(
+ ArbitraryMeshVertex(vertex3f_for_vector3(skinned), Normal3f(0, 0, 0), TexCoord2f(vert.u, vert.v)));
+ }
+
+ for (MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j) {
+ MD5Tri &tri = (*j);
+ surface.indices().insert(RenderIndex(tri.a));
+ surface.indices().insert(RenderIndex(tri.b));
+ surface.indices().insert(RenderIndex(tri.c));
+ }
+
+ for (Surface::indices_t::iterator j = surface.indices().begin(); j != surface.indices().end(); j += 3) {
+ ArbitraryMeshVertex &a = surface.vertices()[*(j + 0)];
+ ArbitraryMeshVertex &b = surface.vertices()[*(j + 1)];
+ ArbitraryMeshVertex &c = surface.vertices()[*(j + 2)];
+ Vector3 weightedNormal(
+ vector3_cross(
+ reinterpret_cast<const Vector3 &>( c.vertex ) -
+ reinterpret_cast<const Vector3 &>( a.vertex ),
+ reinterpret_cast<const Vector3 &>( b.vertex ) -
+ reinterpret_cast<const Vector3 &>( a.vertex )
+ )
+ );
+ reinterpret_cast<Vector3 &>( a.normal ) += weightedNormal;
+ reinterpret_cast<Vector3 &>( b.normal ) += weightedNormal;
+ reinterpret_cast<Vector3 &>( c.normal ) += weightedNormal;
+ }
+
+ for (Surface::vertices_t::iterator j = surface.vertices().begin(); j != surface.vertices().end(); ++j) {
+ vector3_normalise(reinterpret_cast<Vector3 &>((*j).normal ));
+ }
+
+ surface.updateAABB();
+ }
- model.updateAABB();
+ model.updateAABB();
- return true;
+ return true;
}
-void MD5Model_construct(Model& model, TextInputStream& inputStream)
+void MD5Model_construct(Model &model, TextInputStream &inputStream)
{
- Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(inputStream);
- MD5Model_parse(model, tokeniser);
- tokeniser.release();
+ Tokeniser &tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(inputStream);
+ MD5Model_parse(model, tokeniser);
+ tokeniser.release();
}
-scene::Node& MD5Model_new(TextInputStream& inputStream)
+scene::Node &MD5Model_new(TextInputStream &inputStream)
{
- ModelNode* modelNode = new ModelNode();
- MD5Model_construct(modelNode->model(), inputStream);
- return modelNode->node();
+ ModelNode *modelNode = new ModelNode();
+ MD5Model_construct(modelNode->model(), inputStream);
+ return modelNode->node();
}
-scene::Node& loadMD5Model(ArchiveFile& file)
+scene::Node &loadMD5Model(ArchiveFile &file)
{
- BinaryToTextInputStream<InputStream> inputStream(file.getInputStream());
- return MD5Model_new(inputStream);
+ BinaryToTextInputStream<InputStream> inputStream(file.getInputStream());
+ return MD5Model_new(inputStream);
}