Closed EvilTrev closed 1 year ago
Could you please check what the raw string contains? Use fastgltf::URI::raw()
, which will return the raw URI string as parsed from the glTF. Also can I please see the output of path() and perhaps the other views?
Also not sure but you could try and put the std::string on the line before the printf to avoid any lifetime issues?
Very interesting... the value of raw() is a string view with the correct string (Sponza.bin), however the string view returned by .path() is garbage (it contains "D]\U00000002\0`\0\0N\xe3Y"). The std::string created from path() ends up reading "D]" and a block of tofu once printed.
auto& buffers = model->buffers;
for ( auto& buffer : buffers )
{
if ( std::holds_alternative<fastgltf::sources::URI>( buffer.data ) )
{
const auto& data = std::get<fastgltf::sources::URI>( buffer.data );
if ( data.uri.isLocalPath() )
{
auto path = data.uri.path();
auto uri = std::string( path );
auto raw = data.uri.raw();
printf( "Corrupt: %s\n", uri.c_str() );
int breakpoint = 1;
}
}
}
So if I update my code to use .raw() and append the path of the model file itself (which is now missing from buffer paths), I'm running again. I can't seem to use .path() or .fspath().
To be clear on the path string changes, in the past if I loaded say "models\Sponza.gltf" and it referenced "Sponza.bin" it would return a path that included "models\", now it just returns the filename and no folder prefix. Not a deal breaker, might even prefer it as it is now, it just seemed a bit inconsistent.
I just checked the OpenGL example's code: https://github.com/spnda/fastgltf/blob/b0277a50eebfc8fdd8d7604096b8dbae42274954/examples/gl_viewer/gl_viewer.cpp#L490-L494
And I tried to load Sponza (like you seem to have tried) locally (Windows 11, VS 17.5.3) and it does run for me, meaning that all URIs are parsed correctly. What platform are you running on, so I could perhaps figure out more about this issue?
macOS ventura 13.2.1
So you're using AppleClang? (that was the important part). I'm gonna test my changes on my Mac to see if it's some issue with the compiler.
Ok I've tracked it down to the fact that AppleClang's libc++ uses a much larger buffer for small string optimisation. Therefore, the string was properly moved but the pointer couldn't just be copied because the string wasn't stored on the heap. I have now updated the constructors to properly adjust the string views again in the case a copy did happen due to the string being small enough to fit into the small string buffer on the stack. Will push a fix very soon.
Tricky! Thanks for digging!
I'm not entirely sure why yet, but I just updated to the latest and retrofitted around the new URI changes to find that if I don't specify fastgltf::Options::LoadExternalBuffers as an option, when I parse buffers myself (to load manually) I get URIs that claim to be valid local file paths - but they contain garbage strings. Nothing else really going on that should be able to corrupt anything on my end.
Will let you know if I find out more, perhaps I am missing something or making an assumption? My debug code is something along the lines of this: