LibGame  v0.4.0
The LG Game Engine - Copyright (C) 2024 ETMSoftware
lg_camera.c File Reference

Functions

LG_Camera lg_camera ()
 
int lg_camera_init (LG_Camera *cam)
 
int lg_camera_set_all (LG_Camera *cam, vec3_t position, vec3_t target, vec3_t up, float v_fov, float z_near, float z_far)
 
int lg_camera_reset (LG_Camera *cam)
 
mat4_t lg_camera_compute_view_matrix (LG_Camera *cam)
 
mat4_t lg_camera_compute_proj_matrix (LG_Camera *cam)
 
mat4_t lg_camera_compute_view_proj_matrix (LG_Camera *cam)
 
void lg_update_all_cam_m (LG_Camera *cam)
 
int lg_camera_move_to (LG_Camera *cam, vec3_t transl)
 
int lg_camera_rotate_by_eu (LG_Camera *cam, LG_EulerAng ang, const char *rot_order)
 
int lg_camera_rotate_by_quat (LG_Camera *cam, LG_Quat q)
 
int lg_camera_set_rot_by_eu (LG_Camera *cam, LG_EulerAng ang, const char *rot_order)
 
int lg_camera_set_rot_by_quat (LG_Camera *cam, LG_Quat q)
 
void lg_camera_get_frustum (LG_Camera *cam, LG_Frustum *frustum)
 
zboolean is_in_frustum (vec3_t *v, LG_Frustum *frustum)
 
zboolean lg_cuboid_is_in_frustum (LG_Cuboid *cuboid, LG_Frustum *frustum, zboolean fully)
 
zboolean lg_mesh_is_in_frustum (LG_Mesh *mesh, LG_Frustum *frustum, zboolean fully)
 
void lg_camera_override_zfar (LG_Camera *cam, float z_far)
 
void lg_camera_orbit_around (LG_Camera *cam, vec3_t center, float radius, float angle)
 
int lg_plane_normalize (LG_Plane *p)
 
float lg_point_to_plane_distance (vec3_t *v, LG_Plane *p)
 
float lg_point_to_norm_plane_distance (vec3_t *v, LG_Plane *p)
 
void lg_camera_info (LG_Camera *cam)
 
void lg_frustum_info (LG_Frustum *frustum)
 

Detailed Description

 Camera initial position in world coords is always at center ie (0.0, 0.0, 0.0).

 Aircraft/flight simulator camera and user input:
 - All rotations are intrinsic
 - Standard order = YAW/PITCH/ROLL

 With OpenGL right hand coords sys:
 - Yaw = rot/Y
 - Pitch = rot/X
 - Roll = rot/Z

 You can use a global, always available, always default-values-initialized, camera:

     LG_Camera *lg_get_camera_one()

 if needed, or you can use as many cameras as you want.

 When multiplying matrices before rendering, the right order is:

     cam->proj_m * cam->view_m * node->world_matrix

 or

     cam->view_proj_m * node->world_matrix

 MVP stands for Model-View-Proj but it should be WVP for World-View-Proj
 and you multiply matrices in the reversed order, ie P * V * M or P * V * W.

Function Documentation

◆ lg_camera()

LG_Camera lg_camera ( )

Return a new camera, initialized with default values:

 LG_CAMERA_ORIGIN
 LG_CAMERA_TARGET
 LG_CAMERA_UP
 LG_V_FOV
 LG_Z_NEAR
 LG_Z_FAR
Returns
A new LG_Camera

◆ lg_camera_init()

int lg_camera_init ( LG_Camera cam)

Init the camera, with default values:

 LG_CAMERA_ORIGIN
 LG_CAMERA_TARGET
 LG_CAMERA_UP
 LG_V_FOV
 LG_Z_NEAR
 LG_Z_FAR

To change z_far value, use lg_camera_override_zfar()

Parameters
camPointer to a LG_Camera
Returns
LG_OK if OK

◆ lg_camera_set_all()

int lg_camera_set_all ( LG_Camera cam,
vec3_t  position,
vec3_t  target,
vec3_t  up,
float  v_fov,
float  z_near,
float  z_far 
)

Set all camera params

Parameters
camPointer to a LG_Camera
positionPosition in world space
targetLook at target
upThe 'up' vector - will get normalized
v_fovVertical field of view, in degrees
z_nearDistance to the near clipping plane along -z
z_farDistance to the far clipping plane along -z
Returns
LG_OK if OK

◆ lg_camera_reset()

int lg_camera_reset ( LG_Camera cam)

'Reset' the camera

Parameters
camPointer to a LG_Camera
Returns
LG_OK if OK

◆ lg_camera_compute_view_matrix()

mat4_t lg_camera_compute_view_matrix ( LG_Camera cam)

Compute the view matrix from the camera data

WARNING: Doesn't update cam->view_m

Parameters
camPointer to a LG_Camera
Returns
The camera view matrix

◆ lg_camera_compute_proj_matrix()

mat4_t lg_camera_compute_proj_matrix ( LG_Camera cam)

Compute the projection matrix from the camera data

WARNING: Doesn't update cam->proj_m

Parameters
camPointer to a LG_Camera
Returns
The camera projection matrix

◆ lg_camera_compute_view_proj_matrix()

mat4_t lg_camera_compute_view_proj_matrix ( LG_Camera cam)

Compute the view projection matrix from the camera data

WARNING: Doesn't update cam->view_proj_m

Parameters
camPointer to a LG_Camera
Returns
The camera view projection matrix

◆ lg_update_all_cam_m()

void lg_update_all_cam_m ( LG_Camera cam)

(Re)compute and update all cam->view_m/proj_m/view_proj_m.

This is usually done automatically when moving the camera or changing camera settings.

Parameters
camPointer to a LG_Camera

◆ lg_camera_move_to()

int lg_camera_move_to ( LG_Camera cam,
vec3_t  transl 
)

Move the camera

Compute new 'from' and 'to" vectors for the look_at matrix, the 'up' vector remains unchanged by the translation.

Update cam->view_m and cam->view_proj_m

Parameters
camPointer to a LG_Camera
translTranslation vector
Returns
LG_OK if OK

◆ lg_camera_rotate_by_eu()

int lg_camera_rotate_by_eu ( LG_Camera cam,
LG_EulerAng  ang,
const char *  rot_order 
)

Rotate the camera by Euler angles

Getting camera orientation from LG_EulerAng in UI is the easiest/prefered way.

Update cam->view_m and cam->view_proj_m

Parameters
camPointer to a LG_Camera
angThe Euler angles
rot_orderThe rotations order - one of "XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY"
Returns
LG_OK if OK

◆ lg_camera_rotate_by_quat()

int lg_camera_rotate_by_quat ( LG_Camera cam,
LG_Quat  q 
)

Rotate the camera with a quaternion

Then, cam->orientation is stored as a quaternion (we're now using only quats).

Update cam->view_m and cam->view_proj_m

Parameters
camPointer to a LG_Camera
qThe quaternion
Returns
LG_OK if OK

◆ lg_camera_set_rot_by_eu()

int lg_camera_set_rot_by_eu ( LG_Camera cam,
LG_EulerAng  ang,
const char *  rot_order 
)

Set camera rotation by Euler angles

Update cam->view_m and cam->view_proj_m

Parameters
camPointer to a LG_Camera
angThe Euler angles
rot_orderThe rotations order - one of "XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY"
Returns
LG_OK if OK

◆ lg_camera_set_rot_by_quat()

int lg_camera_set_rot_by_quat ( LG_Camera cam,
LG_Quat  q 
)

Set camera rotation by a quaternion

Update cam->view_m and cam->view_proj_m

Parameters
camPointer to a LG_Camera
qThe quaternion
Returns
LG_OK if OK

◆ lg_camera_get_frustum()

void lg_camera_get_frustum ( LG_Camera cam,
LG_Frustum frustum 
)

Get camera frustum, using the Gribb & Hartmann algorithm:

'Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix'
Gil Gribb ggrib.nosp@m.b@ra.nosp@m.venso.nosp@m.ft.c.nosp@m.om
Klaus Hartmann k_har.nosp@m.tman.nosp@m.n@osn.nosp@m.abru.nosp@m.eck.n.nosp@m.etsu.nosp@m.rf.de

Parameters
camPointer to a LG_Camera
frustumPointer to a LG_Frustum

◆ is_in_frustum()

zboolean is_in_frustum ( vec3_t v,
LG_Frustum frustum 
)

Test if pos vector is inside frustum

A pos vector is inside a frustrum if the dot product with all side planes is always > 0

Parameters
vPointer to a vec3_t pos vector
frustumPointer to a LG_Frustum
Returns
TRUE if inside, FALSE otherwise

◆ lg_cuboid_is_in_frustum()

zboolean lg_cuboid_is_in_frustum ( LG_Cuboid cuboid,
LG_Frustum frustum,
zboolean  fully 
)

Test if cuboid is inside frustum (fully or partially)

Parameters
cuboidPointer to a LG_Cuboid
frustumPointer to a LG_Frustum
fullyTRUE to test if all vertices are inside, FALSE to test if at least one is inside
Returns
TRUE if inside, FALSE otherwise

◆ lg_mesh_is_in_frustum()

zboolean lg_mesh_is_in_frustum ( LG_Mesh mesh,
LG_Frustum frustum,
zboolean  fully 
)

Test if mesh is inside frustum (fully or partially)

Parameters
meshPointer to a LG_Mesh
frustumPointer to a LG_Frustum
fullyTRUE to test if all vertices are inside, FALSE to test if at least one is inside
Returns
TRUE if inside, FALSE otherwise

◆ lg_camera_override_zfar()

void lg_camera_override_zfar ( LG_Camera cam,
float  z_far 
)

Set cam->z_far value to z_far (default is LG_Z_FAR)

Update cam->proj_m and cam->view_proj_m

Parameters
camPointer to a LG_Camera
z_farNew cam->z_far value

◆ lg_camera_orbit_around()

void lg_camera_orbit_around ( LG_Camera cam,
vec3_t  center,
float  radius,
float  angle 
)

Compute an orbit and move/rotate the camera along this orbit, always looking at the center

Horizontal orbit, ie cam->position.y stays unchanged - could be extended to allow orbits in any plane

Parameters
camPointer to a LG_Camera
centerCenter of the orbit
radiusRadius of the orbit
angleRotation angle around the orbit, in radians

◆ lg_plane_normalize()

int lg_plane_normalize ( LG_Plane p)

Normalize plane

Parameters
pA pointer to a LG_Plane
Returns
LG_OK if OK, LG_ERROR if magnitude <= LG_FLOAT_EPSILON

◆ lg_point_to_plane_distance()

float lg_point_to_plane_distance ( vec3_t v,
LG_Plane p 
)

Compute point to (non-normalized) plane distance

Parameters
vA pointer to a position vec3_t
pA pointer to a non-normalized LG_Plane
Returns
Distance

◆ lg_point_to_norm_plane_distance()

float lg_point_to_norm_plane_distance ( vec3_t v,
LG_Plane p 
)

Compute point to (normalized) plane distance

Parameters
vA pointer to a position vec3_t
pA pointer to a normalized LG_Plane
Returns
Distance

◆ lg_camera_info()

void lg_camera_info ( LG_Camera cam)

Print out LG_Camera info

Parameters
camPointer to a LG_Camera

◆ lg_frustum_info()

void lg_frustum_info ( LG_Frustum frustum)

Print out LG_Frustum info

Parameters
frustumPointer to a LG_Frustum