Files
coven/modules/ufbx/module.jai
2024-10-18 16:12:24 +02:00

5197 lines
176 KiB
Plaintext

//
// This file was auto-generated using the following command:
//
// jai first.jai
//
#import "Windows";
UFBX_CPP :: 0;
UFBX_PLATFORM_GNUC :: 0;
UFBX_CPP11 :: 0;
UFBX_ERROR_STACK_MAX_DEPTH :: 8;
UFBX_PANIC_MESSAGE_LENGTH :: 128;
UFBX_ERROR_INFO_LENGTH :: 256;
UFBX_NO_INDEX :: cast,trunc(u32)~0;
// TODO: Support overriding `ufbx_real` with `float` or anything else.
ufbx_real :: float64;
// Null-terminated UTF-8 encoded string within an FBX file
ufbx_string :: struct {
data: *u8;
length: size_t;
}
// Opaque byte buffer blob
ufbx_blob :: struct {
data: *void;
size: size_t;
}
// 2D vector
ufbx_vec2 :: struct {
union {
struct {
x: ufbx_real;
y: ufbx_real;
}
v: [2] ufbx_real;
}
}
// 3D vector
ufbx_vec3 :: struct {
union {
struct {
x: ufbx_real;
y: ufbx_real;
z: ufbx_real;
}
v: [3] ufbx_real;
}
}
// 4D vector
ufbx_vec4 :: struct {
union {
struct {
x: ufbx_real;
y: ufbx_real;
z: ufbx_real;
w: ufbx_real;
}
v: [4] ufbx_real;
}
}
// Quaternion
ufbx_quat :: struct {
union {
struct {
x: ufbx_real;
y: ufbx_real;
z: ufbx_real;
w: ufbx_real;
}
v: [4] ufbx_real;
}
}
// Order in which Euler-angle rotation axes are applied for a transform
// NOTE: The order in the name refers to the order of axes *applied*,
// not the multiplication order: eg. `UFBX_ROTATION_XYZ` is `Z*Y*X`
// [TODO: Figure out what the spheric rotation order is...]
ufbx_rotation_order :: enum s32 {
XYZ :: 0;
XZY :: 1;
YZX :: 2;
YXZ :: 3;
ZXY :: 4;
ZYX :: 5;
SPHERIC :: 6;
FORCE_32BIT :: 2147483647;
UFBX_ROTATION_ORDER_XYZ :: XYZ;
UFBX_ROTATION_ORDER_XZY :: XZY;
UFBX_ROTATION_ORDER_YZX :: YZX;
UFBX_ROTATION_ORDER_YXZ :: YXZ;
UFBX_ROTATION_ORDER_ZXY :: ZXY;
UFBX_ROTATION_ORDER_ZYX :: ZYX;
UFBX_ROTATION_ORDER_SPHERIC :: SPHERIC;
UFBX_ROTATION_ORDER_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum :: enum s32 {
UFBX_ROTATION_ORDER_COUNT :: 7;
}
// Explicit translation+rotation+scale transformation.
// NOTE: Rotation is a quaternion, not Euler angles!
ufbx_transform :: struct {
translation: ufbx_vec3;
rotation: ufbx_quat;
scale: ufbx_vec3;
}
// 4x3 matrix encoding an affine transformation.
// `cols[0..2]` are the X/Y/Z basis vectors, `cols[3]` is the translation
ufbx_matrix :: struct {
union {
struct {
m00: ufbx_real;
m10: ufbx_real;
m20: ufbx_real;
m01: ufbx_real;
m11: ufbx_real;
m21: ufbx_real;
m02: ufbx_real;
m12: ufbx_real;
m22: ufbx_real;
m03: ufbx_real;
m13: ufbx_real;
m23: ufbx_real;
}
cols: [4] ufbx_vec3;
v: [12] ufbx_real;
}
}
ufbx_void_list :: struct {
data: *void;
count: size_t;
}
ufbx_bool_list :: struct {
data: *bool;
count: size_t;
}
ufbx_uint32_list :: struct {
data: *u32;
count: size_t;
}
ufbx_real_list :: struct {
data: *ufbx_real;
count: size_t;
}
ufbx_vec2_list :: struct {
data: *ufbx_vec2;
count: size_t;
}
ufbx_vec3_list :: struct {
data: *ufbx_vec3;
count: size_t;
}
ufbx_vec4_list :: struct {
data: *ufbx_vec4;
count: size_t;
}
ufbx_string_list :: struct {
data: *ufbx_string;
count: size_t;
}
// -- Document object model
ufbx_dom_value_type :: enum s32 {
NUMBER :: 0;
STRING :: 1;
ARRAY_I8 :: 2;
ARRAY_I32 :: 3;
ARRAY_I64 :: 4;
ARRAY_F32 :: 5;
ARRAY_F64 :: 6;
ARRAY_RAW_STRING :: 7;
ARRAY_IGNORED :: 8;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_DOM_VALUE_NUMBER :: NUMBER;
UFBX_DOM_VALUE_STRING :: STRING;
UFBX_DOM_VALUE_ARRAY_I8 :: ARRAY_I8;
UFBX_DOM_VALUE_ARRAY_I32 :: ARRAY_I32;
UFBX_DOM_VALUE_ARRAY_I64 :: ARRAY_I64;
UFBX_DOM_VALUE_ARRAY_F32 :: ARRAY_F32;
UFBX_DOM_VALUE_ARRAY_F64 :: ARRAY_F64;
UFBX_DOM_VALUE_ARRAY_RAW_STRING :: ARRAY_RAW_STRING;
UFBX_DOM_VALUE_ARRAY_IGNORED :: ARRAY_IGNORED;
UFBX_DOM_VALUE_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_1 :: enum s32 {
UFBX_DOM_VALUE_TYPE_COUNT :: 9;
}
ufbx_dom_value :: struct {
type: ufbx_dom_value_type;
value_str: ufbx_string;
value_blob: ufbx_blob;
value_int: s64;
value_float: float64;
}
ufbx_dom_node_list :: struct {
data: **ufbx_dom_node;
count: size_t;
}
ufbx_dom_value_list :: struct {
data: *ufbx_dom_value;
count: size_t;
}
ufbx_dom_node :: struct {
name: ufbx_string;
children: ufbx_dom_node_list;
values: ufbx_dom_value_list;
}
// Data type contained within the property. All the data fields are always
// populated regardless of type, so there's no need to switch by type usually
// eg. `prop->value_real` and `prop->value_int` have the same value (well, close)
// if `prop->type == UFBX_PROP_INTEGER`. String values are not converted from/to.
ufbx_prop_type :: enum s32 {
UNKNOWN :: 0;
BOOLEAN :: 1;
INTEGER :: 2;
NUMBER :: 3;
VECTOR :: 4;
COLOR :: 5;
COLOR_WITH_ALPHA :: 6;
STRING :: 7;
DATE_TIME :: 8;
TRANSLATION :: 9;
ROTATION :: 10;
SCALING :: 11;
DISTANCE :: 12;
COMPOUND :: 13;
BLOB :: 14;
REFERENCE :: 15;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_PROP_UNKNOWN :: UNKNOWN;
UFBX_PROP_BOOLEAN :: BOOLEAN;
UFBX_PROP_INTEGER :: INTEGER;
UFBX_PROP_NUMBER :: NUMBER;
UFBX_PROP_VECTOR :: VECTOR;
UFBX_PROP_COLOR :: COLOR;
UFBX_PROP_COLOR_WITH_ALPHA :: COLOR_WITH_ALPHA;
UFBX_PROP_STRING :: STRING;
UFBX_PROP_DATE_TIME :: DATE_TIME;
UFBX_PROP_TRANSLATION :: TRANSLATION;
UFBX_PROP_ROTATION :: ROTATION;
UFBX_PROP_SCALING :: SCALING;
UFBX_PROP_DISTANCE :: DISTANCE;
UFBX_PROP_COMPOUND :: COMPOUND;
UFBX_PROP_BLOB :: BLOB;
UFBX_PROP_REFERENCE :: REFERENCE;
UFBX_PROP_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_2 :: enum s32 {
UFBX_PROP_TYPE_COUNT :: 16;
}
// Property flags: Advanced information about properties, not usually needed.
ufbx_prop_flags :: enum s32 {
FLAG_ANIMATABLE :: 1;
FLAG_USER_DEFINED :: 2;
FLAG_HIDDEN :: 4;
FLAG_LOCK_X :: 16;
FLAG_LOCK_Y :: 32;
FLAG_LOCK_Z :: 64;
FLAG_LOCK_W :: 128;
FLAG_MUTE_X :: 256;
FLAG_MUTE_Y :: 512;
FLAG_MUTE_Z :: 1024;
FLAG_MUTE_W :: 2048;
FLAG_SYNTHETIC :: 4096;
FLAG_ANIMATED :: 8192;
FLAG_NOT_FOUND :: 16384;
FLAG_CONNECTED :: 32768;
FLAG_NO_VALUE :: 65536;
FLAG_OVERRIDDEN :: 131072;
FLAG_VALUE_REAL :: 1048576;
FLAG_VALUE_VEC2 :: 2097152;
FLAG_VALUE_VEC3 :: 4194304;
FLAG_VALUE_VEC4 :: 8388608;
FLAG_VALUE_INT :: 16777216;
FLAG_VALUE_STR :: 33554432;
FLAG_VALUE_BLOB :: 67108864;
FLAGS_FORCE_32BIT :: 2147483647;
UFBX_PROP_FLAG_ANIMATABLE :: FLAG_ANIMATABLE;
UFBX_PROP_FLAG_USER_DEFINED :: FLAG_USER_DEFINED;
UFBX_PROP_FLAG_HIDDEN :: FLAG_HIDDEN;
UFBX_PROP_FLAG_LOCK_X :: FLAG_LOCK_X;
UFBX_PROP_FLAG_LOCK_Y :: FLAG_LOCK_Y;
UFBX_PROP_FLAG_LOCK_Z :: FLAG_LOCK_Z;
UFBX_PROP_FLAG_LOCK_W :: FLAG_LOCK_W;
UFBX_PROP_FLAG_MUTE_X :: FLAG_MUTE_X;
UFBX_PROP_FLAG_MUTE_Y :: FLAG_MUTE_Y;
UFBX_PROP_FLAG_MUTE_Z :: FLAG_MUTE_Z;
UFBX_PROP_FLAG_MUTE_W :: FLAG_MUTE_W;
UFBX_PROP_FLAG_SYNTHETIC :: FLAG_SYNTHETIC;
UFBX_PROP_FLAG_ANIMATED :: FLAG_ANIMATED;
UFBX_PROP_FLAG_NOT_FOUND :: FLAG_NOT_FOUND;
UFBX_PROP_FLAG_CONNECTED :: FLAG_CONNECTED;
UFBX_PROP_FLAG_NO_VALUE :: FLAG_NO_VALUE;
UFBX_PROP_FLAG_OVERRIDDEN :: FLAG_OVERRIDDEN;
UFBX_PROP_FLAG_VALUE_REAL :: FLAG_VALUE_REAL;
UFBX_PROP_FLAG_VALUE_VEC2 :: FLAG_VALUE_VEC2;
UFBX_PROP_FLAG_VALUE_VEC3 :: FLAG_VALUE_VEC3;
UFBX_PROP_FLAG_VALUE_VEC4 :: FLAG_VALUE_VEC4;
UFBX_PROP_FLAG_VALUE_INT :: FLAG_VALUE_INT;
UFBX_PROP_FLAG_VALUE_STR :: FLAG_VALUE_STR;
UFBX_PROP_FLAG_VALUE_BLOB :: FLAG_VALUE_BLOB;
UFBX_PROP_FLAGS_FORCE_32BIT :: FLAGS_FORCE_32BIT;
}
// Single property with name/type/value.
ufbx_prop :: struct {
name: ufbx_string;
_internal_key: u32;
type: ufbx_prop_type;
flags: ufbx_prop_flags;
value_str: ufbx_string;
value_blob: ufbx_blob;
value_int: s64;
union {
value_real_arr: [4] ufbx_real;
value_real: ufbx_real;
value_vec2: ufbx_vec2;
value_vec3: ufbx_vec3;
value_vec4: ufbx_vec4;
}
}
ufbx_prop_list :: struct {
data: *ufbx_prop;
count: size_t;
}
// List of alphabetically sorted properties with potential defaults.
// For animated objects in as scene from `ufbx_evaluate_scene()` this list
// only has the animated properties, the originals are stored under `defaults`.
ufbx_props :: struct {
props: ufbx_prop_list;
num_animated: size_t;
defaults: *ufbx_props;
}
ufbx_element_list :: struct {
data: **ufbx_element;
count: size_t;
}
ufbx_unknown_list :: struct {
data: **ufbx_unknown;
count: size_t;
}
ufbx_node_list :: struct {
data: **ufbx_node;
count: size_t;
}
ufbx_mesh_list :: struct {
data: **ufbx_mesh;
count: size_t;
}
ufbx_light_list :: struct {
data: **ufbx_light;
count: size_t;
}
ufbx_camera_list :: struct {
data: **ufbx_camera;
count: size_t;
}
ufbx_bone_list :: struct {
data: **ufbx_bone;
count: size_t;
}
ufbx_empty_list :: struct {
data: **ufbx_empty;
count: size_t;
}
ufbx_line_curve_list :: struct {
data: **ufbx_line_curve;
count: size_t;
}
ufbx_nurbs_curve_list :: struct {
data: **ufbx_nurbs_curve;
count: size_t;
}
ufbx_nurbs_surface_list :: struct {
data: **ufbx_nurbs_surface;
count: size_t;
}
ufbx_nurbs_trim_surface_list :: struct {
data: **ufbx_nurbs_trim_surface;
count: size_t;
}
ufbx_nurbs_trim_boundary_list :: struct {
data: **ufbx_nurbs_trim_boundary;
count: size_t;
}
ufbx_procedural_geometry_list :: struct {
data: **ufbx_procedural_geometry;
count: size_t;
}
ufbx_stereo_camera_list :: struct {
data: **ufbx_stereo_camera;
count: size_t;
}
ufbx_camera_switcher_list :: struct {
data: **ufbx_camera_switcher;
count: size_t;
}
ufbx_marker_list :: struct {
data: **ufbx_marker;
count: size_t;
}
ufbx_lod_group_list :: struct {
data: **ufbx_lod_group;
count: size_t;
}
ufbx_skin_deformer_list :: struct {
data: **ufbx_skin_deformer;
count: size_t;
}
ufbx_skin_cluster_list :: struct {
data: **ufbx_skin_cluster;
count: size_t;
}
ufbx_blend_deformer_list :: struct {
data: **ufbx_blend_deformer;
count: size_t;
}
ufbx_blend_channel_list :: struct {
data: **ufbx_blend_channel;
count: size_t;
}
ufbx_blend_shape_list :: struct {
data: **ufbx_blend_shape;
count: size_t;
}
ufbx_cache_deformer_list :: struct {
data: **ufbx_cache_deformer;
count: size_t;
}
ufbx_cache_file_list :: struct {
data: **ufbx_cache_file;
count: size_t;
}
ufbx_material_list :: struct {
data: **ufbx_material;
count: size_t;
}
ufbx_texture_list :: struct {
data: **ufbx_texture;
count: size_t;
}
ufbx_video_list :: struct {
data: **ufbx_video;
count: size_t;
}
ufbx_shader_list :: struct {
data: **ufbx_shader;
count: size_t;
}
ufbx_shader_binding_list :: struct {
data: **ufbx_shader_binding;
count: size_t;
}
ufbx_anim_stack_list :: struct {
data: **ufbx_anim_stack;
count: size_t;
}
ufbx_anim_layer_list :: struct {
data: **ufbx_anim_layer;
count: size_t;
}
ufbx_anim_value_list :: struct {
data: **ufbx_anim_value;
count: size_t;
}
ufbx_anim_curve_list :: struct {
data: **ufbx_anim_curve;
count: size_t;
}
ufbx_display_layer_list :: struct {
data: **ufbx_display_layer;
count: size_t;
}
ufbx_selection_set_list :: struct {
data: **ufbx_selection_set;
count: size_t;
}
ufbx_selection_node_list :: struct {
data: **ufbx_selection_node;
count: size_t;
}
ufbx_character_list :: struct {
data: **ufbx_character;
count: size_t;
}
ufbx_constraint_list :: struct {
data: **ufbx_constraint;
count: size_t;
}
ufbx_pose_list :: struct {
data: **ufbx_pose;
count: size_t;
}
ufbx_metadata_object_list :: struct {
data: **ufbx_metadata_object;
count: size_t;
}
ufbx_element_type :: enum s32 {
UNKNOWN :: 0;
NODE :: 1;
MESH :: 2;
LIGHT :: 3;
CAMERA :: 4;
BONE :: 5;
EMPTY :: 6;
LINE_CURVE :: 7;
NURBS_CURVE :: 8;
NURBS_SURFACE :: 9;
NURBS_TRIM_SURFACE :: 10;
NURBS_TRIM_BOUNDARY :: 11;
PROCEDURAL_GEOMETRY :: 12;
STEREO_CAMERA :: 13;
CAMERA_SWITCHER :: 14;
MARKER :: 15;
LOD_GROUP :: 16;
SKIN_DEFORMER :: 17;
SKIN_CLUSTER :: 18;
BLEND_DEFORMER :: 19;
BLEND_CHANNEL :: 20;
BLEND_SHAPE :: 21;
CACHE_DEFORMER :: 22;
CACHE_FILE :: 23;
MATERIAL :: 24;
TEXTURE :: 25;
VIDEO :: 26;
SHADER :: 27;
SHADER_BINDING :: 28;
ANIM_STACK :: 29;
ANIM_LAYER :: 30;
ANIM_VALUE :: 31;
ANIM_CURVE :: 32;
DISPLAY_LAYER :: 33;
SELECTION_SET :: 34;
SELECTION_NODE :: 35;
CHARACTER :: 36;
CONSTRAINT :: 37;
POSE :: 38;
METADATA_OBJECT :: 39;
TYPE_FIRST_ATTRIB :: 2;
TYPE_LAST_ATTRIB :: 16;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_ELEMENT_UNKNOWN :: UNKNOWN;
UFBX_ELEMENT_NODE :: NODE;
UFBX_ELEMENT_MESH :: MESH;
UFBX_ELEMENT_LIGHT :: LIGHT;
UFBX_ELEMENT_CAMERA :: CAMERA;
UFBX_ELEMENT_BONE :: BONE;
UFBX_ELEMENT_EMPTY :: EMPTY;
UFBX_ELEMENT_LINE_CURVE :: LINE_CURVE;
UFBX_ELEMENT_NURBS_CURVE :: NURBS_CURVE;
UFBX_ELEMENT_NURBS_SURFACE :: NURBS_SURFACE;
UFBX_ELEMENT_NURBS_TRIM_SURFACE :: NURBS_TRIM_SURFACE;
UFBX_ELEMENT_NURBS_TRIM_BOUNDARY :: NURBS_TRIM_BOUNDARY;
UFBX_ELEMENT_PROCEDURAL_GEOMETRY :: PROCEDURAL_GEOMETRY;
UFBX_ELEMENT_STEREO_CAMERA :: STEREO_CAMERA;
UFBX_ELEMENT_CAMERA_SWITCHER :: CAMERA_SWITCHER;
UFBX_ELEMENT_MARKER :: MARKER;
UFBX_ELEMENT_LOD_GROUP :: LOD_GROUP;
UFBX_ELEMENT_SKIN_DEFORMER :: SKIN_DEFORMER;
UFBX_ELEMENT_SKIN_CLUSTER :: SKIN_CLUSTER;
UFBX_ELEMENT_BLEND_DEFORMER :: BLEND_DEFORMER;
UFBX_ELEMENT_BLEND_CHANNEL :: BLEND_CHANNEL;
UFBX_ELEMENT_BLEND_SHAPE :: BLEND_SHAPE;
UFBX_ELEMENT_CACHE_DEFORMER :: CACHE_DEFORMER;
UFBX_ELEMENT_CACHE_FILE :: CACHE_FILE;
UFBX_ELEMENT_MATERIAL :: MATERIAL;
UFBX_ELEMENT_TEXTURE :: TEXTURE;
UFBX_ELEMENT_VIDEO :: VIDEO;
UFBX_ELEMENT_SHADER :: SHADER;
UFBX_ELEMENT_SHADER_BINDING :: SHADER_BINDING;
UFBX_ELEMENT_ANIM_STACK :: ANIM_STACK;
UFBX_ELEMENT_ANIM_LAYER :: ANIM_LAYER;
UFBX_ELEMENT_ANIM_VALUE :: ANIM_VALUE;
UFBX_ELEMENT_ANIM_CURVE :: ANIM_CURVE;
UFBX_ELEMENT_DISPLAY_LAYER :: DISPLAY_LAYER;
UFBX_ELEMENT_SELECTION_SET :: SELECTION_SET;
UFBX_ELEMENT_SELECTION_NODE :: SELECTION_NODE;
UFBX_ELEMENT_CHARACTER :: CHARACTER;
UFBX_ELEMENT_CONSTRAINT :: CONSTRAINT;
UFBX_ELEMENT_POSE :: POSE;
UFBX_ELEMENT_METADATA_OBJECT :: METADATA_OBJECT;
UFBX_ELEMENT_TYPE_FIRST_ATTRIB :: TYPE_FIRST_ATTRIB;
UFBX_ELEMENT_TYPE_LAST_ATTRIB :: TYPE_LAST_ATTRIB;
UFBX_ELEMENT_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_3 :: enum s32 {
UFBX_ELEMENT_TYPE_COUNT :: 40;
}
// Connection between two elements.
// Source and destination are somewhat arbitrary but the destination is
// often the "container" like a parent node or mesh containing a deformer.
ufbx_connection :: struct {
src: *ufbx_element;
dst: *ufbx_element;
src_prop: ufbx_string;
dst_prop: ufbx_string;
}
ufbx_connection_list :: struct {
data: *ufbx_connection;
count: size_t;
}
// Element "base-class" common to each element.
// Some fields (like `connections_src`) are advanced and not visible
// in the specialized element structs.
// NOTE: The `element_id` value is consistent when loading the
// _same_ file, but re-exporting the file will invalidate them. (TOMOVE)
ufbx_element :: struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
type: ufbx_element_type;
connections_src: ufbx_connection_list;
connections_dst: ufbx_connection_list;
dom_node: *ufbx_dom_node;
scene: *ufbx_scene;
}
// -- Unknown
ufbx_unknown :: struct {
// Shared "base-class" header, see `ufbx_element`.
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// FBX format specific type information.
// In ASCII FBX format:
// super_type: ID, "type::name", "sub_type" { ... }
type: ufbx_string;
super_type: ufbx_string;
sub_type: ufbx_string;
}
// Inherit type specifies how hierarchial node transforms are combined.
// `UFBX_INHERIT_NORMAL` is combined using the "proper" multiplication
// `UFBX_INHERIT_NO_SHEAR` does component-wise { pos+pos, rot*rot, scale*scale }
// `UFBX_INHERIT_NO_SCALE` ignores the parent scale { pos+pos, rot*rot, scale }
ufbx_inherit_type :: enum s32 {
NO_SHEAR :: 0;
NORMAL :: 1;
NO_SCALE :: 2;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_INHERIT_NO_SHEAR :: NO_SHEAR;
UFBX_INHERIT_NORMAL :: NORMAL;
UFBX_INHERIT_NO_SCALE :: NO_SCALE;
UFBX_INHERIT_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_4 :: enum s32 {
UFBX_INHERIT_TYPE_COUNT :: 3;
}
// Nodes form the scene transformation hierarchy and can contain attached
// elements such as meshes or lights. In normal cases a single `ufbx_node`
// contains only a single attached element, so using `type/mesh/...` is safe.
ufbx_node :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Parent node containing this one if not root.
//
// Always non-`NULL` for non-root nodes unless
// `ufbx_load_opts.allow_nodes_out_of_root` is enabled.
parent: *ufbx_node;
// List of child nodes parented to this node.
children: ufbx_node_list;
// Attached element type and typed pointers.
//
// Set to `NULL` if not in use, so checking `attrib_type` is not required.
mesh: *ufbx_mesh;
light: *ufbx_light;
camera: *ufbx_camera;
bone: *ufbx_bone;
// Less common attributes use these fields.
//
// Defined even if it is one of the above, eg. `ufbx_mesh`. In case there
// is multiple attributes this will be the first one.
attrib: *ufbx_element;
// Geometry transform helper if one exists.
// See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`.
geometry_transform_helper: *ufbx_node;
// `attrib->type` if `attrib` is defined, otherwise `UFBX_ELEMENT_UNKNOWN`.
attrib_type: ufbx_element_type;
// List of _all_ attached attribute elements.
//
// In most cases there is only zero or one attributes per node, but if you
// have a very exotic FBX file nodes may have multiple attributes.
all_attribs: ufbx_element_list;
// Local transform in parent, geometry transform is a non-inherited
// transform applied only to attachments like meshes
inherit_type: ufbx_inherit_type;
local_transform: ufbx_transform #align 4;
geometry_transform: ufbx_transform;
// Specifies the axis order `euler_rotation` is applied in.
rotation_order: ufbx_rotation_order;
// Rotation around the local X/Y/Z axes in `rotation_order`.
// The angles are specified in degrees.
euler_rotation: ufbx_vec3 #align 4;
// Transform to the global "world" space, may be incorrect if the node
// uses `UFBX_INHERIT_NORMAL`, prefer using the `node_to_world` matrix.
world_transform: ufbx_transform;
// Transform from this node to `parent` space.
// Equivalent to `ufbx_transform_to_matrix(&local_transform)`.
node_to_parent: ufbx_matrix;
// Transform from this node to the world space, ie. multiplying all the
// `node_to_parent` matrices of the parent chain together.
// NOTE: Not the same as `ufbx_transform_to_matrix(&world_transform)`
// as this matrix will account for potential shear (if `inherit_type == UFBX_INHERIT_NORMAL`).
node_to_world: ufbx_matrix;
// Transform from the attribute to this node. Does not affect the transforms
// of `children`!
// Equivalent to `ufbx_transform_to_matrix(&geometry_transform)`.
geometry_to_node: ufbx_matrix;
// Transform from attribute space to world space.
// Equivalent to `ufbx_matrix_mul(&node_to_world, &geometry_to_node)`.
geometry_to_world: ufbx_matrix;
adjust_pre_rotation: ufbx_quat; // < Rotation applied between parent and self
adjust_pre_scale: ufbx_vec3; // < Scaling applied between parent and self
adjust_post_rotation: ufbx_quat; // < Rotation applied in local space at the end
// Materials used by `mesh` or other `attrib`.
// There may be multiple copies of a single `ufbx_mesh` with different materials
// in the `ufbx_node` instances.
materials: ufbx_material_list;
// Visibility state.
visible: bool;
// True if this node is the implicit root node of the scene.
is_root: bool;
// True if the node has a non-identity `geometry_transform`.
has_geometry_transform: bool;
// If `true` the transform is adjusted by ufbx, not enabled by default.
// See `adjust_pre_rotation`, `adjust_pre_scale`, `adjust_post_rotation`.
has_adjust_transform: bool;
// True if this node is node is a synthetic geometry transform helper.
// See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`.
is_geometry_transform_helper: bool;
// How deep is this node in the parent hierarchy. Root node is at depth `0`
// and the immediate children of root at `1`.
node_depth: u32;
}
// Vertex attribute: All attributes are stored in a consistent indexed format
// regardless of how it's actually stored in the file.
//
// `values` is a contiguous array of attribute values.
// `indices` maps each mesh index into a value in the `values` array.
//
// If `unique_per_vertex` is set then the attribute is guaranteed to have a
// single defined value per vertex accessible via:
// attrib.values.data[attrib.indices.data[mesh->vertex_first_index[vertex_ix]]
ufbx_vertex_attrib :: struct {
exists: bool;
values: ufbx_void_list;
indices: ufbx_uint32_list;
value_reals: size_t;
unique_per_vertex: bool;
}
// 1D vertex attribute, see `ufbx_vertex_attrib` for information
ufbx_vertex_real :: struct {
exists: bool;
values: ufbx_real_list;
indices: ufbx_uint32_list;
value_reals: size_t;
unique_per_vertex: bool;
}
// 2D vertex attribute, see `ufbx_vertex_attrib` for information
ufbx_vertex_vec2 :: struct {
exists: bool;
values: ufbx_vec2_list;
indices: ufbx_uint32_list;
value_reals: size_t;
unique_per_vertex: bool;
}
// 3D vertex attribute, see `ufbx_vertex_attrib` for information
ufbx_vertex_vec3 :: struct {
exists: bool;
values: ufbx_vec3_list;
indices: ufbx_uint32_list;
value_reals: size_t;
unique_per_vertex: bool;
}
// 4D vertex attribute, see `ufbx_vertex_attrib` for information
ufbx_vertex_vec4 :: struct {
exists: bool;
values: ufbx_vec4_list;
indices: ufbx_uint32_list;
value_reals: size_t;
unique_per_vertex: bool;
}
// Vertex UV set/layer
ufbx_uv_set :: struct {
name: ufbx_string;
index: u32;
vertex_uv: ufbx_vertex_vec2; // < UV / texture coordinates
vertex_tangent: ufbx_vertex_vec3; // < (optional) Tangent vector in UV.x direction
vertex_bitangent: ufbx_vertex_vec3; // < (optional) Tangent vector in UV.y direction
}
// Vertex color set/layer
ufbx_color_set :: struct {
name: ufbx_string;
index: u32;
vertex_color: ufbx_vertex_vec4; // < Per-vertex RGBA color
}
ufbx_uv_set_list :: struct {
data: *ufbx_uv_set;
count: size_t;
}
ufbx_color_set_list :: struct {
data: *ufbx_color_set;
count: size_t;
}
// Edge between two _indices_ in a mesh
ufbx_edge :: struct {
union {
struct {
a: u32;
b: u32;
}
indices: [2] u32;
}
}
ufbx_edge_list :: struct {
data: *ufbx_edge;
count: size_t;
}
// Polygonal face with arbitrary number vertices, a single face contains a
// contiguous range of mesh indices, eg. `{5,3}` would have indices 5, 6, 7
//
// NOTE: `num_indices` maybe less than 3 in which case the face is invalid!
// [TODO #23: should probably remove the bad faces at load time]
ufbx_face :: struct {
index_begin: u32;
num_indices: u32;
}
ufbx_face_list :: struct {
data: *ufbx_face;
count: size_t;
}
ufbx_mesh_material :: struct {
material: *ufbx_material;
num_faces: size_t; // < Number of faces (polygons) using this material
num_triangles: size_t; // < Number of triangles using this material if triangulated
num_empty_faces: size_t; // < Number of faces with zero vertices
num_point_faces: size_t; // < Number of faces with a single vertex
num_line_faces: size_t; // < Number of faces with two vertices
// Indices to `ufbx_mesh.faces[]` that use this material.
// Always contains `num_faces` elements.
face_indices: ufbx_uint32_list;
}
ufbx_mesh_material_list :: struct {
data: *ufbx_mesh_material;
count: size_t;
}
ufbx_face_group :: struct {
id: s32; // < Numerical ID for this group.
name: ufbx_string; // < Name for the face group.
num_faces: size_t; // < Number of faces (polygons) using this material
num_triangles: size_t; // < Number of triangles using this material if triangulated
// Indices to `ufbx_mesh.faces[]` that use this material.
// Always contains `num_faces` elements.
face_indices: ufbx_uint32_list;
}
ufbx_face_group_list :: struct {
data: *ufbx_face_group;
count: size_t;
}
ufbx_subdivision_weight_range :: struct {
weight_begin: u32;
num_weights: u32;
}
ufbx_subdivision_weight_range_list :: struct {
data: *ufbx_subdivision_weight_range;
count: size_t;
}
ufbx_subdivision_weight :: struct {
weight: ufbx_real;
index: u32;
}
ufbx_subdivision_weight_list :: struct {
data: *ufbx_subdivision_weight;
count: size_t;
}
ufbx_subdivision_result :: struct {
result_memory_used: size_t;
temp_memory_used: size_t;
result_allocs: size_t;
temp_allocs: size_t;
// Weights of vertices in the source model.
// Defined if `ufbx_subdivide_opts.evaluate_source_vertices` is set.
source_vertex_ranges: ufbx_subdivision_weight_range_list;
source_vertex_weights: ufbx_subdivision_weight_list;
// Weights of skin clusters in the source model.
// Defined if `ufbx_subdivide_opts.evaluate_skin_weights` is set.
skin_cluster_ranges: ufbx_subdivision_weight_range_list;
skin_cluster_weights: ufbx_subdivision_weight_list;
}
ufbx_subdivision_display_mode :: enum s32 {
DISABLED :: 0;
HULL :: 1;
HULL_AND_SMOOTH :: 2;
SMOOTH :: 3;
MODE_FORCE_32BIT :: 2147483647;
UFBX_SUBDIVISION_DISPLAY_DISABLED :: DISABLED;
UFBX_SUBDIVISION_DISPLAY_HULL :: HULL;
UFBX_SUBDIVISION_DISPLAY_HULL_AND_SMOOTH :: HULL_AND_SMOOTH;
UFBX_SUBDIVISION_DISPLAY_SMOOTH :: SMOOTH;
UFBX_SUBDIVISION_DISPLAY_MODE_FORCE_32BIT :: MODE_FORCE_32BIT;
}
anon_enum_5 :: enum s32 {
UFBX_SUBDIVISION_DISPLAY_MODE_COUNT :: 4;
}
ufbx_subdivision_boundary :: enum s32 {
DEFAULT :: 0;
LEGACY :: 1;
SHARP_CORNERS :: 2;
SHARP_NONE :: 3;
SHARP_BOUNDARY :: 4;
SHARP_INTERIOR :: 5;
FORCE_32BIT :: 2147483647;
UFBX_SUBDIVISION_BOUNDARY_DEFAULT :: DEFAULT;
UFBX_SUBDIVISION_BOUNDARY_LEGACY :: LEGACY;
UFBX_SUBDIVISION_BOUNDARY_SHARP_CORNERS :: SHARP_CORNERS;
UFBX_SUBDIVISION_BOUNDARY_SHARP_NONE :: SHARP_NONE;
UFBX_SUBDIVISION_BOUNDARY_SHARP_BOUNDARY :: SHARP_BOUNDARY;
UFBX_SUBDIVISION_BOUNDARY_SHARP_INTERIOR :: SHARP_INTERIOR;
UFBX_SUBDIVISION_BOUNDARY_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_6 :: enum s32 {
UFBX_SUBDIVISION_BOUNDARY_COUNT :: 6;
}
// Polygonal mesh geometry.
//
// Example mesh with two triangles (x, z) and a quad (y).
// The faces have a constant UV coordinate x/y/z.
// The vertices have _per vertex_ normals that point up/down.
//
// ^ ^ ^
// A---B-----C
// |x / /|
// | / y / |
// |/ / z|
// D-----E---F
// v v v
//
// Attributes may have multiple values within a single vertex, for example a
// UV seam vertex has two UV coordinates. Thus polygons are defined using
// an index that counts each corner of each face polygon. If an attribute is
// defined (even per-vertex) it will always have a valid `indices` array.
//
// {0,3} {3,4} {7,3} faces ({ index_begin, num_indices })
// 0 1 2 3 4 5 6 7 8 9 index
//
// 0 1 3 1 2 4 3 2 4 5 vertex_indices[index]
// A B D B C E D C E F vertices[vertex_indices[index]]
//
// 0 0 1 0 0 1 1 0 1 1 vertex_normal.indices[index]
// ^ ^ v ^ ^ v v ^ v v vertex_normal.data[vertex_normal.indices[index]]
//
// 0 0 0 1 1 1 1 2 2 2 vertex_uv.indices[index]
// x x x y y y y z z z vertex_uv.data[vertex_uv.indices[index]]
//
// Vertex position can also be accessed uniformly through an accessor:
// 0 1 3 1 2 4 3 2 4 5 vertex_position.indices[index]
// A B D B C E D C E F vertex_position.data[vertex_position.indices[index]]
//
// Some geometry data is specified per logical vertex. Vertex positions are
// the only attribute that is guaranteed to be defined _uniquely_ per vertex.
// Vertex attributes _may_ be defined per vertex if `unique_per_vertex == true`.
// You can access the per-vertex values by first finding the first index that
// refers to the given vertex.
//
// 0 1 2 3 4 5 vertex
// A B C D E F vertices[vertex]
//
// 0 1 4 2 5 9 vertex_first_index[vertex]
// 0 0 0 1 1 1 vertex_normal.indices[vertex_first_index[vertex]]
// ^ ^ ^ v v v vertex_normal.data[vertex_normal.indices[vertex_first_index[vertex]]]
//
ufbx_mesh :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
num_vertices: size_t; // < Number of logical "vertex" points
num_indices: size_t; // < Number of combiend vertex/attribute tuples
num_faces: size_t; // < Number of faces (polygons) in the mesh
num_triangles: size_t; // < Number of triangles if triangulated
// Number of edges in the mesh.
// NOTE: May be zero in valid meshes if the file doesn't contain edge adjacency data!
num_edges: size_t;
max_face_triangles: size_t; // < Maximum number of triangles in a face in this mesh
num_empty_faces: size_t; // < Number of faces with zero vertices
num_point_faces: size_t; // < Number of faces with a single vertex
num_line_faces: size_t; // < Number of faces with two vertices
faces: ufbx_face_list; // < Face index range
face_smoothing: ufbx_bool_list; // < Should the face have soft normals
face_material: ufbx_uint32_list; // < Indices to `ufbx_mesh.materials[]` and `ufbx_node.materials[]`
face_group: ufbx_uint32_list; // < Face polygon group index, indices to `ufbx_mesh.face_groups[]`
face_hole: ufbx_bool_list; // < Should the face be hidden as a "hole"
edges: ufbx_edge_list; // < Edge index range
edge_smoothing: ufbx_bool_list; // < Should the edge have soft normals
edge_crease: ufbx_real_list; // < Crease value for subdivision surfaces
edge_visibility: ufbx_bool_list; // < Should the edge be visible
// Logical vertices and positions, alternatively you can use
// `vertex_position` for consistent interface with other attributes.
vertex_indices: ufbx_uint32_list;
vertices: ufbx_vec3_list;
// First index referring to a given vertex, `UFBX_NO_INDEX` if the vertex is unused.
vertex_first_index: ufbx_uint32_list;
vertex_position: ufbx_vertex_vec3; // < Vertex positions
vertex_normal: ufbx_vertex_vec3; // < (optional) Normal vectors (TODO: Generate?)
vertex_uv: ufbx_vertex_vec2; // < (optional) UV / texture coordinates
vertex_tangent: ufbx_vertex_vec3; // < (optional) Tangent vector in UV.x direction
vertex_bitangent: ufbx_vertex_vec3; // < (optional) Tangent vector in UV.y direction
vertex_color: ufbx_vertex_vec4; // < (optional) Per-vertex RGBA color
vertex_crease: ufbx_vertex_real; // < (optional) Crease value for subdivision surfaces
// Multiple named UV/color sets
// NOTE: The first set contains the same data as `vertex_uv/color`!
uv_sets: ufbx_uv_set_list;
color_sets: ufbx_color_set_list;
// List of materials used by the mesh. This is a list of structures that contains
// compact lists of face indices that use a specific material which can be more
// useful convenient `face_material`. Use `materials[index].material` for the
// actual material pointers.
// NOTE: These can be wrong if you want to support per-instance materials!
// Use `ufbx_node.materials[]` to get the per-instance materials at the same indices.
// HINT: If this mesh has no material then `materials[]` will be empty, but if
// you enable `ufbx_load_opts.allow_null_material` there will be a single
// `ufbx_mesh_material` with `material == NULL` with all the faces in it.
materials: ufbx_mesh_material_list;
// Face groups for this mesh.
face_groups: ufbx_face_group_list;
// Skinned vertex positions, for efficiency the skinned positions are the
// same as the static ones for non-skinned meshes and `skinned_is_local`
// is set to true meaning you need to transform them manually using
// `ufbx_transform_position(&node->geometry_to_world, skinned_pos)`!
skinned_is_local: bool;
skinned_position: ufbx_vertex_vec3;
skinned_normal: ufbx_vertex_vec3;
// Deformers
skin_deformers: ufbx_skin_deformer_list;
blend_deformers: ufbx_blend_deformer_list;
cache_deformers: ufbx_cache_deformer_list;
all_deformers: ufbx_element_list;
// Subdivision
subdivision_preview_levels: u32;
subdivision_render_levels: u32;
subdivision_display_mode: ufbx_subdivision_display_mode;
subdivision_boundary: ufbx_subdivision_boundary;
subdivision_uv_boundary: ufbx_subdivision_boundary;
// Normals have been generated instead of evalauted.
// Either from missing normals (via `ufbx_load_opts.generate_missing_normals`), skinning,
// tessellation, or subdivision.
generated_normals: bool;
// Subdivision (result)
subdivision_evaluated: bool;
subdivision_result: *ufbx_subdivision_result;
// Tessellation (result)
from_tessellated_nurbs: bool;
}
// The kind of light source
ufbx_light_type :: enum s32 {
POINT :: 0;
DIRECTIONAL :: 1;
SPOT :: 2;
AREA :: 3;
VOLUME :: 4;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_LIGHT_POINT :: POINT;
UFBX_LIGHT_DIRECTIONAL :: DIRECTIONAL;
UFBX_LIGHT_SPOT :: SPOT;
UFBX_LIGHT_AREA :: AREA;
UFBX_LIGHT_VOLUME :: VOLUME;
UFBX_LIGHT_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_7 :: enum s32 {
UFBX_LIGHT_TYPE_COUNT :: 5;
}
// How fast does the light intensity decay at a distance
ufbx_light_decay :: enum s32 {
NONE :: 0;
LINEAR :: 1;
QUADRATIC :: 2;
CUBIC :: 3;
FORCE_32BIT :: 2147483647;
UFBX_LIGHT_DECAY_NONE :: NONE;
UFBX_LIGHT_DECAY_LINEAR :: LINEAR;
UFBX_LIGHT_DECAY_QUADRATIC :: QUADRATIC;
UFBX_LIGHT_DECAY_CUBIC :: CUBIC;
UFBX_LIGHT_DECAY_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_8 :: enum s32 {
UFBX_LIGHT_DECAY_COUNT :: 4;
}
ufbx_light_area_shape :: enum s32 {
RECTANGLE :: 0;
SPHERE :: 1;
FORCE_32BIT :: 2147483647;
UFBX_LIGHT_AREA_SHAPE_RECTANGLE :: RECTANGLE;
UFBX_LIGHT_AREA_SHAPE_SPHERE :: SPHERE;
UFBX_LIGHT_AREA_SHAPE_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_9 :: enum s32 {
UFBX_LIGHT_AREA_SHAPE_COUNT :: 2;
}
// Light source attached to a `ufbx_node`
ufbx_light :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
// Color and intensity of the light, usually you want to use `color * intensity`
// NOTE: `intensity` is 0.01x of the property `"Intensity"` as that matches
// matches values in DCC programs before exporting.
color: ufbx_vec3;
intensity: ufbx_real;
// Direction the light is aimed at in node's local space, usually -Y
local_direction: ufbx_vec3;
// Type of the light and shape parameters
type: ufbx_light_type;
decay: ufbx_light_decay;
area_shape: ufbx_light_area_shape;
inner_angle: ufbx_real;
outer_angle: ufbx_real;
cast_light: bool;
cast_shadows: bool;
}
ufbx_projection_mode :: enum s32 {
PERSPECTIVE :: 0;
ORTHOGRAPHIC :: 1;
FORCE_32BIT :: 2147483647;
UFBX_PROJECTION_MODE_PERSPECTIVE :: PERSPECTIVE;
UFBX_PROJECTION_MODE_ORTHOGRAPHIC :: ORTHOGRAPHIC;
UFBX_PROJECTION_MODE_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_10 :: enum s32 {
UFBX_PROJECTION_MODE_COUNT :: 2;
}
// Method of specifying the rendering resolution from properties
// NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly!
ufbx_aspect_mode :: enum s32 {
WINDOW_SIZE :: 0;
FIXED_RATIO :: 1;
FIXED_RESOLUTION :: 2;
FIXED_WIDTH :: 3;
FIXED_HEIGHT :: 4;
FORCE_32BIT :: 2147483647;
UFBX_ASPECT_MODE_WINDOW_SIZE :: WINDOW_SIZE;
UFBX_ASPECT_MODE_FIXED_RATIO :: FIXED_RATIO;
UFBX_ASPECT_MODE_FIXED_RESOLUTION :: FIXED_RESOLUTION;
UFBX_ASPECT_MODE_FIXED_WIDTH :: FIXED_WIDTH;
UFBX_ASPECT_MODE_FIXED_HEIGHT :: FIXED_HEIGHT;
UFBX_ASPECT_MODE_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_11 :: enum s32 {
UFBX_ASPECT_MODE_COUNT :: 5;
}
// Method of specifying the field of view from properties
// NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly!
ufbx_aperture_mode :: enum s32 {
HORIZONTAL_AND_VERTICAL :: 0;
HORIZONTAL :: 1;
VERTICAL :: 2;
FOCAL_LENGTH :: 3;
FORCE_32BIT :: 2147483647;
UFBX_APERTURE_MODE_HORIZONTAL_AND_VERTICAL :: HORIZONTAL_AND_VERTICAL;
UFBX_APERTURE_MODE_HORIZONTAL :: HORIZONTAL;
UFBX_APERTURE_MODE_VERTICAL :: VERTICAL;
UFBX_APERTURE_MODE_FOCAL_LENGTH :: FOCAL_LENGTH;
UFBX_APERTURE_MODE_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_12 :: enum s32 {
UFBX_APERTURE_MODE_COUNT :: 4;
}
// Method of specifying the render gate size from properties
// NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly!
ufbx_gate_fit :: enum s32 {
NONE :: 0;
VERTICAL :: 1;
HORIZONTAL :: 2;
FILL :: 3;
OVERSCAN :: 4;
STRETCH :: 5;
FORCE_32BIT :: 2147483647;
UFBX_GATE_FIT_NONE :: NONE;
UFBX_GATE_FIT_VERTICAL :: VERTICAL;
UFBX_GATE_FIT_HORIZONTAL :: HORIZONTAL;
UFBX_GATE_FIT_FILL :: FILL;
UFBX_GATE_FIT_OVERSCAN :: OVERSCAN;
UFBX_GATE_FIT_STRETCH :: STRETCH;
UFBX_GATE_FIT_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_13 :: enum s32 {
UFBX_GATE_FIT_COUNT :: 6;
}
// Camera film/aperture size defaults
// NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly!
ufbx_aperture_format :: enum s32 {
CUSTOM :: 0;
_16MM_THEATRICAL :: 1;
SUPER_16MM :: 2;
_35MM_ACADEMY :: 3;
_35MM_TV_PROJECTION :: 4;
_35MM_FULL_APERTURE :: 5;
_35MM_185_PROJECTION :: 6;
_35MM_ANAMORPHIC :: 7;
_70MM_PROJECTION :: 8;
VISTAVISION :: 9;
DYNAVISION :: 10;
IMAX :: 11;
FORCE_32BIT :: 2147483647;
UFBX_APERTURE_FORMAT_CUSTOM :: CUSTOM;
UFBX_APERTURE_FORMAT_16MM_THEATRICAL :: _16MM_THEATRICAL;
UFBX_APERTURE_FORMAT_SUPER_16MM :: SUPER_16MM;
UFBX_APERTURE_FORMAT_35MM_ACADEMY :: _35MM_ACADEMY;
UFBX_APERTURE_FORMAT_35MM_TV_PROJECTION :: _35MM_TV_PROJECTION;
UFBX_APERTURE_FORMAT_35MM_FULL_APERTURE :: _35MM_FULL_APERTURE;
UFBX_APERTURE_FORMAT_35MM_185_PROJECTION :: _35MM_185_PROJECTION;
UFBX_APERTURE_FORMAT_35MM_ANAMORPHIC :: _35MM_ANAMORPHIC;
UFBX_APERTURE_FORMAT_70MM_PROJECTION :: _70MM_PROJECTION;
UFBX_APERTURE_FORMAT_VISTAVISION :: VISTAVISION;
UFBX_APERTURE_FORMAT_DYNAVISION :: DYNAVISION;
UFBX_APERTURE_FORMAT_IMAX :: IMAX;
UFBX_APERTURE_FORMAT_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_14 :: enum s32 {
UFBX_APERTURE_FORMAT_COUNT :: 12;
}
ufbx_coordinate_axis :: enum s32 {
POSITIVE_X :: 0;
NEGATIVE_X :: 1;
POSITIVE_Y :: 2;
NEGATIVE_Y :: 3;
POSITIVE_Z :: 4;
NEGATIVE_Z :: 5;
UNKNOWN :: 6;
FORCE_32BIT :: 2147483647;
UFBX_COORDINATE_AXIS_POSITIVE_X :: POSITIVE_X;
UFBX_COORDINATE_AXIS_NEGATIVE_X :: NEGATIVE_X;
UFBX_COORDINATE_AXIS_POSITIVE_Y :: POSITIVE_Y;
UFBX_COORDINATE_AXIS_NEGATIVE_Y :: NEGATIVE_Y;
UFBX_COORDINATE_AXIS_POSITIVE_Z :: POSITIVE_Z;
UFBX_COORDINATE_AXIS_NEGATIVE_Z :: NEGATIVE_Z;
UFBX_COORDINATE_AXIS_UNKNOWN :: UNKNOWN;
UFBX_COORDINATE_AXIS_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_15 :: enum s32 {
UFBX_COORDINATE_AXIS_COUNT :: 7;
}
// Coordinate axes the scene is represented in.
// NOTE: `front` is the _opposite_ from forward!
ufbx_coordinate_axes :: struct {
right: ufbx_coordinate_axis;
up: ufbx_coordinate_axis;
front: ufbx_coordinate_axis;
}
// Camera attached to a `ufbx_node`
ufbx_camera :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
// Projection mode (perspective/orthographic).
projection_mode: ufbx_projection_mode;
// If set to `true`, `resolution` reprensents actual pixel values, otherwise
// it's only useful for its aspect ratio.
resolution_is_pixels: bool;
// Render resolution, either in pixels or arbitrary units, depending on above
resolution: ufbx_vec2 #align 3;
// Horizontal/vertical field of view in degrees
// Valid if `projection_mode == UFBX_PROJECTION_MODE_PERSPECTIVE`.
field_of_view_deg: ufbx_vec2;
// Component-wise `tan(field_of_view_deg)`, also represents the size of the
// proection frustum slice at distance of 1.
// Valid if `projection_mode == UFBX_PROJECTION_MODE_PERSPECTIVE`.
field_of_view_tan: ufbx_vec2;
// Orthographic camera extents.
// Valid if `projection_mode == UFBX_PROJECTION_MODE_ORTHOGRAPHIC`.
orthographic_extent: ufbx_real;
// Orthographic camera size.
// Valid if `projection_mode == UFBX_PROJECTION_MODE_ORTHOGRAPHIC`.
orthographic_size: ufbx_vec2;
// Size of the projection plane at distance 1.
// Equal to `field_of_view_tan` if perspective, `orthographic_size` if orthographic.
projection_plane: ufbx_vec2;
// Aspect ratio of the camera.
aspect_ratio: ufbx_real;
// Near plane of the frustum in units from the camera.
near_plane: ufbx_real;
// Far plane of the frustum in units from the camera.
far_plane: ufbx_real;
// Coordinate system that the projection uses.
// FBX saves cameras with +X forward and +Y up, but you can override this using
// `ufbx_load_opts.target_camera_axes` and it will be reflected here.
projection_axes: ufbx_coordinate_axes;
// Advanced properties used to compute the above
aspect_mode: ufbx_aspect_mode;
aperture_mode: ufbx_aperture_mode;
gate_fit: ufbx_gate_fit;
aperture_format: ufbx_aperture_format;
focal_length_mm: ufbx_real; // < Focal length in millimeters
film_size_inch: ufbx_vec2; // < Film size in inches
aperture_size_inch: ufbx_vec2; // < Aperture/film gate size in inches
squeeze_ratio: ufbx_real; // < Anamoprhic stretch ratio
}
// Bone attached to a `ufbx_node`, provides the logical length of the bone
// but most interesting information is directly in `ufbx_node`.
ufbx_bone :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
// Visual radius of the bone
radius: ufbx_real;
// Length of the bone relative to the distance between two nodes
relative_length: ufbx_real;
// Is the bone a root bone
is_root: bool;
}
// Empty/NULL/locator connected to a node, actual details in `ufbx_node`
ufbx_empty :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
}
// Segment of a `ufbx_line_curve`, indices refer to `ufbx_line_curve.point_indces[]`
ufbx_line_segment :: struct {
index_begin: u32;
num_indices: u32;
}
ufbx_line_segment_list :: struct {
data: *ufbx_line_segment;
count: size_t;
}
ufbx_line_curve :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
color: ufbx_vec3;
control_points: ufbx_vec3_list; // < List of possible values the line passes through
point_indices: ufbx_uint32_list; // < Indices to `control_points[]` the line goes through
segments: ufbx_line_segment_list;
// Tessellation (result)
from_tessellated_nurbs: bool;
}
ufbx_nurbs_topology :: enum s32 {
OPEN :: 0;
PERIODIC :: 1;
CLOSED :: 2;
FORCE_32BIT :: 2147483647;
UFBX_NURBS_TOPOLOGY_OPEN :: OPEN;
UFBX_NURBS_TOPOLOGY_PERIODIC :: PERIODIC;
UFBX_NURBS_TOPOLOGY_CLOSED :: CLOSED;
UFBX_NURBS_TOPOLOGY_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_16 :: enum s32 {
UFBX_NURBS_TOPOLOGY_COUNT :: 3;
}
// NURBS basis functions for an axis
ufbx_nurbs_basis :: struct {
// Number of control points influencing a point on the curve/surface.
// Equal to the degree plus one.
order: u32;
// Topology (periodicity) of the dimension.
topology: ufbx_nurbs_topology;
// Subdivision of the parameter range to control points.
knot_vector: ufbx_real_list;
// Range for the parameter value.
t_min: ufbx_real;
t_max: ufbx_real;
// Parameter values of control points.
spans: ufbx_real_list;
// `true` if this axis is two-dimensional.
is_2d: bool;
// Number of control points that need to be copied to the end.
// This is just for convenience as it could be derived from `topology` and
// `order`. If for example `num_wrap_control_points == 3` you should repeat
// the first 3 control points after the end.
// HINT: You don't need to worry about this if you use ufbx functions
// like `ufbx_evaluate_nurbs_curve_point()` as they handle this internally.
num_wrap_control_points: size_t;
// `true` if the parametrization is well defined.
valid: bool;
}
ufbx_nurbs_curve :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
// Basis in the U axis
basis: ufbx_nurbs_basis;
// Linear array of control points
// NOTE: The control points are _not_ homogeneous, meaning you have to multiply
// them by `w` before evaluating the surface.
control_points: ufbx_vec4_list;
}
ufbx_nurbs_surface :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
// Basis in the U/V axes
basis_u: ufbx_nurbs_basis;
basis_v: ufbx_nurbs_basis;
// Number of control points for the U/V axes
num_control_points_u: size_t;
num_control_points_v: size_t;
// 2D array of control points.
// Memory layout: `V * num_control_points_u + U`
// NOTE: The control points are _not_ homogeneous, meaning you have to multiply
// them by `w` before evaluating the surface.
control_points: ufbx_vec4_list;
// How many segments tessellate each step in `ufbx_nurbs_basis.steps`.
span_subdivision_u: u32;
span_subdivision_v: u32;
// If `true` the resulting normals should be flipped when evaluated.
flip_normals: bool;
// Material for the whole surface.
// NOTE: May be `NULL`!
material: *ufbx_material;
}
ufbx_nurbs_trim_surface :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
}
ufbx_nurbs_trim_boundary :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
}
// -- Node attributes (advanced)
ufbx_procedural_geometry :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
}
ufbx_stereo_camera :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
left: *ufbx_camera;
right: *ufbx_camera;
}
ufbx_camera_switcher :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
}
ufbx_marker_type :: enum s32 {
UNKNOWN :: 0;
FK_EFFECTOR :: 1;
IK_EFFECTOR :: 2;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_MARKER_UNKNOWN :: UNKNOWN;
UFBX_MARKER_FK_EFFECTOR :: FK_EFFECTOR;
UFBX_MARKER_IK_EFFECTOR :: IK_EFFECTOR;
UFBX_MARKER_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_17 :: enum s32 {
UFBX_MARKER_TYPE_COUNT :: 3;
}
// Tracking marker for effectors
ufbx_marker :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
// Type of the marker
type: ufbx_marker_type;
}
// LOD level display mode.
ufbx_lod_display :: enum s32 {
USE_LOD :: 0;
SHOW :: 1;
HIDE :: 2;
FORCE_32BIT :: 2147483647;
UFBX_LOD_DISPLAY_USE_LOD :: USE_LOD;
UFBX_LOD_DISPLAY_SHOW :: SHOW;
UFBX_LOD_DISPLAY_HIDE :: HIDE;
UFBX_LOD_DISPLAY_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_18 :: enum s32 {
UFBX_LOD_DISPLAY_COUNT :: 3;
}
// Single LOD level within an LOD group.
// Specifies properties of the Nth child of the _node_ containing the LOD group.
ufbx_lod_level :: struct {
// Minimum distance to show this LOD level.
// NOTE: In world units by default, or in screen percentage if
// `ufbx_lod_group.relative_thresholds` is set.
distance: ufbx_real;
// LOD display mode.
// NOTE: Mostly for editing, you should probably ignore this
// unless making a modeling program.
display: ufbx_lod_display;
}
ufbx_lod_level_list :: struct {
data: *ufbx_lod_level;
count: size_t;
}
// Group of LOD (Level of Detail) levels for an object.
// The actual LOD models are defined in the parent `ufbx_node.children`.
ufbx_lod_group :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
instances: ufbx_node_list;
}
}
// If set to `true`, `ufbx_lod_level.distance` represents a screen size percentage.
relative_distances: bool;
// LOD levels matching in order to `ufbx_node.children`.
lod_levels: ufbx_lod_level_list;
// If set to `true` don't account for parent transform when computing the distance.
ignore_parent_transform: bool;
// If `use_distance_limit` is enabled hide the group if the distance is not between
// `distance_limit_min` and `distance_limit_max`.
use_distance_limit: bool;
distance_limit_min: ufbx_real;
distance_limit_max: ufbx_real;
}
// Method to evaluate the skinning on a per-vertex level
ufbx_skinning_method :: enum s32 {
LINEAR :: 0;
RIGID :: 1;
DUAL_QUATERNION :: 2;
BLENDED_DQ_LINEAR :: 3;
FORCE_32BIT :: 2147483647;
UFBX_SKINNING_METHOD_LINEAR :: LINEAR;
UFBX_SKINNING_METHOD_RIGID :: RIGID;
UFBX_SKINNING_METHOD_DUAL_QUATERNION :: DUAL_QUATERNION;
UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR :: BLENDED_DQ_LINEAR;
UFBX_SKINNING_METHOD_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_19 :: enum s32 {
UFBX_SKINNING_METHOD_COUNT :: 4;
}
// Skin weight information for a single mesh vertex
ufbx_skin_vertex :: struct {
weight_begin: u32; // < Index to start from in the `weights[]` array
num_weights: u32; // < Number of weights influencing the vertex
// Blend weight between Linear Blend Skinning (0.0) and Dual Quaternion (1.0).
// Should be used if `skinning_method == UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR`
dq_weight: ufbx_real;
}
ufbx_skin_vertex_list :: struct {
data: *ufbx_skin_vertex;
count: size_t;
}
// Single per-vertex per-cluster weight, see `ufbx_skin_vertex`
ufbx_skin_weight :: struct {
cluster_index: u32; // < Index into `ufbx_skin_deformer.clusters[]`
weight: ufbx_real; // < Amount this bone influence the vertex
}
ufbx_skin_weight_list :: struct {
data: *ufbx_skin_weight;
count: size_t;
}
// Skin deformer specifies a binding between a logical set of bones (a skeleton)
// and a mesh. Each bone is represented by a `ufbx_skin_cluster` that contains
// the binding matrix and a `ufbx_node *bone` that has the current transformation.
ufbx_skin_deformer :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
skinning_method: ufbx_skinning_method;
// Clusters (bones) in the skin
clusters: ufbx_skin_cluster_list;
// Per-vertex weight information
vertices: ufbx_skin_vertex_list;
weights: ufbx_skin_weight_list;
// Largest amount of weights a single vertex can have
max_weights_per_vertex: size_t;
// Blend weights between Linear Blend Skinning (0.0) and Dual Quaternion (1.0).
// HINT: You probably want to use `vertices` and `ufbx_skin_vertex.dq_weight` instead!
// NOTE: These may be out-of-bounds for a given mesh, `vertices` is always safe.
num_dq_weights: size_t;
dq_vertices: ufbx_uint32_list;
dq_weights: ufbx_real_list;
}
// Cluster of vertices bound to a single bone.
ufbx_skin_cluster :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// The bone node the cluster is attached to
// NOTE: Always valid if found from `ufbx_skin_deformer.clusters[]` unless
// `ufbx_load_opts.connect_broken_elements` is `true`.
bone_node: *ufbx_node;
// Binding matrix from local mesh vertices to the bone
geometry_to_bone: ufbx_matrix;
// Binding matrix from local mesh _node_ to the bone.
// NOTE: Prefer `geometry_to_bone` in most use cases!
mesh_node_to_bone: ufbx_matrix;
// Matrix that specifies the rest/bind pose transform of the node,
// not generally needed for skinning, use `geometry_to_bone` instead.
bind_to_world: ufbx_matrix;
// Precomputed matrix/transform that accounts for the current bone transform
// ie. `ufbx_matrix_mul(&cluster->bone->node_to_world, &cluster->geometry_to_bone)`
geometry_to_world: ufbx_matrix;
geometry_to_world_transform: ufbx_transform;
num_weights: size_t; // < Number of vertices in the cluster
vertices: ufbx_uint32_list; // < Vertex indices in `ufbx_mesh.vertices[]`
weights: ufbx_real_list; // < Per-vertex weight values
}
// Blend shape deformer can contain multiple channels (think of sliders between morphs)
// that may optionally have in-between keyframes.
ufbx_blend_deformer :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Independent morph targets of the deformer.
channels: ufbx_blend_channel_list;
}
// Blend shape associated with a target weight in a series of morphs
ufbx_blend_keyframe :: struct {
// The target blend shape offsets.
shape: *ufbx_blend_shape;
// Weight value at which to apply the keyframe at full strength
target_weight: ufbx_real;
// The weight the shape should be currently applied with
effective_weight: ufbx_real;
}
ufbx_blend_keyframe_list :: struct {
data: *ufbx_blend_keyframe;
count: size_t;
}
// Blend channel consists of multiple morph-key targets that are interpolated.
// In simple cases there will be only one keyframe that is the target shape.
ufbx_blend_channel :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Current weight of the channel
weight: ufbx_real;
// Key morph targets to blend between depending on `weight`
// In usual cases there's only one target per channel
keyframes: ufbx_blend_keyframe_list;
}
// Blend shape target containing the actual vertex offsets
ufbx_blend_shape :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
num_offsets: size_t; // < Number of vertex offsets in the following arrays
offset_vertices: ufbx_uint32_list; // < Indices to `ufbx_mesh.vertices[]`
position_offsets: ufbx_vec3_list; // < Always specified per-vertex offsets
normal_offsets: ufbx_vec3_list; // < Empty if not specified
}
ufbx_cache_file_format :: enum s32 {
UNKNOWN :: 0;
PC2 :: 1;
MC :: 2;
FORCE_32BIT :: 2147483647;
UFBX_CACHE_FILE_FORMAT_UNKNOWN :: UNKNOWN;
UFBX_CACHE_FILE_FORMAT_PC2 :: PC2;
UFBX_CACHE_FILE_FORMAT_MC :: MC;
UFBX_CACHE_FILE_FORMAT_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_20 :: enum s32 {
UFBX_CACHE_FILE_FORMAT_COUNT :: 3;
}
ufbx_cache_data_format :: enum s32 {
UNKNOWN :: 0;
REAL_FLOAT :: 1;
VEC3_FLOAT :: 2;
REAL_DOUBLE :: 3;
VEC3_DOUBLE :: 4;
FORCE_32BIT :: 2147483647;
UFBX_CACHE_DATA_FORMAT_UNKNOWN :: UNKNOWN;
UFBX_CACHE_DATA_FORMAT_REAL_FLOAT :: REAL_FLOAT;
UFBX_CACHE_DATA_FORMAT_VEC3_FLOAT :: VEC3_FLOAT;
UFBX_CACHE_DATA_FORMAT_REAL_DOUBLE :: REAL_DOUBLE;
UFBX_CACHE_DATA_FORMAT_VEC3_DOUBLE :: VEC3_DOUBLE;
UFBX_CACHE_DATA_FORMAT_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_21 :: enum s32 {
UFBX_CACHE_DATA_FORMAT_COUNT :: 5;
}
ufbx_cache_data_encoding :: enum s32 {
UNKNOWN :: 0;
LITTLE_ENDIAN :: 1;
BIG_ENDIAN :: 2;
FORCE_32BIT :: 2147483647;
UFBX_CACHE_DATA_ENCODING_UNKNOWN :: UNKNOWN;
UFBX_CACHE_DATA_ENCODING_LITTLE_ENDIAN :: LITTLE_ENDIAN;
UFBX_CACHE_DATA_ENCODING_BIG_ENDIAN :: BIG_ENDIAN;
UFBX_CACHE_DATA_ENCODING_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_22 :: enum s32 {
UFBX_CACHE_DATA_ENCODING_COUNT :: 3;
}
// Known interpretations of geometry cache data.
ufbx_cache_interpretation :: enum s32 {
UNKNOWN :: 0;
POINTS :: 1;
VERTEX_POSITION :: 2;
VERTEX_NORMAL :: 3;
FORCE_32BIT :: 2147483647;
UFBX_CACHE_INTERPRETATION_UNKNOWN :: UNKNOWN;
UFBX_CACHE_INTERPRETATION_POINTS :: POINTS;
UFBX_CACHE_INTERPRETATION_VERTEX_POSITION :: VERTEX_POSITION;
UFBX_CACHE_INTERPRETATION_VERTEX_NORMAL :: VERTEX_NORMAL;
UFBX_CACHE_INTERPRETATION_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_23 :: enum s32 {
UFBX_CACHE_INTERPRETATION_COUNT :: 4;
}
ufbx_cache_frame :: struct {
// Name of the channel this frame belongs to.
channel: ufbx_string;
// Time of this frame in seconds.
time: float64;
// Name of the file containing the data.
// The specified file may contain multiple frames, use `data_offset` etc. to
// read at the right position.
filename: ufbx_string;
// Format of the wrapper file.
file_format: ufbx_cache_file_format;
data_format: ufbx_cache_data_format; // < Format of the data in the file
data_encoding: ufbx_cache_data_encoding; // < Binary encoding of the data
data_offset: u64; // < Byte offset into the file
data_count: u32; // < Number of data elements
data_element_bytes: u32; // < Size of a single data element in bytes
data_total_bytes: u64; // < Size of the whole data blob in bytes
}
ufbx_cache_frame_list :: struct {
data: *ufbx_cache_frame;
count: size_t;
}
ufbx_cache_channel :: struct {
// Name of the geometry cache channel.
name: ufbx_string;
// What does the data in this channel represent.
interpretation: ufbx_cache_interpretation;
// Source name for `interpretation`, especially useful if `interpretation` is
// `UFBX_CACHE_INTERPRETATION_UNKNOWN`.
interpretation_name: ufbx_string;
// List of frames belonging to this channel.
// Sorted by time (`ufbx_cache_frame.time`).
frames: ufbx_cache_frame_list;
}
ufbx_cache_channel_list :: struct {
data: *ufbx_cache_channel;
count: size_t;
}
ufbx_geometry_cache :: struct {
root_filename: ufbx_string;
channels: ufbx_cache_channel_list;
frames: ufbx_cache_frame_list;
extra_info: ufbx_string_list;
}
ufbx_cache_deformer :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
channel: ufbx_string;
file: *ufbx_cache_file;
// Only valid if `ufbx_load_opts.load_external_files` is set!
external_cache: *ufbx_geometry_cache;
external_channel: *ufbx_cache_channel;
}
ufbx_cache_file :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
filename: ufbx_string;
absolute_filename: ufbx_string;
relative_filename: ufbx_string;
raw_filename: ufbx_blob;
raw_absolute_filename: ufbx_blob;
raw_relative_filename: ufbx_blob;
format: ufbx_cache_file_format;
// Only valid if `ufbx_load_opts.load_external_files` is set!
external_cache: *ufbx_geometry_cache;
}
// Material property, either specified with a constant value or a mapped texture
ufbx_material_map :: struct {
// Constant value or factor for the map.
// May be specified simultaneously with a texture, in this case most shading models
// use multiplicative tinting of the texture values.
union {
value_real: ufbx_real;
value_vec2: ufbx_vec2;
value_vec3: ufbx_vec3;
value_vec4: ufbx_vec4;
}
value_int: s64;
// Texture if connected, otherwise `NULL`.
// May be valid but "disabled" (application specific) if `texture_enabled == false`.
texture: *ufbx_texture;
// `true` if the file has specified any of the values above.
// NOTE: The value may be set to a non-zero default even if `has_value == false`,
// for example missing factors are set to `1.0` if a color is defined.
has_value: bool;
// Controls whether shading should use `texture`.
// NOTE: Some shading models allow this to be `true` even if `texture == NULL`.
texture_enabled: bool;
// Set to `true` if this feature should be disabled (specific to shader type).
feature_disabled: bool;
// Number of components in the value from 1 to 4 if defined, 0 if not.
value_components: u8;
}
// Material feature
ufbx_material_feature_info :: struct {
// Whether the material model uses this feature or not.
// NOTE: The feature can be enabled but still not used if eg. the corresponding factor is at zero!
enabled: bool;
// Explicitly enabled/disabled by the material.
is_explicit: bool;
}
// Texture attached to an FBX property
ufbx_material_texture :: struct {
material_prop: ufbx_string; // < Name of the property in `ufbx_material.props`
shader_prop: ufbx_string; // < Shader-specific property mapping name
// Texture attached to the property.
texture: *ufbx_texture;
}
ufbx_material_texture_list :: struct {
data: *ufbx_material_texture;
count: size_t;
}
// Shading model type
ufbx_shader_type :: enum s32 {
UNKNOWN :: 0;
FBX_LAMBERT :: 1;
FBX_PHONG :: 2;
OSL_STANDARD_SURFACE :: 3;
ARNOLD_STANDARD_SURFACE :: 4;
_3DS_MAX_PHYSICAL_MATERIAL :: 5;
_3DS_MAX_PBR_METAL_ROUGH :: 6;
_3DS_MAX_PBR_SPEC_GLOSS :: 7;
GLTF_MATERIAL :: 8;
SHADERFX_GRAPH :: 9;
BLENDER_PHONG :: 10;
WAVEFRONT_MTL :: 11;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_SHADER_UNKNOWN :: UNKNOWN;
UFBX_SHADER_FBX_LAMBERT :: FBX_LAMBERT;
UFBX_SHADER_FBX_PHONG :: FBX_PHONG;
UFBX_SHADER_OSL_STANDARD_SURFACE :: OSL_STANDARD_SURFACE;
UFBX_SHADER_ARNOLD_STANDARD_SURFACE :: ARNOLD_STANDARD_SURFACE;
UFBX_SHADER_3DS_MAX_PHYSICAL_MATERIAL :: _3DS_MAX_PHYSICAL_MATERIAL;
UFBX_SHADER_3DS_MAX_PBR_METAL_ROUGH :: _3DS_MAX_PBR_METAL_ROUGH;
UFBX_SHADER_3DS_MAX_PBR_SPEC_GLOSS :: _3DS_MAX_PBR_SPEC_GLOSS;
UFBX_SHADER_GLTF_MATERIAL :: GLTF_MATERIAL;
UFBX_SHADER_SHADERFX_GRAPH :: SHADERFX_GRAPH;
UFBX_SHADER_BLENDER_PHONG :: BLENDER_PHONG;
UFBX_SHADER_WAVEFRONT_MTL :: WAVEFRONT_MTL;
UFBX_SHADER_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_24 :: enum s32 {
UFBX_SHADER_TYPE_COUNT :: 12;
}
// FBX builtin material properties, matches maps in `ufbx_material_fbx_maps`
ufbx_material_fbx_map :: enum s32 {
DIFFUSE_FACTOR :: 0;
DIFFUSE_COLOR :: 1;
SPECULAR_FACTOR :: 2;
SPECULAR_COLOR :: 3;
SPECULAR_EXPONENT :: 4;
REFLECTION_FACTOR :: 5;
REFLECTION_COLOR :: 6;
TRANSPARENCY_FACTOR :: 7;
TRANSPARENCY_COLOR :: 8;
EMISSION_FACTOR :: 9;
EMISSION_COLOR :: 10;
AMBIENT_FACTOR :: 11;
AMBIENT_COLOR :: 12;
NORMAL_MAP :: 13;
BUMP :: 14;
BUMP_FACTOR :: 15;
DISPLACEMENT_FACTOR :: 16;
DISPLACEMENT :: 17;
VECTOR_DISPLACEMENT_FACTOR :: 18;
VECTOR_DISPLACEMENT :: 19;
MAP_FORCE_32BIT :: 2147483647;
UFBX_MATERIAL_FBX_DIFFUSE_FACTOR :: DIFFUSE_FACTOR;
UFBX_MATERIAL_FBX_DIFFUSE_COLOR :: DIFFUSE_COLOR;
UFBX_MATERIAL_FBX_SPECULAR_FACTOR :: SPECULAR_FACTOR;
UFBX_MATERIAL_FBX_SPECULAR_COLOR :: SPECULAR_COLOR;
UFBX_MATERIAL_FBX_SPECULAR_EXPONENT :: SPECULAR_EXPONENT;
UFBX_MATERIAL_FBX_REFLECTION_FACTOR :: REFLECTION_FACTOR;
UFBX_MATERIAL_FBX_REFLECTION_COLOR :: REFLECTION_COLOR;
UFBX_MATERIAL_FBX_TRANSPARENCY_FACTOR :: TRANSPARENCY_FACTOR;
UFBX_MATERIAL_FBX_TRANSPARENCY_COLOR :: TRANSPARENCY_COLOR;
UFBX_MATERIAL_FBX_EMISSION_FACTOR :: EMISSION_FACTOR;
UFBX_MATERIAL_FBX_EMISSION_COLOR :: EMISSION_COLOR;
UFBX_MATERIAL_FBX_AMBIENT_FACTOR :: AMBIENT_FACTOR;
UFBX_MATERIAL_FBX_AMBIENT_COLOR :: AMBIENT_COLOR;
UFBX_MATERIAL_FBX_NORMAL_MAP :: NORMAL_MAP;
UFBX_MATERIAL_FBX_BUMP :: BUMP;
UFBX_MATERIAL_FBX_BUMP_FACTOR :: BUMP_FACTOR;
UFBX_MATERIAL_FBX_DISPLACEMENT_FACTOR :: DISPLACEMENT_FACTOR;
UFBX_MATERIAL_FBX_DISPLACEMENT :: DISPLACEMENT;
UFBX_MATERIAL_FBX_VECTOR_DISPLACEMENT_FACTOR :: VECTOR_DISPLACEMENT_FACTOR;
UFBX_MATERIAL_FBX_VECTOR_DISPLACEMENT :: VECTOR_DISPLACEMENT;
UFBX_MATERIAL_FBX_MAP_FORCE_32BIT :: MAP_FORCE_32BIT;
}
anon_enum_25 :: enum s32 {
UFBX_MATERIAL_FBX_MAP_COUNT :: 20;
}
// Known PBR material properties, matches maps in `ufbx_material_pbr_maps`
ufbx_material_pbr_map :: enum s32 {
BASE_FACTOR :: 0;
BASE_COLOR :: 1;
ROUGHNESS :: 2;
METALNESS :: 3;
DIFFUSE_ROUGHNESS :: 4;
SPECULAR_FACTOR :: 5;
SPECULAR_COLOR :: 6;
SPECULAR_IOR :: 7;
SPECULAR_ANISOTROPY :: 8;
SPECULAR_ROTATION :: 9;
TRANSMISSION_FACTOR :: 10;
TRANSMISSION_COLOR :: 11;
TRANSMISSION_DEPTH :: 12;
TRANSMISSION_SCATTER :: 13;
TRANSMISSION_SCATTER_ANISOTROPY :: 14;
TRANSMISSION_DISPERSION :: 15;
TRANSMISSION_ROUGHNESS :: 16;
TRANSMISSION_EXTRA_ROUGHNESS :: 17;
TRANSMISSION_PRIORITY :: 18;
TRANSMISSION_ENABLE_IN_AOV :: 19;
SUBSURFACE_FACTOR :: 20;
SUBSURFACE_COLOR :: 21;
SUBSURFACE_RADIUS :: 22;
SUBSURFACE_SCALE :: 23;
SUBSURFACE_ANISOTROPY :: 24;
SUBSURFACE_TINT_COLOR :: 25;
SUBSURFACE_TYPE :: 26;
SHEEN_FACTOR :: 27;
SHEEN_COLOR :: 28;
SHEEN_ROUGHNESS :: 29;
COAT_FACTOR :: 30;
COAT_COLOR :: 31;
COAT_ROUGHNESS :: 32;
COAT_IOR :: 33;
COAT_ANISOTROPY :: 34;
COAT_ROTATION :: 35;
COAT_NORMAL :: 36;
COAT_AFFECT_BASE_COLOR :: 37;
COAT_AFFECT_BASE_ROUGHNESS :: 38;
THIN_FILM_THICKNESS :: 39;
THIN_FILM_IOR :: 40;
EMISSION_FACTOR :: 41;
EMISSION_COLOR :: 42;
OPACITY :: 43;
INDIRECT_DIFFUSE :: 44;
INDIRECT_SPECULAR :: 45;
NORMAL_MAP :: 46;
TANGENT_MAP :: 47;
DISPLACEMENT_MAP :: 48;
MATTE_FACTOR :: 49;
MATTE_COLOR :: 50;
AMBIENT_OCCLUSION :: 51;
GLOSSINESS :: 52;
COAT_GLOSSINESS :: 53;
TRANSMISSION_GLOSSINESS :: 54;
MAP_FORCE_32BIT :: 2147483647;
UFBX_MATERIAL_PBR_BASE_FACTOR :: BASE_FACTOR;
UFBX_MATERIAL_PBR_BASE_COLOR :: BASE_COLOR;
UFBX_MATERIAL_PBR_ROUGHNESS :: ROUGHNESS;
UFBX_MATERIAL_PBR_METALNESS :: METALNESS;
UFBX_MATERIAL_PBR_DIFFUSE_ROUGHNESS :: DIFFUSE_ROUGHNESS;
UFBX_MATERIAL_PBR_SPECULAR_FACTOR :: SPECULAR_FACTOR;
UFBX_MATERIAL_PBR_SPECULAR_COLOR :: SPECULAR_COLOR;
UFBX_MATERIAL_PBR_SPECULAR_IOR :: SPECULAR_IOR;
UFBX_MATERIAL_PBR_SPECULAR_ANISOTROPY :: SPECULAR_ANISOTROPY;
UFBX_MATERIAL_PBR_SPECULAR_ROTATION :: SPECULAR_ROTATION;
UFBX_MATERIAL_PBR_TRANSMISSION_FACTOR :: TRANSMISSION_FACTOR;
UFBX_MATERIAL_PBR_TRANSMISSION_COLOR :: TRANSMISSION_COLOR;
UFBX_MATERIAL_PBR_TRANSMISSION_DEPTH :: TRANSMISSION_DEPTH;
UFBX_MATERIAL_PBR_TRANSMISSION_SCATTER :: TRANSMISSION_SCATTER;
UFBX_MATERIAL_PBR_TRANSMISSION_SCATTER_ANISOTROPY :: TRANSMISSION_SCATTER_ANISOTROPY;
UFBX_MATERIAL_PBR_TRANSMISSION_DISPERSION :: TRANSMISSION_DISPERSION;
UFBX_MATERIAL_PBR_TRANSMISSION_ROUGHNESS :: TRANSMISSION_ROUGHNESS;
UFBX_MATERIAL_PBR_TRANSMISSION_EXTRA_ROUGHNESS :: TRANSMISSION_EXTRA_ROUGHNESS;
UFBX_MATERIAL_PBR_TRANSMISSION_PRIORITY :: TRANSMISSION_PRIORITY;
UFBX_MATERIAL_PBR_TRANSMISSION_ENABLE_IN_AOV :: TRANSMISSION_ENABLE_IN_AOV;
UFBX_MATERIAL_PBR_SUBSURFACE_FACTOR :: SUBSURFACE_FACTOR;
UFBX_MATERIAL_PBR_SUBSURFACE_COLOR :: SUBSURFACE_COLOR;
UFBX_MATERIAL_PBR_SUBSURFACE_RADIUS :: SUBSURFACE_RADIUS;
UFBX_MATERIAL_PBR_SUBSURFACE_SCALE :: SUBSURFACE_SCALE;
UFBX_MATERIAL_PBR_SUBSURFACE_ANISOTROPY :: SUBSURFACE_ANISOTROPY;
UFBX_MATERIAL_PBR_SUBSURFACE_TINT_COLOR :: SUBSURFACE_TINT_COLOR;
UFBX_MATERIAL_PBR_SUBSURFACE_TYPE :: SUBSURFACE_TYPE;
UFBX_MATERIAL_PBR_SHEEN_FACTOR :: SHEEN_FACTOR;
UFBX_MATERIAL_PBR_SHEEN_COLOR :: SHEEN_COLOR;
UFBX_MATERIAL_PBR_SHEEN_ROUGHNESS :: SHEEN_ROUGHNESS;
UFBX_MATERIAL_PBR_COAT_FACTOR :: COAT_FACTOR;
UFBX_MATERIAL_PBR_COAT_COLOR :: COAT_COLOR;
UFBX_MATERIAL_PBR_COAT_ROUGHNESS :: COAT_ROUGHNESS;
UFBX_MATERIAL_PBR_COAT_IOR :: COAT_IOR;
UFBX_MATERIAL_PBR_COAT_ANISOTROPY :: COAT_ANISOTROPY;
UFBX_MATERIAL_PBR_COAT_ROTATION :: COAT_ROTATION;
UFBX_MATERIAL_PBR_COAT_NORMAL :: COAT_NORMAL;
UFBX_MATERIAL_PBR_COAT_AFFECT_BASE_COLOR :: COAT_AFFECT_BASE_COLOR;
UFBX_MATERIAL_PBR_COAT_AFFECT_BASE_ROUGHNESS :: COAT_AFFECT_BASE_ROUGHNESS;
UFBX_MATERIAL_PBR_THIN_FILM_THICKNESS :: THIN_FILM_THICKNESS;
UFBX_MATERIAL_PBR_THIN_FILM_IOR :: THIN_FILM_IOR;
UFBX_MATERIAL_PBR_EMISSION_FACTOR :: EMISSION_FACTOR;
UFBX_MATERIAL_PBR_EMISSION_COLOR :: EMISSION_COLOR;
UFBX_MATERIAL_PBR_OPACITY :: OPACITY;
UFBX_MATERIAL_PBR_INDIRECT_DIFFUSE :: INDIRECT_DIFFUSE;
UFBX_MATERIAL_PBR_INDIRECT_SPECULAR :: INDIRECT_SPECULAR;
UFBX_MATERIAL_PBR_NORMAL_MAP :: NORMAL_MAP;
UFBX_MATERIAL_PBR_TANGENT_MAP :: TANGENT_MAP;
UFBX_MATERIAL_PBR_DISPLACEMENT_MAP :: DISPLACEMENT_MAP;
UFBX_MATERIAL_PBR_MATTE_FACTOR :: MATTE_FACTOR;
UFBX_MATERIAL_PBR_MATTE_COLOR :: MATTE_COLOR;
UFBX_MATERIAL_PBR_AMBIENT_OCCLUSION :: AMBIENT_OCCLUSION;
UFBX_MATERIAL_PBR_GLOSSINESS :: GLOSSINESS;
UFBX_MATERIAL_PBR_COAT_GLOSSINESS :: COAT_GLOSSINESS;
UFBX_MATERIAL_PBR_TRANSMISSION_GLOSSINESS :: TRANSMISSION_GLOSSINESS;
UFBX_MATERIAL_PBR_MAP_FORCE_32BIT :: MAP_FORCE_32BIT;
}
anon_enum_26 :: enum s32 {
UFBX_MATERIAL_PBR_MAP_COUNT :: 55;
}
// Known material features
ufbx_material_feature :: enum s32 {
PBR :: 0;
METALNESS :: 1;
DIFFUSE :: 2;
SPECULAR :: 3;
EMISSION :: 4;
TRANSMISSION :: 5;
COAT :: 6;
SHEEN :: 7;
OPACITY :: 8;
AMBIENT_OCCLUSION :: 9;
MATTE :: 10;
UNLIT :: 11;
IOR :: 12;
DIFFUSE_ROUGHNESS :: 13;
TRANSMISSION_ROUGHNESS :: 14;
THIN_WALLED :: 15;
CAUSTICS :: 16;
EXIT_TO_BACKGROUND :: 17;
INTERNAL_REFLECTIONS :: 18;
DOUBLE_SIDED :: 19;
ROUGHNESS_AS_GLOSSINESS :: 20;
COAT_ROUGHNESS_AS_GLOSSINESS :: 21;
TRANSMISSION_ROUGHNESS_AS_GLOSSINESS :: 22;
FORCE_32BIT :: 2147483647;
UFBX_MATERIAL_FEATURE_PBR :: PBR;
UFBX_MATERIAL_FEATURE_METALNESS :: METALNESS;
UFBX_MATERIAL_FEATURE_DIFFUSE :: DIFFUSE;
UFBX_MATERIAL_FEATURE_SPECULAR :: SPECULAR;
UFBX_MATERIAL_FEATURE_EMISSION :: EMISSION;
UFBX_MATERIAL_FEATURE_TRANSMISSION :: TRANSMISSION;
UFBX_MATERIAL_FEATURE_COAT :: COAT;
UFBX_MATERIAL_FEATURE_SHEEN :: SHEEN;
UFBX_MATERIAL_FEATURE_OPACITY :: OPACITY;
UFBX_MATERIAL_FEATURE_AMBIENT_OCCLUSION :: AMBIENT_OCCLUSION;
UFBX_MATERIAL_FEATURE_MATTE :: MATTE;
UFBX_MATERIAL_FEATURE_UNLIT :: UNLIT;
UFBX_MATERIAL_FEATURE_IOR :: IOR;
UFBX_MATERIAL_FEATURE_DIFFUSE_ROUGHNESS :: DIFFUSE_ROUGHNESS;
UFBX_MATERIAL_FEATURE_TRANSMISSION_ROUGHNESS :: TRANSMISSION_ROUGHNESS;
UFBX_MATERIAL_FEATURE_THIN_WALLED :: THIN_WALLED;
UFBX_MATERIAL_FEATURE_CAUSTICS :: CAUSTICS;
UFBX_MATERIAL_FEATURE_EXIT_TO_BACKGROUND :: EXIT_TO_BACKGROUND;
UFBX_MATERIAL_FEATURE_INTERNAL_REFLECTIONS :: INTERNAL_REFLECTIONS;
UFBX_MATERIAL_FEATURE_DOUBLE_SIDED :: DOUBLE_SIDED;
UFBX_MATERIAL_FEATURE_ROUGHNESS_AS_GLOSSINESS :: ROUGHNESS_AS_GLOSSINESS;
UFBX_MATERIAL_FEATURE_COAT_ROUGHNESS_AS_GLOSSINESS :: COAT_ROUGHNESS_AS_GLOSSINESS;
UFBX_MATERIAL_FEATURE_TRANSMISSION_ROUGHNESS_AS_GLOSSINESS :: TRANSMISSION_ROUGHNESS_AS_GLOSSINESS;
UFBX_MATERIAL_FEATURE_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_27 :: enum s32 {
UFBX_MATERIAL_FEATURE_COUNT :: 23;
}
ufbx_material_fbx_maps :: struct {
union {
maps: [20] ufbx_material_map;
struct {
diffuse_factor: ufbx_material_map;
diffuse_color: ufbx_material_map;
specular_factor: ufbx_material_map;
specular_color: ufbx_material_map;
specular_exponent: ufbx_material_map;
reflection_factor: ufbx_material_map;
reflection_color: ufbx_material_map;
transparency_factor: ufbx_material_map;
transparency_color: ufbx_material_map;
emission_factor: ufbx_material_map;
emission_color: ufbx_material_map;
ambient_factor: ufbx_material_map;
ambient_color: ufbx_material_map;
normal_map: ufbx_material_map;
bump: ufbx_material_map;
bump_factor: ufbx_material_map;
displacement_factor: ufbx_material_map;
displacement: ufbx_material_map;
vector_displacement_factor: ufbx_material_map;
vector_displacement: ufbx_material_map;
}
}
}
ufbx_material_pbr_maps :: struct {
union {
maps: [55] ufbx_material_map;
struct {
base_factor: ufbx_material_map;
base_color: ufbx_material_map;
roughness: ufbx_material_map;
metalness: ufbx_material_map;
diffuse_roughness: ufbx_material_map;
specular_factor: ufbx_material_map;
specular_color: ufbx_material_map;
specular_ior: ufbx_material_map;
specular_anisotropy: ufbx_material_map;
specular_rotation: ufbx_material_map;
transmission_factor: ufbx_material_map;
transmission_color: ufbx_material_map;
transmission_depth: ufbx_material_map;
transmission_scatter: ufbx_material_map;
transmission_scatter_anisotropy: ufbx_material_map;
transmission_dispersion: ufbx_material_map;
transmission_roughness: ufbx_material_map;
transmission_extra_roughness: ufbx_material_map;
transmission_priority: ufbx_material_map;
transmission_enable_in_aov: ufbx_material_map;
subsurface_factor: ufbx_material_map;
subsurface_color: ufbx_material_map;
subsurface_radius: ufbx_material_map;
subsurface_scale: ufbx_material_map;
subsurface_anisotropy: ufbx_material_map;
subsurface_tint_color: ufbx_material_map;
subsurface_type: ufbx_material_map;
sheen_factor: ufbx_material_map;
sheen_color: ufbx_material_map;
sheen_roughness: ufbx_material_map;
coat_factor: ufbx_material_map;
coat_color: ufbx_material_map;
coat_roughness: ufbx_material_map;
coat_ior: ufbx_material_map;
coat_anisotropy: ufbx_material_map;
coat_rotation: ufbx_material_map;
coat_normal: ufbx_material_map;
coat_affect_base_color: ufbx_material_map;
coat_affect_base_roughness: ufbx_material_map;
thin_film_thickness: ufbx_material_map;
thin_film_ior: ufbx_material_map;
emission_factor: ufbx_material_map;
emission_color: ufbx_material_map;
opacity: ufbx_material_map;
indirect_diffuse: ufbx_material_map;
indirect_specular: ufbx_material_map;
normal_map: ufbx_material_map;
tangent_map: ufbx_material_map;
displacement_map: ufbx_material_map;
matte_factor: ufbx_material_map;
matte_color: ufbx_material_map;
ambient_occlusion: ufbx_material_map;
glossiness: ufbx_material_map;
coat_glossiness: ufbx_material_map;
transmission_glossiness: ufbx_material_map;
}
}
}
ufbx_material_features :: struct {
union {
features: [23] ufbx_material_feature_info;
struct {
pbr: ufbx_material_feature_info;
metalness: ufbx_material_feature_info;
diffuse: ufbx_material_feature_info;
specular: ufbx_material_feature_info;
emission: ufbx_material_feature_info;
transmission: ufbx_material_feature_info;
coat: ufbx_material_feature_info;
sheen: ufbx_material_feature_info;
opacity: ufbx_material_feature_info;
ambient_occlusion: ufbx_material_feature_info;
matte: ufbx_material_feature_info;
unlit: ufbx_material_feature_info;
ior: ufbx_material_feature_info;
diffuse_roughness: ufbx_material_feature_info;
transmission_roughness: ufbx_material_feature_info;
thin_walled: ufbx_material_feature_info;
caustics: ufbx_material_feature_info;
exit_to_background: ufbx_material_feature_info;
internal_reflections: ufbx_material_feature_info;
double_sided: ufbx_material_feature_info;
roughness_as_glossiness: ufbx_material_feature_info;
coat_roughness_as_glossiness: ufbx_material_feature_info;
transmission_roughness_as_glossiness: ufbx_material_feature_info;
}
}
}
// Surface material properties such as color, roughness, etc. Each property may
// be optionally bound to an `ufbx_texture`.
ufbx_material :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// FBX builtin properties
// NOTE: These may be empty if the material is using a custom shader
fbx: ufbx_material_fbx_maps;
// PBR material properties, defined for all shading models but may be
// somewhat approximate if `shader == NULL`.
pbr: ufbx_material_pbr_maps;
// Material features, primarily applies to `pbr`.
features: ufbx_material_features;
shader_type: ufbx_shader_type; // < Always defined
shader: *ufbx_shader; // < Optional extended shader information
shading_model_name: ufbx_string; // < Often one of `{ "lambert", "phong", "unknown" }`
// Prefix before shader property names with trailing `|`.
// For example `"3dsMax|Parameters|"` where properties would have names like
// `"3dsMax|Parameters|base_color"`. You can ignore this if you use the built-in
// `ufbx_material_fbx_maps fbx` and `ufbx_material_pbr_maps pbr` structures.
shader_prop_prefix: ufbx_string;
textures: ufbx_material_texture_list; // < Sorted by `material_prop`
}
ufbx_texture_type :: enum s32 {
FILE :: 0;
LAYERED :: 1;
PROCEDURAL :: 2;
SHADER :: 3;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_TEXTURE_FILE :: FILE;
UFBX_TEXTURE_LAYERED :: LAYERED;
UFBX_TEXTURE_PROCEDURAL :: PROCEDURAL;
UFBX_TEXTURE_SHADER :: SHADER;
UFBX_TEXTURE_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_28 :: enum s32 {
UFBX_TEXTURE_TYPE_COUNT :: 4;
}
// Blend modes to combine layered textures with, compatible with common blend
// mode definitions in many art programs. Simpler blend modes have equations
// specified below where `src` is the layer to compososite over `dst`.
// See eg. https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendingseparable
ufbx_blend_mode :: enum s32 {
TRANSLUCENT :: 0;
ADDITIVE :: 1;
MULTIPLY :: 2;
MULTIPLY_2X :: 3;
OVER :: 4;
REPLACE :: 5;
DISSOLVE :: 6;
DARKEN :: 7;
COLOR_BURN :: 8;
LINEAR_BURN :: 9;
DARKER_COLOR :: 10;
LIGHTEN :: 11;
SCREEN :: 12;
COLOR_DODGE :: 13;
LINEAR_DODGE :: 14;
LIGHTER_COLOR :: 15;
SOFT_LIGHT :: 16;
HARD_LIGHT :: 17;
VIVID_LIGHT :: 18;
LINEAR_LIGHT :: 19;
PIN_LIGHT :: 20;
HARD_MIX :: 21;
DIFFERENCE :: 22;
EXCLUSION :: 23;
SUBTRACT :: 24;
DIVIDE :: 25;
HUE :: 26;
SATURATION :: 27;
COLOR :: 28;
LUMINOSITY :: 29;
OVERLAY :: 30;
MODE_FORCE_32BIT :: 2147483647;
UFBX_BLEND_TRANSLUCENT :: TRANSLUCENT;
UFBX_BLEND_ADDITIVE :: ADDITIVE;
UFBX_BLEND_MULTIPLY :: MULTIPLY;
UFBX_BLEND_MULTIPLY_2X :: MULTIPLY_2X;
UFBX_BLEND_OVER :: OVER;
UFBX_BLEND_REPLACE :: REPLACE;
UFBX_BLEND_DISSOLVE :: DISSOLVE;
UFBX_BLEND_DARKEN :: DARKEN;
UFBX_BLEND_COLOR_BURN :: COLOR_BURN;
UFBX_BLEND_LINEAR_BURN :: LINEAR_BURN;
UFBX_BLEND_DARKER_COLOR :: DARKER_COLOR;
UFBX_BLEND_LIGHTEN :: LIGHTEN;
UFBX_BLEND_SCREEN :: SCREEN;
UFBX_BLEND_COLOR_DODGE :: COLOR_DODGE;
UFBX_BLEND_LINEAR_DODGE :: LINEAR_DODGE;
UFBX_BLEND_LIGHTER_COLOR :: LIGHTER_COLOR;
UFBX_BLEND_SOFT_LIGHT :: SOFT_LIGHT;
UFBX_BLEND_HARD_LIGHT :: HARD_LIGHT;
UFBX_BLEND_VIVID_LIGHT :: VIVID_LIGHT;
UFBX_BLEND_LINEAR_LIGHT :: LINEAR_LIGHT;
UFBX_BLEND_PIN_LIGHT :: PIN_LIGHT;
UFBX_BLEND_HARD_MIX :: HARD_MIX;
UFBX_BLEND_DIFFERENCE :: DIFFERENCE;
UFBX_BLEND_EXCLUSION :: EXCLUSION;
UFBX_BLEND_SUBTRACT :: SUBTRACT;
UFBX_BLEND_DIVIDE :: DIVIDE;
UFBX_BLEND_HUE :: HUE;
UFBX_BLEND_SATURATION :: SATURATION;
UFBX_BLEND_COLOR :: COLOR;
UFBX_BLEND_LUMINOSITY :: LUMINOSITY;
UFBX_BLEND_OVERLAY :: OVERLAY;
UFBX_BLEND_MODE_FORCE_32BIT :: MODE_FORCE_32BIT;
}
anon_enum_29 :: enum s32 {
UFBX_BLEND_MODE_COUNT :: 31;
}
// Blend modes to combine layered textures with, compatible with common blend
ufbx_wrap_mode :: enum s32 {
REPEAT :: 0;
CLAMP :: 1;
MODE_FORCE_32BIT :: 2147483647;
UFBX_WRAP_REPEAT :: REPEAT;
UFBX_WRAP_CLAMP :: CLAMP;
UFBX_WRAP_MODE_FORCE_32BIT :: MODE_FORCE_32BIT;
}
anon_enum_30 :: enum s32 {
UFBX_WRAP_MODE_COUNT :: 2;
}
// Single layer in a layered texture
ufbx_texture_layer :: struct {
texture: *ufbx_texture; // < The inner texture to evaluate, never `NULL`
blend_mode: ufbx_blend_mode; // < Equation to combine the layer to the background
alpha: ufbx_real; // < Blend weight of this layer
}
ufbx_texture_layer_list :: struct {
data: *ufbx_texture_layer;
count: size_t;
}
ufbx_shader_texture_type :: enum s32 {
UNKNOWN :: 0;
SELECT_OUTPUT :: 1;
OSL :: 2;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_SHADER_TEXTURE_UNKNOWN :: UNKNOWN;
UFBX_SHADER_TEXTURE_SELECT_OUTPUT :: SELECT_OUTPUT;
UFBX_SHADER_TEXTURE_OSL :: OSL;
UFBX_SHADER_TEXTURE_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_31 :: enum s32 {
UFBX_SHADER_TEXTURE_TYPE_COUNT :: 3;
}
ufbx_shader_texture_input :: struct {
// Name of the engine.input.
name: ufbx_string;
// Constant value of the engine.input.
union {
value_real: ufbx_real;
value_vec2: ufbx_vec2;
value_vec3: ufbx_vec3;
value_vec4: ufbx_vec4;
}
value_int: s64;
value_str: ufbx_string;
value_blob: ufbx_blob;
// Texture connected to this engine.input.
texture: *ufbx_texture;
// Index of the output to use if `texture` is a multi-output shader node.
texture_output_index: s64;
// Controls whether shading should use `texture`.
// NOTE: Some shading models allow this to be `true` even if `texture == NULL`.
texture_enabled: bool;
// Property representing this engine.input.
prop: *ufbx_prop;
// Property representing `texture`.
texture_prop: *ufbx_prop;
// Property representing `texture_enabled`.
texture_enabled_prop: *ufbx_prop;
}
ufbx_shader_texture_input_list :: struct {
data: *ufbx_shader_texture_input;
count: size_t;
}
ufbx_shader_texture :: struct {
// Type of this shader node.
type: ufbx_shader_texture_type;
// Name of the shader to use.
shader_name: ufbx_string;
// 64-bit opaque identifier for the shader type.
shader_type_id: u64;
// Input values/textures (possibly further shader textures) to the shader.
// Sorted by `ufbx_shader_texture_engine.input.name`.
inputs: ufbx_shader_texture_input_list;
// Shader source code if found.
shader_source: ufbx_string;
raw_shader_source: ufbx_blob;
// Representative texture for this shader.
// Only specified if `main_texture.outputs[main_texture_output_index]` is semantically
// equivalent to this texture.
main_texture: *ufbx_texture;
// Output index of `main_texture` if it is a multi-output shader.
main_texture_output_index: s64;
// Prefix for properties related to this shader in `ufbx_texture`.
// NOTE: Contains the trailing '|' if not empty.
prop_prefix: ufbx_string;
}
// Unique texture within the file.
ufbx_texture_file :: struct {
// Index in `ufbx_scene.texture_files[]`.
index: u32;
// Paths to the resource.
filename: ufbx_string;
absolute_filename: ufbx_string;
relative_filename: ufbx_string;
raw_filename: ufbx_blob;
raw_absolute_filename: ufbx_blob;
raw_relative_filename: ufbx_blob;
// Optional embedded content blob, eg. raw .png format data
content: ufbx_blob;
}
ufbx_texture_file_list :: struct {
data: *ufbx_texture_file;
count: size_t;
}
// Texture that controls material appearance
ufbx_texture :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Texture type (file / layered / procedural / shader)
type: ufbx_texture_type;
// FILE: Paths to the resource
filename: ufbx_string;
absolute_filename: ufbx_string;
relative_filename: ufbx_string;
raw_filename: ufbx_blob;
raw_absolute_filename: ufbx_blob;
raw_relative_filename: ufbx_blob;
// FILE: Optional embedded content blob, eg. raw .png format data
content: ufbx_blob;
// FILE: Optional video texture
video: *ufbx_video;
// FILE: Index into `ufbx_scene.texture_files[]` or `UFBX_NO_INDEX`.
file_index: u32;
// FILE: True if `file_index` has a valid value.
has_file: bool;
// LAYERED: Inner texture layers, ordered from _bottom_ to _top_
layers: ufbx_texture_layer_list;
// SHADER: Shader information
// NOTE: May be specified even if `type == UFBX_TEXTURE_FILE` if `ufbx_load_opts.disable_quirks`
// is _not_ specified. Some known shaders that represent files are interpreted as `UFBX_TEXTURE_FILE`.
shader: *ufbx_shader_texture;
// List of file textures representing this texture.
// Defined even if `type == UFBX_TEXTURE_FILE` in which case the array contains only itself.
file_textures: ufbx_texture_list;
// Name of the UV set to use
uv_set: ufbx_string;
// Wrapping mode
wrap_u: ufbx_wrap_mode;
wrap_v: ufbx_wrap_mode;
has_uv_transform: bool; // < Has a non-identity `transform` and derived matrices.
uv_transform: ufbx_transform #align 7; // < Texture transformation in UV space
texture_to_uv: ufbx_matrix; // < Matrix representation of `transform`
uv_to_texture: ufbx_matrix; // < UV coordinate to normalized texture coordinate matrix
}
// TODO: Video textures
ufbx_video :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Paths to the resource
filename: ufbx_string;
absolute_filename: ufbx_string;
relative_filename: ufbx_string;
raw_filename: ufbx_blob;
raw_absolute_filename: ufbx_blob;
raw_relative_filename: ufbx_blob;
// Optional embedded content blob
content: ufbx_blob;
}
// Shader specifies a shading model and contains `ufbx_shader_binding` elements
// that define how to interpret FBX properties in the shader.
ufbx_shader :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Known shading model
type: ufbx_shader_type;
// Bindings from FBX properties to the shader
// HINT: `ufbx_find_shader_prop()` translates shader properties to FBX properties
bindings: ufbx_shader_binding_list;
}
// Binding from a material property to shader implementation
ufbx_shader_prop_binding :: struct {
shader_prop: ufbx_string; // < Property name used by the shader implementation
material_prop: ufbx_string; // < Property name inside `ufbx_material.props`
}
ufbx_shader_prop_binding_list :: struct {
data: *ufbx_shader_prop_binding;
count: size_t;
}
// Shader binding table
ufbx_shader_binding :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
prop_bindings: ufbx_shader_prop_binding_list; // < Sorted by `shader_prop`
}
// -- Animation
ufbx_anim_layer_desc :: struct {
layer: *ufbx_anim_layer;
weight: ufbx_real;
}
ufbx_const_anim_layer_desc_list :: struct {
data: *ufbx_anim_layer_desc;
count: size_t;
}
ufbx_prop_override :: struct {
// Element (`ufbx_element.id`) to override the property from
// NOTE: You can get this from typed structs eg. `my_node->element.id`
element_id: u32;
// Property name to override.
prop_name: *u8;
// Override value, use `value.x` for scalars. `value_int` is initialized
// from `value.x` if zero so keep `value` zeroed even if you don't need it!
value: ufbx_vec3;
value_str: *u8;
value_int: s64;
// Internal: Gets filled automatically by `ufbx_prepare_prop_overrides()`
_internal_key: u32;
}
ufbx_const_prop_override_list :: struct {
data: *ufbx_prop_override;
count: size_t;
}
ufbx_anim :: struct {
layers: ufbx_const_anim_layer_desc_list;
// Override individual `ufbx_prop` values from elements
// NOTE: Call `ufbx_prepare_prop_overrides()` to obtain this!
prop_overrides: ufbx_const_prop_override_list;
ignore_connections: bool;
// Not used by evaluation
time_begin: float64;
time_end: float64;
}
ufbx_anim_stack :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
time_begin: float64;
time_end: float64;
layers: ufbx_anim_layer_list;
anim: ufbx_anim;
}
ufbx_anim_prop :: struct {
element: *ufbx_element;
_internal_key: u32;
prop_name: ufbx_string;
anim_value: *ufbx_anim_value;
}
ufbx_anim_prop_list :: struct {
data: *ufbx_anim_prop;
count: size_t;
}
ufbx_anim_layer :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
weight: ufbx_real;
weight_is_animated: bool;
blended: bool;
additive: bool;
compose_rotation: bool;
compose_scale: bool;
anim_values: ufbx_anim_value_list;
anim_props: ufbx_anim_prop_list; // < Sorted by `element,prop_name`
anim: ufbx_anim;
_min_element_id: u32;
_max_element_id: u32;
_element_id_bitmask: [4] u32;
}
ufbx_anim_value :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
}
}
default_value: ufbx_vec3;
curves: [3] *ufbx_anim_curve;
}
// Animation curve segment interpolation mode between two keyframes
ufbx_interpolation :: enum s32 {
CONSTANT_PREV :: 0;
CONSTANT_NEXT :: 1;
LINEAR :: 2;
CUBIC :: 3;
FORCE_32BIT :: 2147483647;
UFBX_INTERPOLATION_CONSTANT_PREV :: CONSTANT_PREV;
UFBX_INTERPOLATION_CONSTANT_NEXT :: CONSTANT_NEXT;
UFBX_INTERPOLATION_LINEAR :: LINEAR;
UFBX_INTERPOLATION_CUBIC :: CUBIC;
UFBX_INTERPOLATION_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_32 :: enum s32 {
UFBX_INTERPOLATION_COUNT :: 4;
}
// Tangent vector at a keyframe, may be split into left/right
ufbx_tangent :: struct {
dx: float; // < Derivative in the time axis
dy: float; // < Derivative in the (curve specific) value axis
}
// Single real `value` at a specified `time`, interpolation between two keyframes
// is determined by the `interpolation` field of the _previous_ key.
// If `interpolation == UFBX_INTERPOLATION_CUBIC` the span is evaluated as a
// cubic bezier curve through the following points:
//
// (prev->time, prev->value)
// (prev->time + prev->right.dx, prev->value + prev->right.dy)
// (next->time - next->left.dx, next->value - next->left.dy)
// (next->time, next->value)
//
// HINT: You can use `ufbx_evaluate_curve(ufbx_anim_curve *curve, double time)`
// rather than trying to manually handle all the interpolation modes.
ufbx_keyframe :: struct {
time: float64;
value: ufbx_real;
interpolation: ufbx_interpolation;
left: ufbx_tangent;
right: ufbx_tangent;
}
ufbx_keyframe_list :: struct {
data: *ufbx_keyframe;
count: size_t;
}
ufbx_anim_curve :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
keyframes: ufbx_keyframe_list;
}
// Collection of nodes to hide/freeze
ufbx_display_layer :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Nodes included in the layer (exclusively at most one layer per node)
nodes: ufbx_node_list;
visible: bool; // < Contained nodes are visible
frozen: bool; // < Contained nodes cannot be edited
ui_color: ufbx_vec3 #align 6; // < Visual color for UI
}
// Named set of nodes/geometry features to select.
ufbx_selection_set :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Included nodes and geometry features
nodes: ufbx_selection_node_list;
}
// Selection state of a node, potentially contains vertex/edge/face selection as well.
ufbx_selection_node :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Selection targets, possibly `NULL`
target_node: *ufbx_node;
target_mesh: *ufbx_mesh;
include_node: bool; // < Is `target_node` included in the selection
vertices: ufbx_uint32_list; // < Indices to `ufbx_mesh.vertices`
edges: ufbx_uint32_list; // < Indices to `ufbx_mesh.edges`
faces: ufbx_uint32_list; // < Indices to `ufbx_mesh.faces`
}
// -- Constraints
ufbx_character :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
}
// Type of property constrain eg. position or look-at
ufbx_constraint_type :: enum s32 {
UNKNOWN :: 0;
AIM :: 1;
PARENT :: 2;
POSITION :: 3;
ROTATION :: 4;
SCALE :: 5;
SINGLE_CHAIN_IK :: 6;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_CONSTRAINT_UNKNOWN :: UNKNOWN;
UFBX_CONSTRAINT_AIM :: AIM;
UFBX_CONSTRAINT_PARENT :: PARENT;
UFBX_CONSTRAINT_POSITION :: POSITION;
UFBX_CONSTRAINT_ROTATION :: ROTATION;
UFBX_CONSTRAINT_SCALE :: SCALE;
UFBX_CONSTRAINT_SINGLE_CHAIN_IK :: SINGLE_CHAIN_IK;
UFBX_CONSTRAINT_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_33 :: enum s32 {
UFBX_CONSTRAINT_TYPE_COUNT :: 7;
}
// Target to follow with a constraint
ufbx_constraint_target :: struct {
node: *ufbx_node; // < Target node reference
weight: ufbx_real; // < Relative weight to other targets (does not always sum to 1)
transform: ufbx_transform; // < Offset from the actual target
}
ufbx_constraint_target_list :: struct {
data: *ufbx_constraint_target;
count: size_t;
}
// Method to determine the up vector in aim constraints
ufbx_constraint_aim_up_type :: enum s32 {
SCENE :: 0;
TO_NODE :: 1;
ALIGN_NODE :: 2;
VECTOR :: 3;
NONE :: 4;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_CONSTRAINT_AIM_UP_SCENE :: SCENE;
UFBX_CONSTRAINT_AIM_UP_TO_NODE :: TO_NODE;
UFBX_CONSTRAINT_AIM_UP_ALIGN_NODE :: ALIGN_NODE;
UFBX_CONSTRAINT_AIM_UP_VECTOR :: VECTOR;
UFBX_CONSTRAINT_AIM_UP_NONE :: NONE;
UFBX_CONSTRAINT_AIM_UP_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_34 :: enum s32 {
UFBX_CONSTRAINT_AIM_UP_TYPE_COUNT :: 5;
}
// Method to determine the up vector in aim constraints
ufbx_constraint_ik_pole_type :: enum s32 {
VECTOR :: 0;
NODE :: 1;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_CONSTRAINT_IK_POLE_VECTOR :: VECTOR;
UFBX_CONSTRAINT_IK_POLE_NODE :: NODE;
UFBX_CONSTRAINT_IK_POLE_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_35 :: enum s32 {
UFBX_CONSTRAINT_IK_POLE_TYPE_COUNT :: 2;
}
ufbx_constraint :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
// Type of constraint to use
type: ufbx_constraint_type;
type_name: ufbx_string;
// Node to be constrained
node: *ufbx_node;
// List of weighted targets for the constraint (pole vectors for IK)
targets: ufbx_constraint_target_list;
// State of the constraint
weight: ufbx_real;
active: bool;
// Translation/rotation/scale axes the constraint is applied to
constrain_translation: [3] bool;
constrain_rotation: [3] bool;
constrain_scale: [3] bool;
// Offset from the constrained position
transform_offset: ufbx_transform #align 6;
// AIM: Target and up vectors
aim_vector: ufbx_vec3;
aim_up_type: ufbx_constraint_aim_up_type;
aim_up_node: *ufbx_node;
aim_up_vector: ufbx_vec3;
// SINGLE_CHAIN_IK: Target for the IK, `targets` contains pole vectors!
ik_effector: *ufbx_node;
ik_end_node: *ufbx_node;
ik_pole_vector: ufbx_vec3;
}
// -- Miscellaneous
ufbx_bone_pose :: struct {
bone_node: *ufbx_node;
bone_to_world: ufbx_matrix;
}
ufbx_bone_pose_list :: struct {
data: *ufbx_bone_pose;
count: size_t;
}
ufbx_pose :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
bind_pose: bool;
bone_poses: ufbx_bone_pose_list;
}
ufbx_metadata_object :: struct {
union {
element: ufbx_element;
struct {
name: ufbx_string;
props: ufbx_props;
element_id: u32;
typed_id: u32;
}
}
}
// -- Named elements
ufbx_name_element :: struct {
name: ufbx_string;
type: ufbx_element_type;
_internal_key: u32;
element: *ufbx_element;
}
ufbx_name_element_list :: struct {
data: *ufbx_name_element;
count: size_t;
}
// Scene is the root object loaded by ufbx that everything is accessed from.
ufbx_exporter :: enum s32 {
UNKNOWN :: 0;
FBX_SDK :: 1;
BLENDER_BINARY :: 2;
BLENDER_ASCII :: 3;
MOTION_BUILDER :: 4;
BC_UNITY_EXPORTER :: 5;
FORCE_32BIT :: 2147483647;
UFBX_EXPORTER_UNKNOWN :: UNKNOWN;
UFBX_EXPORTER_FBX_SDK :: FBX_SDK;
UFBX_EXPORTER_BLENDER_BINARY :: BLENDER_BINARY;
UFBX_EXPORTER_BLENDER_ASCII :: BLENDER_ASCII;
UFBX_EXPORTER_MOTION_BUILDER :: MOTION_BUILDER;
UFBX_EXPORTER_BC_UNITY_EXPORTER :: BC_UNITY_EXPORTER;
UFBX_EXPORTER_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_36 :: enum s32 {
UFBX_EXPORTER_COUNT :: 6;
}
ufbx_application :: struct {
vendor: ufbx_string;
name: ufbx_string;
version: ufbx_string;
}
ufbx_file_format :: enum s32 {
UNKNOWN :: 0;
FBX :: 1;
OBJ :: 2;
MTL :: 3;
FORCE_32BIT :: 2147483647;
UFBX_FILE_FORMAT_UNKNOWN :: UNKNOWN;
UFBX_FILE_FORMAT_FBX :: FBX;
UFBX_FILE_FORMAT_OBJ :: OBJ;
UFBX_FILE_FORMAT_MTL :: MTL;
UFBX_FILE_FORMAT_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_37 :: enum s32 {
UFBX_FILE_FORMAT_COUNT :: 4;
}
ufbx_warning_type :: enum s32 {
MISSING_EXTERNAL_FILE :: 0;
IMPLICIT_MTL :: 1;
TRUNCATED_ARRAY :: 2;
INDEX_CLAMPED :: 3;
BAD_UNICODE :: 4;
BAD_ELEMENT_CONNECTED_TO_ROOT :: 5;
DUPLICATE_OBJECT_ID :: 6;
EMPTY_FACE_REMOVED :: 7;
UNKNOWN_OBJ_DIRECTIVE :: 8;
TYPE_FIRST_DEDUPLICATED :: 3;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_WARNING_MISSING_EXTERNAL_FILE :: MISSING_EXTERNAL_FILE;
UFBX_WARNING_IMPLICIT_MTL :: IMPLICIT_MTL;
UFBX_WARNING_TRUNCATED_ARRAY :: TRUNCATED_ARRAY;
UFBX_WARNING_INDEX_CLAMPED :: INDEX_CLAMPED;
UFBX_WARNING_BAD_UNICODE :: BAD_UNICODE;
UFBX_WARNING_BAD_ELEMENT_CONNECTED_TO_ROOT :: BAD_ELEMENT_CONNECTED_TO_ROOT;
UFBX_WARNING_DUPLICATE_OBJECT_ID :: DUPLICATE_OBJECT_ID;
UFBX_WARNING_EMPTY_FACE_REMOVED :: EMPTY_FACE_REMOVED;
UFBX_WARNING_UNKNOWN_OBJ_DIRECTIVE :: UNKNOWN_OBJ_DIRECTIVE;
UFBX_WARNING_TYPE_FIRST_DEDUPLICATED :: TYPE_FIRST_DEDUPLICATED;
UFBX_WARNING_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_38 :: enum s32 {
UFBX_WARNING_TYPE_COUNT :: 9;
}
// Warning about a non-fatal issue in the file.
// Often contains information about issues that ufbx has corrected about the
// file but it might indicate something is not working properly.
ufbx_warning :: struct {
// Type of the warning.
type: ufbx_warning_type;
// Description of the warning.
description: ufbx_string;
// Number of times this warning was encountered.
count: size_t;
}
ufbx_warning_list :: struct {
data: *ufbx_warning;
count: size_t;
}
// Miscellaneous data related to the loaded file
ufbx_metadata :: struct {
// List of non-fatal warnings about the file.
// If you need to only check whether a specific warning was triggered you
// can use `ufbx_metadata.has_warning[]`.
warnings: ufbx_warning_list;
// FBX ASCII file format.
ascii: bool;
// FBX version in integer format, eg. 7400 for 7.4.
version: u32;
// File format of the source file.
file_format: ufbx_file_format;
// Index arrays may contain `UFBX_NO_INDEX` instead of a valid index
// to indicate gaps.
may_contain_no_index: bool;
// May contain `ufbx_mesh_material` entries where `ufbx_mesh_material.material == NULL`.
// NOTE: The corresponding `ufbx_node.material[]` will be empty in this case.
may_contain_null_materials: bool;
// May contain meshes with no defined vertex position.
// NOTE: `ufbx_mesh.vertex_position.exists` may be `false`!
may_contain_missing_vertex_position: bool;
// Arrays may contain items with `NULL` element references.
// See `ufbx_load_opts.connect_broken_elements`.
may_contain_broken_elements: bool;
// Some API guarantees do not apply (depending on unsafe options used).
// Loaded with `ufbx_load_opts.allow_unsafe` enabled.
is_unsafe: bool;
// Flag for each possible warning type.
// See `ufbx_metadata.warnings[]` for detailed warning information.
has_warning: [9] bool;
creator: ufbx_string;
big_endian: bool;
filename: ufbx_string;
relative_root: ufbx_string;
raw_filename: ufbx_blob;
raw_relative_root: ufbx_blob;
exporter: ufbx_exporter;
exporter_version: u32;
scene_props: ufbx_props;
original_application: ufbx_application;
latest_application: ufbx_application;
geometry_ignored: bool;
animation_ignored: bool;
embedded_ignored: bool;
max_face_triangles: size_t;
result_memory_used: size_t;
temp_memory_used: size_t;
result_allocs: size_t;
temp_allocs: size_t;
element_buffer_size: size_t;
num_shader_textures: size_t;
bone_prop_size_unit: ufbx_real;
bone_prop_limb_length_relative: bool;
ktime_to_sec: float64;
original_file_path: ufbx_string;
raw_original_file_path: ufbx_blob;
}
ufbx_time_mode :: enum s32 {
DEFAULT :: 0;
_120_FPS :: 1;
_100_FPS :: 2;
_60_FPS :: 3;
_50_FPS :: 4;
_48_FPS :: 5;
_30_FPS :: 6;
_30_FPS_DROP :: 7;
NTSC_DROP_FRAME :: 8;
NTSC_FULL_FRAME :: 9;
PAL :: 10;
_24_FPS :: 11;
_1000_FPS :: 12;
FILM_FULL_FRAME :: 13;
CUSTOM :: 14;
_96_FPS :: 15;
_72_FPS :: 16;
_59_94_FPS :: 17;
FORCE_32BIT :: 2147483647;
UFBX_TIME_MODE_DEFAULT :: DEFAULT;
UFBX_TIME_MODE_120_FPS :: _120_FPS;
UFBX_TIME_MODE_100_FPS :: _100_FPS;
UFBX_TIME_MODE_60_FPS :: _60_FPS;
UFBX_TIME_MODE_50_FPS :: _50_FPS;
UFBX_TIME_MODE_48_FPS :: _48_FPS;
UFBX_TIME_MODE_30_FPS :: _30_FPS;
UFBX_TIME_MODE_30_FPS_DROP :: _30_FPS_DROP;
UFBX_TIME_MODE_NTSC_DROP_FRAME :: NTSC_DROP_FRAME;
UFBX_TIME_MODE_NTSC_FULL_FRAME :: NTSC_FULL_FRAME;
UFBX_TIME_MODE_PAL :: PAL;
UFBX_TIME_MODE_24_FPS :: _24_FPS;
UFBX_TIME_MODE_1000_FPS :: _1000_FPS;
UFBX_TIME_MODE_FILM_FULL_FRAME :: FILM_FULL_FRAME;
UFBX_TIME_MODE_CUSTOM :: CUSTOM;
UFBX_TIME_MODE_96_FPS :: _96_FPS;
UFBX_TIME_MODE_72_FPS :: _72_FPS;
UFBX_TIME_MODE_59_94_FPS :: _59_94_FPS;
UFBX_TIME_MODE_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_39 :: enum s32 {
UFBX_TIME_MODE_COUNT :: 18;
}
ufbx_time_protocol :: enum s32 {
SMPTE :: 0;
FRAME_COUNT :: 1;
DEFAULT :: 2;
FORCE_32BIT :: 2147483647;
UFBX_TIME_PROTOCOL_SMPTE :: SMPTE;
UFBX_TIME_PROTOCOL_FRAME_COUNT :: FRAME_COUNT;
UFBX_TIME_PROTOCOL_DEFAULT :: DEFAULT;
UFBX_TIME_PROTOCOL_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_40 :: enum s32 {
UFBX_TIME_PROTOCOL_COUNT :: 3;
}
ufbx_snap_mode :: enum s32 {
NONE :: 0;
SNAP :: 1;
PLAY :: 2;
SNAP_AND_PLAY :: 3;
FORCE_32BIT :: 2147483647;
UFBX_SNAP_MODE_NONE :: NONE;
UFBX_SNAP_MODE_SNAP :: SNAP;
UFBX_SNAP_MODE_PLAY :: PLAY;
UFBX_SNAP_MODE_SNAP_AND_PLAY :: SNAP_AND_PLAY;
UFBX_SNAP_MODE_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_41 :: enum s32 {
UFBX_SNAP_MODE_COUNT :: 4;
}
// Global settings: Axes and time/unit scales
ufbx_scene_settings :: struct {
props: ufbx_props;
// Mapping of X/Y/Z axes to world-space directions.
// HINT: Use `ufbx_load_opts.target_axes` to normalize this.
// NOTE: This contains the _original_ axes even if you supply `ufbx_load_opts.target_axes`.
axes: ufbx_coordinate_axes;
// How many meters does a single world-space unit represent.
// FBX files usually default to centimeters, reported as `0.01` here.
// HINT: Use `ufbx_load_opts.target_unit_meters` to normalize this.
unit_meters: ufbx_real;
frames_per_second: float64;
ambient_color: ufbx_vec3;
default_camera: ufbx_string;
time_mode: ufbx_time_mode;
time_protocol: ufbx_time_protocol;
snap_mode: ufbx_snap_mode;
// Original settings (?)
original_axis_up: ufbx_coordinate_axis;
original_unit_meters: ufbx_real;
}
ufbx_scene :: struct {
metadata: ufbx_metadata;
// Global settings
settings: ufbx_scene_settings;
// Node instances in the scene
root_node: *ufbx_node;
// Default animation descriptor
anim: ufbx_anim;
// All animation stacks combined
combined_anim: ufbx_anim;
union {
struct {
unknowns: ufbx_unknown_list;
// Nodes
nodes: ufbx_node_list;
// Node attributes (common)
meshes: ufbx_mesh_list;
lights: ufbx_light_list;
cameras: ufbx_camera_list;
bones: ufbx_bone_list;
empties: ufbx_empty_list;
// Node attributes (curves/surfaces)
line_curves: ufbx_line_curve_list;
nurbs_curves: ufbx_nurbs_curve_list;
nurbs_surfaces: ufbx_nurbs_surface_list;
nurbs_trim_surfaces: ufbx_nurbs_trim_surface_list;
nurbs_trim_boundaries: ufbx_nurbs_trim_boundary_list;
// Node attributes (advanced)
procedural_geometries: ufbx_procedural_geometry_list;
stereo_cameras: ufbx_stereo_camera_list;
camera_switchers: ufbx_camera_switcher_list;
markers: ufbx_marker_list;
lod_groups: ufbx_lod_group_list;
// Deformers
skin_deformers: ufbx_skin_deformer_list;
skin_clusters: ufbx_skin_cluster_list;
blend_deformers: ufbx_blend_deformer_list;
blend_channels: ufbx_blend_channel_list;
blend_shapes: ufbx_blend_shape_list;
cache_deformers: ufbx_cache_deformer_list;
cache_files: ufbx_cache_file_list;
// Materials
materials: ufbx_material_list;
textures: ufbx_texture_list;
videos: ufbx_video_list;
shaders: ufbx_shader_list;
shader_bindings: ufbx_shader_binding_list;
// Animation
anim_stacks: ufbx_anim_stack_list;
anim_layers: ufbx_anim_layer_list;
anim_values: ufbx_anim_value_list;
anim_curves: ufbx_anim_curve_list;
// Collections
display_layers: ufbx_display_layer_list;
selection_sets: ufbx_selection_set_list;
selection_nodes: ufbx_selection_node_list;
// Constraints
characters: ufbx_character_list;
constraints: ufbx_constraint_list;
// Miscellaneous
poses: ufbx_pose_list;
metadata_objects: ufbx_metadata_object_list;
}
elements_by_type: [40] ufbx_element_list;
}
// Unique texture files referenced by the scene.
texture_files: ufbx_texture_file_list;
elements: ufbx_element_list; // < Sorted by `id`
connections_src: ufbx_connection_list; // < Sorted by `src,src_prop`
connections_dst: ufbx_connection_list; // < Sorted by `dst,dst_prop`
// Elements sorted by name, type
elements_by_name: ufbx_name_element_list;
// Enabled if `ufbx_load_opts.retain_dom == true`.
dom_root: *ufbx_dom_node;
}
// -- Curves
ufbx_curve_point :: struct {
valid: bool;
position: ufbx_vec3 #align 7;
derivative: ufbx_vec3;
}
ufbx_surface_point :: struct {
valid: bool;
position: ufbx_vec3 #align 7;
derivative_u: ufbx_vec3;
derivative_v: ufbx_vec3;
}
// -- Mesh topology
ufbx_topo_flags :: enum s32 {
NON_MANIFOLD :: 1;
FLAGS_FORCE_32BIT :: 2147483647;
UFBX_TOPO_NON_MANIFOLD :: NON_MANIFOLD;
UFBX_TOPO_FLAGS_FORCE_32BIT :: FLAGS_FORCE_32BIT;
}
ufbx_topo_edge :: struct {
index: u32; // < Starting index of the edge, always defined
next: u32; // < Ending index of the edge / next per-face `ufbx_topo_edge`, always defined
prev: u32; // < Previous per-face `ufbx_topo_edge`, always defined
twin: u32; // < `ufbx_topo_edge` on the opposite side, `UFBX_NO_INDEX` if not found
face: u32; // < Index into `mesh->faces[]`, always defined
edge: u32; // < Index into `mesh->edges[]`, `UFBX_NO_INDEX` if not found
flags: ufbx_topo_flags;
}
ufbx_vertex_stream :: struct {
data: *void;
vertex_size: size_t;
}
// Allocate `size` bytes, must be at least 8 byte aligned
ufbx_alloc_fn :: #type (user: *void, size: size_t) -> *void #c_call;
// Reallocate `old_ptr` from `old_size` to `new_size`
// NOTE: If omit `alloc_fn` and `free_fn` they will be translated to:
// `alloc(size)` -> `realloc_fn(user, NULL, 0, size)`
// `free_fn(ptr, size)` -> `realloc_fn(user, ptr, size, 0)`
ufbx_realloc_fn :: #type (user: *void, old_ptr: *void, old_size: size_t, new_size: size_t) -> *void #c_call;
// Free pointer `ptr` (of `size` bytes) returned by `alloc_fn` or `realloc_fn`
ufbx_free_fn :: #type (user: *void, ptr: *void, size: size_t) -> void #c_call;
// Free the allocator itself
ufbx_free_allocator_fn :: #type (user: *void) -> void #c_call;
// Allocator callbacks and user context
// NOTE: The allocator will be stored to the loaded scene and will be called
// again from `ufbx_free_scene()` so make sure `user` outlives that!
// You can use `free_allocator_fn()` to free the allocator yourself.
ufbx_allocator :: struct {
// Callback functions, see `typedef`s above for information
alloc_fn: ufbx_alloc_fn;
realloc_fn: ufbx_realloc_fn;
free_fn: ufbx_free_fn;
free_allocator_fn: ufbx_free_allocator_fn;
user: *void;
}
ufbx_allocator_opts :: struct {
// Allocator callbacks
allocator: ufbx_allocator;
// Maximum number of bytes to allocate before failing
memory_limit: size_t;
// Maximum number of allocations to attempt before failing
allocation_limit: size_t;
// Threshold to swap from batched allocations to individual ones
// Defaults to 1MB if set to zero
// NOTE: If set to `1` ufbx will allocate everything in the smallest
// possible chunks which may be useful for debugging (eg. ASAN)
huge_threshold: size_t;
// Maximum size of a single allocation containing sub-allocations.
// Defaults to 16MB if set to zero
// The maximum amount of wasted memory depends on `max_chunk_size` and
// `huge_threshold`: each chunk can waste up to `huge_threshold` bytes
// internally and the last chunk might be incomplete. So for example
// with the defaults we can waste around 1MB/16MB = 6.25% overall plus
// up to 32MB due to the two incomplete blocks. The actual amounts differ
// slightly as the chunks start out at 4kB and double in size each time,
// meaning that the maximum fixed overhead (up to 32MB with defaults) is
// at most ~30% of the total allocation size.
max_chunk_size: size_t;
}
// Try to read up to `size` bytes to `data`, return the amount of read bytes.
// Return `SIZE_MAX` to indicate an IO error.
ufbx_read_fn :: #type (user: *void, data: *void, size: size_t) -> size_t #c_call;
// Skip `size` bytes in the file.
ufbx_skip_fn :: #type (user: *void, size: size_t) -> bool #c_call;
// Close the file
ufbx_close_fn :: #type (user: *void) -> void #c_call;
ufbx_stream :: struct {
read_fn: ufbx_read_fn; // < Required
skip_fn: ufbx_skip_fn; // < Optional: Will use `read_fn()` if missing
close_fn: ufbx_close_fn; // < Optional
// Context passed to other functions
user: *void;
}
ufbx_open_file_type :: enum s32 {
MAIN_MODEL :: 0;
GEOMETRY_CACHE :: 1;
OBJ_MTL :: 2;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_OPEN_FILE_MAIN_MODEL :: MAIN_MODEL;
UFBX_OPEN_FILE_GEOMETRY_CACHE :: GEOMETRY_CACHE;
UFBX_OPEN_FILE_OBJ_MTL :: OBJ_MTL;
UFBX_OPEN_FILE_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_42 :: enum s32 {
UFBX_OPEN_FILE_TYPE_COUNT :: 3;
}
ufbx_open_file_info :: struct {
// Kind of file to load.
type: ufbx_open_file_type;
// Temporary allocator to use.
temp_allocator: ufbx_allocator;
// Original filename in the file, not resolved or UTF-8 encoded.
// NOTE: Not necessarily NULL-terminated!
original_filename: ufbx_blob;
}
// Callback for opening an external file from the filesystem
ufbx_open_file_fn :: #type (user: *void, stream: *ufbx_stream, path: *u8, path_len: size_t, info: *ufbx_open_file_info) -> bool #c_call;
ufbx_open_file_cb :: struct {
fn: ufbx_open_file_fn;
user: *void;
}
// Memory stream options
ufbx_close_memory_fn :: #type (user: *void, data: *void, data_size: size_t) -> void #c_call;
ufbx_close_memory_cb :: struct {
fn: ufbx_close_memory_fn;
user: *void;
}
// Options for `ufbx_open_memory()`.
ufbx_open_memory_opts :: struct {
_begin_zero: u32;
// Allocator to allocate the memory with.
// NOTE: Used even if no copy is made to allocate a small metadata block.
allocator: ufbx_allocator_opts;
// Do not copy the memory.
// You can use `close_cb` to free the memory when the stream is closed.
// NOTE: This means the provided data pointer is referenced after creating
// the memory stream, make sure the data stays valid until the stream is closed!
no_copy: bool;
// Callback to free the memory blob.
close_cb: ufbx_close_memory_cb;
_end_zero: u32;
}
// Detailed error stack frame
ufbx_error_frame :: struct {
source_line: u32;
function: ufbx_string;
description: ufbx_string;
}
// Error causes (and `UFBX_ERROR_NONE` for no error).
ufbx_error_type :: enum s32 {
NONE :: 0;
UNKNOWN :: 1;
FILE_NOT_FOUND :: 2;
OUT_OF_MEMORY :: 3;
MEMORY_LIMIT :: 4;
ALLOCATION_LIMIT :: 5;
TRUNCATED_FILE :: 6;
IO :: 7;
CANCELLED :: 8;
UNRECOGNIZED_FILE_FORMAT :: 9;
UNINITIALIZED_OPTIONS :: 10;
ZERO_VERTEX_SIZE :: 11;
INVALID_UTF8 :: 12;
FEATURE_DISABLED :: 13;
BAD_NURBS :: 14;
BAD_INDEX :: 15;
UNSAFE_OPTIONS :: 16;
TYPE_FORCE_32BIT :: 2147483647;
UFBX_ERROR_NONE :: NONE;
UFBX_ERROR_UNKNOWN :: UNKNOWN;
UFBX_ERROR_FILE_NOT_FOUND :: FILE_NOT_FOUND;
UFBX_ERROR_OUT_OF_MEMORY :: OUT_OF_MEMORY;
UFBX_ERROR_MEMORY_LIMIT :: MEMORY_LIMIT;
UFBX_ERROR_ALLOCATION_LIMIT :: ALLOCATION_LIMIT;
UFBX_ERROR_TRUNCATED_FILE :: TRUNCATED_FILE;
UFBX_ERROR_IO :: IO;
UFBX_ERROR_CANCELLED :: CANCELLED;
UFBX_ERROR_UNRECOGNIZED_FILE_FORMAT :: UNRECOGNIZED_FILE_FORMAT;
UFBX_ERROR_UNINITIALIZED_OPTIONS :: UNINITIALIZED_OPTIONS;
UFBX_ERROR_ZERO_VERTEX_SIZE :: ZERO_VERTEX_SIZE;
UFBX_ERROR_INVALID_UTF8 :: INVALID_UTF8;
UFBX_ERROR_FEATURE_DISABLED :: FEATURE_DISABLED;
UFBX_ERROR_BAD_NURBS :: BAD_NURBS;
UFBX_ERROR_BAD_INDEX :: BAD_INDEX;
UFBX_ERROR_UNSAFE_OPTIONS :: UNSAFE_OPTIONS;
UFBX_ERROR_TYPE_FORCE_32BIT :: TYPE_FORCE_32BIT;
}
anon_enum_43 :: enum s32 {
UFBX_ERROR_TYPE_COUNT :: 17;
}
// Error description with detailed stack trace
// HINT: You can use `ufbx_format_error()` for formatting the error
ufbx_error :: struct {
type: ufbx_error_type;
description: ufbx_string;
stack_size: u32;
stack: [8] ufbx_error_frame;
info_length: size_t;
info: [256] u8;
}
// -- Progress callbacks
ufbx_progress :: struct {
bytes_read: u64;
bytes_total: u64;
}
ufbx_progress_result :: enum s32 {
CONTINUE :: 256;
CANCEL :: 512;
RESULT_FORCE_32BIT :: 2147483647;
UFBX_PROGRESS_CONTINUE :: CONTINUE;
UFBX_PROGRESS_CANCEL :: CANCEL;
UFBX_PROGRESS_RESULT_FORCE_32BIT :: RESULT_FORCE_32BIT;
}
// Called periodically with the current progress
// Return `false` to cancel further processing
ufbx_progress_fn :: #type (user: *void, progress: *ufbx_progress) -> ufbx_progress_result #c_call;
ufbx_progress_cb :: struct {
fn: ufbx_progress_fn;
user: *void;
}
// Source data/stream to decompress with `ufbx_inflate()`
ufbx_inflate_input :: struct {
// Total size of the data in bytes
total_size: size_t;
// (optional) Initial or complete data chunk
data: *void;
data_size: size_t;
// (optional) Temporary buffer, defaults to 256b stack buffer
buffer: *void;
buffer_size: size_t;
// (optional) Streaming read function, concatenated after `data`
read_fn: ufbx_read_fn;
read_user: *void;
// (optional) Progress reporting
progress_cb: ufbx_progress_cb;
progress_interval_hint: u64; // < Bytes between progress report calls
// (optional) Change the progress scope
progress_size_before: u64;
progress_size_after: u64;
// (optional) No the DEFLATE header
no_header: bool;
// (optional) No the Adler32 checksum
no_checksum: bool;
// (optional) Force internal fast lookup bit amount
internal_fast_bits: size_t;
}
// Persistent data between `ufbx_inflate()` calls
// NOTE: You must set `initialized` to `false`, but `data` may be uninitialized
ufbx_inflate_retain :: struct {
initialized: bool;
data: [1024] u64;
}
ufbx_index_error_handling :: enum s32 {
CLAMP :: 0;
NO_INDEX :: 1;
ABORT_LOADING :: 2;
UNSAFE_IGNORE :: 3;
FORCE_32BIT :: 2147483647;
UFBX_INDEX_ERROR_HANDLING_CLAMP :: CLAMP;
UFBX_INDEX_ERROR_HANDLING_NO_INDEX :: NO_INDEX;
UFBX_INDEX_ERROR_HANDLING_ABORT_LOADING :: ABORT_LOADING;
UFBX_INDEX_ERROR_HANDLING_UNSAFE_IGNORE :: UNSAFE_IGNORE;
UFBX_INDEX_ERROR_HANDLING_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_44 :: enum s32 {
UFBX_INDEX_ERROR_HANDLING_COUNT :: 4;
}
ufbx_unicode_error_handling :: enum s32 {
REPLACEMENT_CHARACTER :: 0;
UNDERSCORE :: 1;
QUESTION_MARK :: 2;
REMOVE :: 3;
ABORT_LOADING :: 4;
UNSAFE_IGNORE :: 5;
FORCE_32BIT :: 2147483647;
UFBX_UNICODE_ERROR_HANDLING_REPLACEMENT_CHARACTER :: REPLACEMENT_CHARACTER;
UFBX_UNICODE_ERROR_HANDLING_UNDERSCORE :: UNDERSCORE;
UFBX_UNICODE_ERROR_HANDLING_QUESTION_MARK :: QUESTION_MARK;
UFBX_UNICODE_ERROR_HANDLING_REMOVE :: REMOVE;
UFBX_UNICODE_ERROR_HANDLING_ABORT_LOADING :: ABORT_LOADING;
UFBX_UNICODE_ERROR_HANDLING_UNSAFE_IGNORE :: UNSAFE_IGNORE;
UFBX_UNICODE_ERROR_HANDLING_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_45 :: enum s32 {
UFBX_UNICODE_ERROR_HANDLING_COUNT :: 6;
}
// How to handle FBX node geometry transforms.
// FBX nodes can have "geometry transforms" that affect only the attached meshes,
// but not the children. This is not allowed in many scene representations so
// ufbx provides some ways to simplify them.
// Geometry transforms can also be used to transform any other attributes such
// as lights or cameras.
ufbx_geometry_transform_handling :: enum s32 {
PRESERVE :: 0;
HELPER_NODES :: 1;
MODIFY_GEOMETRY :: 2;
MODIFY_GEOMETRY_NO_FALLBACK :: 3;
FORCE_32BIT :: 2147483647;
UFBX_GEOMETRY_TRANSFORM_HANDLING_PRESERVE :: PRESERVE;
UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES :: HELPER_NODES;
UFBX_GEOMETRY_TRANSFORM_HANDLING_MODIFY_GEOMETRY :: MODIFY_GEOMETRY;
UFBX_GEOMETRY_TRANSFORM_HANDLING_MODIFY_GEOMETRY_NO_FALLBACK :: MODIFY_GEOMETRY_NO_FALLBACK;
UFBX_GEOMETRY_TRANSFORM_HANDLING_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_46 :: enum s32 {
UFBX_GEOMETRY_TRANSFORM_HANDLING_COUNT :: 4;
}
// Specify how unit / coordinate system conversion should be performed.
// Affects how `ufbx_load_opts.target_axes` and `ufbx_load_opts.target_unit_meters` work,
// has no effect if neither is specified.
ufbx_space_conversion :: enum s32 {
TRANSFORM_ROOT :: 0;
ADJUST_TRANSFORMS :: 1;
FORCE_32BIT :: 2147483647;
UFBX_SPACE_CONVERSION_TRANSFORM_ROOT :: TRANSFORM_ROOT;
UFBX_SPACE_CONVERSION_ADJUST_TRANSFORMS :: ADJUST_TRANSFORMS;
UFBX_SPACE_CONVERSION_FORCE_32BIT :: FORCE_32BIT;
}
anon_enum_47 :: enum s32 {
UFBX_SPACE_CONVERSION_COUNT :: 2;
}
// Options for `ufbx_load_file/memory/stream/stdio()`
// NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
ufbx_load_opts :: struct {
_begin_zero: u32;
temp_allocator: ufbx_allocator_opts; // < Allocator used during loading
result_allocator: ufbx_allocator_opts; // < Allocator used for the final scene
ignore_geometry: bool; // < Do not load geometry datsa (vertices, indices, etc)
ignore_animation: bool; // < Do not load animation curves
ignore_embedded: bool; // < Do not load embedded content
ignore_all_content: bool; // < Do not load any content (geometry, animation, embedded)
evaluate_skinning: bool; // < Evaluate skinning (see ufbx_mesh.skinned_vertices)
evaluate_caches: bool; // < Evaluate vertex caches (see ufbx_mesh.skinned_vertices)
// Try to open external files referenced by the main file automatically.
// Applies to geometry caches and .mtl files for OBJ.
// NOTE: This may be risky for untrusted data as the input files may contain
// references to arbitrary paths in the filesystem.
// NOTE: This only applies to files *implicitly* referenced by the scene, if
// you request additional files via eg. `ufbx_load_opts.obj_mtl_path` they
// are still loaded.
load_external_files: bool;
// Don't fail loading if external files are not found.
ignore_missing_external_files: bool;
// Don't compute `ufbx_skin_deformer` `vertices` and `weights` arrays saving
// a bit of memory and time if not needed
skip_skin_vertices: bool;
// Don't adjust reading the FBX file depending on the detected exporter
disable_quirks: bool;
// Don't allow partially broken FBX files to load
strict: bool;
// UNSAFE: If enabled allows using unsafe options that may fundamentally
// break the API guarantees.
allow_unsafe: bool;
// Specify how to handle broken indices.
index_error_handling: ufbx_index_error_handling;
// Connect related elements even if they are broken. If `false` (default)
// `ufbx_skin_cluster` with a missing `bone` field are _not_ included in
// the `ufbx_skin_deformer.clusters[]` array for example.
connect_broken_elements: bool;
// Allow nodes that are not connected in any way to the root. Conversely if
// disabled, all lone nodes will be parented under `ufbx_scene.root_node`.
allow_nodes_out_of_root: bool;
// If a mesh does not have a material create a `ufbx_mesh_material` part
// with a `NULL` material pointer. This can be more convenient if you need
// to split models into parts per material.
allow_null_material: bool;
// Allow meshes with no vertex position attribute.
// NOTE: If this is set `ufbx_mesh.vertex_position.exists` may be `false`.
allow_missing_vertex_position: bool;
// Allow faces with zero indices.
allow_empty_faces: bool;
// Generate vertex normals for a meshes that are missing normals.
// You can see if the normals have been generated from `ufbx_mesh.generated_normals`.
generate_missing_normals: bool;
// Ignore `open_file_cb` when loading the main file.
open_main_file_with_default: bool;
// Path separator character, defaults to '\' on Windows and '/' otherwise.
path_separator: u8;
// Estimated file size for progress reporting
file_size_estimate: u64;
// Buffer size in bytes to use for reading from files or IO callbacks
read_buffer_size: size_t;
// Filename to use as a base for relative file paths if not specified using
// `ufbx_load_file()`. Use `length = SIZE_MAX` for NULL-terminated strings.
// `raw_filename` will be derived from this if empty.
filename: ufbx_string;
// Raw non-UTF8 filename. Does not support NULL termination.
// `filename` will be derived from this if empty.
raw_filename: ufbx_blob;
// Progress reporting
progress_cb: ufbx_progress_cb;
progress_interval_hint: u64; // < Bytes between progress report calls
// External file callbacks (defaults to stdio.h)
open_file_cb: ufbx_open_file_cb;
// How to handle geometry transforms in the nodes.
// See `ufbx_geometry_transform_handling` for an explanation.
geometry_transform_handling: ufbx_geometry_transform_handling;
// How to perform space conversion by `target_axes` and `target_unit_meters`.
// See `ufbx_space_conversion` for an explanation.
space_conversion: ufbx_space_conversion;
// Apply an implicit root transformation to match axes.
// Used if `ufbx_coordinate_axes_valid(target_axes)`.
target_axes: ufbx_coordinate_axes;
// Scale the scene so that one world-space unit is `target_unit_meters` meters.
// By default units are not scaled.
target_unit_meters: ufbx_real;
// Target space for camera.
// By default FBX cameras point towards the positive X axis.
// Used if `ufbx_coordinate_axes_valid(target_camera_axes)`.
target_camera_axes: ufbx_coordinate_axes;
// Target space for directed lights.
// By default FBX lights point towards the negative Y axis.
// Used if `ufbx_coordinate_axes_valid(target_light_axes)`.
target_light_axes: ufbx_coordinate_axes;
// Name for dummy geometry transform helper nodes.
// See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`.
geometry_transform_helper_name: ufbx_string;
// Do not scale necessary properties curves with `target_unit_meters`.
// Used only if `space_conversion == UFBX_SPACE_CONVERSION_TRANSFORM_ROOT`.
no_prop_unit_scaling: bool;
// Do not scale necessary animation curves with `target_unit_meters`.
// Used only if `space_conversion == UFBX_SPACE_CONVERSION_TRANSFORM_ROOT`.
no_anim_curve_unit_scaling: bool;
// Normalize vertex normals.
normalize_normals: bool;
// Normalize tangents and bitangents.
normalize_tangents: bool;
// Override for the root transform
use_root_transform: bool;
root_transform: ufbx_transform #align 3;
// Specify how to handle Unicode errors in strings.
unicode_error_handling: ufbx_unicode_error_handling;
// Retain the raw document structure using `ufbx_dom_node`.
retain_dom: bool;
// Force a specific file format instead of detecting it.
file_format: ufbx_file_format;
// How far to read into the file to determine the file format.
// Default: 16kB
file_format_lookahead: size_t;
// Do not attempt to detect file format from file content.
no_format_from_content: bool;
// Do not attempt to detect file format from filename extension.
// ufbx primarily detects file format from the file header,
// this is just used as a fallback.
no_format_from_extension: bool;
// (.obj) Try to find .mtl file with matching filename as the .obj file.
// Used if the file specified `mtllib` line is not found, eg. for a file called
// `model.obj` that contains the line `usemtl materials.mtl`, ufbx would first
// try to open `materials.mtl` and if that fails it tries to open `model.mtl`.
obj_search_mtl_by_filename: bool;
// (.obj) Don't split geometry into meshes by object.
obj_merge_objects: bool;
// (.obj) Don't split geometry into meshes by groups.
obj_merge_groups: bool;
// (.obj) Force splitting groups even on object boundaries.
obj_split_groups: bool;
// (.obj) Path to the .mtl file.
// Use `length = SIZE_MAX` for NULL-terminated strings.
// NOTE: This is used _instead_ of the one in the file even if not found
// and sidesteps `load_external_files` as it's _explicitly_ requested.
obj_mtl_path: ufbx_string;
// (.obj) Data for the .mtl file.
obj_mtl_data: ufbx_blob;
_end_zero: u32;
}
// Options for `ufbx_evaluate_scene()`
// NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
ufbx_evaluate_opts :: struct {
_begin_zero: u32;
temp_allocator: ufbx_allocator_opts; // < Allocator used during evaluation
result_allocator: ufbx_allocator_opts; // < Allocator used for the final scene
evaluate_skinning: bool; // < Evaluate skinning (see ufbx_mesh.skinned_vertices)
evaluate_caches: bool; // < Evaluate vertex caches (see ufbx_mesh.skinned_vertices)
// WARNING: Potentially unsafe! Try to open external files such as geometry caches
load_external_files: bool;
// External file callbacks (defaults to stdio.h)
open_file_cb: ufbx_open_file_cb;
_end_zero: u32;
}
// Options for `ufbx_tessellate_nurbs_curve()`
// NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
ufbx_tessellate_curve_opts :: struct {
_begin_zero: u32;
temp_allocator: ufbx_allocator_opts; // < Allocator used during tessellation
result_allocator: ufbx_allocator_opts; // < Allocator used for the final line curve
// How many segments tessellate each step in `ufbx_nurbs_basis.steps`.
span_subdivision: u32;
_end_zero: u32;
}
// Options for `ufbx_tessellate_nurbs_surface()`
// NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
ufbx_tessellate_surface_opts :: struct {
_begin_zero: u32;
temp_allocator: ufbx_allocator_opts; // < Allocator used during tessellation
result_allocator: ufbx_allocator_opts; // < Allocator used for the final mesh
// How many segments tessellate each step in `ufbx_nurbs_basis.steps`.
// NOTE: Default is `4`, _not_ `ufbx_nurbs_surface.span_subdivision_u/v` as that
// would make it easy to create an FBX file with an absurdly high subdivision
// rate (similar to mesh subdivision). Please enforce copy the value yourself
// enforcing whatever limits you deem reasonable.
span_subdivision_u: u32;
span_subdivision_v: u32;
_end_zero: u32;
}
// Options for `ufbx_subdivide_mesh()`
// NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
ufbx_subdivide_opts :: struct {
_begin_zero: u32;
temp_allocator: ufbx_allocator_opts; // < Allocator used during subdivision
result_allocator: ufbx_allocator_opts; // < Allocator used for the final mesh
boundary: ufbx_subdivision_boundary;
uv_boundary: ufbx_subdivision_boundary;
// Do not generate normals
ignore_normals: bool;
// Interpolate existing normals using the subdivision rules
// instead of generating new normals
interpolate_normals: bool;
// Subdivide also tangent attributes
interpolate_tangents: bool;
// Map subdivided vertices into weighted original vertices.
// NOTE: May be O(n^2) if `max_source_vertices` is not specified!
evaluate_source_vertices: bool;
// Limit source vertices per subdivided vertex.
max_source_vertices: size_t;
// Calculate bone influences over subdivided vertices (if applicable).
// NOTE: May be O(n^2) if `max_skin_weights` is not specified!
evaluate_skin_weights: bool;
// Limit bone influences per subdivided vertex.
max_skin_weights: size_t;
// Index of the skin deformer to use for `evaluate_skin_weights`.
skin_deformer_index: size_t;
_end_zero: u32;
}
// Options for `ufbx_load_geometry_cache()`
// NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
ufbx_geometry_cache_opts :: struct {
_begin_zero: u32;
temp_allocator: ufbx_allocator_opts; // < Allocator used during loading
result_allocator: ufbx_allocator_opts; // < Allocator used for the final scene
// External file callbacks (defaults to stdio.h)
open_file_cb: ufbx_open_file_cb;
// FPS value for converting frame times to seconds
frames_per_second: float64;
_end_zero: u32;
}
// Options for `ufbx_read_geometry_cache_*()`
// NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++)
ufbx_geometry_cache_data_opts :: struct {
_begin_zero: u32;
// External file callbacks (defaults to stdio.h)
open_file_cb: ufbx_open_file_cb;
additive: bool;
use_weight: bool;
weight: ufbx_real;
_end_zero: u32;
}
ufbx_panic :: struct {
did_panic: bool;
message_length: size_t;
message: [128] u8;
}
// Practically always `true` (see below), if not you need to be careful with threads.
//
// Guaranteed to be `true` in _any_ of the following conditions:
// - ufbx.c has been compiled using: GCC / Clang / MSVC / ICC / EMCC / TCC
// - ufbx.c has been compiled as C++11 or later
// - ufbx.c has been compiled as C11 or later with `<stdatomic.h>` support
//
// If `false` you can't call the following functions concurrently:
// ufbx_evaluate_scene()
// ufbx_free_scene()
// ufbx_subdivide_mesh()
// ufbx_tessellate_nurbs_surface()
// ufbx_free_mesh()
ufbx_is_thread_safe :: () -> bool #foreign ufbx;
// Load a scene from a `size` byte memory buffer at `data`
ufbx_load_memory :: (data: *void, data_size: size_t, opts: *ufbx_load_opts, error: *ufbx_error) -> *ufbx_scene #foreign ufbx;
// Load a scene by opening a file named `filename`
ufbx_load_file :: (filename: *u8, opts: *ufbx_load_opts, error: *ufbx_error) -> *ufbx_scene #foreign ufbx;
ufbx_load_file_len :: (filename: *u8, filename_len: size_t, opts: *ufbx_load_opts, error: *ufbx_error) -> *ufbx_scene #foreign ufbx;
// Load a scene by reading from an `FILE *file` stream
// NOTE: `file` is passed as a `void` pointer to avoid including <stdio.h>
ufbx_load_stdio :: (file: *void, opts: *ufbx_load_opts, error: *ufbx_error) -> *ufbx_scene #foreign ufbx;
// Load a scene by reading from an `FILE *file` stream with a prefix
// NOTE: `file` is passed as a `void` pointer to avoid including <stdio.h>
ufbx_load_stdio_prefix :: (file: *void, prefix: *void, prefix_size: size_t, opts: *ufbx_load_opts, error: *ufbx_error) -> *ufbx_scene #foreign ufbx;
// Load a scene from a user-specified stream
ufbx_load_stream :: (stream: *ufbx_stream, opts: *ufbx_load_opts, error: *ufbx_error) -> *ufbx_scene #foreign ufbx;
// Load a scene from a user-specified stream with a prefix
ufbx_load_stream_prefix :: (stream: *ufbx_stream, prefix: *void, prefix_size: size_t, opts: *ufbx_load_opts, error: *ufbx_error) -> *ufbx_scene #foreign ufbx;
// Free a previously loaded or evaluated scene
ufbx_free_scene :: (scene: *ufbx_scene) -> void #foreign ufbx;
// Increment `scene` refcount
ufbx_retain_scene :: (scene: *ufbx_scene) -> void #foreign ufbx;
// Format a textual description of `error`.
// Always produces a NULL-terminated string to `char dst[dst_size]`, truncating if
// necessary. Returns the number of characters written not including the NULL terminator.
ufbx_format_error :: (dst: *u8, dst_size: size_t, error: *ufbx_error) -> size_t #foreign ufbx;
// Find a property `name` from `props`, returns `NULL` if not found.
// Searches through `ufbx_props.defaults` as well.
ufbx_find_prop_len :: (props: *ufbx_props, name: *u8, name_len: size_t) -> *ufbx_prop #foreign ufbx;
// Utility functions for finding the value of a property, returns `def` if not found.
// NOTE: For `ufbx_string` you need to ensure the lifetime of the default is
// sufficient as no copy is made.
ufbx_find_real_len :: (props: *ufbx_props, name: *u8, name_len: size_t, def: ufbx_real) -> ufbx_real #foreign ufbx;
ufbx_find_vec3_len :: (props: *ufbx_props, name: *u8, name_len: size_t, def: ufbx_vec3) -> ufbx_vec3 #foreign ufbx;
ufbx_find_int_len :: (props: *ufbx_props, name: *u8, name_len: size_t, def: s64) -> s64 #foreign ufbx;
ufbx_find_bool_len :: (props: *ufbx_props, name: *u8, name_len: size_t, def: bool) -> bool #foreign ufbx;
ufbx_find_string_len :: (props: *ufbx_props, name: *u8, name_len: size_t, def: ufbx_string) -> ufbx_string #foreign ufbx;
ufbx_find_blob_len :: (props: *ufbx_props, name: *u8, name_len: size_t, def: ufbx_blob) -> ufbx_blob #foreign ufbx;
// Find property in `props` with concatendated `parts[num_parts]`.
ufbx_find_prop_concat :: (props: *ufbx_props, parts: *ufbx_string, num_parts: size_t) -> *ufbx_prop #foreign ufbx;
// Get an element connected to a property.
ufbx_get_prop_element :: (element: *ufbx_element, prop: *ufbx_prop, type: ufbx_element_type) -> *ufbx_element #foreign ufbx;
// Find any element of type `type` in `scene` by `name`.
// For example if you want to find `ufbx_material` named `Mat`:
// (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Mat");
ufbx_find_element_len :: (scene: *ufbx_scene, type: ufbx_element_type, name: *u8, name_len: size_t) -> *ufbx_element #foreign ufbx;
// Find node in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_NODE)`).
ufbx_find_node_len :: (scene: *ufbx_scene, name: *u8, name_len: size_t) -> *ufbx_node #foreign ufbx;
// Find an animation stack in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_ANIM_STACK)`)
ufbx_find_anim_stack_len :: (scene: *ufbx_scene, name: *u8, name_len: size_t) -> *ufbx_anim_stack #foreign ufbx;
// Find a material in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_MATERIAL)`).
ufbx_find_material_len :: (scene: *ufbx_scene, name: *u8, name_len: size_t) -> *ufbx_material #foreign ufbx;
// Find a single animated property `prop` of `element` in `layer`.
// Returns `NULL` if not found.
ufbx_find_anim_prop_len :: (layer: *ufbx_anim_layer, element: *ufbx_element, prop: *u8, prop_len: size_t) -> *ufbx_anim_prop #foreign ufbx;
// Find all animated properties of `element` in `layer`.
ufbx_find_anim_props :: (layer: *ufbx_anim_layer, element: *ufbx_element) -> ufbx_anim_prop_list #foreign ufbx;
// Get a matrix that transforms normals in the same way as Autodesk software.
// NOTE: The resulting normals are slightly incorrect as this function deliberately
// inverts geometric transformation wrong. For better results use
// `ufbx_matrix_for_normals(&node->geometry_to_world)`.
ufbx_get_compatible_matrix_for_normals :: (node: *ufbx_node) -> ufbx_matrix #foreign ufbx;
// Decompress a DEFLATE compressed buffer.
// Returns the decompressed size or a negative error code (see source for details).
// NOTE: You must supply a valid `retain` with `ufbx_inflate_retain.initialized == false`
// but the rest can be uninitialized.
ufbx_inflate :: (dst: *void, dst_size: size_t, input: *ufbx_inflate_input, retain: *ufbx_inflate_retain) -> s64 #foreign ufbx;
// Open a `ufbx_stream` from a file.
// Use `path_len == SIZE_MAX` for NULL terminated string.
ufbx_open_file :: (stream: *ufbx_stream, path: *u8, path_len: size_t) -> bool #foreign ufbx;
// Same as `ufbx_open_file()` but compatible with the callback in `ufbx_open_file_fn`.
// The `user` parameter is actually not used here.
ufbx_default_open_file :: (user: *void, stream: *ufbx_stream, path: *u8, path_len: size_t, info: *ufbx_open_file_info) -> bool #foreign ufbx;
// NOTE: Uses the default ufbx allocator!
ufbx_open_memory :: (stream: *ufbx_stream, data: *void, data_size: size_t, opts: *ufbx_open_memory_opts, error: *ufbx_error) -> bool #foreign ufbx;
// Evaluate a single animation `curve` at a `time`.
// Returns `default_value` only if `curve == NULL` or it has no keyframes.
ufbx_evaluate_curve :: (curve: *ufbx_anim_curve, time: float64, default_value: ufbx_real) -> ufbx_real #foreign ufbx;
// Evaluate a value from bundled animation curves.
ufbx_evaluate_anim_value_real :: (anim_value: *ufbx_anim_value, time: float64) -> ufbx_real #foreign ufbx;
ufbx_evaluate_anim_value_vec2 :: (anim_value: *ufbx_anim_value, time: float64) -> ufbx_vec2 #foreign ufbx;
ufbx_evaluate_anim_value_vec3 :: (anim_value: *ufbx_anim_value, time: float64) -> ufbx_vec3 #foreign ufbx;
// Evaluate an animated property `name` from `element` at `time`.
// NOTE: If the property is not found it will have the flag `UFBX_PROP_FLAG_NOT_FOUND`.
ufbx_evaluate_prop_len :: (anim: *ufbx_anim, element: *ufbx_element, name: *u8, name_len: size_t, time: float64) -> ufbx_prop #foreign ufbx;
// Evaluate all _animated_ properties of `element`.
// HINT: This function returns an `ufbx_props` structure with the original properties as
// `ufbx_props.defaults`. This lets you use `ufbx_find_prop/value()` for the results.
ufbx_evaluate_props :: (anim: *ufbx_anim, element: *ufbx_element, time: float64, buffer: *ufbx_prop, buffer_size: size_t) -> ufbx_props #foreign ufbx;
ufbx_evaluate_transform :: (anim: *ufbx_anim, node: *ufbx_node, time: float64) -> ufbx_transform #foreign ufbx;
ufbx_evaluate_blend_weight :: (anim: *ufbx_anim, channel: *ufbx_blend_channel, time: float64) -> ufbx_real #foreign ufbx;
ufbx_prepare_prop_overrides :: (overrides: *ufbx_prop_override, num_overrides: size_t) -> ufbx_const_prop_override_list #foreign ufbx;
// Evaluate the whole `scene` at a specific `time` in the animation `anim`.
// The returned scene behaves as if it had been exported at a specific time
// in the specified animation, except that animated elements' properties contain
// only the animated values, the original ones are in `props->defaults`.
//
// NOTE: The returned scene refers to the original `scene` so the original
// scene cannot be freed until all evaluated scenes are freed.
ufbx_evaluate_scene :: (scene: *ufbx_scene, anim: *ufbx_anim, time: float64, opts: *ufbx_evaluate_opts, error: *ufbx_error) -> *ufbx_scene #foreign ufbx;
// Materials
ufbx_find_prop_texture_len :: (material: *ufbx_material, name: *u8, name_len: size_t) -> *ufbx_texture #foreign ufbx;
ufbx_find_shader_prop_len :: (shader: *ufbx_shader, name: *u8, name_len: size_t) -> ufbx_string #foreign ufbx;
ufbx_find_shader_prop_bindings_len :: (shader: *ufbx_shader, name: *u8, name_len: size_t) -> ufbx_shader_prop_binding_list #foreign ufbx;
ufbx_find_shader_texture_input_len :: (shader: *ufbx_shader_texture, name: *u8, name_len: size_t) -> *ufbx_shader_texture_input #foreign ufbx;
// Math
ufbx_coordinate_axes_valid :: (axes: ufbx_coordinate_axes) -> bool #foreign ufbx;
ufbx_quat_dot :: (a: ufbx_quat, b: ufbx_quat) -> ufbx_real #foreign ufbx;
ufbx_quat_mul :: (a: ufbx_quat, b: ufbx_quat) -> ufbx_quat #foreign ufbx;
ufbx_quat_normalize :: (q: ufbx_quat) -> ufbx_quat #foreign ufbx;
ufbx_quat_fix_antipodal :: (q: ufbx_quat, reference: ufbx_quat) -> ufbx_quat #foreign ufbx;
ufbx_quat_slerp :: (a: ufbx_quat, b: ufbx_quat, t: ufbx_real) -> ufbx_quat #foreign ufbx;
ufbx_quat_rotate_vec3 :: (q: ufbx_quat, v: ufbx_vec3) -> ufbx_vec3 #foreign ufbx;
ufbx_quat_to_euler :: (q: ufbx_quat, order: ufbx_rotation_order) -> ufbx_vec3 #foreign ufbx;
ufbx_euler_to_quat :: (v: ufbx_vec3, order: ufbx_rotation_order) -> ufbx_quat #foreign ufbx;
ufbx_matrix_mul :: (a: *ufbx_matrix, b: *ufbx_matrix) -> ufbx_matrix #foreign ufbx;
ufbx_matrix_determinant :: (m: *ufbx_matrix) -> ufbx_real #foreign ufbx;
ufbx_matrix_invert :: (m: *ufbx_matrix) -> ufbx_matrix #foreign ufbx;
ufbx_matrix_for_normals :: (m: *ufbx_matrix) -> ufbx_matrix #foreign ufbx;
ufbx_transform_position :: (m: *ufbx_matrix, v: ufbx_vec3) -> ufbx_vec3 #foreign ufbx;
ufbx_transform_direction :: (m: *ufbx_matrix, v: ufbx_vec3) -> ufbx_vec3 #foreign ufbx;
ufbx_transform_to_matrix :: (t: *ufbx_transform) -> ufbx_matrix #foreign ufbx;
ufbx_matrix_to_transform :: (m: *ufbx_matrix) -> ufbx_transform #foreign ufbx;
// Skinning
ufbx_catch_get_skin_vertex_matrix :: (panic: *ufbx_panic, skin: *ufbx_skin_deformer, vertex: size_t, fallback: *ufbx_matrix) -> ufbx_matrix #foreign ufbx;
ufbx_get_blend_shape_vertex_offset :: (shape: *ufbx_blend_shape, vertex: size_t) -> ufbx_vec3 #foreign ufbx;
ufbx_get_blend_vertex_offset :: (blend: *ufbx_blend_deformer, vertex: size_t) -> ufbx_vec3 #foreign ufbx;
ufbx_add_blend_shape_vertex_offsets :: (shape: *ufbx_blend_shape, vertices: *ufbx_vec3, num_vertices: size_t, weight: ufbx_real) -> void #foreign ufbx;
ufbx_add_blend_vertex_offsets :: (blend: *ufbx_blend_deformer, vertices: *ufbx_vec3, num_vertices: size_t, weight: ufbx_real) -> void #foreign ufbx;
// Curves/surfaces
ufbx_evaluate_nurbs_basis :: (basis: *ufbx_nurbs_basis, u: ufbx_real, weights: *ufbx_real, num_weights: size_t, derivatives: *ufbx_real, num_derivatives: size_t) -> size_t #foreign ufbx;
ufbx_evaluate_nurbs_curve :: (curve: *ufbx_nurbs_curve, u: ufbx_real) -> ufbx_curve_point #foreign ufbx;
ufbx_evaluate_nurbs_surface :: (surface: *ufbx_nurbs_surface, u: ufbx_real, v: ufbx_real) -> ufbx_surface_point #foreign ufbx;
ufbx_tessellate_nurbs_curve :: (curve: *ufbx_nurbs_curve, opts: *ufbx_tessellate_curve_opts, error: *ufbx_error) -> *ufbx_line_curve #foreign ufbx;
ufbx_tessellate_nurbs_surface :: (surface: *ufbx_nurbs_surface, opts: *ufbx_tessellate_surface_opts, error: *ufbx_error) -> *ufbx_mesh #foreign ufbx;
ufbx_free_line_curve :: (curve: *ufbx_line_curve) -> void #foreign ufbx;
ufbx_retain_line_curve :: (curve: *ufbx_line_curve) -> void #foreign ufbx;
// Mesh Topology
ufbx_catch_triangulate_face :: (panic: *ufbx_panic, indices: *u32, num_indices: size_t, mesh: *ufbx_mesh, face: ufbx_face) -> u32 #foreign ufbx;
// Generate the half-edge representation of `mesh` to `topo[mesh->num_indices]`
ufbx_catch_compute_topology :: (panic: *ufbx_panic, mesh: *ufbx_mesh, topo: *ufbx_topo_edge, num_topo: size_t) -> void #foreign ufbx;
// Get the next/previous edge around a vertex
// NOTE: Does not return the half-edge on the opposite side (ie. `topo[index].twin`)
ufbx_catch_topo_next_vertex_edge :: (panic: *ufbx_panic, topo: *ufbx_topo_edge, num_topo: size_t, index: u32) -> u32 #foreign ufbx;
ufbx_catch_topo_prev_vertex_edge :: (panic: *ufbx_panic, topo: *ufbx_topo_edge, num_topo: size_t, index: u32) -> u32 #foreign ufbx;
ufbx_catch_get_weighted_face_normal :: (panic: *ufbx_panic, positions: *ufbx_vertex_vec3, face: ufbx_face) -> ufbx_vec3 #foreign ufbx;
ufbx_catch_generate_normal_mapping :: (panic: *ufbx_panic, mesh: *ufbx_mesh, topo: *ufbx_topo_edge, num_topo: size_t, normal_indices: *u32, num_normal_indices: size_t, assume_smooth: bool) -> size_t #foreign ufbx;
ufbx_generate_normal_mapping :: (mesh: *ufbx_mesh, topo: *ufbx_topo_edge, num_topo: size_t, normal_indices: *u32, num_normal_indices: size_t, assume_smooth: bool) -> size_t #foreign ufbx;
ufbx_catch_compute_normals :: (panic: *ufbx_panic, mesh: *ufbx_mesh, positions: *ufbx_vertex_vec3, normal_indices: *u32, num_normal_indices: size_t, normals: *ufbx_vec3, num_normals: size_t) -> void #foreign ufbx;
ufbx_compute_normals :: (mesh: *ufbx_mesh, positions: *ufbx_vertex_vec3, normal_indices: *u32, num_normal_indices: size_t, normals: *ufbx_vec3, num_normals: size_t) -> void #foreign ufbx;
ufbx_subdivide_mesh :: (mesh: *ufbx_mesh, level: size_t, opts: *ufbx_subdivide_opts, error: *ufbx_error) -> *ufbx_mesh #foreign ufbx;
ufbx_free_mesh :: (mesh: *ufbx_mesh) -> void #foreign ufbx;
ufbx_retain_mesh :: (mesh: *ufbx_mesh) -> void #foreign ufbx;
// Geometry caches
ufbx_load_geometry_cache :: (filename: *u8, opts: *ufbx_geometry_cache_opts, error: *ufbx_error) -> *ufbx_geometry_cache #foreign ufbx;
ufbx_load_geometry_cache_len :: (filename: *u8, filename_len: size_t, opts: *ufbx_geometry_cache_opts, error: *ufbx_error) -> *ufbx_geometry_cache #foreign ufbx;
ufbx_free_geometry_cache :: (cache: *ufbx_geometry_cache) -> void #foreign ufbx;
ufbx_retain_geometry_cache :: (cache: *ufbx_geometry_cache) -> void #foreign ufbx;
ufbx_read_geometry_cache_real :: (frame: *ufbx_cache_frame, data: *ufbx_real, num_data: size_t, opts: *ufbx_geometry_cache_data_opts) -> size_t #foreign ufbx;
ufbx_sample_geometry_cache_real :: (channel: *ufbx_cache_channel, time: float64, data: *ufbx_real, num_data: size_t, opts: *ufbx_geometry_cache_data_opts) -> size_t #foreign ufbx;
ufbx_read_geometry_cache_vec3 :: (frame: *ufbx_cache_frame, data: *ufbx_vec3, num_data: size_t, opts: *ufbx_geometry_cache_data_opts) -> size_t #foreign ufbx;
ufbx_sample_geometry_cache_vec3 :: (channel: *ufbx_cache_channel, time: float64, data: *ufbx_vec3, num_data: size_t, opts: *ufbx_geometry_cache_data_opts) -> size_t #foreign ufbx;
// DOM
ufbx_dom_find_len :: (parent: *ufbx_dom_node, name: *u8, name_len: size_t) -> *ufbx_dom_node #foreign ufbx;
// Utility
ufbx_generate_indices :: (streams: *ufbx_vertex_stream, num_streams: size_t, indices: *u32, num_indices: size_t, allocator: *ufbx_allocator_opts, error: *ufbx_error) -> size_t #foreign ufbx;
// -- Inline API
ufbx_catch_get_vertex_real :: (panic: *ufbx_panic, v: *ufbx_vertex_real, index: size_t) -> ufbx_real #foreign ufbx;
ufbx_catch_get_vertex_vec2 :: (panic: *ufbx_panic, v: *ufbx_vertex_vec2, index: size_t) -> ufbx_vec2 #foreign ufbx;
ufbx_catch_get_vertex_vec3 :: (panic: *ufbx_panic, v: *ufbx_vertex_vec3, index: size_t) -> ufbx_vec3 #foreign ufbx;
ufbx_catch_get_vertex_vec4 :: (panic: *ufbx_panic, v: *ufbx_vertex_vec4, index: size_t) -> ufbx_vec4 #foreign ufbx;
ufbx_get_triangulate_face_num_indices :: (face: ufbx_face) -> size_t #foreign ufbx;
ufbx_as_unknown :: (element: *ufbx_element) -> *ufbx_unknown #foreign ufbx;
ufbx_as_node :: (element: *ufbx_element) -> *ufbx_node #foreign ufbx;
ufbx_as_mesh :: (element: *ufbx_element) -> *ufbx_mesh #foreign ufbx;
ufbx_as_light :: (element: *ufbx_element) -> *ufbx_light #foreign ufbx;
ufbx_as_camera :: (element: *ufbx_element) -> *ufbx_camera #foreign ufbx;
ufbx_as_bone :: (element: *ufbx_element) -> *ufbx_bone #foreign ufbx;
ufbx_as_empty :: (element: *ufbx_element) -> *ufbx_empty #foreign ufbx;
ufbx_as_line_curve :: (element: *ufbx_element) -> *ufbx_line_curve #foreign ufbx;
ufbx_as_nurbs_curve :: (element: *ufbx_element) -> *ufbx_nurbs_curve #foreign ufbx;
ufbx_as_nurbs_surface :: (element: *ufbx_element) -> *ufbx_nurbs_surface #foreign ufbx;
ufbx_as_nurbs_trim_surface :: (element: *ufbx_element) -> *ufbx_nurbs_trim_surface #foreign ufbx;
ufbx_as_nurbs_trim_boundary :: (element: *ufbx_element) -> *ufbx_nurbs_trim_boundary #foreign ufbx;
ufbx_as_procedural_geometry :: (element: *ufbx_element) -> *ufbx_procedural_geometry #foreign ufbx;
ufbx_as_stereo_camera :: (element: *ufbx_element) -> *ufbx_stereo_camera #foreign ufbx;
ufbx_as_camera_switcher :: (element: *ufbx_element) -> *ufbx_camera_switcher #foreign ufbx;
ufbx_as_marker :: (element: *ufbx_element) -> *ufbx_marker #foreign ufbx;
ufbx_as_lod_group :: (element: *ufbx_element) -> *ufbx_lod_group #foreign ufbx;
ufbx_as_skin_deformer :: (element: *ufbx_element) -> *ufbx_skin_deformer #foreign ufbx;
ufbx_as_skin_cluster :: (element: *ufbx_element) -> *ufbx_skin_cluster #foreign ufbx;
ufbx_as_blend_deformer :: (element: *ufbx_element) -> *ufbx_blend_deformer #foreign ufbx;
ufbx_as_blend_channel :: (element: *ufbx_element) -> *ufbx_blend_channel #foreign ufbx;
ufbx_as_blend_shape :: (element: *ufbx_element) -> *ufbx_blend_shape #foreign ufbx;
ufbx_as_cache_deformer :: (element: *ufbx_element) -> *ufbx_cache_deformer #foreign ufbx;
ufbx_as_cache_file :: (element: *ufbx_element) -> *ufbx_cache_file #foreign ufbx;
ufbx_as_material :: (element: *ufbx_element) -> *ufbx_material #foreign ufbx;
ufbx_as_texture :: (element: *ufbx_element) -> *ufbx_texture #foreign ufbx;
ufbx_as_video :: (element: *ufbx_element) -> *ufbx_video #foreign ufbx;
ufbx_as_shader :: (element: *ufbx_element) -> *ufbx_shader #foreign ufbx;
ufbx_as_shader_binding :: (element: *ufbx_element) -> *ufbx_shader_binding #foreign ufbx;
ufbx_as_anim_stack :: (element: *ufbx_element) -> *ufbx_anim_stack #foreign ufbx;
ufbx_as_anim_layer :: (element: *ufbx_element) -> *ufbx_anim_layer #foreign ufbx;
ufbx_as_anim_value :: (element: *ufbx_element) -> *ufbx_anim_value #foreign ufbx;
ufbx_as_anim_curve :: (element: *ufbx_element) -> *ufbx_anim_curve #foreign ufbx;
ufbx_as_display_layer :: (element: *ufbx_element) -> *ufbx_display_layer #foreign ufbx;
ufbx_as_selection_set :: (element: *ufbx_element) -> *ufbx_selection_set #foreign ufbx;
ufbx_as_selection_node :: (element: *ufbx_element) -> *ufbx_selection_node #foreign ufbx;
ufbx_as_character :: (element: *ufbx_element) -> *ufbx_character #foreign ufbx;
ufbx_as_constraint :: (element: *ufbx_element) -> *ufbx_constraint #foreign ufbx;
ufbx_as_pose :: (element: *ufbx_element) -> *ufbx_pose #foreign ufbx;
ufbx_as_metadata_object :: (element: *ufbx_element) -> *ufbx_metadata_object #foreign ufbx;
// -- FFI API
ufbx_ffi_find_int_len :: (retval: *s64, props: *ufbx_props, name: *u8, name_len: size_t, def: *s64) -> void #foreign ufbx;
ufbx_ffi_find_vec3_len :: (retval: *ufbx_vec3, props: *ufbx_props, name: *u8, name_len: size_t, def: *ufbx_vec3) -> void #foreign ufbx;
ufbx_ffi_find_string_len :: (retval: *ufbx_string, props: *ufbx_props, name: *u8, name_len: size_t, def: *ufbx_string) -> void #foreign ufbx;
ufbx_ffi_find_anim_props :: (retval: *ufbx_anim_prop_list, layer: *ufbx_anim_layer, element: *ufbx_element) -> void #foreign ufbx;
ufbx_ffi_get_compatible_matrix_for_normals :: (retval: *ufbx_matrix, node: *ufbx_node) -> void #foreign ufbx;
ufbx_ffi_evaluate_anim_value_vec2 :: (retval: *ufbx_vec2, anim_value: *ufbx_anim_value, time: float64) -> void #foreign ufbx;
ufbx_ffi_evaluate_anim_value_vec3 :: (retval: *ufbx_vec3, anim_value: *ufbx_anim_value, time: float64) -> void #foreign ufbx;
ufbx_ffi_evaluate_prop_len :: (retval: *ufbx_prop, anim: *ufbx_anim, element: *ufbx_element, name: *u8, name_len: size_t, time: float64) -> void #foreign ufbx;
ufbx_ffi_evaluate_props :: (retval: *ufbx_props, anim: *ufbx_anim, element: *ufbx_element, time: float64, buffer: *ufbx_prop, buffer_size: size_t) -> void #foreign ufbx;
ufbx_ffi_evaluate_transform :: (retval: *ufbx_transform, anim: *ufbx_anim, node: *ufbx_node, time: float64) -> void #foreign ufbx;
ufbx_ffi_evaluate_blend_weight :: (anim: *ufbx_anim, channel: *ufbx_blend_channel, time: float64) -> ufbx_real #foreign ufbx;
ufbx_ffi_prepare_prop_overrides :: (retval: *ufbx_const_prop_override_list, overrides: *ufbx_prop_override, num_overrides: size_t) -> void #foreign ufbx;
ufbx_ffi_quat_mul :: (retval: *ufbx_quat, a: *ufbx_quat, b: *ufbx_quat) -> void #foreign ufbx;
ufbx_ffi_quat_normalize :: (retval: *ufbx_quat, q: *ufbx_quat) -> void #foreign ufbx;
ufbx_ffi_quat_fix_antipodal :: (retval: *ufbx_quat, q: *ufbx_quat, reference: *ufbx_quat) -> void #foreign ufbx;
ufbx_ffi_quat_slerp :: (retval: *ufbx_quat, a: *ufbx_quat, b: *ufbx_quat, t: ufbx_real) -> void #foreign ufbx;
ufbx_ffi_quat_rotate_vec3 :: (retval: *ufbx_vec3, q: *ufbx_quat, v: *ufbx_vec3) -> void #foreign ufbx;
ufbx_ffi_quat_to_euler :: (retval: *ufbx_vec3, q: *ufbx_quat, order: ufbx_rotation_order) -> void #foreign ufbx;
ufbx_ffi_euler_to_quat :: (retval: *ufbx_quat, v: *ufbx_vec3, order: ufbx_rotation_order) -> void #foreign ufbx;
ufbx_ffi_matrix_mul :: (retval: *ufbx_matrix, a: *ufbx_matrix, b: *ufbx_matrix) -> void #foreign ufbx;
ufbx_ffi_matrix_invert :: (retval: *ufbx_matrix, m: *ufbx_matrix) -> void #foreign ufbx;
ufbx_ffi_matrix_for_normals :: (retval: *ufbx_matrix, m: *ufbx_matrix) -> void #foreign ufbx;
ufbx_ffi_transform_position :: (retval: *ufbx_vec3, m: *ufbx_matrix, v: *ufbx_vec3) -> void #foreign ufbx;
ufbx_ffi_transform_direction :: (retval: *ufbx_vec3, m: *ufbx_matrix, v: *ufbx_vec3) -> void #foreign ufbx;
ufbx_ffi_transform_to_matrix :: (retval: *ufbx_matrix, t: *ufbx_transform) -> void #foreign ufbx;
ufbx_ffi_matrix_to_transform :: (retval: *ufbx_transform, m: *ufbx_matrix) -> void #foreign ufbx;
ufbx_ffi_get_skin_vertex_matrix :: (retval: *ufbx_matrix, skin: *ufbx_skin_deformer, vertex: size_t, fallback: *ufbx_matrix) -> void #foreign ufbx;
ufbx_ffi_get_blend_shape_vertex_offset :: (retval: *ufbx_vec3, shape: *ufbx_blend_shape, vertex: size_t) -> void #foreign ufbx;
ufbx_ffi_get_blend_vertex_offset :: (retval: *ufbx_vec3, blend: *ufbx_blend_deformer, vertex: size_t) -> void #foreign ufbx;
ufbx_ffi_evaluate_nurbs_curve :: (retval: *ufbx_curve_point, curve: *ufbx_nurbs_curve, u: ufbx_real) -> void #foreign ufbx;
ufbx_ffi_evaluate_nurbs_surface :: (retval: *ufbx_surface_point, surface: *ufbx_nurbs_surface, u: ufbx_real, v: ufbx_real) -> void #foreign ufbx;
ufbx_ffi_get_weighted_face_normal :: (retval: *ufbx_vec3, positions: *ufbx_vertex_vec3, face: *ufbx_face) -> void #foreign ufbx;
ufbx_ffi_get_triangulate_face_num_indices :: (face: *ufbx_face) -> size_t #foreign ufbx;
ufbx_ffi_triangulate_face :: (indices: *u32, num_indices: size_t, mesh: *ufbx_mesh, face: *ufbx_face) -> u32 #foreign ufbx;
#scope_file
ufbx :: #library,no_dll "./ufbx";