md5.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /*
  2. Copyright (C) 2001-2006, William Joseph.
  3. All Rights Reserved.
  4. This file is part of GtkRadiant.
  5. GtkRadiant is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. GtkRadiant is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GtkRadiant; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #include "md5.h"
  18. #include "iscriplib.h"
  19. #include "imodel.h"
  20. #include "archivelib.h"
  21. #include "stringio.h"
  22. #include "model.h"
  23. #define MD5_RETURN_FALSE_IF_FAIL(expression) if(!(expression)) { globalErrorStream() << "md5 parse failed: " #expression "\n"; return false; } else
  24. bool MD5_parseToken(Tokeniser& tokeniser, const char* string)
  25. {
  26. const char* token = tokeniser.getToken();
  27. MD5_RETURN_FALSE_IF_FAIL(token != 0);
  28. return string_equal(token, string);
  29. }
  30. bool MD5_parseFloat(Tokeniser& tokeniser, float& f)
  31. {
  32. const char* token = tokeniser.getToken();
  33. MD5_RETURN_FALSE_IF_FAIL(token != 0);
  34. return string_parse_float(token, f);
  35. }
  36. bool MD5_parseString(Tokeniser& tokeniser, const char*& s)
  37. {
  38. const char* token = tokeniser.getToken();
  39. MD5_RETURN_FALSE_IF_FAIL(token != 0);
  40. s = token;
  41. return true;
  42. }
  43. bool MD5_parseInteger(Tokeniser& tokeniser, int& i)
  44. {
  45. const char* token = tokeniser.getToken();
  46. MD5_RETURN_FALSE_IF_FAIL(token != 0);
  47. return string_parse_int(token, i);
  48. }
  49. bool MD5_parseSize(Tokeniser& tokeniser, std::size_t& i)
  50. {
  51. const char* token = tokeniser.getToken();
  52. MD5_RETURN_FALSE_IF_FAIL(token != 0);
  53. return string_parse_size(token, i);
  54. }
  55. bool MD5_parseVector3(Tokeniser& tokeniser, Vector3& v)
  56. {
  57. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "("));
  58. MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.x()));
  59. MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.y()));
  60. MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, v.z()));
  61. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, ")"));
  62. return true;
  63. }
  64. template<typename Element>
  65. inline Element float_squared(const Element& f)
  66. {
  67. return f * f;
  68. }
  69. class MD5Joint
  70. {
  71. public:
  72. int parent;
  73. Vector3 position;
  74. Vector4 rotation;
  75. };
  76. typedef Array<MD5Joint> MD5Joints;
  77. class MD5Vert
  78. {
  79. public:
  80. std::size_t index;
  81. float u;
  82. float v;
  83. std::size_t weight_index;
  84. std::size_t weight_count;
  85. };
  86. typedef Array<MD5Vert> MD5Verts;
  87. class MD5Tri
  88. {
  89. public:
  90. std::size_t index;
  91. std::size_t a;
  92. std::size_t b;
  93. std::size_t c;
  94. };
  95. typedef Array<MD5Tri> MD5Tris;
  96. class MD5Weight
  97. {
  98. public:
  99. std::size_t index;
  100. std::size_t joint;
  101. float t;
  102. Vector3 v;
  103. };
  104. typedef Array<MD5Weight> MD5Weights;
  105. typedef float MD5Component;
  106. typedef Array<MD5Component> MD5Components;
  107. class MD5Frame
  108. {
  109. public:
  110. MD5Components m_components;
  111. };
  112. typedef Array<MD5Weight> MD5Weights;
  113. bool MD5_parseVersion(Tokeniser& tokeniser)
  114. {
  115. {
  116. const char* versionKey = tokeniser.getToken();
  117. if(versionKey == 0 || !string_equal(versionKey, "MD5Version"))
  118. {
  119. globalErrorStream() << "not a valid md5 file\n";
  120. return false;
  121. }
  122. }
  123. {
  124. const char* versionValue = tokeniser.getToken();
  125. if(versionValue == 0 || !string_equal(versionValue, "10"))
  126. {
  127. globalErrorStream() << "only md5 version 10 supported\n";
  128. return false;
  129. }
  130. }
  131. return true;
  132. }
  133. bool MD5Anim_parse(Tokeniser& tokeniser)
  134. {
  135. MD5_RETURN_FALSE_IF_FAIL(MD5_parseVersion(tokeniser));
  136. tokeniser.nextLine();
  137. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "commandline"));
  138. const char* commandline;
  139. MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, commandline));
  140. tokeniser.nextLine();
  141. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numFrames"));
  142. std::size_t numFrames;
  143. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numFrames));
  144. tokeniser.nextLine();
  145. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numJoints"));
  146. std::size_t numJoints;
  147. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numJoints));
  148. tokeniser.nextLine();
  149. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "frameRate"));
  150. std::size_t frameRate;
  151. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, frameRate));
  152. tokeniser.nextLine();
  153. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numAnimatedComponents"));
  154. std::size_t numAnimatedComponents;
  155. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numAnimatedComponents));
  156. tokeniser.nextLine();
  157. // parse heirarchy
  158. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "hierarchy"));
  159. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
  160. tokeniser.nextLine();
  161. for(std::size_t i = 0; i < numJoints; ++i)
  162. {
  163. const char* name;
  164. MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, name));
  165. int parent;
  166. MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, parent));
  167. std::size_t flags;
  168. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, flags));
  169. std::size_t index;
  170. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, index));
  171. tokeniser.nextLine();
  172. }
  173. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
  174. tokeniser.nextLine();
  175. // parse bounds
  176. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "bounds"));
  177. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
  178. tokeniser.nextLine();
  179. for(std::size_t i = 0; i < numFrames; ++i)
  180. {
  181. Vector3 mins;
  182. MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, mins));
  183. Vector3 maxs;
  184. MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, maxs));
  185. tokeniser.nextLine();
  186. }
  187. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
  188. tokeniser.nextLine();
  189. // parse baseframe
  190. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "baseframe"));
  191. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
  192. tokeniser.nextLine();
  193. for(std::size_t i = 0; i < numJoints; ++i)
  194. {
  195. Vector3 position;
  196. MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, position));
  197. Vector3 rotation;
  198. MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, rotation));
  199. tokeniser.nextLine();
  200. }
  201. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
  202. tokeniser.nextLine();
  203. // parse frames
  204. for(std::size_t i = 0; i < numFrames; ++i)
  205. {
  206. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "frame"));
  207. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
  208. tokeniser.nextLine();
  209. for(std::size_t i = 0; i < numAnimatedComponents; ++i)
  210. {
  211. float component;
  212. MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, component));
  213. tokeniser.nextLine();
  214. }
  215. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
  216. tokeniser.nextLine();
  217. }
  218. return true;
  219. }
  220. bool MD5Model_parse(Model& model, Tokeniser& tokeniser)
  221. {
  222. MD5_RETURN_FALSE_IF_FAIL(MD5_parseVersion(tokeniser));
  223. tokeniser.nextLine();
  224. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "commandline"));
  225. const char* commandline;
  226. MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, commandline));
  227. tokeniser.nextLine();
  228. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numJoints"));
  229. std::size_t numJoints;
  230. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numJoints));
  231. tokeniser.nextLine();
  232. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numMeshes"));
  233. std::size_t numMeshes;
  234. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numMeshes));
  235. tokeniser.nextLine();
  236. MD5Joints joints(numJoints);
  237. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "joints"));
  238. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
  239. tokeniser.nextLine();
  240. for(MD5Joints::iterator i = joints.begin(); i != joints.end(); ++i)
  241. {
  242. const char* jointName;
  243. MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, jointName));
  244. MD5_RETURN_FALSE_IF_FAIL(MD5_parseInteger(tokeniser, (*i).parent));
  245. MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*i).position));
  246. MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*i).rotation));
  247. (*i).rotation.w() = -static_cast<float>(sqrt(1.0f - (float_squared((*i).rotation.x()) + float_squared((*i).rotation.y()) + float_squared((*i).rotation.z()))));
  248. tokeniser.nextLine();
  249. }
  250. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
  251. tokeniser.nextLine();
  252. for(std::size_t i = 0; i < numMeshes; ++i)
  253. {
  254. Surface& surface = model.newSurface();
  255. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "mesh"));
  256. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "{"));
  257. tokeniser.nextLine();
  258. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "shader"));
  259. const char* shader;
  260. MD5_RETURN_FALSE_IF_FAIL(MD5_parseString(tokeniser, shader));
  261. surface.setShader(shader);
  262. tokeniser.nextLine();
  263. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numverts"));
  264. std::size_t numVerts;
  265. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numVerts));
  266. tokeniser.nextLine();
  267. MD5Verts verts(numVerts);
  268. for(MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j)
  269. {
  270. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "vert"));
  271. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
  272. MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - verts.begin()));
  273. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "("));
  274. MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).u));
  275. MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).v));
  276. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, ")"));
  277. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_index));
  278. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).weight_count));
  279. tokeniser.nextLine();
  280. }
  281. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numtris"));
  282. std::size_t numTris;
  283. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numTris));
  284. tokeniser.nextLine();
  285. MD5Tris tris(numTris);
  286. for(MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j)
  287. {
  288. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "tri"));
  289. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
  290. MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - tris.begin()));
  291. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).a));
  292. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).b));
  293. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).c));
  294. tokeniser.nextLine();
  295. }
  296. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "numweights"));
  297. std::size_t numWeights;
  298. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, numWeights));
  299. tokeniser.nextLine();
  300. MD5Weights weights(numWeights);
  301. for(MD5Weights::iterator j = weights.begin(); j != weights.end(); ++j)
  302. {
  303. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "weight"));
  304. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).index));
  305. MD5_RETURN_FALSE_IF_FAIL((*j).index == std::size_t(j - weights.begin()));
  306. MD5_RETURN_FALSE_IF_FAIL(MD5_parseSize(tokeniser, (*j).joint));
  307. MD5_RETURN_FALSE_IF_FAIL(MD5_parseFloat(tokeniser, (*j).t));
  308. MD5_RETURN_FALSE_IF_FAIL(MD5_parseVector3(tokeniser, (*j).v));
  309. tokeniser.nextLine();
  310. }
  311. MD5_RETURN_FALSE_IF_FAIL(MD5_parseToken(tokeniser, "}"));
  312. tokeniser.nextLine();
  313. for(MD5Verts::iterator j = verts.begin(); j != verts.end(); ++j)
  314. {
  315. MD5Vert& vert = (*j);
  316. Vector3 skinned(0, 0, 0);
  317. for(std::size_t k = 0; k != vert.weight_count; ++k)
  318. {
  319. MD5Weight& weight = weights[vert.weight_index + k];
  320. MD5Joint& joint = joints[weight.joint];
  321. skinned += (quaternion_transformed_point(joint.rotation, weight.v) + joint.position) * weight.t;
  322. }
  323. surface.vertices().push_back(ArbitraryMeshVertex(vertex3f_for_vector3(skinned), Normal3f(0, 0, 0), TexCoord2f(vert.u, vert.v)));
  324. }
  325. for(MD5Tris::iterator j = tris.begin(); j != tris.end(); ++j)
  326. {
  327. MD5Tri& tri = (*j);
  328. surface.indices().insert(RenderIndex(tri.a));
  329. surface.indices().insert(RenderIndex(tri.b));
  330. surface.indices().insert(RenderIndex(tri.c));
  331. }
  332. for(Surface::indices_t::iterator j = surface.indices().begin(); j != surface.indices().end(); j += 3)
  333. {
  334. ArbitraryMeshVertex& a = surface.vertices()[*(j + 0)];
  335. ArbitraryMeshVertex& b = surface.vertices()[*(j + 1)];
  336. ArbitraryMeshVertex& c = surface.vertices()[*(j + 2)];
  337. Vector3 weightedNormal(
  338. vector3_cross(
  339. reinterpret_cast<const Vector3&>(c.vertex) - reinterpret_cast<const Vector3&>(a.vertex),
  340. reinterpret_cast<const Vector3&>(b.vertex) - reinterpret_cast<const Vector3&>(a.vertex)
  341. )
  342. );
  343. reinterpret_cast<Vector3&>(a.normal) += weightedNormal;
  344. reinterpret_cast<Vector3&>(b.normal) += weightedNormal;
  345. reinterpret_cast<Vector3&>(c.normal) += weightedNormal;
  346. }
  347. for(Surface::vertices_t::iterator j = surface.vertices().begin(); j != surface.vertices().end(); ++j)
  348. {
  349. vector3_normalise(reinterpret_cast<Vector3&>((*j).normal));
  350. }
  351. surface.updateAABB();
  352. }
  353. model.updateAABB();
  354. return true;
  355. }
  356. void MD5Model_construct(Model& model, TextInputStream& inputStream)
  357. {
  358. Tokeniser& tokeniser = GlobalScriptLibrary().m_pfnNewSimpleTokeniser(inputStream);
  359. MD5Model_parse(model, tokeniser);
  360. tokeniser.release();
  361. }
  362. scene::Node& MD5Model_new(TextInputStream& inputStream)
  363. {
  364. ModelNode* modelNode = new ModelNode();
  365. MD5Model_construct(modelNode->model(), inputStream);
  366. return modelNode->node();
  367. }
  368. scene::Node& loadMD5Model(ArchiveFile& file)
  369. {
  370. BinaryToTextInputStream<InputStream> inputStream(file.getInputStream());
  371. return MD5Model_new(inputStream);
  372. }