MeshLoader.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #include "anki/resource/MeshLoader.h"
  2. #include "anki/util/BinaryStream.h"
  3. #include <fstream>
  4. #include <cstring>
  5. namespace anki {
  6. std::string lala;
  7. //==============================================================================
  8. void MeshLoader::load(const char* filename)
  9. {
  10. lala = filename;
  11. // Try
  12. try
  13. {
  14. // Open the file
  15. std::fstream file(filename, std::fstream::in | std::fstream::binary);
  16. if(!file.is_open())
  17. {
  18. throw ANKI_EXCEPTION("Cannot open file:" + filename);
  19. }
  20. BinaryStream bs(file.rdbuf());
  21. // Magic word
  22. char magic[8];
  23. bs.read(magic, 8);
  24. if(bs.fail() || memcmp(magic, "ANKIMESH", 8))
  25. {
  26. throw ANKI_EXCEPTION("Incorrect magic word");
  27. }
  28. // Mesh name
  29. std::string meshName = bs.readString();
  30. // Verts num
  31. uint vertsNum = bs.readUint();
  32. vertCoords.resize(vertsNum);
  33. // Vert coords
  34. for(Vec3& vertCoord : vertCoords)
  35. {
  36. for(uint j = 0; j < 3; j++)
  37. {
  38. vertCoord[j] = bs.readFloat();
  39. }
  40. }
  41. // Faces num
  42. uint facesNum = bs.readUint();
  43. tris.resize(facesNum);
  44. // Faces IDs
  45. for(Triangle& tri : tris)
  46. {
  47. for(uint j = 0; j < 3; j++)
  48. {
  49. tri.vertIds[j] = bs.readUint();
  50. // a sanity check
  51. if(tri.vertIds[j] >= vertCoords.size())
  52. {
  53. throw ANKI_EXCEPTION("Vert index out of bounds");
  54. }
  55. }
  56. }
  57. // Tex coords num
  58. uint texCoordsNum = bs.readUint();
  59. texCoords.resize(texCoordsNum);
  60. // Tex coords
  61. for(Vec2& texCoord : texCoords)
  62. {
  63. for(uint i = 0; i < 2; i++)
  64. {
  65. texCoord[i] = bs.readFloat();
  66. }
  67. }
  68. // Vert weights num
  69. uint vertWeightsNum = bs.readUint();
  70. vertWeights.resize(vertWeightsNum);
  71. // Vert weights
  72. for(VertexWeight& vw : vertWeights)
  73. {
  74. // get the bone connections num
  75. uint boneConnections = bs.readUint();
  76. // we treat as error if one vert doesnt have a bone
  77. if(boneConnections < 1)
  78. {
  79. throw ANKI_EXCEPTION("Vert sould have at least one bone");
  80. }
  81. // and here is another possible error
  82. if(boneConnections > VertexWeight::MAX_BONES_PER_VERT)
  83. {
  84. uint tmp = VertexWeight::MAX_BONES_PER_VERT;
  85. throw ANKI_EXCEPTION("Cannot have more than "
  86. + std::to_string(tmp) + " bones per vertex");
  87. }
  88. vw.bonesNum = boneConnections;
  89. // for all the weights of the current vertes
  90. for(uint i = 0; i < vw.bonesNum; i++)
  91. {
  92. // read bone id
  93. uint boneId = bs.readUint();
  94. vw.boneIds[i] = boneId;
  95. // read the weight of that bone
  96. float weight = bs.readFloat();
  97. vw.weights[i] = weight;
  98. }
  99. } // end for all vert weights
  100. doPostLoad();
  101. }
  102. catch(Exception& e)
  103. {
  104. throw ANKI_EXCEPTION("Loading of file failed: " + filename) << e;
  105. }
  106. }
  107. //==============================================================================
  108. void MeshLoader::doPostLoad()
  109. {
  110. // Sanity checks
  111. if(vertCoords.size() < 1 || tris.size() < 1)
  112. {
  113. throw ANKI_EXCEPTION("Vert coords and tris must be filled");
  114. }
  115. if(texCoords.size() != 0 && texCoords.size() != vertCoords.size())
  116. {
  117. throw ANKI_EXCEPTION("Tex coords num must be "
  118. "zero or equal to the vertex "
  119. "coords num");
  120. }
  121. if(vertWeights.size() != 0 && vertWeights.size() != vertCoords.size())
  122. {
  123. throw ANKI_EXCEPTION("Vert weights num must be zero or equal to the "
  124. "vertex coords num");
  125. }
  126. createAllNormals();
  127. fixNormals();
  128. if(texCoords.size() > 0)
  129. {
  130. createVertTangents();
  131. }
  132. createVertIndeces();
  133. }
  134. //==============================================================================
  135. void MeshLoader::createVertIndeces()
  136. {
  137. vertIndices.resize(tris.size() * 3);
  138. for(uint i = 0; i < tris.size(); i++)
  139. {
  140. vertIndices[i * 3 + 0] = tris[i].vertIds[0];
  141. vertIndices[i * 3 + 1] = tris[i].vertIds[1];
  142. vertIndices[i * 3 + 2] = tris[i].vertIds[2];
  143. }
  144. }
  145. //==============================================================================
  146. void MeshLoader::createFaceNormals()
  147. {
  148. for(Triangle& tri : tris)
  149. {
  150. const Vec3& v0 = vertCoords[tri.vertIds[0]];
  151. const Vec3& v1 = vertCoords[tri.vertIds[1]];
  152. const Vec3& v2 = vertCoords[tri.vertIds[2]];
  153. tri.normal = (v1 - v0).cross(v2 - v0);
  154. tri.normal.normalize();
  155. }
  156. }
  157. //==============================================================================
  158. void MeshLoader::createVertNormals()
  159. {
  160. vertNormals.resize(vertCoords.size());
  161. for(Vec3& vertNormal : vertNormals)
  162. {
  163. vertNormal = Vec3(0.0, 0.0, 0.0);
  164. }
  165. for(Triangle& tri : tris)
  166. {
  167. vertNormals[tri.vertIds[0]] += tri.normal;
  168. vertNormals[tri.vertIds[1]] += tri.normal;
  169. vertNormals[tri.vertIds[2]] += tri.normal;
  170. }
  171. for(Vec3& vertNormal : vertNormals)
  172. {
  173. vertNormal.normalize();
  174. }
  175. }
  176. //==============================================================================
  177. void MeshLoader::createVertTangents()
  178. {
  179. vertTangents.resize(vertCoords.size(), Vec4(0.0)); // alloc
  180. Vector<Vec3> bitagents(vertCoords.size(), Vec3(0.0));
  181. for(uint i = 0; i < tris.size(); i++)
  182. {
  183. const Triangle& tri = tris[i];
  184. const int i0 = tri.vertIds[0];
  185. const int i1 = tri.vertIds[1];
  186. const int i2 = tri.vertIds[2];
  187. const Vec3& v0 = vertCoords[i0];
  188. const Vec3& v1 = vertCoords[i1];
  189. const Vec3& v2 = vertCoords[i2];
  190. Vec3 edge01 = v1 - v0;
  191. Vec3 edge02 = v2 - v0;
  192. Vec2 uvedge01 = texCoords[i1] - texCoords[i0];
  193. Vec2 uvedge02 = texCoords[i2] - texCoords[i0];
  194. float det = (uvedge01.y() * uvedge02.x()) -
  195. (uvedge01.x() * uvedge02.y());
  196. if(isZero(det))
  197. {
  198. //ANKI_LOGW(getRsrcName() << ": det == " << fixed << det);
  199. det = 0.0001;
  200. }
  201. else
  202. {
  203. det = 1.0 / det;
  204. }
  205. Vec3 t = (edge02 * uvedge01.y() - edge01 * uvedge02.y()) * det;
  206. Vec3 b = (edge02 * uvedge01.x() - edge01 * uvedge02.x()) * det;
  207. t.normalize();
  208. b.normalize();
  209. vertTangents[i0] += Vec4(t, 1.0);
  210. vertTangents[i1] += Vec4(t, 1.0);
  211. vertTangents[i2] += Vec4(t, 1.0);
  212. bitagents[i0] += b;
  213. bitagents[i1] += b;
  214. bitagents[i2] += b;
  215. }
  216. for(uint i = 0; i < vertTangents.size(); i++)
  217. {
  218. Vec3 t = Vec3(vertTangents[i]);
  219. const Vec3& n = vertNormals[i];
  220. Vec3& b = bitagents[i];
  221. //t = t - n * n.dot(t);
  222. t.normalize();
  223. b.normalize();
  224. float w = ((n.cross(t)).dot(b) < 0.0) ? 1.0 : -1.0;
  225. vertTangents[i] = Vec4(t, w);
  226. }
  227. }
  228. //==============================================================================
  229. void MeshLoader::fixNormals()
  230. {
  231. const F32 positionsDistanceThresh = getEpsilon<F32>() * getEpsilon<F32>();
  232. for(U i = 1; i < vertCoords.size(); i++)
  233. {
  234. const Vec3& crntPos = vertCoords[i];
  235. Vec3& crntNormal = vertNormals[i];
  236. // Check the previous
  237. for(U j = 0; j < i; j++)
  238. {
  239. const Vec3& otherPos = vertCoords[j];
  240. Vec3& otherNormal = vertNormals[j];
  241. F32 distanceSq = crntPos.getDistanceSquared(otherPos);
  242. if(distanceSq <= positionsDistanceThresh)
  243. {
  244. F32 dot = crntNormal.dot(otherNormal);
  245. F32 ang = acos(dot);
  246. if(ang <= NORMALS_ANGLE_MERGE)
  247. {
  248. Vec3 newNormal = (crntNormal + otherNormal) * 0.5;
  249. newNormal.normalize();
  250. crntNormal = newNormal;
  251. otherNormal = newNormal;
  252. }
  253. }
  254. }
  255. }
  256. }
  257. } // end namespace anki