mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-22 12:59:07 -06:00
Split up path helper functions to separate, more specific, files
Some in Ghoul and some in OpenSpace core util
This commit is contained in:
Submodule ext/ghoul updated: 2ffa7b7f7a...152e6cd6c9
@@ -40,7 +40,7 @@ public:
|
||||
|
||||
/*
|
||||
* Compute and rteturn the position along the path at the specified relative
|
||||
* distance. The input parameter should be in range [0, 1], where 1 correspond to
|
||||
* distance. The input parameter should be in range [0, 1], where 1 correspond to
|
||||
* the full length of the path
|
||||
*/
|
||||
glm::dvec3 positionAt(double relativeDistance);
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
protected:
|
||||
/*
|
||||
* Precompute information related to the spline parameters, that are
|
||||
* needed for arc length reparameterization. Must be called after
|
||||
* needed for arc length reparameterization. Must be called after
|
||||
* control point creation
|
||||
*/
|
||||
void initializeParameterData();
|
||||
@@ -75,11 +75,11 @@ protected:
|
||||
double arcLength(double lowerLimit, double upperLimit);
|
||||
|
||||
std::vector<glm::dvec3> _points;
|
||||
unsigned int _nSegments;
|
||||
unsigned int _nSegments = 0;
|
||||
|
||||
std::vector<double> _curveParameterSteps; // per segment
|
||||
std::vector<double> _lengthSums; // per segment
|
||||
double _totalLength;
|
||||
double _totalLength = 0.0;
|
||||
|
||||
struct ParameterPair {
|
||||
double u; // curve parameter
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___PATHHELPERFUNCTIONS___H__
|
||||
#define __OPENSPACE_CORE___PATHHELPERFUNCTIONS___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::helpers {
|
||||
|
||||
// Make interpolator parameter t [0,1] progress only inside a subinterval
|
||||
double shiftAndScale(double t, double newStart, double newEnd);
|
||||
|
||||
/*
|
||||
* Compute a quaternion that represents the rotation looking from \p eye to
|
||||
* \p center, with the specified \p up direction
|
||||
*/
|
||||
glm::dquat lookAtQuaternion(glm::dvec3 eye, glm::dvec3 center, glm::dvec3 up);
|
||||
|
||||
/*
|
||||
* Compute a view direction vector from a quaternion representing a rotation
|
||||
*/
|
||||
glm::dvec3 viewDirection(const glm::dquat& q);
|
||||
|
||||
/*
|
||||
* Calculate the intersection of a line and a sphere.
|
||||
* The line segment is defined from \p p1 to \p p2.
|
||||
* The sphere is defined by the radius \p r and center point \p center.
|
||||
* The resulting intersection point is stored in the \p intersectionPoint parameter.
|
||||
*
|
||||
* In the case of two intersection points, only care anout the first one.
|
||||
*
|
||||
* \return True if the line between \p p1 and \p p2 intersects the sphere given by
|
||||
* \p r and \p center, and false otherwise
|
||||
*/
|
||||
bool lineSphereIntersection(glm::dvec3 p1, glm::dvec3 p2, glm::dvec3 center,
|
||||
double r, glm::dvec3& intersectionPoint);
|
||||
|
||||
/*
|
||||
* Check if the point p is inside of the sphere defined by radius r and center
|
||||
* point c
|
||||
*/
|
||||
bool isPointInsideSphere(const glm::dvec3& p, const glm::dvec3& c, double r);
|
||||
|
||||
/*
|
||||
* Approximate integral of function f over inteval [t0, t1] using Simpson's rule.
|
||||
* The integer n is the number of partitions and must be an even number.
|
||||
*/
|
||||
double simpsonsRule(double t0, double t1, int n, std::function<double(double)> f);
|
||||
|
||||
/*
|
||||
* Approximate integral of function f over inteval [t0, t1] using
|
||||
* 5-point Gauss-Legendre quadrature
|
||||
* https://en.wikipedia.org/wiki/Gaussian_quadrature
|
||||
*/
|
||||
double fivePointGaussianQuadrature(double t0, double t1,
|
||||
std::function<double(double)> f);
|
||||
|
||||
} // namespace openspace::helpers
|
||||
|
||||
namespace openspace::splines {
|
||||
|
||||
// TODO: Move these to ghoul's interpolator file (and make template versions)
|
||||
|
||||
/*
|
||||
* Catmull-Rom curve interpolation based on implementation by Mika Rantanen
|
||||
* https://qroph.github.io/2018/07/30/smooth-paths-using-catmull-rom-splines.html
|
||||
* Centripetal version alpha = 0, uniform for alpha = 0.5 and chordal for alpha = 1
|
||||
*/
|
||||
glm::dvec3 catmullRom(double t, const glm::dvec3& p0, const glm::dvec3& p1,
|
||||
const glm::dvec3& p2, const glm::dvec3& p3, double alpha = 0.5);
|
||||
|
||||
/*
|
||||
* Compute the interpolation along the cubic Bézier curve defined by the points p0,
|
||||
* p1, p2, and p3. The curve will pass through p0 and p3
|
||||
*/
|
||||
glm::dvec3 cubicBezier(double t, const glm::dvec3& p0, const glm::dvec3& p1,
|
||||
const glm::dvec3& p2, const glm::dvec3& p3);
|
||||
|
||||
glm::dvec3 linear(double t, const glm::dvec3& cp1, const glm::dvec3& cp2);
|
||||
|
||||
} // namespace openspace::splines
|
||||
#endif // __OPENSPACE_CORE___PATHHELPERFUNCTIONS___H__
|
||||
59
include/openspace/util/collisionhelper.h
Normal file
59
include/openspace/util/collisionhelper.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___COLLISIONHELPER___H__
|
||||
#define __OPENSPACE_CORE___COLLISIONHELPER___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace openspace::collision {
|
||||
|
||||
/*
|
||||
* Calculate the intersection of a line segment and a sphere.
|
||||
* The line segment is defined from \p p1 to \p p2.
|
||||
* The sphere is defined by the radius \p r and center point \p center.
|
||||
* The resulting intersection point is stored in the \p intersectionPoint parameter.
|
||||
*
|
||||
* In the case of two intersection points, only care about the first one.
|
||||
*
|
||||
* \param p1 The start point for the line segment
|
||||
* \param p2 The end point for the line segment
|
||||
* \param center The center point for the sphere
|
||||
* \param r The radius of the sphere
|
||||
* \param intersectionPoint A variable to store the resulting intersection point in
|
||||
* \return True if the line between \p p1 and \p p2 intersects the sphere given by
|
||||
* \p r and \p center, and false otherwise
|
||||
*/
|
||||
bool lineSphereIntersection(glm::dvec3 p1, glm::dvec3 p2, glm::dvec3 center,
|
||||
double r, glm::dvec3& intersectionPoint);
|
||||
|
||||
/*
|
||||
* Check if the point \p p is inside of the sphere defined by radius \p r and center
|
||||
* point \p c
|
||||
*/
|
||||
bool isPointInsideSphere(const glm::dvec3& p, const glm::dvec3& c, double r);
|
||||
|
||||
} // namespace openspace::collision
|
||||
|
||||
#endif // __OPENSPACE_CORE___COLLISIONHELPER___H__
|
||||
48
include/openspace/util/universalhelpers.h
Normal file
48
include/openspace/util/universalhelpers.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___UNIVERSALHELPERS___H__
|
||||
#define __OPENSPACE_CORE___UNIVERSALHELPERS___H__
|
||||
|
||||
/*
|
||||
* This file is meant to contain generally useful functions that is used a bit all over
|
||||
* the place but that do not belong in any other, more specific, file.
|
||||
*
|
||||
* If you implement a function that can be useful in several other situations, feel free
|
||||
* to document it and put it this file
|
||||
*/
|
||||
|
||||
namespace openspace::helpers {
|
||||
|
||||
/*
|
||||
* Remap a parameter t in [0,1] to a subinterval [start, end], by shifting and scaling
|
||||
* the value to match the interval. If \p t is smaller than \p start, the return value
|
||||
* will be 0 and if bigger than \p end it will be 1. Other values will be linearly
|
||||
* interpolated within the range [start, end]
|
||||
*/
|
||||
double shiftAndScale(double t, double start, double end);
|
||||
|
||||
} // namespace openspace::helpers
|
||||
|
||||
#endif // __OPENSPACE_CORE___UNIVERSALHELPERS___H__
|
||||
@@ -73,7 +73,6 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/orbitalnavigator.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/path.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathcurve.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathhelperfunctions.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathnavigator.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathnavigator_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/waypoint.cpp
|
||||
@@ -161,6 +160,7 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/scripting/systemcapabilitiesbinding.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/blockplaneintersectiongeometry.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/boxgeometry.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/collisionhelper.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/coordinateconversion.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/distanceconversion.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/factorymanager.cpp
|
||||
@@ -189,6 +189,7 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/util/timerange.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/touch.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/transformationmanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/universalhelpers.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/versionchecker.cpp
|
||||
)
|
||||
|
||||
@@ -253,7 +254,6 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/orbitalnavigator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/path.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/pathcurve.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/pathhelperfunctions.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/pathnavigator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/waypoint.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h
|
||||
@@ -344,6 +344,7 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scripting/systemcapabilitiesbinding.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/blockplaneintersectiongeometry.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/boxgeometry.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/collisionhelper.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentjobmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentjobmanager.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentqueue.h
|
||||
@@ -382,6 +383,7 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/timemanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/timerange.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/touch.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/universalhelpers.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/updatestructures.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/versionchecker.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/transformationmanager.h
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/query/query.h>
|
||||
@@ -854,7 +853,7 @@ OrbitalNavigator::CameraRotationDecomposition
|
||||
const SceneGraphNode& reference)
|
||||
{
|
||||
const glm::dvec3 cameraUp = cameraPose.rotation * Camera::UpDirectionCameraSpace;
|
||||
const glm::dvec3 cameraViewDirection = helpers::viewDirection(cameraPose.rotation);
|
||||
const glm::dvec3 cameraViewDirection = ghoul::viewDirection(cameraPose.rotation);
|
||||
|
||||
const glm::dmat4 modelTransform = reference.modelTransform();
|
||||
const glm::dmat4 inverseModelTransform = glm::inverse(modelTransform);
|
||||
@@ -871,7 +870,7 @@ OrbitalNavigator::CameraRotationDecomposition
|
||||
);
|
||||
|
||||
// To avoid problem with lookup in up direction we adjust is with the view direction
|
||||
const glm::dquat globalCameraRotation = helpers::lookAtQuaternion(
|
||||
const glm::dquat globalCameraRotation = ghoul::lookAtQuaternion(
|
||||
glm::dvec3(0.0),
|
||||
-directionFromSurfaceToCamera,
|
||||
normalize(cameraViewDirection + cameraUp)
|
||||
@@ -888,10 +887,10 @@ OrbitalNavigator::CameraRotationDecomposition
|
||||
glm::dvec3 reference)
|
||||
{
|
||||
const glm::dvec3 cameraUp = cameraPose.rotation * glm::dvec3(0.0, 1.0, 0.0);
|
||||
const glm::dvec3 cameraViewDirection = helpers::viewDirection(cameraPose.rotation);
|
||||
const glm::dvec3 cameraViewDirection = ghoul::viewDirection(cameraPose.rotation);
|
||||
|
||||
// To avoid problem with lookup in up direction we adjust is with the view direction
|
||||
const glm::dquat globalCameraRotation = helpers::lookAtQuaternion(
|
||||
const glm::dquat globalCameraRotation = ghoul::lookAtQuaternion(
|
||||
glm::dvec3(0.0),
|
||||
reference - cameraPose.position,
|
||||
normalize(cameraViewDirection + cameraUp)
|
||||
@@ -1068,7 +1067,7 @@ glm::dquat OrbitalNavigator::interpolateLocalRotation(double deltaTime,
|
||||
const glm::dvec3 localUp =
|
||||
localCameraRotation * Camera::UpDirectionCameraSpace;
|
||||
|
||||
const glm::dquat targetRotation = helpers::lookAtQuaternion(
|
||||
const glm::dquat targetRotation = ghoul::lookAtQuaternion(
|
||||
glm::dvec3(0.0),
|
||||
Camera::ViewDirectionCameraSpace,
|
||||
normalize(localUp)
|
||||
@@ -1299,7 +1298,7 @@ glm::dquat OrbitalNavigator::rotateGlobally(const glm::dquat& globalCameraRotati
|
||||
const glm::dvec3 cameraUpWhenFacingSurface = glm::inverse(focusNodeRotationDiff) *
|
||||
globalCameraRotation * Camera::UpDirectionCameraSpace;
|
||||
|
||||
return helpers::lookAtQuaternion(
|
||||
return ghoul::lookAtQuaternion(
|
||||
glm::dvec3(0.0),
|
||||
-directionFromSurfaceToCamera,
|
||||
cameraUpWhenFacingSurface
|
||||
|
||||
@@ -32,10 +32,11 @@
|
||||
#include <openspace/navigation/pathcurve.h>
|
||||
#include <openspace/navigation/pathcurves/avoidcollisioncurve.h>
|
||||
#include <openspace/navigation/pathcurves/zoomoutoverviewcurve.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/util/collisionhelper.h>
|
||||
#include <openspace/util/universalhelpers.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/interpolator.h>
|
||||
|
||||
@@ -198,7 +199,7 @@ glm::dquat Path::lookAtTargetsRotation(double t) const {
|
||||
if (t < t1) {
|
||||
// Compute a position in front of the camera at the start orientation
|
||||
const double inFrontDistance = glm::distance(startPos, startNodePos);
|
||||
const glm::dvec3 viewDir = helpers::viewDirection(_start.rotation());
|
||||
const glm::dvec3 viewDir = ghoul::viewDirection(_start.rotation());
|
||||
const glm::dvec3 inFrontOfStart = startPos + inFrontDistance * viewDir;
|
||||
|
||||
const double tScaled = ghoul::cubicEaseInOut(t / t1);
|
||||
@@ -212,7 +213,7 @@ glm::dquat Path::lookAtTargetsRotation(double t) const {
|
||||
else if (t > t2) {
|
||||
// Compute a position in front of the camera at the end orientation
|
||||
const double inFrontDistance = glm::distance(endPos, endNodePos);
|
||||
const glm::dvec3 viewDir = helpers::viewDirection(_end.rotation());
|
||||
const glm::dvec3 viewDir = ghoul::viewDirection(_end.rotation());
|
||||
const glm::dvec3 inFrontOfEnd = endPos + inFrontDistance * viewDir;
|
||||
|
||||
const double tScaled = ghoul::cubicEaseInOut((t - t2) / (1.0 - t2));
|
||||
@@ -227,7 +228,7 @@ glm::dquat Path::lookAtTargetsRotation(double t) const {
|
||||
tUp = ghoul::sineEaseInOut(tUp);
|
||||
glm::dvec3 up = ghoul::interpolateLinear(tUp, startUp, endUp);
|
||||
|
||||
return helpers::lookAtQuaternion(_curve->positionAt(t), lookAtPos, up);
|
||||
return ghoul::lookAtQuaternion(_curve->positionAt(t), lookAtPos, up);
|
||||
}
|
||||
|
||||
double Path::speedAlongPath(double traveledDistance) {
|
||||
@@ -303,7 +304,7 @@ SceneGraphNode* findNodeNearTarget(const SceneGraphNode* node) {
|
||||
const glm::dvec3 posInModelCoords =
|
||||
glm::inverse(n->modelTransform()) * glm::dvec4(node->worldPosition(), 1.0);
|
||||
|
||||
bool isClose = helpers::isPointInsideSphere(
|
||||
bool isClose = collision::isPointInsideSphere(
|
||||
posInModelCoords,
|
||||
glm::dvec3(0.0, 0.0, 0.0),
|
||||
proximityRadius
|
||||
@@ -317,19 +318,19 @@ SceneGraphNode* findNodeNearTarget(const SceneGraphNode* node) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Compute a target position close to the specified target node, using knowledge of
|
||||
// Compute a target position close to the specified target node, using knowledge of
|
||||
// the start point and a desired distance from the node's center
|
||||
glm::dvec3 computeGoodStepDirection(const SceneGraphNode* targetNode,
|
||||
glm::dvec3 computeGoodStepDirection(const SceneGraphNode* targetNode,
|
||||
const Waypoint& startPoint)
|
||||
{
|
||||
const glm::dvec3 nodePos = targetNode->worldPosition();
|
||||
const SceneGraphNode* closeNode = findNodeNearTarget(targetNode);
|
||||
const SceneGraphNode* sun = sceneGraphNode(SunIdentifier);
|
||||
|
||||
// @TODO (2021-07-09, emmbr): Not nice to depend on a specific scene graph node,
|
||||
// as it might not exist. Ideally, each SGN could know about their preferred
|
||||
// direction to be viewed from (their "good side"), and then that could be queried
|
||||
// and used instead.
|
||||
// @TODO (2021-07-09, emmbr): Not nice to depend on a specific scene graph node,
|
||||
// as it might not exist. Ideally, each SGN could know about their preferred
|
||||
// direction to be viewed from (their "good side"), and then that could be queried
|
||||
// and used instead.
|
||||
if (closeNode) {
|
||||
// If the node is close to another node in the scene, set the direction in a way
|
||||
// that minimizes risk of collision
|
||||
@@ -378,7 +379,7 @@ Waypoint computeWaypointFromNodeInfo(const NodeInfo& info, const Waypoint& start
|
||||
|
||||
glm::dvec3 targetPos;
|
||||
if (info.position.has_value()) {
|
||||
// The position in instruction is given in the targetNode's local coordinates.
|
||||
// The position in instruction is given in the targetNode's local coordinates.
|
||||
// Convert to world coordinates
|
||||
targetPos = glm::dmat3(targetNode->modelTransform()) * info.position.value();
|
||||
}
|
||||
@@ -402,7 +403,7 @@ Waypoint computeWaypointFromNodeInfo(const NodeInfo& info, const Waypoint& start
|
||||
|
||||
// Compute rotation so the camera is looking at the targetted node
|
||||
const glm::dvec3 lookAtPos = targetNode->worldPosition();
|
||||
const glm::dquat targetRot = helpers::lookAtQuaternion(targetPos, lookAtPos, up);
|
||||
const glm::dquat targetRot = ghoul::lookAtQuaternion(targetPos, lookAtPos, up);
|
||||
|
||||
return Waypoint(targetPos, targetRot, info.identifier);
|
||||
}
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
|
||||
#include <openspace/navigation/pathcurve.h>
|
||||
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/navigation/waypoint.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/integration.h>
|
||||
#include <ghoul/misc/interpolator.h>
|
||||
#include <glm/gtx/projection.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
@@ -188,7 +189,7 @@ double PathCurve::arcLength(double limit) {
|
||||
}
|
||||
|
||||
double PathCurve::arcLength(double lowerLimit, double upperLimit) {
|
||||
return helpers::fivePointGaussianQuadrature(
|
||||
return ghoul::integrateGaussianQuadrature<double>(
|
||||
lowerLimit,
|
||||
upperLimit,
|
||||
[this](double u) { return approximatedDerivative(u); }
|
||||
@@ -196,7 +197,7 @@ double PathCurve::arcLength(double lowerLimit, double upperLimit) {
|
||||
}
|
||||
|
||||
glm::dvec3 PathCurve::interpolate(double u) {
|
||||
ghoul_assert(u >= 0 && u <= 1.0, "Interpolation variable out of range [0, 1]");
|
||||
ghoul_assert(u >= 0 && u <= 1.0, "Interpolation variable must be in range [0,1]");
|
||||
|
||||
if (u < 0.0) {
|
||||
return _points[1];
|
||||
@@ -208,14 +209,14 @@ glm::dvec3 PathCurve::interpolate(double u) {
|
||||
std::vector<double>::iterator segmentEndIt =
|
||||
std::lower_bound(_curveParameterSteps.begin(), _curveParameterSteps.end(), u);
|
||||
|
||||
const int index =
|
||||
const int index =
|
||||
static_cast<int>((segmentEndIt - 1) - _curveParameterSteps.begin());
|
||||
|
||||
double segmentStart = _curveParameterSteps[index];
|
||||
double segmentDuration = (_curveParameterSteps[index + 1] - segmentStart);
|
||||
double uSegment = (u - segmentStart) / segmentDuration;
|
||||
|
||||
return splines::catmullRom(
|
||||
return ghoul::interpolateCatmullRom(
|
||||
uSegment,
|
||||
_points[index],
|
||||
_points[index + 1],
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/navigation/waypoint.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/collisionhelper.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <glm/gtx/projection.hpp>
|
||||
#include <algorithm>
|
||||
@@ -60,7 +60,7 @@ AvoidCollisionCurve::AvoidCollisionCurve(const Waypoint& start, const Waypoint&
|
||||
const glm::dvec3 endNodeCenter = end.node()->worldPosition();
|
||||
const double startNodeRadius = start.validBoundingSphere();
|
||||
const double endNodeRadius = end.validBoundingSphere();
|
||||
const glm::dvec3 startViewDir = helpers::viewDirection(start.rotation());
|
||||
const glm::dvec3 startViewDir = ghoul::viewDirection(start.rotation());
|
||||
|
||||
// Add control points for a catmull-rom spline, first and last will not be intersected
|
||||
_points.push_back(start.position());
|
||||
@@ -83,7 +83,7 @@ AvoidCollisionCurve::AvoidCollisionCurve(const Waypoint& start, const Waypoint&
|
||||
|
||||
if (targetInOppositeDirection) {
|
||||
const glm::dquat midleRot = glm::slerp(start.rotation(), end.rotation(), 0.5);
|
||||
const glm::dvec3 middleViewDir = helpers::viewDirection(midleRot);
|
||||
const glm::dvec3 middleViewDir = ghoul::viewDirection(midleRot);
|
||||
const double stepOutDistance = 0.4 * glm::length(startToEnd);
|
||||
|
||||
glm::dvec3 newPos = start.position() + 0.2 * startToEnd -
|
||||
@@ -137,14 +137,14 @@ void AvoidCollisionCurve::removeCollisions(int step) {
|
||||
// Add a buffer to avoid passing too close to the node.
|
||||
// Dont't add it if any point is inside the buffer
|
||||
double buffer = CollisionBufferSizeRadiusMultiplier * radius;
|
||||
bool p1IsInside = helpers::isPointInsideSphere(p1, center, radius + buffer);
|
||||
bool p2IsInside = helpers::isPointInsideSphere(p2, center, radius + buffer);
|
||||
bool p1IsInside = collision::isPointInsideSphere(p1, center, radius + buffer);
|
||||
bool p2IsInside = collision::isPointInsideSphere(p2, center, radius + buffer);
|
||||
if (!p1IsInside && !p2IsInside) {
|
||||
radius += buffer;
|
||||
}
|
||||
|
||||
glm::dvec3 intersectionPointModelCoords;
|
||||
bool collision = helpers::lineSphereIntersection(
|
||||
bool collision = collision::lineSphereIntersection(
|
||||
p1,
|
||||
p2,
|
||||
center,
|
||||
@@ -157,8 +157,8 @@ void AvoidCollisionCurve::removeCollisions(int step) {
|
||||
glm::dvec4(intersectionPointModelCoords, 1.0);
|
||||
|
||||
// before collision response, make sure none of the points are inside the node
|
||||
bool isStartInsideNode = helpers::isPointInsideSphere(p1, center, radius);
|
||||
bool isEndInsideNode = helpers::isPointInsideSphere(p2, center, radius);
|
||||
bool isStartInsideNode = collision::isPointInsideSphere(p1, center, radius);
|
||||
bool isEndInsideNode = collision::isPointInsideSphere(p2, center, radius);
|
||||
if (isStartInsideNode || isEndInsideNode) {
|
||||
LWARNING(fmt::format(
|
||||
"Something went wrong! "
|
||||
@@ -177,7 +177,7 @@ void AvoidCollisionCurve::removeCollisions(int step) {
|
||||
const glm::dvec3 parallell = glm::proj(collisionPointToCenter, lineDirection);
|
||||
const glm::dvec3 orthogonal = collisionPointToCenter - parallell;
|
||||
|
||||
const double avoidCollisionDistance =
|
||||
const double avoidCollisionDistance =
|
||||
AvoidCollisionDistanceRadiusMultiplier * radius;
|
||||
|
||||
glm::dvec3 extraKnot = collisionPoint -
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/navigation/waypoint.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
@@ -48,7 +47,7 @@ ZoomOutOverviewCurve::ZoomOutOverviewCurve(const Waypoint& start, const Waypoint
|
||||
|
||||
if (!start.node() || !end.node()) { // guard, but should never happen
|
||||
LERROR("Something went wrong. The start or end node does not exist");
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
const double endTangentsLengthFactor = 2.0;
|
||||
@@ -73,7 +72,7 @@ ZoomOutOverviewCurve::ZoomOutOverviewCurve(const Waypoint& start, const Waypoint
|
||||
// Decide the step direction for the "overview point" based on the directions
|
||||
// at the start and end of the path, to try to get a nice curve shape
|
||||
glm::dvec3 goodStepDirection;
|
||||
if (glm::dot(n1, n2) < 0.0) {
|
||||
if (glm::dot(n1, n2) < 0.0) {
|
||||
// Facing in different directions => step in direction of the cross product
|
||||
goodStepDirection = glm::normalize(glm::cross(-n1, n2));
|
||||
}
|
||||
@@ -83,13 +82,13 @@ ZoomOutOverviewCurve::ZoomOutOverviewCurve(const Waypoint& start, const Waypoint
|
||||
|
||||
// Find a direction that is orthogonal to the line between the start and end position
|
||||
const glm::dvec3 startPosToEndPos = end.position() - start.position();
|
||||
const glm::dvec3 outwardStepVector =
|
||||
const glm::dvec3 outwardStepVector =
|
||||
0.5 * glm::length(startPosToEndPos) * goodStepDirection;
|
||||
|
||||
const glm::dvec3 projectedVec = glm::proj(outwardStepVector, startPosToEndPos);
|
||||
const glm::dvec3 orthogonalComponent = outwardStepVector - projectedVec;
|
||||
const glm::dvec3 stepDirection = glm::normalize(orthogonalComponent);
|
||||
|
||||
|
||||
// Step half-way along the line between the position and then orthogonally
|
||||
const glm::dvec3 extraKnot = start.position() + 0.5 * startPosToEndPos
|
||||
+ 1.5 * glm::length(startPosToEndPos) * stepDirection;
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/easing.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "Helpers";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::helpers {
|
||||
|
||||
// Shift and scale to a subinterval [start,end]
|
||||
double shiftAndScale(double t, double start, double end) {
|
||||
ghoul_assert(0.0 < start && start < end && end < 1.0,
|
||||
"Values must be 0.0 < start < end < 1.0!");
|
||||
double tScaled = t / (end - start) - start;
|
||||
return std::max(0.0, std::min(tScaled, 1.0));
|
||||
}
|
||||
|
||||
glm::dquat lookAtQuaternion(glm::dvec3 eye, glm::dvec3 center, glm::dvec3 up) {
|
||||
glm::dmat4 lookAtMat = glm::lookAt(eye, center, up);
|
||||
return glm::normalize(glm::inverse(glm::quat_cast(lookAtMat)));
|
||||
}
|
||||
|
||||
glm::dvec3 viewDirection(const glm::dquat& q) {
|
||||
return glm::normalize(q * glm::dvec3(0.0, 0.0, -1.0));
|
||||
};
|
||||
|
||||
/*
|
||||
* Source: http://paulbourke.net/geometry/circlesphere/raysphere.c
|
||||
*/
|
||||
bool lineSphereIntersection(glm::dvec3 p1, glm::dvec3 p2, glm::dvec3 center,
|
||||
double r, glm::dvec3& intersectionPoint)
|
||||
{
|
||||
long double a, b, c;
|
||||
glm::dvec3 dp = p2 - p1;
|
||||
|
||||
a = dp.x * dp.x + dp.y * dp.y + dp.z * dp.z;
|
||||
b = 2.0 * (dp.x * (p1.x - center.x) + dp.y * (p1.y - center.y) +
|
||||
dp.z * (p1.z - center.z));
|
||||
c = center.x * center.x + center.y * center.y + center.z * center.z;
|
||||
c += p1.x * p1.x + p1.y * p1.y + p1.z * p1.z;
|
||||
c -= 2.0 * (center.x * p1.x + center.y * p1.y + center.z * p1.z);
|
||||
c -= r * r;
|
||||
|
||||
long double intersectionTest = b * b - 4.0 * a * c;
|
||||
|
||||
// No intersection
|
||||
if (std::abs(a) < 0 || intersectionTest < 0.0) {
|
||||
return false;
|
||||
}
|
||||
// Intersection
|
||||
else {
|
||||
// Only care about the first intersection point if we have two
|
||||
const double t = (-b - std::sqrt(intersectionTest)) / (2.0 *a);
|
||||
|
||||
// Check if utside of line segment between p1 and p2
|
||||
if (t <= 0 || t >= 1.0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
intersectionPoint = p1 + t * dp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool isPointInsideSphere(const glm::dvec3& p, const glm::dvec3& c, double r) {
|
||||
const glm::dvec3 v = c - p;
|
||||
const long double squaredDistance = v.x * v.x + v.y * v.y + v.z * v.z;
|
||||
const long double squaredRadius = r * r;
|
||||
|
||||
return (squaredDistance <= squaredRadius);
|
||||
}
|
||||
|
||||
double simpsonsRule(double t0, double t1, int n, std::function<double(double)> f) {
|
||||
ghoul_assert(n % 2 == 0, "n must be an even number");
|
||||
ghoul_assert(n >= 2, "Number of partitions, n, must be at least 2");
|
||||
|
||||
const double h = (t1 - t0) / static_cast<double>(n);
|
||||
const double endpoints = f(t0) + f(t1);
|
||||
double times4 = 0.0;
|
||||
double times2 = 0.0;
|
||||
|
||||
// weight 4
|
||||
for (int i = 1; i < n; i += 2) {
|
||||
double t = t0 + i * h;
|
||||
times4 += f(t);
|
||||
}
|
||||
|
||||
// weight 2
|
||||
for (int i = 2; i < n; i += 2) {
|
||||
double t = t0 + i * h;
|
||||
times2 += f(t);
|
||||
}
|
||||
|
||||
return (h / 3) * (endpoints + 4 * times4 + 2 * times2);
|
||||
}
|
||||
|
||||
double fivePointGaussianQuadrature(double t0, double t1,
|
||||
std::function<double(double)> f)
|
||||
{
|
||||
struct GaussLengendreCoefficient {
|
||||
double abscissa; // xi
|
||||
double weight; // wi
|
||||
};
|
||||
|
||||
static constexpr GaussLengendreCoefficient coefficients[] = {
|
||||
{ 0.0, 0.5688889 },
|
||||
{ -0.5384693, 0.47862867 },
|
||||
{ 0.5384693, 0.47862867 },
|
||||
{ -0.90617985, 0.23692688 },
|
||||
{ 0.90617985, 0.23692688 }
|
||||
};
|
||||
|
||||
const double a = t0;
|
||||
const double b = t1;
|
||||
double sum = 0.0;
|
||||
for (auto coefficient : coefficients) {
|
||||
// change of interval to [a, b] from [-1, 1] (also 0.5 * (b - a) below)
|
||||
double const t = 0.5 * ((b - a) * coefficient.abscissa + (b + a));
|
||||
sum += f(t) * coefficient.weight;
|
||||
}
|
||||
return 0.5 * (b - a) * sum;
|
||||
}
|
||||
|
||||
} // namespace openspace::helpers
|
||||
|
||||
namespace openspace::splines {
|
||||
|
||||
// Based on implementation by Mika Rantanen, but without tension
|
||||
// https://qroph.github.io/2018/07/30/smooth-paths-using-catmull-rom-splines.html
|
||||
glm::dvec3 catmullRom(double t, const glm::dvec3& p0, const glm::dvec3& p1,
|
||||
const glm::dvec3& p2, const glm::dvec3& p3, double alpha)
|
||||
{
|
||||
ghoul_assert(t >= 0 && t <= 1.0, "Interpolation variable out of range [0, 1]");
|
||||
|
||||
double t01 = std::pow(glm::distance(p0, p1), alpha);
|
||||
double t12 = std::pow(glm::distance(p1, p2), alpha);
|
||||
double t23 = std::pow(glm::distance(p2, p3), alpha);
|
||||
|
||||
constexpr const double Epsilon = 1E-7;
|
||||
const glm::dvec3 zero = glm::dvec3(0.0);
|
||||
glm::dvec3 m01 = (t01 > Epsilon) ? (p1 - p0) / t01 : zero;
|
||||
glm::dvec3 m23 = (t23 > Epsilon) ? (p3 - p2) / t23 : zero;
|
||||
glm::dvec3 m02 = (t01 + t12 > Epsilon) ? (p2 - p0) / (t01 + t12) : zero;
|
||||
glm::dvec3 m13 = (t12 + t23 > Epsilon) ? (p3 - p1) / (t12 + t23) : zero;
|
||||
|
||||
glm::dvec3 m1 = p2 - p1 + t12 * (m01 - m02);
|
||||
glm::dvec3 m2 = p2 - p1 + t12 * (m23 - m13);
|
||||
|
||||
glm::dvec3 a = 2.0 * (p1 - p2) + m1 + m2;
|
||||
glm::dvec3 b = -3.0 * (p1 - p2) - m1 - m1 - m2;
|
||||
glm::dvec3 c = m1;
|
||||
glm::dvec3 d = p1;
|
||||
|
||||
return a * t * t * t
|
||||
+ b * t * t
|
||||
+ c * t
|
||||
+ d;
|
||||
}
|
||||
|
||||
glm::dvec3 cubicBezier(double t, const glm::dvec3& p0, const glm::dvec3& p1,
|
||||
const glm::dvec3& p2, const glm::dvec3& p3)
|
||||
{
|
||||
ghoul_assert(t >= 0 && t <= 1.0, "Interpolation variable out of range [0, 1]");
|
||||
|
||||
double a = 1.0 - t;
|
||||
return p0 * a * a * a
|
||||
+ p1 * t * a * a * 3.0
|
||||
+ p2 * t * t * a * 3.0
|
||||
+ p3 * t * t * t;
|
||||
}
|
||||
|
||||
glm::dvec3 linear(double t, const glm::dvec3 &cp1, const glm::dvec3 &cp2) {
|
||||
ghoul_assert(t >= 0 && t <= 1.0, "Interpolation variable out of range [0, 1]");
|
||||
return cp1 * (1.0 - t) + cp2 * t;
|
||||
}
|
||||
} // namespace openspace::splines
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
@@ -61,8 +60,8 @@ namespace {
|
||||
"A camera motion behavior that is applied when no path is being played"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
ApplyStopBehaviorWhenIdleInfo =
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
ApplyStopBehaviorWhenIdleInfo =
|
||||
{
|
||||
"ApplyStopBehaviorWhenIdle",
|
||||
"Apply Stop Behavior When Idle",
|
||||
@@ -107,12 +106,12 @@ namespace openspace::interaction {
|
||||
PathNavigator::PathNavigator()
|
||||
: properties::PropertyOwner({ "PathNavigator" })
|
||||
, _defaultCurveOption(
|
||||
DefaultCurveOptionInfo,
|
||||
DefaultCurveOptionInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
, _includeRoll(IncludeRollInfo, false)
|
||||
, _stopBehavior(
|
||||
StopBehaviorInfo,
|
||||
StopBehaviorInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
, _applyStopBehaviorWhenIdle(ApplyStopBehaviorWhenIdleInfo, false)
|
||||
@@ -203,7 +202,7 @@ void PathNavigator::updateCamera(double deltaTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent long delta times due to e.g. computations from other actions to cause
|
||||
// Prevent long delta times due to e.g. computations from other actions to cause
|
||||
// really big jumps in the motion along the path
|
||||
// OBS! Causes problems if the general FPS is lower than 10, but then the user should
|
||||
// probably not use the camera paths anyways
|
||||
@@ -388,7 +387,7 @@ void PathNavigator::removeRollRotation(CameraPose& pose, double deltaTime) {
|
||||
const double anchorToPosDistance = glm::distance(anchorPos, pose.position);
|
||||
const double notTooCloseDistance = deltaTime * anchorToPosDistance;
|
||||
glm::dvec3 lookAtPos = pose.position + notTooCloseDistance * cameraDir;
|
||||
glm::dquat rollFreeRotation = helpers::lookAtQuaternion(
|
||||
glm::dquat rollFreeRotation = ghoul::lookAtQuaternion(
|
||||
pose.position,
|
||||
lookAtPos,
|
||||
camera()->lookUpVectorWorldSpace()
|
||||
@@ -414,7 +413,7 @@ void PathNavigator::orbitAnchorNode(double deltaTime) {
|
||||
|
||||
const glm::dvec3 prevPosition = camera()->positionVec3();
|
||||
const glm::dquat prevRotation = camera()->rotationQuaternion();
|
||||
const glm::dvec3 nodeCenter = anchor()->worldPosition();
|
||||
const glm::dvec3 nodeCenter = anchor()->worldPosition();
|
||||
|
||||
const double speedFactor = 0.1 * _orbitSpeedFactor;
|
||||
|
||||
@@ -425,7 +424,7 @@ void PathNavigator::orbitAnchorNode(double deltaTime) {
|
||||
|
||||
// Compute a new position along the orbit
|
||||
const glm::dvec3 up = camera()->lookUpVectorWorldSpace();
|
||||
const glm::dquat lookAtNodeRotation = helpers::lookAtQuaternion(
|
||||
const glm::dquat lookAtNodeRotation = ghoul::lookAtQuaternion(
|
||||
prevPosition,
|
||||
nodeCenter,
|
||||
up
|
||||
@@ -444,7 +443,7 @@ void PathNavigator::orbitAnchorNode(double deltaTime) {
|
||||
// Rotate along the orbit, but keep relative orientation with regards to the anchor
|
||||
const glm::dquat localRotation = glm::inverse(lookAtNodeRotation) * prevRotation;
|
||||
const glm::dquat newLookAtRotation =
|
||||
helpers::lookAtQuaternion(newPosition, nodeCenter, up);
|
||||
ghoul::lookAtQuaternion(newPosition, nodeCenter, up);
|
||||
|
||||
const glm::dquat newRotation = newLookAtRotation * localRotation;
|
||||
|
||||
|
||||
75
src/util/collisionhelper.cpp
Normal file
75
src/util/collisionhelper.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/util/collisionhelper.h>
|
||||
|
||||
namespace openspace::collision {
|
||||
|
||||
// Source: http://paulbourke.net/geometry/circlesphere/raysphere.c
|
||||
bool lineSphereIntersection(glm::dvec3 p1, glm::dvec3 p2, glm::dvec3 center,
|
||||
double r, glm::dvec3& intersectionPoint)
|
||||
{
|
||||
long double a, b, c;
|
||||
const glm::dvec3 diffp = p2 - p1;
|
||||
|
||||
a = diffp.x * diffp.x + diffp.y * diffp.y + diffp.z * diffp.z;
|
||||
b = 2.0 * (diffp.x * (p1.x - center.x) + diffp.y * (p1.y - center.y) +
|
||||
diffp.z * (p1.z - center.z));
|
||||
c = center.x * center.x + center.y * center.y + center.z * center.z;
|
||||
c += p1.x * p1.x + p1.y * p1.y + p1.z * p1.z;
|
||||
c -= 2.0 * (center.x * p1.x + center.y * p1.y + center.z * p1.z);
|
||||
c -= r * r;
|
||||
|
||||
long double intersectionTest = b * b - 4.0 * a * c;
|
||||
|
||||
// No intersection
|
||||
if (std::abs(a) < 0 || intersectionTest < 0.0) {
|
||||
return false;
|
||||
}
|
||||
// Intersection
|
||||
else {
|
||||
// Only care about the first intersection point if we have two
|
||||
const double t = static_cast<double>(
|
||||
(-b - std::sqrt(intersectionTest)) / (2.0 * a)
|
||||
);
|
||||
|
||||
// Check if utside of line segment between p1 and p2
|
||||
if (t <= 0 || t >= 1.0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
intersectionPoint = p1 + t * diffp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool isPointInsideSphere(const glm::dvec3& p, const glm::dvec3& c, double r) {
|
||||
const glm::dvec3 v = c - p;
|
||||
const long double squaredDistance = v.x * v.x + v.y * v.y + v.z * v.z;
|
||||
const long double squaredRadius = r * r;
|
||||
|
||||
return (squaredDistance <= squaredRadius);
|
||||
}
|
||||
|
||||
} // namespace openspace::collision
|
||||
37
src/util/universalhelpers.cpp
Normal file
37
src/util/universalhelpers.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/util/universalhelpers.h>
|
||||
|
||||
namespace openspace::helpers {
|
||||
|
||||
double shiftAndScale(double t, double start, double end) {
|
||||
ghoul_assert(0.0 < start && start < end && end < 1.0,
|
||||
"Values must be 0.0 < start < end < 1.0!");
|
||||
|
||||
double tScaled = t / (end - start) - start;
|
||||
return std::max(0.0, std::min(tScaled, 1.0));
|
||||
}
|
||||
|
||||
} // namespace openspace::helpers
|
||||
Reference in New Issue
Block a user