2019-03-06 14:46:19 +00:00
|
|
|
#ifndef slic3r_Camera_hpp_
|
|
|
|
#define slic3r_Camera_hpp_
|
|
|
|
|
|
|
|
#include "libslic3r/BoundingBox.hpp"
|
2019-10-31 15:40:38 +00:00
|
|
|
#if ENABLE_THUMBNAIL_GENERATOR
|
|
|
|
#include "3DScene.hpp"
|
|
|
|
#endif // ENABLE_THUMBNAIL_GENERATOR
|
2019-04-01 08:28:04 +00:00
|
|
|
#include <array>
|
2019-03-06 14:46:19 +00:00
|
|
|
|
|
|
|
namespace Slic3r {
|
|
|
|
namespace GUI {
|
|
|
|
|
|
|
|
struct Camera
|
|
|
|
{
|
2019-06-19 11:01:18 +00:00
|
|
|
static const double DefaultDistance;
|
2019-10-31 15:40:38 +00:00
|
|
|
#if ENABLE_THUMBNAIL_GENERATOR
|
|
|
|
static const double DefaultZoomToBoxMarginFactor;
|
|
|
|
static const double DefaultZoomToVolumesMarginFactor;
|
|
|
|
#endif // ENABLE_THUMBNAIL_GENERATOR
|
2019-08-03 07:07:38 +00:00
|
|
|
static double FrustrumMinZRange;
|
|
|
|
static double FrustrumMinNearZ;
|
2019-06-14 08:38:09 +00:00
|
|
|
static double FrustrumZMargin;
|
2019-08-03 07:07:38 +00:00
|
|
|
static double MaxFovDeg;
|
2019-06-13 07:12:44 +00:00
|
|
|
|
2019-03-06 14:46:19 +00:00
|
|
|
enum EType : unsigned char
|
|
|
|
{
|
|
|
|
Unknown,
|
|
|
|
Ortho,
|
2019-06-20 08:02:52 +00:00
|
|
|
Perspective,
|
2019-03-06 14:46:19 +00:00
|
|
|
Num_types
|
|
|
|
};
|
|
|
|
|
2020-01-15 11:49:34 +00:00
|
|
|
#if !ENABLE_6DOF_CAMERA
|
2019-03-06 14:46:19 +00:00
|
|
|
float phi;
|
2019-04-30 13:09:25 +00:00
|
|
|
bool inverted_phi;
|
2020-01-15 11:49:34 +00:00
|
|
|
#endif // !ENABLE_6DOF_CAMERA
|
|
|
|
bool requires_zoom_to_bed;
|
2019-03-06 14:46:19 +00:00
|
|
|
|
|
|
|
private:
|
2019-06-19 11:01:18 +00:00
|
|
|
EType m_type;
|
2019-03-06 14:46:19 +00:00
|
|
|
Vec3d m_target;
|
2020-01-15 11:49:34 +00:00
|
|
|
#if !ENABLE_6DOF_CAMERA
|
2019-03-06 14:46:19 +00:00
|
|
|
float m_theta;
|
2020-01-15 11:49:34 +00:00
|
|
|
#endif // !ENABLE_6DOF_CAMERA
|
2019-06-19 12:18:51 +00:00
|
|
|
double m_zoom;
|
2019-06-19 11:01:18 +00:00
|
|
|
// Distance between camera position and camera target measured along the camera Z axis
|
2019-06-24 07:38:46 +00:00
|
|
|
mutable double m_distance;
|
|
|
|
mutable double m_gui_scale;
|
2019-03-06 14:46:19 +00:00
|
|
|
|
2019-04-01 08:00:10 +00:00
|
|
|
mutable std::array<int, 4> m_viewport;
|
2020-01-15 11:49:34 +00:00
|
|
|
#if ENABLE_6DOF_CAMERA
|
|
|
|
Transform3d m_view_matrix;
|
|
|
|
#else
|
2019-04-01 08:00:10 +00:00
|
|
|
mutable Transform3d m_view_matrix;
|
2020-01-15 11:49:34 +00:00
|
|
|
#endif // ENABLE_6DOF_CAMERA
|
2019-04-01 08:00:10 +00:00
|
|
|
mutable Transform3d m_projection_matrix;
|
2019-06-14 08:38:09 +00:00
|
|
|
mutable std::pair<double, double> m_frustrum_zs;
|
2019-04-01 08:00:10 +00:00
|
|
|
|
2019-03-06 14:46:19 +00:00
|
|
|
BoundingBoxf3 m_scene_box;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Camera();
|
|
|
|
|
2019-06-19 11:01:18 +00:00
|
|
|
EType get_type() const { return m_type; }
|
2019-03-06 14:46:19 +00:00
|
|
|
std::string get_type_as_string() const;
|
2019-06-20 08:02:52 +00:00
|
|
|
void set_type(EType type);
|
2019-06-24 13:55:14 +00:00
|
|
|
// valid values for type: "0" -> ortho, "1" -> perspective
|
2019-06-20 08:02:52 +00:00
|
|
|
void set_type(const std::string& type);
|
2019-06-19 11:01:18 +00:00
|
|
|
void select_next_type();
|
2019-03-06 14:46:19 +00:00
|
|
|
|
|
|
|
const Vec3d& get_target() const { return m_target; }
|
|
|
|
void set_target(const Vec3d& target);
|
|
|
|
|
2019-06-24 07:38:46 +00:00
|
|
|
double get_distance() const { return m_distance; }
|
|
|
|
double get_gui_scale() const { return m_gui_scale; }
|
|
|
|
|
2020-01-15 11:49:34 +00:00
|
|
|
#if !ENABLE_6DOF_CAMERA
|
2019-03-06 14:46:19 +00:00
|
|
|
float get_theta() const { return m_theta; }
|
|
|
|
void set_theta(float theta, bool apply_limit);
|
2020-01-15 11:49:34 +00:00
|
|
|
#endif // !ENABLE_6DOF_CAMERA
|
2019-03-06 14:46:19 +00:00
|
|
|
|
2019-06-19 12:18:51 +00:00
|
|
|
double get_zoom() const { return m_zoom; }
|
2020-01-16 09:17:07 +00:00
|
|
|
double get_inv_zoom() const { assert(m_zoom != 0.0); return 1.0 / m_zoom; }
|
2019-10-03 09:38:31 +00:00
|
|
|
void update_zoom(double delta_zoom);
|
|
|
|
void set_zoom(double zoom);
|
2019-06-19 12:18:51 +00:00
|
|
|
|
2019-03-06 14:46:19 +00:00
|
|
|
const BoundingBoxf3& get_scene_box() const { return m_scene_box; }
|
2019-06-19 12:18:51 +00:00
|
|
|
void set_scene_box(const BoundingBoxf3& box) { m_scene_box = box; }
|
2019-04-01 08:00:10 +00:00
|
|
|
|
2020-01-15 11:49:34 +00:00
|
|
|
#if ENABLE_6DOF_CAMERA
|
|
|
|
void select_view(const std::string& direction);
|
|
|
|
#else
|
2019-04-01 08:00:10 +00:00
|
|
|
bool select_view(const std::string& direction);
|
2020-01-15 11:49:34 +00:00
|
|
|
#endif // ENABLE_6DOF_CAMERA
|
2019-04-01 08:00:10 +00:00
|
|
|
|
|
|
|
const std::array<int, 4>& get_viewport() const { return m_viewport; }
|
|
|
|
const Transform3d& get_view_matrix() const { return m_view_matrix; }
|
|
|
|
const Transform3d& get_projection_matrix() const { return m_projection_matrix; }
|
|
|
|
|
|
|
|
Vec3d get_dir_right() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(0); }
|
|
|
|
Vec3d get_dir_up() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(1); }
|
2019-06-13 06:38:49 +00:00
|
|
|
Vec3d get_dir_forward() const { return -m_view_matrix.matrix().block(0, 0, 3, 3).row(2); }
|
2019-04-01 08:00:10 +00:00
|
|
|
|
2019-06-13 06:47:38 +00:00
|
|
|
Vec3d get_position() const { return m_view_matrix.matrix().inverse().block(0, 3, 3, 1); }
|
2019-04-01 08:00:10 +00:00
|
|
|
|
2019-06-14 08:38:09 +00:00
|
|
|
double get_near_z() const { return m_frustrum_zs.first; }
|
|
|
|
double get_far_z() const { return m_frustrum_zs.second; }
|
|
|
|
|
2019-06-24 07:38:46 +00:00
|
|
|
double get_fov() const;
|
|
|
|
|
2019-04-01 08:00:10 +00:00
|
|
|
void apply_viewport(int x, int y, unsigned int w, unsigned int h) const;
|
|
|
|
void apply_view_matrix() const;
|
2019-11-28 13:18:24 +00:00
|
|
|
// Calculates and applies the projection matrix tighting the frustrum z range around the given box.
|
|
|
|
// If larger z span is needed, pass the desired values of near and far z (negative values are ignored)
|
|
|
|
void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0) const;
|
2019-05-16 13:54:11 +00:00
|
|
|
|
2019-10-31 15:40:38 +00:00
|
|
|
#if ENABLE_THUMBNAIL_GENERATOR
|
|
|
|
void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor);
|
|
|
|
void zoom_to_volumes(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToVolumesMarginFactor);
|
|
|
|
#else
|
2019-06-19 12:18:51 +00:00
|
|
|
void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h);
|
2019-10-31 15:40:38 +00:00
|
|
|
#endif // ENABLE_THUMBNAIL_GENERATOR
|
2019-06-19 12:18:51 +00:00
|
|
|
|
2019-05-20 07:39:57 +00:00
|
|
|
#if ENABLE_CAMERA_STATISTICS
|
|
|
|
void debug_render() const;
|
|
|
|
#endif // ENABLE_CAMERA_STATISTICS
|
|
|
|
|
2020-01-15 11:49:34 +00:00
|
|
|
#if ENABLE_6DOF_CAMERA
|
|
|
|
// translate the camera in world space
|
|
|
|
void translate_world(const Vec3d& displacement);
|
|
|
|
|
|
|
|
// rotate the camera on a sphere having center == m_target and radius == m_distance
|
|
|
|
// using the given variations of spherical coordinates
|
2020-01-16 08:12:36 +00:00
|
|
|
void rotate_on_sphere(double delta_azimut_rad, double delta_zenit_rad);
|
2020-01-15 11:49:34 +00:00
|
|
|
|
|
|
|
// rotate the camera around three axes parallel to the camera local axes and passing through m_target
|
|
|
|
void rotate_local_around_target(const Vec3d& rotation_rad);
|
|
|
|
|
2020-01-16 11:00:54 +00:00
|
|
|
// rotate the camera around three axes parallel to the camera local axes and passing through the given pivot point
|
|
|
|
void rotate_local_around_pivot(const Vec3d& rotation_rad, const Vec3d& pivot);
|
|
|
|
|
2020-01-15 11:49:34 +00:00
|
|
|
// returns true if the camera z axis (forward) is pointing in the negative direction of the world z axis
|
2020-01-17 08:36:34 +00:00
|
|
|
bool is_looking_downward() const { return get_dir_forward().dot(Vec3d::UnitZ()) < 0.0; }
|
|
|
|
|
|
|
|
double max_zoom() const { return 100.0; }
|
|
|
|
double min_zoom() const;
|
2020-01-15 11:49:34 +00:00
|
|
|
#endif // ENABLE_6DOF_CAMERA
|
|
|
|
|
2019-05-16 13:54:11 +00:00
|
|
|
private:
|
2019-06-14 08:38:09 +00:00
|
|
|
// returns tight values for nearZ and farZ plane around the given bounding box
|
|
|
|
// the camera MUST be outside of the bounding box in eye coordinate of the given box
|
|
|
|
std::pair<double, double> calc_tight_frustrum_zs_around(const BoundingBoxf3& box) const;
|
2019-10-31 15:40:38 +00:00
|
|
|
#if ENABLE_THUMBNAIL_GENERATOR
|
|
|
|
double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor) const;
|
|
|
|
double calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, Vec3d& center, double margin_factor = DefaultZoomToVolumesMarginFactor) const;
|
|
|
|
#else
|
2019-06-19 12:18:51 +00:00
|
|
|
double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const;
|
2019-10-31 15:40:38 +00:00
|
|
|
#endif // ENABLE_THUMBNAIL_GENERATOR
|
2019-08-03 07:07:38 +00:00
|
|
|
void set_distance(double distance) const;
|
2020-01-15 11:49:34 +00:00
|
|
|
|
|
|
|
#if ENABLE_6DOF_CAMERA
|
2020-01-28 08:13:54 +00:00
|
|
|
void look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up);
|
2020-01-15 11:49:34 +00:00
|
|
|
void set_default_orientation();
|
|
|
|
Vec3d validate_target(const Vec3d& target) const;
|
|
|
|
#endif // ENABLE_6DOF_CAMERA
|
2019-03-06 14:46:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // GUI
|
|
|
|
} // Slic3r
|
|
|
|
|
|
|
|
#endif // slic3r_Camera_hpp_
|
|
|
|
|