feat: loading skeleton from vcm & add 'squash' model asset parameter

This commit is contained in:
MihailRis 2026-01-16 02:24:00 +03:00
parent 42c4716be2
commit 19e180ddbb
3 changed files with 50 additions and 6 deletions

View file

@ -181,6 +181,12 @@ void AssetsLoader::processPreload(
config = std::make_shared<PostEffectCfg>(advanced); config = std::make_shared<PostEffectCfg>(advanced);
break; break;
} }
case AssetType::MODEL: {
bool squashed = false;
map.at("squash").get(squashed);
config = std::make_shared<ModelCfg>(squashed);
break;
}
default: default:
break; break;
} }
@ -214,6 +220,7 @@ void AssetsLoader::processPreloadConfig(const io::path& file) {
processPreloadList(AssetType::SOUND, root["sounds"]); processPreloadList(AssetType::SOUND, root["sounds"]);
processPreloadList(AssetType::MODEL, root["models"]); processPreloadList(AssetType::MODEL, root["models"]);
processPreloadList(AssetType::POST_EFFECT, root["post-effects"]); processPreloadList(AssetType::POST_EFFECT, root["post-effects"]);
processPreloadList(AssetType::SKELETON, root["skeletons"]);
// layouts are loaded automatically // layouts are loaded automatically
} }

View file

@ -59,6 +59,12 @@ struct PostEffectCfg : AssetCfg {
PostEffectCfg(bool advanced) : advanced(advanced) {} PostEffectCfg(bool advanced) : advanced(advanced) {}
}; };
struct ModelCfg : AssetCfg {
bool squashed;
ModelCfg(bool squashed) : squashed(squashed) {}
};
using aloader_func = std::function< using aloader_func = std::function<
assetload:: assetload::
postfunc(AssetsLoader*, const ResPaths&, const std::string&, const std::string&, std::shared_ptr<AssetCfg>)>; postfunc(AssetsLoader*, const ResPaths&, const std::string&, const std::string&, std::shared_ptr<AssetCfg>)>;

View file

@ -325,8 +325,10 @@ assetload::postfunc assetload::model(
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& const std::shared_ptr<AssetCfg>& config
) { ) {
auto cfg = std::dynamic_pointer_cast<ModelCfg>(config);
auto path = paths.find(file + ".vec3"); auto path = paths.find(file + ".vec3");
if (io::exists(path)) { if (io::exists(path)) {
auto bytes = io::read_bytes_buffer(path); auto bytes = io::read_bytes_buffer(path);
@ -382,11 +384,40 @@ assetload::postfunc assetload::model(
auto text = io::read_string(path); auto text = io::read_string(path);
try { try {
auto vcmModel = vcm::parse(path.string(), text, path.extension() == ".xml"); auto vcmModel = vcm::parse(path.string(), text, path.extension() == ".xml");
auto model = std::make_unique<model::Model>(std::move(vcmModel.squash())).release();
return [=](Assets* assets) { assert(vcmModel.parts.size() > 0);
request_textures(loader, *model);
assets->store(std::unique_ptr<model::Model>(model), name); if (vcmModel.parts.size() == 1 || (cfg && cfg->squashed)) {
}; auto modelPtr = std::make_unique<model::Model>(std::move(vcmModel.squash())).release();
return [=](Assets* assets) {
auto model = std::unique_ptr<model::Model>(modelPtr);
request_textures(loader, *model);
assets->store(std::move(model), name);
logger.info() << "store model " << util::quote(name);
};
} else {
auto vcmModelPtr = std::make_unique<vcm::VcmModel>(std::move(vcmModel)).release();
return [=](Assets* assets) {
auto vcmModel = std::unique_ptr<vcm::VcmModel>(vcmModelPtr);
for (auto& [partName, model] : vcmModel->parts) {
auto fullName = name + "." + partName;
logger.info()
<< "store model part " << util::quote(partName)
<< " as " << util::quote(fullName);
assets->store(
std::make_unique<model::Model>(std::move(model)),
fullName
);
}
logger.info() << "store skeleton " << util::quote(name);
assets->store<rigging::SkeletonConfig>(
std::make_unique<rigging::SkeletonConfig>(
std::move(*vcmModel->skeleton)
),
name
);
};
}
} catch (const parsing_error& err) { } catch (const parsing_error& err) {
std::cerr << err.errorLog() << std::endl; std::cerr << err.errorLog() << std::endl;
throw; throw;