Change free camera: any possible orientation now
This commit is contained in:
parent
957493e2e2
commit
c89deef9cf
3 changed files with 47 additions and 24 deletions
|
|
@ -205,8 +205,7 @@ struct grass_app
|
|||
camera.near_clip = 0.1f;
|
||||
camera.far_clip = 1000.f;
|
||||
camera.pos = {0.5f, 0.5f, 1.5f};
|
||||
camera.elevation_angle = geom::rad(15.f);
|
||||
camera.azimuthal_angle = geom::rad(-90.f);
|
||||
camera.rotateYZ(geom::rad(-90.f));
|
||||
|
||||
init_ground();
|
||||
init_grass();
|
||||
|
|
@ -474,8 +473,8 @@ struct grass_app
|
|||
|
||||
if (is_middle_button_down())
|
||||
{
|
||||
camera.azimuthal_angle -= dx * 0.01f;
|
||||
camera.elevation_angle += dy * 0.01f;
|
||||
camera.rotateZX(0.01f * dx);
|
||||
camera.rotateYZ(0.01f * dy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -128,22 +128,28 @@ namespace psemek::geom
|
|||
struct free_camera
|
||||
: perspective_camera
|
||||
{
|
||||
// assumes up is +Z
|
||||
// azimuthal angle is in XY plane
|
||||
// both angles zero gives X right, Y forward, and Z up
|
||||
|
||||
float azimuthal_angle;
|
||||
float elevation_angle;
|
||||
point<float, 3> pos;
|
||||
vector<float, 3> axes[3];
|
||||
|
||||
free_camera() = default;
|
||||
free_camera()
|
||||
{
|
||||
axes[0] = {1.f, 0.f, 0.f};
|
||||
axes[1] = {0.f, 1.f, 0.f};
|
||||
axes[2] = {0.f, 0.f, 1.f};
|
||||
}
|
||||
|
||||
free_camera(float fov_x, float fov_y, float near_clip, float far_clip, float azimuthal_angle, float elevation_angle, point<float, 3> const & pos)
|
||||
free_camera(float fov_x, float fov_y, float near_clip, float far_clip, point<float, 3> const & pos)
|
||||
: perspective_camera(fov_x, fov_y, near_clip, far_clip)
|
||||
, azimuthal_angle{azimuthal_angle}
|
||||
, elevation_angle{elevation_angle}
|
||||
, pos{pos}
|
||||
{}
|
||||
{
|
||||
axes[0] = {1.f, 0.f, 0.f};
|
||||
axes[1] = {0.f, 1.f, 0.f};
|
||||
axes[2] = {0.f, 0.f, 1.f};
|
||||
}
|
||||
|
||||
void rotateXY(float angle);
|
||||
void rotateYZ(float angle);
|
||||
void rotateZX(float angle);
|
||||
|
||||
matrix<float, 4, 4> view() const override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -120,17 +120,35 @@ namespace psemek::geom
|
|||
return tr.homogeneous_matrix();
|
||||
}
|
||||
|
||||
static void rotate(geom::vector<float, 3> & a, geom::vector<float, 3> & b, float angle)
|
||||
{
|
||||
auto s = std::sin(angle);
|
||||
auto c = std::cos(angle);
|
||||
|
||||
auto aa = a * c - b * s;
|
||||
auto bb = a * s + b * c;
|
||||
a = aa;
|
||||
b = bb;
|
||||
}
|
||||
|
||||
void free_camera::rotateXY(float angle)
|
||||
{
|
||||
rotate(axes[0], axes[1], angle);
|
||||
}
|
||||
|
||||
void free_camera::rotateYZ(float angle)
|
||||
{
|
||||
rotate(axes[1], axes[2], angle);
|
||||
}
|
||||
|
||||
void free_camera::rotateZX(float angle)
|
||||
{
|
||||
rotate(axes[2], axes[0], angle);
|
||||
}
|
||||
|
||||
matrix<float, 4, 4> free_camera::view() const
|
||||
{
|
||||
auto tr =
|
||||
swap<float, 3>(1, 2).transform()
|
||||
* scale<float, 3>({1.f, -1.f, 1.f}).transform()
|
||||
* plane_rotation<float, 3>(1, 2, elevation_angle).transform()
|
||||
* plane_rotation<float, 3>(1, 0, azimuthal_angle).transform()
|
||||
* translation<float, 3>({ -pos[0], -pos[1], -pos[2] }).transform()
|
||||
;
|
||||
|
||||
return tr.homogeneous_matrix();
|
||||
return homogeneous(by_rows(axes[0], axes[1], axes[2])) * translation{geom::point<float, 3>::zero() - pos}.homogeneous_matrix();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue