mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-25 05:28:37 -05:00
Initial navigation with mouse during path traversal
This commit is contained in:
@@ -27,6 +27,9 @@
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/interaction/delayedvariable.h>
|
||||
#include <openspace/interaction/interpolator.h>
|
||||
#include <openspace/interaction/mousecamerastates.h>
|
||||
#include <openspace/navigation/path.h>
|
||||
#include <openspace/properties/list/stringlistproperty.h>
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
@@ -64,6 +67,10 @@ public:
|
||||
bool isPlayingPath() const;
|
||||
|
||||
void updateCamera(double deltaTime);
|
||||
|
||||
void updateStatesFromInput(const MouseInputState& mouseInputState,
|
||||
const KeyboardInputState& keyboardInputState, double deltaTime);
|
||||
|
||||
void createPath(const ghoul::Dictionary& dictionary);
|
||||
void clearPath();
|
||||
void startPath();
|
||||
@@ -86,6 +93,7 @@ private:
|
||||
*/
|
||||
void findRelevantNodes();
|
||||
|
||||
void applyLocalRotationFromInput(CameraPose& pose, double deltaTime);
|
||||
void removeRollRotation(CameraPose& pose, double deltaTime);
|
||||
|
||||
std::unique_ptr<Path> _currentPath = nullptr;
|
||||
@@ -100,6 +108,13 @@ private:
|
||||
|
||||
std::vector<SceneGraphNode*> _relevantNodes;
|
||||
bool _hasInitializedRelevantNodes = false;
|
||||
|
||||
properties::FloatProperty _mouseSensitivity;
|
||||
MouseCameraStates _mouseStates;
|
||||
|
||||
float _localPanAngle = 0.f;
|
||||
float _localTiltAngle = 0.f;
|
||||
float _localRollAngle = 0.f;
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
@@ -177,6 +177,11 @@ void NavigationHandler::updateCamera(double deltaTime) {
|
||||
_keyframeNavigator.updateCamera(*_camera, _playbackModeEnabled);
|
||||
}
|
||||
else if (_pathNavigator.isPlayingPath()) {
|
||||
_pathNavigator.updateStatesFromInput(
|
||||
_mouseInputState,
|
||||
_keyboardInputState,
|
||||
deltaTime
|
||||
);
|
||||
_pathNavigator.updateCamera(deltaTime);
|
||||
updateCameraTransitions();
|
||||
}
|
||||
|
||||
@@ -87,6 +87,17 @@ namespace {
|
||||
"List of tags for the nodes that are relevant for path creation, for example "
|
||||
"when avoiding collisions."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo MouseSensitivityInfo = {
|
||||
"MouseSensitivity",
|
||||
"Mouse Sensitivity",
|
||||
"Determines the sensitivity of the camera motion thorugh the mouse. The lower "
|
||||
"the sensitivity is the less impact a mouse motion will have."
|
||||
};
|
||||
|
||||
// TEST: for now use constant friction
|
||||
const float Friction = 0.5f; // [0, 1]
|
||||
const float RollFriction = 1.f; // [0, 1]
|
||||
} // namespace
|
||||
|
||||
#include "pathnavigator_lua.inl"
|
||||
@@ -104,6 +115,8 @@ PathNavigator::PathNavigator()
|
||||
, _applyIdleBehaviorOnFinish(IdleBehaviorOnFinishInfo, false)
|
||||
, _minValidBoundingSphere(MinBoundingSphereInfo, 10.0, 1.0, 3e10)
|
||||
, _relevantNodeTags(RelevantNodeTagsInfo)
|
||||
, _mouseSensitivity(MouseSensitivityInfo, 15.f, 1.f, 50.f)
|
||||
, _mouseStates(_mouseSensitivity * 0.0001, 1.0 / (Friction + 0.0000001))
|
||||
{
|
||||
_defaultPathType.addOptions({
|
||||
{ Path::Type::AvoidCollision, "AvoidCollision" },
|
||||
@@ -124,6 +137,12 @@ PathNavigator::PathNavigator()
|
||||
};
|
||||
_relevantNodeTags.onChange([this]() { findRelevantNodes(); });
|
||||
addProperty(_relevantNodeTags);
|
||||
|
||||
_mouseStates.setRotationalFriction(RollFriction);
|
||||
_mouseSensitivity.onChange([&]() {
|
||||
_mouseStates.setSensitivity(_mouseSensitivity * 0.0001);
|
||||
});
|
||||
addProperty(_mouseSensitivity);
|
||||
}
|
||||
|
||||
PathNavigator::~PathNavigator() {} // NOLINT
|
||||
@@ -195,6 +214,8 @@ void PathNavigator::updateCamera(double deltaTime) {
|
||||
removeRollRotation(newPose, deltaTime);
|
||||
}
|
||||
|
||||
applyLocalRotationFromInput(newPose, deltaTime);
|
||||
|
||||
camera()->setPositionVec3(newPose.position);
|
||||
camera()->setRotation(newPose.rotation);
|
||||
|
||||
@@ -218,6 +239,13 @@ void PathNavigator::updateCamera(double deltaTime) {
|
||||
}
|
||||
}
|
||||
|
||||
void PathNavigator::updateStatesFromInput(const MouseInputState& mouseInputState,
|
||||
const KeyboardInputState& keyboardInputState,
|
||||
double deltaTime)
|
||||
{
|
||||
_mouseStates.updateStateFromInput(mouseInputState, keyboardInputState, deltaTime);
|
||||
}
|
||||
|
||||
void PathNavigator::createPath(const ghoul::Dictionary& dictionary) {
|
||||
// @TODO (2021-08.16, emmbr): Improve how curve types are handled.
|
||||
// We want the user to be able to choose easily
|
||||
@@ -272,6 +300,12 @@ void PathNavigator::startPath() {
|
||||
LINFO("Starting path");
|
||||
_isPlaying = true;
|
||||
|
||||
// TEST: interaction
|
||||
_localPanAngle = 0.f;
|
||||
_localTiltAngle = 0.f;
|
||||
_localRollAngle = 0.f;
|
||||
_mouseStates.resetVelocities();
|
||||
|
||||
global::navigationHandler->orbitalNavigator().updateOnCameraInteraction();
|
||||
}
|
||||
|
||||
@@ -368,6 +402,48 @@ void PathNavigator::findRelevantNodes() {
|
||||
_relevantNodes = resultingNodes;
|
||||
}
|
||||
|
||||
void PathNavigator::applyLocalRotationFromInput(CameraPose& pose, double deltaTime) {
|
||||
const float maxAngle = glm::radians(30.f);
|
||||
|
||||
const glm::dvec2 velocity = _mouseStates.globalRotationVelocity();
|
||||
_localPanAngle += velocity.x;
|
||||
_localPanAngle = std::clamp(_localPanAngle, -maxAngle, maxAngle);
|
||||
_localTiltAngle += velocity.y;
|
||||
_localTiltAngle = std::clamp(_localTiltAngle, -maxAngle, maxAngle);
|
||||
|
||||
const float rollVelocity = _mouseStates.globalRollVelocity().x; // OBS! Adding delta time leads to too small sensitivity
|
||||
_localRollAngle = 0.1 * rollVelocity; // Note: Not adding here on purpose. The roll will be preserved between frams if roll is removed
|
||||
//_localRollAngle = std::clamp(_localRollAngle, -maxAngle, maxAngle);
|
||||
|
||||
//LINFO(fmt::format("Pan angle: {}", _localPanAngle));
|
||||
//LINFO(fmt::format("Tilt angle: {}", _localTiltAngle));
|
||||
//LINFO(fmt::format("Roll angle: {}", _localRollAngle));
|
||||
|
||||
const glm::dvec3 cameraForward = camera()->viewDirectionWorldSpace();
|
||||
const glm::dvec3 cameraUp = camera()->lookUpVectorWorldSpace();
|
||||
const glm::dvec3 cameraRight = glm::cross(cameraForward, cameraUp);
|
||||
|
||||
const glm::dquat panDiffRotation = glm::angleAxis(
|
||||
static_cast<double>(_localPanAngle),
|
||||
cameraUp
|
||||
);
|
||||
|
||||
const glm::dquat tiltDiffRotation = glm::angleAxis(
|
||||
static_cast<double>(_localTiltAngle),
|
||||
cameraRight
|
||||
);
|
||||
|
||||
const glm::dquat rollDiffRotation = glm::angleAxis(
|
||||
static_cast<double>(_localRollAngle),
|
||||
cameraForward
|
||||
);
|
||||
|
||||
pose.rotation = tiltDiffRotation * panDiffRotation * rollDiffRotation * pose.rotation;
|
||||
|
||||
// Reset velocities after every frame
|
||||
_mouseStates.resetVelocities();
|
||||
}
|
||||
|
||||
void PathNavigator::removeRollRotation(CameraPose& pose, double deltaTime) {
|
||||
const glm::dvec3 anchorPos = anchor()->worldPosition();
|
||||
const glm::dvec3 cameraDir = glm::normalize(
|
||||
|
||||
Reference in New Issue
Block a user