Skip to content

Commit

Permalink
camera sharing between views (#116)
Browse files Browse the repository at this point in the history
* camera sharing between views

* camera sharing bugfix Linux compilation
  • Loading branch information
sylvainthery authored Sep 28, 2024
1 parent a9f5ad0 commit e22ee77
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 55 deletions.
14 changes: 14 additions & 0 deletions cgogn/rendering/apps/simple_surface_viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ int main(int argc, char** argv)
v1->link_module(&sr);
// v1->link_module(&str);

// test for camera sharing
cgogn::ui::View* v2 = app.add_view();
v2->link_module(&mp);
v2->link_module(&sr);

v2->share_camera(v1);

cgogn::ui::View* v3 = app.add_view();
v3->link_module(&mp);
v3->link_module(&sr);

v3->share_camera(v1);

app.set_views_3_columns();

if (filename.length() > 0)
{
Expand Down
36 changes: 34 additions & 2 deletions cgogn/ui/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ void App::adapt_views_geometry()
case 3:
views_[0]->set_view_ratio(0, 0, 0.5, 0.5);
views_[1]->set_view_ratio(0.5, 0, 0.5, 0.5);
views_[2]->set_view_ratio(0, 0, 1, 0.5);
views_[2]->set_view_ratio(0, 0.5, 1, 0.5);
break;
case 4:
views_[0]->set_view_ratio(0, 0, 0.5, 0.5);
Expand All @@ -472,6 +472,35 @@ void App::adapt_views_geometry()
v->resize_event(window_width_, window_height_, framebuffer_width_, framebuffer_height_);
}

void App::set_views_3_columns()
{
if (views_.size() == 3)
{
views_[0]->set_view_ratio(0, 0, 0.33, 1);
views_[1]->set_view_ratio(0.33, 0, 0.33, 1);
views_[2]->set_view_ratio(0.66, 0, 0.33, 1);
}

for (const auto& v : views_)
v->resize_event(window_width_, window_height_, framebuffer_width_, framebuffer_height_);
}


void App::set_views_4_columns()
{
if (views_.size() == 4)
{
views_[0]->set_view_ratio(0, 0, 0.25, 1);
views_[1]->set_view_ratio(0.25, 0, 0.25, 1);
views_[2]->set_view_ratio(0.5, 0, 0.25, 1);
views_[3]->set_view_ratio(0.75, 0, 0.25, 1);
}

for (const auto& v : views_)
v->resize_event(window_width_, window_height_, framebuffer_width_, framebuffer_height_);
}


void App::init_modules()
{
for (Module* m : modules_)
Expand All @@ -489,6 +518,9 @@ int App::launch()
boost::synapse::poll(*tlq_);

glfwPollEvents();
if (glfwWindowShouldClose(window_))
break;

glfwMakeContextCurrent(window_);

frame_time_ = glfwGetTime();
Expand Down Expand Up @@ -674,8 +706,8 @@ int App::launch()

void App::stop()
{
close_event();
glfwSetWindowShouldClose(window_, GLFW_TRUE);
close_event();
}

} // namespace ui
Expand Down
5 changes: 5 additions & 0 deletions cgogn/ui/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ class CGOGN_UI_EXPORT App
static float64 frame_time_;

View* add_view();

void set_views_3_columns();

void set_views_4_columns();

inline View* current_view() const
{
return current_view_;
Expand Down
71 changes: 36 additions & 35 deletions cgogn/ui/gl_viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ namespace ui

GLViewer::GLViewer(Inputs* inputs) : viewport_width_(0), viewport_height_(0), inputs_(inputs), need_redraw_(true)
{
current_frame_ = &camera_;
camera_saved_ = camera_;
camera_ = std::make_shared<Camera>();
current_frame_ = camera_.get();
camera_saved_ = *camera_;
}

GLViewer::~GLViewer()
Expand All @@ -46,15 +47,15 @@ void GLViewer::set_manipulated_frame(MovingFrame* frame)
if (frame != nullptr)
current_frame_ = frame;
else
current_frame_ = &camera_;
current_frame_ = camera_.get();
}

void GLViewer::resize_event(int32 viewport_width, int32 viewport_height)
{
viewport_width_ = viewport_width;
viewport_height_ = viewport_height;
camera_.set_aspect_ratio(double(viewport_width_) / viewport_height_);
need_redraw_ = true;
camera_->set_aspect_ratio(double(viewport_width_) / viewport_height_);
request_update();
}

void GLViewer::close_event()
Expand All @@ -68,7 +69,7 @@ void GLViewer::mouse_press_event(int32 button, int32, int32)
current_frame_->is_moving_ = false;
spinning_speed_ = 0;
current_frame_->spin_ = rendering::Transfo3d::Identity();
need_redraw_ = true;
request_update();
}
}

Expand All @@ -82,7 +83,7 @@ void GLViewer::mouse_release_event(int32 button, int32, int32)
spinning_speed_ = 0;
current_frame_->spin_ = rendering::Transfo3d::Identity();
}
need_redraw_ = true;
request_update();
}
}

Expand All @@ -93,8 +94,8 @@ void GLViewer::mouse_dbl_click_event(int32 /*buttons*/, int32 x, int32 y)
rendering::GLVec3d P;
if (pixel_scene_position(x, y, P))
{
camera_.set_pivot_point(P);
need_redraw_ = true;
camera_->set_pivot_point(P);
request_update();
}
}
}
Expand All @@ -115,9 +116,9 @@ void GLViewer::mouse_move_event(int32 x, int32 y)
spinning_speed_ *= inputs_->mouse_sensitivity_;
if (obj_mode())
{
rendering::Transfo3d inv_camera = camera_.frame_.inverse();
rendering::Transfo3d inv_camera = camera_->frame_.inverse();
rendering::Transfo3d sm(Eigen::AngleAxisd(2.0 * spinning_speed_, axis));
current_frame_->spin_ = inv_camera * sm * camera_.frame_;
current_frame_->spin_ = inv_camera * sm * camera_->frame_;
auto tr = current_frame_->frame_.translation().eval();
current_frame_->frame_.translation().setZero();
current_frame_->frame_ = current_frame_->spin_ * current_frame_->frame_;
Expand All @@ -130,33 +131,33 @@ void GLViewer::mouse_move_event(int32 x, int32 y)
current_frame_->frame_.translation().setZero();
current_frame_->frame_ = Eigen::AngleAxisd(spinning_speed_, axis) * current_frame_->frame_;
current_frame_->frame_.translation() = tr;
camera_.update_matrices();
camera_->update_matrices();
}
need_redraw_ = true;
request_update();
}

if (mouse_button_pressed(GLFW_MOUSE_BUTTON_RIGHT))
{
float64 zcam = 1.0 / std::tan(camera_.field_of_view() / 2.0);
float64 a = camera_.scene_radius() - camera_.frame_.translation().z() / zcam;
float64 zcam = 1.0 / std::tan(camera_->field_of_view() / 2.0);
float64 a = camera_->scene_radius() - camera_->frame_.translation().z() / zcam;
if (obj_mode())
{
rendering::Transfo3d inv_camera = camera_.frame_.inverse();
float64 tx = dx / viewport_width_ * camera_.width() * a;
float64 ty = -dy / viewport_height_ * camera_.height() * a;
rendering::Transfo3d inv_camera = camera_->frame_.inverse();
float64 tx = dx / viewport_width_ * camera_->width() * a;
float64 ty = -dy / viewport_height_ * camera_->height() * a;
rendering::Transfo3d ntr =
inv_camera * Eigen::Translation3d(rendering::GLVec3d(tx, ty, 0.0)) * camera_.frame_;
inv_camera * Eigen::Translation3d(rendering::GLVec3d(tx, ty, 0.0)) * camera_->frame_;
current_frame_->frame_ = ntr * current_frame_->frame_;
}
else
{
float64 nx = float64(dx) / viewport_width_ * camera_.width() * a;
float64 ny = -1.0 * float64(dy) / viewport_height_ * camera_.height() * a;
camera_.frame_.translation().x() += 2 * nx;
camera_.frame_.translation().y() += 2 * ny;
camera_.update_matrices();
float64 nx = float64(dx) / viewport_width_ * camera_->width() * a;
float64 ny = -1.0 * float64(dy) / viewport_height_ * camera_->height() * a;
camera_->frame_.translation().x() += 2 * nx;
camera_->frame_.translation().y() += 2 * ny;
camera_->update_matrices();
}
need_redraw_ = true;
request_update();
}
}

Expand All @@ -166,19 +167,19 @@ void GLViewer::mouse_wheel_event(float64, float64 dy)
{
if (obj_mode())
{
rendering::Transfo3d inv_camera = camera_.frame_.inverse();
rendering::Transfo3d inv_camera = camera_->frame_.inverse();
auto ntr = inv_camera * Eigen::Translation3d(rendering::GLVec3d(0, 0, -inputs_->wheel_sensitivity_ * dy)) *
camera_.frame_;
camera_->frame_;
current_frame_->frame_ = ntr * current_frame_->frame_;
}
else
{
float64 zcam = 1.0 / std::tan(camera_.field_of_view() / 2.0);
float64 a = camera_.scene_radius() - camera_.frame_.translation().z() / zcam / camera_.scene_radius();
camera_.frame_.translation().z() -= inputs_->wheel_sensitivity_ * dy * std::max(0.1, a);
camera_.update_matrices();
float64 zcam = 1.0 / std::tan(camera_->field_of_view() / 2.0);
float64 a = camera_->scene_radius() - camera_->frame_.translation().z() / zcam / camera_->scene_radius();
camera_->frame_.translation().z() -= inputs_->wheel_sensitivity_ * dy * std::max(0.1, a);
camera_->update_matrices();
}
need_redraw_ = true;
request_update();
}
}

Expand All @@ -200,9 +201,9 @@ void GLViewer::spin()
current_frame_->frame_.translation().setZero();
current_frame_->frame_ = current_frame_->spin_ * current_frame_->frame_;
current_frame_->frame_.translation() = tr;
if (current_frame_ == &camera_)
camera_.update_matrices();
need_redraw_ = true;
if (current_frame_ == camera_.get())
camera_->update_matrices();
request_update();
}
}

Expand Down
53 changes: 35 additions & 18 deletions cgogn/ui/gl_viewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <cgogn/ui/cgogn_ui_export.h>
#include <cgogn/ui/inputs.h>

#include <memory>

#include <fstream>

namespace cgogn
Expand All @@ -45,80 +47,93 @@ class CGOGN_UI_EXPORT GLViewer
virtual ~GLViewer();
CGOGN_NOT_COPYABLE_NOR_MOVABLE(GLViewer);

inline void share_camera(GLViewer* v)
{
camera_ = v->camera_;
current_frame_ = v->current_frame_;
shared_cam_with_.push_back(v);
v->shared_cam_with_.push_back(this);
}

inline bool need_redraw() const
{
return need_redraw_;
}

inline void request_update()
{
need_redraw_ = true;
for (auto* v : shared_cam_with_)
if (!v->need_redraw())
v->request_update();
}

inline const Camera& camera() const
{
return camera_;
return *camera_;
}
inline void save_camera()
{
std::ofstream out_file;
out_file.open("saved_camera");
if (out_file.is_open())
{
out_file << camera_;
out_file << *camera_;
out_file.close();
}
camera_saved_ = camera_;
camera_saved_ = *camera_;
}
inline void restore_camera()
{
camera_ = camera_saved_;
*camera_ = camera_saved_;
std::ifstream in_file("saved_camera", std::ios::in);
if (in_file.is_open())
{
in_file >> camera_;
in_file >> *camera_;
in_file.close();
}
need_redraw_ = true;
request_update();
}

inline const rendering::GLMat4& projection_matrix() const
{
return camera_.projection_matrix();
return camera_->projection_matrix();
}
inline const rendering::GLMat4d& projection_matrix_d() const
{
return camera_.projection_matrix_d();
return camera_->projection_matrix_d();
}
inline const rendering::GLMat4& modelview_matrix() const
{
return camera_.modelview_matrix();
return camera_->modelview_matrix();
}
inline const rendering::GLMat4d& modelview_matrix_d() const
{
return camera_.modelview_matrix_d();
return camera_->modelview_matrix_d();
}


void set_manipulated_frame(MovingFrame* frame);

inline void set_scene_radius(float64 radius)
{
camera_.set_scene_radius(radius);
camera_->set_scene_radius(radius);
}
inline void set_scene_center(const rendering::GLVec3d& center)
{
scene_center_ = center;
if (!camera_.pivot_point_initialized())
camera_.set_pivot_point(scene_center_);
if (!camera_->pivot_point_initialized())
camera_->set_pivot_point(scene_center_);
}
inline void set_scene_center(const rendering::GLVec3& center)
{
scene_center_ = center.cast<float64>();
if (!camera_.pivot_point_initialized())
camera_.set_pivot_point(scene_center_);
if (!camera_->pivot_point_initialized())
camera_->set_pivot_point(scene_center_);
}
inline void show_entire_scene()
{
camera_.show_entire_scene();
camera_->show_entire_scene();
request_update();
}

Expand Down Expand Up @@ -201,11 +216,13 @@ class CGOGN_UI_EXPORT GLViewer

inline bool obj_mode() const
{
return current_frame_ != &camera_;
return current_frame_ != camera_.get();
}
void spin();

Camera camera_;
std::shared_ptr<Camera> camera_;
std::vector<GLViewer*> shared_cam_with_;

Camera camera_saved_;
MovingFrame* current_frame_;
rendering::GLVec3d scene_center_;
Expand Down
Loading

0 comments on commit e22ee77

Please sign in to comment.