namespace Msp {
namespace GL {
+/**
+Represents a point of view in 3D space.
+
+A Camera provides two matrices. The view matrix is the inverse of the camera's
+model matrix and transforms coordinates from world space to eye space (the
+camera's object space). The projection matrix transforms coordinates from eye
+space to clip space.
+
+Orientation of the Camera is determined by look direction and up direction.
+Look direction corresponds to the negative Z axis direction in eye space. The
+YZ plane of eye space is aligned to the plane formed by the look and up
+directions. Setting the up direction to the opposite of gravity direction is
+an easy way to keep the camera upright.
+*/
class Camera: public Placeable
{
public:
};
private:
- Geometry::Angle<float> fov;
- float height;
- float aspect;
+ Geometry::Angle<float> fov = Geometry::Angle<float>::from_turns(0.125f);
+ float height = 0.0f;
+ float aspect = 4.0f/3.0f;
// Some compilers have "near" and "far" keywords
- float clip_near;
- float clip_far;
- float frustum_x;
- float frustum_y;
+ float clip_near = 0.1f;
+ float clip_far = 10.0f;
+ float frustum_x = 0.0f;
+ float frustum_y = 0.0f;
Geometry::Angle<float> rotate;
- Vector3 position;
- Vector3 look_dir;
- Vector3 up_dir;
+ Vector3 position = { 0.0f, 0.0f, 0.0f };
+ Vector3 look_dir = { 0.0f, 0.0f, -1.0f };
+ Vector3 up_dir = { 0.0f, 1.0f, 0.0f };
Matrix view_matrix;
Matrix proj_matrix;
ProgramData shdata;
+ Vector4 frustum_planes[6];
public:
Camera();
+ void copy_parameters(const Camera &);
+
+ /** Sets the camera projection to perspective, characterised by the vertical
+ field of view. Horizontal FoV is computed with the aspect ratio. */
void set_field_of_view(const Geometry::Angle<float> &);
+
+ /** Sets the camera projection to orthogonal, characterized by the size of
+ the projection region. */
void set_orthographic(float, float);
+
void set_aspect_ratio(float);
void set_depth_clip(float, float);
+
+ /** Sets the direction of the frustum axis, which corresponds to the center
+ of the screen. The offset is expressed in terms of the neutral frustum such
+ that -1 is the left or bottom edge and 1 is the right or top edge. */
void set_frustum_axis(float, float);
+
+ /** Apply a rotation to the view frustum after projection. This can be used
+ with rotated displayes without affecting the camera's orientation. */
void set_frustum_rotation(const Geometry::Angle<float> &);
+
const Geometry::Angle<float> &get_field_of_view() const { return fov; }
bool is_orthographic() const { return fov==Geometry::Angle<float>::zero(); }
float get_orthographic_width() const { return height*aspect; }
Vector4 unproject(const Vector4 &) const;
Vector3 unproject(const Vector3 &) const;
+ /** Returns a ProgramData object containing the camera matrices. */
const ProgramData &get_shader_data() const { return shdata; }
+ bool is_in_frustum(const Renderable &) const;
+
private:
void update_projection_matrix();
void update_object_matrix();
+ void update_frustum_planes();
public:
void set_debug_name(const std::string &);