diff --git a/src/Raw2Gltf.cpp b/src/Raw2Gltf.cpp index 2ea7465..4c9a87a 100644 --- a/src/Raw2Gltf.cpp +++ b/src/Raw2Gltf.cpp @@ -93,6 +93,35 @@ struct GLTFData return bufferView; } + std::shared_ptr AddBufferViewForFile(BufferData &buffer, const std::string &filename) + { + // see if we've already created a BufferViewData for this precise file + auto iter = filenameToBufferView.find(filename); + if (iter != filenameToBufferView.end()) { + return iter->second; + } + + std::shared_ptr result; + std::ifstream file(filename, std::ios::binary | std::ios::ate); + if (file) { + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + + std::vector fileBuffer(size); + if (file.read(fileBuffer.data(), size)) { + result = AddRawBufferView(buffer, fileBuffer.data(), size); + } else { + fmt::printf("Warning: Couldn't read %lu bytes from %s, skipping\n", size, filename); + } + } else { + fmt::printf("Warning: Couldn't open texture file %s, skipping\n", filename); + } + // note that we persist here not only success, but also failure, as nullptr + filenameToBufferView[filename] = result; + return result; + } + + template std::shared_ptr AddAccessorWithView( BufferViewData &bufferView, const GLType &type, const std::vector &source) @@ -164,8 +193,13 @@ struct GLTFData } const bool isGlb; + + // cache BufferViewData instances that've already been created from a given filename + const std::map> filenameToBufferView; + std::shared_ptr > binary; + Holder buffers; Holder bufferViews; Holder accessors; @@ -332,23 +366,13 @@ ModelData *Raw2Gltf( ImageData *source = nullptr; if (options.outputBinary) { - std::ifstream file(texFilename, std::ios::binary | std::ios::ate); - if (file) { - std::streamsize size = file.tellg(); - file.seekg(0, std::ios::beg); - - std::vector fileBuffer(size); - if (file.read(fileBuffer.data(), size)) { - auto bufferView = gltf->AddRawBufferView(buffer, fileBuffer.data(), size); - source = new ImageData(textureName, *bufferView, "image/png"); - } else { - fmt::printf("Warning: Couldn't read %lu bytes from %s, skipping\n", size, texFilename.c_str()); - } - } else { - fmt::printf("Warning: Couldn't open texture file %s, skipping\n", texFilename.c_str()); + auto bufferView = gltf->AddBufferViewForFile(buffer, texFilename); + if (bufferView) { + source = new ImageData(textureName, *bufferView, "image/png"); } + } else { - // TODO: write to buffer.bin? + // TODO: don't add .ktx here; try to work out a reasonable relative path. source = new ImageData(textureName, textureName + ".ktx"); } if (!source) {