Orrery
A GPU-accelerated N-body gravitational simulator
Loading...
Searching...
No Matches
orrery::viz::OrbitCamera Class Reference

A camera that orbits a point. More...

#include <orrery/viz/camera.hpp>

Public Member Functions

core::Vec3 eye () const noexcept
 Where the camera is, which follows from the target, the distance and the two angles.
Mat4 view () const noexcept
Mat4 projection (core::Real aspect_ratio) const noexcept
Mat4 view_projection (core::Real aspect_ratio) const noexcept
 The product of the two, which is the only matrix the renderer needs.
void orbit (core::Real delta_azimuth, core::Real delta_elevation) noexcept
 Turn about the target, clamping the elevation away from the poles.
void zoom (core::Real factor) noexcept
 Move towards or away from the target by a multiplicative factor.
void pan (core::Real right, core::Real up) noexcept
 Slide the target across the plane of the screen.

Public Attributes

core::Vec3 target
 The point the camera looks at.
core::Real distance = 30
 The distance from the target, which is what zooming changes.
core::Real azimuth = 0
 The angle in the x-y plane, in radians, measured from the positive x axis.
core::Real elevation = static_cast<core::Real>(0.3)
 The angle above the x-y plane, in radians.
core::Real field_of_view = static_cast<core::Real>(0.6981317)
 The whole vertical angle the frustum spans, in radians.
core::Real near_fraction = static_cast<core::Real>(0.01)
 The near and far clipping distances, as fractions of the distance to the target.
core::Real far_fraction = 10

Static Public Attributes

static constexpr core::Real kMaximumElevation = static_cast<core::Real>(1.5607963)
 The largest angle from the plane the camera will take, in radians.

Detailed Description

A camera that orbits a point.

The angles follow the usual astronomical convention rather than a graphics one: the azimuth is measured in the x-y plane from the positive x axis, and the elevation up from that plane towards positive z. The simulation's own spin axes are z axes, so a camera at zero elevation looks at a disc galaxy edge on and one at a right angle looks at it face on, which is the vocabulary the scenario is described in.

Member Function Documentation

◆ zoom()

void orrery::viz::OrbitCamera::zoom ( core::Real factor)
noexcept

Move towards or away from the target by a multiplicative factor.

Multiplicative rather than additive so that one notch of a scroll wheel covers the same fraction of the remaining distance wherever the camera is. An additive step is either uselessly small when far away or lands inside the target when near it.

The distance is kept positive; a factor that would take it to zero or through it leaves it at the smallest value this camera will hold.

◆ pan()

void orrery::viz::OrbitCamera::pan ( core::Real right,
core::Real up )
noexcept

Slide the target across the plane of the screen.

The arguments are fractions of the height of the frame at the distance of the target, so a pan of one moves the target by the full height of what is on screen whatever the camera's distance or field of view.

Member Data Documentation

◆ kMaximumElevation

core::Real orrery::viz::OrbitCamera::kMaximumElevation = static_cast<core::Real>(1.5607963)
staticconstexpr

The largest angle from the plane the camera will take, in radians.

A hundredth of a radian short of the pole. Exactly at the pole the direction of view is parallel to the up vector and the view transform has no defined orientation, which shows on screen as the image spinning through a right angle as the camera crosses it. Clamping is the ordinary remedy and the alternative, carrying an explicit up vector through the controls, buys a view nobody has asked for at the cost of a camera that can end up upside down with no obvious way back.

◆ field_of_view

core::Real orrery::viz::OrbitCamera::field_of_view = static_cast<core::Real>(0.6981317)

The whole vertical angle the frustum spans, in radians.

Forty degrees. Wide enough that a merging pair fills the frame without the perspective distortion a wider angle gives, which for a point cloud with no straight lines in it reads as the near side of the system being unaccountably larger than the far side.

◆ near_fraction

core::Real orrery::viz::OrbitCamera::near_fraction = static_cast<core::Real>(0.01)

The near and far clipping distances, as fractions of the distance to the target.

Relative rather than absolute because the camera is used at scales from a single galaxy to a pair separated by twenty scale lengths, and a fixed near plane that suits one clips through the other. Keeping the ratio of far to near at a thousand also keeps the depth buffer usable, which matters even though the points are drawn without depth testing: a caller that turns it on should not find the precision already spent.


The documentation for this class was generated from the following file: