@@ -93,6 +93,35 @@ struct GLTFData
9393 return bufferView;
9494 }
9595
96+ std::shared_ptr<BufferViewData> AddBufferViewForFile (BufferData &buffer, const std::string &filename)
97+ {
98+ // see if we've already created a BufferViewData for this precise file
99+ auto iter = filenameToBufferView.find (filename);
100+ if (iter != filenameToBufferView.end ()) {
101+ return iter->second ;
102+ }
103+
104+ std::shared_ptr<BufferViewData> result;
105+ std::ifstream file (filename, std::ios::binary | std::ios::ate);
106+ if (file) {
107+ std::streamsize size = file.tellg ();
108+ file.seekg (0 , std::ios::beg);
109+
110+ std::vector<char > fileBuffer (size);
111+ if (file.read (fileBuffer.data (), size)) {
112+ result = AddRawBufferView (buffer, fileBuffer.data (), size);
113+ } else {
114+ fmt::printf (" Warning: Couldn't read %lu bytes from %s, skipping\n " , size, filename);
115+ }
116+ } else {
117+ fmt::printf (" Warning: Couldn't open texture file %s, skipping\n " , filename);
118+ }
119+ // note that we persist here not only success, but also failure, as nullptr
120+ filenameToBufferView[filename] = result;
121+ return result;
122+ }
123+
124+
96125 template <class T >
97126 std::shared_ptr<AccessorData> AddAccessorWithView (
98127 BufferViewData &bufferView, const GLType &type, const std::vector<T> &source)
@@ -164,8 +193,13 @@ struct GLTFData
164193 }
165194
166195 const bool isGlb;
196+
197+ // cache BufferViewData instances that've already been created from a given filename
198+ std::map<std::string, std::shared_ptr<BufferViewData>> filenameToBufferView;
199+
167200 std::shared_ptr<std::vector<uint8_t > > binary;
168201
202+
169203 Holder<BufferData> buffers;
170204 Holder<BufferViewData> bufferViews;
171205 Holder<AccessorData> accessors;
@@ -332,23 +366,13 @@ ModelData *Raw2Gltf(
332366
333367 ImageData *source = nullptr ;
334368 if (options.outputBinary ) {
335- std::ifstream file (texFilename, std::ios::binary | std::ios::ate);
336- if (file) {
337- std::streamsize size = file.tellg ();
338- file.seekg (0 , std::ios::beg);
339-
340- std::vector<char > fileBuffer (size);
341- if (file.read (fileBuffer.data (), size)) {
342- auto bufferView = gltf->AddRawBufferView (buffer, fileBuffer.data (), size);
343- source = new ImageData (textureName, *bufferView, " image/png" );
344- } else {
345- fmt::printf (" Warning: Couldn't read %lu bytes from %s, skipping\n " , size, texFilename.c_str ());
346- }
347- } else {
348- fmt::printf (" Warning: Couldn't open texture file %s, skipping\n " , texFilename.c_str ());
369+ auto bufferView = gltf->AddBufferViewForFile (buffer, texFilename);
370+ if (bufferView) {
371+ source = new ImageData (textureName, *bufferView, " image/png" );
349372 }
373+
350374 } else {
351- // TODO: write to buffer.bin?
375+ // TODO: don't add .ktx here; try to work out a reasonable relative path.
352376 source = new ImageData (textureName, textureName + " .ktx" );
353377 }
354378 if (!source) {
0 commit comments