GLTFLoader.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. #ifndef GUL_GLTF_LOADER_H
  2. #define GUL_GLTF_LOADER_H
  3. #include "MeshPrimitive2.h"
  4. #include "Image.h"
  5. #include "math/Transform.h"
  6. #include <fstream>
  7. #include <vector>
  8. #include <nlohmann/json.hpp>
  9. #include "ImageLoad_stb.h"
  10. //#include "spdlog/spdlog.h"
  11. namespace gul
  12. {
  13. template<typename T>
  14. struct typed_id
  15. {
  16. uint32_t index=0xFFFFFFFF;
  17. operator bool() const
  18. {
  19. return index != 0xFFFFFFFF;
  20. }
  21. };
  22. struct Sampler
  23. {
  24. int magFilter = 9729;
  25. int minFilter = 9729;
  26. int wrapS = 10497;
  27. int wrapT = 10497;
  28. };
  29. struct Texture
  30. {
  31. typed_id<Sampler> sampler;
  32. typed_id<Image> source;
  33. };
  34. struct Material
  35. {
  36. glm::vec3 emissiveFactor = glm::vec3(0,0,0);
  37. struct
  38. {
  39. glm::vec4 baseColorFactor = glm::vec4(1,1,1,1);
  40. float metallicFactor = 1.0f;
  41. float roughnessFactor = 1.0f;
  42. struct
  43. {
  44. typed_id<Texture> index;
  45. int texCoord = 0;
  46. } baseColorTexture, metallicRoughnessTexture;
  47. } pbrMetallicRoughness;
  48. struct
  49. {
  50. typed_id<Texture> index;
  51. int texCoord = 0;
  52. float scale = 1.0f;
  53. } normalTexture;
  54. struct
  55. {
  56. typed_id<Texture> index;
  57. int texCoord = 0;
  58. float strength = 1.0f;
  59. } occlusionTexture;
  60. struct
  61. {
  62. typed_id<Texture> index;
  63. int texCoord = 0;
  64. } emissiveTexture;
  65. std::string alphaMode = "OPAQUE";
  66. float alphaCutOff = 0.5f;
  67. bool doubleSided = false;
  68. };
  69. struct Primitive
  70. {
  71. typed_id<MeshPrimitive> primitive;
  72. typed_id<Material> material;
  73. };
  74. struct Mesh
  75. {
  76. std::vector<Primitive> primitive;
  77. };
  78. struct Node : gul::Transform
  79. {
  80. std::vector<uint32_t> children;
  81. typed_id<Mesh> mesh;
  82. };
  83. struct GLTFAsset
  84. {
  85. Image& get(typed_id<Image> id)
  86. {
  87. return images.at(id.index);
  88. }
  89. Mesh& get(typed_id<Mesh> id)
  90. {
  91. return meshes.at(id.index);
  92. }
  93. std::vector<Node> nodes;
  94. std::vector<Mesh> meshes;
  95. //std::vector<Material> materials;
  96. //std::vector<Texture> textures;
  97. //std::vector<Sampler> samplers;
  98. // low level objects
  99. std::vector<MeshPrimitive> primitives;
  100. std::vector<Image> images;
  101. // low
  102. #define _DEF_VECTOR(type, name) \
  103. std::vector<type> name;\
  104. type & get(typed_id<type> id)\
  105. {\
  106. return name.at(id.index);\
  107. }
  108. _DEF_VECTOR(Material, materials);
  109. _DEF_VECTOR(Texture, textures);
  110. _DEF_VECTOR(Sampler, samplers);
  111. };
  112. GLTFAsset loadGLTF(std::istream & in, std::string const & rootPath)
  113. {
  114. using namespace nlohmann;
  115. std::map<uint32_t, std::vector<char>> buffers;
  116. std::vector<VertexAttribute> accessors;
  117. std::unordered_map<json, uint32_t> meshPrimitives;
  118. GLTFAsset G;
  119. json J;
  120. auto first = in.peek();
  121. if( first == 0x67 ) // GLTF magic number: 0x46546C67
  122. {
  123. // this is a GLB
  124. uint32_t magic;
  125. uint32_t version;
  126. uint32_t length;
  127. in.read( reinterpret_cast<char*>(&magic), 4);
  128. in.read( reinterpret_cast<char*>(&version), 4);
  129. in.read( reinterpret_cast<char*>(&length), 4);
  130. assert(magic == 0x46546C67);
  131. uint32_t json_chunk_length;
  132. uint32_t json_chunk_type;
  133. in.read( reinterpret_cast<char*>(&json_chunk_length), 4);
  134. in.read( reinterpret_cast<char*>(&json_chunk_type), 4);
  135. assert(json_chunk_type == 0x4E4F534A);
  136. std::string json_string(json_chunk_length, ' ');
  137. in.read(&json_string[0], json_chunk_length);
  138. J = json::parse(json_string);
  139. uint32_t bin_chunk_length;
  140. uint32_t bin_chunk_type;
  141. in.read( reinterpret_cast<char*>(&bin_chunk_length), 4);
  142. in.read( reinterpret_cast<char*>(&bin_chunk_type), 4);
  143. assert(bin_chunk_type == 0x004E4942);
  144. buffers[0].resize( bin_chunk_length);
  145. in.read(buffers[0].data(), bin_chunk_length);
  146. }
  147. else
  148. {
  149. in >> J;
  150. uint32_t bi=0;
  151. for(auto & b : J["buffers"])
  152. {
  153. std::cout << "Buffer found: " << b["name"] << std::endl;
  154. if( b.contains("uri"))
  155. {
  156. auto path = rootPath + "/" + b.at("uri").get<std::string>();
  157. std::ifstream i( path, std::ios_base::binary);
  158. buffers[bi] =
  159. std::vector<char>( std::istreambuf_iterator<char>(i),
  160. std::istreambuf_iterator<char>() );
  161. }
  162. ++bi;
  163. }
  164. }
  165. struct Accessor
  166. {
  167. uint32_t stride = 0;
  168. uint32_t componentType = 0;
  169. std::string type;
  170. };
  171. for(auto & a : J["accessors"])
  172. {
  173. auto bv_i = a["bufferView"].get<uint32_t>();
  174. auto & bv = J["bufferViews"][ bv_i ];
  175. auto b_i = bv["buffer"].get<uint32_t>();
  176. auto & buffer = buffers[b_i];
  177. #if 1
  178. auto type = a.value("type", std::string("UNKNOWN"));
  179. auto componentType = a.value("componentType", 0u);
  180. auto count = a.value("count", 0u);
  181. auto byteOffset = a.value("byteOffset", 0u);
  182. auto bufferViewByteStride = bv.value("byteStride", 0u);
  183. auto bufferViewByteOffset = bv.value("byteOffset", 0u);
  184. auto V = fromGLTFAccessor(buffer.data() + bufferViewByteOffset,
  185. bufferViewByteStride, count, byteOffset,componentType,type);
  186. #else
  187. uint32_t stride=0;
  188. auto type = a["type"].get<std::string>();
  189. auto componentType = a["componentType"].get<uint32_t>();
  190. auto count = a["count"].get<uint32_t>();
  191. eType _type = {};
  192. if(type == "SCALAR") _type = eType::SCALAR;
  193. if(type == "VEC2") _type = eType::VEC2;
  194. if(type == "VEC3") _type = eType::VEC3;
  195. if(type == "VEC4") _type = eType::VEC4;
  196. auto bufferViewData = buffer.data();
  197. if(bv.contains("byteOffset"))
  198. {
  199. bufferViewData += bv.at("byteOffset").get<uint32_t>();
  200. }
  201. if(a.contains("byteOffset"))
  202. {
  203. bufferViewData += a.at("byteOffset").get<uint32_t>();
  204. }
  205. VertexAttribute V( eComponentType(componentType), _type);
  206. if(bv.contains("byteStride"))
  207. {
  208. stride = bv.at("byteStride").get<uint32_t>();
  209. }
  210. else
  211. {
  212. stride = V.getAttributeSize();
  213. }
  214. auto attrSize = V.getAttributeSize();
  215. for(uint32_t jj=0;jj<count;jj++)
  216. {
  217. std::memcpy( static_cast<uint8_t*>(V.data()) + jj*attrSize,
  218. bufferViewData + jj*stride,
  219. attrSize);
  220. }
  221. #endif
  222. std::cout << "Accessor Found: " << type << " " << V.getByteSize() << " Count: " << V.attributeCount() << std::endl;
  223. accessors.push_back( std::move(V) );
  224. };
  225. for(auto & i : J["images"])
  226. {
  227. if(i.contains("uri"))
  228. {
  229. auto path = rootPath + "/" + i.at("uri").get<std::string>();
  230. #if 1
  231. G.images.push_back( gul::loadImage(path) );
  232. #else
  233. std::ifstream i(path, std::ios_base::binary);
  234. auto data = std::vector<char>( std::istreambuf_iterator<char>(i), std::istreambuf_iterator<char>() );
  235. G.images.push_back( gul::loadImage(data.data(), int(data.size())));
  236. #endif
  237. }
  238. else if(i.contains("bufferView"))
  239. {
  240. //uint32_t bvi = ;
  241. auto & b = J["bufferViews"][ i["bufferView"].get<uint32_t>() ] ;
  242. uint32_t bufferIndex = b["buffer"];
  243. auto bufferData = buffers[bufferIndex].data();
  244. if(b.contains("byteOffset"))
  245. {
  246. bufferData += b["byteOffset"].get<uint32_t>();
  247. }
  248. auto byteLength = b["byteLength"].get<int32_t>();
  249. auto I = gul::loadImage(bufferData, byteLength);
  250. G.images.push_back( std::move(I));
  251. }
  252. }
  253. for(auto & v : J["meshes"])
  254. {
  255. auto & m = G.meshes.emplace_back();
  256. for(auto & p : v["primitives"])
  257. {
  258. json P;
  259. P = p["attributes"];
  260. P["indices"] = p["indices"];
  261. if(meshPrimitives.count(P) == 0)
  262. {
  263. gul::MeshPrimitive M;
  264. if(P.contains("POSITION")) M.POSITION = accessors[ P["POSITION"].get<uint32_t>() ];
  265. if(P.contains("NORMAL")) M.NORMAL = accessors[ P["NORMAL"].get<uint32_t>() ];
  266. if(P.contains("TANGENT")) M.TANGENT = accessors[ P["TANGENT"].get<uint32_t>() ];
  267. if(P.contains("TEXCOORD_0")) M.TEXCOORD_0 = accessors[ P["TEXCOORD_0"].get<uint32_t>() ];
  268. if(P.contains("TEXCOORD_1")) M.TEXCOORD_1 = accessors[ P["TEXCOORD_1"].get<uint32_t>() ];
  269. if(P.contains("JOINTS_0")) M.JOINTS_0 = accessors[ P["JOINTS_0"].get<uint32_t>() ];
  270. if(P.contains("WEIGHTS_0")) M.WEIGHTS_0 = accessors[ P["WEIGHTS_0"].get<uint32_t>() ];
  271. if(P.contains("COLOR_0")) M.COLOR_0 = accessors[ P["COLOR_0"].get<uint32_t>() ];
  272. if(P.contains("indices")) M.INDEX = accessors[ P["indices"].get<uint32_t>() ];
  273. std::cout << "Mesh found: " << v["name"] << ": " << M.calculateDeviceSize() << std::endl;
  274. G.primitives.push_back(std::move(M));
  275. meshPrimitives[P] = uint32_t(G.primitives.size()-1);
  276. }
  277. auto & pr = m.primitive.emplace_back();
  278. pr.primitive.index = meshPrimitives.at(P);
  279. if(p.count("material"))
  280. {
  281. pr.material.index = p.at("material").get<uint32_t>();
  282. }
  283. }
  284. }
  285. for(auto & n : J["nodes"])
  286. {
  287. auto & N = G.nodes.emplace_back();
  288. if(n.contains("position"))
  289. {
  290. N.position.x = n.at("position")[0].get<float>();
  291. N.position.y = n.at("position")[1].get<float>();
  292. N.position.z = n.at("position")[2].get<float>();
  293. }
  294. if(n.contains("rotation"))
  295. {
  296. N.rotation.x = n.at("rotation")[0].get<float>();
  297. N.rotation.y = n.at("rotation")[1].get<float>();
  298. N.rotation.z = n.at("rotation")[2].get<float>();
  299. N.rotation.w = n.at("rotation")[3].get<float>();
  300. }
  301. if(n.contains("scale"))
  302. {
  303. N.scale.x = n.at("scale")[0].get<float>();
  304. N.scale.y = n.at("scale")[1].get<float>();
  305. N.scale.z = n.at("scale")[2].get<float>();
  306. }
  307. if(n.contains("children"))
  308. {
  309. N.children = n.at("children").get< std::vector<uint32_t> >();
  310. }
  311. if(n.contains("mesh"))
  312. {
  313. N.mesh.index = n.at("mesh").get< uint32_t >();
  314. }
  315. }
  316. for(auto & t : J["samplers"])
  317. {
  318. auto & S = G.samplers.emplace_back();
  319. if(t.contains("magFilter")) S.magFilter = t["magFilter"].get<int>();
  320. if(t.contains("minFilter")) S.magFilter = t["minFilter"].get<int>();
  321. if(t.contains("wrapS")) S.wrapS = t["wrapS"].get<int>();
  322. if(t.contains("wrapT")) S.wrapT = t["wrapT"].get<int>();
  323. }
  324. for(auto & t : J["textures"])
  325. {
  326. auto & S = G.textures.emplace_back();
  327. if(t.contains("sampler")) S.sampler.index = t["sampler"].get<uint32_t>();
  328. if(t.contains("source")) S.source .index = t["source"].get<uint32_t>();
  329. }
  330. for(auto & t : J["materials"])
  331. {
  332. auto & S = G.materials.emplace_back();
  333. //json jj;
  334. #define _GETIF(VAR, jj, prop)\
  335. if(jj.contains(#prop))\
  336. {\
  337. VAR = jj[#prop].get< decltype(VAR) >();\
  338. }\
  339. if(t.contains("normalTexture"))
  340. {
  341. auto & normalTexture = t["normalTexture"];
  342. _GETIF(S.normalTexture.index.index , normalTexture, "index" );
  343. _GETIF(S.normalTexture.texCoord , normalTexture, "texCoord");
  344. _GETIF(S.normalTexture.scale , normalTexture, "scale" );
  345. }
  346. if(t.contains("occlusionTexture"))
  347. {
  348. auto & normalTexture = t["occlusionTexture"];
  349. _GETIF(S.occlusionTexture.index.index , normalTexture, "index" );
  350. _GETIF(S.occlusionTexture.texCoord , normalTexture, "texCoord");
  351. _GETIF(S.occlusionTexture.strength , normalTexture, "strength" );
  352. }
  353. if(t.contains("emissiveFactor"))
  354. {
  355. auto & bc = t["emissiveFactor"];
  356. S.emissiveFactor = glm::vec3(bc[0],bc[1],bc[2]);
  357. }
  358. if(t.contains("pbrMetallicRoughness"))
  359. {
  360. auto & pbrMetallicRoughness = t["pbrMetallicRoughness"];
  361. if(pbrMetallicRoughness.contains("baseColorFactor"))
  362. {
  363. auto & bc = pbrMetallicRoughness["baseColorFactor"];
  364. S.pbrMetallicRoughness.baseColorFactor = glm::vec4(bc[0],bc[1],bc[2],bc[3]);
  365. }
  366. if(pbrMetallicRoughness.contains("baseColorTexture"))
  367. {
  368. auto &bc = pbrMetallicRoughness["baseColorTexture"];
  369. S.pbrMetallicRoughness.baseColorTexture.index.index = bc.value("index", 0u);//bc["index"];
  370. S.pbrMetallicRoughness.baseColorTexture.texCoord = bc.value("texCoord", 0);
  371. }
  372. if(pbrMetallicRoughness.contains("metallicRoughnessTexture"))
  373. {
  374. auto &bc = pbrMetallicRoughness["metallicRoughnessTexture"];
  375. S.pbrMetallicRoughness.metallicRoughnessTexture.index.index = bc.value("index", 0u);
  376. S.pbrMetallicRoughness.metallicRoughnessTexture.texCoord = bc.value("texCoord", 0);
  377. }
  378. if(t.contains("emissiveTexture"))
  379. {
  380. auto &bc = t["emissiveTexture"];
  381. S.emissiveTexture.index.index = bc.value("index", 0u);
  382. S.emissiveTexture.texCoord = bc.value("texCoord", 0);
  383. }
  384. if(t.contains("occlusionTexture"))
  385. {
  386. auto &bc = t["occlusionTexture"];
  387. S.occlusionTexture.index.index = bc.value("index", 0u);
  388. S.occlusionTexture.texCoord = bc.value("texCoord", 0);
  389. S.occlusionTexture.strength = bc.value("strength", 1.f);
  390. }
  391. S.pbrMetallicRoughness.metallicFactor = pbrMetallicRoughness.value("metallicFactor", 1.0f);
  392. S.pbrMetallicRoughness.roughnessFactor = pbrMetallicRoughness.value("roughnessFactor", 1.0f);
  393. if(t.contains("normalTexture"))
  394. {
  395. auto &bc = t["normalTexture"];
  396. S.normalTexture.index.index = bc.value("index", 0u);
  397. S.normalTexture.texCoord = bc.value("texCoord", 0);
  398. }
  399. S.alphaCutOff = t.value("alphaCutOff", 0.5f);
  400. S.alphaMode = t.value("alphaMode", std::string("OPAQUE"));
  401. S.doubleSided = t.value("doubleSided", false);
  402. }
  403. }
  404. return G;
  405. }
  406. }
  407. #endif