From 19e180ddbb07d6963f0c67db5a778f0c47b79a5a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 16 Jan 2026 02:24:00 +0300 Subject: [PATCH] feat: loading skeleton from vcm & add 'squash' model asset parameter --- src/assets/AssetsLoader.cpp | 7 ++++++ src/assets/AssetsLoader.hpp | 6 +++++ src/assets/assetload_funcs.cpp | 43 +++++++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index 9729eedb8..cec4e0887 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -181,6 +181,12 @@ void AssetsLoader::processPreload( config = std::make_shared(advanced); break; } + case AssetType::MODEL: { + bool squashed = false; + map.at("squash").get(squashed); + config = std::make_shared(squashed); + break; + } default: break; } @@ -214,6 +220,7 @@ void AssetsLoader::processPreloadConfig(const io::path& file) { processPreloadList(AssetType::SOUND, root["sounds"]); processPreloadList(AssetType::MODEL, root["models"]); processPreloadList(AssetType::POST_EFFECT, root["post-effects"]); + processPreloadList(AssetType::SKELETON, root["skeletons"]); // layouts are loaded automatically } diff --git a/src/assets/AssetsLoader.hpp b/src/assets/AssetsLoader.hpp index e35a78ce2..78152b6ac 100644 --- a/src/assets/AssetsLoader.hpp +++ b/src/assets/AssetsLoader.hpp @@ -59,6 +59,12 @@ struct PostEffectCfg : AssetCfg { PostEffectCfg(bool advanced) : advanced(advanced) {} }; +struct ModelCfg : AssetCfg { + bool squashed; + + ModelCfg(bool squashed) : squashed(squashed) {} +}; + using aloader_func = std::function< assetload:: postfunc(AssetsLoader*, const ResPaths&, const std::string&, const std::string&, std::shared_ptr)>; diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index f739aee7c..4110278c0 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -325,8 +325,10 @@ assetload::postfunc assetload::model( const ResPaths& paths, const std::string& file, const std::string& name, - const std::shared_ptr& + const std::shared_ptr& config ) { + auto cfg = std::dynamic_pointer_cast(config); + auto path = paths.find(file + ".vec3"); if (io::exists(path)) { auto bytes = io::read_bytes_buffer(path); @@ -382,11 +384,40 @@ assetload::postfunc assetload::model( auto text = io::read_string(path); try { auto vcmModel = vcm::parse(path.string(), text, path.extension() == ".xml"); - auto model = std::make_unique(std::move(vcmModel.squash())).release(); - return [=](Assets* assets) { - request_textures(loader, *model); - assets->store(std::unique_ptr(model), name); - }; + + assert(vcmModel.parts.size() > 0); + + if (vcmModel.parts.size() == 1 || (cfg && cfg->squashed)) { + auto modelPtr = std::make_unique(std::move(vcmModel.squash())).release(); + return [=](Assets* assets) { + auto model = std::unique_ptr(modelPtr); + request_textures(loader, *model); + assets->store(std::move(model), name); + logger.info() << "store model " << util::quote(name); + }; + } else { + auto vcmModelPtr = std::make_unique(std::move(vcmModel)).release(); + return [=](Assets* assets) { + auto vcmModel = std::unique_ptr(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(std::move(model)), + fullName + ); + } + logger.info() << "store skeleton " << util::quote(name); + assets->store( + std::make_unique( + std::move(*vcmModel->skeleton) + ), + name + ); + }; + } } catch (const parsing_error& err) { std::cerr << err.errorLog() << std::endl; throw;