mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-13 00:38:33 -05:00
Improved look at rotation interpolation
This commit is contained in:
@@ -129,7 +129,7 @@ void PathSegment::initCurve() {
|
||||
{
|
||||
case CurveType::Bezier3:
|
||||
_curve = std::make_unique<Bezier3Curve>(_start, _end);
|
||||
_rotationInterpolator = std::make_unique<LookAtRotator>(
|
||||
_rotationInterpolator = std::make_unique<LookAtInterpolator>(
|
||||
_start.rotation(),
|
||||
_end.rotation(),
|
||||
_start.node()->worldPosition(),
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <modules/autonavigation/helperfunctions.h>
|
||||
#include <modules/autonavigation/waypoint.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/interpolator.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "RotationInterpolator";
|
||||
@@ -70,4 +71,57 @@ glm::dquat LookAtRotator::interpolate(double u) {
|
||||
return helpers::getLookAtQuaternion(_path->positionAt(u), lookAtPos, startUpVec);
|
||||
}
|
||||
|
||||
LookAtInterpolator::LookAtInterpolator(glm::dquat start, glm::dquat end,
|
||||
glm::dvec3 startLookAtPos,
|
||||
glm::dvec3 endLookAtPos,
|
||||
PathCurve* path)
|
||||
: RotationInterpolator(start, end),
|
||||
_startLookAtPos(startLookAtPos),
|
||||
_endLookAtPos(endLookAtPos),
|
||||
_path(path)
|
||||
{}
|
||||
|
||||
// Turn towards start node, turn towards end node, then turn to end view
|
||||
glm::dquat LookAtInterpolator::interpolate(double u) {
|
||||
//TODO: base on curve position?
|
||||
double u1 = 0.2;
|
||||
double u2 = 0.8;
|
||||
|
||||
glm::dvec3 startPosition = _path->positionAt(0.0);
|
||||
glm::dvec3 endPosition = _path->positionAt(1.0);
|
||||
|
||||
glm::dvec3 lookAtPos;
|
||||
if (u < u1) {
|
||||
// Create aim positions not too close to camera based on view direction
|
||||
glm::dvec3 startViewDir = glm::normalize(_start * glm::dvec3(0.0, 0.0, -1.0));
|
||||
double startViewDist = glm::length(startPosition - _startLookAtPos);
|
||||
glm::dvec3 startViewPos = startPosition + startViewDist * startViewDir;
|
||||
double uNew = u / u1;
|
||||
uNew = ghoul::cubicEaseInOut(uNew);
|
||||
lookAtPos = interpolation::linear(uNew, startViewPos, _startLookAtPos);
|
||||
}
|
||||
else if (u <= u2) {
|
||||
double uNew = (u - u1) / (u2 - u1);
|
||||
uNew = ghoul::cubicEaseInOut(uNew);
|
||||
lookAtPos = interpolation::linear(uNew, _startLookAtPos, _endLookAtPos);
|
||||
}
|
||||
else if (u2 < u) {
|
||||
glm::dvec3 endViewDir = glm::normalize(_end * glm::dvec3(0.0, 0.0, -1.0));
|
||||
double endViewDist = glm::length(endPosition - _endLookAtPos);
|
||||
glm::dvec3 endViewPos = endPosition + endViewDist * endViewDir;
|
||||
double uNew = (u - u2) / (1.0 - u2);
|
||||
uNew = ghoul::cubicEaseInOut(uNew);
|
||||
lookAtPos = interpolation::linear(uNew, _endLookAtPos, endViewPos);
|
||||
}
|
||||
|
||||
// handle up vector
|
||||
glm::dvec3 startUp = _start * glm::dvec3(0.0, 1.0, 0.0);
|
||||
glm::dvec3 endUp = _end * glm::dvec3(0.0, 1.0, 0.0);
|
||||
|
||||
double uUp = ghoul::cubicEaseInOut(u);
|
||||
glm::dvec3 up = ghoul::interpolateLinear(uUp, startUp, endUp);
|
||||
|
||||
return helpers::getLookAtQuaternion(_path->positionAt(u), lookAtPos, up);
|
||||
}
|
||||
|
||||
} // namespace openspace::autonavigation
|
||||
|
||||
@@ -63,6 +63,20 @@ private:
|
||||
PathCurve* _path = nullptr;
|
||||
};
|
||||
|
||||
// Interpolates a look at position for the camera, and takes the start and end rotation
|
||||
// into account
|
||||
class LookAtInterpolator : public RotationInterpolator {
|
||||
public:
|
||||
LookAtInterpolator(glm::dquat start, glm::dquat end, glm::dvec3 startLookAtPos,
|
||||
glm::dvec3 endLookAtPos, PathCurve* path);
|
||||
glm::dquat interpolate(double u);
|
||||
|
||||
private:
|
||||
glm::dvec3 _startLookAtPos;
|
||||
glm::dvec3 _endLookAtPos;
|
||||
PathCurve* _path = nullptr;
|
||||
};
|
||||
|
||||
} // namespace openspace::autonavigation
|
||||
|
||||
#endif // __OPENSPACE_MODULE_AUTONAVIGATION___ROTATIONINTERPOLATOR___H__
|
||||
|
||||
Reference in New Issue
Block a user