Camera refactoring: Frustrum calculations moved into Camera class
This commit is contained in:
parent
cf35d750a0
commit
8c6304688d
3 changed files with 44 additions and 62 deletions
|
@ -28,6 +28,8 @@ Camera::Camera()
|
||||||
, inverted_phi(false)
|
, inverted_phi(false)
|
||||||
, m_theta(45.0f)
|
, m_theta(45.0f)
|
||||||
, m_target(Vec3d::Zero())
|
, m_target(Vec3d::Zero())
|
||||||
|
, m_view_matrix(Transform3d::Identity())
|
||||||
|
, m_projection_matrix(Transform3d::Identity())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,11 +67,6 @@ void Camera::set_theta(float theta, bool apply_limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::set_scene_box(const BoundingBoxf3& box)
|
|
||||||
{
|
|
||||||
m_scene_box = box;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Camera::select_view(const std::string& direction)
|
bool Camera::select_view(const std::string& direction)
|
||||||
{
|
{
|
||||||
const float* dir_vec = nullptr;
|
const float* dir_vec = nullptr;
|
||||||
|
@ -111,13 +108,43 @@ void Camera::apply_view_matrix() const
|
||||||
glsafe(::glLoadIdentity());
|
glsafe(::glLoadIdentity());
|
||||||
|
|
||||||
glsafe(::glRotatef(-m_theta, 1.0f, 0.0f, 0.0f)); // pitch
|
glsafe(::glRotatef(-m_theta, 1.0f, 0.0f, 0.0f)); // pitch
|
||||||
glsafe(::glRotatef(phi, 0.0f, 0.0f, 1.0f)); // yaw
|
glsafe(::glRotatef(phi, 0.0f, 0.0f, 1.0f)); // yaw
|
||||||
glsafe(::glTranslated(-m_target(0), -m_target(1), -m_target(2)));
|
|
||||||
|
glsafe(::glTranslated(-m_target(0), -m_target(1), -m_target(2))); // target to origin
|
||||||
|
|
||||||
glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, m_view_matrix.data()));
|
glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, m_view_matrix.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const
|
void Camera::apply_projection(const BoundingBoxf3& box) const
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: calculate a tighter value for depth will improve z-fighting
|
||||||
|
// Set at least some minimum depth in case the bounding box is empty to avoid an OpenGL driver error.
|
||||||
|
double depth = std::max(1.0, 5.0 * box.max_size());
|
||||||
|
apply_ortho_projection(-w2, w2, -h2, h2, -depth, depth);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// case Perspective:
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(::glMatrixMode(GL_PROJECTION));
|
||||||
glsafe(::glLoadIdentity());
|
glsafe(::glLoadIdentity());
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
void set_theta(float theta, bool apply_limit);
|
void set_theta(float theta, bool apply_limit);
|
||||||
|
|
||||||
const BoundingBoxf3& get_scene_box() const { return m_scene_box; }
|
const BoundingBoxf3& get_scene_box() const { return m_scene_box; }
|
||||||
void set_scene_box(const BoundingBoxf3& box);
|
void set_scene_box(const BoundingBoxf3& box){ m_scene_box = box; }
|
||||||
|
|
||||||
bool select_view(const std::string& direction);
|
bool select_view(const std::string& direction);
|
||||||
|
|
||||||
|
@ -62,7 +62,10 @@ public:
|
||||||
|
|
||||||
void apply_viewport(int x, int y, unsigned int w, unsigned int h) const;
|
void apply_viewport(int x, int y, unsigned int w, unsigned int h) const;
|
||||||
void apply_view_matrix() const;
|
void apply_view_matrix() const;
|
||||||
void apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const;
|
void apply_projection(const BoundingBoxf3& box) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void apply_ortho_projection(double x_min, double x_max, double y_min, double y_max, double z_min, double z_max) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // GUI
|
} // GUI
|
||||||
|
|
|
@ -1472,6 +1472,7 @@ BoundingBoxf3 GLCanvas3D::scene_bounding_box() const
|
||||||
bb.min(2) = std::min(bb.min(2), -h);
|
bb.min(2) = std::min(bb.min(2), -h);
|
||||||
bb.max(2) = std::max(bb.max(2), h);
|
bb.max(2) = std::max(bb.max(2), h);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3593,59 +3594,10 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
|
||||||
|
|
||||||
// ensures that this canvas is current
|
// ensures that this canvas is current
|
||||||
_set_current();
|
_set_current();
|
||||||
|
|
||||||
|
// updates camera
|
||||||
m_camera.apply_viewport(0, 0, w, h);
|
m_camera.apply_viewport(0, 0, w, h);
|
||||||
|
m_camera.apply_projection(_max_bounding_box());
|
||||||
const BoundingBoxf3& bbox = _max_bounding_box();
|
|
||||||
|
|
||||||
switch (m_camera.type)
|
|
||||||
{
|
|
||||||
case Camera::Ortho:
|
|
||||||
{
|
|
||||||
float w2 = w;
|
|
||||||
float h2 = h;
|
|
||||||
float two_zoom = 2.0f * m_camera.zoom;
|
|
||||||
if (two_zoom != 0.0f)
|
|
||||||
{
|
|
||||||
float inv_two_zoom = 1.0f / two_zoom;
|
|
||||||
w2 *= inv_two_zoom;
|
|
||||||
h2 *= inv_two_zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: calculate a tighter value for depth will improve z-fighting
|
|
||||||
// Set at least some minimum depth in case the bounding box is empty to avoid an OpenGL driver error.
|
|
||||||
float depth = std::max(1.f, 5.0f * (float)bbox.max_size());
|
|
||||||
m_camera.apply_ortho_projection(-w2, w2, -h2, h2, -depth, depth);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// case Camera::Perspective:
|
|
||||||
// {
|
|
||||||
// float bbox_r = (float)bbox.radius();
|
|
||||||
// float fov = PI * 45.0f / 180.0f;
|
|
||||||
// float fov_tan = tan(0.5f * fov);
|
|
||||||
// float cam_distance = 0.5f * bbox_r / fov_tan;
|
|
||||||
// m_camera.distance = cam_distance;
|
|
||||||
//
|
|
||||||
// float nr = cam_distance - bbox_r * 1.1f;
|
|
||||||
// float fr = cam_distance + bbox_r * 1.1f;
|
|
||||||
// if (nr < 1.0f)
|
|
||||||
// nr = 1.0f;
|
|
||||||
//
|
|
||||||
// if (fr < nr + 1.0f)
|
|
||||||
// fr = nr + 1.0f;
|
|
||||||
//
|
|
||||||
// float h2 = fov_tan * nr;
|
|
||||||
// float w2 = h2 * w / h;
|
|
||||||
// ::glFrustum(-w2, w2, -h2, h2, nr, fr);
|
|
||||||
//
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Invalid camera type.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue