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