165 lines
4.9 KiB
C++
165 lines
4.9 KiB
C++
// Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
|
|
|
#include "orbitcameracontroller.h"
|
|
|
|
#include <Qt3DRender/QCamera>
|
|
|
|
/*!
|
|
\class Qt3DExtras::OrbitCameraController
|
|
\ingroup qt3d-extras-cameracontrollers
|
|
\brief The OrbitCameraController class allows controlling the scene camera along orbital path.
|
|
\inmodule Qt3DExtras
|
|
\since 5.7
|
|
\inherits Qt3DCore::QEntity
|
|
|
|
The controls are:
|
|
\table
|
|
\header
|
|
\li Input
|
|
\li Action
|
|
\row
|
|
\li Left mouse button
|
|
\li While the left mouse button is pressed, mouse movement along x-axis moves the camera
|
|
left and right and movement along y-axis moves it up and down.
|
|
\row
|
|
\li Right mouse button
|
|
\li While the right mouse button is pressed, mouse movement along x-axis pans the camera
|
|
around the camera view center and movement along y-axis tilts it around the camera
|
|
view center.
|
|
\row
|
|
\li Both left and right mouse button
|
|
\li While both the left and the right mouse button are pressed, mouse movement along y-axis
|
|
zooms the camera in and out without changing the view center.
|
|
\row
|
|
\li Mouse scroll wheel
|
|
\li Zooms the camera in and out without changing the view center.
|
|
\row
|
|
\li Arrow keys
|
|
\li Move the camera vertically and horizontally relative to camera viewport.
|
|
\row
|
|
\li Page up and page down keys
|
|
\li Move the camera forwards and backwards.
|
|
\row
|
|
\li Shift key
|
|
\li Changes the behavior of the up and down arrow keys to zoom the camera in and out
|
|
without changing the view center. The other movement keys are disabled.
|
|
\row
|
|
\li Alt key
|
|
\li Changes the behovior of the arrow keys to pan and tilt the camera around the view
|
|
center. Disables the page up and page down keys.
|
|
\row
|
|
\li Escape
|
|
\li Moves the camera so that entire scene is visible in the camera viewport.
|
|
\endtable
|
|
*/
|
|
|
|
OrbitCameraController::OrbitCameraController(QVector2D orthoSize, Qt3DCore::QNode *parent)
|
|
: QAbstractCameraController(parent),
|
|
m_orthoSize(orthoSize)
|
|
{
|
|
}
|
|
|
|
OrbitCameraController::~OrbitCameraController()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
\property OrbitCameraController::zoomInLimit
|
|
|
|
Holds the current zoom-in limit. The zoom-in limit determines how close to the view center
|
|
the camera can be zoomed.
|
|
*/
|
|
float OrbitCameraController::zoomInLimit() const
|
|
{
|
|
return m_zoomInLimit;
|
|
}
|
|
|
|
void OrbitCameraController::updateProjection()
|
|
{
|
|
camera()->lens()->setOrthographicProjection(0-(m_orthoSize.x()/m_zoomFactor)/2, (m_orthoSize.x()/m_zoomFactor)/2,
|
|
0-(m_orthoSize.y()/m_zoomFactor)/2, (m_orthoSize.y()/m_zoomFactor)/2, 0.01, 100000);
|
|
}
|
|
|
|
void OrbitCameraController::setZoomInLimit(float zoomInLimit)
|
|
{
|
|
if (m_zoomInLimit != zoomInLimit)
|
|
{
|
|
m_zoomInLimit = zoomInLimit;
|
|
emit zoomInLimitChanged();
|
|
}
|
|
}
|
|
|
|
void OrbitCameraController::setZoomFactor(float factor)
|
|
{
|
|
m_zoomFactor = factor;
|
|
updateProjection();
|
|
}
|
|
|
|
void OrbitCameraController::setOrthoSize(QVector2D orthoSize)
|
|
{
|
|
m_orthoSize = orthoSize;
|
|
updateProjection();
|
|
}
|
|
|
|
inline float clampInputs(float input1, float input2)
|
|
{
|
|
float axisValue = input1 + input2;
|
|
return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue;
|
|
}
|
|
|
|
inline float zoomDistance(QVector3D firstPoint, QVector3D secondPoint)
|
|
{
|
|
return (secondPoint - firstPoint).lengthSquared();
|
|
}
|
|
|
|
void OrbitCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt)
|
|
{
|
|
Qt3DRender::QCamera *theCamera = camera();
|
|
|
|
if (theCamera == nullptr)
|
|
return;
|
|
|
|
const QVector3D upVector(0.0f, 0.0f, 1.0f);
|
|
|
|
if(state.tzAxisValue != 0)
|
|
{
|
|
m_zoomFactor+=0.1*state.tzAxisValue;
|
|
if(m_zoomFactor < 1)
|
|
m_zoomFactor = 1;
|
|
else if(m_zoomFactor > m_zoomInLimit)
|
|
m_zoomFactor = m_zoomInLimit;
|
|
updateProjection();
|
|
}
|
|
|
|
// Mouse input
|
|
if (state.rightMouseButtonActive)
|
|
{
|
|
// Translate
|
|
theCamera->translate(QVector3D(clampInputs(0-state.rxAxisValue, 0-state.txAxisValue) * linearSpeed(),
|
|
clampInputs(0-state.ryAxisValue, 0-state.tyAxisValue) * linearSpeed(),
|
|
0) * dt);
|
|
}
|
|
else if (state.leftMouseButtonActive)
|
|
{
|
|
// Orbit
|
|
theCamera->panAboutViewCenter((state.rxAxisValue * -1 * lookSpeed()) * dt, upVector);
|
|
theCamera->tiltAboutViewCenter((state.ryAxisValue * -1 * lookSpeed()) * dt);
|
|
}
|
|
|
|
// Keyboard Input
|
|
if (state.altKeyActive)
|
|
{
|
|
// Orbit
|
|
theCamera->panAboutViewCenter((state.txAxisValue * lookSpeed()) * dt, upVector);
|
|
theCamera->tiltAboutViewCenter((state.tyAxisValue * lookSpeed()) * dt);
|
|
}
|
|
else
|
|
{
|
|
// Translate
|
|
theCamera->translate(QVector3D(clampInputs(state.leftMouseButtonActive ? state.rxAxisValue : 0, state.txAxisValue) * linearSpeed(),
|
|
clampInputs(state.leftMouseButtonActive ? state.ryAxisValue : 0, state.tyAxisValue) * linearSpeed(),
|
|
state.tzAxisValue * linearSpeed()) * dt);
|
|
}
|
|
}
|