#include #include #include #include #include #include #include namespace psemek::geom { matrix camera::transform() const { return projection() * view(); } point camera::position() const { vector b{ 0.f, 0.f, 0.f, 1.f }; gauss(view(), b); return { b[0], b[1], b[2] }; } vector camera::axis_x() const { vector b{ 1.f, 0.f, 0.f, 0.f }; gauss(view(), b); return { b[0], b[1], b[2] }; } vector camera::axis_y() const { vector b{ 0.f, 1.f, 0.f, 0.f }; gauss(view(), b); return { b[0], b[1], b[2] }; } vector camera::axis_z() const { vector b{ 0.f, 0.f, 1.f, 0.f }; gauss(view(), b); return { b[0], b[1], b[2] }; } vector camera::direction(float x, float y) const { vector b{ x, y, -1.f, 1.f}; gauss(transform(), b); point p{ b[0] / b[3], b[1] / b[3], b[2] / b[3] }; return p - position(); } std::array, 6> camera::clip_planes() const { auto const m = transpose(transform()); std::array, 6> p; p[0] = m * vector{1.f, 0.f, 0.f, 1.f}; p[1] = m * vector{-1.f, 0.f, 0.f, 1.f}; p[2] = m * vector{0.f, 1.f, 0.f, 1.f}; p[3] = m * vector{0.f, -1.f, 0.f, 1.f}; p[4] = m * vector{0.f, 0.f, 1.f, 1.f}; p[5] = m * vector{0.f, 0.f, -1.f, 1.f}; return p; } matrix perspective_camera::projection() const { return perspective(fov_x, fov_y, near_clip, far_clip).homogeneous_matrix(); } matrix spherical_camera::view() const { return translation({0.f, 0.f, -distance}).homogeneous_matrix() * homogeneous(plane_rotation(1, 2, elevation_angle).matrix()) * homogeneous(plane_rotation(2, 0, azimuthal_angle).matrix()) * translation({ -target[0], -target[1], -target[2] }).homogeneous_matrix() ; } }