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 (LG_Path path, LG_LoadMesh_Flags flags)
 
LG_Meshlg_mesh_new_from_obj (LG_Path path, zboolean invert_z, zboolean normalize_xyz, zboolean horiz_center, zboolean vert_center, zboolean vert_bottom)
 
LG_Meshlg_mesh_new_from_fbx (LG_Path 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 (LG_Path path, LG_Mesh *mesh)
 
LG_Meshlg_bmesh_load_from_file (LG_Path path)
 
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_as_bmesh_linux, zboolean invert_z, zboolean normalize_xyz, zboolean horiz_center, zboolean vert_center, zboolean vert_bottom)
 
void lg_mesh_override_bounding_cuboid_color (LG_Mesh *mesh, LG_Color_u color)
 
void lg_mesh_info (LG_Mesh *mesh, int show_first_n)
 
char * lg_mesh_info_to_string (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 only use this func to load meshes:

LG_Mesh *lg_mesh_load(path, flags)
LG_Mesh * lg_mesh_load(LG_Path path, LG_LoadMesh_Flags flags)
Definition lg_mesh.c:97
Definition lg_mesh.h:80

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

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

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()

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
Definition lg_mesh.h:117

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

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 ( LG_Path  path,
LG_LoadMesh_Flags  flags 
)

Load OBJ or FBX or BMESH mesh file

If all your meshes (OBJ, FBX, BMESH) are in the 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

// The ASSETS dir structure:
//
// <assets_dir>
// / \
// <images> <meshes>
// | / \
// <textures> <bmesh> <obj>
// Mesh loading flags
typedef struct {
zboolean save_as_bmesh_linux; // If OBJ or FBX loaded from assets, save as a BMESH asset, only on Linux
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

Usage examples:

LG_LoadMesh_Flags flags = lg_loadmesh_flags(FALSE, FALSE, NORMALIZE_XYZ, HORIZ_CENTER, VERT_CENTER, FALSE);
LG_Mesh *mesh1 = lg_mesh_load(lg_path('meshes/obj/file1.obj', IN_ASSETS), flags);
LG_Mesh *mesh2 = lg_mesh_load(lg_path('meshes/bmesh/file2.bmesh', IN_ASSETS), flags);
LG_Path lg_path(const char *s, lg_path_type t)
Definition lg_goodies.c:149
LG_LoadMesh_Flags lg_loadmesh_flags(zboolean save_as_bmesh_linux, zboolean invert_z, zboolean normalize_xyz, zboolean horiz_center, zboolean vert_center, zboolean vert_bottom)
Definition lg_mesh.c:586

On Linux, if OBJ or FBX file was successfully loaded from assets and flags.save_as_bmesh_linux is set to TRUE, it will be saved as a BMESH asset

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

WARNING: FBX support is not complete yet

Parameters
pathLG_Path of mesh file, with extension OBJ or FBX or BMESH
flagsApply to OBJ/FBX meshes loading: save_as_bmesh_linux, 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 ( LG_Path  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
pathLG_PATH to 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_fbx()

LG_Mesh * lg_mesh_new_from_fbx ( LG_Path  path,
zboolean  invert_z,
zboolean  normalize_xyz,
zboolean  horiz_center,
zboolean  vert_center,
zboolean  vert_bottom 
)

Create mesh from FBX file.

Parameters
pathLG_PATH to 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_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 ( LG_Path  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:162
Parameters
pathLG_Path to BMESH file
meshPointer to a LG_Mesh
Returns
LG_OK if OK, error code otherwise

◆ lg_bmesh_load_from_file()

LG_Mesh * lg_bmesh_load_from_file ( LG_Path  path)

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
pathLG_Path to BMESH file
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_as_bmesh_linux,
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_AS_BMESH_LINUX
  • INVERT_Z
  • NORMALIZE_XYZ
  • VERT_CENTER
  • VERT_BOTTOM
Parameters
save_as_bmesh_linuxIf OBJ or FBX loaded from assets, save as a BMESH asset, only on Linux
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_override_bounding_cuboid_color()

void lg_mesh_override_bounding_cuboid_color ( LG_Mesh mesh,
LG_Color_u  color 
)

Override color of mesh bounding cuboid AND bounding cuboid VB

Why is this needed ? bc color is set at mesh creation time

mesh->b_cuboid = LG_Cuboid // Bounding cuboid mesh->Lines3D_VB = b_cuboid_l3d_vb // Lines3D_VB from bounding cuboid

Parameters
meshPointer to a LG_Mesh
colorColor as a LG_Color_u

◆ 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_NEWMTL_USEMTL_TAGS_MAX]
  • mesh->i_mat_in_lib[N_NEWMTL_USEMTL_TAGS_MAX]

◆ lg_mesh_info_to_string()

char * lg_mesh_info_to_string ( LG_Mesh mesh,
int  show_first_n 
)

Get LG_Mesh info as a string

NOTE: mesh->b_cuboid is not output (so far)

Parameters
meshPointer to a LG_Mesh
show_first_nShow first n elements of:
  • mesh->i_mat_in_vbo[N_NEWMTL_USEMTL_TAGS_MAX]
  • mesh->i_mat_in_lib[N_NEWMTL_USEMTL_TAGS_MAX]
Returns
LG_Mesh info as a string - must be freed when done, or NULL on error

◆ 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:879
Parameters
path
new_ext
Returns
New path with swapped extension if OK, NULL on error