File indexing completed on 2025-02-02 04:11:07
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "path_modifier.hpp" 0008 0009 #include "model/shapes/group.hpp" 0010 #include "model/shapes/path.hpp" 0011 0012 #include "model/animation/join_animatables.hpp" 0013 0014 0015 static void to_path_value( 0016 const glaxnimate::math::bezier::MultiBezier& mbez, 0017 std::vector<glaxnimate::model::Path*>& paths, 0018 glaxnimate::model::Group* group, 0019 glaxnimate::model::Document* document 0020 ) 0021 { 0022 for ( int i = 0; i < mbez.size(); i++ ) 0023 { 0024 if ( i >= int(paths.size()) ) 0025 { 0026 auto new_path = std::make_unique<glaxnimate::model::Path>(document); 0027 paths.push_back(new_path.get()); 0028 group->shapes.insert(std::move(new_path)); 0029 } 0030 0031 auto path = paths[i]; 0032 path->shape.set(mbez.beziers()[i]); 0033 } 0034 } 0035 0036 static void to_path_frame( 0037 const glaxnimate::math::bezier::MultiBezier& mbez, 0038 std::vector<glaxnimate::model::Path*>& paths, 0039 glaxnimate::model::FrameTime t, 0040 const glaxnimate::model::KeyframeTransition& transition, 0041 glaxnimate::model::Group* group, 0042 glaxnimate::model::Document* document 0043 ) 0044 { 0045 for ( int i = 0; i < mbez.size(); i++ ) 0046 { 0047 if ( i >= int(paths.size()) ) 0048 { 0049 auto new_path = std::make_unique<glaxnimate::model::Path>(document); 0050 if ( t > 0 ) 0051 { 0052 glaxnimate::model::KeyframeTransition trans; 0053 trans.set_hold(true); 0054 new_path->shape.set_keyframe(0, glaxnimate::math::bezier::Bezier{})->set_transition({trans}); 0055 } 0056 paths.push_back(new_path.get()); 0057 group->shapes.insert(std::move(new_path)); 0058 } 0059 0060 auto path = paths[i]; 0061 path->shape.set_keyframe(t, mbez.beziers()[i])->set_transition(transition); 0062 } 0063 } 0064 0065 std::unique_ptr<glaxnimate::model::ShapeElement> glaxnimate::model::PathModifier::to_path() const 0066 { 0067 auto group = std::make_unique<glaxnimate::model::Group>(document()); 0068 group->name.set(name.get()); 0069 group->group_color.set(group_color.get()); 0070 group->visible.set(visible.get()); 0071 0072 0073 std::vector<const AnimatableBase*> properties; 0074 auto flags = PropertyTraits::Visual|PropertyTraits::Animated; 0075 for ( auto prop : this->properties() ) 0076 { 0077 if ( (prop->traits().flags & flags) == flags ) 0078 properties.push_back(static_cast<AnimatableBase*>(prop)); 0079 } 0080 0081 JoinAnimatables ja(std::move(properties), JoinAnimatables::NoValues); 0082 FrameTime cur_time = ja.properties()[0]->time(); 0083 0084 std::vector<glaxnimate::model::Path*> paths; 0085 0086 if ( ja.animated() ) 0087 { 0088 for ( const auto & kf : ja ) 0089 { 0090 auto bez = collect_shapes(kf.time, {}); 0091 to_path_frame(bez, paths, kf.time, kf.transition(), group.get(), document()); 0092 } 0093 } 0094 else 0095 { 0096 auto bez = collect_shapes(time(), {}); 0097 to_path_value(bez, paths, group.get(), document()); 0098 } 0099 0100 group->set_time(cur_time); 0101 return group; 0102 0103 } 0104 0105 void glaxnimate::model::PathModifier::on_paint(QPainter* painter, glaxnimate::model::FrameTime t, glaxnimate::model::VisualNode::PaintMode mode, glaxnimate::model::Modifier*) const 0106 { 0107 for ( auto sib : affected() ) 0108 sib->paint(painter, t, mode, const_cast<glaxnimate::model::PathModifier*>(this)); 0109 } 0110 0111