#ifndef ARCBALLCAMERA_H #define ARCBALLCAMERA_H #include #include #include #include #include "arc_ball.h" using namespace Magnum; /* Arcball camera implementation integrated into the SceneGraph */ class ArcBallCamera : public ArcBall { public: template ArcBallCamera(SceneGraph::Scene &scene, const Vector3 &cameraPosition, const Vector3 &viewCenter, const Vector3 &upDir, Deg fov, const Vector2i &windowSize, const Vector2i &viewportSize) : ArcBall{cameraPosition, viewCenter, upDir, fov, windowSize} { /* Create a camera object of a concrete type */ auto *cameraObject = new SceneGraph::Object{&scene}; (*(m_camera = new SceneGraph::Camera3D{*cameraObject})) .setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend) .setProjectionMatrix(Matrix4::perspectiveProjection( fov, Vector2{windowSize}.aspectRatio(), 0.01f, 100.0f)) .setViewport(viewportSize); /* Save the abstract transformation interface and initialize the camera position through that */ (*(m_cameraObject = cameraObject)) .rotate(transformation().rotation()) .translate(transformation().translation()); } /* Update screen and viewport size after the window has been resized */ void reshape(const Vector2i &windowSize, const Vector2i &viewportSize) { m_windowSize = windowSize; m_camera->setViewport(viewportSize); } /* Update the SceneGraph camera if arcball has been changed */ bool update() { /* call the internal update */ if (!updateTransformation()) return false; (*m_cameraObject) .resetTransformation() .rotate(transformation().rotation()) .translate(transformation().translation()); return true; } /* Draw objects using the internal scenegraph camera */ void draw(SceneGraph::DrawableGroup3D &drawables) { m_camera->draw(drawables); } private: SceneGraph::AbstractTranslationRotation3D *m_cameraObject{}; SceneGraph::Camera3D *m_camera{}; }; #endif