mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-23 12:39:24 -05:00
Move speed function out to its own class
This commit is contained in:
@@ -24,13 +24,9 @@
|
||||
|
||||
#include <modules/autonavigation/pathsegment.h>
|
||||
|
||||
#include <modules/autonavigation/helperfunctions.h>
|
||||
#include <modules/autonavigation/pathcurves.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/easing.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "PathSegment";
|
||||
@@ -38,18 +34,24 @@ namespace {
|
||||
|
||||
namespace openspace::autonavigation {
|
||||
|
||||
PathSegment::PathSegment(
|
||||
Waypoint start, Waypoint end, CurveType type)
|
||||
PathSegment::PathSegment(Waypoint start, Waypoint end, CurveType type,
|
||||
std::optional<double> duration = std::nullopt)
|
||||
: _start(start), _end(end), _curveType(type)
|
||||
{
|
||||
initCurve();
|
||||
|
||||
// TODO: compute default duration based on curve length
|
||||
// Also, when compensatng for simulation time later we need to make a guess for
|
||||
// the duration, based on the current position of the target.
|
||||
_duration = 5;
|
||||
// TODO: handle duration better
|
||||
if (duration.has_value()) {
|
||||
_duration = duration.value();
|
||||
}
|
||||
else {
|
||||
// TODO: compute default duration based on curve length
|
||||
// Also, when compensatng for simulation time later we need to make a guess for
|
||||
// the duration, based on the current position of the target.
|
||||
_duration = 5;
|
||||
}
|
||||
|
||||
_speedFunction = SpeedFunction(_duration);
|
||||
_speedFunction = std::make_unique<CubicDampenedSpeed>(_duration); // TODO: per curve type
|
||||
}
|
||||
|
||||
void PathSegment::setStart(Waypoint cs) {
|
||||
@@ -58,11 +60,6 @@ void PathSegment::setStart(Waypoint cs) {
|
||||
// TODO later: maybe recompute duration as well...
|
||||
}
|
||||
|
||||
void PathSegment::setDuration(double d) {
|
||||
_duration = d;
|
||||
_speedFunction = SpeedFunction(_duration);
|
||||
}
|
||||
|
||||
const Waypoint PathSegment::start() const { return _start; }
|
||||
|
||||
const Waypoint PathSegment::end() const { return _end; }
|
||||
@@ -111,16 +108,8 @@ bool PathSegment::hasReachedEnd() const {
|
||||
return (_traveledDistance / pathLength()) >= 1.0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get speed at time value in the range [0, duration]
|
||||
* OBS! If integrated over the curve it must match the total length or the curve.
|
||||
* Thus, we scale according to the constraint in eq. 14 in Eberly 2007
|
||||
* (https://www.geometrictools.com/Documentation/MovingAlongCurveSpecifiedSpeed.pdf)
|
||||
*/
|
||||
double PathSegment::speedAtTime(double time) const {
|
||||
ghoul_assert(time >= 0 && time <= _duration, "Time out of range [0, duration]");
|
||||
double t = std::clamp(time / _duration, 0.0, 1.0);
|
||||
return (pathLength() * _speedFunction.value(t)) / _speedFunction.integratedSum;
|
||||
return _speedFunction->scaledValue(time, _duration, pathLength());
|
||||
}
|
||||
|
||||
CameraPose PathSegment::interpolatedPose(double u) const {
|
||||
@@ -147,40 +136,4 @@ void PathSegment::initCurve() {
|
||||
}
|
||||
}
|
||||
|
||||
PathSegment::SpeedFunction::SpeedFunction(double duration) {
|
||||
// apply duration constraint (eq. 14 in Eberly)
|
||||
double speedSum = 0.0;
|
||||
int steps = 100;
|
||||
double dt = duration / steps;
|
||||
const double h = 1.0 / steps;
|
||||
for (double t = 0.0; t <= 1.0; t += h) {
|
||||
double midpointSpeed = 0.5 * (value(t + 0.5*h) + value(t - 0.5*h));
|
||||
speedSum += dt * midpointSpeed;
|
||||
}
|
||||
|
||||
integratedSum = speedSum;
|
||||
}
|
||||
|
||||
double PathSegment::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 = 1.0;
|
||||
|
||||
// accelerate
|
||||
if (t <= tPeak) {
|
||||
double tScaled = t / tPeak;
|
||||
speed = ghoul::cubicEaseInOut(tScaled);
|
||||
}
|
||||
// deaccelerate
|
||||
else if (t < 1.0) {
|
||||
double tScaled = (t - tPeak) / (1.0 - tPeak);
|
||||
speed = 1.0 - ghoul::cubicEaseInOut(tScaled);
|
||||
}
|
||||
|
||||
// avoid zero speed
|
||||
speed += 0.001;
|
||||
return speed;
|
||||
}
|
||||
|
||||
} // namespace openspace::autonavigation
|
||||
|
||||
Reference in New Issue
Block a user