Skip to content

Commit

Permalink
Keep camera on reload (f3d-app#788)
Browse files Browse the repository at this point in the history
Co-authored-by: snoyer <noyer.stephane@gmail.com>
  • Loading branch information
mwestphal and snoyer authored Jun 2, 2023
1 parent 901ebb2 commit 4a0fefc
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 31 deletions.
35 changes: 22 additions & 13 deletions application/F3DStarter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -164,30 +164,40 @@ int F3DStarter::Start(int argc, char** argv)

f3d::window& window = this->Internals->Engine->getWindow();
f3d::interactor& interactor = this->Internals->Engine->getInteractor();

interactor.setKeyPressCallBack(
[this](int, const std::string& keySym) -> bool
{
if (keySym == "Left")
const auto loadFile = [this](int index, bool restoreCamera = false) -> bool
{
this->Internals->Engine->getInteractor().stopAnimation();
this->LoadFile(-1, true);

if (restoreCamera)
{
f3d::camera& cam = this->Internals->Engine->getWindow().getCamera();
const auto camState = cam.getState();
this->LoadFile(index, true);
cam.setState(camState);
}
else
{
this->LoadFile(index, true);
}

this->Render();
return true;
};

if (keySym == "Left")
{
return loadFile(-1);
}
else if (keySym == "Right")
{
this->Internals->Engine->getInteractor().stopAnimation();
this->LoadFile(1, true);
this->Render();
return true;
return loadFile(+1);
}
else if (keySym == "Up")
{
this->Internals->Engine->getInteractor().stopAnimation();
this->LoadFile(0, true);
this->Render();
return true;
return loadFile(0, true);
}
else if (keySym == "Down")
{
Expand All @@ -198,8 +208,7 @@ int F3DStarter::Start(int argc, char** argv)
this->Internals->FilesList[static_cast<size_t>(this->Internals->CurrentFileIndex)]
.parent_path(),
true);
this->LoadFile(0, true);
this->Render();
return loadFile(0);
}
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions doc/user/INTERACTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ Other hotkeys are available:
* `SPACE`: play the animation if any.
* `LEFT`: load the previous file if any.
* `RIGHT`: load the next file if any.
* `UP`: reload the current file.
* `DOWN`: add current file parent directory to the list of files and reload the current file.
* `UP`: reload the current file without resetting the camera.
* `DOWN`: add current file parent directory to the list of files, reload the current file and reset the camera.

When loading another file or reloading, options that have been changed interactively are kept but can be overridden
if a dedicated regular expression block in the configuration file is present, see the [configuration file](CONFIGURATION_FILE.md)
Expand Down
3 changes: 3 additions & 0 deletions library/private/camera_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class camera_impl : public camera
camera& setViewAngle(const angle_deg_t& angle) override;
angle_deg_t getViewAngle() override;
void getViewAngle(angle_deg_t& angle) override;
camera& setState(const camera_state_t& state) override;
camera_state_t getState() override;
void getState(camera_state_t& state) override;

camera& dolly(double val) override;
camera& roll(angle_deg_t angle) override;
Expand Down
11 changes: 11 additions & 0 deletions library/public/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@

namespace f3d
{
struct F3D_EXPORT camera_state_t
{
point3_t pos = { 0., 0., 1. };
point3_t foc = { 0., 0., 0. };
vector3_t up = { 0., 1., 0. };
angle_deg_t angle = 30.;
};

/**
* @class camera
* @brief Abstract class to control a camera in a window
Expand Down Expand Up @@ -38,6 +46,9 @@ class F3D_EXPORT camera
virtual camera& setViewAngle(const angle_deg_t& angle) = 0;
virtual angle_deg_t getViewAngle() = 0;
virtual void getViewAngle(angle_deg_t& angle) = 0;
virtual camera& setState(const camera_state_t& state) = 0;
virtual camera_state_t getState() = 0;
virtual void getState(camera_state_t& state) = 0;
///@}

///@{ @name Manipulation
Expand Down
6 changes: 4 additions & 2 deletions library/public/types.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#ifndef f3d_types_h
#define f3d_types_h

#include "export.h"

#include <array>

namespace f3d
{
/**
* Describe a 3D point.
*/
struct point3_t : std::array<double, 3>
struct F3D_EXPORT point3_t : std::array<double, 3>
{
template<typename... Args>
point3_t(Args&&... args)
Expand All @@ -20,7 +22,7 @@ struct point3_t : std::array<double, 3>
/**
* Describe a 3D vector.
*/
struct vector3_t : std::array<double, 3>
struct F3D_EXPORT vector3_t : std::array<double, 3>
{
template<typename... Args>
vector3_t(Args&&... args)
Expand Down
39 changes: 33 additions & 6 deletions library/src/camera_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class camera_impl::internals
{
public:
vtkRenderer* VTKRenderer = nullptr;
vtkNew<vtkCamera> DefaultVTKCamera;
camera_state_t DefaultCamera;
};

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -124,6 +124,36 @@ void camera_impl::getViewAngle(angle_deg_t& angle)
angle = cam->GetViewAngle();
}

//----------------------------------------------------------------------------
camera& camera_impl::setState(const camera_state_t& state)
{
vtkCamera* cam = this->GetVTKCamera();
cam->SetPosition(state.pos.data());
cam->SetFocalPoint(state.foc.data());
cam->SetViewUp(state.up.data());
cam->SetViewAngle(state.angle);
cam->OrthogonalizeViewUp();
this->Internals->VTKRenderer->ResetCameraClippingRange();
return *this;
}

//----------------------------------------------------------------------------
camera_state_t camera_impl::getState()
{
camera_state_t state;
this->getState(state);
return state;
}

//----------------------------------------------------------------------------
void camera_impl::getState(camera_state_t& state)
{
vtkCamera* cam = this->GetVTKCamera();
cam->GetPosition(state.pos.data());
cam->GetFocalPoint(state.foc.data());
cam->GetViewUp(state.up.data());
state.angle = cam->GetViewAngle();
}
//----------------------------------------------------------------------------
camera& camera_impl::dolly(double val)
{
Expand Down Expand Up @@ -187,17 +217,14 @@ camera& camera_impl::pitch(angle_deg_t angle)
//----------------------------------------------------------------------------
camera& camera_impl::setCurrentAsDefault()
{
vtkCamera* cam = this->GetVTKCamera();
this->Internals->DefaultVTKCamera->DeepCopy(cam);
this->getState(this->Internals->DefaultCamera);
return *this;
}

//----------------------------------------------------------------------------
camera& camera_impl::resetToDefault()
{
vtkCamera* cam = this->GetVTKCamera();
cam->DeepCopy(this->Internals->DefaultVTKCamera);
this->Internals->VTKRenderer->ResetCameraClippingRange();
this->setState(this->Internals->DefaultCamera);
return *this;
}

Expand Down
4 changes: 4 additions & 0 deletions python/F3DPythonBindings.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ PYBIND11_MODULE(f3d, module)

// f3d::camera
py::class_<f3d::camera, std::unique_ptr<f3d::camera, py::nodelete> > camera(module, "camera");
py::class_<f3d::camera_state_t>(module, "camera_state_t");

camera.def("setPosition", &f3d::camera::setPosition)
.def("getPosition", py::overload_cast<>(&f3d::camera::getPosition))
Expand All @@ -132,6 +133,9 @@ PYBIND11_MODULE(f3d, module)
.def("yaw", &f3d::camera::yaw)
.def("elevation", &f3d::camera::elevation)
.def("pitch", &f3d::camera::pitch)
.def("setState", &f3d::camera::setState)
.def("getState", py::overload_cast<>(&f3d::camera::getState))
.def("getState", py::overload_cast<f3d::camera_state_t&>(&f3d::camera::getState))
.def("setCurrentAsDefault", &f3d::camera::setCurrentAsDefault)
.def("resetToDefault", &f3d::camera::resetToDefault)
.def("resetToBounds", &f3d::camera::resetToBounds, py::arg("zoomFactor") = 0.9);
Expand Down
4 changes: 4 additions & 0 deletions python/testing/TestPythonCamera.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
camera.elevation(angle)
camera.pitch(angle)

state = camera.getState()
camera.getState(state)
camera.setState(state)

camera.setCurrentAsDefault()
camera.resetToBounds()
camera.resetToDefault()
4 changes: 2 additions & 2 deletions testing/baselines/TestInteractionReload.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 15 additions & 6 deletions testing/recordings/TestInteractionReload.log
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# StreamVersion 1.1
ExposeEvent 0 599 0 0 0 0
RenderEvent 0 599 0 0 0 0
KeyPressEvent 354 650 0 0 1 Up
CharEvent 354 650 0 0 1 Up
KeyReleaseEvent 354 650 0 0 1 Up
# StreamVersion 1.2
ExposeEvent 0 299 0 0 0 0 0
RenderEvent 0 299 0 0 0 0 0
EnterEvent 290 186 0 0 0 0 0
LeftButtonPressEvent 90 130 0 0 0 0 0
StartInteractionEvent 90 130 0 0 0 0 0
MouseMoveEvent 190 130 0 0 0 0 0
RenderEvent 190 130 0 0 0 0 0
InteractionEvent 190 130 0 0 0 0 0
LeftButtonReleaseEvent 190 130 0 0 0 0 0
EndInteractionEvent 190 130 0 0 0 0 0
RenderEvent 190 130 0 0 0 0 0
KeyPressEvent 190 130 0 0 1 Up 0
CharEvent 190 130 0 0 1 Up 0
KeyReleaseEvent 190 130 0 0 1 Up 0

0 comments on commit 4a0fefc

Please sign in to comment.