diff options
Diffstat (limited to 'source/Game/Sprite.cpp')
-rw-r--r-- | source/Game/Sprite.cpp | 328 |
1 files changed, 0 insertions, 328 deletions
diff --git a/source/Game/Sprite.cpp b/source/Game/Sprite.cpp deleted file mode 100644 index 2b4923c..0000000 --- a/source/Game/Sprite.cpp +++ /dev/null @@ -1,328 +0,0 @@ -#include "Sprite.hpp" - -#include "AppConfig.hpp" -#include "CommonVertexIndex.hpp" -#include "EditorCore.hpp" -#include "EditorUtils.hpp" -#include "Image.hpp" -#include "RapidJsonHelper.hpp" -#include "Rect.hpp" - -#include <imgui.h> -#include <misc/cpp/imgui_stdlib.h> -#include <rapidjson/document.h> -#include <memory> - -using namespace std::literals; - -bool SpriteDefinition::IsValid() const { - return mAtlas != nullptr; -} - -bool IresSpriteFiles::IsValid() const { - return !spriteFiles.empty(); -} - -SpriteDefinition* IresSpriteFiles::CreateInstance() const { - if (IsValid()) { - return nullptr; - } - - std::vector<Texture::AtlasSource> sources; - sources.resize(spriteFiles.size()); - for (auto& file : spriteFiles) { - } - - Texture::AtlasOutput atlasOut; - Texture::AtlasInput atlasIn{ - .sources = sources, - .packingMode = Texture::PM_KeepSquare, - }; - atlasIn.sources = sources; - auto atlas = std::make_unique<Texture>(); - if (atlas->InitAtlas(atlasIn, &atlasOut) != Texture::EC_Success) { - return nullptr; - } - - auto sprite = std::make_unique<SpriteDefinition>(); - sprite->mAtlas.Attach(atlas.release()); - sprite->mBoundingBox = atlasOut.elements[0].subregionSize; - sprite->mFrames.reserve(atlasOut.elements.size()); - for (auto& elm : atlasOut.elements) { - // Validate bounding box - if (sprite->mBoundingBox != elm.subregionSize) { - return nullptr; - } - - // Copy frame subregion - sprite->mFrames.push_back(elm.subregion); - } - return sprite.release(); -} - -SpriteDefinition* IresSpriteFiles::GetInstance() { - if (mInstance == nullptr) { - mInstance.Attach(CreateInstance()); - } - return mInstance.Get(); -} - -void IresSpriteFiles::InvalidateInstance() { - mInstance.Attach(nullptr); -} - -void IresSpriteFiles::Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjson::Document& root) const { - IresObject::Write(ctx, value, root); - value.AddMember("Sprites", rapidjson::WriteVectorPrimitives(root, spriteFiles.begin(), spriteFiles.end()), root.GetAllocator()); -} - -void IresSpriteFiles::Read(IresLoadingContext& ctx, const rapidjson::Value& value) { - InvalidateInstance(); - - IresObject::Read(ctx, value); - - auto rvFileList = rapidjson::GetProperty(value, rapidjson::kArrayType, "Sprites"sv); - if (!rvFileList) return; - spriteFiles.clear(); - rapidjson::ReadVectorPrimitives<decltype(spriteFiles)>(*rvFileList, spriteFiles); -} - -bool IresSpritesheet::IsValid() const { - return !spritesheetFile.empty() && - sheetWSplit != 0 && - sheetHSplit != 0; -} - -void IresSpritesheet::ResplitSpritesheet(SpriteDefinition* sprite, const IresSpritesheet* conf) { - ResplitSpritesheet(sprite, conf->sheetWSplit, conf->sheetHSplit, conf->frameCountOverride); -} - -void IresSpritesheet::ResplitSpritesheet(SpriteDefinition* sprite, int wSplit, int hSplit, int frameCount) { - auto atlas = sprite->GetAtlas(); - auto size = atlas->GetInfo().size; - int frameWidth = size.x / wSplit; - int frameHeight = size.y / hSplit; - - sprite->mBoundingBox = { frameWidth, frameHeight }; - sprite->mFrames.clear(); - sprite->mFrames.reserve(wSplit * hSplit); - - // Width and height in UV coordinates for each frame - float deltaU = 1.0f / wSplit; - float deltaV = 1.0f / hSplit; - int i = 0; - if (frameCount < 0) { - frameCount = std::numeric_limits<int>::max(); - } - for (int y = 0; y < hSplit; ++y) { - for (int x = 0; x < wSplit; ++x) { - auto& subregion = sprite->mFrames.emplace_back(); - // Top left - subregion.u0 = deltaU * x; - subregion.v0 = deltaV * y; - // Bottom right - subregion.u1 = subregion.u0 + deltaU; - subregion.v1 = subregion.v0 + deltaV; - - if ((i + 1) >= frameCount) { - return; - } - - ++i; - } - } -} - -SpriteDefinition* IresSpritesheet::CreateInstance() const { - if (!IsValid()) { - return nullptr; - } - - char path[2048]; - snprintf(path, sizeof(path), "%s/%s", AppConfig::assetDir.c_str(), spritesheetFile.c_str()); - - auto atlas = std::make_unique<Texture>(); - if (atlas->InitFromFile(path) != Texture::EC_Success) { - return nullptr; - } - - auto sprite = std::make_unique<SpriteDefinition>(); - sprite->mAtlas.Attach(atlas.release()); - ResplitSpritesheet(sprite.get(), this); - return sprite.release(); -} - -SpriteDefinition* IresSpritesheet::GetInstance() { - if (mInstance == nullptr) { - mInstance.Attach(CreateInstance()); - } - return mInstance.Get(); -} - -void IresSpritesheet::InvalidateInstance() { - mInstance.Attach(nullptr); -} - -bool IresSpritesheet::IsFrameCountOverriden() const { - return frameCountOverride > 0; -} - -int IresSpritesheet::GetFrameCount() const { - if (IsFrameCountOverriden()) { - return frameCountOverride; - } else { - return sheetWSplit * sheetHSplit; - } -} - -void IresSpritesheet::ShowEditor(IEditor& editor) { - IresObject::ShowEditor(editor); - - bool doInvalidateInstance = false; - auto instance = GetInstance(); // NOTE: may be null - - if (ImGui::Button("View Sprite", instance == nullptr)) { - editor.OpenSpriteViewer(instance); - } - - if (ImGui::InputText("Spritesheet", &spritesheetFile)) { - doInvalidateInstance = true; - } - - if (ImGui::InputInt("Horizontal split", &sheetWSplit)) { - sheetWSplit = std::max(sheetWSplit, 1); - if (instance) IresSpritesheet::ResplitSpritesheet(instance, this); - } - - if (ImGui::InputInt("Vertical split", &sheetHSplit)) { - sheetHSplit = std::max(sheetHSplit, 1); - if (instance) IresSpritesheet::ResplitSpritesheet(instance, this); - } - - bool frameCountOverriden = frameCountOverride > 0; - if (ImGui::Checkbox("##", &frameCountOverriden)) { - if (frameCountOverriden) { - frameCountOverride = sheetWSplit * sheetHSplit; - } else { - frameCountOverride = 0; - } - } - ImGui::SameLine(); - if (frameCountOverriden) { - if (ImGui::InputInt("Frame count", &frameCountOverride)) { - frameCountOverride = std::max(frameCountOverride, 1); - if (instance) IresSpritesheet::ResplitSpritesheet(instance, this); - } - } else { - int dummy = sheetWSplit * sheetHSplit; - ImGui::PushDisabled(); - ImGui::InputInt("Frame count", &dummy, ImGuiInputTextFlags_ReadOnly); - ImGui::PopDisabled(); - } - - if (instance) { - auto atlas = instance->GetAtlas(); - auto imageSize = Utils::FitImage(atlas->GetInfo().size); - auto imagePos = ImGui::GetCursorScreenPos(); - ImGui::Image((ImTextureID)(uintptr_t)atlas->GetHandle(), imageSize); - - auto drawlist = ImGui::GetWindowDrawList(); - float deltaX = imageSize.x / sheetWSplit; - for (int ix = 0; ix < sheetWSplit + 1; ++ix) { - float x = ix * deltaX; - ImVec2 start{ imagePos.x + x, imagePos.y }; - ImVec2 end{ imagePos.x + x, imagePos.y + imageSize.y }; - drawlist->AddLine(start, end, IM_COL32(255, 255, 0, 255)); - } - float deltaY = imageSize.y / sheetHSplit; - for (int iy = 0; iy < sheetHSplit + 1; ++iy) { - float y = iy * deltaY; - ImVec2 start{ imagePos.x, imagePos.y + y }; - ImVec2 end{ imagePos.x + imageSize.x, imagePos.y + y }; - drawlist->AddLine(start, end, IM_COL32(255, 255, 0, 255)); - } - - int i = sheetWSplit * sheetHSplit; - int frameCount = GetFrameCount(); - for (int y = sheetHSplit - 1; y >= 0; --y) { - for (int x = sheetWSplit - 1; x >= 0; --x) { - if (i > frameCount) { - ImVec2 tl{ imagePos.x + x * deltaX + 1.0f, imagePos.y + y * deltaY + 1.0f }; - ImVec2 br{ imagePos.x + (x + 1) * deltaX, imagePos.y + (y + 1) * deltaY }; - drawlist->AddRectFilled(tl, br, IM_COL32(255, 0, 0, 100)); - } - --i; - } - } - } else { - ImGui::TextUnformatted("Sprite configuration invalid"); - } - - if (doInvalidateInstance) { - InvalidateInstance(); - } -} - -void IresSpritesheet::Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjson::Document& root) const { - IresObject::Write(ctx, value, root); - value.AddMember("SpriteSheet", spritesheetFile, root.GetAllocator()); - value.AddMember("WSplit", sheetWSplit, root.GetAllocator()); - value.AddMember("HSplit", sheetHSplit, root.GetAllocator()); - if (frameCountOverride > 0) { - value.AddMember("FrameCount", frameCountOverride, root.GetAllocator()); - } -} - -void IresSpritesheet::Read(IresLoadingContext& ctx, const rapidjson::Value& value) { - InvalidateInstance(); - - IresObject::Read(ctx, value); - BRUSSEL_JSON_GET(value, "SpriteSheet", std::string, spritesheetFile, return ); - BRUSSEL_JSON_GET(value, "WSplit", int, sheetWSplit, return ); - BRUSSEL_JSON_GET(value, "HSplit", int, sheetHSplit, return ); - BRUSSEL_JSON_GET_DEFAULT(value, "FrameCount", int, frameCountOverride, 0); -} - -Sprite::Sprite() - : mDefinition(nullptr) { -} - -bool Sprite::IsValid() const { - return mDefinition != nullptr; -} - -void Sprite::SetDefinition(SpriteDefinition* definition) { - mDefinition.Attach(definition); - mCurrentFrame = 0; -} - -int Sprite::GetFrame() const { - return mCurrentFrame; -} - -const Subregion& Sprite::GetFrameSubregion() const { - return mDefinition->GetFrames()[mCurrentFrame]; -} - -void Sprite::SetFrame(int frame) { - mCurrentFrame = frame; -} - -void Sprite::PlayFrame() { - ++mTimeElapsed; - if (mTimeElapsed >= mPlaybackSpeed) { - mTimeElapsed -= mPlaybackSpeed; - - int frameCount = mDefinition->GetFrames().size(); - int nextFrame = (mCurrentFrame + 1) % frameCount; - SetFrame(nextFrame); - } -} - -int Sprite::GetPlaybackSpeed() const { - return mPlaybackSpeed; -} - -void Sprite::SetPlaybackSpeed(int speed) { - // TODO -} |