From 4af0a8acf7c07bf3e2447ea36e02cd0d3861cf49 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 30 Apr 2024 00:20:24 +0300 Subject: [PATCH] atlas animation moved to textures/ATLAS/animation --- src/assets/assetload_funcs.cpp | 198 +++++++++++++++-------------- src/logic/scripting/lua/libgui.cpp | 15 +-- 2 files changed, 112 insertions(+), 101 deletions(-) diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index 32072f71..b7143fdb 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -1,8 +1,4 @@ #include "assetload_funcs.h" - -#include -#include -#include #include "Assets.h" #include "AssetsLoader.h" #include "../audio/audio.h" @@ -19,20 +15,25 @@ #include "../graphics/core/TextureAnimation.hpp" #include "../frontend/UiDocument.h" +#include +#include +#include + namespace fs = std::filesystem; static bool animation( - Assets* assets, - const ResPaths* paths, - const std::string directory, - const std::string name, + Assets* assets, + const ResPaths* paths, + const std::string& atlasName, + const std::string& directory, + const std::string& name, Atlas* dstAtlas ); assetload::postfunc assetload::texture( AssetsLoader*, const ResPaths* paths, - const std::string filename, + const std::string filename, const std::string name, std::shared_ptr ) { @@ -69,7 +70,7 @@ assetload::postfunc assetload::shader( }; } -static bool appendAtlas(AtlasBuilder& atlas, const fs::path& file) { +static bool append_atlas(AtlasBuilder& atlas, const fs::path& file) { std::string name = file.stem().string(); // skip duplicates if (atlas.has(name)) { @@ -92,7 +93,7 @@ assetload::postfunc assetload::atlas( for (const auto& file : paths->listdir(directory)) { if (!imageio::is_read_supported(file.extension())) continue; - if (!appendAtlas(builder, file)) + if (!append_atlas(builder, file)) continue; } std::set names = builder.getNames(); @@ -100,10 +101,8 @@ assetload::postfunc assetload::atlas( return [=](auto assets) { atlas->prepare(); assets->store(atlas, name); - - // TODO for (const auto& file : names) { - animation(assets, paths, "textures", file, atlas); + animation(assets, paths, name, directory, file, atlas); } }; } @@ -189,106 +188,119 @@ assetload::postfunc assetload::sound( }; } -// TODO: integrate +static void read_anim_file( + const std::string& animFile, + std::vector>& frameList +) { + auto root = files::read_json(animFile); + auto frameArr = root->list("frames"); + float frameDuration = DEFAULT_FRAME_DURATION; + std::string frameName; + + if (frameArr) { + for (size_t i = 0; i < frameArr->size(); i++) { + auto currentFrame = frameArr->list(i); + + frameName = currentFrame->str(0); + if (currentFrame->size() > 1) { + frameDuration = currentFrame->integer(1); + } + frameList.emplace_back(frameName, frameDuration); + } + } +} + +static TextureAnimation create_animation( + Atlas* srcAtlas, + Atlas* dstAtlas, + const std::string& name, + const std::set& frameNames, + const std::vector>& frameList +) { + Texture* srcTex = srcAtlas->getTexture(); + Texture* dstTex = dstAtlas->getTexture(); + UVRegion region = dstAtlas->get(name); + + TextureAnimation animation(srcTex, dstTex); + Frame frame; + + uint dstWidth = dstTex->getWidth(); + uint dstHeight = dstTex->getHeight(); + + uint srcWidth = srcTex->getWidth(); + uint srcHeight = srcTex->getHeight(); + + frame.dstPos = glm::ivec2(region.u1 * dstWidth, region.v1 * dstHeight); + frame.size = glm::ivec2(region.u2 * dstWidth, region.v2 * dstHeight) - frame.dstPos; + + for (const auto& elem : frameList) { + if (!srcAtlas->has(elem.first)) { + std::cerr << "Unknown frame name: " << elem.first << std::endl; + continue; + } + region = srcAtlas->get(elem.first); + if (elem.second > 0) { + frame.duration = static_cast(elem.second) / 1000.0f; + } + frame.srcPos = glm::ivec2(region.u1 * srcWidth, srcHeight - region.v2 * srcHeight); + animation.addFrame(frame); + } + return animation; +} + +inline bool contains( + const std::vector>& frameList, + const std::string& frameName +) { + for (const auto& elem : frameList) { + if (frameName == elem.first) { + return true; + } + } + return false; +} + static bool animation( Assets* assets, - const ResPaths* paths, - const std::string directory, - const std::string name, + const ResPaths* paths, + const std::string& atlasName, + const std::string& directory, + const std::string& name, Atlas* dstAtlas ) { - std::string animsDir = directory + "/animations"; - std::string blocksDir = directory + "/blocks"; + std::string animsDir = directory + "/animation"; for (const auto& folder : paths->listdir(animsDir)) { if (!fs::is_directory(folder)) continue; - if (folder.filename().string() != name) continue; + if (folder.filename().u8string() != name) continue; if (fs::is_empty(folder)) continue; AtlasBuilder builder; - appendAtlas(builder, paths->find(blocksDir + "/" + name + ".png")); - - std::string animFile = folder.string() + "/animation.json"; - - std::vector> frameList; + append_atlas(builder, paths->find(directory + "/" + name + ".png")); + std::vector> frameList; + std::string animFile = folder.u8string() + "/animation.json"; if (fs::exists(animFile)) { - auto root = files::read_json(animFile); - - auto frameArr = root->list("frames"); - - float frameDuration = DEFAULT_FRAME_DURATION; - std::string frameName; - - if (frameArr) { - for (size_t i = 0; i < frameArr->size(); i++) { - auto currentFrame = frameArr->list(i); - - frameName = currentFrame->str(0); - if (currentFrame->size() > 1) - frameDuration = static_cast(currentFrame->integer(1)) / 1000; - - frameList.emplace_back(frameName, frameDuration); - } - } + read_anim_file(animFile, frameList); } for (const auto& file : paths->listdir(animsDir + "/" + name)) { - if (!frameList.empty()) { - bool contains = false; - for (const auto& elem : frameList) { - if (file.stem() == elem.first) { - contains = true; - break; - } - } - if (!contains) continue; + if (!frameList.empty() && !contains(frameList, file.stem())) { + continue; } - if (!appendAtlas(builder, file)) + if (!append_atlas(builder, file)) continue; } - - auto srcAtlas = builder.build(2); - srcAtlas->prepare(); - - Texture* srcTex = srcAtlas->getTexture(); - Texture* dstTex = dstAtlas->getTexture(); - - TextureAnimation animation(srcTex, dstTex); - Frame frame; - UVRegion region = dstAtlas->get(name); - - uint dstWidth = dstTex->getWidth(); - uint dstHeight = dstTex->getHeight(); - - uint srcWidth = srcTex->getWidth(); - uint srcHeight = srcTex->getHeight(); - - frame.dstPos = glm::ivec2(region.u1 * dstWidth, region.v1 * dstHeight); - frame.size = glm::ivec2(region.u2 * dstWidth, region.v2 * dstHeight) - frame.dstPos; - + auto srcAtlas = builder.build(2, true); if (frameList.empty()) { - for (const auto& elem : builder.getNames()) { - region = srcAtlas->get(elem); - frame.srcPos = glm::ivec2(region.u1 * srcWidth, srcHeight - region.v2 * srcHeight); - animation.addFrame(frame); + for (const auto& frameName : builder.getNames()) { + frameList.emplace_back(frameName, 0); } } - else { - for (const auto& elem : frameList) { - if (!srcAtlas->has(elem.first)) { - std::cerr << "Unknown frame name: " << elem.first << std::endl; - continue; - } - region = srcAtlas->get(elem.first); - frame.duration = elem.second; - frame.srcPos = glm::ivec2(region.u1 * srcWidth, srcHeight - region.v2 * srcHeight); - animation.addFrame(frame); - } - } - - assets->store(srcAtlas.release(), name + "_animation"); + auto animation = create_animation( + srcAtlas.get(), dstAtlas, name, builder.getNames(), frameList + ); + assets->store(srcAtlas.release(), atlasName + "/" + name + "_animation"); assets->store(animation); - return true; } return true; diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index cca1c9fc..2b3e8f24 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -226,22 +226,21 @@ static bool setattr(lua_State* L, Menu* menu, const std::string& attr) { if (menu == nullptr) return false; if (attr == "page") { - auto page = lua_tostring(L, 4); - menu->setPage(page); + menu->setPage(lua_tostring(L, 4)); return true; } return false; } -static bool setattr(lua_State* L, InventoryView* inventory, const std::string& attr) { - if (inventory == nullptr) +static bool setattr(lua_State* L, InventoryView* view, const std::string& attr) { + if (view == nullptr) return false; if (attr == "inventory") { - auto inv = scripting::level->inventories->get(lua_tointeger(L, 4)); - if (inv == nullptr) { - inventory->unbind(); + auto inventory = scripting::level->inventories->get(lua_tointeger(L, 4)); + if (inventory == nullptr) { + view->unbind(); } else { - inventory->bind(inv, scripting::content); + view->bind(inventory, scripting::content); } return true; }