finally added limits to bezier so curves can't loop over themselves

This commit is contained in:
itsmattkc
2021-01-24 14:04:18 +11:00
parent b68397d687
commit 49a9e5b870
5 changed files with 144 additions and 37 deletions
+56 -5
View File
@@ -30,10 +30,12 @@ NodeKeyframe::NodeKeyframe(const rational &time, const QVariant &value, const No
time_(time),
value_(value),
type_(type),
bezier_control_in_(QPointF(-1.0, 0.0)),
bezier_control_out_(QPointF(1.0, 0.0)),
bezier_control_in_(QPointF(0.0, 0.0)),
bezier_control_out_(QPointF(0.0, 0.0)),
track_(track),
element_(element)
element_(element),
previous_(nullptr),
next_(nullptr)
{
setParent(parent);
}
@@ -85,8 +87,31 @@ const NodeKeyframe::Type &NodeKeyframe::type() const
void NodeKeyframe::set_type(const NodeKeyframe::Type &type)
{
type_ = type;
emit TypeChanged(type_);
if (type_ != type) {
type_ = type;
if (type_ == kBezier) {
// Set some sane defaults if this keyframe existed in the track and was just changed
if (bezier_control_in_.isNull()) {
if (previous_) {
// Set the in point to be half way between
set_bezier_control_in(QPointF((previous_->time().toDouble() - this->time().toDouble()) * 0.5, 0.0));
} else {
set_bezier_control_in(QPointF(-1.0, 0.0));
}
}
if (bezier_control_out_.isNull()) {
if (next_) {
set_bezier_control_out(QPointF((next_->time().toDouble() - this->time().toDouble()) * 0.5, 0.0));
} else {
set_bezier_control_out(QPointF(1.0, 0.0));
}
}
}
emit TypeChanged(type_);
}
}
const QPointF &NodeKeyframe::bezier_control_in() const
@@ -111,6 +136,32 @@ void NodeKeyframe::set_bezier_control_out(const QPointF &control)
emit BezierControlOutChanged(bezier_control_out_);
}
QPointF NodeKeyframe::valid_bezier_control_in() const
{
double t = time().toDouble();
qreal adjusted_x = t + bezier_control_in_.x();
if (previous_) {
// Limit to the point of that keyframe
adjusted_x = qMax(adjusted_x, previous_->time().toDouble());
}
return QPointF(adjusted_x - t, bezier_control_in_.y());
}
QPointF NodeKeyframe::valid_bezier_control_out() const
{
double t = time().toDouble();
qreal adjusted_x = t + bezier_control_out_.x();
if (next_) {
// Limit to the point of that keyframe
adjusted_x = qMin(adjusted_x, next_->time().toDouble());
}
return QPointF(adjusted_x - t, bezier_control_out_.y());
}
const QPointF &NodeKeyframe::bezier_control(NodeKeyframe::BezierType type) const
{
if (type == kInHandle) {