123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #include <iostream>
- #include <fstream>
- #define TINYGLTF_IMPLEMENTATION
- #define STB_IMAGE_IMPLEMENTATION
- #define STB_IMAGE_WRITE_IMPLEMENTATION
- #include "b3dm_loader.h"
- MeshInfo* b3dm_loader::VisitorPrimitive(const tinygltf::Model& model, const Primitive& primitive)
- {
- MeshInfo* meshInfo = new MeshInfo();
- //顶点索引
- const tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
- const tinygltf::BufferView& indexBufView = model.bufferViews[indexAccessor.bufferView];
- const tinygltf::Buffer& indexBuf = model.buffers[indexBufView.buffer];
- std::cout << indexAccessor.componentType << " " << indexAccessor.type << std::endl;
- int faceCount = indexAccessor.count;
- unsigned int* faceIndex = new unsigned int[faceCount];
- memcpy(faceIndex, &indexBuf.data[0] + indexBufView.byteOffset + indexAccessor.byteOffset, faceCount * sizeof(unsigned int));
- /*meshInfo->mTriangles = new unsigned int[faceCount];
- for (int i = 0; i < faceCount; ++i)
- {
- meshInfo->mTriangles[i] = faceIndex[i];
- }*/
- meshInfo->mTriangles = faceIndex;
- meshInfo->mTriangleCount = faceCount;
- std::cout << "faceIndex count " << indexAccessor.count << std::endl;
- //顶点,uv
- float* pointArr = NULL;
- float* textureArr = NULL;
- int pointCount = 0;
- int texCount = 0;
- std::map<std::string, int>::const_iterator it(primitive.attributes.begin());
- std::map<std::string, int>::const_iterator itEnd(primitive.attributes.end());
- for (; it != itEnd; it++)
- {
- const tinygltf::Accessor& accessor = model.accessors[it->second];
- const tinygltf::BufferView& bufferView_pt = model.bufferViews[accessor.bufferView];
- const tinygltf::Buffer& buffer_pt = model.buffers[bufferView_pt.buffer];
- int count = tinygltf::GetNumComponentsInType(accessor.type);
- if (it->first.compare("POSITION") == 0)
- {
- pointCount = accessor.count * count;
- pointArr = new float[pointCount];
- memcpy(pointArr, &buffer_pt.data[0] + bufferView_pt.byteOffset + accessor.byteOffset, pointCount * sizeof(float));
- meshInfo->mVertexCount = accessor.count;
- meshInfo->mVertexs = pointArr;
- }
- else if (it->first.compare("TEXCOORD_0") == 0)
- {
- texCount = accessor.count * count;
- textureArr = new float[texCount];
- memcpy(textureArr, &buffer_pt.data[0] + bufferView_pt.byteOffset + accessor.byteOffset, texCount * sizeof(float));
- meshInfo->mTexCoordCount = accessor.count;
- meshInfo->mTexCoords = textureArr;
- }
- }
- //纹理数据
- tinygltf::Material mat = model.materials[primitive.material];
- int texIndex = mat.pbrMetallicRoughness.baseColorTexture.index;
- Texture texture = model.textures[texIndex];
- Image image = model.images[texture.source];
- std::cout << image.width << " " << image.height << " " << image.image.size() << " " << image.mimeType << std::endl;
- meshInfo->mImageResolutionS = image.width;
- meshInfo->mImageResolutionT = image.height;
- meshInfo->mImageSize = image.image.size();
- meshInfo->mImageData = new unsigned char[image.image.size()];
- memcpy(meshInfo->mImageData, &image.image[0], image.image.size());
- return meshInfo;
- }
- void b3dm_loader::VisitorModel(const tinygltf::Model& model)
- {
- Scene curScene = model.scenes[0];
- for (int i = 0; i < (int)curScene.nodes.size(); ++i)
- {
- int nodeIndex = curScene.nodes[i];
- Node node = model.nodes[nodeIndex];
- int meshIndex = curScene.nodes[i];
- Mesh mesh = model.meshes[meshIndex];
- for (int j = 0; j < (int)mesh.primitives.size(); ++j)
- {
- MeshInfo* meshInfo = VisitorPrimitive(model, mesh.primitives[j]);
- mMeshInfos.push_back(meshInfo);
- }
- }
- }
- int ReadB3dmHeaderLength(const std::string& filename)
- {
- std::ifstream f(filename.c_str(), std::ios::binary);
- if (!f)
- {
- return 0;
- }
- f.seekg(0, f.beg);
- std::vector<char> file_data(28);
- f.read(&file_data.at(0), static_cast<std::streamsize>(28));
- if (file_data.empty())
- return 0;
- int header[7];
- ::memcpy(header, file_data.data(), 7 * sizeof(int));
- int len_featureTable = header[3];
- return 7 * sizeof(int) + header[3] + header[4] + header[5] + header[6];
- }
- b3dm_loader* b3dm_loader::LoadB3dmFromFile(const std::string& filename)
- {
- std::ifstream f(filename.c_str(), std::ios::binary);
- if (!f)
- {
- std::cout << "Failed to open file: " << filename << std::endl;
- return nullptr;
- }
- f.seekg(0, f.end);
- size_t sz = static_cast<size_t>(f.tellg());
- int len_b3dm = ReadB3dmHeaderLength(filename);
- int gltfSize = sz - len_b3dm;
- std::vector<char> buf(gltfSize);
- f.seekg(len_b3dm, f.beg);
- f.read(&buf.at(0), static_cast<std::streamsize>(gltfSize));
- f.close();
- Model model;
- TinyGLTF loader;
- std::string err;
- std::string warn;
- std::string basedir;
- unsigned char* data = reinterpret_cast<unsigned char*>(&buf.at(0));
- int length = static_cast<unsigned int>(buf.size());
- bool ret = loader.LoadBinaryFromMemory(&model, &err, &warn, data, length, basedir);
- //loader.WriteGltfSceneToFile(&model, "./test.gltf");
- /*std::ofstream fout;
- fout.open("./test.glb", std::ios::app | std::ios::binary);
- fout.write(&buf.at(0), gltfSize);
- fout.close();*/
- if (!ret)
- {
- std::cout << "Failed to parse b3dm " << err << std::endl;
- return nullptr;
- }
- else
- {
- std::cout << "Success to parse b3dm " << sz << std::endl;
- b3dm_loader* loader = new b3dm_loader();
- loader->VisitorModel(model);
- return loader;
- }
- }
|