repair gltf_viewer drag&drop
Drag and dropping a gltf folder was broken: - the handle didn't find the gltf file on drag&drop - the ResourceLoader cached the asset path - don't exit(1) when drag&dropping an invalid file
This commit is contained in:
committed by
Mathias Agopian
parent
46e6664c3d
commit
7d694ee85e
@@ -69,9 +69,12 @@ class UTILS_PUBLIC ResourceLoader {
|
||||
public:
|
||||
using BufferDescriptor = filament::backend::BufferDescriptor;
|
||||
|
||||
ResourceLoader(const ResourceConfiguration& config);
|
||||
explicit ResourceLoader(const ResourceConfiguration& config);
|
||||
~ResourceLoader();
|
||||
|
||||
|
||||
void setConfiguration(const ResourceConfiguration& config);
|
||||
|
||||
/**
|
||||
* Feeds the binary content of an external resource into the loader's URI cache.
|
||||
*
|
||||
|
||||
@@ -74,15 +74,15 @@ enum class CacheResult {
|
||||
};
|
||||
|
||||
struct ResourceLoader::Impl {
|
||||
Impl(const ResourceConfiguration& config) :
|
||||
explicit Impl(const ResourceConfiguration& config) :
|
||||
mEngine(config.engine),
|
||||
mNormalizeSkinningWeights(config.normalizeSkinningWeights),
|
||||
mGltfPath(config.gltfPath ? config.gltfPath : ""),
|
||||
mUriDataCache(std::make_shared<UriDataCache>()) {}
|
||||
|
||||
Engine* const mEngine;
|
||||
const bool mNormalizeSkinningWeights;
|
||||
const std::string mGltfPath;
|
||||
bool mNormalizeSkinningWeights;
|
||||
std::string mGltfPath;
|
||||
|
||||
// User-provided resource data with URI string keys, populated with addResourceData().
|
||||
// This is used on platforms without traditional file systems, such as Android, iOS, and WebGL.
|
||||
@@ -320,6 +320,11 @@ ResourceLoader::~ResourceLoader() {
|
||||
delete pImpl;
|
||||
}
|
||||
|
||||
void ResourceLoader::setConfiguration(const ResourceConfiguration& config) {
|
||||
pImpl->mNormalizeSkinningWeights = config.normalizeSkinningWeights;
|
||||
pImpl->mGltfPath = config.gltfPath;
|
||||
}
|
||||
|
||||
void ResourceLoader::addResourceData(const char* uri, BufferDescriptor&& buffer) {
|
||||
pImpl->addResourceData(uri, std::move(buffer));
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
#include <imgui.h>
|
||||
#include <filagui/ImGuiExtensions.h>
|
||||
|
||||
#include <cgltf.h>
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -485,6 +487,57 @@ static void onClick(App& app, View* view, ImVec2 pos) {
|
||||
});
|
||||
}
|
||||
|
||||
static utils::Path getPathForAsset(std::string_view string) {
|
||||
utils::Path filename{ string };
|
||||
if (!filename.exists()) {
|
||||
std::cerr << "file " << filename << " not found!" << std::endl;
|
||||
return {};
|
||||
}
|
||||
if (filename.isDirectory()) {
|
||||
auto files = filename.listContents();
|
||||
for (const auto& file: files) {
|
||||
if (file.getExtension() == "gltf" || file.getExtension() == "glb") {
|
||||
filename = file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (filename.isDirectory()) {
|
||||
std::cerr << "no glTF file found in " << filename << std::endl;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
static bool checkAsset(const utils::Path& filename) {
|
||||
// Peek at the file size to allow pre-allocation.
|
||||
long const contentSize = static_cast<long>(getFileSize(filename.c_str()));
|
||||
if (contentSize <= 0) {
|
||||
std::cerr << "Unable to open " << filename << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Consume the glTF file.
|
||||
std::ifstream in(filename.c_str(), std::ifstream::binary | std::ifstream::in);
|
||||
std::vector<uint8_t> buffer(static_cast<unsigned long>(contentSize));
|
||||
if (!in.read((char*) buffer.data(), contentSize)) {
|
||||
std::cerr << "Unable to read " << filename << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the glTF file and create Filament entities.
|
||||
cgltf_options options{};
|
||||
cgltf_data* sourceAsset;
|
||||
cgltf_result result = cgltf_parse(&options, buffer.data(), contentSize, &sourceAsset);
|
||||
if (result != cgltf_result_success) {
|
||||
slog.e << "Unable to parse glTF file." << io::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
App app;
|
||||
|
||||
@@ -496,24 +549,10 @@ int main(int argc, char** argv) {
|
||||
utils::Path filename;
|
||||
int const num_args = argc - optionIndex;
|
||||
if (num_args >= 1) {
|
||||
filename = argv[optionIndex];
|
||||
if (!filename.exists()) {
|
||||
std::cerr << "file " << filename << " not found!" << std::endl;
|
||||
filename = getPathForAsset(argv[optionIndex]);
|
||||
if (filename.isEmpty()) {
|
||||
return 1;
|
||||
}
|
||||
if (filename.isDirectory()) {
|
||||
auto files = filename.listContents();
|
||||
for (const auto& file : files) {
|
||||
if (file.getExtension() == "gltf" || file.getExtension() == "glb") {
|
||||
filename = file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (filename.isDirectory()) {
|
||||
std::cerr << "no glTF file found in " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto loadAsset = [&app](const utils::Path& filename) {
|
||||
@@ -534,14 +573,14 @@ int main(int argc, char** argv) {
|
||||
|
||||
// Parse the glTF file and create Filament entities.
|
||||
app.asset = app.assetLoader->createAsset(buffer.data(), buffer.size());
|
||||
app.instance = app.asset->getInstance();
|
||||
buffer.clear();
|
||||
buffer.shrink_to_fit();
|
||||
|
||||
if (!app.asset) {
|
||||
std::cerr << "Unable to parse " << filename << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
app.instance = app.asset->getInstance();
|
||||
buffer.clear();
|
||||
buffer.shrink_to_fit();
|
||||
};
|
||||
|
||||
auto loadResources = [&app] (const utils::Path& filename) {
|
||||
@@ -559,6 +598,8 @@ int main(int argc, char** argv) {
|
||||
app.resourceLoader->addTextureProvider("image/png", app.stbDecoder);
|
||||
app.resourceLoader->addTextureProvider("image/jpeg", app.stbDecoder);
|
||||
app.resourceLoader->addTextureProvider("image/ktx2", app.ktxDecoder);
|
||||
} else {
|
||||
app.resourceLoader->setConfiguration(configuration);
|
||||
}
|
||||
|
||||
if (!app.resourceLoader->asyncBeginLoad(app.asset)) {
|
||||
@@ -1021,14 +1062,19 @@ int main(int argc, char** argv) {
|
||||
filamentApp.animate(animate);
|
||||
filamentApp.resize(resize);
|
||||
|
||||
filamentApp.setDropHandler([&] (std::string_view path) {
|
||||
app.resourceLoader->asyncCancelLoad();
|
||||
app.resourceLoader->evictResourceData();
|
||||
app.viewer->removeAsset();
|
||||
app.assetLoader->destroyAsset(app.asset);
|
||||
loadAsset(path);
|
||||
loadResources(path);
|
||||
app.viewer->setAsset(app.asset, app.instance);
|
||||
filamentApp.setDropHandler([&](std::string_view path) {
|
||||
utils::Path const filename = getPathForAsset(path);
|
||||
if (!filename.isEmpty()) {
|
||||
if (checkAsset(filename)) {
|
||||
app.resourceLoader->asyncCancelLoad();
|
||||
app.resourceLoader->evictResourceData();
|
||||
app.viewer->removeAsset();
|
||||
app.assetLoader->destroyAsset(app.asset);
|
||||
loadAsset(filename);
|
||||
loadResources(filename);
|
||||
app.viewer->setAsset(app.asset, app.instance);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
filamentApp.run(app.config, setup, cleanup, gui, preRender, postRender);
|
||||
|
||||
Reference in New Issue
Block a user