Camera target constrained to scene bounding box

This commit is contained in:
Enrico Turri 2018-12-07 16:23:04 +01:00
parent 10cf82774b
commit 198b23283c
3 changed files with 107 additions and 6 deletions

View File

@ -31,6 +31,8 @@
#define ENABLE_SLA_SUPPORT_GIZMO_MOD (1 && ENABLE_1_42_0) #define ENABLE_SLA_SUPPORT_GIZMO_MOD (1 && ENABLE_1_42_0)
// Removes the wxNotebook from plater // Removes the wxNotebook from plater
#define ENABLE_REMOVE_TABS_FROM_PLATER (1 && ENABLE_1_42_0) #define ENABLE_REMOVE_TABS_FROM_PLATER (1 && ENABLE_1_42_0)
// Constrains the camera target into the scene bounding box
#define ENABLE_CONSTRAINED_CAMERA_TARGET (1 && ENABLE_1_42_0)
#endif // _technologies_h_ #endif // _technologies_h_

View File

@ -273,8 +273,13 @@ GLCanvas3D::Camera::Camera()
, zoom(1.0f) , zoom(1.0f)
, phi(45.0f) , phi(45.0f)
// , distance(0.0f) // , distance(0.0f)
#if !ENABLE_CONSTRAINED_CAMERA_TARGET
, target(0.0, 0.0, 0.0) , target(0.0, 0.0, 0.0)
#endif // !ENABLE_CONSTRAINED_CAMERA_TARGET
, m_theta(45.0f) , m_theta(45.0f)
#if ENABLE_CONSTRAINED_CAMERA_TARGET
, m_target(Vec3d::Zero())
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
{ {
} }
@ -292,16 +297,32 @@ std::string GLCanvas3D::Camera::get_type_as_string() const
}; };
} }
float GLCanvas3D::Camera::get_theta() const
{
return m_theta;
}
void GLCanvas3D::Camera::set_theta(float theta) void GLCanvas3D::Camera::set_theta(float theta)
{ {
m_theta = clamp(0.0f, GIMBALL_LOCK_THETA_MAX, theta); m_theta = clamp(0.0f, GIMBALL_LOCK_THETA_MAX, theta);
} }
#if ENABLE_CONSTRAINED_CAMERA_TARGET
void GLCanvas3D::Camera::set_target(const Vec3d& target, GLCanvas3D& canvas)
{
m_target = target;
m_target(0) = clamp(m_scene_box.min(0), m_scene_box.max(0), m_target(0));
m_target(1) = clamp(m_scene_box.min(1), m_scene_box.max(1), m_target(1));
m_target(2) = clamp(m_scene_box.min(2), m_scene_box.max(2), m_target(2));
if (!m_target.isApprox(target))
canvas.viewport_changed();
}
void GLCanvas3D::Camera::set_scene_box(const BoundingBoxf3& box, GLCanvas3D& canvas)
{
if (m_scene_box != box)
{
m_scene_box = box;
canvas.viewport_changed();
}
}
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
GLCanvas3D::Bed::Bed() GLCanvas3D::Bed::Bed()
: m_type(Custom) : m_type(Custom)
{ {
@ -3650,6 +3671,15 @@ BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const
return bb; return bb;
} }
#if ENABLE_CONSTRAINED_CAMERA_TARGET
BoundingBoxf3 GLCanvas3D::scene_bounding_box() const
{
BoundingBoxf3 bb = volumes_bounding_box();
bb.merge(m_bed.get_bounding_box());
return bb;
}
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
bool GLCanvas3D::is_layers_editing_enabled() const bool GLCanvas3D::is_layers_editing_enabled() const
{ {
return m_layers_editing.is_enabled(); return m_layers_editing.is_enabled();
@ -3789,7 +3819,12 @@ void GLCanvas3D::set_viewport_from_scene(const GLCanvas3D& other)
{ {
m_camera.phi = other.m_camera.phi; m_camera.phi = other.m_camera.phi;
m_camera.set_theta(other.m_camera.get_theta()); m_camera.set_theta(other.m_camera.get_theta());
#if ENABLE_CONSTRAINED_CAMERA_TARGET
m_camera.set_scene_box(other.m_camera.get_scene_box(), *this);
m_camera.set_target(other.m_camera.get_target(), *this);
#else
m_camera.target = other.m_camera.target; m_camera.target = other.m_camera.target;
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
m_camera.zoom = other.m_camera.zoom; m_camera.zoom = other.m_camera.zoom;
m_dirty = true; m_dirty = true;
} }
@ -4318,6 +4353,12 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
// restore to default value // restore to default value
m_regenerate_volumes = true; m_regenerate_volumes = true;
#if ENABLE_CONSTRAINED_CAMERA_TARGET
m_camera.set_scene_box(scene_bounding_box(), *this);
m_camera.set_target(m_camera.get_target(), *this);
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
// and force this canvas to be redrawn. // and force this canvas to be redrawn.
m_dirty = true; m_dirty = true;
} }
@ -4857,7 +4898,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
float z = 0.0f; float z = 0.0f;
const Vec3d& cur_pos = _mouse_to_3d(pos, &z); const Vec3d& cur_pos = _mouse_to_3d(pos, &z);
Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z); Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
#if ENABLE_CONSTRAINED_CAMERA_TARGET
m_camera.set_target(m_camera.get_target() + orig - cur_pos, *this);
#else
m_camera.target += orig - cur_pos; m_camera.target += orig - cur_pos;
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
viewport_changed(); viewport_changed();
@ -4938,10 +4983,14 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
#if ENABLE_WORLD_ROTATIONS #if ENABLE_WORLD_ROTATIONS
_update_gizmos_data(); _update_gizmos_data();
#endif // ENABLE_WORLD_ROTATIONS #endif // ENABLE_WORLD_ROTATIONS
wxGetApp().obj_manipul()->update_settings_value(m_selection); wxGetApp().obj_manipul()->update_settings_value(m_selection);
// Let the platter know that the dragging finished, so a delayed refresh // Let the platter know that the dragging finished, so a delayed refresh
// of the scene with the background processing data should be performed. // of the scene with the background processing data should be performed.
post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
#if ENABLE_CONSTRAINED_CAMERA_TARGET
m_camera.set_scene_box(scene_bounding_box(), *this);
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
} }
m_moving = false; m_moving = false;
@ -5533,7 +5582,11 @@ void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox)
{ {
m_camera.zoom = zoom; m_camera.zoom = zoom;
// center view around bounding box center // center view around bounding box center
#if ENABLE_CONSTRAINED_CAMERA_TARGET
m_camera.set_target(bbox.center(), *this);
#else
m_camera.target = bbox.center(); m_camera.target = bbox.center();
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
viewport_changed(); viewport_changed();
@ -5655,7 +5708,12 @@ void GLCanvas3D::_camera_tranform() const
::glRotatef(-m_camera.get_theta(), 1.0f, 0.0f, 0.0f); // pitch ::glRotatef(-m_camera.get_theta(), 1.0f, 0.0f, 0.0f); // pitch
::glRotatef(m_camera.phi, 0.0f, 0.0f, 1.0f); // yaw ::glRotatef(m_camera.phi, 0.0f, 0.0f, 1.0f); // yaw
#if ENABLE_CONSTRAINED_CAMERA_TARGET
Vec3d target = -m_camera.get_target();
::glTranslated(target(0), target(1), target(2));
#else
::glTranslated(-m_camera.target(0), -m_camera.target(1), -m_camera.target(2)); ::glTranslated(-m_camera.target(0), -m_camera.target(1), -m_camera.target(2));
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
} }
void GLCanvas3D::_picking_pass() const void GLCanvas3D::_picking_pass() const
@ -5970,6 +6028,23 @@ void GLCanvas3D::_render_camera_target() const
::glLineWidth(2.0f); ::glLineWidth(2.0f);
::glBegin(GL_LINES); ::glBegin(GL_LINES);
#if ENABLE_CONSTRAINED_CAMERA_TARGET
const Vec3d& target = m_camera.get_target();
// draw line for x axis
::glColor3f(1.0f, 0.0f, 0.0f);
::glVertex3d(target(0) - half_length, target(1), target(2));
::glVertex3d(target(0) + half_length, target(1), target(2));
// draw line for y axis
::glColor3f(0.0f, 1.0f, 0.0f);
::glVertex3d(target(0), target(1) - half_length, target(2));
::glVertex3d(target(0), target(1) + half_length, target(2));
::glEnd();
::glBegin(GL_LINES);
::glColor3f(0.0f, 0.0f, 1.0f);
::glVertex3d(target(0), target(1), target(2) - half_length);
::glVertex3d(target(0), target(1), target(2) + half_length);
#else
// draw line for x axis // draw line for x axis
::glColor3f(1.0f, 0.0f, 0.0f); ::glColor3f(1.0f, 0.0f, 0.0f);
::glVertex3d(m_camera.target(0) - half_length, m_camera.target(1), m_camera.target(2)); ::glVertex3d(m_camera.target(0) - half_length, m_camera.target(1), m_camera.target(2));
@ -5984,6 +6059,7 @@ void GLCanvas3D::_render_camera_target() const
::glColor3f(0.0f, 0.0f, 1.0f); ::glColor3f(0.0f, 0.0f, 1.0f);
::glVertex3d(m_camera.target(0), m_camera.target(1), m_camera.target(2) - half_length); ::glVertex3d(m_camera.target(0), m_camera.target(1), m_camera.target(2) - half_length);
::glVertex3d(m_camera.target(0), m_camera.target(1), m_camera.target(2) + half_length); ::glVertex3d(m_camera.target(0), m_camera.target(1), m_camera.target(2) + half_length);
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
::glEnd(); ::glEnd();
} }
#endif // ENABLE_SHOW_CAMERA_TARGET #endif // ENABLE_SHOW_CAMERA_TARGET

View File

@ -153,9 +153,15 @@ class GLCanvas3D
float zoom; float zoom;
float phi; float phi;
// float distance; // float distance;
#if !ENABLE_CONSTRAINED_CAMERA_TARGET
Vec3d target; Vec3d target;
#endif !// ENABLE_CONSTRAINED_CAMERA_TARGET
private: private:
#if ENABLE_CONSTRAINED_CAMERA_TARGET
Vec3d m_target;
BoundingBoxf3 m_scene_box;
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
float m_theta; float m_theta;
public: public:
@ -163,8 +169,16 @@ class GLCanvas3D
std::string get_type_as_string() const; std::string get_type_as_string() const;
float get_theta() const; float get_theta() const { return m_theta; }
void set_theta(float theta); void set_theta(float theta);
#if ENABLE_CONSTRAINED_CAMERA_TARGET
const Vec3d& get_target() const { return m_target; }
void set_target(const Vec3d& target, GLCanvas3D& canvas);
const BoundingBoxf3& get_scene_box() const { return m_scene_box; }
void set_scene_box(const BoundingBoxf3& box, GLCanvas3D& canvas);
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
}; };
class Bed class Bed
@ -782,7 +796,9 @@ private:
wxWindow *m_external_gizmo_widgets_parent; wxWindow *m_external_gizmo_widgets_parent;
#endif // not ENABLE_IMGUI #endif // not ENABLE_IMGUI
#if !ENABLE_CONSTRAINED_CAMERA_TARGET
void viewport_changed(); void viewport_changed();
#endif // !ENABLE_CONSTRAINED_CAMERA_TARGET
public: public:
GLCanvas3D(wxGLCanvas* canvas); GLCanvas3D(wxGLCanvas* canvas);
@ -845,6 +861,9 @@ public:
float get_camera_zoom() const; float get_camera_zoom() const;
BoundingBoxf3 volumes_bounding_box() const; BoundingBoxf3 volumes_bounding_box() const;
#if ENABLE_CONSTRAINED_CAMERA_TARGET
BoundingBoxf3 scene_bounding_box() const;
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
bool is_layers_editing_enabled() const; bool is_layers_editing_enabled() const;
bool is_layers_editing_allowed() const; bool is_layers_editing_allowed() const;
@ -936,6 +955,10 @@ public:
void update_gizmos_on_off_state(); void update_gizmos_on_off_state();
#if ENABLE_CONSTRAINED_CAMERA_TARGET
void viewport_changed();
#endif // ENABLE_CONSTRAINED_CAMERA_TARGET
private: private:
bool _is_shown_on_screen() const; bool _is_shown_on_screen() const;
void _force_zoom_to_bed(); void _force_zoom_to_bed();