9 fov(Geometry::Angle<float>::from_turns(0.125)),
20 void Camera::set_field_of_view(const Geometry::Angle<float> &f)
25 void Camera::set_aspect(float a)
30 void Camera::set_depth_clip(float n, float f)
36 void Camera::set_frustum_axis(float x, float y)
42 void Camera::set_position(const Vector3 &p)
48 void Camera::set_up_direction(const Vector3 &u)
50 up_dir = normalize(u);
55 void Camera::set_look_direction(const Vector3 &l)
57 look_dir = normalize(l);
62 void Camera::look_at(const Vector3 &p)
64 set_look_direction(p-position);
67 Vector3 Camera::project(const Vector4 &p) const
69 float frustum_h = tan(fov/2.0f);
70 float frustum_w = frustum_h*aspect;
71 float z_range = clip_far-clip_near;
73 Vector4 eye = matrix*p;
75 return Vector3(eye.x/frustum_w/-eye.z, eye.y/frustum_h/-eye.z,
76 (clip_far+clip_near)/z_range+2*clip_far*clip_near/(eye.z*z_range));
79 Vector3 Camera::project(const Vector3 &p) const
81 return project(Vector4(p.x, p.y, p.z, 1.0));
84 Vector4 Camera::unproject(const Vector4 &p) const
86 float frustum_h = tan(fov/2.0f);
87 float frustum_w = frustum_h*aspect;
88 float z_range = clip_far-clip_near;
90 float z = (2*clip_far*clip_near)/(p.z*z_range-(clip_far+clip_near))-matrix[14]*p.w;
91 float x = p.x*-z*frustum_w-matrix[12]*p.w;
92 float y = p.y*-z*frustum_h-matrix[13]*p.w;
94 return Vector4(matrix[0]*x+matrix[1]*y+matrix[2]*z,
95 matrix[4]*x+matrix[5]*y+matrix[6]*z,
96 matrix[8]*x+matrix[9]*y+matrix[10]*z,
100 void Camera::apply() const
102 float frustum_h = tan(fov/2.0f)*clip_near;
103 float frustum_w = frustum_h*aspect;
104 float left = frustum_w*(frustum_x-1.0f);
105 float right = frustum_w*(frustum_x+1.0f);
106 float bottom = frustum_h*(frustum_y-1.0f);
107 float top = frustum_h*(frustum_y+1.0f);
108 MatrixStack::projection() = Matrix::frustum(left, right, bottom, top, clip_near, clip_far);
109 MatrixStack::modelview() = matrix;
112 void Camera::compute_matrix()
114 Vector3 right_dir = normalize(cross(look_dir, up_dir));
117 mdata[0] = right_dir.x;
118 mdata[4] = right_dir.y;
119 mdata[8] = right_dir.z;
121 mdata[1] = right_dir.y*look_dir.z-right_dir.z*look_dir.y;
122 mdata[5] = right_dir.z*look_dir.x-right_dir.x*look_dir.z;
123 mdata[9] = right_dir.x*look_dir.y-right_dir.y*look_dir.x;
125 mdata[2] = -look_dir.x;
126 mdata[6] = -look_dir.y;
127 mdata[10] = -look_dir.z;
129 mdata[12] = -position.x*mdata[0]-position.y*mdata[4]-position.z*mdata[8];
130 mdata[13] = -position.x*mdata[1]-position.y*mdata[5]-position.z*mdata[9];
131 mdata[14] = -position.x*mdata[2]-position.y*mdata[6]-position.z*mdata[10];