1#include <Gui/Viewer/FlightCameraManipulator.hpp>
3#include <Core/Asset/Camera.hpp>
4#include <Core/Math/Math.hpp>
5#include <Core/Utils/Log.hpp>
6#include <Engine/Scene/Light.hpp>
7#include <Gui/Utils/Keyboard.hpp>
9#include <Gui/Utils/KeyMappingManager.hpp>
11#include <Engine/Scene/CameraComponent.hpp>
12#include <QApplication>
23using namespace Core::Utils;
28#define KMA_VALUE( XX ) Gui::KeyMappingManager::KeyMappingAction Gui::FlightCameraManipulator::XX;
29KeyMappingFlightManipulator
32void FlightCameraManipulator::configureKeyMapping_impl() {
34 FlightCameraKeyMapping::setContext(
35 Gui::KeyMappingManager::getInstance()->getContext(
"FlightManipulatorContext" ) );
37 if ( KeyMapping::getContext().isInvalid() ) {
39 <<
"CameraContext not defined (maybe the configuration file do not contains "
40 "it). Add it for default key mapping.";
41 FlightCameraKeyMapping::setContext(
42 Gui::KeyMappingManager::getInstance()->addContext(
"FlightManipulatorContext" ) );
45#define KMA_VALUE( XX ) \
46 XX = Gui::KeyMappingManager::getInstance()->getAction( FlightCameraKeyMapping::getContext(), \
48 KeyMappingFlightManipulator
51 auto mgr = Gui::KeyMappingManager::getInstance();
52 auto context = FlightCameraKeyMapping::getContext();
56 KeyMappingManager::EventBinding>;
63 ActionBindingPair { FLIGHTMODECAMERA_PAN,
64 mgr->createEventBindingFromStrings(
65 "LeftButton",
"ShiftModifier" ) } ) );
69 ActionBindingPair { FLIGHTMODECAMERA_ROTATE,
70 mgr->createEventBindingFromStrings(
"LeftButton" ) } ) );
74 ActionBindingPair { FLIGHTMODECAMERA_ZOOM,
75 mgr->createEventBindingFromStrings(
76 "LeftButton",
"ControlModifier" ) } ) );
78 for (
auto& [actionName, actionBinding] : defaultBinding ) {
79 if ( actionBinding.first.get().isInvalid() ) {
80 LOG( logWARNING ) <<
"FlightManipulator action " << actionName
81 <<
" not defined in configuration file. Adding default keymapping.";
82 actionBinding.first.get() = mgr->addAction( context, actionBinding.second, actionName );
88void FlightCameraManipulator::setupKeyMappingCallbacks() {
91 [=]( QEvent* event ) { panCallback( event ); } );
93 FLIGHTMODECAMERA_ROTATE, [=]( QEvent* event ) { rotateCallback( event ); } );
96 [=]( QEvent* event ) { zoomCallback( event ); } );
99void FlightCameraManipulator::panCallback( QEvent* event ) {
100 if ( event->type() == QEvent::MouseMove ) {
101 auto mouseEvent =
reinterpret_cast<QMouseEvent*
>( event );
102 auto [dx, dy] = computeDeltaMouseMove( mouseEvent );
103 handleCameraPan( dx, dy );
107void FlightCameraManipulator::rotateCallback( QEvent* event ) {
108 if ( event->type() == QEvent::MouseMove ) {
109 auto mouseEvent =
reinterpret_cast<QMouseEvent*
>( event );
110 auto [dx, dy] = computeDeltaMouseMove( mouseEvent );
111 handleCameraRotate( dx, dy );
115void FlightCameraManipulator::zoomCallback( QEvent* event ) {
116 if ( event->type() == QEvent::MouseMove ) {
117 auto mouseEvent =
reinterpret_cast<QMouseEvent*
>( event );
118 auto [dx, dy] = computeDeltaMouseMove( mouseEvent );
119 handleCameraZoom( dx, dy );
121 if ( event->type() == QEvent::Wheel ) {
122 auto wheelEvent =
reinterpret_cast<QWheelEvent*
>( event );
124 ( wheelEvent->angleDelta().y() * 0.01_ra + wheelEvent->angleDelta().x() * 0.01_ra ) *
130 return FlightCameraKeyMapping::getContext();
133FlightCameraManipulator::FlightCameraManipulator() :
136 setupKeyMappingCallbacks();
144 initializeFixedUpVector();
145 setupKeyMappingCallbacks();
154 initializeFixedUpVector();
157 m_flightSpeed = 0.2_ra;
165void FlightCameraManipulator::resetCamera() {
168 initializeFixedUpVector();
171 m_flightSpeed = 0.2_ra;
180 const Qt::MouseButtons&,
181 const Qt::KeyboardModifiers&,
190 const Qt::MouseButtons& ,
191 const Qt::KeyboardModifiers& ,
212 const Qt::MouseButtons&,
213 const Qt::KeyboardModifiers&,
232void FlightCameraManipulator::setCameraPosition(
const Core::Vector3& position ) {
234 QMessageBox::warning(
nullptr,
"Error",
"Position cannot be set to target point" );
246void FlightCameraManipulator::setCameraTarget(
const Core::Vector3& target ) {
248 QMessageBox::warning(
nullptr,
"Error",
"Target cannot be set to current camera position" );
258void FlightCameraManipulator::fitScene(
const Core::Aabb& aabb ) {
264 const Scalar r = ( aabb.max() - aabb.min() ).norm() / 2_ra;
265 const Scalar x = r /
std::sin( f / 2_ra );
266 const Scalar y = r /
std::sin( f * a / 2_ra );
270 Core::Vector3( aabb.center().x(), aabb.center().y(), aabb.center().z() + d ) );
272 initializeFixedUpVector();
275 m_flightSpeed = d / 10_ra;
286void FlightCameraManipulator::handleCameraRotate( Scalar dx, Scalar dy ) {
290 Core::Transform R( Core::Transform::Identity() );
291 if ( std::abs( dphi ) > std::abs( dtheta ) ) {
292 R = Core::AngleAxis( -dphi, m_fixUpVector );
294 else { R = Core::AngleAxis( -dtheta, -
m_camera->getRightVector().normalized() ); }
302void FlightCameraManipulator::handleCameraPan( Scalar dx, Scalar dy ) {
306 Core::Vector3 R = -
m_camera->getRightVector();
307 Core::Vector3 U = m_fixUpVector;
309 Core::Transform T( Core::Transform::Identity() );
310 Core::Vector3 t = x * R + y * U;
317void FlightCameraManipulator::handleCameraZoom( Scalar dx, Scalar dy ) {
321void FlightCameraManipulator::handleCameraZoom( Scalar z ) {
323 Core::Transform T( Core::Transform::Identity() );
330void FlightCameraManipulator::initializeFixedUpVector() {
334 if ( std::abs(upVector[0]) > std::abs(upVector[1]) )
336 if ( std::abs(upVector[0]) > std::abs(upVector[2]) ) { m_fixUpVector = Ra::Core::Vector3( 1, 0, 0 ); }
338 { m_fixUpVector = Ra::Core::Vector3( 0, 0, 1 ); }
340 else if ( std::abs(upVector[1]) > std::abs(upVector[2]) )
341 { m_fixUpVector = Ra::Core::Vector3( 0, 1, 0 ); }
343 { m_fixUpVector = Ra::Core::Vector3( 0, 0, 1 ); }
345 m_fixUpVector = Ra::Core::Vector3( 0_ra, 1_ra, 0_ra );
Scalar getZFar() const
Return the Z Far plane distance from the camera.
void setPosition(const Core::Vector3 &position)
Set the position of the camera to position.
void setDirection(const Core::Vector3 &direction)
void setZFar(Scalar zFar)
Set the Z Far plane distance to zFar.
Core::Vector3 getPosition() const
Return the position.
Core::Vector3 getUpVector() const
Return the up vector.
void setFrame(const Core::Transform &frame)
Set the frame of the camera to frame.
Scalar getAspect() const
Return the aspect ratio of the viewport.
Core::Vector3 getDirection() const
Return the direction the camera is looking at.
virtual void setDirection(const Eigen::Matrix< Scalar, 3, 1 > &)
virtual void setPosition(const Eigen::Matrix< Scalar, 3, 1 > &)
The CameraManipulator class is the generic class for camera manipulators.
Scalar m_lastMouseX
x-position of the mouse on the screen at the manipulation start.
Scalar m_quickCameraModifier
Additional factor for camera sensitivity.
Core::Asset::Camera * m_camera
The Camera.
Scalar m_lastMouseY
y-position of the mouse on the screen at the manipulation start.
Scalar m_wheelSpeedModifier
Speed modifier on mouse wheel events.
Engine::Scene::Light * m_light
The light attached to the Camera.
Scalar m_cameraSensitivity
the Camera sensitivity to manipulation.
bool handleKeyPressEvent(QKeyEvent *event, const KeyMappingManager::KeyMappingAction &action) override
bool handleWheelEvent(QWheelEvent *event, const Qt::MouseButtons &buttons, const Qt::KeyboardModifiers &modifiers, int key) override
virtual ~FlightCameraManipulator()
[Constructor]
bool handleMousePressEvent(QMouseEvent *event, const Qt::MouseButtons &buttons, const Qt::KeyboardModifiers &modifiers, int key) override
bool handleMouseReleaseEvent(QMouseEvent *event) override
void updateCamera() override
KeyMappingManager::Context mappingContext() override
bool handleMouseMoveEvent(QMouseEvent *event, const Qt::MouseButtons &buttons, const Qt::KeyboardModifiers &modifiers, int key) override
bool triggerEventCallback(QEvent *event, int key, bool wheel=false)
void addEventCallback(KeyMappingAction action, Callback callback)
KeyMappingManageable decorator to use as CRTP.
Ra::Core::Utils::Index KeyMappingAction
handle to an action
Ra::Core::Utils::Index Context
handle to a Context
constexpr int sign(const T &val)
Returns the sign of any numeric type as { -1, 0, 1}.
hepler function to manage enum as underlying types in VariableSet