![]() |
LibGame
v0.4.0
The LG Game Engine - Copyright (C) 2024-2025 ETMSoftware
|
=== SO FAR, USES RH COORDS SYS FOR MATRIX OPS ===
=== Need to write LH versions for these funcs:
Because OpenGL coords sys is RH but the Z dir is visually counter-intuitive IMO
See:
Renamed funcs in math_3d.h:
Renamed funcs in lg_camera.c/h:
Camera initial position in world coords is always at center ie (0.0, 0.0, 0.0)
NOTE about cam->orientation and cam->target:
Aircraft/flight simulator camera and user input:
With OpenGL right hand coords sys:
So:
LibGame uses column-major order matrices LibGame try to/will use LH 3D coords sys as often as possible (!= OpenGL) (To avoid endless confusion, always mention coords sys or anything relevant)
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.
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
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_near value, use lg_camera_override_znear()
To change z_far value, use lg_camera_override_zfar()
What matters is the ratio (not the difference) between these values
cam | Pointer to a LG_Camera |
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
cam | Pointer to a LG_Camera |
position | Position in world space |
target | Look at target |
up | The 'up' vector - will get normalized |
v_fov | Vertical field of view, in degrees |
z_near | Distance to the near clipping plane along -z |
z_far | Distance to the far clipping plane along -z |
int lg_camera_reset | ( | LG_Camera * | cam | ) |
Compute and return the view matrix from the camera data
WARNING: Doesn't update cam->view_m
cam | Pointer to a LG_Camera |
Compute and return the projection matrix from the camera data
WARNING: Doesn't update cam->proj_m
cam | Pointer to a LG_Camera |
Compute and return the view projection matrix from the camera data
WARNING: Doesn't update cam->view_proj_m
cam | Pointer to a LG_Camera |
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 (if necessary) when moving/rotating the camera or changing other camera settings
cam | Pointer to a LG_Camera |
Move the camera (FORWARD if transl.x = 0, transl.y = 0, transl.z != 0)
Compute new 'from' and 'to" vectors for the look_at matrix, the 'up' vector remains unchanged by the translation
Doesn't change cam orientation
Update cam->view_m and cam->view_proj_m
cam | Pointer to a LG_Camera |
transl | Translation vector |
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->target, cam->up, cam->view_m, and cam->view_proj_m
cam | Pointer to a LG_Camera |
ang | The Euler angles |
rot_order | The rotations order - one of "XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY" |
Rotate the camera with a quaternion
Update cam->target, cam->up, cam->view_m, and cam->view_proj_m
cam | Pointer to a LG_Camera |
q | The quaternion |
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->target, cam->up, cam->view_m, and cam->view_proj_m
cam | Pointer to a LG_Camera |
ang | The Euler angles |
rot_order | The rotations order - one of "XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY" |
Set camera rotation by a quaternion
Update cam->target, cam->up, cam->view_m, and cam->view_proj_m
cam | Pointer to a LG_Camera |
q | The quaternion |
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 b@ra venso ft.c om
Klaus Hartmann k_har tman n@osn abru eck.n etsu rf.de
cam | Pointer to a LG_Camera |
frustum | Pointer to a LG_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
v | Pointer to a vec3_t pos vector |
frustum | Pointer to a LG_Frustum |
zboolean lg_cuboid_is_in_frustum | ( | LG_Cuboid * | cuboid, |
LG_Frustum * | frustum, | ||
zboolean | fully | ||
) |
Test if cuboid is inside frustum (fully or partially)
cuboid | Pointer to a LG_Cuboid |
frustum | Pointer to a LG_Frustum |
fully | TRUE to test if all vertices are inside, FALSE to test if at least one is inside |
zboolean lg_mesh_is_in_frustum | ( | LG_Mesh * | mesh, |
LG_Frustum * | frustum, | ||
zboolean | fully | ||
) |
Test if mesh is inside frustum (fully or partially)
mesh | Pointer to a LG_Mesh |
frustum | Pointer to a LG_Frustum |
fully | TRUE to test if all vertices are inside, FALSE to test if at least one is inside |
void lg_camera_override_znear | ( | LG_Camera * | cam, |
float | z_near | ||
) |
Set cam->z_near value to z_near (default is LG_Z_NEAR, defined in lg_camera.h)
Update cam->proj_m and cam->view_proj_m
cam | Pointer to a LG_Camera |
z_near | New cam->z_near value |
void lg_camera_override_zfar | ( | LG_Camera * | cam, |
float | z_far | ||
) |
Set cam->z_far value to z_far (default is LG_Z_FAR, defined in lg_camera.h)
Update cam->proj_m and cam->view_proj_m
cam | Pointer to a LG_Camera |
z_far | New cam->z_far value |
Compute an orbit and move/rotate the camera along this orbit, always looking at the center
This is working fine until cam goes "through" center, ie get out of frustum
cam | Pointer to a LG_Camera |
center | Center of the orbit |
yaw | Rotation angle around the Y axis, in radians |
pitch | Rotation angle around the X axis, in radians |
int lg_plane_normalize | ( | LG_Plane * | p | ) |
Normalize plane
p | A pointer to a LG_Plane |
void lg_camera_info | ( | LG_Camera * | cam | ) |
void lg_frustum_info | ( | LG_Frustum * | frustum | ) |
Print out LG_Frustum info
frustum | Pointer to a LG_Frustum |