Enabled perspective camera

This commit is contained in:
Enrico Turri 2019-06-19 13:01:18 +02:00
parent a15cb597ab
commit a3e6412113
3 changed files with 52 additions and 41 deletions

View file

@ -22,19 +22,19 @@ static const float VIEW_REAR[2] = { 180.0f, 90.0f };
namespace Slic3r {
namespace GUI {
const float Camera::DefaultDistance = 1000.0f;
const double Camera::DefaultDistance = 1000.0;
double Camera::FrustrumMinZSize = 50.0;
double Camera::FrustrumZMargin = 10.0;
Camera::Camera()
: type(Ortho)
, zoom(1.0f)
: zoom(1.0f)
, phi(45.0f)
, distance(DefaultDistance)
, requires_zoom_to_bed(false)
, inverted_phi(false)
, m_theta(45.0f)
, m_type(Ortho)
, m_target(Vec3d::Zero())
, m_theta(45.0f)
, m_distance(DefaultDistance)
, m_view_matrix(Transform3d::Identity())
, m_projection_matrix(Transform3d::Identity())
{
@ -42,18 +42,27 @@ Camera::Camera()
std::string Camera::get_type_as_string() const
{
switch (type)
switch (m_type)
{
default:
case Unknown:
return "unknown";
// case Perspective:
// return "perspective";
case Perspective:
return "perspective";
case Ortho:
return "orthographic";
};
}
void Camera::select_next_type()
{
unsigned char next = (unsigned char)m_type + 1;
if (next == (unsigned char)Num_types)
next = 1;
m_type = (EType)next;
}
void Camera::set_target(const Vec3d& target)
{
m_target = target;
@ -114,7 +123,7 @@ void Camera::apply_view_matrix() const
double theta_rad = Geometry::deg2rad(-(double)m_theta);
double phi_rad = Geometry::deg2rad((double)phi);
double sin_theta = ::sin(theta_rad);
Vec3d camera_pos = m_target + (double)distance * Vec3d(sin_theta * ::sin(phi_rad), sin_theta * ::cos(phi_rad), ::cos(theta_rad));
Vec3d camera_pos = m_target + m_distance * Vec3d(sin_theta * ::sin(phi_rad), sin_theta * ::cos(phi_rad), ::cos(theta_rad));
glsafe(::glMatrixMode(GL_MODELVIEW));
glsafe(::glLoadIdentity());
@ -131,27 +140,36 @@ void Camera::apply_projection(const BoundingBoxf3& box) const
{
m_frustrum_zs = calc_tight_frustrum_zs_around(box);
switch (type)
double w = (double)m_viewport[2];
double h = (double)m_viewport[3];
double two_zoom = 2.0 * zoom;
if (two_zoom != 0.0)
{
double inv_two_zoom = 1.0 / two_zoom;
w *= inv_two_zoom;
h *= inv_two_zoom;
}
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glLoadIdentity());
switch (m_type)
{
default:
case Ortho:
{
double w2 = (double)m_viewport[2];
double h2 = (double)m_viewport[3];
double two_zoom = 2.0 * zoom;
if (two_zoom != 0.0)
{
double inv_two_zoom = 1.0 / two_zoom;
w2 *= inv_two_zoom;
h2 *= inv_two_zoom;
}
apply_ortho_projection(-w2, w2, -h2, h2, m_frustrum_zs.first, m_frustrum_zs.second);
glsafe(::glOrtho(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
break;
}
// case Perspective:
// {
// }
case Perspective:
{
glsafe(::glFrustum(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
break;
}
}
glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data()));
glsafe(::glMatrixMode(GL_MODELVIEW));
}
#if ENABLE_CAMERA_STATISTICS
@ -187,17 +205,6 @@ void Camera::debug_render() const
}
#endif // ENABLE_CAMERA_STATISTICS
void Camera::apply_ortho_projection(double x_min, double x_max, double y_min, double y_max, double z_min, double z_max) const
{
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glLoadIdentity());
glsafe(::glOrtho(x_min, x_max, y_min, y_max, z_min, z_max));
glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data()));
glsafe(::glMatrixMode(GL_MODELVIEW));
}
std::pair<double, double> Camera::calc_tight_frustrum_zs_around(const BoundingBoxf3& box) const
{
std::pair<double, double> ret = std::make_pair(DBL_MAX, -DBL_MAX);

View file

@ -9,29 +9,29 @@ namespace GUI {
struct Camera
{
static const float DefaultDistance;
static const double DefaultDistance;
static double FrustrumMinZSize;
static double FrustrumZMargin;
enum EType : unsigned char
{
Unknown,
// Perspective,
Perspective,
Ortho,
Num_types
};
EType type;
float zoom;
float phi;
// Distance between camera position and camera target measured along the camera Z axis
float distance;
bool requires_zoom_to_bed;
bool inverted_phi;
private:
EType m_type;
Vec3d m_target;
float m_theta;
// Distance between camera position and camera target measured along the camera Z axis
double m_distance;
mutable std::array<int, 4> m_viewport;
mutable Transform3d m_view_matrix;
@ -43,7 +43,10 @@ private:
public:
Camera();
EType get_type() const { return m_type; }
std::string get_type_as_string() const;
void set_type(EType type) { m_type = type; }
void select_next_type();
const Vec3d& get_target() const { return m_target; }
void set_target(const Vec3d& target);
@ -78,7 +81,6 @@ public:
#endif // ENABLE_CAMERA_STATISTICS
private:
void apply_ortho_projection(double x_min, double x_max, double y_min, double y_max, double z_min, double z_max) const;
// 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;

View file

@ -2365,6 +2365,8 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
case 'B':
case 'b': { zoom_to_bed(); break; }
case 'C':
case 'c': { m_camera.select_next_type(); m_dirty = true; break; }
case 'I':
case 'i': { set_camera_zoom(1.0f); break; }
case 'O':