LibGame v0.4.0
The LG Game Engine - Copyright (C) 2024-2026 ETMSoftware
Loading...
Searching...
No Matches
lg_mesh.c File Reference

Functions

LG_Meshlg_mesh_load (const char *full_path, LG_LoadMesh_Flags flags)
 
LG_Meshlg_mesh_new_from_obj (const char *full_path, zboolean invert_z, zboolean normalize_xyz, zboolean horiz_center, zboolean vert_center, zboolean vert_bottom)
 
LG_Meshlg_mesh_new_from_obj_relpath (const char *relative_path, zboolean invert_z, zboolean normalize_xyz, zboolean horiz_center, zboolean vert_center, zboolean vert_bottom)
 
LG_Meshlg_mesh_new_from_fbx (const char *full_path, zboolean invert_z, zboolean normalize_xyz, zboolean horiz_center, zboolean vert_center, zboolean vert_bottom)
 
LG_Meshlg_mesh_new_from_fbx_relpath (const char *relative_path, zboolean invert_z, zboolean normalize_xyz, zboolean horiz_center, zboolean vert_center, zboolean vert_bottom)
 
void lg_mesh_free (LG_Mesh *mesh)
 
void lg_mesh_free_v2 (LG_Mesh **mesh)
 
int lg_bmesh_save_to_file (const char *full_path, LG_Mesh *mesh)
 
int lg_bmesh_load_from_file (const char *full_path, LG_Mesh **mesh)
 
int lg_mesh_reload_mats (LG_Mesh *mesh)
 
void lg_serialize_LG_Material_64_to_32 (Serializable_LG_Material *s_mat, LG_Material *mat)
 
void lg_unserialize_LG_Material_32_to_64 (LG_Material *mat, Serializable_LG_Material *s_mat)
 
void lg_serialize_LG_Mesh_64_to_32 (Serializable_LG_Mesh *s_mesh, LG_Mesh *mesh)
 
void lg_unserialize_LG_Mesh_32_to_64 (LG_Mesh *mesh, Serializable_LG_Mesh *s_mesh)
 
LG_LoadMesh_Flags lg_loadmesh_flags (zboolean save_to_assets, zboolean invert_z, zboolean normalize_xyz, zboolean horiz_center, zboolean vert_center, zboolean vert_bottom)
 
void lg_mesh_info (LG_Mesh *mesh, int show_first_n)
 
char * lg_replace_file_extension (const char *path, const char *new_ext)
 

Detailed Description

This module deals with meshes, ie data that will feed VBOs and IBOs for fast and efficient drawing.

You can/should only use this func to load meshes, if they're all in an <assets_dir> folder, defined by the macro ASSETS_DIR

// The <assets_dir> structure:
//
// <assets_dir>
// / \
// <images> <meshes>
// | / \
// <textures> <bmesh> <obj>
#define ASSETS_DIR <assets_dir>
LG_Mesh *lg_mesh_load(const char *full_path, LG_LoadMesh_Flags flags)
// LG_Mesh struct is defined in lg_mesh.h
// full_path = full path of mesh file, with extension OBJ or FBX or BMESH
// Mesh loading flags
typedef struct {
zboolean save_to_assets; // Save to assets as BMESH, otherwise to cache - on Android, should always be set to FALSE as you can't write to assets
zboolean invert_z; // Invert z spatial coord - should be set to TRUE if mesh uses RH coords sys, FALSE if mesh uses LH coords sys
zboolean normalize_xyz;
zboolean horiz_center;
zboolean vert_center; // Center mesh vertically, if vert_bottom is not set
zboolean vert_bottom; // Set mesh origin vertically at bottom, override vert_center
LG_Mesh * lg_mesh_load(const char *full_path, LG_LoadMesh_Flags flags)
Definition lg_mesh.c:104
Definition lg_mesh.h:123
Definition lg_mesh.h:87

and you can/should only use this func when done with a mesh:

void lg_mesh_free(LG_Mesh *mesh)
Definition lg_mesh.c:260

and just ignore the details.

(Use everything here only if you know what you're doing).

NEW CONVENTIONS FOR PATHS / FILE NAMES AS FUNC ARGS:

- full_path -> Absolute path, include file name (default for paths)
- relative_path -> Relative path, include file name = sub_dir1/sub_dir2/---/file_name
- file_name -> Basename only, always with extension

In funcs names:

- bla_bla()
vs
- bla_bla_relpath()

Function Documentation

◆ lg_mesh_load()

LG_Mesh * lg_mesh_load ( const char *  full_path,
LG_LoadMesh_Flags  flags 
)

Load OBJ or FBX or BMESH mesh file

If all your meshes (OBJ, FBX, BMESH) are in an <assets_dir> folder, defined by the macro ASSETS_DIR, then this is the entry point for loading them and the only func you need to call

  • Valid extensions are OBJ, FBX, and BMESH
  • Expected to be in predefined locations
  • The <assets_dir> structure:
    // The <assets_dir> structure:
    //
    // <assets_dir>
    // / \
    // <images> <meshes>
    // | / \
    // <textures> <bmesh> <obj>
    #define ASSETS_DIR <assets_dir>

If OBJ or FBX file successfully loaded, it will be saved as BMESH in cache, and also in assets if flags.save_to_assets is set

Always saved as BMESH as it is LibGame binary format for meshes - optimized, faster to load, not requiring parsing

WARNING: FBX support is not complete yet

Parameters
full_pathFull path of mesh file, with extension OBJ or FBX or BMESH
flagsApply to mesh: save_to_assets, invert_z, normalize_xyz, horiz_center, vert_center, vert_bottom
Returns
Pointer to LG_Mesh if OK, NULL on error

◆ lg_mesh_new_from_obj()

LG_Mesh * lg_mesh_new_from_obj ( const char *  full_path,
zboolean  invert_z,
zboolean  normalize_xyz,
zboolean  horiz_center,
zboolean  vert_center,
zboolean  vert_bottom 
)

Create mesh from OBJ file.

Read data from WAVEFRONT OBJ files: vertex/index values for v (coords), vt (texture coords), vn (normals), f (triangular faces), mtllib, usemtl (materials/textures stuff), plus newmtl, and map_K* (in MTL files).

Other data is ignored so far.

=== WARNING: MESHES MUST BE PURE-TRIANGULAR ===

Will create a Vertex_uv_n VBO (see lg_vertex.h).

NO-OP on Android as BMESH files should be used instead

Using MeshLab filters:
remeshing, simplification and reconstruction
turn into a pure-triangle mesh
Also:
normals, curvatures and orientation
transform: translate, center, set origin
-> center on layer bbox
normals, curvatures and orientation
transform: scale, normalize
-> scale to unit bbox
Parameters
full_pathFull (absolute) path of OBJ file (with extension OBJ)
invert_zInvert z spatial coord - should be set to TRUE if mesh uses RH coords sys, FALSE if mesh uses LH coords sys
normalize_xyzNormalize spatial coords
horiz_centerCenter mesh horizontally
vert_centerCenter mesh vertically, if vert_bottom is not set
vert_bottomSet mesh origin vertically at bottom, override vert_center
Returns
A new LG_Mesh instance if OK, NULL on error

◆ lg_mesh_new_from_obj_relpath()

LG_Mesh * lg_mesh_new_from_obj_relpath ( const char *  relative_path,
zboolean  invert_z,
zboolean  normalize_xyz,
zboolean  horiz_center,
zboolean  vert_center,
zboolean  vert_bottom 
)

Same as above but take OBJ file relative path

Parameters
relative_pathRelative path of OBJ file (with extension OBJ), expected to be in OBJ_DIR predefined location
invert_zInvert z spatial coord - should be set to TRUE if mesh uses RH coords sys, FALSE if mesh uses LH coords sys
normalize_xyzNormalize spatial coords
horiz_centerCenter mesh horizontally
vert_centerCenter mesh vertically, if vert_bottom is not set
vert_bottomSet mesh origin vertically at bottom, override vert_center
Returns
A new LG_Mesh instance if OK, NULL on error

◆ lg_mesh_new_from_fbx()

LG_Mesh * lg_mesh_new_from_fbx ( const char *  full_path,
zboolean  invert_z,
zboolean  normalize_xyz,
zboolean  horiz_center,
zboolean  vert_center,
zboolean  vert_bottom 
)

Create mesh from FBX file.

Parameters
full_pathFull path of FBX file (with extension FBX)
invert_zInvert z spatial coord - should be set to TRUE if mesh uses RH coords sys, FALSE if mesh uses LH coords sys
normalize_xyzNormalize spatial coords
horiz_centerCenter mesh horizontally
vert_centerCenter mesh vertically, if vert_bottom is not set
vert_bottomSet mesh origin vertically at bottom, override vert_center
Returns
A new LG_Mesh instance if OK, NULL on error

◆ lg_mesh_new_from_fbx_relpath()

LG_Mesh * lg_mesh_new_from_fbx_relpath ( const char *  relative_path,
zboolean  invert_z,
zboolean  normalize_xyz,
zboolean  horiz_center,
zboolean  vert_center,
zboolean  vert_bottom 
)

Create mesh from FBX file.

Parameters
relative_pathRelative path of FBX file (with extension FBX), expected to be in FBX_DIR predefined location
invert_zInvert z spatial coord - should be set to TRUE if mesh uses RH coords sys, FALSE if mesh uses LH coords sys
normalize_xyzNormalize spatial coords
horiz_centerCenter mesh horizontally
vert_centerCenter mesh vertically, if vert_bottom is not set
vert_bottomSet mesh origin vertically at bottom, override vert_center
Returns
A new LG_Mesh instance if OK, NULL on error

◆ lg_mesh_free()

void lg_mesh_free ( LG_Mesh mesh)

Free mesh.

Parameters
meshPointer to mesh

◆ lg_mesh_free_v2()

void lg_mesh_free_v2 ( LG_Mesh **  mesh)

NEW - needs extensive testing

Free mesh v2.

Take pointer to pointer to mesh arg, so that it can be nullified afterwards.

Parameters
meshPointer to pointer to mesh

◆ lg_bmesh_save_to_file()

int lg_bmesh_save_to_file ( const char *  full_path,
LG_Mesh mesh 
)

Save mesh in BINARY MESH (.bmesh) format. Don't add suffix BINARY_MESH_EXT, as it's done automagically.

BINARY MESH (.bmesh) file format
================================
- VBO data block - aligned to 4 bytes boundaries
-> starting at header_size
- IBO data block - aligned to 4 bytes boundaries
-> starting at header_size + lg_align_up_to_next_4_bytes_boundary((void *)(uint64_t)mesh->vbo_size)
void * lg_align_up_to_next_4_bytes_boundary(void *addr)
Definition lg_misc.c:280
Definition lg_mesh.h:168
Parameters
full_pathBMESH file full path
meshPointer to a LG_Mesh
Returns
LG_OK if OK, error code otherwise

◆ lg_bmesh_load_from_file()

int lg_bmesh_load_from_file ( const char *  full_path,
LG_Mesh **  mesh 
)

Load mesh from BINARY MESH (.bmesh) file. Don't add suffix BINARY_MESH_EXT, as it's done automagically.

BINARY MESH (.bmesh) file format
================================
- VBO data block - aligned to 4 bytes boundaries
-> starting at header_size
- IBO data block - aligned to 4 bytes boundaries
-> starting at header_size + lg_align_up_to_next_4_bytes_boundary((void *)(uint64_t)mesh->vbo_size)
Parameters
full_pathBMESH file full path
meshPointer to an array of pointers to LG_Mesh
Returns
LG_OK if OK, error code otherwise

◆ lg_mesh_reload_mats()

int lg_mesh_reload_mats ( LG_Mesh mesh)

Reload materials textures correctly, when mesh is not loaded from OBJ file.

Parameters
meshPointer to a LG_Mesh
Returns
LG_OK if OK, error code otherwise

◆ lg_serialize_LG_Material_64_to_32()

void lg_serialize_LG_Material_64_to_32 ( Serializable_LG_Material s_mat,
LG_Material mat 
)

Serialize a LG_Material instance

Parameters
s_matPointer to a Serializable_LG_Material
matPointer to a Serializable_LG_Material

◆ lg_unserialize_LG_Material_32_to_64()

void lg_unserialize_LG_Material_32_to_64 ( LG_Material mat,
Serializable_LG_Material s_mat 
)

Unserialize a LG_Material instance

Parameters
matPointer to a Serializable_LG_Material
s_matPointer to a Serializable_LG_Material

◆ lg_serialize_LG_Mesh_64_to_32()

void lg_serialize_LG_Mesh_64_to_32 ( Serializable_LG_Mesh s_mesh,
LG_Mesh mesh 
)

Serialize a LG_Mesh instance

Parameters
s_meshPointer to a Serializable_LG_Mesh
meshPointer to a LG_Mesh

◆ lg_unserialize_LG_Mesh_32_to_64()

void lg_unserialize_LG_Mesh_32_to_64 ( LG_Mesh mesh,
Serializable_LG_Mesh s_mesh 
)

Unserialize a LG_Mesh instance

Parameters
meshPointer to a LG_Mesh
s_meshPointer to a Serializable_LG_Mesh

◆ lg_loadmesh_flags()

LG_LoadMesh_Flags lg_loadmesh_flags ( zboolean  save_to_assets,
zboolean  invert_z,
zboolean  normalize_xyz,
zboolean  horiz_center,
zboolean  vert_center,
zboolean  vert_bottom 
)

Mesh loading flags.

See lg_mesh_load().

You can use these helper, which are all set to TRUE:

  • SAVE_TO_ASSETS
  • INVERT_Z
  • NORMALIZE_XYZ
  • VERT_CENTER
  • VERT_BOTTOM
Parameters
save_to_assetsSave to assets as BMESH, otherwise to cache - on Android, should always be set to FALSE as you can't write to assets
invert_zInvert z spatial coord - should be set to TRUE if mesh uses RH coords sys, FALSE if mesh uses LH coords sys
normalize_xyz
horiz_center
vert_centerCenter mesh vertically, if vert_bottom is not set
vert_bottomSet mesh origin vertically at bottom, override vert_center
Returns
A LG_LoadMesh_Flags

◆ lg_mesh_info()

void lg_mesh_info ( LG_Mesh mesh,
int  show_first_n 
)

Print out LG_Mesh info.

Parameters
meshPointer to a LG_Mesh
show_first_nShow first n elements of mesh->i_mat_in_vbo[N_USEMTL_MAX] and mesh->i_mat_in_lib[N_MAT_MAX]

= NULL ? mesh->materials[i].tex_full_path : "NULL"

◆ lg_replace_file_extension()

char * lg_replace_file_extension ( const char *  path,
const char *  new_ext 
)

Replace file extension with another extension, ie 'bla_bla/hello.old_ext' -> 'bla_bla/hello.new_ext'

Extension must not include leading dot

Remove trailing dot if new_ext is empty string

Returned new path must be freed after use (dynamically allocated)

lg_replace_file_extension('hello.vbo', 'blob') = 'hello.blob'
lg_replace_file_extension('bla_bla_1/bla_bla_2.vbo', 'blob') = 'bla_bla_1/bla_bla_2.blob'
lg_replace_file_extension('bla_bla_1/bla_bla_2.v', 'z') = 'bla_bla_1/bla_bla_2.z'
lg_replace_file_extension('hello1.hello2.vbo', 'blob') = 'hello1.hello2.blob'
lg_replace_file_extension('v.1', '2') = 'v.2'
lg_replace_file_extension('v1', '2') = 'v1.2'
lg_replace_file_extension('bla_bla_1/bla_bla_1', '2') = 'bla_bla_1/bla_bla_1.2'
lg_replace_file_extension('.1', '2') = '.2'
lg_replace_file_extension('vbo.1', '') = 'vbo'
lg_replace_file_extension('v.1', '') = 'v'
lg_replace_file_extension('1.', '2') = '1.2'
char * lg_replace_file_extension(const char *path, const char *new_ext)
Definition lg_mesh.c:751
Parameters
path
new_ext
Returns
New path with swapped extension