fix generate animation from grid

This commit is contained in:
2026-05-22 09:09:00 -04:00
parent 9d8109be72
commit 39f09b75e1
5 changed files with 80 additions and 29 deletions
+1 -1
View File
@@ -1 +1 @@
/home/anon/sda/Personal/Repos/anm2ed/out/build/linux-release/compile_commands.json
/home/anon/sda/Personal/Repos/anm2ed/out/build/linux-debug/compile_commands.json
+31
View File
@@ -1493,6 +1493,37 @@ namespace anm2ed
if (command.run) command.run(manager, *this);
}
std::vector<Reference> Document::layer_references_get()
{
std::set<Reference> 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<Reference> 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,
+1
View File
@@ -118,6 +118,7 @@ namespace anm2ed
bool spritesheet_any_dirty();
void spritesheet_hashes_reset();
void spritesheet_hashes_sync();
std::vector<Reference> layer_references_get();
Element* frame_get();
Element* item_get();
+3 -4
View File
@@ -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<Reference>{};
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));
@@ -1,7 +1,6 @@
#include "generate_animation_from_grid.hpp"
#include <algorithm>
#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<ItemType>(queuedReference.itemType);
auto item = document.anm2.element_get(queuedReference.animationIndex, itemType,
bool isChanged{};
for (auto queuedReference : queuedLayerReferences)
{
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 (item && animation)
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();