File indexing completed on 2025-01-05 04:01:22

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 #include "utils.hpp"
0007 
0008 
0009 std::vector<std::unique_ptr<glaxnimate::model::KeyframeBase>> glaxnimate::io::split_keyframes(model::AnimatableBase* prop)
0010 {
0011     std::vector<std::unique_ptr<model::KeyframeBase>> split_kfs;
0012     std::unique_ptr<model::KeyframeBase> previous = prop->keyframe(0)->clone();
0013 
0014     for ( int i = 1, e = prop->keyframe_count(); i < e; i++ )
0015     {
0016         if ( previous->transition().hold() )
0017         {
0018             split_kfs.push_back(std::move(previous));
0019             previous = prop->keyframe(i)->clone();
0020             continue;
0021         }
0022 
0023         std::array<qreal, 2> raw_splits;
0024         std::tie(raw_splits[0], raw_splits[1]) = previous->transition().bezier().extrema(1);
0025 
0026         std::vector<qreal> splits;
0027         for ( qreal t : raw_splits )
0028         {
0029             QPointF p = previous->transition().bezier().solve(t);
0030             if ( p.y() < 0 || p.y() > 1 )
0031                 splits.push_back(t);
0032         }
0033 
0034         if ( splits.size() == 0 )
0035         {
0036             split_kfs.push_back(std::move(previous));
0037             previous = prop->keyframe(i)->clone();
0038         }
0039         else
0040         {
0041             auto next = prop->keyframe(i);
0042             auto next_segment = previous->split(next, splits);
0043             previous = std::move(next_segment.back());
0044             split_kfs.insert(split_kfs.end(), std::make_move_iterator(next_segment.begin()), std::make_move_iterator(next_segment.end() - 1));
0045         }
0046     }
0047 
0048     split_kfs.push_back(std::move(previous));
0049 
0050     return split_kfs;
0051 }
0052