I just wrote these template methods:
template<class T>
bool ImportAndSaveFile(const std::string& file, const std::string& target, bool compress,
bs::SPtr<typename OptionsCreator<T>::OptionsType> options =
OptionsCreator<T>::Create())
{
auto resource = bs::gImporter().import<T>(file.c_str(), options);
if(resource) {
bs::gResources().save(resource, target.c_str(), true, compress);
return true;
}
return false;
}
template<class T>
bool MultiResourceSaveSingle(const bs::Vector<bs::SubResource>& resources,
size_t& resourceCounter, const std::vector<std::string>& targets, bool compress)
{
if(resourceCounter >= resources.size()) {
LOG_ERROR("Importer: ran out of resources in multi resource import");
return false;
}
if(resourceCounter >= targets.size()) {
LOG_ERROR("Importer: ran out of targets in multi resource import");
return false;
}
auto resource = bs::static_resource_cast<T>(resources[resourceCounter].value);
if(resource) {
bs::gResources().save(resource, targets[resourceCounter].c_str(), true, compress);
} else {
LOG_ERROR("Importer: converting multi import resource failed, index: " +
std::to_string(resourceCounter) +
", name: " + resources[resourceCounter].name.c_str());
return false;
}
++resourceCounter;
return true;
}
template<class T>
bool MultiResourceSaveHelper(const bs::Vector<bs::SubResource>& resources,
size_t& resourceCounter, const std::vector<std::string>& targets, bool compress)
{
if(resourceCounter + 1 < targets.size()) {
LOG_WARNING("Importer: excess targets provided for multi resource import");
}
return MultiResourceSaveSingle<T>(resources, resourceCounter, targets, compress);
}
template<class T, class SecondT, class... ExtraT>
bool MultiResourceSaveHelper(const bs::Vector<bs::SubResource>& resources,
size_t& resourceCounter, const std::vector<std::string>& targets, bool compress)
{
if(!MultiResourceSaveSingle<T>(resources, resourceCounter, targets, compress))
return false;
return MultiResourceSaveHelper<SecondT, ExtraT...>(
resources, resourceCounter, targets, compress);
}
template<class T, class... AdditionalTypes>
bool ImportMultiResource(const std::string& file, const std::vector<std::string>& targets,
bool compress, bs::SPtr<typename OptionsCreator<T>::OptionsType> options)
{
auto resources = bs::gImporter().importAll(file.c_str(), options);
if(resources->entries.size() == 0)
return false;
size_t resourceCounter = 0;
return MultiResourceSaveHelper<T, AdditionalTypes...>(
resources->entries, resourceCounter, targets, compress);
}
template<class T>
bool ImportAndSaveWithOptions(const std::string& file, const std::string& target,
bool compress, const Json::Value& options)
{
auto importOptions = OptionsCreator<T>::Create();
std::vector<std::string> targets;
targets.push_back(target);
// Check for options and perform multi-imports
if constexpr(std::is_same_v<T, bs::Mesh>) {
if(options["animation"]) {
importOptions->importAnimation = true;
bool valid = false;
for(const auto& animation : options["animation"]) {
// TODO: error checking
const auto type = animation["type"].asString();
const auto target = Importer::GetTargetWithoutSingleCheck(
animation["target"].asString(), Importer::FileType::Model);
targets.push_back(target);
if(type == "skin") {
importOptions->importSkin = true;
} else {
LOG_ERROR("Importer: unknown animation type: " + type);
return false;
}
// importOptions->setImportBlendShapes(true);
LOG_INFO("Animation target is '" + target + "'");
valid = true;
}
if(!valid) {
LOG_ERROR("Importer: animation definition is invalid");
return false;
}
return ImportMultiResource<T, bs::AnimationClip>(
file, targets, compress, importOptions);
}
}
// Non-multi import
return ImportAndSaveFile<T>(file, target, compress, importOptions);
}