// // 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 `` 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 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 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";