b3dm_loader.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include <iostream>
  2. #include <fstream>
  3. #define TINYGLTF_IMPLEMENTATION
  4. #define STB_IMAGE_IMPLEMENTATION
  5. #define STB_IMAGE_WRITE_IMPLEMENTATION
  6. #include "b3dm_loader.h"
  7. MeshInfo* b3dm_loader::VisitorPrimitive(const tinygltf::Model& model, const Primitive& primitive)
  8. {
  9. MeshInfo* meshInfo = new MeshInfo();
  10. //顶点索引
  11. const tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
  12. const tinygltf::BufferView& indexBufView = model.bufferViews[indexAccessor.bufferView];
  13. const tinygltf::Buffer& indexBuf = model.buffers[indexBufView.buffer];
  14. std::cout << indexAccessor.componentType << " " << indexAccessor.type << std::endl;
  15. int faceCount = indexAccessor.count;
  16. unsigned int* faceIndex = new unsigned int[faceCount];
  17. memcpy(faceIndex, &indexBuf.data[0] + indexBufView.byteOffset + indexAccessor.byteOffset, faceCount * sizeof(unsigned int));
  18. /*meshInfo->mTriangles = new unsigned int[faceCount];
  19. for (int i = 0; i < faceCount; ++i)
  20. {
  21. meshInfo->mTriangles[i] = faceIndex[i];
  22. }*/
  23. meshInfo->mTriangles = faceIndex;
  24. meshInfo->mTriangleCount = faceCount;
  25. std::cout << "faceIndex count " << indexAccessor.count << std::endl;
  26. //顶点,uv
  27. float* pointArr = NULL;
  28. float* textureArr = NULL;
  29. int pointCount = 0;
  30. int texCount = 0;
  31. std::map<std::string, int>::const_iterator it(primitive.attributes.begin());
  32. std::map<std::string, int>::const_iterator itEnd(primitive.attributes.end());
  33. for (; it != itEnd; it++)
  34. {
  35. const tinygltf::Accessor& accessor = model.accessors[it->second];
  36. const tinygltf::BufferView& bufferView_pt = model.bufferViews[accessor.bufferView];
  37. const tinygltf::Buffer& buffer_pt = model.buffers[bufferView_pt.buffer];
  38. int count = tinygltf::GetNumComponentsInType(accessor.type);
  39. if (it->first.compare("POSITION") == 0)
  40. {
  41. pointCount = accessor.count * count;
  42. pointArr = new float[pointCount];
  43. memcpy(pointArr, &buffer_pt.data[0] + bufferView_pt.byteOffset + accessor.byteOffset, pointCount * sizeof(float));
  44. meshInfo->mVertexCount = accessor.count;
  45. meshInfo->mVertexs = pointArr;
  46. }
  47. else if (it->first.compare("TEXCOORD_0") == 0)
  48. {
  49. texCount = accessor.count * count;
  50. textureArr = new float[texCount];
  51. memcpy(textureArr, &buffer_pt.data[0] + bufferView_pt.byteOffset + accessor.byteOffset, texCount * sizeof(float));
  52. meshInfo->mTexCoordCount = accessor.count;
  53. meshInfo->mTexCoords = textureArr;
  54. }
  55. }
  56. //纹理数据
  57. tinygltf::Material mat = model.materials[primitive.material];
  58. int texIndex = mat.pbrMetallicRoughness.baseColorTexture.index;
  59. Texture texture = model.textures[texIndex];
  60. Image image = model.images[texture.source];
  61. std::cout << image.width << " " << image.height << " " << image.image.size() << " " << image.mimeType << std::endl;
  62. meshInfo->mImageResolutionS = image.width;
  63. meshInfo->mImageResolutionT = image.height;
  64. meshInfo->mImageSize = image.image.size();
  65. meshInfo->mImageData = new unsigned char[image.image.size()];
  66. memcpy(meshInfo->mImageData, &image.image[0], image.image.size());
  67. return meshInfo;
  68. }
  69. void b3dm_loader::VisitorModel(const tinygltf::Model& model)
  70. {
  71. Scene curScene = model.scenes[0];
  72. for (int i = 0; i < (int)curScene.nodes.size(); ++i)
  73. {
  74. int nodeIndex = curScene.nodes[i];
  75. Node node = model.nodes[nodeIndex];
  76. int meshIndex = curScene.nodes[i];
  77. Mesh mesh = model.meshes[meshIndex];
  78. for (int j = 0; j < (int)mesh.primitives.size(); ++j)
  79. {
  80. MeshInfo* meshInfo = VisitorPrimitive(model, mesh.primitives[j]);
  81. mMeshInfos.push_back(meshInfo);
  82. }
  83. }
  84. }
  85. int ReadB3dmHeaderLength(const std::string& filename)
  86. {
  87. std::ifstream f(filename.c_str(), std::ios::binary);
  88. if (!f)
  89. {
  90. return 0;
  91. }
  92. f.seekg(0, f.beg);
  93. std::vector<char> file_data(28);
  94. f.read(&file_data.at(0), static_cast<std::streamsize>(28));
  95. if (file_data.empty())
  96. return 0;
  97. int header[7];
  98. ::memcpy(header, file_data.data(), 7 * sizeof(int));
  99. int len_featureTable = header[3];
  100. return 7 * sizeof(int) + header[3] + header[4] + header[5] + header[6];
  101. }
  102. b3dm_loader* b3dm_loader::LoadB3dmFromFile(const std::string& filename)
  103. {
  104. std::ifstream f(filename.c_str(), std::ios::binary);
  105. if (!f)
  106. {
  107. std::cout << "Failed to open file: " << filename << std::endl;
  108. return nullptr;
  109. }
  110. f.seekg(0, f.end);
  111. size_t sz = static_cast<size_t>(f.tellg());
  112. int len_b3dm = ReadB3dmHeaderLength(filename);
  113. int gltfSize = sz - len_b3dm;
  114. std::vector<char> buf(gltfSize);
  115. f.seekg(len_b3dm, f.beg);
  116. f.read(&buf.at(0), static_cast<std::streamsize>(gltfSize));
  117. f.close();
  118. Model model;
  119. TinyGLTF loader;
  120. std::string err;
  121. std::string warn;
  122. std::string basedir;
  123. unsigned char* data = reinterpret_cast<unsigned char*>(&buf.at(0));
  124. int length = static_cast<unsigned int>(buf.size());
  125. bool ret = loader.LoadBinaryFromMemory(&model, &err, &warn, data, length, basedir);
  126. //loader.WriteGltfSceneToFile(&model, "./test.gltf");
  127. /*std::ofstream fout;
  128. fout.open("./test.glb", std::ios::app | std::ios::binary);
  129. fout.write(&buf.at(0), gltfSize);
  130. fout.close();*/
  131. if (!ret)
  132. {
  133. std::cout << "Failed to parse b3dm " << err << std::endl;
  134. return nullptr;
  135. }
  136. else
  137. {
  138. std::cout << "Success to parse b3dm " << sz << std::endl;
  139. b3dm_loader* loader = new b3dm_loader();
  140. loader->VisitorModel(model);
  141. return loader;
  142. }
  143. }