diff --git a/compile_commands.json b/compile_commands.json index e2be980..bc0dce8 120000 --- a/compile_commands.json +++ b/compile_commands.json @@ -1 +1 @@ -/home/anon/sda/Personal/Repos/anm2ed/out/build/linux-release/compile_commands.json \ No newline at end of file +/home/anon/sda/Personal/Repos/anm2ed/out/build/linux-debug/compile_commands.json \ No newline at end of file diff --git a/src/document.cpp b/src/document.cpp index 82b39fb..2f8421e 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1493,6 +1493,37 @@ namespace anm2ed if (command.run) command.run(manager, *this); } + std::vector Document::layer_references_get() + { + std::set selectedReferences = items.references; + if (selectedReferences.empty()) + for (auto frameReference : frames.references) + { + frameReference.frameIndex = -1; + selectedReferences.insert(frameReference); + } + if (selectedReferences.empty() && !frames.selection.empty()) + selectedReferences.insert({reference.animationIndex, reference.itemType, reference.itemID}); + if (selectedReferences.empty() && reference.itemType != NONE) + selectedReferences.insert({reference.animationIndex, reference.itemType, reference.itemID}); + + std::vector result{}; + for (auto itemReference : selectedReferences) + { + itemReference.frameIndex = -1; + if (itemReference.itemType != LAYER) return {}; + if (!anm2.element_get(itemReference.animationIndex, ItemType::LAYER, itemReference.itemID)) + { + if (reference.animationIndex == itemReference.animationIndex || + !anm2.element_get(reference.animationIndex, ItemType::LAYER, itemReference.itemID)) + return {}; + itemReference.animationIndex = reference.animationIndex; + } + result.push_back(itemReference); + } + return result; + } + Element* Document::frame_get() { return anm2.element_get(reference.animationIndex, document::item_type_get(reference.itemType), reference.frameIndex, diff --git a/src/document.hpp b/src/document.hpp index 6b05d3d..075fba2 100644 --- a/src/document.hpp +++ b/src/document.hpp @@ -118,6 +118,7 @@ namespace anm2ed bool spritesheet_any_dirty(); void spritesheet_hashes_reset(); void spritesheet_hashes_sync(); + std::vector layer_references_get(); Element* frame_get(); Element* item_get(); diff --git a/src/imgui/taskbar.cpp b/src/imgui/taskbar.cpp index 3d2045d..013a1da 100644 --- a/src/imgui/taskbar.cpp +++ b/src/imgui/taskbar.cpp @@ -86,10 +86,9 @@ namespace anm2ed::imgui auto itemType = document ? (ItemType)document->reference.itemType : ItemType::NONE; auto animation = document ? document->anm2.element_get(ElementType::ANIMATION, document->reference.animationIndex) : nullptr; - auto item = - document ? document->anm2.element_get(document->reference.animationIndex, itemType, document->reference.itemID) - : nullptr; auto frames = document ? &document->frames : nullptr; + auto layerReferences = document ? document->layer_references_get() : std::vector{}; + bool isGenerateAnimationFromGridAvailable = !layerReferences.empty(); bool hasRegions = false; if (document) { @@ -182,7 +181,7 @@ namespace anm2ed::imgui if (ImGui::BeginMenu(localize.get(LABEL_WIZARD_MENU))) { if (ImGui::MenuItem(localize.get(LABEL_TASKBAR_GENERATE_ANIMATION_FROM_GRID), nullptr, false, - item && itemType == ItemType::LAYER)) + isGenerateAnimationFromGridAvailable)) generatePopup.open(); ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_WIZARD_GENERATE_ANIMATION_FROM_GRID)); diff --git a/src/imgui/wizard/generate_animation_from_grid.cpp b/src/imgui/wizard/generate_animation_from_grid.cpp index bcc867c..587f5e8 100644 --- a/src/imgui/wizard/generate_animation_from_grid.cpp +++ b/src/imgui/wizard/generate_animation_from_grid.cpp @@ -1,7 +1,6 @@ #include "generate_animation_from_grid.hpp" #include - #include "math.hpp" #include "types.hpp" #include "util/imgui/imgui.hpp" @@ -29,6 +28,12 @@ namespace anm2ed::imgui::wizard auto& delay = settings.generateDuration; auto& zoom = settings.generateZoom; auto& zoomStep = settings.inputZoomStep; + auto layerReferences = document.layer_references_get(); + auto previewReference = layerReferences.empty() ? Reference{} : layerReferences.front(); + for (auto itemReference : layerReferences) + if (itemReference.animationIndex == reference.animationIndex && itemReference.itemType == reference.itemType && + itemReference.itemID == reference.itemID) + previewReference = itemReference; auto childSize = ImVec2(row_widget_width_get(2), size_without_footer_get().y); @@ -63,28 +68,36 @@ namespace anm2ed::imgui::wizard auto previewMin = ImGui::GetCursorScreenPos(); auto previewMax = to_imvec2(to_vec2(previewMin) + to_vec2(previewSize)); - bind(); size_set(to_vec2(previewSize)); + bind(); viewport_set(); clear(isTransparent ? vec4(0) : vec4(backgroundColor, 1.0f)); - if (reference.itemType == LAYER) + if (!layerReferences.empty()) { - auto layer = anm2.element_get(ElementType::LAYER_ELEMENT, reference.itemID); + auto layer = anm2.element_get(ElementType::LAYER_ELEMENT, previewReference.itemID); auto sourceTexture = layer ? document.texture_get(layer->spritesheetId) : nullptr; - if (sourceTexture) + if (sourceTexture && sourceTexture->is_valid()) { - auto index = std::clamp((int)(time * (count - 1)), 0, (count - 1)); - auto row = index / columns; - auto column = index % columns; - auto crop = startPosition + ivec2(size.x * column, size.y * row); - auto uvMin = (vec2(crop) + vec2(0.5f)) / vec2(sourceTexture->size); - auto uvMax = (vec2(crop) + vec2(size) - vec2(0.5f)) / vec2(sourceTexture->size); + auto previewTrack = element_make(ElementType::LAYER_ANIMATION); + frames_generate_from_grid(previewTrack, startPosition, size, pivot, columns, count, delay); - mat4 transform = transform_get(zoom) * math::quad_model_get(size, {}, pivot); + auto length = std::max(track_length_get(previewTrack), FRAME_DURATION_MIN); + auto sampleTime = std::min(time * (float)length, (float)length - 0.001f); + auto frame = frame_generate(previewTrack, sampleTime); + auto textureSize = vec2(sourceTexture->size); - texture_render(shaderTexture, sourceTexture->id, transform, vec4(1.0f), {}, - math::uv_vertices_get(uvMin, uvMax).data()); + if (textureSize.x > 0.0f && textureSize.y > 0.0f && frame.size.x > 0.0f && frame.size.y > 0.0f) + { + auto uvMin = frame.crop / textureSize; + auto uvMax = (frame.crop + frame.size) / textureSize; + mat4 transform = transform_get(zoom) * + math::quad_model_get(frame.size, frame.position, frame.pivot, + math::percent_to_unit(frame.scale), frame.rotation); + auto vertices = math::uv_vertices_get(uvMin, uvMax); + + texture_render(shaderTexture, sourceTexture->id, transform, frame.tint, frame.colorOffset, vertices.data()); + } } } @@ -107,9 +120,10 @@ namespace anm2ed::imgui::wizard auto widgetSize = widget_size_with_row_get(2); + ImGui::BeginDisabled(layerReferences.empty()); if (ImGui::Button(localize.get(LABEL_GENERATE), widgetSize)) { - auto queuedReference = reference; + auto queuedLayerReferences = layerReferences; auto queuedStartPosition = startPosition; auto queuedSize = size; auto queuedPivot = pivot; @@ -120,23 +134,29 @@ namespace anm2ed::imgui::wizard manager.command_push({manager.selected, [=](Manager&, Document& document) { - auto itemType = static_cast(queuedReference.itemType); - auto item = document.anm2.element_get(queuedReference.animationIndex, itemType, - queuedReference.itemID); - auto animation = - document.anm2.element_get(ElementType::ANIMATION, queuedReference.animationIndex); - - if (item && animation) + bool isChanged{}; + for (auto queuedReference : queuedLayerReferences) { - document.snapshot(localize.get(EDIT_GENERATE_ANIMATION_FROM_GRID)); + auto item = document.anm2.element_get(queuedReference.animationIndex, ItemType::LAYER, + queuedReference.itemID); + auto animation = + document.anm2.element_get(ElementType::ANIMATION, queuedReference.animationIndex); + if (!item || !animation) continue; + + if (!isChanged) + { + document.snapshot(localize.get(EDIT_GENERATE_ANIMATION_FROM_GRID)); + isChanged = true; + } frames_generate_from_grid(*item, queuedStartPosition, queuedSize, queuedPivot, queuedColumns, queuedCount, queuedDelay); animation->frameNum = animation_length_get(*animation); - document.anm2_change(Document::FRAMES); } + if (isChanged) document.anm2_change(Document::FRAMES); }}); isEnd = true; } + ImGui::EndDisabled(); ImGui::SameLine();