I N T E R P O L A T I O N
This commit is contained in:
@@ -25,6 +25,17 @@ namespace anm2ed::imgui
|
||||
auto regionLabelsString = std::vector<std::string>{localize.get(BASIC_NONE)};
|
||||
auto regionLabels = std::vector<const char*>{regionLabelsString[0].c_str()};
|
||||
auto regionIds = std::vector<int>{-1};
|
||||
auto interpolationLabelsString =
|
||||
std::vector<std::string>{localize.get(BASIC_NONE), localize.get(BASIC_LINEAR), localize.get(BASIC_EASE_IN),
|
||||
localize.get(BASIC_EASE_OUT), localize.get(BASIC_EASE_IN_OUT)};
|
||||
auto interpolationLabels =
|
||||
std::vector<const char*>{interpolationLabelsString[0].c_str(), interpolationLabelsString[1].c_str(),
|
||||
interpolationLabelsString[2].c_str(), interpolationLabelsString[3].c_str(),
|
||||
interpolationLabelsString[4].c_str()};
|
||||
auto interpolationValues =
|
||||
std::vector<int>{anm2::Frame::Interpolation::NONE, anm2::Frame::Interpolation::LINEAR,
|
||||
anm2::Frame::Interpolation::EASE_IN, anm2::Frame::Interpolation::EASE_OUT,
|
||||
anm2::Frame::Interpolation::EASE_IN_OUT};
|
||||
|
||||
if (type == anm2::LAYER && document.reference.itemID != -1)
|
||||
{
|
||||
@@ -219,21 +230,20 @@ namespace anm2ed::imgui
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_REGION));
|
||||
ImGui::EndDisabled();
|
||||
|
||||
auto interpolationValue = frame ? static_cast<int>(useFrame.interpolation) : dummy_value<int>();
|
||||
if (combo_id_mapped(localize.get(BASIC_INTERPOLATED), &interpolationValue, interpolationValues,
|
||||
interpolationLabels) &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_INTERPOLATION), Document::FRAMES,
|
||||
frame->interpolation = static_cast<anm2::Frame::Interpolation>(interpolationValue));
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_FRAME_INTERPOLATION));
|
||||
|
||||
if (ImGui::Checkbox(localize.get(BASIC_VISIBLE), frame ? &useFrame.isVisible : &dummy_value<bool>()) &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_VISIBILITY), Document::FRAMES,
|
||||
frame->isVisible = useFrame.isVisible);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_FRAME_VISIBILITY));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Checkbox(localize.get(BASIC_INTERPOLATED),
|
||||
frame ? &useFrame.isInterpolated : &dummy_value<bool>()) &&
|
||||
frame)
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_INTERPOLATION), Document::FRAMES,
|
||||
frame->isInterpolated = useFrame.isInterpolated);
|
||||
ImGui::SetItemTooltip("%s", localize.get(TOOLTIP_FRAME_INTERPOLATION));
|
||||
|
||||
auto widgetSize = widget_size_with_row_get(2);
|
||||
|
||||
if (ImGui::Button(localize.get(LABEL_FLIP_X), widgetSize) && frame)
|
||||
|
||||
@@ -34,6 +34,17 @@ namespace anm2ed::imgui
|
||||
|
||||
auto spritesheet = map::find(anm2.content.spritesheets, spritesheetReference);
|
||||
|
||||
if (manager.isMakeRegionRequested)
|
||||
{
|
||||
spritesheetReference = manager.makeRegionSpritesheetId;
|
||||
reference = -1;
|
||||
editRegion = manager.makeRegion;
|
||||
isPreserveEditRegionOnOpen = true;
|
||||
propertiesPopup.open();
|
||||
manager.isMakeRegionRequested = false;
|
||||
spritesheet = map::find(anm2.content.spritesheets, spritesheetReference);
|
||||
}
|
||||
|
||||
auto remove_unused = [&]()
|
||||
{
|
||||
if (!spritesheet) return;
|
||||
@@ -474,7 +485,12 @@ namespace anm2ed::imgui
|
||||
auto childSize = child_size_get(5);
|
||||
auto& region = reference == -1 ? editRegion : spritesheet->regions.at(reference);
|
||||
|
||||
if (propertiesPopup.isJustOpened) editRegion = anm2::Spritesheet::Region{};
|
||||
if (propertiesPopup.isJustOpened)
|
||||
{
|
||||
if (!isPreserveEditRegionOnOpen)
|
||||
editRegion = anm2::Spritesheet::Region{};
|
||||
isPreserveEditRegionOnOpen = false;
|
||||
}
|
||||
|
||||
if (ImGui::BeginChild("##Child", childSize, ImGuiChildFlags_Borders))
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace anm2ed::imgui
|
||||
public:
|
||||
anm2::Spritesheet::Region editRegion{};
|
||||
int newRegionId{-1};
|
||||
bool isPreserveEditRegionOnOpen{};
|
||||
imgui::PopupHelper propertiesPopup{imgui::PopupHelper(LABEL_REGION_PROPERTIES, imgui::POPUP_SMALL_NO_HEIGHT)};
|
||||
|
||||
void update(Manager&, Settings&, Resources&, Clipboard&);
|
||||
|
||||
@@ -292,9 +292,27 @@ namespace anm2ed::imgui
|
||||
auto nextFrame = vector::in_bounds(item->frames, reference.frameIndex + 1)
|
||||
? &item->frames[reference.frameIndex + 1]
|
||||
: nullptr;
|
||||
if (frame->isInterpolated && nextFrame)
|
||||
if (frame->interpolation != anm2::Frame::Interpolation::NONE && nextFrame)
|
||||
{
|
||||
float interpolation = (float)firstDuration / (float)originalDuration;
|
||||
switch (frame->interpolation)
|
||||
{
|
||||
case anm2::Frame::Interpolation::EASE_IN:
|
||||
interpolation *= interpolation;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_OUT:
|
||||
interpolation = 1.0f - ((1.0f - interpolation) * (1.0f - interpolation));
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_IN_OUT:
|
||||
interpolation = interpolation < 0.5f ? (2.0f * interpolation * interpolation)
|
||||
: (1.0f - std::pow(-2.0f * interpolation + 2.0f, 2.0f) * 0.5f);
|
||||
break;
|
||||
case anm2::Frame::Interpolation::LINEAR:
|
||||
case anm2::Frame::Interpolation::NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
splitFrame.rotation = glm::mix(frame->rotation, nextFrame->rotation, interpolation);
|
||||
splitFrame.position = glm::mix(frame->position, nextFrame->position, interpolation);
|
||||
splitFrame.scale = glm::mix(frame->scale, nextFrame->scale, interpolation);
|
||||
@@ -450,9 +468,37 @@ namespace anm2ed::imgui
|
||||
if (shortcut(manager.chords[SHORTCUT_BAKE], shortcut::FOCUSED)) frames_bake();
|
||||
if (shortcut(manager.chords[SHORTCUT_FIT], shortcut::FOCUSED)) fit_animation_length();
|
||||
|
||||
auto make_region = [&]()
|
||||
{
|
||||
auto frame = document.frame_get();
|
||||
if (!frame || reference.itemType != anm2::LAYER || reference.itemID == -1) return;
|
||||
if (frame->regionID != -1) return;
|
||||
if (!anm2.content.layers.contains(reference.itemID)) return;
|
||||
|
||||
auto spritesheetID = anm2.content.layers.at(reference.itemID).spritesheetID;
|
||||
if (!anm2.content.spritesheets.contains(spritesheetID)) return;
|
||||
|
||||
anm2::Spritesheet::Region region{};
|
||||
region.crop = frame->crop;
|
||||
region.size = frame->size;
|
||||
region.pivot = frame->pivot;
|
||||
region.origin = anm2::Spritesheet::Region::CUSTOM;
|
||||
|
||||
document.spritesheet.reference = spritesheetID;
|
||||
settings.windowIsRegions = true;
|
||||
manager.makeRegionSpritesheetId = spritesheetID;
|
||||
manager.makeRegion = region;
|
||||
manager.isMakeRegionRequested = true;
|
||||
};
|
||||
|
||||
if (ImGui::BeginPopupContextWindow("##Context Menu", ImGuiPopupFlags_MouseButtonRight))
|
||||
{
|
||||
auto item = animation ? animation->item_get(reference.itemType, reference.itemID) : nullptr;
|
||||
auto frame = document.frame_get();
|
||||
bool isMakeRegion =
|
||||
frame && reference.itemType == anm2::LAYER && reference.itemID != -1 && frame->regionID == -1 &&
|
||||
anm2.content.layers.contains(reference.itemID) &&
|
||||
anm2.content.spritesheets.contains(anm2.content.layers.at(reference.itemID).spritesheetID);
|
||||
|
||||
if (ImGui::MenuItem(localize.get(SHORTCUT_STRING_UNDO), settings.shortcutUndo.c_str(), false,
|
||||
document.is_able_to_undo()))
|
||||
@@ -484,6 +530,8 @@ namespace anm2ed::imgui
|
||||
frames.selection.size() == 1))
|
||||
frame_split();
|
||||
|
||||
if (ImGui::MenuItem(localize.get(LABEL_MAKE_REGION), nullptr, false, isMakeRegion)) make_region();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem(localize.get(BASIC_CUT), settings.shortcutCut.c_str(), false, !frames.selection.empty()))
|
||||
@@ -1130,10 +1178,7 @@ namespace anm2ed::imgui
|
||||
auto buttonPos = ImVec2(cursorPos.x + (frameTime * frameSize.x), cursorPos.y);
|
||||
|
||||
if (frameFocusRequested && frameFocusIndex == (int)i && reference == frameReference)
|
||||
{
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
frameFocusRequested = false;
|
||||
}
|
||||
|
||||
ImGui::SetCursorPos(buttonPos);
|
||||
|
||||
@@ -1161,7 +1206,9 @@ namespace anm2ed::imgui
|
||||
{
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Alt))
|
||||
DOCUMENT_EDIT(document, localize.get(EDIT_FRAME_INTERPOLATION), Document::FRAMES,
|
||||
frame.isInterpolated = !frame.isInterpolated);
|
||||
frame.interpolation = frame.interpolation == anm2::Frame::Interpolation::NONE
|
||||
? anm2::Frame::Interpolation::LINEAR
|
||||
: anm2::Frame::Interpolation::NONE);
|
||||
|
||||
document.frameTime = frameTime;
|
||||
}
|
||||
@@ -1327,9 +1374,33 @@ namespace anm2ed::imgui
|
||||
auto borderThickness = isReferenced ? FRAME_BORDER_THICKNESS_REFERENCED : FRAME_BORDER_THICKNESS;
|
||||
drawList->AddRect(rectMin, rectMax, ImGui::GetColorU32(borderColor), FRAME_ROUNDING, 0, borderThickness);
|
||||
|
||||
auto icon = type == anm2::TRIGGER ? icon::TRIGGER
|
||||
: frame.isInterpolated ? icon::INTERPOLATED
|
||||
: icon::UNINTERPOLATED;
|
||||
auto icon = icon::UNINTERPOLATED;
|
||||
if (type == anm2::TRIGGER)
|
||||
icon = icon::TRIGGER;
|
||||
else
|
||||
{
|
||||
switch (frame.interpolation)
|
||||
{
|
||||
case anm2::Frame::Interpolation::NONE:
|
||||
icon = icon::UNINTERPOLATED;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::LINEAR:
|
||||
icon = icon::INTERPOLATED;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_IN:
|
||||
icon = icon::EASE_IN;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_OUT:
|
||||
icon = icon::EASE_OUT;
|
||||
break;
|
||||
case anm2::Frame::Interpolation::EASE_IN_OUT:
|
||||
icon = icon::EASE_IN_OUT;
|
||||
break;
|
||||
default:
|
||||
icon = icon::UNINTERPOLATED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto iconPos = ImVec2(cursorPos.x + (frameTime * frameSize.x),
|
||||
cursorPos.y + (frameSize.y / 2) - (icon_size_get().y / 2));
|
||||
ImGui::SetCursorPos(iconPos);
|
||||
@@ -1426,8 +1497,7 @@ namespace anm2ed::imgui
|
||||
auto childWidth = anm2.animations.length() * ImGui::GetTextLineHeight();
|
||||
if (animation && animation->frameNum > anm2.animations.length())
|
||||
childWidth = animation->frameNum * ImGui::GetTextLineHeight();
|
||||
else if (ImGui::GetContentRegionAvail().x > childWidth)
|
||||
childWidth = ImGui::GetContentRegionAvail().x;
|
||||
childWidth = std::max(childWidth, ImGui::GetContentRegionAvail().x);
|
||||
|
||||
childWidth *= WIDTH_MULTIPLIER;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user