Jo Engine 2026.11.1
Jo Sega Saturn Engine
Loading...
Searching...
No Matches
model.h File Reference

3D models (.JOM files): meshes made with a 3D software, converted by Compiler/COMMON/jo_model.py More...

Go to the source code of this file.

Data Structures

struct  jo_3d_material
 Material of a model (the same layout as the file: 32 bytes). More...
struct  jo_3d_model_group
 Group of a model: OBJ o or g (the same layout as the file: 24 bytes). More...
struct  jo_3d_bone
 Bone of a rigid skeleton (the same layout as the file: 32 bytes). More...
struct  jo_3d_animation
 Animation of a skeleton (the same layout as the file: 28 bytes). More...
struct  jo_3d_pose
 Pose of a skeleton: the angles of the bones (see jo_3d_model_get_pose() and jo_3d_model_draw_pose()). More...
struct  jo_3d_model
 3D model loaded from a JOM file More...

Macros

#define JO_3D_MODEL_VERSION
 Version of the JOM files read by this engine.
#define JO_3D_MATERIAL_DUAL_PLANE
 Material: drawn on both sides (JO_3D_DUAL_PLANE).
#define JO_3D_MATERIAL_SORT_MIN
 Material: sorted with the nearest point (JO_3D_SORT_MIN).
#define JO_3D_MATERIAL_SORT_MAX
 Material: sorted with the farthest point (JO_3D_SORT_MAX).
#define JO_3D_MATERIAL_SORT_PREVIOUS
 Material: sorted with the depth of the previous polygon of the model (JO_3D_SORT_PREVIOUS): a decal drawn over the face before it (a grille, a sign), whatever their nearest points.
#define JO_3D_MATERIAL_GOURAUD
 Material: gouraud shading with the vertex colors ("GOUR" chunk).
#define JO_3D_MATERIAL_HALF_TRANSPARENT
 Material: half transparent.
#define JO_3D_MATERIAL_SCREEN_DOORS
 Material: screen doors (mesh).
#define JO_3D_MATERIAL_LIGHT
 Material: lit by the light of the engine (jo_3d_light()).
#define JO_3D_MATERIAL_FLIP_H
 Material: texture flipped horizontally.
#define JO_3D_MATERIAL_FLIP_V
 Material: texture flipped vertically.
#define JO_3D_MATERIAL_END_CODES
 Material: the texture stops each line after its last visible pixel (jo_sprite_add_end_codes()).
#define JO_3D_MATERIAL_MIPMAPS
 Material: smaller copies of the texture far away (jo_3d_set_texture_mipmaps()).
#define JO_3D_MATERIAL_SUBDIVISION
 Material: the polygons near the camera are drawn in parts (jo_3d_set_texture_subdivision()).
#define JO_3D_MATERIAL_SUBDIVISION_NEAR
 Material: only the polygons that cross the near plane are drawn in parts (jo_3d_set_texture_subdivision_near_only(), MTL: jo_subdivision 2).
#define JO_3D_MATERIAL_USER(N)
 First flag of the program (bits 16 to 31, MTL: jo_user).
#define JO_3D_MAX_BONES
 Bones of a model at most (jo_3d_pose).
#define JO_3D_BONE_NO_GROUP
 jo_3d_bone.group: the bone has no polygons
#define JO_3D_ANIMATION_LOOP
 jo_3d_animation.flags: the last key goes back to the first one
#define JO_3D_ANIMATION_TICKS_PER_SECOND
 Ticks of the animations per second (the time of jo_3d_model_get_pose()).

Typedefs

typedef void(*) jo_3d_bone_callback(const int bone, void *const param, const jo_fixed(*const matrix)[3])
 Called by jo_3d_model_draw_pose() after each bone is drawn, with the matrix of the bone (the program draws a weapon in a hand, a muzzle flash...).

Functions

jo_3d_model * jo_3d_create_model_from_memory (const unsigned char *const data, const unsigned int size)
 Create a model from the content of a JOM file.
jo_3d_model * jo_3d_create_model_in_place (const unsigned char *const data, const unsigned int size)
 Create a model that uses the content of a JOM file in place (like jo_3d_load_model(): the points, the polygons, the materials are not copied): much faster than jo_3d_create_model_from_memory() for many models (a level read in one block: 4 memory blocks per model instead of about 12), and smaller.
jo_3d_model * jo_3d_load_model (const char *const filename)
 Load a model (JOM file) from the current directory of the CD.
jo_3d_model * __jo_3d_load_model_for_lights (const char *const filename)
 Load a model with a gouraud table per polygon (Internal usage: the cells, lit by the point lights, see jo_3d_point_lights_add_mesh()). jo_3d_load_model() gives one table to the polygons with the same colors.
int jo_3d_model_texture (const char *const filename)
 Get the sprite id of a texture of the models (loaded the first time: a texture shared by several models, or by the program, is loaded once).
int jo_3d_model_loaded_texture (const char *const name)
 Get the sprite id of a texture already loaded by the models (embedded in a model, or loaded by jo_3d_model_texture()), without loading it.
void jo_3d_free_model (jo_3d_model *const model)
 Free a model (the textures stay loaded).
void jo_3d_model_free_textures_from (const int sprite_id)
 Free the sprites added since a sprite (the textures of the models loaded since, their tiles and smaller copies, their gouraud tables, the sprites added by the program): the VRAM of the VDP1 is given back.
const jo_3d_model_group * jo_3d_model_find_group (const jo_3d_model *const model, const char *const name)
 Find a group of a model.
int jo_3d_model_find_bone (const jo_3d_model *const model, const char *const name)
 Find a bone of a model.
int jo_3d_model_find_animation (const jo_3d_model *const model, const char *const name)
 Find an animation of a model.
bool jo_3d_model_is_animation (const jo_3d_model *const model, const int animation, const char *const name)
 Check if an animation is the one jo_3d_model_find_animation() finds for a name (faster: the name of this one is compared, the ones before it only when it matches).
int jo_3d_model_animation_duration (const jo_3d_model *const model, const int animation)
 Duration of an animation.
void jo_3d_model_get_pose (const jo_3d_model *const model, const int animation, int time, jo_3d_pose *const pose)
 Pose of a skeleton at a time of an animation (the keys are interpolated).
void jo_3d_pose_blend (const jo_3d_model *const model, jo_3d_pose *const pose, const jo_3d_pose *const other, const int weight)
 Blend 2 poses (a smooth change of animation).
void jo_3d_model_draw_pose (const jo_3d_model *const model, const jo_3d_pose *const pose, const jo_3d_bone_callback callback, void *const param)
 Draw a model with a skeleton with the current matrix.
void jo_3d_model_set_hidden_bones (const unsigned int mask)
 Bones not drawn by the next jo_3d_model_draw_pose() (a hat shot off the head of a character: its bone hidden, the hat drawn alone where it falls: the other bones hidden).
static __jo_force_inline void jo_3d_model_draw (const jo_3d_model *const model)
 Draw a model with the current matrix.

Detailed Description

3D models (.JOM files): meshes made with a 3D software, converted by Compiler/COMMON/jo_model.py

Author
Johannes Fetz
Remarks
The converter reads Wavefront OBJ files (and their MTL materials, see jo_model.py for the options of the materials) and writes a JOM file. The data of a JOM file are in the memory format of the Saturn (big endian, 16.16 fixed point): the points and the polygons are copied as they are, nothing is converted when it is loaded

JOM file (all the values are big endian, the chunks are aligned on 4 bytes):

Header (24 bytes)
char[4] "JOM1"
u16 version (1)
u16 reserved (0)
fixed[3] center of the bounding sphere (16.16)
fixed radius of the bounding sphere
Chunks, until the "END " chunk. A chunk: char[4] tag, u32 size of the data (multiple of 4), data.
The loader skips the unknown chunks (newer versions of the converter)
"TIMG" (optional, first chunk) u32 count, then count x (char[16] name, u16 width, u16 height, u16 format,
u16 reserved, then the pixels, 4 bytes aligned): embedded textures. Format 0 (RGB 555): width x height u16
pixels, 0 is transparent. Format 1 (16 colors, jo_lut in the MTL): 16 u16 colors (RGB 555, the color 0 is
transparent), then 2 pixels per byte (the left pixel in the high bits), see jo_sprite_add_4bits_lut()
(jo_model.py --embed-textures). jo_3d_load_model() reads them one at a time and copies them in the VRAM
(a texture already loaded by another model is skipped), they don't stay in the work RAM
"PNTS" u32 count, then count x (fixed x, fixed y, fixed z) Points (Saturn axes: Y down)
"QUAD" u32 count, then count x (fixed nx, ny, nz, u16 v0, v1, v2, v3) Polygons (jo_3d_polygon): normal and
4 point indexes (a triangle: v3 = v2)
"QMAT" u32 count, then count x u16 (+ u16 pad if count is odd) Material of each polygon
"MATL" u32 count, then count x jo_3d_material (32 bytes) Materials
"TEXT" u32 count, then count x char[16] Textures: names (the embedded textures, or
the files on the CD: .BIN or .TGA)
"NTAB" u32 count, then count x (fixed x, fixed y, fixed z) Normals (OBJ vn)
"CNRM" u32 count (4 x polygons), then count x u16 (+ pad) Normal of each corner of each polygon
"VCOL" u32 count (points), then count x (fixed r, fixed g, fixed b) Vertex colors (OBJ v x y z r g b), 1.0 = 0x10000
"GOUR" u32 count (4 x polygons), then count x u16 (+ pad) Gouraud colors of the corners (RGB 555 of
the vertex colors: 16 = texture unchanged)
"GRUP" u32 count, then count x jo_3d_model_group (24 bytes) Groups (OBJ o and g): names, ranges of
polygons and of the points used only by
the group (for animations)
"BONE" u32 count, then count x jo_3d_bone (32 bytes) Rigid skeleton: each bone moves a group
(its polygons use only its points), a
parent is before its children
"ANIM" u32 count, then count x jo_3d_animation (28 bytes), then the keys Animations. The keys of an animation
(at offset from the count): key_count x
(fixed root x, y, z, then bones x
(s16 angle x, y, z), + s16 pad if odd)
"END " 0
Polygon (quadrilateral, a triangle repeats the last vertex).
Definition 3d.h:128
jo_3d_model * jo_3d_load_model(const char *const filename)
Load a model (JOM file) from the current directory of the CD.
Animation of a skeleton (the same layout as the file: 28 bytes).
Definition model.h:167
Bone of a rigid skeleton (the same layout as the file: 32 bytes).
Definition model.h:158
Material of a model (the same layout as the file: 32 bytes).
Definition model.h:124
Group of a model: OBJ o or g (the same layout as the file: 24 bytes).
Definition model.h:139
int jo_sprite_add_4bits_lut(const unsigned char *const pixels, const unsigned short width, const unsigned short height, const jo_color *const lut)
Add a 16 colors texture with its color lookup table: 4 bits per pixel (4 times less VRAM than an RGB ...

Data Structure Documentation

◆ jo_3d_material

struct jo_3d_material

Material of a model (the same layout as the file: 32 bytes).

Data Fields
unsigned char b
unsigned int flags
unsigned char g
char name[16]
unsigned char r
unsigned char shine
unsigned short subdivision_error
short texture
unsigned int user

◆ jo_3d_model_group

struct jo_3d_model_group

Group of a model: OBJ o or g (the same layout as the file: 24 bytes).

Data Fields
unsigned short first_point
unsigned short first_polygon
char name[16]
unsigned short point_count
unsigned short polygon_count

◆ jo_3d_bone

struct jo_3d_bone

Bone of a rigid skeleton (the same layout as the file: 32 bytes).

Data Fields
unsigned short group
char name[16]
short parent
jo_pos3D_fixed pivot

◆ jo_3d_animation

struct jo_3d_animation

Animation of a skeleton (the same layout as the file: 28 bytes).

Data Fields
unsigned short duplicate
unsigned short flags
unsigned short key_count
unsigned short key_ticks
char name[16]
unsigned int offset

◆ jo_3d_pose

struct jo_3d_pose

Pose of a skeleton: the angles of the bones (see jo_3d_model_get_pose() and jo_3d_model_draw_pose()).

Data Fields
jo_angle angles[(32)][3]
jo_pos3D_fixed root

◆ jo_3d_model

struct jo_3d_model

3D model loaded from a JOM file

Data Fields
unsigned int animation_count
const unsigned char * animation_data
jo_3d_animation * animations
signed char * bone_children
unsigned int bone_count
jo_3d_bone * bones
jo_pos3D_fixed center
unsigned short * corner_normals
void * file
bool file_not_owned
unsigned short gouraud_tables
unsigned int group_count
jo_3d_model_group * groups
unsigned int material_count
jo_3d_material * materials
jo_3d_mesh * mesh
unsigned int normal_count
jo_pos3D_fixed * normals
unsigned short * polygon_materials
jo_fixed radius
bool single_block
unsigned int texture_count
int * textures
jo_pos3D_fixed * vertex_colors

Macro Definition Documentation

◆ JO_3D_ANIMATION_LOOP

#define JO_3D_ANIMATION_LOOP

jo_3d_animation.flags: the last key goes back to the first one

◆ JO_3D_ANIMATION_TICKS_PER_SECOND

#define JO_3D_ANIMATION_TICKS_PER_SECOND

Ticks of the animations per second (the time of jo_3d_model_get_pose()).

◆ JO_3D_BONE_NO_GROUP

#define JO_3D_BONE_NO_GROUP

jo_3d_bone.group: the bone has no polygons

◆ JO_3D_MATERIAL_DUAL_PLANE

#define JO_3D_MATERIAL_DUAL_PLANE

Material: drawn on both sides (JO_3D_DUAL_PLANE).

◆ JO_3D_MATERIAL_END_CODES

#define JO_3D_MATERIAL_END_CODES

Material: the texture stops each line after its last visible pixel (jo_sprite_add_end_codes()).

◆ JO_3D_MATERIAL_FLIP_H

#define JO_3D_MATERIAL_FLIP_H

Material: texture flipped horizontally.

◆ JO_3D_MATERIAL_FLIP_V

#define JO_3D_MATERIAL_FLIP_V

Material: texture flipped vertically.

◆ JO_3D_MATERIAL_GOURAUD

#define JO_3D_MATERIAL_GOURAUD

Material: gouraud shading with the vertex colors ("GOUR" chunk).

◆ JO_3D_MATERIAL_HALF_TRANSPARENT

#define JO_3D_MATERIAL_HALF_TRANSPARENT

Material: half transparent.

◆ JO_3D_MATERIAL_LIGHT

#define JO_3D_MATERIAL_LIGHT

Material: lit by the light of the engine (jo_3d_light()).

◆ JO_3D_MATERIAL_MIPMAPS

#define JO_3D_MATERIAL_MIPMAPS

Material: smaller copies of the texture far away (jo_3d_set_texture_mipmaps()).

◆ JO_3D_MATERIAL_SCREEN_DOORS

#define JO_3D_MATERIAL_SCREEN_DOORS

Material: screen doors (mesh).

◆ JO_3D_MATERIAL_SORT_MAX

#define JO_3D_MATERIAL_SORT_MAX

Material: sorted with the farthest point (JO_3D_SORT_MAX).

◆ JO_3D_MATERIAL_SORT_MIN

#define JO_3D_MATERIAL_SORT_MIN

Material: sorted with the nearest point (JO_3D_SORT_MIN).

◆ JO_3D_MATERIAL_SORT_PREVIOUS

#define JO_3D_MATERIAL_SORT_PREVIOUS

Material: sorted with the depth of the previous polygon of the model (JO_3D_SORT_PREVIOUS): a decal drawn over the face before it (a grille, a sign), whatever their nearest points.

◆ JO_3D_MATERIAL_SUBDIVISION

#define JO_3D_MATERIAL_SUBDIVISION

Material: the polygons near the camera are drawn in parts (jo_3d_set_texture_subdivision()).

◆ JO_3D_MATERIAL_SUBDIVISION_NEAR

#define JO_3D_MATERIAL_SUBDIVISION_NEAR

Material: only the polygons that cross the near plane are drawn in parts (jo_3d_set_texture_subdivision_near_only(), MTL: jo_subdivision 2).

◆ JO_3D_MATERIAL_USER

#define JO_3D_MATERIAL_USER ( N)

First flag of the program (bits 16 to 31, MTL: jo_user).

◆ JO_3D_MAX_BONES

#define JO_3D_MAX_BONES

Bones of a model at most (jo_3d_pose).

◆ JO_3D_MODEL_VERSION

#define JO_3D_MODEL_VERSION

Version of the JOM files read by this engine.

Typedef Documentation

◆ jo_3d_bone_callback

typedef void(*) jo_3d_bone_callback(const int bone, void *const param, const jo_fixed(*const matrix)[3])

Called by jo_3d_model_draw_pose() after each bone is drawn, with the matrix of the bone (the program draws a weapon in a hand, a muzzle flash...).

Parameters
boneIndex of the bone
paramParameter of jo_3d_model_draw_pose()
matrixMatrix of the bone (4 rows of 3, see jo_3d_transform_point_by()); the current matrix is not the one of the bone

Function Documentation

◆ __jo_3d_load_model_for_lights()

jo_3d_model * __jo_3d_load_model_for_lights ( const char *const filename)

Load a model with a gouraud table per polygon (Internal usage: the cells, lit by the point lights, see jo_3d_point_lights_add_mesh()). jo_3d_load_model() gives one table to the polygons with the same colors.

Parameters
filenameFile name
Returns
The model, JO_NULL if not loaded

◆ jo_3d_create_model_from_memory()

jo_3d_model * jo_3d_create_model_from_memory ( const unsigned char *const data,
const unsigned int size )

Create a model from the content of a JOM file.

Parameters
dataContent of the file (4 bytes aligned)
sizeSize in bytes
Returns
The model, JO_NULL if the file is wrong or if out of memory
Remarks
The embedded textures ("TIMG" chunk) are copied to the VRAM, the other textures are loaded from the CD (see jo_3d_model_texture()). The data can be freed after the call

◆ jo_3d_create_model_in_place()

jo_3d_model * jo_3d_create_model_in_place ( const unsigned char *const data,
const unsigned int size )

Create a model that uses the content of a JOM file in place (like jo_3d_load_model(): the points, the polygons, the materials are not copied): much faster than jo_3d_create_model_from_memory() for many models (a level read in one block: 4 memory blocks per model instead of about 12), and smaller.

Parameters
dataContent of the file (4 bytes aligned), kept by the caller as long as the model exists
sizeSize in bytes
Returns
The model, JO_NULL if the file is wrong or if out of memory
Remarks
jo_3d_free_model() does not free the data

◆ jo_3d_free_model()

void jo_3d_free_model ( jo_3d_model *const model)

Free a model (the textures stay loaded).

Parameters
modelModel

◆ jo_3d_load_model()

jo_3d_model * jo_3d_load_model ( const char *const filename)

Load a model (JOM file) from the current directory of the CD.

Parameters
filenameFile name (example: "MODEL.JOM")
Returns
The model, JO_NULL if the file is not found, wrong or if out of memory
Remarks
Free it with jo_3d_free_model()
The model uses the data of the file (one memory block: the points and the polygons are not copied)
Embedded textures (jo_model.py –embed-textures): read one at a time and copied to the VRAM, they don't stay in the work RAM

◆ jo_3d_model_animation_duration()

int jo_3d_model_animation_duration ( const jo_3d_model *const model,
const int animation )

Duration of an animation.

Parameters
modelModel
animationIndex of the animation
Returns
Ticks (1/60 s): a loop goes back to its first key at this time, the other animations stay on their last key

◆ jo_3d_model_draw()

__jo_force_inline void jo_3d_model_draw ( const jo_3d_model *const model)
static

Draw a model with the current matrix.

Parameters
modelModel
Remarks
A model with a skeleton is drawn in the pose of the OBJ (see jo_3d_model_draw_pose())

◆ jo_3d_model_draw_pose()

void jo_3d_model_draw_pose ( const jo_3d_model *const model,
const jo_3d_pose *const pose,
const jo_3d_bone_callback callback,
void *const param )

Draw a model with a skeleton with the current matrix.

Parameters
modelModel
posePose (JO_NULL: the pose of the OBJ)
callbackCalled after each bone is drawn, with the matrix of the bone (JO_NULL: none)
paramParameter of the callback

◆ jo_3d_model_find_animation()

int jo_3d_model_find_animation ( const jo_3d_model *const model,
const char *const name )

Find an animation of a model.

Parameters
modelModel
nameName of the animation
Returns
Index of the animation, -1 if not found

◆ jo_3d_model_find_bone()

int jo_3d_model_find_bone ( const jo_3d_model *const model,
const char *const name )

Find a bone of a model.

Parameters
modelModel
nameName of the bone
Returns
Index of the bone, -1 if not found

◆ jo_3d_model_find_group()

const jo_3d_model_group * jo_3d_model_find_group ( const jo_3d_model *const model,
const char *const name )

Find a group of a model.

Parameters
modelModel
nameName of the group (OBJ o or g)
Returns
The group, JO_NULL if not found

◆ jo_3d_model_free_textures_from()

void jo_3d_model_free_textures_from ( const int sprite_id)

Free the sprites added since a sprite (the textures of the models loaded since, their tiles and smaller copies, their gouraud tables, the sprites added by the program): the VRAM of the VDP1 is given back.

Parameters
sprite_idFirst sprite to free (jo_sprite_count() before the models were loaded)
Remarks
Call it after the models were freed (jo_3d_free_model()): a level loaded and freed again and again, with its models, would use up the VRAM otherwise (the gouraud tables of a model are new sprites at each load)

◆ jo_3d_model_get_pose()

void jo_3d_model_get_pose ( const jo_3d_model *const model,
const int animation,
int time,
jo_3d_pose *const pose )

Pose of a skeleton at a time of an animation (the keys are interpolated).

Parameters
modelModel
animationIndex of the animation, -1: the bones don't turn (the pose of the OBJ)
timeTicks (1/60 s) from the start of the animation
posePose

◆ jo_3d_model_is_animation()

bool jo_3d_model_is_animation ( const jo_3d_model *const model,
const int animation,
const char *const name )

Check if an animation is the one jo_3d_model_find_animation() finds for a name (faster: the name of this one is compared, the ones before it only when it matches).

Parameters
modelModel
animationIndex of the animation
nameName (case insensitive)
Returns
true if jo_3d_model_find_animation(model, name) == animation

◆ jo_3d_model_loaded_texture()

int jo_3d_model_loaded_texture ( const char *const name)

Get the sprite id of a texture already loaded by the models (embedded in a model, or loaded by jo_3d_model_texture()), without loading it.

Parameters
nameName of the texture (its file name, or its name in the model)
Returns
Sprite id, -1 if no model has this texture

◆ jo_3d_model_set_hidden_bones()

void jo_3d_model_set_hidden_bones ( const unsigned int mask)

Bones not drawn by the next jo_3d_model_draw_pose() (a hat shot off the head of a character: its bone hidden, the hat drawn alone where it falls: the other bones hidden).

Parameters
maskBit k: the bone k (and its children) hidden, 0: all drawn

◆ jo_3d_model_texture()

int jo_3d_model_texture ( const char *const filename)

Get the sprite id of a texture of the models (loaded the first time: a texture shared by several models, or by the program, is loaded once).

Parameters
filenameFile name on the CD (.BIN: jo_sprite_add_bin(), .TGA: jo_sprite_add_tga())
Returns
Sprite id, -1 if not loaded
Remarks
The transparent color is JO_COLOR_Transparent

◆ jo_3d_pose_blend()

void jo_3d_pose_blend ( const jo_3d_model *const model,
jo_3d_pose *const pose,
const jo_3d_pose *const other,
const int weight )

Blend 2 poses (a smooth change of animation).

Parameters
modelModel
poseFirst pose, the result
otherSecond pose
weightWeight of the second pose (0 to 256)