Skip to content

Commit

Permalink
Merge pull request #418 from Tucchhaa/expose_camera_api_python
Browse files Browse the repository at this point in the history
Camera Controller: expose complete API to python
  • Loading branch information
yungyuc authored Aug 25, 2024
2 parents 4166c1a + 42161b5 commit f7195c7
Show file tree
Hide file tree
Showing 7 changed files with 321 additions and 279 deletions.
20 changes: 2 additions & 18 deletions cpp/modmesh/view/R3DWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ R3DWidget::R3DWidget(Qt3DExtras::Qt3DWindow * window, RScene * scene, QWidget *
{
m_view->setRootEntity(m_scene);

resetCamera();
cameraController()->setCamera(m_view->camera());
cameraController()->reset();

if (Toggle::instance().fixed().get_show_axis())
{
Expand Down Expand Up @@ -99,23 +100,6 @@ void R3DWidget::resizeEvent(QResizeEvent * event)
m_container->resize(event->size());
}

void R3DWidget::resetCamera() const
{
Qt3DRender::QCamera * camera = m_view->camera();

// Set up the camera.
camera->lens()->setPerspectiveProjection(45.0f, 16.0f / 9.0f, 0.1f, 1000.0f);
camera->setPosition(QVector3D(0.0f, 0.0f, 10.0f));
camera->setViewCenter(QVector3D(0.0f, 0.0f, 0.0f));
camera->setUpVector(QVector3D(0.f, 1.f, 0.f));

// Set up the camera control.
auto * control = m_scene->controller();
control->setCamera(camera);
control->setLinearSpeed(50.0f);
control->setLookSpeed(180.0f);
}

} /* end namespace modmesh */

// vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:
18 changes: 7 additions & 11 deletions cpp/modmesh/view/R3DWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,17 @@ namespace modmesh
class RScene
: public Qt3DCore::QEntity
{

public:

explicit RScene(Qt3DCore::QNode * parent = nullptr)
: Qt3DCore::QEntity(parent)
, m_controller(new ROrbitCameraController(this))
explicit RScene(QNode * parent = nullptr)
: QEntity(parent)
{
m_controller = new ROrbitCameraController(this);
}

Qt3DExtras::QAbstractCameraController const * controller() const { return m_controller; }
Qt3DExtras::QAbstractCameraController * controller() { return m_controller; }
RCameraController * controller() const { return m_controller; }

void setCameraController(Qt3DExtras::QAbstractCameraController * controller)
void setCameraController(RCameraController * controller)
{
m_controller->deleteLater();
m_controller = controller;
Expand All @@ -73,7 +71,7 @@ class RScene

private:

Qt3DExtras::QAbstractCameraController * m_controller = nullptr;
RCameraController * m_controller;

}; /* end class RScene */

Expand All @@ -97,10 +95,8 @@ class R3DWidget
Qt3DExtras::Qt3DWindow * view() { return m_view; }
RScene * scene() { return m_scene; }
Qt3DRender::QCamera * camera() { return m_view->camera(); }
Qt3DExtras::QAbstractCameraController * qtCameraController() { return m_scene->controller(); }
CameraController * cameraController() { return dynamic_cast<CameraController *>(m_scene->controller()); }

void resetCamera() const;
RCameraController * cameraController() const { return m_scene->controller(); }

QPixmap grabPixmap() const { return m_view->screen()->grabWindow(m_view->winId()); }

Expand Down
31 changes: 24 additions & 7 deletions cpp/modmesh/view/RCameraController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,18 +212,33 @@ void RCameraInputListener::initKeyboardListeners() const
m_ty_axis->addInput(m_keyboard_ty_neg_input);
}

void RCameraController::reset()
{
constexpr float fov_deg = 45.0f;
constexpr float nearPlane = 0.1f;
constexpr float farPlane = 1000.0f;
camera()->lens()->setPerspectiveProjection(fov_deg, camera()->lens()->aspectRatio(), nearPlane, farPlane);

setPosition(m_default_position);
setViewCenter(m_default_view_center);
setUpVector(m_default_up_vector);

setLinearSpeed(m_default_linear_speed);
setLookSpeed(m_default_look_speed);
}

RFirstPersonCameraController::RFirstPersonCameraController(QNode * parent)
: QFirstPersonCameraController(parent)
: RCameraController(parent)
{
auto callback = [this](const CameraInputState & state, const float dt)
{
updateCameraPosition(state, dt);
moveCamera(state, dt);
};

m_listener = new RCameraInputListener(keyboardDevice(), mouseDevice(), callback, this);
}

void RFirstPersonCameraController::updateCameraPosition(const CameraInputState & input, const float dt)
void RFirstPersonCameraController::moveCamera(const CameraInputState & input, const float dt)
{
constexpr auto positiveY = QVector3D(0.f, 1.f, 0.f);

Expand All @@ -244,17 +259,17 @@ void RFirstPersonCameraController::updateCameraPosition(const CameraInputState &
}

ROrbitCameraController::ROrbitCameraController(QNode * parent)
: QOrbitCameraController(parent)
: RCameraController(parent)
{
auto callback = [this](const CameraInputState & state, const float dt)
{
updateCameraPosition(state, dt);
moveCamera(state, dt);
};

m_listener = new RCameraInputListener(keyboardDevice(), mouseDevice(), callback, this);
}

void ROrbitCameraController::updateCameraPosition(const CameraInputState & input, const float dt)
void ROrbitCameraController::moveCamera(const CameraInputState & input, const float dt)
{
if (camera() == nullptr)
return;
Expand Down Expand Up @@ -305,7 +320,9 @@ void ROrbitCameraController::updateCameraPosition(const CameraInputState & input

void ROrbitCameraController::zoom(const float zoomValue) const
{
const float limitSquared = zoomInLimit() * zoomInLimit();
constexpr float zoomInLimit = 2.0f; // Default Qt zoomInLimit value

const float limitSquared = zoomInLimit * zoomInLimit;
const float distanceSquared = zoomDistanceSquared(camera()->position(), camera()->viewCenter());

const float z = distanceSquared > limitSquared ? zoomValue : -0.5f;
Expand Down
88 changes: 53 additions & 35 deletions cpp/modmesh/view/RCameraController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@
*/

#include <modmesh/view/common_detail.hpp> // Must be the first include.

#include <QOrbitCameraController>
#include <QFirstPersonCameraController>
#include <QCamera>
#include <QAbstractCameraController>

#include <Qt3DLogic/QFrameAction>
#include <Qt3DInput/QActionInput>
Expand Down Expand Up @@ -128,77 +126,97 @@ class RCameraInputListener : public Qt3DCore::QEntity
Qt3DInput::QButtonAxisInput * m_keyboard_tz_neg_input;
}; /* end class RCameraInputListener */

class CameraController
class RCameraController : public Qt3DExtras::QAbstractCameraController
{
Q_OBJECT

public:
virtual ~CameraController() = default;
explicit RCameraController(Qt3DCore::QNode * parent = nullptr)
: QAbstractCameraController(parent)
{
}

virtual void updateCameraPosition(const CameraInputState & state, float dt) = 0;
void moveCamera(const InputState & state, float dt) override
{
// Do nothing in QAbstractCameraController's moveCamera
}

virtual void moveCamera(const CameraInputState & state, float dt) = 0;

virtual Qt3DRender::QCamera * getCamera() = 0;
Qt3DRender::QCamera * camera() const { return QAbstractCameraController::camera(); }
void setCamera(Qt3DRender::QCamera * camera) { QAbstractCameraController::setCamera(camera); }

virtual float getLinearSpeed() = 0;
float linearSpeed() const { return QAbstractCameraController::linearSpeed(); }
void setLinearSpeed(float value) { QAbstractCameraController::setLinearSpeed(value); }

virtual float getLookSpeed() = 0;
float lookSpeed() const { return QAbstractCameraController::lookSpeed(); }
void setLookSpeed(float value) { QAbstractCameraController::setLookSpeed(value); }

virtual CameraControllerType getType() = 0;

QVector3D position() { return getCamera()->position(); }
QVector3D position() const { return camera()->position(); }
void setPosition(const QVector3D & value) const { camera()->setPosition(value); }

QVector3D viewVector() const { return camera()->viewVector(); }

QVector3D viewCenter() const { return camera()->viewCenter(); }
void setViewCenter(const QVector3D & value) const { camera()->setViewCenter(value); }

QVector3D viewVector() { return getCamera()->viewVector(); }
QVector3D upVector() const { return camera()->upVector(); }
void setUpVector(const QVector3D & value) const { camera()->setUpVector(value); }

QVector3D viewCenter() { return getCamera()->viewCenter(); }
void reset();

QVector3D upVector() { return getCamera()->upVector(); }
QVector3D defaultPosition() const { return m_default_position; }
void setDefaultPosition(QVector3D value) { m_default_position = value; }

QVector3D defaultViewCenter() const { return m_default_view_center; }
void setDefaultViewCenter(QVector3D value) { m_default_view_center = value; }

QVector3D defaultUpVector() const { return m_default_up_vector; }
void setDefaultUpVector(QVector3D value) { m_default_up_vector = value; }

float defaultLinearSpeed() const { return m_default_linear_speed; }
void setDefaultLinearSpeed(float value) { m_default_linear_speed = value; }

float defaultLookSpeed() const { return m_default_look_speed; }
void setDefaultLookSpeed(float value) { m_default_look_speed = value; }

protected:
RCameraInputListener * m_listener = nullptr;

private:
Qt3DExtras::QAbstractCameraController * asQtCameraController()
{
return dynamic_cast<Qt3DExtras::QAbstractCameraController *>(this);
}
QVector3D m_default_position = QVector3D(0.0f, 0.0f, 10.0f);
QVector3D m_default_view_center = QVector3D(0.0f, 0.0f, 0.0f);
QVector3D m_default_up_vector = QVector3D(0.0f, 1.0f, 0.0f);
float m_default_linear_speed = 50.0f;
float m_default_look_speed = 180.0f;
}; /* end class CameraController */

class RFirstPersonCameraController : public Qt3DExtras::QFirstPersonCameraController
, public CameraController
class RFirstPersonCameraController : public RCameraController
{
Q_OBJECT

public:
explicit RFirstPersonCameraController(QNode * parent = nullptr);

Qt3DRender::QCamera * getCamera() override { return camera(); }
float getLinearSpeed() override { return linearSpeed(); }
float getLookSpeed() override { return lookSpeed(); }

private:
static constexpr auto lookSpeedFactorOnShiftPressed = 0.2f;

void moveCamera(const InputState & state, float dt) override {}

void updateCameraPosition(const CameraInputState & input, float dt) override;
void moveCamera(const CameraInputState & input, float dt) override;

CameraControllerType getType() override { return CameraControllerType::FirstPerson; }
}; /* end class RFirstPersonCameraController */

class ROrbitCameraController : public Qt3DExtras::QOrbitCameraController
, public CameraController
class ROrbitCameraController : public RCameraController
{
Q_OBJECT

public:
explicit ROrbitCameraController(QNode * parent = nullptr);

Qt3DRender::QCamera * getCamera() override { return camera(); }
float getLinearSpeed() override { return linearSpeed(); }
float getLookSpeed() override { return lookSpeed(); }

private:
void moveCamera(const InputState & state, float dt) override {}

void updateCameraPosition(const CameraInputState & input, float dt) override;
void moveCamera(const CameraInputState & input, float dt) override;

void zoom(float zoomValue) const;

Expand Down
4 changes: 2 additions & 2 deletions cpp/modmesh/view/RManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ void RManager::setUpCameraMovementMenuItems() const
if (viewer == nullptr || viewer->camera() == nullptr)
return;

viewer->resetCamera();
viewer->cameraController()->reset();
});

auto * move_camera_up = new RAction(
Expand Down Expand Up @@ -379,7 +379,7 @@ std::function<void()> RManager::createCameraMovementItemHandler(const std::funct
}
}

viewer->cameraController()->updateCameraPosition(input, 0.01);
viewer->cameraController()->moveCamera(input, 0.01);
};
}

Expand Down
Loading

0 comments on commit f7195c7

Please sign in to comment.