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

Functions

LG_Scene lg_scene_new (int id, LG_Camera *cam1, LG_Light light1, Rec2Df landscape_rec, uint16_t grid_width)
 
void lg_scene_free (LG_Scene *scene)
 
LG_SceneNodelg_scenenode_new_and_set (int id, LG_SceneNode *parent, const char *mesh_file, LG_LoadMesh_Flags flags, vec3_t transl, LG_Quat orientation, vec3_t scaling)
 
LG_SceneNodelg_mesh_NTOS_array_to_scenenodes (LG_SceneNode *node, LG_LoadMesh_Flags flags, LG_Mesh_NTOS *mesh_ntos, int n_mesh_ntos)
 
mat4_t lg_get_TRS_matrix_from_TOS_v (vec3_t transl, LG_EulerAng orientation, vec3_t scaling, const char *rot_order)
 
zboolean lg_set_TRS_matrix_from_mesh_NTOS (mat4_t *m_TRS, LG_Mesh_NTOS *tos)
 
void lg_mesh_NTOS_array_info (LG_Mesh_NTOS *mesh_ntos, int n_mesh_ntos)
 
LG_SceneDZ lg_scenedz_load_from_assets (const char *path)
 
LG_SceneDZ lg_scenedz_load_from_file (const char *path)
 
zboolean lg_scenedz_save_to_file (LG_SceneDZ *scenedz, const char *path)
 
zboolean lg_create_wr_scenes_dir ()
 
void lg_scene_set_from_scenedz (LG_Scene *scene, LG_SceneDZ *scenedz)
 
void lg_scenedz_set_from_scene (LG_SceneDZ *scenedz, LG_Scene *scene)
 
LG_SceneNodelg_generate_scenenodes_from_scenedz (LG_SceneDZ *sdz, LG_LoadMesh_Flags flags)
 

Detailed Description

 === Higher level scene/frame stuff ===

 The starting point for scenes

Function Documentation

◆ lg_scene_new()

LG_Scene lg_scene_new ( int  id,
LG_Camera cam1,
LG_Light  light1,
Rec2Df  landscape_rec,
uint16_t  grid_width 
)

Create and init a new scene

Can not contain more than MESH_NTOS_MAX_NUM mesh references

LG_Mesh_NTOS, LG_Scene, and LG_SceneDZ are defined in lg_scene_graph.h

// NTOS stands for Name and TOS (Transl/Orientation/Scaling)
// Use float for LG_EulerAng
typedef union {
struct {
// Name
char name[LG_MESH_NAME_MAX_LEN + 1]; // OBJ/FBX basename
// Transl.
float x_t;
float y_t;
float z_t;
// Orientation as LG_EulerAng
float x_o;
float y_o;
float z_o;
// Scaling
float x_s;
float y_s;
float z_s;
// Rot. order
char rot_order[4];
};
struct {
char name2[LG_MESH_NAME_MAX_LEN + 1];
float v[9];
char rot_order2[4];
};
typedef struct {
int id; // Set to -1 on error
LG_Camera *cam1;
LG_Light light1;
Rec2Df landscape_rec;
LG_SceneNode *root;
LG_SceneNode *grid;
LG_SceneNode *xyz_arrows;
LG_Mesh_NTOS meshes_ntos[MESH_NTOS_MAX_NUM];
int n_mesh_ntos;
// Serialized LG_Scene data - not everything
// DZ stands for Data serialiZation (huh ?)
typedef struct {
LG_Camera cam;
Rec2Df landscape_rec;
LG_Mesh_NTOS meshes_ntos[MESH_NTOS_MAX_NUM];
int n_mesh_ntos;

Generated nodes:

  • root -> parent of grid and xyz_arrows, id = 0, type = ROOT
  • grid -> with an initialized Lines3D_VB horizontal grid, id = 1, type = GRID
  • xyz_arrows -> with an initialized Lines3D_VB xyz_arrows, id = 2, type = LINES3D
Parameters
idScene's id, set to -1 on error
cam1A pointer to a LG_Camera
light1A LG_Light
landscape_recA Rec2Df, should be centered
grid_widthGrid width, ie number of units along one row or one column, should be even - if odd, we substract one
Returns
An initialized LG_Scene if OK, id set to -1 on error

◆ lg_scene_free()

void lg_scene_free ( LG_Scene scene)

Free scene root, grid, and xyz_arrows nodes

Parameters
sceneA LG_Scene

◆ lg_scenenode_new_and_set()

LG_SceneNode* lg_scenenode_new_and_set ( int  id,
LG_SceneNode parent,
const char *  mesh_file,
LG_LoadMesh_Flags  flags,
vec3_t  transl,
LG_Quat  orientation,
vec3_t  scaling 
)

Helper func to create and set a new LG_SceneNode instance

Create node, add node to scene graph, load node's mesh, and set node's local matrix

Helper macros for less confusion:

#define transl_v3(x, y, z) vec3(x, y, z)
#define scaling_v3(x, y, z) vec3(x, y, z)

Mesh must be freed when done with the scene

Parameters
idNode's id
parentA pointer to a scene graph node
mesh_fileRelative path to mesh file to load, inside the mesh folder
flagsApply to mesh: force_reload, invert_z, normalize_xyz, horiz_center, vert_center, vert_bottom
translTranslation/position vec3
orientationOrientation quat
scalingScaling vec3
Returns
A pointer to a LG_SceneNode if OK, NULL on error - must be freed afterwards

◆ lg_mesh_NTOS_array_to_scenenodes()

LG_SceneNode* lg_mesh_NTOS_array_to_scenenodes ( LG_SceneNode node,
LG_LoadMesh_Flags  flags,
LG_Mesh_NTOS mesh_ntos,
int  n_mesh_ntos 
)

Get an array of LG_Mesh_NTOS and create and set scenenodes

NTOS stands for Name and TOS (Transl/Orientation/Scaling)

Generated scenenodes id start at MNTOS_ARRAY_INDEX_TO_SCENENODE_ID

Example code #1:

LG_LoadMesh_Flags flags1 = lg_loadmesh_flags(FALSE, FALSE, NORMALIZE_XYZ, HORIZ_CENTER, FALSE, VERT_BOTTOM);
LG_Mesh_NTOS mesh_ntos[] = {
{{"obj/shark1.obj", 0, 40, 0, 0, 0, 0, 25, 25, 25 ROT_ORDER}},
{{"obj/pikachu2.obj", -50, 0, 50, 0, 0, 0, 25, 25, 25 ROT_ORDER}},
{{"obj/tree2.obj", 50, 0, 50, 0, 0, 0, 25, 25, 25 ROT_ORDER}},
{{"obj/windmill1.obj", -50, 0, -50, 0, 0, 0, 25, 25, 25 ROT_ORDER}},
{{"obj/cube3.obj", 50, 0, -50, 0, 0, 0, 12, 12, 12 ROT_ORDER}}};
int n_mesh_ntos = (int)(sizeof(mesh_ntos) / sizeof(LG_Mesh_NTOS));
// Generate nodes from a LG_Mesh_NTOS array
LG_SceneNode *first_obj_node = lg_mesh_NTOS_array_to_scenenodes(first_obj_node, flags1, (LG_Mesh_NTOS *)mesh_ntos, n_mesh_ntos);

Example code #2:

LG_Scene scene = lg_scene_new(...);
LG_SceneDZ sdz = lg_scenedz_load_from_file(lg_app_wr_file("scenes/hello_1.scene"));
// Generate nodes from a LG_Mesh_NTOS array
LG_SceneNode *first_obj_node = lg_mesh_NTOS_array_to_scenenodes(first_obj_node, flags1, (LG_Mesh_NTOS *)scene.meshes_ntos, scene.n_mesh_ntos);
lg_scenedz_set_from_scene(&sdz, &lev->scene);
lg_scenedz_save_to_file(&sdz, lg_app_wr_file("scenes/hello_2.scene"));
Parameters
nodeA scene node
flagsFlags for mesh loading
mesh_ntosAn array of LG_Mesh_NTOS
n_mesh_ntosNum of LG_Mesh_NTOS in the array
Returns
The same scene node

◆ lg_get_TRS_matrix_from_TOS_v()

mat4_t lg_get_TRS_matrix_from_TOS_v ( vec3_t  transl,
LG_EulerAng  orientation,
vec3_t  scaling,
const char *  rot_order 
)

Create a TRS matrix (Transl/Rotation/Scaling) from TOS values (Transl/Orientation/Scaling)

Parameters
translTranslation vector
orientationOrientation LG_EulerAng
scalingScaling vector

◆ lg_set_TRS_matrix_from_mesh_NTOS()

zboolean lg_set_TRS_matrix_from_mesh_NTOS ( mat4_t m_TRS,
LG_Mesh_NTOS tos 
)

Set an existing TRS matrix (Transl/Rotation/Scaling) from a LG_Mesh_NTOS

Parameters
m_TRSPointer to a mat4_t
tosPointer to a LG_Mesh_NTOS
scalingScaling vector

◆ lg_mesh_NTOS_array_info()

void lg_mesh_NTOS_array_info ( LG_Mesh_NTOS mesh_ntos,
int  n_mesh_ntos 
)

Print out LG_Mesh_NTOS[] info

Parameters
mesh_ntosAn array of LG_Mesh_NTOS
n_mesh_ntosNum of LG_Mesh_NTOS in the array

◆ lg_scenedz_load_from_assets()

LG_SceneDZ lg_scenedz_load_from_assets ( const char *  path)

Load a LG_Scene from a file in the ASSETS/SCENES_DIR folder

Parameters
pathRelative path to scene file, inside env->assets_dir/scenes
Returns
A new LG_Scene, id set to -1 on error

◆ lg_scenedz_load_from_file()

LG_SceneDZ lg_scenedz_load_from_file ( const char *  path)

Load a LG_SceneDZ from a file in the APP WRITABLE folder

Parameters
pathPath to scene file, inside env->app_wr_dir
Returns
A new LG_SceneDZ, n_mesh_ntos set to -1 on error

◆ lg_scenedz_save_to_file()

zboolean lg_scenedz_save_to_file ( LG_SceneDZ scenedz,
const char *  path 
)

Save a LG_SceneDZ to a file in the APP WRITABLE folder

Parameters
scenePointer a to LG_SceneDZ
pathPath to scene file, inside env->app_wr_dir
Returns
TRUE if OK, FALSE on error

◆ lg_create_wr_scenes_dir()

zboolean lg_create_wr_scenes_dir ( )

Create the scene folder (SCENES_DIR) in the APP WRITABLE folder

Returns
TRUE if OK, FALSE on error

◆ lg_scene_set_from_scenedz()

void lg_scene_set_from_scenedz ( LG_Scene scene,
LG_SceneDZ scenedz 
)

Set LG_Scene data from LG_SceneDZ data

-> cam, landscape_rec, meshes_ntos[MESH_NTOS_MAX_NUM], and n_mesh_ntos

Parameters
scenePointer to a LG_Scene
scenedzPointer to a LG_SceneDZ

◆ lg_scenedz_set_from_scene()

void lg_scenedz_set_from_scene ( LG_SceneDZ scenedz,
LG_Scene scene 
)

Set LG_SceneDZ data from LG_Scene data

-> cam, landscape_rec, meshes_ntos[MESH_NTOS_MAX_NUM], and n_mesh_ntos

Parameters
scenedzPointer to a LG_SceneDZ
scenePointer to a LG_Scene

◆ lg_generate_scenenodes_from_scenedz()

LG_SceneNode* lg_generate_scenenodes_from_scenedz ( LG_SceneDZ sdz,
LG_LoadMesh_Flags  flags 
)

Helper func to generate scene nodes (LG_SceneNode *) from a LG_SceneDZ and mesh files

You can then add this node to your scene root node

Top node:

  • node.id = 3
  • node->name = "first_obj_node"
  • node->type = FIRST_OBJ
Parameters
sdzPointer to a LG_SceneDZ
flagsMesh loading flags
Returns
Pointer to a new scene node
lg_scene_set_from_scenedz
void lg_scene_set_from_scenedz(LG_Scene *scene, LG_SceneDZ *scenedz)
Definition: lg_scene.c:465
LG_LoadMesh_Flags
Definition: lg_mesh.h:119
Rec2Df
Definition: lg_gr_func.h:56
lg_scene_new
LG_Scene lg_scene_new(int id, LG_Camera *cam1, LG_Light light1, Rec2Df landscape_rec, uint16_t grid_width)
Definition: lg_scene.c:87
LG_SceneNode
Definition: lg_scene_graph.h:37
LG_Scene
Definition: lg_scene_graph.h:86
LG_Light
Definition: lg_light.h:26
lg_scenedz_save_to_file
zboolean lg_scenedz_save_to_file(LG_SceneDZ *scenedz, const char *path)
Definition: lg_scene.c:435
LG_Camera
Definition: lg_camera.h:22
lg_mesh_NTOS_array_to_scenenodes
LG_SceneNode * lg_mesh_NTOS_array_to_scenenodes(LG_SceneNode *node, LG_LoadMesh_Flags flags, LG_Mesh_NTOS *mesh_ntos, int n_mesh_ntos)
Definition: lg_scene.c:272
lg_loadmesh_flags
LG_LoadMesh_Flags lg_loadmesh_flags(zboolean force_reload, zboolean invert_z, zboolean normalize_xyz, zboolean horiz_center, zboolean vert_center, zboolean vert_bottom)
Definition: lg_mesh.c:532
LG_SceneDZ
Definition: lg_scene_graph.h:99
lg_scenedz_set_from_scene
void lg_scenedz_set_from_scene(LG_SceneDZ *scenedz, LG_Scene *scene)
Definition: lg_scene.c:489
LG_Mesh_NTOS
Definition: lg_scene_graph.h:60
lg_app_wr_file
const char * lg_app_wr_file(const char *file_name)
Definition: lg_dirs_stuff.c:190
lg_scenedz_load_from_file
LG_SceneDZ lg_scenedz_load_from_file(const char *path)
Definition: lg_scene.c:409