Skip to content

Commit 443243a

Browse files
author
Par Winzell
committed
Only ever create one BufferViewData per file.
It is not uncommon for multiple logical textures in an FBX to reference the same filename. Each such filename should yield one buffer view only, and all sharing textures should reference it.
1 parent bc80321 commit 443243a

File tree

1 file changed

+39
-15
lines changed

1 file changed

+39
-15
lines changed

src/Raw2Gltf.cpp

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)