nngn
Loading...
Searching...
No Matches
nngn::Camera Struct Reference

Abstract orthographic/perspective camera. More...

#include <camera.h>

Collaboration diagram for nngn::Camera:

Public Types

enum  Flag : uint8_t {
  UPDATED = 1u << 1 , SCREEN_UPDATED = 1u << 2 , DASH = 1u << 3 , PERSPECTIVE = 1u << 4 ,
  N_FLAGS = 1u << 5 , UPDATED = 1u << 1 , SCREEN_UPDATED = 1u << 2 , DASH = 1u << 3 ,
  PERSPECTIVE = 1u << 4 , IGNORE_LIMITS = 1u << 4
}
 
enum  Flag : u8 {
  UPDATED = 1u << 1 , SCREEN_UPDATED = 1u << 2 , DASH = 1u << 3 , PERSPECTIVE = 1u << 4 ,
  N_FLAGS = 1u << 5 , UPDATED = 1u << 1 , SCREEN_UPDATED = 1u << 2 , DASH = 1u << 3 ,
  PERSPECTIVE = 1u << 4 , IGNORE_LIMITS = 1u << 4
}
 State flags and configuration. More...
 

Public Member Functions

bool dash (void) const
 
bool perspective (void) const
 
vec3 pos (void) const
 
vec3 eye (void) const
 
vec3 up (void) const
 
mat4 gen_proj (void) const
 
mat4 gen_screen_proj (void) const
 
mat4 gen_view (void) const
 
float fov_z (void) const
 
vec3 to_clip (vec3 vp) const
 
vec4 to_view (vec3 vp) const
 
vec3 to_world (vec3 vp) const
 
void set_perspective (bool b)
 
void set_screen (const uvec2 &s)
 
void set_pos (const vec3 &pos)
 
void set_rot (const vec3 &rot)
 
void set_zoom (float z)
 
void set_fov_y (float f)
 
void set_dash (bool b)
 
void look_at (const vec3 &pos, const vec3 &eye, const vec3 &up)
 
bool update (const Timing &t)
 
bool dash (void) const
 
bool perspective (void) const
 
void set_dash (bool b)
 
void set_perspective (bool b)
 
void set_ignore_limits (bool b)
 
vec3 center (void) const
 p added to a unit vector in the view direction.
 
vec3 up (void) const
 The "up" vector for the view direction.
 
vec3 world_to_view (vec3 p) const
 Projects a point from world to view space.
 
vec3 view_to_clip (vec3 p) const
 Projects a point from view to clip space.
 
vec2 clip_to_screen (vec3 p)
 Projects a point from clip to screen space.
 
vec3 screen_to_clip (vec2 p)
 Projects a point from screen to clip space.
 
vec3 clip_to_view (vec3 p) const
 Projects a point from clip to view space.
 
vec3 view_to_world (vec3 p) const
 Projects a point from view to world space.
 
float z_for_fov (void) const
 Derives Z coordinate from the camera's screen size and field of view.
 
float scale_for_fov (void) const
 Derives orthographic scaling factor from camera parameters.
 
void set_pos (vec3 p)
 
void set_rot (vec3 r)
 
void set_zoom (float z)
 
void set_fov_y (float f)
 
void set_fov_z (float z)
 
void set_screen (uvec2 s)
 
void set_limits (vec3 bl, vec3 tr)
 
void look_at (vec3 center, vec3 pos, vec3 up)
 
bool update (const Timing &t)
 

Static Public Member Functions

static constexpr float fov (float distance, float length)
 
static constexpr float fov (float z, float w)
 Calculates field of view based on screen size and distance.
 

Public Attributes

vec3 p = {}
 Position.
 
vec3 v = {}
 Velocity.
 
vec3 a = {}
 Acceleration.
 
vec3 r = {}
 
vec3 rv = {}
 
vec3 ra = {}
 
float zoom = 1
 Scaling factor.
 
float zoom_v = {}
 Scaling factor velocity.
 
float zoom_a = {}
 Scaling factor acceleration.
 
uvec2 screen = {}
 Screen size.
 
float fov_y = FOVY
 Field of view in perspective mode.
 
mat4 proj = mat4{1}
 Projection matrix (orthographic/perspective).
 
mat4 screen_proj = mat4{1}
 Projection matrix for screen coordinates.
 
mat4 view = mat4{1}
 View matrix.
 
float max_v = std::numeric_limits<float>::infinity()
 Maximum value for v.
 
float max_rv = std::numeric_limits<float>::infinity()
 
float max_zv = std::numeric_limits<float>::infinity()
 
float damp = {}
 Damping factor when not accelerating.
 
Flags< Flagflags = {}
 
vec3 rot = {}
 Rotational Euler angles (ZYX).
 
vec3 rot_v = {}
 Rotational velocity.
 
vec3 rot_a = {}
 Rotational acceleration.
 
vec3 bl_limit = {-INFINITY, -INFINITY, -INFINITY}
 Bottom left point of the limit for p.
 
vec3 tr_limit = {+INFINITY, +INFINITY, +INFINITY}
 Top right point of the limit for p.
 
float max_rot_v = INFINITY
 Maximum value for rot_v.
 
float max_zoom_v = INFINITY
 Maximum value for zoom_v.
 
float fov_z = {}
 Enable auto-adjustment of the field-of-view angle.
 
mat4 inv_proj = mat4{1}
 Inverse matrix of proj.
 
mat4 inv_view = mat4{1}
 Inverse matrix of view.
 

Static Public Attributes

static constexpr float NEAR = 0.01f
 Perspective projection near plane.
 
static constexpr float FAR = 2048.0f
 Perspective projection far plane.
 
static constexpr float FOVY = Math::radians(60.0f)
 Perspective projection field of view along the Y axis (default).
 
static const float TAN_FOVY
 
static const float TAN_HALF_FOVY
 

Detailed Description

Abstract orthographic/perspective camera.

Two complementary projection modes are supported: orthographic and perspective. Some facilities are provided to make them as close to each other as possible.

Orthographic projection

In orthographic mode, objects ocupy the XY plane. The projection matrix is set up so that objects are displayed in their natural size, scaled by the zoom parameter. Their Z position is expected to be set such that they can be rendered in any order, using a depth buffer to sort overlaps.

The z value of the position is also used as a scaling factor. This preserves the size of objects on the XY plane when transitioning from ortographic to perspective mode, as long as the camera remains parallel to the Z axis. The scaling factor is the ratio of z_for_fov to the z position.

Perspective projection

In perspective mode, objects maintain their position in the XY plane but have a third dimension in the Z direction. A standing sprite thus has the same XY position but is rotated 90° at its base around the X axis. Although counter-intuitive, having the "up" vector parallel to the Z axis (as opposed to the Y axis, as is commonly done) allows sprites to occupy the same XY position in both projection modes.

This mode tries to be as close to the orthographic mode as possible, by adjusting the camera's projection matrix and Z position so that the position and relative scale of objects is maintained as long as the camera view vector is parallel to the Z axis. With the regular camera orientation facing the direction of the -Z axis, toggling between the two projection modes leaves objects in the XY plane (such as the map) unchanged.

Field of view

Calculations of dimensions, field-of-view, etc. are based on a 14"/35.5cm, 16:9 laptop monitor at a distance of 60cm from the camera/eye:

 x/y
-----  x = 31cm
\z| /  y = 17.4cm
 \|/   z = 60cm
 fov   fov = 2 * atan(31/60) ~= 60° = π/3

The initial size of the window is taken to be the full screen size and assigned a vertical field-of-view angle of 60° (π/3). This angle can be automatically adjusted when the window is resized (see set_fov_z): this ensures the image is not distorted — i.e. objects retain their size and proportion — in perspective mode.

Member Enumeration Documentation

◆ Flag [1/2]

enum nngn::Camera::Flag : uint8_t
Enumerator
UPDATED 

Parameters of the camera have changed.

This indicates the matrices need to be recalculated (via update).

SCREEN_UPDATED 

The screen size has changed.

Not used internally, but can be used by external code mid-frame to determine whether values dependent on the screen size need to be updated.

DASH 

Increases the speed of displacement/rotation/etc.

PERSPECTIVE 

Chooses between orthographic/perspective mode.

N_FLAGS 
UPDATED 

Parameters of the camera have changed.

This indicates the matrices need to be recalculated (via update).

SCREEN_UPDATED 

The screen size has changed.

Not used internally, but can be used by external code mid-frame to determine whether values dependent on the screen size need to be updated.

DASH 

Increases the speed of displacement/rotation/etc.

PERSPECTIVE 

Chooses between orthographic/perspective mode.

IGNORE_LIMITS 

The camera limits do not restrict movement when set.

◆ Flag [2/2]

State flags and configuration.

Enumerator
UPDATED 

Parameters of the camera have changed.

This indicates the matrices need to be recalculated (via update).

SCREEN_UPDATED 

The screen size has changed.

Not used internally, but can be used by external code mid-frame to determine whether values dependent on the screen size need to be updated.

DASH 

Increases the speed of displacement/rotation/etc.

PERSPECTIVE 

Chooses between orthographic/perspective mode.

N_FLAGS 
UPDATED 

Parameters of the camera have changed.

This indicates the matrices need to be recalculated (via update).

SCREEN_UPDATED 

The screen size has changed.

Not used internally, but can be used by external code mid-frame to determine whether values dependent on the screen size need to be updated.

DASH 

Increases the speed of displacement/rotation/etc.

PERSPECTIVE 

Chooses between orthographic/perspective mode.

IGNORE_LIMITS 

The camera limits do not restrict movement when set.

Member Function Documentation

◆ center()

vec3 nngn::Camera::center ( void  ) const

p added to a unit vector in the view direction.

Here is the caller graph for this function:

◆ clip_to_screen()

vec2 nngn::Camera::clip_to_screen ( vec3  p)
inline

Projects a point from clip to screen space.

Here is the call graph for this function:

◆ clip_to_view()

vec3 nngn::Camera::clip_to_view ( vec3  p) const
inline

Projects a point from clip to view space.

Here is the call graph for this function:

◆ dash() [1/2]

bool nngn::Camera::dash ( void  ) const
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dash() [2/2]

bool nngn::Camera::dash ( void  ) const

◆ eye()

vec3 nngn::Camera::eye ( void  ) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fov() [1/2]

constexpr float nngn::Camera::fov ( float  distance,
float  length 
)
inlinestaticconstexpr
Here is the caller graph for this function:

◆ fov() [2/2]

static constexpr float nngn::Camera::fov ( float  z,
float  w 
)
staticconstexpr

Calculates field of view based on screen size and distance.

  w
-----  a = fov / 2, op = w / 2, adj = z
\z| /  tan(a) = op / adj
 \|/   tan(fov/2) = w / 2 / z
 fov
Parameters
zDistance from the camera to the projection plane.
wWidth of the projection plane.
Returns
Angle such that the intersection of the field of view with a line/plane at distance z has width w.

◆ fov_z()

float nngn::Camera::fov_z ( void  ) const

◆ gen_proj()

mat4 nngn::Camera::gen_proj ( void  ) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gen_screen_proj()

mat4 nngn::Camera::gen_screen_proj ( void  ) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gen_view()

mat4 nngn::Camera::gen_view ( void  ) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ look_at() [1/2]

void nngn::Camera::look_at ( const vec3 pos,
const vec3 eye,
const vec3 up 
)
Here is the call graph for this function:

◆ look_at() [2/2]

void nngn::Camera::look_at ( vec3  center,
vec3  pos,
vec3  up 
)
Here is the call graph for this function:

◆ perspective() [1/2]

bool nngn::Camera::perspective ( void  ) const
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ perspective() [2/2]

bool nngn::Camera::perspective ( void  ) const

◆ pos()

vec3 nngn::Camera::pos ( void  ) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scale_for_fov()

float nngn::Camera::scale_for_fov ( void  ) const
inline

Derives orthographic scaling factor from camera parameters.

When an orthographic projection is used (i.e. when the camera's Z position does not alter the apparent size of objects), this factor can be used to preserve the size of objects directly on the XY plane as if a perspective projection were used (with the same constraints as z_for_fov).

   y'
---------  y = screen.y
\ z'|   /  z = z_for_fov(), z' = p.z
y\-----/   y' / z' = y / z
  \z| /    s = y / y'
   \|/     s = z / z'
   fov
Here is the call graph for this function:

◆ screen_to_clip()

vec3 nngn::Camera::screen_to_clip ( vec2  p)
inline

Projects a point from screen to clip space.

◆ set_dash() [1/2]

void nngn::Camera::set_dash ( bool  b)
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_dash() [2/2]

void nngn::Camera::set_dash ( bool  b)

◆ set_fov_y() [1/2]

void nngn::Camera::set_fov_y ( float  f)
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_fov_y() [2/2]

void nngn::Camera::set_fov_y ( float  f)

◆ set_fov_z()

void nngn::Camera::set_fov_z ( float  z)
inline

◆ set_ignore_limits()

void nngn::Camera::set_ignore_limits ( bool  b)
inline
Here is the call graph for this function:

◆ set_limits()

void nngn::Camera::set_limits ( vec3  bl,
vec3  tr 
)
inline
Here is the call graph for this function:

◆ set_perspective() [1/2]

void nngn::Camera::set_perspective ( bool  b)
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_perspective() [2/2]

void nngn::Camera::set_perspective ( bool  b)

◆ set_pos() [1/2]

void nngn::Camera::set_pos ( const vec3 pos)
Here is the call graph for this function:

◆ set_pos() [2/2]

void nngn::Camera::set_pos ( vec3  p)
inline
Here is the call graph for this function:

◆ set_rot() [1/2]

void nngn::Camera::set_rot ( const vec3 rot)
Here is the call graph for this function:

◆ set_rot() [2/2]

void nngn::Camera::set_rot ( vec3  r)
inline
Here is the call graph for this function:

◆ set_screen() [1/2]

void nngn::Camera::set_screen ( const uvec2 s)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_screen() [2/2]

void nngn::Camera::set_screen ( uvec2  s)
inline
Here is the call graph for this function:

◆ set_zoom() [1/2]

void nngn::Camera::set_zoom ( float  z)
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_zoom() [2/2]

void nngn::Camera::set_zoom ( float  z)

◆ to_clip()

vec3 nngn::Camera::to_clip ( vec3  vp) const
Here is the caller graph for this function:

◆ to_view()

vec4 nngn::Camera::to_view ( vec3  vp) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_world()

vec3 nngn::Camera::to_world ( vec3  vp) const
Here is the call graph for this function:

◆ up() [1/2]

vec3 nngn::Camera::up ( void  ) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ up() [2/2]

vec3 nngn::Camera::up ( void  ) const

The "up" vector for the view direction.

◆ update() [1/2]

bool nngn::Camera::update ( const Timing t)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update() [2/2]

bool nngn::Camera::update ( const Timing t)

◆ view_to_clip()

vec3 nngn::Camera::view_to_clip ( vec3  p) const
inline

Projects a point from view to clip space.

Here is the call graph for this function:

◆ view_to_world()

vec3 nngn::Camera::view_to_world ( vec3  p) const
inline

Projects a point from view to world space.

Here is the call graph for this function:

◆ world_to_view()

vec3 nngn::Camera::world_to_view ( vec3  p) const
inline

Projects a point from world to view space.

Here is the call graph for this function:

◆ z_for_fov()

float nngn::Camera::z_for_fov ( void  ) const
inline

Derives Z coordinate from the camera's screen size and field of view.

When changing the camera's projection matrix from perspective to orthographic, using this Z coordinate will preserve the size of objects directly on the XY plane (provided the camera's view vector is perpendicular to it, i.e. parallel to the Z axis).

  y
-----   a = fov / 2, op = y / 2, adj = z
\z| /   tan(a) = op / adj
 \|/    tan(fov / 2) = y / 2 / z
 fov    z = y / 2 / tan(fov / 2)
Here is the caller graph for this function:

Member Data Documentation

◆ a

vec3 nngn::Camera::a = {}

Acceleration.

◆ bl_limit

vec3 nngn::Camera::bl_limit = {-INFINITY, -INFINITY, -INFINITY}

Bottom left point of the limit for p.

◆ damp

float nngn::Camera::damp = {}

Damping factor when not accelerating.

◆ FAR

static constexpr float nngn::Camera::FAR = 2048.0f
staticconstexpr

Perspective projection far plane.

◆ flags

Flags< Flag > nngn::Camera::flags = {}

◆ fov_y

float nngn::Camera::fov_y = FOVY

Field of view in perspective mode.

◆ fov_z

float nngn::Camera::fov_z ( void  ) = {}

Enable auto-adjustment of the field-of-view angle.

In perspective mode, this makes the image retain its size when the window is resized. The value should be z_for_fov. A value of zero disables auto-adjustment.

◆ FOVY

static constexpr float nngn::Camera::FOVY = Math::radians(60.0f)
staticconstexpr

Perspective projection field of view along the Y axis (default).

◆ inv_proj

mat4 nngn::Camera::inv_proj = mat4{1}

Inverse matrix of proj.

◆ inv_view

mat4 nngn::Camera::inv_view = mat4{1}

Inverse matrix of view.

◆ max_rot_v

float nngn::Camera::max_rot_v = INFINITY

Maximum value for rot_v.

◆ max_rv

float nngn::Camera::max_rv = std::numeric_limits<float>::infinity()

◆ max_v

float nngn::Camera::max_v = std::numeric_limits<float>::infinity()

Maximum value for v.

◆ max_zoom_v

float nngn::Camera::max_zoom_v = INFINITY

Maximum value for zoom_v.

◆ max_zv

float nngn::Camera::max_zv = std::numeric_limits<float>::infinity()

◆ NEAR

static constexpr float nngn::Camera::NEAR = 0.01f
staticconstexpr

Perspective projection near plane.

◆ p

vec3 nngn::Camera::p = {}

Position.

◆ proj

mat4 nngn::Camera::proj = mat4{1}

Projection matrix (orthographic/perspective).

◆ r

vec3 nngn::Camera::r = {}

◆ ra

vec3 nngn::Camera::ra = {}

◆ rot

vec3 nngn::Camera::rot = {}

Rotational Euler angles (ZYX).

◆ rot_a

vec3 nngn::Camera::rot_a = {}

Rotational acceleration.

◆ rot_v

vec3 nngn::Camera::rot_v = {}

Rotational velocity.

◆ rv

vec3 nngn::Camera::rv = {}

◆ screen

uvec2 nngn::Camera::screen = {}

Screen size.

◆ screen_proj

mat4 nngn::Camera::screen_proj = mat4{1}

Projection matrix for screen coordinates.

◆ TAN_FOVY

const float nngn::Camera::TAN_FOVY
static

◆ TAN_HALF_FOVY

const float nngn::Camera::TAN_HALF_FOVY
static

◆ tr_limit

vec3 nngn::Camera::tr_limit = {+INFINITY, +INFINITY, +INFINITY}

Top right point of the limit for p.

◆ v

vec3 nngn::Camera::v = {}

Velocity.

◆ view

mat4 nngn::Camera::view = mat4{1}

View matrix.

◆ zoom

float nngn::Camera::zoom = 1

Scaling factor.

◆ zoom_a

float nngn::Camera::zoom_a = {}

Scaling factor acceleration.

◆ zoom_v

float nngn::Camera::zoom_v = {}

Scaling factor velocity.


The documentation for this struct was generated from the following files: