mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 19:19:39 -06:00
Simplify speed function a bit (less object oriented)
This commit is contained in:
@@ -49,6 +49,8 @@ Path::Path(Waypoint start, Waypoint end, CurveType type,
|
||||
{
|
||||
initializePath();
|
||||
|
||||
_speedFunction = SpeedFunction(SpeedFunction::Type::DampenedQuintic);
|
||||
|
||||
if (duration.has_value()) {
|
||||
_duration = duration.value();
|
||||
}
|
||||
@@ -79,7 +81,7 @@ const std::vector<glm::dvec3> Path::controlPoints() const {
|
||||
}
|
||||
|
||||
CameraPose Path::traversePath(double dt) {
|
||||
if (!_curve || !_rotationInterpolator || !_speedFunction) {
|
||||
if (!_curve || !_rotationInterpolator) {
|
||||
// TODO: handle better (abort path somehow)
|
||||
return _start.pose;
|
||||
}
|
||||
@@ -111,7 +113,7 @@ bool Path::hasReachedEnd() const {
|
||||
}
|
||||
|
||||
double Path::speedAtTime(double time) const {
|
||||
return _speedFunction->scaledValue(time, _duration, pathLength());
|
||||
return _speedFunction.scaledValue(time, _duration, pathLength());
|
||||
}
|
||||
|
||||
CameraPose Path::interpolatedPose(double distance) const {
|
||||
@@ -125,44 +127,37 @@ CameraPose Path::interpolatedPose(double distance) const {
|
||||
void Path::initializePath() {
|
||||
_curve.reset();
|
||||
|
||||
switch (_curveType)
|
||||
{
|
||||
case CurveType::AvoidCollision:
|
||||
_curve = std::make_unique<AvoidCollisionCurve>(_start, _end);
|
||||
_rotationInterpolator = std::make_unique<EasedSlerpInterpolator>(
|
||||
_start.rotation(),
|
||||
_end.rotation()
|
||||
);
|
||||
_speedFunction = std::make_unique<QuinticDampenedSpeed>();
|
||||
break;
|
||||
|
||||
case CurveType::Linear:
|
||||
_curve = std::make_unique<LinearCurve>(_start, _end);
|
||||
_rotationInterpolator = std::make_unique<EasedSlerpInterpolator>(
|
||||
_start.rotation(),
|
||||
_end.rotation()
|
||||
);
|
||||
_speedFunction = std::make_unique<QuinticDampenedSpeed>();
|
||||
break;
|
||||
|
||||
case CurveType::ZoomOutOverview:
|
||||
_curve = std::make_unique<ZoomOutOverviewCurve>(_start, _end);
|
||||
_rotationInterpolator = std::make_unique<LookAtInterpolator>(
|
||||
_start.rotation(),
|
||||
_end.rotation(),
|
||||
_start.node()->worldPosition(),
|
||||
_end.node()->worldPosition(),
|
||||
_curve.get()
|
||||
);
|
||||
_speedFunction = std::make_unique<QuinticDampenedSpeed>();
|
||||
break;
|
||||
|
||||
default:
|
||||
LERROR("Could not create curve. Type does not exist!");
|
||||
return;
|
||||
switch (_curveType) {
|
||||
case CurveType::AvoidCollision:
|
||||
_curve = std::make_unique<AvoidCollisionCurve>(_start, _end);
|
||||
_rotationInterpolator = std::make_unique<EasedSlerpInterpolator>(
|
||||
_start.rotation(),
|
||||
_end.rotation()
|
||||
);
|
||||
break;
|
||||
case CurveType::Linear:
|
||||
_curve = std::make_unique<LinearCurve>(_start, _end);
|
||||
_rotationInterpolator = std::make_unique<EasedSlerpInterpolator>(
|
||||
_start.rotation(),
|
||||
_end.rotation()
|
||||
);
|
||||
break;
|
||||
case CurveType::ZoomOutOverview:
|
||||
_curve = std::make_unique<ZoomOutOverviewCurve>(_start, _end);
|
||||
_rotationInterpolator = std::make_unique<LookAtInterpolator>(
|
||||
_start.rotation(),
|
||||
_end.rotation(),
|
||||
_start.node()->worldPosition(),
|
||||
_end.node()->worldPosition(),
|
||||
_curve.get()
|
||||
);
|
||||
break;
|
||||
default:
|
||||
LERROR("Could not create curve. Type does not exist!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_curve || !_rotationInterpolator || !_speedFunction) {
|
||||
if (!_curve || !_rotationInterpolator) {
|
||||
LERROR("Curve type has not been properly initialized.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
double _duration;
|
||||
CurveType _curveType;
|
||||
|
||||
std::unique_ptr<SpeedFunction> _speedFunction;
|
||||
SpeedFunction _speedFunction;
|
||||
std::unique_ptr<RotationInterpolator> _rotationInterpolator;
|
||||
std::unique_ptr<PathCurve> _curve;
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@ namespace {
|
||||
|
||||
namespace openspace::autonavigation {
|
||||
|
||||
SpeedFunction::SpeedFunction(Type type) : _type(type) {
|
||||
initializeIntegratedSum();
|
||||
}
|
||||
|
||||
SpeedFunction::~SpeedFunction() {}
|
||||
|
||||
/*
|
||||
@@ -49,7 +53,7 @@ double SpeedFunction::scaledValue(double time, double duration, double pathLengt
|
||||
return (pathLength * this->value(t)) / (duration * _integratedSum);
|
||||
}
|
||||
|
||||
void SpeedFunction::initIntegratedSum() {
|
||||
void SpeedFunction::initializeIntegratedSum() {
|
||||
const int steps = 100;
|
||||
_integratedSum = helpers::simpsonsRule(
|
||||
0.0,
|
||||
@@ -59,54 +63,36 @@ void SpeedFunction::initIntegratedSum() {
|
||||
);
|
||||
}
|
||||
|
||||
SexticDampenedSpeed::SexticDampenedSpeed() {
|
||||
initIntegratedSum();
|
||||
}
|
||||
|
||||
double SexticDampenedSpeed::value(double t) const {
|
||||
double SpeedFunction::value(double t) const {
|
||||
ghoul_assert(t >= 0.0 && t <= 1.0, "Variable t out of range [0,1]");
|
||||
|
||||
const double tPeak = 0.5;
|
||||
double speed = 0.0;
|
||||
|
||||
// accelerate
|
||||
auto applyEasingFunction = [this](double tScaled) {
|
||||
switch (_type) {
|
||||
case Type::DampenedQuintic:
|
||||
return ghoul::cubicEaseInOut(ghoul::quadraticEaseInOut(tScaled));
|
||||
break;
|
||||
case Type::DampenedSextic:
|
||||
return ghoul::cubicEaseInOut(ghoul::cubicEaseInOut(tScaled));
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
};
|
||||
|
||||
// Accelerate
|
||||
if (t <= tPeak) {
|
||||
double tScaled = t / tPeak;
|
||||
speed = ghoul::cubicEaseInOut(ghoul::cubicEaseInOut(tScaled));
|
||||
speed = applyEasingFunction(tScaled);
|
||||
}
|
||||
// deaccelerate
|
||||
// Deccelerate
|
||||
else if (t <= 1.0) {
|
||||
double tScaled = (t - tPeak) / (1.0 - tPeak);
|
||||
speed = 1.0 - ghoul::cubicEaseInOut(ghoul::cubicEaseInOut(tScaled));
|
||||
speed = 1.0 - applyEasingFunction(tScaled);
|
||||
}
|
||||
|
||||
// avoid zero speed
|
||||
speed += 0.00001; // TODO: Minimal speed should depend on size of visible object/node
|
||||
return speed;
|
||||
}
|
||||
|
||||
QuinticDampenedSpeed::QuinticDampenedSpeed() {
|
||||
initIntegratedSum();
|
||||
}
|
||||
|
||||
double QuinticDampenedSpeed::value(double t) const {
|
||||
ghoul_assert(t >= 0.0 && t <= 1.0, "Variable t out of range [0,1]");
|
||||
|
||||
const double tPeak = 0.5;
|
||||
double speed = 0.0;
|
||||
|
||||
// accelerate
|
||||
if (t <= tPeak) {
|
||||
double tScaled = t / tPeak;
|
||||
speed = ghoul::cubicEaseInOut(ghoul::quadraticEaseInOut(tScaled));
|
||||
}
|
||||
// deaccelerate
|
||||
else if (t <= 1.0) {
|
||||
double tScaled = (t - tPeak) / (1.0 - tPeak);
|
||||
speed = 1.0 - ghoul::cubicEaseInOut(ghoul::quadraticEaseInOut(tScaled));
|
||||
}
|
||||
|
||||
// avoid zero speed
|
||||
// Avoid zero speed
|
||||
speed += 0.00001; // TODO: Minimal speed should depend on size of visible object/node
|
||||
return speed;
|
||||
}
|
||||
|
||||
@@ -30,32 +30,27 @@ namespace openspace::autonavigation {
|
||||
// The speed function describing the shape of the speed curve. Values in [0,1].
|
||||
class SpeedFunction {
|
||||
public:
|
||||
SpeedFunction() = default;
|
||||
enum class Type {
|
||||
DampenedQuintic,
|
||||
DampenedSextic
|
||||
};
|
||||
|
||||
SpeedFunction(Type type = Type::DampenedQuintic);
|
||||
virtual ~SpeedFunction();
|
||||
|
||||
double scaledValue(double time, double duration, double pathLength) const;
|
||||
|
||||
virtual double value(double t) const = 0;
|
||||
virtual double value(double t) const;
|
||||
|
||||
protected:
|
||||
// must be called by each subclass after initialization
|
||||
void initIntegratedSum();
|
||||
void initializeIntegratedSum();
|
||||
|
||||
// store the sum of the function over the duration of the segment,
|
||||
// so we don't need to recompue it every time we access the speed
|
||||
double _integratedSum = 0.0;
|
||||
};
|
||||
|
||||
class SexticDampenedSpeed : public SpeedFunction {
|
||||
public:
|
||||
SexticDampenedSpeed();
|
||||
double value(double t) const override;
|
||||
};
|
||||
|
||||
class QuinticDampenedSpeed : public SpeedFunction {
|
||||
public:
|
||||
QuinticDampenedSpeed();
|
||||
double value(double t) const override;
|
||||
Type _type;
|
||||
};
|
||||
|
||||
} // namespace openspace::autonavigation
|
||||
|
||||
Reference in New Issue
Block a user