ufbx.odin (182675B)
1 package ufbx 2 3 import "core:c" 4 5 foreign import lib "ufbx.lib" 6 _ :: lib 7 8 CPP :: 0 9 PLATFORM_GNUC :: 0 10 CPP11 :: 0 11 12 // Limits for embedded arrays within structures. 13 ERROR_STACK_MAX_DEPTH :: 8 14 PANIC_MESSAGE_LENGTH :: 128 15 ERROR_INFO_LENGTH :: 256 16 17 // Number of thread groups to use if threading is enabled. 18 // A thread group processes a number of tasks and is then waited and potentially 19 // re-used later. In essence, this controls the granularity of threading. 20 THREAD_GROUP_COUNT :: 4 21 HAS_FORCE_32BIT :: 1 22 23 // Version of the ufbx header. 24 // `UFBX_VERSION` is simply an alias of `UFBX_HEADER_VERSION`. 25 // `ufbx_source_version` contains the version of the corresponding source file. 26 // HINT: The version can be compared numerically to the result of `ufbx_pack_version()`, 27 // for example `#if UFBX_VERSION >= ufbx_pack_version(0, 12, 0)`. 28 HEADER_VERSION :: ((u32)(0)*1000000+(u32)(18)*1000+(u32)(0)) 29 VERSION :: HEADER_VERSION 30 31 // Main floating point type used everywhere in ufbx, defaults to `double`. 32 // If you define `UFBX_REAL_IS_FLOAT` to any value, `ufbx_real` will be defined 33 // as `float` instead. 34 // You can also manually define `UFBX_REAL_TYPE` to any floating point type. 35 Real :: f32 36 37 // Null-terminated UTF-8 encoded string within an FBX file 38 String :: struct { 39 data: cstring, 40 length: c.size_t, 41 } 42 43 // Opaque byte buffer blob 44 Blob :: struct { 45 data: rawptr, 46 size: c.size_t, 47 } 48 49 // 2D vector 50 Vec2 :: [2]Real 51 52 // 3D vector 53 Vec3 :: [3]Real 54 55 // 4D vector 56 Vec4 :: [4]Real 57 58 // Quaternion 59 Quat :: quaternion128 60 61 // Order in which Euler-angle rotation axes are applied for a transform 62 // NOTE: The order in the name refers to the order of axes *applied*, 63 // not the multiplication order: eg. `UFBX_ROTATION_ORDER_XYZ` is `Z*Y*X` 64 // [TODO: Figure out what the spheric rotation order is...] 65 Rotation_Order :: enum i32 { 66 XYZ = 0, 67 XZY = 1, 68 YZX = 2, 69 YXZ = 3, 70 ZXY = 4, 71 ZYX = 5, 72 SPHERIC = 6, 73 } 74 75 ROTATION_ORDER_COUNT :: 7 76 77 // Explicit translation+rotation+scale transformation. 78 // NOTE: Rotation is a quaternion, not Euler angles! 79 Transform :: struct { 80 translation: Vec3, 81 rotation: Quat, 82 scale: Vec3, 83 } 84 85 // 4x3 matrix encoding an affine transformation. 86 // `cols[0..2]` are the X/Y/Z basis vectors, `cols[3]` is the translation 87 Matrix :: struct { 88 using _: struct #raw_union { 89 using _: struct { 90 m00, m10, m20: Real, 91 m01, m11, m21: Real, 92 m02, m12, m22: Real, 93 m03, m13, m23: Real, 94 }, 95 96 cols: [4]Vec3, 97 v: [12]Real, 98 }, 99 } 100 101 Void_List :: struct { 102 data: [^]rawptr, 103 count: c.size_t, 104 } 105 106 Bool_List :: struct { 107 data: [^]bool, 108 count: c.size_t, 109 } 110 111 Uint32_List :: struct { 112 data: [^]u32, 113 count: c.size_t, 114 } 115 116 Real_List :: struct { 117 data: [^]Real, 118 count: c.size_t, 119 } 120 121 Vec2_List :: struct { 122 data: [^]Vec2, 123 count: c.size_t, 124 } 125 126 Vec3_List :: struct { 127 data: [^]Vec3, 128 count: c.size_t, 129 } 130 131 Vec4_List :: struct { 132 data: [^]Vec4, 133 count: c.size_t, 134 } 135 136 String_List :: struct { 137 data: [^]String, 138 count: c.size_t, 139 } 140 141 // Sentinel value used to represent a missing index. 142 NO_INDEX :: max(u32) 143 144 // -- Document object model 145 Dom_Value_Type :: enum i32 { 146 NUMBER = 0, 147 STRING = 1, 148 ARRAY_I8 = 2, 149 ARRAY_I32 = 3, 150 ARRAY_I64 = 4, 151 ARRAY_F32 = 5, 152 ARRAY_F64 = 6, 153 ARRAY_RAW_STRING = 7, 154 ARRAY_IGNORED = 8, 155 } 156 157 DOM_VALUE_TYPE_COUNT :: 9 158 159 Dom_Value :: struct { 160 type: Dom_Value_Type, 161 value_str: String, 162 value_blob: Blob, 163 value_int: i64, 164 value_float: f64, 165 } 166 167 Dom_Node_List :: struct { 168 data: ^^Dom_Node, 169 count: c.size_t, 170 } 171 172 Dom_Value_List :: struct { 173 data: [^]Dom_Value, 174 count: c.size_t, 175 } 176 177 Dom_Node :: struct { 178 name: String, 179 children: Dom_Node_List, 180 values: Dom_Value_List, 181 } 182 183 // Data type contained within the property. All the data fields are always 184 // populated regardless of type, so there's no need to switch by type usually 185 // eg. `prop->value_real` and `prop->value_int` have the same value (well, close) 186 // if `prop->type == UFBX_PROP_INTEGER`. String values are not converted from/to. 187 Prop_Type :: enum i32 { 188 UNKNOWN = 0, 189 BOOLEAN = 1, 190 INTEGER = 2, 191 NUMBER = 3, 192 VECTOR = 4, 193 COLOR = 5, 194 COLOR_WITH_ALPHA = 6, 195 STRING = 7, 196 DATE_TIME = 8, 197 TRANSLATION = 9, 198 ROTATION = 10, 199 SCALING = 11, 200 DISTANCE = 12, 201 COMPOUND = 13, 202 BLOB = 14, 203 REFERENCE = 15, 204 } 205 206 PROP_TYPE_COUNT :: 16 207 208 Prop_Flag :: enum i32 { 209 // Supports animation. 210 // NOTE: ufbx ignores this and allows animations on non-animatable properties. 211 ANIMATABLE = 0, 212 213 // User defined (custom) property. 214 USER_DEFINED = 1, 215 216 // Hidden in UI. 217 HIDDEN = 2, 218 219 // Disallow modification from UI for components. 220 LOCK_X = 4, 221 LOCK_Y = 5, 222 LOCK_Z = 6, 223 LOCK_W = 7, 224 225 // Disable animation from components. 226 MUTE_X = 8, 227 MUTE_Y = 9, 228 MUTE_Z = 10, 229 MUTE_W = 11, 230 231 // Property created by ufbx when an element has a connected `ufbx_anim_prop` 232 // but doesn't contain the `ufbx_prop` it's referring to. 233 // NOTE: The property may have been found in the templated defaults. 234 SYNTHETIC = 12, 235 236 // The property has at least one `ufbx_anim_prop` in some layer. 237 ANIMATED = 13, 238 239 // Used by `ufbx_evaluate_prop()` to indicate the the property was not found. 240 NOT_FOUND = 14, 241 242 // The property is connected to another one. 243 // This use case is relatively rare so `ufbx_prop` does not track connections 244 // directly. You can find connections from `ufbx_element.connections_dst` where 245 // `ufbx_connection.dst_prop` is this property and `ufbx_connection.src_prop` is defined. 246 CONNECTED = 15, 247 248 // The value of this property is undefined (represented as zero). 249 NO_VALUE = 16, 250 251 // This property has been overridden by the user. 252 // See `ufbx_anim.prop_overrides` for more information. 253 OVERRIDDEN = 17, 254 255 // Value type. 256 // `REAL/VEC2/VEC3/VEC4` are mutually exclusive but may coexist with eg. `STRING` 257 // in some rare cases where the string defines the unit for the vector. 258 VALUE_REAL = 20, 259 VALUE_VEC2 = 21, 260 VALUE_VEC3 = 22, 261 VALUE_VEC4 = 23, 262 VALUE_INT = 24, 263 VALUE_STR = 25, 264 VALUE_BLOB = 26, 265 } 266 267 // Property flags: Advanced information about properties, not usually needed. 268 Prop_Flags :: bit_set[Prop_Flag; i32] 269 270 // Single property with name/type/value. 271 Prop :: struct { 272 name: String, 273 _internal_key: u32, 274 type: Prop_Type, 275 flags: Prop_Flags, 276 value_str: String, 277 value_blob: Blob, 278 value_int: i64, 279 280 using _: struct #raw_union { 281 value_real_arr: [4]Real, 282 value_real: Real, 283 value_vec2: Vec2, 284 value_vec3: Vec3, 285 value_vec4: Vec4, 286 }, 287 } 288 289 Prop_List :: struct { 290 data: ^Prop, 291 count: c.size_t, 292 } 293 294 // List of alphabetically sorted properties with potential defaults. 295 // For animated objects in as scene from `ufbx_evaluate_scene()` this list 296 // only has the animated properties, the originals are stored under `defaults`. 297 Props :: struct { 298 props: Prop_List, 299 num_animated: c.size_t, 300 defaults: ^Props, 301 } 302 303 Element_List :: struct { 304 data: ^^Element, 305 count: c.size_t, 306 } 307 308 Unknown_List :: struct { 309 data: ^^Unknown, 310 count: c.size_t, 311 } 312 313 Node_List :: struct { 314 data: [^]^Node, 315 count: c.size_t, 316 } 317 318 Mesh_List :: struct { 319 data: ^^Mesh, 320 count: c.size_t, 321 } 322 323 Light_List :: struct { 324 data: ^^Light, 325 count: c.size_t, 326 } 327 328 Camera_List :: struct { 329 data: ^^Camera, 330 count: c.size_t, 331 } 332 333 Bone_List :: struct { 334 data: ^^Bone, 335 count: c.size_t, 336 } 337 338 Empty_List :: struct { 339 data: ^^Empty, 340 count: c.size_t, 341 } 342 343 Line_Curve_List :: struct { 344 data: ^^Line_Curve, 345 count: c.size_t, 346 } 347 348 Nurbs_Curve_List :: struct { 349 data: ^^Nurbs_Curve, 350 count: c.size_t, 351 } 352 353 Nurbs_Surface_List :: struct { 354 data: ^^Nurbs_Surface, 355 count: c.size_t, 356 } 357 358 Nurbs_Trim_Surface_List :: struct { 359 data: ^^Nurbs_Trim_Surface, 360 count: c.size_t, 361 } 362 363 Nurbs_Trim_Boundary_List :: struct { 364 data: ^^Nurbs_Trim_Boundary, 365 count: c.size_t, 366 } 367 368 Procedural_Geometry_List :: struct { 369 data: ^^Procedural_Geometry, 370 count: c.size_t, 371 } 372 373 Stereo_Camera_List :: struct { 374 data: ^^Stereo_Camera, 375 count: c.size_t, 376 } 377 378 Camera_Switcher_List :: struct { 379 data: ^^Camera_Switcher, 380 count: c.size_t, 381 } 382 383 Marker_List :: struct { 384 data: ^^Marker, 385 count: c.size_t, 386 } 387 388 Lod_Group_List :: struct { 389 data: ^^Lod_Group, 390 count: c.size_t, 391 } 392 393 Skin_Deformer_List :: struct { 394 data: ^^Skin_Deformer, 395 count: c.size_t, 396 } 397 398 Skin_Cluster_List :: struct { 399 data: ^^Skin_Cluster, 400 count: c.size_t, 401 } 402 403 Blend_Deformer_List :: struct { 404 data: ^^Blend_Deformer, 405 count: c.size_t, 406 } 407 408 Blend_Channel_List :: struct { 409 data: ^^Blend_Channel, 410 count: c.size_t, 411 } 412 413 Blend_Shape_List :: struct { 414 data: ^^Blend_Shape, 415 count: c.size_t, 416 } 417 418 Cache_Deformer_List :: struct { 419 data: ^^Cache_Deformer, 420 count: c.size_t, 421 } 422 423 Cache_File_List :: struct { 424 data: ^^Cache_File, 425 count: c.size_t, 426 } 427 428 Material_List :: struct { 429 data: ^^Material, 430 count: c.size_t, 431 } 432 433 Texture_List :: struct { 434 data: ^^Texture, 435 count: c.size_t, 436 } 437 438 Video_List :: struct { 439 data: ^^Video, 440 count: c.size_t, 441 } 442 443 Shader_List :: struct { 444 data: ^^Shader, 445 count: c.size_t, 446 } 447 448 Shader_Binding_List :: struct { 449 data: ^^Shader_Binding, 450 count: c.size_t, 451 } 452 453 Anim_Stack_List :: struct { 454 data: ^^Anim_Stack, 455 count: c.size_t, 456 } 457 458 Anim_Layer_List :: struct { 459 data: ^^Anim_Layer, 460 count: c.size_t, 461 } 462 463 Anim_Value_List :: struct { 464 data: ^^Anim_Value, 465 count: c.size_t, 466 } 467 468 Anim_Curve_List :: struct { 469 data: ^^Anim_Curve, 470 count: c.size_t, 471 } 472 473 Display_Layer_List :: struct { 474 data: ^^Display_Layer, 475 count: c.size_t, 476 } 477 478 Selection_Set_List :: struct { 479 data: ^^Selection_Set, 480 count: c.size_t, 481 } 482 483 Selection_Node_List :: struct { 484 data: ^^Selection_Node, 485 count: c.size_t, 486 } 487 488 Character_List :: struct { 489 data: ^^Character, 490 count: c.size_t, 491 } 492 493 Constraint_List :: struct { 494 data: ^^Constraint, 495 count: c.size_t, 496 } 497 498 Audio_Layer_List :: struct { 499 data: ^^Audio_Layer, 500 count: c.size_t, 501 } 502 503 Audio_Clip_List :: struct { 504 data: ^^Audio_Clip, 505 count: c.size_t, 506 } 507 508 Pose_List :: struct { 509 data: ^^Pose, 510 count: c.size_t, 511 } 512 513 Metadata_Object_List :: struct { 514 data: ^^Metadata_Object, 515 count: c.size_t, 516 } 517 518 Element_Type :: enum i32 { 519 UNKNOWN = 0, // < `ufbx_unknown` 520 NODE = 1, // < `ufbx_node` 521 MESH = 2, // < `ufbx_mesh` 522 LIGHT = 3, // < `ufbx_light` 523 CAMERA = 4, // < `ufbx_camera` 524 BONE = 5, // < `ufbx_bone` 525 EMPTY = 6, // < `ufbx_empty` 526 LINE_CURVE = 7, // < `ufbx_line_curve` 527 NURBS_CURVE = 8, // < `ufbx_nurbs_curve` 528 NURBS_SURFACE = 9, // < `ufbx_nurbs_surface` 529 NURBS_TRIM_SURFACE = 10, // < `ufbx_nurbs_trim_surface` 530 NURBS_TRIM_BOUNDARY = 11, // < `ufbx_nurbs_trim_boundary` 531 PROCEDURAL_GEOMETRY = 12, // < `ufbx_procedural_geometry` 532 STEREO_CAMERA = 13, // < `ufbx_stereo_camera` 533 CAMERA_SWITCHER = 14, // < `ufbx_camera_switcher` 534 MARKER = 15, // < `ufbx_marker` 535 LOD_GROUP = 16, // < `ufbx_lod_group` 536 SKIN_DEFORMER = 17, // < `ufbx_skin_deformer` 537 SKIN_CLUSTER = 18, // < `ufbx_skin_cluster` 538 BLEND_DEFORMER = 19, // < `ufbx_blend_deformer` 539 BLEND_CHANNEL = 20, // < `ufbx_blend_channel` 540 BLEND_SHAPE = 21, // < `ufbx_blend_shape` 541 CACHE_DEFORMER = 22, // < `ufbx_cache_deformer` 542 CACHE_FILE = 23, // < `ufbx_cache_file` 543 MATERIAL = 24, // < `ufbx_material` 544 TEXTURE = 25, // < `ufbx_texture` 545 VIDEO = 26, // < `ufbx_video` 546 SHADER = 27, // < `ufbx_shader` 547 SHADER_BINDING = 28, // < `ufbx_shader_binding` 548 ANIM_STACK = 29, // < `ufbx_anim_stack` 549 ANIM_LAYER = 30, // < `ufbx_anim_layer` 550 ANIM_VALUE = 31, // < `ufbx_anim_value` 551 ANIM_CURVE = 32, // < `ufbx_anim_curve` 552 DISPLAY_LAYER = 33, // < `ufbx_display_layer` 553 SELECTION_SET = 34, // < `ufbx_selection_set` 554 SELECTION_NODE = 35, // < `ufbx_selection_node` 555 CHARACTER = 36, // < `ufbx_character` 556 CONSTRAINT = 37, // < `ufbx_constraint` 557 AUDIO_LAYER = 38, // < `ufbx_audio_layer` 558 AUDIO_CLIP = 39, // < `ufbx_audio_clip` 559 POSE = 40, // < `ufbx_pose` 560 METADATA_OBJECT = 41, // < `ufbx_metadata_object` 561 TYPE_FIRST_ATTRIB = 2, 562 TYPE_LAST_ATTRIB = 16, 563 } 564 565 ELEMENT_TYPE_COUNT :: 42 566 567 // Connection between two elements. 568 // Source and destination are somewhat arbitrary but the destination is 569 // often the "container" like a parent node or mesh containing a deformer. 570 Connection :: struct { 571 src: ^Element, 572 dst: ^Element, 573 src_prop: String, 574 dst_prop: String, 575 } 576 577 Connection_List :: struct { 578 data: ^Connection, 579 count: c.size_t, 580 } 581 582 // Element "base-class" common to each element. 583 // Some fields (like `connections_src`) are advanced and not visible 584 // in the specialized element structs. 585 // NOTE: The `element_id` value is consistent when loading the 586 // _same_ file, but re-exporting the file will invalidate them. 587 Element :: struct { 588 name: String, 589 props: Props, 590 element_id: u32, 591 typed_id: u32, 592 instances: Node_List, 593 type: Element_Type, 594 connections_src: Connection_List, 595 connections_dst: Connection_List, 596 dom_node: ^Dom_Node, 597 scene: ^Scene, 598 } 599 600 // -- Unknown 601 Unknown :: struct { 602 // Shared "base-class" header, see `ufbx_element`. 603 using _: struct #raw_union { 604 // Shared "base-class" header, see `ufbx_element`. 605 element: Element, 606 607 using _: struct { 608 name: String, 609 props: Props, 610 element_id: u32, 611 typed_id: u32, 612 }, 613 }, 614 615 // FBX format specific type information. 616 // In ASCII FBX format: 617 // super_type: ID, "type::name", "sub_type" { ... } 618 type: String, 619 super_type: String, 620 sub_type: String, 621 } 622 623 // Inherit type specifies how hierarchial node transforms are combined. 624 // This only affects the final scaling, as rotation and translation are always 625 // inherited correctly. 626 // NOTE: These don't map to `"InheritType"` property as there may be new ones for 627 // compatibility with various exporters. 628 Inherit_Mode :: enum i32 { 629 // Normal matrix composition of hierarchy: `R*S*r*s`. 630 // child.node_to_world = parent.node_to_world * child.node_to_parent; 631 NORMAL = 0, 632 633 // Ignore parent scale when computing the transform: `R*r*s`. 634 // ufbx_transform t = node.local_transform; 635 // t.translation *= parent.inherit_scale; 636 // t.scale *= node.inherit_scale_node.inherit_scale; 637 // child.node_to_world = parent.unscaled_node_to_world * t; 638 // Also known as "Segment scale compensate" in some software. 639 IGNORE_PARENT_SCALE = 1, 640 641 // Apply parent scale component-wise: `R*r*S*s`. 642 // ufbx_transform t = node.local_transform; 643 // t.translation *= parent.inherit_scale; 644 // t.scale *= node.inherit_scale_node.inherit_scale; 645 // child.node_to_world = parent.unscaled_node_to_world * t; 646 COMPONENTWISE_SCALE = 2, 647 } 648 649 INHERIT_MODE_COUNT :: 3 650 651 // Axis used to mirror transformations for handedness conversion. 652 Mirror_Axis :: enum i32 { 653 NONE = 0, 654 X = 1, 655 Y = 2, 656 Z = 3, 657 } 658 659 MIRROR_AXIS_COUNT :: 4 660 661 // Nodes form the scene transformation hierarchy and can contain attached 662 // elements such as meshes or lights. In normal cases a single `ufbx_node` 663 // contains only a single attached element, so using `type/mesh/...` is safe. 664 Node :: struct { 665 using _: struct #raw_union { 666 element: Element, 667 668 using _: struct { 669 name: String, 670 props: Props, 671 element_id: u32, 672 typed_id: u32, 673 }, 674 }, 675 676 // Node hierarchy 677 678 // Parent node containing this one if not root. 679 // 680 // Always non-`NULL` for non-root nodes unless 681 // `ufbx_load_opts.allow_nodes_out_of_root` is enabled. 682 parent: ^Node, 683 684 // List of child nodes parented to this node. 685 children: Node_List, 686 687 // Common attached element type and typed pointers. Set to `NULL` if not in 688 // use, so checking `attrib_type` is not required. 689 // 690 // HINT: If you need less common attributes access `ufbx_node.attrib`, you 691 // can use utility functions like `ufbx_as_nurbs_curve(attrib)` to convert 692 // and check the attribute in one step. 693 mesh: ^Mesh, 694 light: ^Light, 695 camera: ^Camera, 696 bone: ^Bone, 697 698 // Less common attributes use these fields. 699 // 700 // Defined even if it is one of the above, eg. `ufbx_mesh`. In case there 701 // is multiple attributes this will be the first one. 702 attrib: ^Element, 703 704 // Geometry transform helper if one exists. 705 // See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`. 706 geometry_transform_helper: ^Node, 707 708 // Scale helper if one exists. 709 // See `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`. 710 scale_helper: ^Node, 711 712 // `attrib->type` if `attrib` is defined, otherwise `UFBX_ELEMENT_UNKNOWN`. 713 attrib_type: Element_Type, 714 715 // List of _all_ attached attribute elements. 716 // 717 // In most cases there is only zero or one attributes per node, but if you 718 // have a very exotic FBX file nodes may have multiple attributes. 719 all_attribs: Element_List, 720 721 // Local transform in parent, geometry transform is a non-inherited 722 // transform applied only to attachments like meshes 723 inherit_mode: Inherit_Mode, 724 original_inherit_mode: Inherit_Mode, 725 local_transform: Transform, 726 geometry_transform: Transform, 727 728 // Combined scale when using `UFBX_INHERIT_MODE_COMPONENTWISE_SCALE`. 729 // Contains `local_transform.scale` otherwise. 730 inherit_scale: Vec3, 731 732 // Node where scale is inherited from for `UFBX_INHERIT_MODE_COMPONENTWISE_SCALE` 733 // and even for `UFBX_INHERIT_MODE_IGNORE_PARENT_SCALE`. 734 // For componentwise-scale nodes, this will point to `parent`, for scale ignoring 735 // nodes this will point to the parent of the nearest componentwise-scaled node 736 // in the parent chain. 737 inherit_scale_node: ^Node, 738 739 // Raw Euler angles in degrees for those who want them 740 741 // Specifies the axis order `euler_rotation` is applied in. 742 rotation_order: Rotation_Order, 743 744 // Rotation around the local X/Y/Z axes in `rotation_order`. 745 // The angles are specified in degrees. 746 euler_rotation: Vec3, 747 748 // Matrices derived from the transformations, for transforming geometry 749 // prefer using `geometry_to_world` as that supports geometric transforms. 750 751 // Transform from this node to `parent` space. 752 // Equivalent to `ufbx_transform_to_matrix(&local_transform)`. 753 node_to_parent: Matrix, 754 755 // Transform from this node to the world space, ie. multiplying all the 756 // `node_to_parent` matrices of the parent chain together. 757 node_to_world: Matrix, 758 759 // Transform from the attribute to this node. Does not affect the transforms 760 // of `children`! 761 // Equivalent to `ufbx_transform_to_matrix(&geometry_transform)`. 762 geometry_to_node: Matrix, 763 764 // Transform from attribute space to world space. 765 // Equivalent to `ufbx_matrix_mul(&node_to_world, &geometry_to_node)`. 766 geometry_to_world: Matrix, 767 768 // Transform from this node to world space, ignoring self scaling. 769 unscaled_node_to_world: Matrix, 770 771 // ufbx-specific adjustment for switching between coodrinate/unit systems. 772 // HINT: In most cases you don't need to deal with these as these are baked 773 // into all the transforms above and into `ufbx_evaluate_transform()`. 774 adjust_pre_translation: Vec3, // < Translation applied between parent and self 775 adjust_pre_rotation: Quat, // < Rotation applied between parent and self 776 adjust_pre_scale: Real, // < Scaling applied between parent and self 777 adjust_post_rotation: Quat, // < Rotation applied in local space at the end 778 adjust_post_scale: Real, // < Scaling applied in local space at the end 779 adjust_translation_scale: Real, // < Scaling applied to translation only 780 adjust_mirror_axis: Mirror_Axis, // < Mirror translation and rotation on this axis 781 782 // Materials used by `mesh` or other `attrib`. 783 // There may be multiple copies of a single `ufbx_mesh` with different materials 784 // in the `ufbx_node` instances. 785 materials: Material_List, 786 787 // Bind pose 788 bind_pose: ^Pose, 789 790 // Visibility state. 791 visible: bool, 792 793 // True if this node is the implicit root node of the scene. 794 is_root: bool, 795 796 // True if the node has a non-identity `geometry_transform`. 797 has_geometry_transform: bool, 798 799 // If `true` the transform is adjusted by ufbx, not enabled by default. 800 // See `adjust_pre_rotation`, `adjust_pre_scale`, `adjust_post_rotation`, 801 // and `adjust_post_scale`. 802 has_adjust_transform: bool, 803 804 // Scale is adjusted by root scale. 805 has_root_adjust_transform: bool, 806 807 // True if this node is a synthetic geometry transform helper. 808 // See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`. 809 is_geometry_transform_helper: bool, 810 811 // True if the node is a synthetic scale compensation helper. 812 // See `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`. 813 is_scale_helper: bool, 814 815 // Parent node to children that can compensate for parent scale. 816 is_scale_compensate_parent: bool, 817 818 // How deep is this node in the parent hierarchy. Root node is at depth `0` 819 // and the immediate children of root at `1`. 820 node_depth: u32, 821 } 822 823 // Vertex attribute: All attributes are stored in a consistent indexed format 824 // regardless of how it's actually stored in the file. 825 // 826 // `values` is a contiguous array of attribute values. 827 // `indices` maps each mesh index into a value in the `values` array. 828 // 829 // If `unique_per_vertex` is set then the attribute is guaranteed to have a 830 // single defined value per vertex accessible via: 831 // attrib.values.data[attrib.indices.data[mesh->vertex_first_index[vertex_ix]] 832 Vertex_Attrib :: struct { 833 // Is this attribute defined by the mesh. 834 exists: bool, 835 836 // List of values the attribute uses. 837 values: Void_List, 838 839 // Indices into `values[]`, indexed up to `ufbx_mesh.num_indices`. 840 indices: Uint32_List, 841 842 // Number of `ufbx_real` entries per value. 843 value_reals: c.size_t, 844 845 // `true` if this attribute is defined per vertex, instead of per index. 846 unique_per_vertex: bool, 847 848 // Optional 4th 'W' component for the attribute. 849 // May be defined for the following: 850 // ufbx_mesh.vertex_normal 851 // ufbx_mesh.vertex_tangent / ufbx_uv_set.vertex_tangent 852 // ufbx_mesh.vertex_bitangent / ufbx_uv_set.vertex_bitangent 853 // NOTE: This is not loaded by default, set `ufbx_load_opts.retain_vertex_attrib_w`. 854 values_w: Real_List, 855 } 856 857 // 1D vertex attribute, see `ufbx_vertex_attrib` for information 858 Vertex_Real :: struct { 859 exists: bool, 860 values: Real_List, 861 indices: Uint32_List, 862 value_reals: c.size_t, 863 unique_per_vertex: bool, 864 values_w: Real_List, 865 } 866 867 // 2D vertex attribute, see `ufbx_vertex_attrib` for information 868 Vertex_Vec2 :: struct { 869 exists: bool, 870 values: Vec2_List, 871 indices: Uint32_List, 872 value_reals: c.size_t, 873 unique_per_vertex: bool, 874 values_w: Real_List, 875 } 876 877 // 3D vertex attribute, see `ufbx_vertex_attrib` for information 878 Vertex_Vec3 :: struct { 879 exists: bool, 880 values: Vec3_List, 881 indices: Uint32_List, 882 value_reals: c.size_t, 883 unique_per_vertex: bool, 884 values_w: Real_List, 885 } 886 887 // 4D vertex attribute, see `ufbx_vertex_attrib` for information 888 Vertex_Vec4 :: struct { 889 exists: bool, 890 values: Vec4_List, 891 indices: Uint32_List, 892 value_reals: c.size_t, 893 unique_per_vertex: bool, 894 values_w: Real_List, 895 } 896 897 // Vertex UV set/layer 898 Uv_Set :: struct { 899 name: String, 900 index: u32, 901 902 // Vertex attributes, see `ufbx_mesh` attributes for more information 903 vertex_uv: Vertex_Vec2, // < UV / texture coordinates 904 vertex_tangent: Vertex_Vec3, // < (optional) Tangent vector in UV.x direction 905 vertex_bitangent: Vertex_Vec3, // < (optional) Tangent vector in UV.y direction 906 } 907 908 // Vertex color set/layer 909 Color_Set :: struct { 910 name: String, 911 index: u32, 912 913 // Vertex attributes, see `ufbx_mesh` attributes for more information 914 vertex_color: Vertex_Vec4, // < Per-vertex RGBA color 915 } 916 917 Uv_Set_List :: struct { 918 data: ^Uv_Set, 919 count: c.size_t, 920 } 921 922 Color_Set_List :: struct { 923 data: ^Color_Set, 924 count: c.size_t, 925 } 926 927 // Edge between two _indices_ in a mesh 928 Edge :: struct { 929 using _: struct #raw_union { 930 using _: struct { 931 a, b: u32, 932 }, 933 934 indices: [2]u32, 935 }, 936 } 937 938 Edge_List :: struct { 939 data: ^Edge, 940 count: c.size_t, 941 } 942 943 // Polygonal face with arbitrary number vertices, a single face contains a 944 // contiguous range of mesh indices, eg. `{5,3}` would have indices 5, 6, 7 945 // 946 // NOTE: `num_indices` maybe less than 3 in which case the face is invalid! 947 // [TODO #23: should probably remove the bad faces at load time] 948 Face :: struct { 949 index_begin: u32, 950 num_indices: u32, 951 } 952 953 Face_List :: struct { 954 data: [^]Face, 955 count: c.size_t, 956 } 957 958 // Subset of mesh faces used by a single material or group. 959 Mesh_Part :: struct { 960 // Index of the mesh part. 961 index: u32, 962 963 // Sub-set of the geometry 964 num_faces: c.size_t, // < Number of faces (polygons) 965 num_triangles: c.size_t, // < Number of triangles if triangulated 966 num_empty_faces: c.size_t, // < Number of faces with zero vertices 967 num_point_faces: c.size_t, // < Number of faces with a single vertex 968 num_line_faces: c.size_t, // < Number of faces with two vertices 969 970 // Indices to `ufbx_mesh.faces[]`. 971 // Always contains `num_faces` elements. 972 face_indices: Uint32_List, 973 } 974 975 Mesh_Part_List :: struct { 976 data: ^Mesh_Part, 977 count: c.size_t, 978 } 979 980 Face_Group :: struct { 981 id: i32, // < Numerical ID for this group. 982 name: String, // < Name for the face group. 983 } 984 985 Face_Group_List :: struct { 986 data: ^Face_Group, 987 count: c.size_t, 988 } 989 990 Subdivision_Weight_Range :: struct { 991 weight_begin: u32, 992 num_weights: u32, 993 } 994 995 Subdivision_Weight_Range_List :: struct { 996 data: ^Subdivision_Weight_Range, 997 count: c.size_t, 998 } 999 1000 Subdivision_Weight :: struct { 1001 weight: Real, 1002 index: u32, 1003 } 1004 1005 Subdivision_Weight_List :: struct { 1006 data: ^Subdivision_Weight, 1007 count: c.size_t, 1008 } 1009 1010 Subdivision_Result :: struct { 1011 result_memory_used: c.size_t, 1012 temp_memory_used: c.size_t, 1013 result_allocs: c.size_t, 1014 temp_allocs: c.size_t, 1015 1016 // Weights of vertices in the source model. 1017 // Defined if `ufbx_subdivide_opts.evaluate_source_vertices` is set. 1018 source_vertex_ranges: Subdivision_Weight_Range_List, 1019 source_vertex_weights: Subdivision_Weight_List, 1020 1021 // Weights of skin clusters in the source model. 1022 // Defined if `ufbx_subdivide_opts.evaluate_skin_weights` is set. 1023 skin_cluster_ranges: Subdivision_Weight_Range_List, 1024 skin_cluster_weights: Subdivision_Weight_List, 1025 } 1026 1027 Subdivision_Display_Mode :: enum i32 { 1028 DISABLED = 0, 1029 HULL = 1, 1030 HULL_AND_SMOOTH = 2, 1031 SMOOTH = 3, 1032 } 1033 1034 SUBDIVISION_DISPLAY_MODE_COUNT :: 4 1035 1036 Subdivision_Boundary :: enum i32 { 1037 DEFAULT = 0, 1038 LEGACY = 1, 1039 1040 // OpenSubdiv: `VTX_BOUNDARY_EDGE_AND_CORNER` / `FVAR_LINEAR_CORNERS_ONLY` 1041 SHARP_CORNERS = 2, 1042 1043 // OpenSubdiv: `VTX_BOUNDARY_EDGE_ONLY` / `FVAR_LINEAR_NONE` 1044 SHARP_NONE = 3, 1045 1046 // OpenSubdiv: `FVAR_LINEAR_BOUNDARIES` 1047 SHARP_BOUNDARY = 4, 1048 1049 // OpenSubdiv: `FVAR_LINEAR_ALL` 1050 SHARP_INTERIOR = 5, 1051 } 1052 1053 SUBDIVISION_BOUNDARY_COUNT :: 6 1054 1055 // Polygonal mesh geometry. 1056 // 1057 // Example mesh with two triangles (x, z) and a quad (y). 1058 // The faces have a constant UV coordinate x/y/z. 1059 // The vertices have _per vertex_ normals that point up/down. 1060 // 1061 // ^ ^ ^ 1062 // A---B-----C 1063 // |x / /| 1064 // | / y / | 1065 // |/ / z| 1066 // D-----E---F 1067 // v v v 1068 // 1069 // Attributes may have multiple values within a single vertex, for example a 1070 // UV seam vertex has two UV coordinates. Thus polygons are defined using 1071 // an index that counts each corner of each face polygon. If an attribute is 1072 // defined (even per-vertex) it will always have a valid `indices` array. 1073 // 1074 // {0,3} {3,4} {7,3} faces ({ index_begin, num_indices }) 1075 // 0 1 2 3 4 5 6 7 8 9 index 1076 // 1077 // 0 1 3 1 2 4 3 2 4 5 vertex_indices[index] 1078 // A B D B C E D C E F vertices[vertex_indices[index]] 1079 // 1080 // 0 0 1 0 0 1 1 0 1 1 vertex_normal.indices[index] 1081 // ^ ^ v ^ ^ v v ^ v v vertex_normal.data[vertex_normal.indices[index]] 1082 // 1083 // 0 0 0 1 1 1 1 2 2 2 vertex_uv.indices[index] 1084 // x x x y y y y z z z vertex_uv.data[vertex_uv.indices[index]] 1085 // 1086 // Vertex position can also be accessed uniformly through an accessor: 1087 // 0 1 3 1 2 4 3 2 4 5 vertex_position.indices[index] 1088 // A B D B C E D C E F vertex_position.data[vertex_position.indices[index]] 1089 // 1090 // Some geometry data is specified per logical vertex. Vertex positions are 1091 // the only attribute that is guaranteed to be defined _uniquely_ per vertex. 1092 // Vertex attributes _may_ be defined per vertex if `unique_per_vertex == true`. 1093 // You can access the per-vertex values by first finding the first index that 1094 // refers to the given vertex. 1095 // 1096 // 0 1 2 3 4 5 vertex 1097 // A B C D E F vertices[vertex] 1098 // 1099 // 0 1 4 2 5 9 vertex_first_index[vertex] 1100 // 0 0 0 1 1 1 vertex_normal.indices[vertex_first_index[vertex]] 1101 // ^ ^ ^ v v v vertex_normal.data[vertex_normal.indices[vertex_first_index[vertex]]] 1102 // 1103 Mesh :: struct { 1104 using _: struct #raw_union { 1105 element: Element, 1106 1107 using _: struct { 1108 name: String, 1109 props: Props, 1110 element_id: u32, 1111 typed_id: u32, 1112 instances: Node_List, 1113 }, 1114 }, 1115 1116 // Number of "logical" vertices that would be treated as a single point, 1117 // one vertex may be split to multiple indices for split attributes, eg. UVs 1118 num_vertices: c.size_t, // < Number of logical "vertex" points 1119 num_indices: c.size_t, // < Number of combiend vertex/attribute tuples 1120 num_faces: c.size_t, // < Number of faces (polygons) in the mesh 1121 num_triangles: c.size_t, // < Number of triangles if triangulated 1122 1123 // Number of edges in the mesh. 1124 // NOTE: May be zero in valid meshes if the file doesn't contain edge adjacency data! 1125 num_edges: c.size_t, 1126 max_face_triangles: c.size_t, // < Maximum number of triangles in a face in this mesh 1127 num_empty_faces: c.size_t, // < Number of faces with zero vertices 1128 num_point_faces: c.size_t, // < Number of faces with a single vertex 1129 num_line_faces: c.size_t, // < Number of faces with two vertices 1130 1131 // Faces and optional per-face extra data 1132 faces: Face_List, // < Face index range 1133 face_smoothing: Bool_List, // < Should the face have soft normals 1134 face_material: Uint32_List, // < Indices to `ufbx_mesh.materials[]` and `ufbx_node.materials[]` 1135 face_group: Uint32_List, // < Face polygon group index, indices to `ufbx_mesh.face_groups[]` 1136 face_hole: Bool_List, // < Should the face be hidden as a "hole" 1137 1138 // Edges and optional per-edge extra data 1139 edges: Edge_List, // < Edge index range 1140 edge_smoothing: Bool_List, // < Should the edge have soft normals 1141 edge_crease: Real_List, // < Crease value for subdivision surfaces 1142 edge_visibility: Bool_List, // < Should the edge be visible 1143 1144 // Logical vertices and positions, alternatively you can use 1145 // `vertex_position` for consistent interface with other attributes. 1146 vertex_indices: Uint32_List, 1147 vertices: Vec3_List, 1148 1149 // First index referring to a given vertex, `UFBX_NO_INDEX` if the vertex is unused. 1150 vertex_first_index: Uint32_List, 1151 1152 // Vertex attributes, see the comment over the struct. 1153 // 1154 // NOTE: Not all meshes have all attributes, in that case `indices/data == NULL`! 1155 // 1156 // NOTE: UV/tangent/bitangent and color are the from first sets, 1157 // use `uv_sets/color_sets` to access the other layers. 1158 vertex_position: Vertex_Vec3, // < Vertex positions 1159 vertex_normal: Vertex_Vec3, // < (optional) Normal vectors, always defined if `ufbx_load_opts.generate_missing_normals` 1160 vertex_uv: Vertex_Vec2, // < (optional) UV / texture coordinates 1161 vertex_tangent: Vertex_Vec3, // < (optional) Tangent vector in UV.x direction 1162 vertex_bitangent: Vertex_Vec3, // < (optional) Tangent vector in UV.y direction 1163 vertex_color: Vertex_Vec4, // < (optional) Per-vertex RGBA color 1164 vertex_crease: Vertex_Real, // < (optional) Crease value for subdivision surfaces 1165 1166 // Multiple named UV/color sets 1167 // NOTE: The first set contains the same data as `vertex_uv/color`! 1168 uv_sets: Uv_Set_List, 1169 color_sets: Color_Set_List, 1170 1171 // Materials used by the mesh. 1172 // NOTE: These can be wrong if you want to support per-instance materials! 1173 // Use `ufbx_node.materials[]` to get the per-instance materials at the same indices. 1174 materials: Material_List, 1175 1176 // Face groups for this mesh. 1177 face_groups: Face_Group_List, 1178 1179 // Segments that use a given material. 1180 // Defined even if the mesh doesn't have any materials. 1181 material_parts: Mesh_Part_List, 1182 1183 // Segments for each face group. 1184 face_group_parts: Mesh_Part_List, 1185 1186 // Order of `material_parts` by first face that refers to it. 1187 // Useful for compatibility with FBX SDK and various importers using it, 1188 // as they use this material order by default. 1189 material_part_usage_order: Uint32_List, 1190 1191 // Skinned vertex positions, for efficiency the skinned positions are the 1192 // same as the static ones for non-skinned meshes and `skinned_is_local` 1193 // is set to true meaning you need to transform them manually using 1194 // `ufbx_transform_position(&node->geometry_to_world, skinned_pos)`! 1195 skinned_is_local: bool, 1196 skinned_position: Vertex_Vec3, 1197 skinned_normal: Vertex_Vec3, 1198 1199 // Deformers 1200 skin_deformers: Skin_Deformer_List, 1201 blend_deformers: Blend_Deformer_List, 1202 cache_deformers: Cache_Deformer_List, 1203 all_deformers: Element_List, 1204 1205 // Subdivision 1206 subdivision_preview_levels: u32, 1207 subdivision_render_levels: u32, 1208 subdivision_display_mode: Subdivision_Display_Mode, 1209 subdivision_boundary: Subdivision_Boundary, 1210 subdivision_uv_boundary: Subdivision_Boundary, 1211 1212 // The winding of the faces has been reversed. 1213 reversed_winding: bool, 1214 1215 // Normals have been generated instead of evaluated. 1216 // Either from missing normals (via `ufbx_load_opts.generate_missing_normals`), skinning, 1217 // tessellation, or subdivision. 1218 generated_normals: bool, 1219 1220 // Subdivision (result) 1221 subdivision_evaluated: bool, 1222 subdivision_result: ^Subdivision_Result, 1223 1224 // Tessellation (result) 1225 from_tessellated_nurbs: bool, 1226 } 1227 1228 // The kind of light source 1229 Light_Type :: enum i32 { 1230 // Single point at local origin, at `node->world_transform.position` 1231 POINT = 0, 1232 1233 // Infinite directional light pointing locally towards `light->local_direction` 1234 // For global: `ufbx_transform_direction(&node->node_to_world, light->local_direction)` 1235 DIRECTIONAL = 1, 1236 1237 // Cone shaped light towards `light->local_direction`, between `light->inner/outer_angle`. 1238 // For global: `ufbx_transform_direction(&node->node_to_world, light->local_direction)` 1239 SPOT = 2, 1240 1241 // Area light, shape specified by `light->area_shape` 1242 // TODO: Units? 1243 AREA = 3, 1244 1245 // Volumetric light source 1246 // TODO: How does this work 1247 VOLUME = 4, 1248 } 1249 1250 LIGHT_TYPE_COUNT :: 5 1251 1252 // How fast does the light intensity decay at a distance 1253 Light_Decay :: enum i32 { 1254 NONE = 0, // < 1 (no decay) 1255 LINEAR = 1, // < 1 / d 1256 QUADRATIC = 2, // < 1 / d^2 (physically accurate) 1257 CUBIC = 3, // < 1 / d^3 1258 } 1259 1260 LIGHT_DECAY_COUNT :: 4 1261 1262 Light_Area_Shape :: enum i32 { 1263 RECTANGLE = 0, 1264 SPHERE = 1, 1265 } 1266 1267 LIGHT_AREA_SHAPE_COUNT :: 2 1268 1269 // Light source attached to a `ufbx_node` 1270 Light :: struct { 1271 using _: struct #raw_union { 1272 element: Element, 1273 1274 using _: struct { 1275 name: String, 1276 props: Props, 1277 element_id: u32, 1278 typed_id: u32, 1279 instances: Node_List, 1280 }, 1281 }, 1282 1283 // Color and intensity of the light, usually you want to use `color * intensity` 1284 // NOTE: `intensity` is 0.01x of the property `"Intensity"` as that matches 1285 // matches values in DCC programs before exporting. 1286 color: Vec3, 1287 intensity: Real, 1288 1289 // Direction the light is aimed at in node's local space, usually -Y 1290 local_direction: Vec3, 1291 1292 // Type of the light and shape parameters 1293 type: Light_Type, 1294 decay: Light_Decay, 1295 area_shape: Light_Area_Shape, 1296 inner_angle: Real, 1297 outer_angle: Real, 1298 cast_light: bool, 1299 cast_shadows: bool, 1300 } 1301 1302 Projection_Mode :: enum i32 { 1303 // Perspective projection. 1304 PERSPECTIVE = 0, 1305 1306 // Orthographic projection. 1307 ORTHOGRAPHIC = 1, 1308 } 1309 1310 PROJECTION_MODE_COUNT :: 2 1311 1312 // Method of specifying the rendering resolution from properties 1313 // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly! 1314 Aspect_Mode :: enum i32 { 1315 // No defined resolution 1316 WINDOW_SIZE = 0, 1317 1318 // `"AspectWidth"` and `"AspectHeight"` are relative to each other 1319 FIXED_RATIO = 1, 1320 1321 // `"AspectWidth"` and `"AspectHeight"` are both pixels 1322 FIXED_RESOLUTION = 2, 1323 1324 // `"AspectWidth"` is pixels, `"AspectHeight"` is relative to width 1325 FIXED_WIDTH = 3, 1326 1327 // < `"AspectHeight"` is pixels, `"AspectWidth"` is relative to height 1328 FIXED_HEIGHT = 4, 1329 } 1330 1331 ASPECT_MODE_COUNT :: 5 1332 1333 // Method of specifying the field of view from properties 1334 // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly! 1335 Aperture_Mode :: enum i32 { 1336 // Use separate `"FieldOfViewX"` and `"FieldOfViewY"` as horizontal/vertical FOV angles 1337 HORIZONTAL_AND_VERTICAL = 0, 1338 1339 // Use `"FieldOfView"` as horizontal FOV angle, derive vertical angle via aspect ratio 1340 HORIZONTAL = 1, 1341 1342 // Use `"FieldOfView"` as vertical FOV angle, derive horizontal angle via aspect ratio 1343 VERTICAL = 2, 1344 1345 // Compute the field of view from the render gate size and focal length 1346 FOCAL_LENGTH = 3, 1347 } 1348 1349 APERTURE_MODE_COUNT :: 4 1350 1351 // Method of specifying the render gate size from properties 1352 // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly! 1353 Gate_Fit :: enum i32 { 1354 // Use the film/aperture size directly as the render gate 1355 NONE = 0, 1356 1357 // Fit the render gate to the height of the film, derive width from aspect ratio 1358 VERTICAL = 1, 1359 1360 // Fit the render gate to the width of the film, derive height from aspect ratio 1361 HORIZONTAL = 2, 1362 1363 // Fit the render gate so that it is fully contained within the film gate 1364 FILL = 3, 1365 1366 // Fit the render gate so that it fully contains the film gate 1367 OVERSCAN = 4, 1368 1369 // Stretch the render gate to match the film gate 1370 // TODO: Does this differ from `UFBX_GATE_FIT_NONE`? 1371 STRETCH = 5, 1372 } 1373 1374 GATE_FIT_COUNT :: 6 1375 1376 // Camera film/aperture size defaults 1377 // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly! 1378 Aperture_Format :: enum i32 { 1379 CUSTOM = 0, // < Use `"FilmWidth"` and `"FilmHeight"` 1380 _16MM_THEATRICAL = 1, // < 0.404 x 0.295 inches 1381 SUPER_16MM = 2, // < 0.493 x 0.292 inches 1382 _35MM_ACADEMY = 3, // < 0.864 x 0.630 inches 1383 _35MM_TV_PROJECTION = 4, // < 0.816 x 0.612 inches 1384 _35MM_FULL_APERTURE = 5, // < 0.980 x 0.735 inches 1385 _35MM_185_PROJECTION = 6, // < 0.825 x 0.446 inches 1386 _35MM_ANAMORPHIC = 7, // < 0.864 x 0.732 inches (squeeze ratio: 2) 1387 _70MM_PROJECTION = 8, // < 2.066 x 0.906 inches 1388 VISTAVISION = 9, // < 1.485 x 0.991 inches 1389 DYNAVISION = 10, // < 2.080 x 1.480 inches 1390 IMAX = 11, // < 2.772 x 2.072 inches 1391 } 1392 1393 APERTURE_FORMAT_COUNT :: 12 1394 1395 Coordinate_Axis :: enum i32 { 1396 POSITIVE_X = 0, 1397 NEGATIVE_X = 1, 1398 POSITIVE_Y = 2, 1399 NEGATIVE_Y = 3, 1400 POSITIVE_Z = 4, 1401 NEGATIVE_Z = 5, 1402 UNKNOWN = 6, 1403 } 1404 1405 COORDINATE_AXIS_COUNT :: 7 1406 1407 // Coordinate axes the scene is represented in. 1408 // NOTE: `front` is the _opposite_ from forward! 1409 Coordinate_Axes :: struct { 1410 right: Coordinate_Axis, 1411 up: Coordinate_Axis, 1412 front: Coordinate_Axis, 1413 } 1414 1415 // Camera attached to a `ufbx_node` 1416 Camera :: struct { 1417 using _: struct #raw_union { 1418 element: Element, 1419 1420 using _: struct { 1421 name: String, 1422 props: Props, 1423 element_id: u32, 1424 typed_id: u32, 1425 instances: Node_List, 1426 }, 1427 }, 1428 1429 // Projection mode (perspective/orthographic). 1430 projection_mode: Projection_Mode, 1431 1432 // If set to `true`, `resolution` represents actual pixel values, otherwise 1433 // it's only useful for its aspect ratio. 1434 resolution_is_pixels: bool, 1435 1436 // Render resolution, either in pixels or arbitrary units, depending on above 1437 resolution: Vec2, 1438 1439 // Horizontal/vertical field of view in degrees 1440 // Valid if `projection_mode == UFBX_PROJECTION_MODE_PERSPECTIVE`. 1441 field_of_view_deg: Vec2, 1442 1443 // Component-wise `tan(field_of_view_deg)`, also represents the size of the 1444 // proection frustum slice at distance of 1. 1445 // Valid if `projection_mode == UFBX_PROJECTION_MODE_PERSPECTIVE`. 1446 field_of_view_tan: Vec2, 1447 1448 // Orthographic camera extents. 1449 // Valid if `projection_mode == UFBX_PROJECTION_MODE_ORTHOGRAPHIC`. 1450 orthographic_extent: Real, 1451 1452 // Orthographic camera size. 1453 // Valid if `projection_mode == UFBX_PROJECTION_MODE_ORTHOGRAPHIC`. 1454 orthographic_size: Vec2, 1455 1456 // Size of the projection plane at distance 1. 1457 // Equal to `field_of_view_tan` if perspective, `orthographic_size` if orthographic. 1458 projection_plane: Vec2, 1459 1460 // Aspect ratio of the camera. 1461 aspect_ratio: Real, 1462 1463 // Near plane of the frustum in units from the camera. 1464 near_plane: Real, 1465 1466 // Far plane of the frustum in units from the camera. 1467 far_plane: Real, 1468 1469 // Coordinate system that the projection uses. 1470 // FBX saves cameras with +X forward and +Y up, but you can override this using 1471 // `ufbx_load_opts.target_camera_axes` and it will be reflected here. 1472 projection_axes: Coordinate_Axes, 1473 1474 // Advanced properties used to compute the above 1475 aspect_mode: Aspect_Mode, 1476 aperture_mode: Aperture_Mode, 1477 gate_fit: Gate_Fit, 1478 aperture_format: Aperture_Format, 1479 focal_length_mm: Real, // < Focal length in millimeters 1480 film_size_inch: Vec2, // < Film size in inches 1481 aperture_size_inch: Vec2, // < Aperture/film gate size in inches 1482 squeeze_ratio: Real, // < Anamoprhic stretch ratio 1483 } 1484 1485 // Bone attached to a `ufbx_node`, provides the logical length of the bone 1486 // but most interesting information is directly in `ufbx_node`. 1487 Bone :: struct { 1488 using _: struct #raw_union { 1489 element: Element, 1490 1491 using _: struct { 1492 name: String, 1493 props: Props, 1494 element_id: u32, 1495 typed_id: u32, 1496 instances: Node_List, 1497 }, 1498 }, 1499 1500 // Visual radius of the bone 1501 radius: Real, 1502 1503 // Length of the bone relative to the distance between two nodes 1504 relative_length: Real, 1505 1506 // Is the bone a root bone 1507 is_root: bool, 1508 } 1509 1510 // Empty/NULL/locator connected to a node, actual details in `ufbx_node` 1511 Empty :: struct { 1512 using _: struct #raw_union { 1513 element: Element, 1514 1515 using _: struct { 1516 name: String, 1517 props: Props, 1518 element_id: u32, 1519 typed_id: u32, 1520 instances: Node_List, 1521 }, 1522 }, 1523 } 1524 1525 // Segment of a `ufbx_line_curve`, indices refer to `ufbx_line_curve.point_indices[]` 1526 Line_Segment :: struct { 1527 index_begin: u32, 1528 num_indices: u32, 1529 } 1530 1531 Line_Segment_List :: struct { 1532 data: ^Line_Segment, 1533 count: c.size_t, 1534 } 1535 1536 Line_Curve :: struct { 1537 using _: struct #raw_union { 1538 element: Element, 1539 1540 using _: struct { 1541 name: String, 1542 props: Props, 1543 element_id: u32, 1544 typed_id: u32, 1545 instances: Node_List, 1546 }, 1547 }, 1548 1549 color: Vec3, 1550 control_points: Vec3_List, // < List of possible values the line passes through 1551 point_indices: Uint32_List, // < Indices to `control_points[]` the line goes through 1552 segments: Line_Segment_List, 1553 1554 // Tessellation (result) 1555 from_tessellated_nurbs: bool, 1556 } 1557 1558 Nurbs_Topology :: enum i32 { 1559 // The endpoints are not connected. 1560 OPEN = 0, 1561 1562 // Repeats first `ufbx_nurbs_basis.order - 1` control points after the end. 1563 PERIODIC = 1, 1564 1565 // Repeats the first control point after the end. 1566 CLOSED = 2, 1567 } 1568 1569 NURBS_TOPOLOGY_COUNT :: 3 1570 1571 // NURBS basis functions for an axis 1572 Nurbs_Basis :: struct { 1573 // Number of control points influencing a point on the curve/surface. 1574 // Equal to the degree plus one. 1575 order: u32, 1576 1577 // Topology (periodicity) of the dimension. 1578 topology: Nurbs_Topology, 1579 1580 // Subdivision of the parameter range to control points. 1581 knot_vector: Real_List, 1582 1583 // Range for the parameter value. 1584 t_min: Real, 1585 t_max: Real, 1586 1587 // Parameter values of control points. 1588 spans: Real_List, 1589 1590 // `true` if this axis is two-dimensional. 1591 is_2d: bool, 1592 1593 // Number of control points that need to be copied to the end. 1594 // This is just for convenience as it could be derived from `topology` and 1595 // `order`. If for example `num_wrap_control_points == 3` you should repeat 1596 // the first 3 control points after the end. 1597 // HINT: You don't need to worry about this if you use ufbx functions 1598 // like `ufbx_evaluate_nurbs_curve()` as they handle this internally. 1599 num_wrap_control_points: c.size_t, 1600 1601 // `true` if the parametrization is well defined. 1602 valid: bool, 1603 } 1604 1605 Nurbs_Curve :: struct { 1606 using _: struct #raw_union { 1607 element: Element, 1608 1609 using _: struct { 1610 name: String, 1611 props: Props, 1612 element_id: u32, 1613 typed_id: u32, 1614 instances: Node_List, 1615 }, 1616 }, 1617 1618 // Basis in the U axis 1619 basis: Nurbs_Basis, 1620 1621 // Linear array of control points 1622 // NOTE: The control points are _not_ homogeneous, meaning you have to multiply 1623 // them by `w` before evaluating the surface. 1624 control_points: Vec4_List, 1625 } 1626 1627 Nurbs_Surface :: struct { 1628 using _: struct #raw_union { 1629 element: Element, 1630 1631 using _: struct { 1632 name: String, 1633 props: Props, 1634 element_id: u32, 1635 typed_id: u32, 1636 instances: Node_List, 1637 }, 1638 }, 1639 1640 // Basis in the U/V axes 1641 basis_u: Nurbs_Basis, 1642 basis_v: Nurbs_Basis, 1643 1644 // Number of control points for the U/V axes 1645 num_control_points_u: c.size_t, 1646 num_control_points_v: c.size_t, 1647 1648 // 2D array of control points. 1649 // Memory layout: `V * num_control_points_u + U` 1650 // NOTE: The control points are _not_ homogeneous, meaning you have to multiply 1651 // them by `w` before evaluating the surface. 1652 control_points: Vec4_List, 1653 1654 // How many segments tessellate each span in `ufbx_nurbs_basis.spans`. 1655 span_subdivision_u: u32, 1656 span_subdivision_v: u32, 1657 1658 // If `true` the resulting normals should be flipped when evaluated. 1659 flip_normals: bool, 1660 1661 // Material for the whole surface. 1662 // NOTE: May be `NULL`! 1663 material: ^Material, 1664 } 1665 1666 Nurbs_Trim_Surface :: struct { 1667 using _: struct #raw_union { 1668 element: Element, 1669 1670 using _: struct { 1671 name: String, 1672 props: Props, 1673 element_id: u32, 1674 typed_id: u32, 1675 instances: Node_List, 1676 }, 1677 }, 1678 } 1679 1680 Nurbs_Trim_Boundary :: struct { 1681 using _: struct #raw_union { 1682 element: Element, 1683 1684 using _: struct { 1685 name: String, 1686 props: Props, 1687 element_id: u32, 1688 typed_id: u32, 1689 instances: Node_List, 1690 }, 1691 }, 1692 } 1693 1694 // -- Node attributes (advanced) 1695 Procedural_Geometry :: struct { 1696 using _: struct #raw_union { 1697 element: Element, 1698 1699 using _: struct { 1700 name: String, 1701 props: Props, 1702 element_id: u32, 1703 typed_id: u32, 1704 instances: Node_List, 1705 }, 1706 }, 1707 } 1708 1709 Stereo_Camera :: struct { 1710 using _: struct #raw_union { 1711 element: Element, 1712 1713 using _: struct { 1714 name: String, 1715 props: Props, 1716 element_id: u32, 1717 typed_id: u32, 1718 instances: Node_List, 1719 }, 1720 }, 1721 1722 left: ^Camera, 1723 right: ^Camera, 1724 } 1725 1726 Camera_Switcher :: struct { 1727 using _: struct #raw_union { 1728 element: Element, 1729 1730 using _: struct { 1731 name: String, 1732 props: Props, 1733 element_id: u32, 1734 typed_id: u32, 1735 instances: Node_List, 1736 }, 1737 }, 1738 } 1739 1740 Marker_Type :: enum i32 { 1741 UNKNOWN = 0, // < Unknown marker type 1742 FK_EFFECTOR = 1, // < FK (Forward Kinematics) effector 1743 IK_EFFECTOR = 2, // < IK (Inverse Kinematics) effector 1744 } 1745 1746 MARKER_TYPE_COUNT :: 3 1747 1748 // Tracking marker for effectors 1749 Marker :: struct { 1750 using _: struct #raw_union { 1751 element: Element, 1752 1753 using _: struct { 1754 name: String, 1755 props: Props, 1756 element_id: u32, 1757 typed_id: u32, 1758 instances: Node_List, 1759 }, 1760 }, 1761 1762 // Type of the marker 1763 type: Marker_Type, 1764 } 1765 1766 // LOD level display mode. 1767 Lod_Display :: enum i32 { 1768 USE_LOD = 0, // < Display the LOD level if the distance is appropriate. 1769 SHOW = 1, // < Always display the LOD level. 1770 HIDE = 2, // < Never display the LOD level. 1771 } 1772 1773 LOD_DISPLAY_COUNT :: 3 1774 1775 // Single LOD level within an LOD group. 1776 // Specifies properties of the Nth child of the _node_ containing the LOD group. 1777 Lod_Level :: struct { 1778 // Minimum distance to show this LOD level. 1779 // NOTE: In world units by default, or in screen percentage if 1780 // `ufbx_lod_group.relative_distances` is set. 1781 distance: Real, 1782 1783 // LOD display mode. 1784 // NOTE: Mostly for editing, you should probably ignore this 1785 // unless making a modeling program. 1786 display: Lod_Display, 1787 } 1788 1789 Lod_Level_List :: struct { 1790 data: ^Lod_Level, 1791 count: c.size_t, 1792 } 1793 1794 // Group of LOD (Level of Detail) levels for an object. 1795 // The actual LOD models are defined in the parent `ufbx_node.children`. 1796 Lod_Group :: struct { 1797 using _: struct #raw_union { 1798 element: Element, 1799 1800 using _: struct { 1801 name: String, 1802 props: Props, 1803 element_id: u32, 1804 typed_id: u32, 1805 instances: Node_List, 1806 }, 1807 }, 1808 1809 // If set to `true`, `ufbx_lod_level.distance` represents a screen size percentage. 1810 relative_distances: bool, 1811 1812 // LOD levels matching in order to `ufbx_node.children`. 1813 lod_levels: Lod_Level_List, 1814 1815 // If set to `true` don't account for parent transform when computing the distance. 1816 ignore_parent_transform: bool, 1817 1818 // If `use_distance_limit` is enabled hide the group if the distance is not between 1819 // `distance_limit_min` and `distance_limit_max`. 1820 use_distance_limit: bool, 1821 distance_limit_min: Real, 1822 distance_limit_max: Real, 1823 } 1824 1825 // Method to evaluate the skinning on a per-vertex level 1826 Skinning_Method :: enum i32 { 1827 // Linear blend skinning: Blend transformation matrices by vertex weights 1828 LINEAR = 0, 1829 1830 // One vertex should have only one bone attached 1831 RIGID = 1, 1832 1833 // Convert the transformations to dual quaternions and blend in that space 1834 DUAL_QUATERNION = 2, 1835 1836 // Blend between `UFBX_SKINNING_METHOD_LINEAR` and `UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR` 1837 // The blend weight can be found either per-vertex in `ufbx_skin_vertex.dq_weight` 1838 // or in `ufbx_skin_deformer.dq_vertices/dq_weights` (indexed by vertex). 1839 BLENDED_DQ_LINEAR = 3, 1840 } 1841 1842 SKINNING_METHOD_COUNT :: 4 1843 1844 // Skin weight information for a single mesh vertex 1845 Skin_Vertex :: struct { 1846 // Each vertex is influenced by weights from `ufbx_skin_deformer.weights[]` 1847 // The weights are sorted by decreasing weight so you can take the first N 1848 // weights to get a cheaper approximation of the vertex. 1849 // NOTE: The weights are not guaranteed to be normalized! 1850 weight_begin: u32, // < Index to start from in the `weights[]` array 1851 num_weights: u32, // < Number of weights influencing the vertex 1852 1853 // Blend weight between Linear Blend Skinning (0.0) and Dual Quaternion (1.0). 1854 // Should be used if `skinning_method == UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR` 1855 dq_weight: Real, 1856 } 1857 1858 Skin_Vertex_List :: struct { 1859 data: ^Skin_Vertex, 1860 count: c.size_t, 1861 } 1862 1863 // Single per-vertex per-cluster weight, see `ufbx_skin_vertex` 1864 Skin_Weight :: struct { 1865 cluster_index: u32, // < Index into `ufbx_skin_deformer.clusters[]` 1866 weight: Real, // < Amount this bone influence the vertex 1867 } 1868 1869 Skin_Weight_List :: struct { 1870 data: ^Skin_Weight, 1871 count: c.size_t, 1872 } 1873 1874 // Skin deformer specifies a binding between a logical set of bones (a skeleton) 1875 // and a mesh. Each bone is represented by a `ufbx_skin_cluster` that contains 1876 // the binding matrix and a `ufbx_node *bone` that has the current transformation. 1877 Skin_Deformer :: struct { 1878 using _: struct #raw_union { 1879 element: Element, 1880 1881 using _: struct { 1882 name: String, 1883 props: Props, 1884 element_id: u32, 1885 typed_id: u32, 1886 }, 1887 }, 1888 1889 skinning_method: Skinning_Method, 1890 1891 // Clusters (bones) in the skin 1892 clusters: Skin_Cluster_List, 1893 1894 // Per-vertex weight information 1895 vertices: Skin_Vertex_List, 1896 weights: Skin_Weight_List, 1897 1898 // Largest amount of weights a single vertex can have 1899 max_weights_per_vertex: c.size_t, 1900 1901 // Blend weights between Linear Blend Skinning (0.0) and Dual Quaternion (1.0). 1902 // HINT: You probably want to use `vertices` and `ufbx_skin_vertex.dq_weight` instead! 1903 // NOTE: These may be out-of-bounds for a given mesh, `vertices` is always safe. 1904 num_dq_weights: c.size_t, 1905 dq_vertices: Uint32_List, 1906 dq_weights: Real_List, 1907 } 1908 1909 // Cluster of vertices bound to a single bone. 1910 Skin_Cluster :: struct { 1911 using _: struct #raw_union { 1912 element: Element, 1913 1914 using _: struct { 1915 name: String, 1916 props: Props, 1917 element_id: u32, 1918 typed_id: u32, 1919 }, 1920 }, 1921 1922 // The bone node the cluster is attached to 1923 // NOTE: Always valid if found from `ufbx_skin_deformer.clusters[]` unless 1924 // `ufbx_load_opts.connect_broken_elements` is `true`. 1925 bone_node: ^Node, 1926 1927 // Binding matrix from local mesh vertices to the bone 1928 geometry_to_bone: Matrix, 1929 1930 // Binding matrix from local mesh _node_ to the bone. 1931 // NOTE: Prefer `geometry_to_bone` in most use cases! 1932 mesh_node_to_bone: Matrix, 1933 1934 // Matrix that specifies the rest/bind pose transform of the node, 1935 // not generally needed for skinning, use `geometry_to_bone` instead. 1936 bind_to_world: Matrix, 1937 1938 // Precomputed matrix/transform that accounts for the current bone transform 1939 // ie. `ufbx_matrix_mul(&cluster->bone->node_to_world, &cluster->geometry_to_bone)` 1940 geometry_to_world: Matrix, 1941 geometry_to_world_transform: Transform, 1942 1943 // Raw weights indexed by each _vertex_ of a mesh (not index!) 1944 // HINT: It may be simpler to use `ufbx_skin_deformer.vertices[]/weights[]` instead! 1945 // NOTE: These may be out-of-bounds for a given mesh, `ufbx_skin_deformer.vertices` is always safe. 1946 num_weights: c.size_t, // < Number of vertices in the cluster 1947 vertices: Uint32_List, // < Vertex indices in `ufbx_mesh.vertices[]` 1948 weights: Real_List, // < Per-vertex weight values 1949 } 1950 1951 // Blend shape deformer can contain multiple channels (think of sliders between morphs) 1952 // that may optionally have in-between keyframes. 1953 Blend_Deformer :: struct { 1954 using _: struct #raw_union { 1955 element: Element, 1956 1957 using _: struct { 1958 name: String, 1959 props: Props, 1960 element_id: u32, 1961 typed_id: u32, 1962 }, 1963 }, 1964 1965 // Independent morph targets of the deformer. 1966 channels: Blend_Channel_List, 1967 } 1968 1969 // Blend shape associated with a target weight in a series of morphs 1970 Blend_Keyframe :: struct { 1971 // The target blend shape offsets. 1972 shape: ^Blend_Shape, 1973 1974 // Weight value at which to apply the keyframe at full strength 1975 target_weight: Real, 1976 1977 // The weight the shape should be currently applied with 1978 effective_weight: Real, 1979 } 1980 1981 Blend_Keyframe_List :: struct { 1982 data: ^Blend_Keyframe, 1983 count: c.size_t, 1984 } 1985 1986 // Blend channel consists of multiple morph-key targets that are interpolated. 1987 // In simple cases there will be only one keyframe that is the target shape. 1988 Blend_Channel :: struct { 1989 using _: struct #raw_union { 1990 element: Element, 1991 1992 using _: struct { 1993 name: String, 1994 props: Props, 1995 element_id: u32, 1996 typed_id: u32, 1997 }, 1998 }, 1999 2000 // Current weight of the channel 2001 weight: Real, 2002 2003 // Key morph targets to blend between depending on `weight` 2004 // In usual cases there's only one target per channel 2005 keyframes: Blend_Keyframe_List, 2006 2007 // Final blend shape ignoring any intermediate blend shapes. 2008 target_shape: ^Blend_Shape, 2009 } 2010 2011 // Blend shape target containing the actual vertex offsets 2012 Blend_Shape :: struct { 2013 using _: struct #raw_union { 2014 element: Element, 2015 2016 using _: struct { 2017 name: String, 2018 props: Props, 2019 element_id: u32, 2020 typed_id: u32, 2021 }, 2022 }, 2023 2024 // Vertex offsets to apply over the base mesh 2025 // NOTE: The `offset_vertices` may be out-of-bounds for a given mesh! 2026 num_offsets: c.size_t, // < Number of vertex offsets in the following arrays 2027 offset_vertices: Uint32_List, // < Indices to `ufbx_mesh.vertices[]` 2028 position_offsets: Vec3_List, // < Always specified per-vertex offsets 2029 normal_offsets: Vec3_List, // < Empty if not specified 2030 } 2031 2032 Cache_File_Format :: enum i32 { 2033 UNKNOWN = 0, // < Unknown cache file format 2034 PC2 = 1, // < .pc2 Point cache file 2035 MC = 2, // < .mc/.mcx Maya cache file 2036 } 2037 2038 CACHE_FILE_FORMAT_COUNT :: 3 2039 2040 Cache_Data_Format :: enum i32 { 2041 UNKNOWN = 0, // < Unknown data format 2042 REAL_FLOAT = 1, // < `float data[]` 2043 VEC3_FLOAT = 2, // < `struct { float x, y, z; } data[]` 2044 REAL_DOUBLE = 3, // < `double data[]` 2045 VEC3_DOUBLE = 4, // < `struct { double x, y, z; } data[]` 2046 } 2047 2048 CACHE_DATA_FORMAT_COUNT :: 5 2049 2050 Cache_Data_Encoding :: enum i32 { 2051 UNKNOWN = 0, // < Unknown data encoding 2052 LITTLE_ENDIAN = 1, // < Contiguous little-endian array 2053 BIG_ENDIAN = 2, // < Contiguous big-endian array 2054 } 2055 2056 CACHE_DATA_ENCODING_COUNT :: 3 2057 2058 // Known interpretations of geometry cache data. 2059 Cache_Interpretation :: enum i32 { 2060 // Unknown interpretation, see `ufbx_cache_channel.interpretation_name` for more information. 2061 UNKNOWN = 0, 2062 2063 // Generic "points" interpretation, FBX SDK default. Usually fine to interpret 2064 // as vertex positions if no other cache channels are specified. 2065 POINTS = 1, 2066 2067 // Vertex positions. 2068 VERTEX_POSITION = 2, 2069 2070 // Vertex normals. 2071 VERTEX_NORMAL = 3, 2072 } 2073 2074 CACHE_INTERPRETATION_COUNT :: 4 2075 2076 Cache_Frame :: struct { 2077 // Name of the channel this frame belongs to. 2078 channel: String, 2079 2080 // Time of this frame in seconds. 2081 time: f64, 2082 2083 // Name of the file containing the data. 2084 // The specified file may contain multiple frames, use `data_offset` etc. to 2085 // read at the right position. 2086 filename: String, 2087 2088 // Format of the wrapper file. 2089 file_format: Cache_File_Format, 2090 2091 // Axis to mirror the read data by. 2092 mirror_axis: Mirror_Axis, 2093 2094 // Factor to scale the geometry by. 2095 scale_factor: Real, 2096 data_format: Cache_Data_Format, // < Format of the data in the file 2097 data_encoding: Cache_Data_Encoding, // < Binary encoding of the data 2098 data_offset: u64, // < Byte offset into the file 2099 data_count: u32, // < Number of data elements 2100 data_element_bytes: u32, // < Size of a single data element in bytes 2101 data_total_bytes: u64, // < Size of the whole data blob in bytes 2102 } 2103 2104 Cache_Frame_List :: struct { 2105 data: ^Cache_Frame, 2106 count: c.size_t, 2107 } 2108 2109 Cache_Channel :: struct { 2110 // Name of the geometry cache channel. 2111 name: String, 2112 2113 // What does the data in this channel represent. 2114 interpretation: Cache_Interpretation, 2115 2116 // Source name for `interpretation`, especially useful if `interpretation` is 2117 // `UFBX_CACHE_INTERPRETATION_UNKNOWN`. 2118 interpretation_name: String, 2119 2120 // List of frames belonging to this channel. 2121 // Sorted by time (`ufbx_cache_frame.time`). 2122 frames: Cache_Frame_List, 2123 2124 // Axis to mirror the frames by. 2125 mirror_axis: Mirror_Axis, 2126 2127 // Factor to scale the geometry by. 2128 scale_factor: Real, 2129 } 2130 2131 Cache_Channel_List :: struct { 2132 data: ^Cache_Channel, 2133 count: c.size_t, 2134 } 2135 2136 Geometry_Cache :: struct { 2137 root_filename: String, 2138 channels: Cache_Channel_List, 2139 frames: Cache_Frame_List, 2140 extra_info: String_List, 2141 } 2142 2143 Cache_Deformer :: struct { 2144 using _: struct #raw_union { 2145 element: Element, 2146 2147 using _: struct { 2148 name: String, 2149 props: Props, 2150 element_id: u32, 2151 typed_id: u32, 2152 }, 2153 }, 2154 2155 channel: String, 2156 file: ^Cache_File, 2157 2158 // Only valid if `ufbx_load_opts.load_external_files` is set! 2159 external_cache: ^Geometry_Cache, 2160 external_channel: ^Cache_Channel, 2161 } 2162 2163 Cache_File :: struct { 2164 using _: struct #raw_union { 2165 element: Element, 2166 2167 using _: struct { 2168 name: String, 2169 props: Props, 2170 element_id: u32, 2171 typed_id: u32, 2172 }, 2173 }, 2174 2175 // Filename relative to the currently loaded file. 2176 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2177 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2178 filename: String, 2179 2180 // Absolute filename specified in the file. 2181 absolute_filename: String, 2182 2183 // Relative filename specified in the file. 2184 // NOTE: May be absolute if the file is saved in a different drive. 2185 relative_filename: String, 2186 2187 // Filename relative to the loaded file, non-UTF-8 encoded. 2188 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2189 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2190 raw_filename: Blob, 2191 2192 // Absolute filename specified in the file, non-UTF-8 encoded. 2193 raw_absolute_filename: Blob, 2194 2195 // Relative filename specified in the file, non-UTF-8 encoded. 2196 // NOTE: May be absolute if the file is saved in a different drive. 2197 raw_relative_filename: Blob, 2198 format: Cache_File_Format, 2199 2200 // Only valid if `ufbx_load_opts.load_external_files` is set! 2201 external_cache: ^Geometry_Cache, 2202 } 2203 2204 // Material property, either specified with a constant value or a mapped texture 2205 Material_Map :: struct { 2206 // Constant value or factor for the map. 2207 // May be specified simultaneously with a texture, in this case most shading models 2208 // use multiplicative tinting of the texture values. 2209 using _: struct #raw_union { 2210 value_real: Real, 2211 value_vec2: Vec2, 2212 value_vec3: Vec3, 2213 value_vec4: Vec4, 2214 }, 2215 2216 // Constant value or factor for the map. 2217 // May be specified simultaneously with a texture, in this case most shading models 2218 // use multiplicative tinting of the texture values. 2219 value_int: i64, 2220 2221 // Texture if connected, otherwise `NULL`. 2222 // May be valid but "disabled" (application specific) if `texture_enabled == false`. 2223 texture: ^Texture, 2224 2225 // `true` if the file has specified any of the values above. 2226 // NOTE: The value may be set to a non-zero default even if `has_value == false`, 2227 // for example missing factors are set to `1.0` if a color is defined. 2228 has_value: bool, 2229 2230 // Controls whether shading should use `texture`. 2231 // NOTE: Some shading models allow this to be `true` even if `texture == NULL`. 2232 texture_enabled: bool, 2233 2234 // Set to `true` if this feature should be disabled (specific to shader type). 2235 feature_disabled: bool, 2236 2237 // Number of components in the value from 1 to 4 if defined, 0 if not. 2238 value_components: u8, 2239 } 2240 2241 // Material feature 2242 Material_Feature_Info :: struct { 2243 // Whether the material model uses this feature or not. 2244 // NOTE: The feature can be enabled but still not used if eg. the corresponding factor is at zero! 2245 enabled: bool, 2246 2247 // Explicitly enabled/disabled by the material. 2248 is_explicit: bool, 2249 } 2250 2251 // Texture attached to an FBX property 2252 Material_Texture :: struct { 2253 material_prop: String, // < Name of the property in `ufbx_material.props` 2254 shader_prop: String, // < Shader-specific property mapping name 2255 2256 // Texture attached to the property. 2257 texture: ^Texture, 2258 } 2259 2260 Material_Texture_List :: struct { 2261 data: ^Material_Texture, 2262 count: c.size_t, 2263 } 2264 2265 // Shading model type 2266 Shader_Type :: enum i32 { 2267 // Unknown shading model 2268 UNKNOWN = 0, 2269 2270 // FBX builtin diffuse material 2271 FBX_LAMBERT = 1, 2272 2273 // FBX builtin diffuse+specular material 2274 FBX_PHONG = 2, 2275 OSL_STANDARD_SURFACE = 3, 2276 ARNOLD_STANDARD_SURFACE = 4, 2277 _3DS_MAX_PHYSICAL_MATERIAL = 5, 2278 _3DS_MAX_PBR_METAL_ROUGH = 6, 2279 _3DS_MAX_PBR_SPEC_GLOSS = 7, 2280 GLTF_MATERIAL = 8, 2281 OPENPBR_MATERIAL = 9, 2282 2283 // Stingray ShaderFX shader graph. 2284 // Contains a serialized `"ShaderGraph"` in `ufbx_props`. 2285 SHADERFX_GRAPH = 10, 2286 2287 // Variation of the FBX phong shader that can recover PBR properties like 2288 // `metalness` or `roughness` from the FBX non-physical values. 2289 // NOTE: Enable `ufbx_load_opts.use_blender_pbr_material`. 2290 BLENDER_PHONG = 11, 2291 2292 // Wavefront .mtl format shader (used by .obj files) 2293 WAVEFRONT_MTL = 12, 2294 } 2295 2296 SHADER_TYPE_COUNT :: 13 2297 2298 // FBX builtin material properties, matches maps in `ufbx_material_fbx_maps` 2299 Material_Fbx_Map :: enum i32 { 2300 DIFFUSE_FACTOR = 0, 2301 DIFFUSE_COLOR = 1, 2302 SPECULAR_FACTOR = 2, 2303 SPECULAR_COLOR = 3, 2304 SPECULAR_EXPONENT = 4, 2305 REFLECTION_FACTOR = 5, 2306 REFLECTION_COLOR = 6, 2307 TRANSPARENCY_FACTOR = 7, 2308 TRANSPARENCY_COLOR = 8, 2309 EMISSION_FACTOR = 9, 2310 EMISSION_COLOR = 10, 2311 AMBIENT_FACTOR = 11, 2312 AMBIENT_COLOR = 12, 2313 NORMAL_MAP = 13, 2314 BUMP = 14, 2315 BUMP_FACTOR = 15, 2316 DISPLACEMENT_FACTOR = 16, 2317 DISPLACEMENT = 17, 2318 VECTOR_DISPLACEMENT_FACTOR = 18, 2319 VECTOR_DISPLACEMENT = 19, 2320 } 2321 2322 MATERIAL_FBX_MAP_COUNT :: 20 2323 2324 // Known PBR material properties, matches maps in `ufbx_material_pbr_maps` 2325 Material_Pbr_Map :: enum i32 { 2326 BASE_FACTOR = 0, 2327 BASE_COLOR = 1, 2328 ROUGHNESS = 2, 2329 METALNESS = 3, 2330 DIFFUSE_ROUGHNESS = 4, 2331 SPECULAR_FACTOR = 5, 2332 SPECULAR_COLOR = 6, 2333 SPECULAR_IOR = 7, 2334 SPECULAR_ANISOTROPY = 8, 2335 SPECULAR_ROTATION = 9, 2336 TRANSMISSION_FACTOR = 10, 2337 TRANSMISSION_COLOR = 11, 2338 TRANSMISSION_DEPTH = 12, 2339 TRANSMISSION_SCATTER = 13, 2340 TRANSMISSION_SCATTER_ANISOTROPY = 14, 2341 TRANSMISSION_DISPERSION = 15, 2342 TRANSMISSION_ROUGHNESS = 16, 2343 TRANSMISSION_EXTRA_ROUGHNESS = 17, 2344 TRANSMISSION_PRIORITY = 18, 2345 TRANSMISSION_ENABLE_IN_AOV = 19, 2346 SUBSURFACE_FACTOR = 20, 2347 SUBSURFACE_COLOR = 21, 2348 SUBSURFACE_RADIUS = 22, 2349 SUBSURFACE_SCALE = 23, 2350 SUBSURFACE_ANISOTROPY = 24, 2351 SUBSURFACE_TINT_COLOR = 25, 2352 SUBSURFACE_TYPE = 26, 2353 SHEEN_FACTOR = 27, 2354 SHEEN_COLOR = 28, 2355 SHEEN_ROUGHNESS = 29, 2356 COAT_FACTOR = 30, 2357 COAT_COLOR = 31, 2358 COAT_ROUGHNESS = 32, 2359 COAT_IOR = 33, 2360 COAT_ANISOTROPY = 34, 2361 COAT_ROTATION = 35, 2362 COAT_NORMAL = 36, 2363 COAT_AFFECT_BASE_COLOR = 37, 2364 COAT_AFFECT_BASE_ROUGHNESS = 38, 2365 THIN_FILM_FACTOR = 39, 2366 THIN_FILM_THICKNESS = 40, 2367 THIN_FILM_IOR = 41, 2368 EMISSION_FACTOR = 42, 2369 EMISSION_COLOR = 43, 2370 OPACITY = 44, 2371 INDIRECT_DIFFUSE = 45, 2372 INDIRECT_SPECULAR = 46, 2373 NORMAL_MAP = 47, 2374 TANGENT_MAP = 48, 2375 DISPLACEMENT_MAP = 49, 2376 MATTE_FACTOR = 50, 2377 MATTE_COLOR = 51, 2378 AMBIENT_OCCLUSION = 52, 2379 GLOSSINESS = 53, 2380 COAT_GLOSSINESS = 54, 2381 TRANSMISSION_GLOSSINESS = 55, 2382 } 2383 2384 MATERIAL_PBR_MAP_COUNT :: 56 2385 2386 // Known material features 2387 Material_Feature :: enum i32 { 2388 PBR = 0, 2389 METALNESS = 1, 2390 DIFFUSE = 2, 2391 SPECULAR = 3, 2392 EMISSION = 4, 2393 TRANSMISSION = 5, 2394 COAT = 6, 2395 SHEEN = 7, 2396 OPACITY = 8, 2397 AMBIENT_OCCLUSION = 9, 2398 MATTE = 10, 2399 UNLIT = 11, 2400 IOR = 12, 2401 DIFFUSE_ROUGHNESS = 13, 2402 TRANSMISSION_ROUGHNESS = 14, 2403 THIN_WALLED = 15, 2404 CAUSTICS = 16, 2405 EXIT_TO_BACKGROUND = 17, 2406 INTERNAL_REFLECTIONS = 18, 2407 DOUBLE_SIDED = 19, 2408 ROUGHNESS_AS_GLOSSINESS = 20, 2409 COAT_ROUGHNESS_AS_GLOSSINESS = 21, 2410 TRANSMISSION_ROUGHNESS_AS_GLOSSINESS = 22, 2411 } 2412 2413 MATERIAL_FEATURE_COUNT :: 23 2414 2415 Material_Fbx_Maps :: struct { 2416 using _: struct #raw_union { 2417 maps: [20]Material_Map, 2418 2419 using _: struct { 2420 diffuse_factor: Material_Map, 2421 diffuse_color: Material_Map, 2422 specular_factor: Material_Map, 2423 specular_color: Material_Map, 2424 specular_exponent: Material_Map, 2425 reflection_factor: Material_Map, 2426 reflection_color: Material_Map, 2427 transparency_factor: Material_Map, 2428 transparency_color: Material_Map, 2429 emission_factor: Material_Map, 2430 emission_color: Material_Map, 2431 ambient_factor: Material_Map, 2432 ambient_color: Material_Map, 2433 normal_map: Material_Map, 2434 bump: Material_Map, 2435 bump_factor: Material_Map, 2436 displacement_factor: Material_Map, 2437 displacement: Material_Map, 2438 vector_displacement_factor: Material_Map, 2439 vector_displacement: Material_Map, 2440 }, 2441 }, 2442 } 2443 2444 Material_Pbr_Maps :: struct { 2445 using _: struct #raw_union { 2446 maps: [56]Material_Map, 2447 2448 using _: struct { 2449 base_factor: Material_Map, 2450 base_color: Material_Map, 2451 roughness: Material_Map, 2452 metalness: Material_Map, 2453 diffuse_roughness: Material_Map, 2454 specular_factor: Material_Map, 2455 specular_color: Material_Map, 2456 specular_ior: Material_Map, 2457 specular_anisotropy: Material_Map, 2458 specular_rotation: Material_Map, 2459 transmission_factor: Material_Map, 2460 transmission_color: Material_Map, 2461 transmission_depth: Material_Map, 2462 transmission_scatter: Material_Map, 2463 transmission_scatter_anisotropy: Material_Map, 2464 transmission_dispersion: Material_Map, 2465 transmission_roughness: Material_Map, 2466 transmission_extra_roughness: Material_Map, 2467 transmission_priority: Material_Map, 2468 transmission_enable_in_aov: Material_Map, 2469 subsurface_factor: Material_Map, 2470 subsurface_color: Material_Map, 2471 subsurface_radius: Material_Map, 2472 subsurface_scale: Material_Map, 2473 subsurface_anisotropy: Material_Map, 2474 subsurface_tint_color: Material_Map, 2475 subsurface_type: Material_Map, 2476 sheen_factor: Material_Map, 2477 sheen_color: Material_Map, 2478 sheen_roughness: Material_Map, 2479 coat_factor: Material_Map, 2480 coat_color: Material_Map, 2481 coat_roughness: Material_Map, 2482 coat_ior: Material_Map, 2483 coat_anisotropy: Material_Map, 2484 coat_rotation: Material_Map, 2485 coat_normal: Material_Map, 2486 coat_affect_base_color: Material_Map, 2487 coat_affect_base_roughness: Material_Map, 2488 thin_film_factor: Material_Map, 2489 thin_film_thickness: Material_Map, 2490 thin_film_ior: Material_Map, 2491 emission_factor: Material_Map, 2492 emission_color: Material_Map, 2493 opacity: Material_Map, 2494 indirect_diffuse: Material_Map, 2495 indirect_specular: Material_Map, 2496 normal_map: Material_Map, 2497 tangent_map: Material_Map, 2498 displacement_map: Material_Map, 2499 matte_factor: Material_Map, 2500 matte_color: Material_Map, 2501 ambient_occlusion: Material_Map, 2502 glossiness: Material_Map, 2503 coat_glossiness: Material_Map, 2504 transmission_glossiness: Material_Map, 2505 }, 2506 }, 2507 } 2508 2509 Material_Features :: struct { 2510 using _: struct #raw_union { 2511 features: [23]Material_Feature_Info, 2512 2513 using _: struct { 2514 pbr: Material_Feature_Info, 2515 metalness: Material_Feature_Info, 2516 diffuse: Material_Feature_Info, 2517 specular: Material_Feature_Info, 2518 emission: Material_Feature_Info, 2519 transmission: Material_Feature_Info, 2520 coat: Material_Feature_Info, 2521 sheen: Material_Feature_Info, 2522 opacity: Material_Feature_Info, 2523 ambient_occlusion: Material_Feature_Info, 2524 matte: Material_Feature_Info, 2525 unlit: Material_Feature_Info, 2526 ior: Material_Feature_Info, 2527 diffuse_roughness: Material_Feature_Info, 2528 transmission_roughness: Material_Feature_Info, 2529 thin_walled: Material_Feature_Info, 2530 caustics: Material_Feature_Info, 2531 exit_to_background: Material_Feature_Info, 2532 internal_reflections: Material_Feature_Info, 2533 double_sided: Material_Feature_Info, 2534 roughness_as_glossiness: Material_Feature_Info, 2535 coat_roughness_as_glossiness: Material_Feature_Info, 2536 transmission_roughness_as_glossiness: Material_Feature_Info, 2537 }, 2538 }, 2539 } 2540 2541 // Surface material properties such as color, roughness, etc. Each property may 2542 // be optionally bound to an `ufbx_texture`. 2543 Material :: struct { 2544 using _: struct #raw_union { 2545 element: Element, 2546 2547 using _: struct { 2548 name: String, 2549 props: Props, 2550 element_id: u32, 2551 typed_id: u32, 2552 }, 2553 }, 2554 2555 // FBX builtin properties 2556 // NOTE: These may be empty if the material is using a custom shader 2557 fbx: Material_Fbx_Maps, 2558 2559 // PBR material properties, defined for all shading models but may be 2560 // somewhat approximate if `shader == NULL`. 2561 pbr: Material_Pbr_Maps, 2562 2563 // Material features, primarily applies to `pbr`. 2564 features: Material_Features, 2565 2566 // Shading information 2567 shader_type: Shader_Type, // < Always defined 2568 shader: ^Shader, // < Optional extended shader information 2569 shading_model_name: String, // < Often one of `{ "lambert", "phong", "unknown" }` 2570 2571 // Prefix before shader property names with trailing `|`. 2572 // For example `"3dsMax|Parameters|"` where properties would have names like 2573 // `"3dsMax|Parameters|base_color"`. You can ignore this if you use the built-in 2574 // `ufbx_material_fbx_maps fbx` and `ufbx_material_pbr_maps pbr` structures. 2575 shader_prop_prefix: String, 2576 2577 // All textures attached to the material, if you want specific maps if might be 2578 // more convenient to use eg. `fbx.diffuse_color.texture` or `pbr.base_color.texture` 2579 textures: Material_Texture_List, // < Sorted by `material_prop` 2580 } 2581 2582 Texture_Type :: enum i32 { 2583 // Texture associated with an image file/sequence. `texture->filename` and 2584 // and `texture->relative_filename` contain the texture's path. If the file 2585 // has embedded content `texture->content` may hold `texture->content_size` 2586 // bytes of raw image data. 2587 FILE = 0, 2588 2589 // The texture consists of multiple texture layers blended together. 2590 LAYERED = 1, 2591 2592 // Reserved as these _should_ exist in FBX files. 2593 PROCEDURAL = 2, 2594 2595 // Node in a shader graph. 2596 // Use `ufbx_texture.shader` for more information. 2597 SHADER = 3, 2598 } 2599 2600 TEXTURE_TYPE_COUNT :: 4 2601 2602 // Blend modes to combine layered textures with, compatible with common blend 2603 // mode definitions in many art programs. Simpler blend modes have equations 2604 // specified below where `src` is the layer to composite over `dst`. 2605 // See eg. https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendingseparable 2606 Blend_Mode :: enum i32 { 2607 TRANSLUCENT = 0, // < `src` effects result alpha 2608 ADDITIVE = 1, // < `src + dst` 2609 MULTIPLY = 2, // < `src * dst` 2610 MULTIPLY_2X = 3, // < `2 * src * dst` 2611 OVER = 4, // < `src * src_alpha + dst * (1-src_alpha)` 2612 REPLACE = 5, // < `src` Replace the contents 2613 DISSOLVE = 6, // < `random() + src_alpha >= 1.0 ? src : dst` 2614 DARKEN = 7, // < `min(src, dst)` 2615 COLOR_BURN = 8, // < `src > 0 ? 1 - min(1, (1-dst) / src) : 0` 2616 LINEAR_BURN = 9, // < `src + dst - 1` 2617 DARKER_COLOR = 10, // < `value(src) < value(dst) ? src : dst` 2618 LIGHTEN = 11, // < `max(src, dst)` 2619 SCREEN = 12, // < `1 - (1-src)*(1-dst)` 2620 COLOR_DODGE = 13, // < `src < 1 ? dst / (1 - src)` : (dst>0?1:0)` 2621 LINEAR_DODGE = 14, // < `src + dst` 2622 LIGHTER_COLOR = 15, // < `value(src) > value(dst) ? src : dst` 2623 SOFT_LIGHT = 16, // < https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendingsoftlight 2624 HARD_LIGHT = 17, // < https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendinghardlight 2625 VIVID_LIGHT = 18, // < Combination of `COLOR_DODGE` and `COLOR_BURN` 2626 LINEAR_LIGHT = 19, // < Combination of `LINEAR_DODGE` and `LINEAR_BURN` 2627 PIN_LIGHT = 20, // < Combination of `DARKEN` and `LIGHTEN` 2628 HARD_MIX = 21, // < Produces primary colors depending on similarity 2629 DIFFERENCE = 22, // < `abs(src - dst)` 2630 EXCLUSION = 23, // < `dst + src - 2 * src * dst` 2631 SUBTRACT = 24, // < `dst - src` 2632 DIVIDE = 25, // < `dst / src` 2633 HUE = 26, // < Replace hue 2634 SATURATION = 27, // < Replace saturation 2635 COLOR = 28, // < Replace hue and saturatio 2636 LUMINOSITY = 29, // < Replace value 2637 OVERLAY = 30, // < Same as `HARD_LIGHT` but with `src` and `dst` swapped 2638 } 2639 2640 BLEND_MODE_COUNT :: 31 2641 2642 // Blend modes to combine layered textures with, compatible with common blend 2643 Wrap_Mode :: enum i32 { 2644 REPEAT = 0, // < Repeat the texture past the [0,1] range 2645 CLAMP = 1, // < Clamp the normalized texture coordinates to [0,1] 2646 } 2647 2648 WRAP_MODE_COUNT :: 2 2649 2650 // Single layer in a layered texture 2651 Texture_Layer :: struct { 2652 texture: ^Texture, // < The inner texture to evaluate, never `NULL` 2653 blend_mode: Blend_Mode, // < Equation to combine the layer to the background 2654 alpha: Real, // < Blend weight of this layer 2655 } 2656 2657 Texture_Layer_List :: struct { 2658 data: ^Texture_Layer, 2659 count: c.size_t, 2660 } 2661 2662 Shader_Texture_Type :: enum i32 { 2663 UNKNOWN = 0, 2664 2665 // Select an output of a multi-output shader. 2666 // HINT: If this type is used the `ufbx_shader_texture.main_texture` and 2667 // `ufbx_shader_texture.main_texture_output_index` fields are set. 2668 SELECT_OUTPUT = 1, 2669 OSL = 2, 2670 } 2671 2672 SHADER_TEXTURE_TYPE_COUNT :: 3 2673 2674 // Input to a shader texture, see `ufbx_shader_texture`. 2675 Shader_Texture_Input :: struct { 2676 // Name of the input. 2677 name: String, 2678 2679 // Constant value of the input. 2680 using _: struct #raw_union { 2681 value_real: Real, 2682 value_vec2: Vec2, 2683 value_vec3: Vec3, 2684 value_vec4: Vec4, 2685 }, 2686 2687 // Constant value of the input. 2688 value_int: i64, 2689 value_str: String, 2690 value_blob: Blob, 2691 2692 // Texture connected to this input. 2693 texture: ^Texture, 2694 2695 // Index of the output to use if `texture` is a multi-output shader node. 2696 texture_output_index: i64, 2697 2698 // Controls whether shading should use `texture`. 2699 // NOTE: Some shading models allow this to be `true` even if `texture == NULL`. 2700 texture_enabled: bool, 2701 2702 // Property representing this input. 2703 prop: ^Prop, 2704 2705 // Property representing `texture`. 2706 texture_prop: ^Prop, 2707 2708 // Property representing `texture_enabled`. 2709 texture_enabled_prop: ^Prop, 2710 } 2711 2712 Shader_Texture_Input_List :: struct { 2713 data: ^Shader_Texture_Input, 2714 count: c.size_t, 2715 } 2716 2717 // Texture that emulates a shader graph node. 2718 // 3ds Max exports some materials as node graphs serialized to textures. 2719 // ufbx can parse a small subset of these, as normal maps are often hidden behind 2720 // some kind of bump node. 2721 // NOTE: These encode a lot of details of 3ds Max internals, not recommended for direct use. 2722 // HINT: `ufbx_texture.file_textures[]` contains a list of "real" textures that are connected 2723 // to the `ufbx_texture` that is pretending to be a shader node. 2724 Shader_Texture :: struct { 2725 // Type of this shader node. 2726 type: Shader_Texture_Type, 2727 2728 // Name of the shader to use. 2729 shader_name: String, 2730 2731 // 64-bit opaque identifier for the shader type. 2732 shader_type_id: u64, 2733 2734 // Input values/textures (possibly further shader textures) to the shader. 2735 // Sorted by `ufbx_shader_texture_input.name`. 2736 inputs: Shader_Texture_Input_List, 2737 2738 // Shader source code if found. 2739 shader_source: String, 2740 raw_shader_source: Blob, 2741 2742 // Representative texture for this shader. 2743 // Only specified if `main_texture.outputs[main_texture_output_index]` is semantically 2744 // equivalent to this texture. 2745 main_texture: ^Texture, 2746 2747 // Output index of `main_texture` if it is a multi-output shader. 2748 main_texture_output_index: i64, 2749 2750 // Prefix for properties related to this shader in `ufbx_texture`. 2751 // NOTE: Contains the trailing '|' if not empty. 2752 prop_prefix: String, 2753 } 2754 2755 // Unique texture within the file. 2756 Texture_File :: struct { 2757 // Index in `ufbx_scene.texture_files[]`. 2758 index: u32, 2759 2760 // Paths to the resource. 2761 2762 // Filename relative to the currently loaded file. 2763 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2764 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2765 filename: String, 2766 2767 // Absolute filename specified in the file. 2768 absolute_filename: String, 2769 2770 // Relative filename specified in the file. 2771 // NOTE: May be absolute if the file is saved in a different drive. 2772 relative_filename: String, 2773 2774 // Filename relative to the loaded file, non-UTF-8 encoded. 2775 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2776 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2777 raw_filename: Blob, 2778 2779 // Absolute filename specified in the file, non-UTF-8 encoded. 2780 raw_absolute_filename: Blob, 2781 2782 // Relative filename specified in the file, non-UTF-8 encoded. 2783 // NOTE: May be absolute if the file is saved in a different drive. 2784 raw_relative_filename: Blob, 2785 2786 // Optional embedded content blob, eg. raw .png format data 2787 content: Blob, 2788 } 2789 2790 Texture_File_List :: struct { 2791 data: ^Texture_File, 2792 count: c.size_t, 2793 } 2794 2795 // Texture that controls material appearance 2796 Texture :: struct { 2797 using _: struct #raw_union { 2798 element: Element, 2799 2800 using _: struct { 2801 name: String, 2802 props: Props, 2803 element_id: u32, 2804 typed_id: u32, 2805 }, 2806 }, 2807 2808 // Texture type (file / layered / procedural / shader) 2809 type: Texture_Type, 2810 2811 // FILE: Paths to the resource 2812 2813 // Filename relative to the currently loaded file. 2814 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2815 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2816 filename: String, 2817 2818 // Absolute filename specified in the file. 2819 absolute_filename: String, 2820 2821 // Relative filename specified in the file. 2822 // NOTE: May be absolute if the file is saved in a different drive. 2823 relative_filename: String, 2824 2825 // Filename relative to the loaded file, non-UTF-8 encoded. 2826 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2827 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2828 raw_filename: Blob, 2829 2830 // Absolute filename specified in the file, non-UTF-8 encoded. 2831 raw_absolute_filename: Blob, 2832 2833 // Relative filename specified in the file, non-UTF-8 encoded. 2834 // NOTE: May be absolute if the file is saved in a different drive. 2835 raw_relative_filename: Blob, 2836 2837 // FILE: Optional embedded content blob, eg. raw .png format data 2838 content: Blob, 2839 2840 // FILE: Optional video texture 2841 video: ^Video, 2842 2843 // FILE: Index into `ufbx_scene.texture_files[]` or `UFBX_NO_INDEX`. 2844 file_index: u32, 2845 2846 // FILE: True if `file_index` has a valid value. 2847 has_file: bool, 2848 2849 // LAYERED: Inner texture layers, ordered from _bottom_ to _top_ 2850 layers: Texture_Layer_List, 2851 2852 // SHADER: Shader information 2853 // NOTE: May be specified even if `type == UFBX_TEXTURE_FILE` if `ufbx_load_opts.disable_quirks` 2854 // is _not_ specified. Some known shaders that represent files are interpreted as `UFBX_TEXTURE_FILE`. 2855 shader: ^Shader_Texture, 2856 2857 // List of file textures representing this texture. 2858 // Defined even if `type == UFBX_TEXTURE_FILE` in which case the array contains only itself. 2859 file_textures: Texture_List, 2860 2861 // Name of the UV set to use 2862 uv_set: String, 2863 2864 // Wrapping mode 2865 wrap_u: Wrap_Mode, 2866 wrap_v: Wrap_Mode, 2867 2868 // UV transform 2869 has_uv_transform: bool, // < Has a non-identity `transform` and derived matrices. 2870 uv_transform: Transform, // < Texture transformation in UV space 2871 texture_to_uv: Matrix, // < Matrix representation of `transform` 2872 uv_to_texture: Matrix, // < UV coordinate to normalized texture coordinate matrix 2873 } 2874 2875 // TODO: Video textures 2876 Video :: struct { 2877 using _: struct #raw_union { 2878 element: Element, 2879 2880 using _: struct { 2881 name: String, 2882 props: Props, 2883 element_id: u32, 2884 typed_id: u32, 2885 }, 2886 }, 2887 2888 // Paths to the resource 2889 2890 // Filename relative to the currently loaded file. 2891 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2892 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2893 filename: String, 2894 2895 // Absolute filename specified in the file. 2896 absolute_filename: String, 2897 2898 // Relative filename specified in the file. 2899 // NOTE: May be absolute if the file is saved in a different drive. 2900 relative_filename: String, 2901 2902 // Filename relative to the loaded file, non-UTF-8 encoded. 2903 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2904 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2905 raw_filename: Blob, 2906 2907 // Absolute filename specified in the file, non-UTF-8 encoded. 2908 raw_absolute_filename: Blob, 2909 2910 // Relative filename specified in the file, non-UTF-8 encoded. 2911 // NOTE: May be absolute if the file is saved in a different drive. 2912 raw_relative_filename: Blob, 2913 2914 // Optional embedded content blob 2915 content: Blob, 2916 } 2917 2918 // Shader specifies a shading model and contains `ufbx_shader_binding` elements 2919 // that define how to interpret FBX properties in the shader. 2920 Shader :: struct { 2921 using _: struct #raw_union { 2922 element: Element, 2923 2924 using _: struct { 2925 name: String, 2926 props: Props, 2927 element_id: u32, 2928 typed_id: u32, 2929 }, 2930 }, 2931 2932 // Known shading model 2933 type: Shader_Type, 2934 2935 // TODO: Expose actual properties here 2936 2937 // Bindings from FBX properties to the shader 2938 // HINT: `ufbx_find_shader_prop()` translates shader properties to FBX properties 2939 bindings: Shader_Binding_List, 2940 } 2941 2942 // Binding from a material property to shader implementation 2943 Shader_Prop_Binding :: struct { 2944 shader_prop: String, // < Property name used by the shader implementation 2945 material_prop: String, // < Property name inside `ufbx_material.props` 2946 } 2947 2948 Shader_Prop_Binding_List :: struct { 2949 data: ^Shader_Prop_Binding, 2950 count: c.size_t, 2951 } 2952 2953 // Shader binding table 2954 Shader_Binding :: struct { 2955 using _: struct #raw_union { 2956 element: Element, 2957 2958 using _: struct { 2959 name: String, 2960 props: Props, 2961 element_id: u32, 2962 typed_id: u32, 2963 }, 2964 }, 2965 2966 prop_bindings: Shader_Prop_Binding_List, // < Sorted by `shader_prop` 2967 } 2968 2969 // -- Animation 2970 Prop_Override :: struct { 2971 element_id: u32, 2972 _internal_key: u32, 2973 prop_name: String, 2974 value: Vec4, 2975 value_str: String, 2976 value_int: i64, 2977 } 2978 2979 Prop_Override_List :: struct { 2980 data: ^Prop_Override, 2981 count: c.size_t, 2982 } 2983 2984 Transform_Override :: struct { 2985 node_id: u32, 2986 transform: Transform, 2987 } 2988 2989 Transform_Override_List :: struct { 2990 data: ^Transform_Override, 2991 count: c.size_t, 2992 } 2993 2994 // Animation descriptor used for evaluating animation. 2995 // Usually obtained from `ufbx_scene` via either global animation `ufbx_scene.anim`, 2996 // per-stack animation `ufbx_anim_stack.anim` or per-layer animation `ufbx_anim_layer.anim`. 2997 // 2998 // For advanced usage you can use `ufbx_create_anim()` to create animation descriptors 2999 // with custom layers, property overrides, special flags, etc. 3000 Anim :: struct { 3001 // Time begin/end for the animation, both may be zero if absent. 3002 time_begin: f64, 3003 time_end: f64, 3004 3005 // List of layers in the animation. 3006 layers: Anim_Layer_List, 3007 3008 // Optional overrides for weights for each layer in `layers[]`. 3009 override_layer_weights: Real_List, 3010 3011 // Sorted by `element_id, prop_name` 3012 prop_overrides: Prop_Override_List, 3013 3014 // Sorted by `node_id` 3015 transform_overrides: Transform_Override_List, 3016 3017 // Evaluate connected properties as if they would not be connected. 3018 ignore_connections: bool, 3019 3020 // Custom `ufbx_anim` created by `ufbx_create_anim()`. 3021 custom: bool, 3022 } 3023 3024 Anim_Stack :: struct { 3025 using _: struct #raw_union { 3026 element: Element, 3027 3028 using _: struct { 3029 name: String, 3030 props: Props, 3031 element_id: u32, 3032 typed_id: u32, 3033 }, 3034 }, 3035 3036 time_begin: f64, 3037 time_end: f64, 3038 layers: Anim_Layer_List, 3039 anim: ^Anim, 3040 } 3041 3042 Anim_Prop :: struct { 3043 element: ^Element, 3044 _internal_key: u32, 3045 prop_name: String, 3046 anim_value: ^Anim_Value, 3047 } 3048 3049 Anim_Prop_List :: struct { 3050 data: ^Anim_Prop, 3051 count: c.size_t, 3052 } 3053 3054 Anim_Layer :: struct { 3055 using _: struct #raw_union { 3056 element: Element, 3057 3058 using _: struct { 3059 name: String, 3060 props: Props, 3061 element_id: u32, 3062 typed_id: u32, 3063 }, 3064 }, 3065 3066 weight: Real, 3067 weight_is_animated: bool, 3068 blended: bool, 3069 additive: bool, 3070 compose_rotation: bool, 3071 compose_scale: bool, 3072 anim_values: Anim_Value_List, 3073 anim_props: Anim_Prop_List, // < Sorted by `element,prop_name` 3074 anim: ^Anim, 3075 _min_element_id: u32, 3076 _max_element_id: u32, 3077 _element_id_bitmask: [4]u32, 3078 } 3079 3080 Anim_Value :: struct { 3081 using _: struct #raw_union { 3082 element: Element, 3083 3084 using _: struct { 3085 name: String, 3086 props: Props, 3087 element_id: u32, 3088 typed_id: u32, 3089 }, 3090 }, 3091 3092 default_value: Vec3, 3093 curves: [3]^Anim_Curve, 3094 } 3095 3096 // Animation curve segment interpolation mode between two keyframes 3097 Interpolation :: enum i32 { 3098 CONSTANT_PREV = 0, // < Hold previous key value 3099 CONSTANT_NEXT = 1, // < Hold next key value 3100 LINEAR = 2, // < Linear interpolation between two keys 3101 CUBIC = 3, // < Cubic interpolation, see `ufbx_tangent` 3102 } 3103 3104 INTERPOLATION_COUNT :: 4 3105 3106 Extrapolation_Mode :: enum i32 { 3107 CONSTANT = 0, // < Use the value of the first/last keyframe 3108 REPEAT = 1, // < Repeat the whole animation curve 3109 MIRROR = 2, // < Repeat with mirroring 3110 SLOPE = 3, // < Use the tangent of the last keyframe to linearly extrapolate 3111 REPEAT_RELATIVE = 4, // < Repeat the animation curve but connect the first and last keyframe values 3112 } 3113 3114 EXTRAPOLATION_MODE_COUNT :: 5 3115 3116 Extrapolation :: struct { 3117 mode: Extrapolation_Mode, 3118 3119 // Count used for repeating modes. 3120 // Negative values mean infinite repetition. 3121 repeat_count: i32, 3122 } 3123 3124 // Tangent vector at a keyframe, may be split into left/right 3125 Tangent :: struct { 3126 dx: f32, // < Derivative in the time axis 3127 dy: f32, // < Derivative in the (curve specific) value axis 3128 } 3129 3130 // Single real `value` at a specified `time`, interpolation between two keyframes 3131 // is determined by the `interpolation` field of the _previous_ key. 3132 // If `interpolation == UFBX_INTERPOLATION_CUBIC` the span is evaluated as a 3133 // cubic bezier curve through the following points: 3134 // 3135 // (prev->time, prev->value) 3136 // (prev->time + prev->right.dx, prev->value + prev->right.dy) 3137 // (next->time - next->left.dx, next->value - next->left.dy) 3138 // (next->time, next->value) 3139 // 3140 // HINT: You can use `ufbx_evaluate_curve(ufbx_anim_curve *curve, double time)` 3141 // rather than trying to manually handle all the interpolation modes. 3142 Keyframe :: struct { 3143 time: f64, 3144 value: Real, 3145 interpolation: Interpolation, 3146 left: Tangent, 3147 right: Tangent, 3148 } 3149 3150 Keyframe_List :: struct { 3151 data: ^Keyframe, 3152 count: c.size_t, 3153 } 3154 3155 Anim_Curve :: struct { 3156 using _: struct #raw_union { 3157 element: Element, 3158 3159 using _: struct { 3160 name: String, 3161 props: Props, 3162 element_id: u32, 3163 typed_id: u32, 3164 }, 3165 }, 3166 3167 // List of keyframes that define the curve. 3168 keyframes: Keyframe_List, 3169 3170 // Extrapolation before the curve. 3171 pre_extrapolation: Extrapolation, 3172 3173 // Extrapolation after the curve. 3174 post_extrapolation: Extrapolation, 3175 3176 // Value range for all the keyframes. 3177 min_value: Real, 3178 max_value: Real, 3179 3180 // Time range for all the keyframes. 3181 min_time: f64, 3182 max_time: f64, 3183 } 3184 3185 // Collection of nodes to hide/freeze 3186 Display_Layer :: struct { 3187 using _: struct #raw_union { 3188 element: Element, 3189 3190 using _: struct { 3191 name: String, 3192 props: Props, 3193 element_id: u32, 3194 typed_id: u32, 3195 }, 3196 }, 3197 3198 // Nodes included in the layer (exclusively at most one layer per node) 3199 nodes: Node_List, 3200 3201 // Layer state 3202 visible: bool, // < Contained nodes are visible 3203 frozen: bool, // < Contained nodes cannot be edited 3204 ui_color: Vec3, // < Visual color for UI 3205 } 3206 3207 // Named set of nodes/geometry features to select. 3208 Selection_Set :: struct { 3209 using _: struct #raw_union { 3210 element: Element, 3211 3212 using _: struct { 3213 name: String, 3214 props: Props, 3215 element_id: u32, 3216 typed_id: u32, 3217 }, 3218 }, 3219 3220 // Included nodes and geometry features 3221 nodes: Selection_Node_List, 3222 } 3223 3224 // Selection state of a node, potentially contains vertex/edge/face selection as well. 3225 Selection_Node :: struct { 3226 using _: struct #raw_union { 3227 element: Element, 3228 3229 using _: struct { 3230 name: String, 3231 props: Props, 3232 element_id: u32, 3233 typed_id: u32, 3234 }, 3235 }, 3236 3237 // Selection targets, possibly `NULL` 3238 target_node: ^Node, 3239 target_mesh: ^Mesh, 3240 include_node: bool, // < Is `target_node` included in the selection 3241 3242 // Indices to selected components. 3243 // Guaranteed to be valid as per `ufbx_load_opts.index_error_handling` 3244 // if `target_mesh` is not `NULL`. 3245 vertices: Uint32_List, // < Indices to `ufbx_mesh.vertices` 3246 edges: Uint32_List, // < Indices to `ufbx_mesh.edges` 3247 faces: Uint32_List, // < Indices to `ufbx_mesh.faces` 3248 } 3249 3250 // -- Constraints 3251 Character :: struct { 3252 using _: struct #raw_union { 3253 element: Element, 3254 3255 using _: struct { 3256 name: String, 3257 props: Props, 3258 element_id: u32, 3259 typed_id: u32, 3260 }, 3261 }, 3262 } 3263 3264 // Type of property constrain eg. position or look-at 3265 Constraint_Type :: enum i32 { 3266 UNKNOWN = 0, 3267 AIM = 1, 3268 PARENT = 2, 3269 POSITION = 3, 3270 ROTATION = 4, 3271 SCALE = 5, 3272 3273 // Inverse kinematic chain to a single effector `ufbx_constraint.ik_effector` 3274 // `targets` optionally contains a list of pole targets! 3275 SINGLE_CHAIN_IK = 6, 3276 } 3277 3278 CONSTRAINT_TYPE_COUNT :: 7 3279 3280 // Target to follow with a constraint 3281 Constraint_Target :: struct { 3282 node: ^Node, // < Target node reference 3283 weight: Real, // < Relative weight to other targets (does not always sum to 1) 3284 transform: Transform, // < Offset from the actual target 3285 } 3286 3287 Constraint_Target_List :: struct { 3288 data: ^Constraint_Target, 3289 count: c.size_t, 3290 } 3291 3292 // Method to determine the up vector in aim constraints 3293 Constraint_Aim_Up_Type :: enum i32 { 3294 SCENE = 0, // < Align the up vector to the scene global up vector 3295 TO_NODE = 1, // < Aim the up vector at `ufbx_constraint.aim_up_node` 3296 ALIGN_NODE = 2, // < Copy the up vector from `ufbx_constraint.aim_up_node` 3297 VECTOR = 3, // < Use `ufbx_constraint.aim_up_vector` as the up vector 3298 NONE = 4, // < Don't align the up vector to anything 3299 } 3300 3301 CONSTRAINT_AIM_UP_TYPE_COUNT :: 5 3302 3303 // Method to determine the up vector in aim constraints 3304 Constraint_Ik_Pole_Type :: enum i32 { 3305 VECTOR = 0, // < Use towards calculated from `ufbx_constraint.targets` 3306 NODE = 1, // < Use `ufbx_constraint.ik_pole_vector` directly 3307 } 3308 3309 CONSTRAINT_IK_POLE_TYPE_COUNT :: 2 3310 3311 Constraint :: struct { 3312 using _: struct #raw_union { 3313 element: Element, 3314 3315 using _: struct { 3316 name: String, 3317 props: Props, 3318 element_id: u32, 3319 typed_id: u32, 3320 }, 3321 }, 3322 3323 // Type of constraint to use 3324 type: Constraint_Type, 3325 type_name: String, 3326 3327 // Node to be constrained 3328 node: ^Node, 3329 3330 // List of weighted targets for the constraint (pole vectors for IK) 3331 targets: Constraint_Target_List, 3332 3333 // State of the constraint 3334 weight: Real, 3335 active: bool, 3336 3337 // Translation/rotation/scale axes the constraint is applied to 3338 constrain_translation: [3]bool, 3339 constrain_rotation: [3]bool, 3340 constrain_scale: [3]bool, 3341 3342 // Offset from the constrained position 3343 transform_offset: Transform, 3344 3345 // AIM: Target and up vectors 3346 aim_vector: Vec3, 3347 aim_up_type: Constraint_Aim_Up_Type, 3348 aim_up_node: ^Node, 3349 aim_up_vector: Vec3, 3350 3351 // SINGLE_CHAIN_IK: Target for the IK, `targets` contains pole vectors! 3352 ik_effector: ^Node, 3353 ik_end_node: ^Node, 3354 ik_pole_vector: Vec3, 3355 } 3356 3357 // -- Audio 3358 Audio_Layer :: struct { 3359 using _: struct #raw_union { 3360 element: Element, 3361 3362 using _: struct { 3363 name: String, 3364 props: Props, 3365 element_id: u32, 3366 typed_id: u32, 3367 }, 3368 }, 3369 3370 // Clips contained in this layer. 3371 clips: Audio_Clip_List, 3372 } 3373 3374 Audio_Clip :: struct { 3375 using _: struct #raw_union { 3376 element: Element, 3377 3378 using _: struct { 3379 name: String, 3380 props: Props, 3381 element_id: u32, 3382 typed_id: u32, 3383 }, 3384 }, 3385 3386 // Filename relative to the currently loaded file. 3387 // HINT: If using functions other than `ufbx_load_file()`, you can provide 3388 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 3389 filename: String, 3390 3391 // Absolute filename specified in the file. 3392 absolute_filename: String, 3393 3394 // Relative filename specified in the file. 3395 // NOTE: May be absolute if the file is saved in a different drive. 3396 relative_filename: String, 3397 3398 // Filename relative to the loaded file, non-UTF-8 encoded. 3399 // HINT: If using functions other than `ufbx_load_file()`, you can provide 3400 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 3401 raw_filename: Blob, 3402 3403 // Absolute filename specified in the file, non-UTF-8 encoded. 3404 raw_absolute_filename: Blob, 3405 3406 // Relative filename specified in the file, non-UTF-8 encoded. 3407 // NOTE: May be absolute if the file is saved in a different drive. 3408 raw_relative_filename: Blob, 3409 3410 // Optional embedded content blob, eg. raw .png format data 3411 content: Blob, 3412 } 3413 3414 // -- Miscellaneous 3415 Bone_Pose :: struct { 3416 // Node to apply the pose to. 3417 bone_node: ^Node, 3418 3419 // Matrix from node local space to world space. 3420 bone_to_world: Matrix, 3421 3422 // Matrix from node local space to parent space. 3423 // NOTE: FBX only stores world transformations so this is approximated from 3424 // the parent world transform. 3425 bone_to_parent: Matrix, 3426 } 3427 3428 Bone_Pose_List :: struct { 3429 data: ^Bone_Pose, 3430 count: c.size_t, 3431 } 3432 3433 Pose :: struct { 3434 using _: struct #raw_union { 3435 element: Element, 3436 3437 using _: struct { 3438 name: String, 3439 props: Props, 3440 element_id: u32, 3441 typed_id: u32, 3442 }, 3443 }, 3444 3445 // Set if this pose is marked as a bind pose. 3446 is_bind_pose: bool, 3447 3448 // List of bone poses. 3449 // Sorted by `ufbx_node.typed_id`. 3450 bone_poses: Bone_Pose_List, 3451 } 3452 3453 Metadata_Object :: struct { 3454 using _: struct #raw_union { 3455 element: Element, 3456 3457 using _: struct { 3458 name: String, 3459 props: Props, 3460 element_id: u32, 3461 typed_id: u32, 3462 }, 3463 }, 3464 } 3465 3466 // -- Named elements 3467 Name_Element :: struct { 3468 name: String, 3469 type: Element_Type, 3470 _internal_key: u32, 3471 element: ^Element, 3472 } 3473 3474 Name_Element_List :: struct { 3475 data: ^Name_Element, 3476 count: c.size_t, 3477 } 3478 3479 // Scene is the root object loaded by ufbx that everything is accessed from. 3480 Exporter :: enum i32 { 3481 UNKNOWN = 0, 3482 FBX_SDK = 1, 3483 BLENDER_BINARY = 2, 3484 BLENDER_ASCII = 3, 3485 MOTION_BUILDER = 4, 3486 } 3487 3488 EXPORTER_COUNT :: 5 3489 3490 Application :: struct { 3491 vendor: String, 3492 name: String, 3493 version: String, 3494 } 3495 3496 File_Format :: enum i32 { 3497 UNKNOWN = 0, // < Unknown file format 3498 FBX = 1, // < .fbx Kaydara/Autodesk FBX file 3499 OBJ = 2, // < .obj Wavefront OBJ file 3500 MTL = 3, // < .mtl Wavefront MTL (Material template library) file 3501 } 3502 3503 FILE_FORMAT_COUNT :: 4 3504 3505 Warning_Type :: enum i32 { 3506 // Missing external file file (for example .mtl for Wavefront .obj file or a 3507 // geometry cache) 3508 MISSING_EXTERNAL_FILE = 0, 3509 3510 // Loaded a Wavefront .mtl file derived from the filename instead of a proper 3511 // `mtllib` statement. 3512 IMPLICIT_MTL = 1, 3513 3514 // Truncated array has been auto-expanded. 3515 TRUNCATED_ARRAY = 2, 3516 3517 // Geometry data has been defined but has no data. 3518 MISSING_GEOMETRY_DATA = 3, 3519 3520 // Duplicated connection between two elements that shouldn't have. 3521 DUPLICATE_CONNECTION = 4, 3522 3523 // Vertex 'W' attribute length differs from main attribute. 3524 BAD_VERTEX_W_ATTRIBUTE = 5, 3525 3526 // Missing polygon mapping type. 3527 MISSING_POLYGON_MAPPING = 6, 3528 3529 // Unsupported version, loaded but may be incorrect. 3530 // If the loading fails `UFBX_ERROR_UNSUPPORTED_VERSION` is issued instead. 3531 UNSUPPORTED_VERSION = 7, 3532 3533 // Out-of-bounds index has been clamped to be in-bounds. 3534 // HINT: You can use `ufbx_index_error_handling` to adjust behavior. 3535 INDEX_CLAMPED = 8, 3536 3537 // Non-UTF8 encoded strings. 3538 // HINT: You can use `ufbx_unicode_error_handling` to adjust behavior. 3539 BAD_UNICODE = 9, 3540 3541 // Invalid base64-encoded embedded content ignored. 3542 BAD_BASE64_CONTENT = 10, 3543 3544 // Non-node element connected to root. 3545 BAD_ELEMENT_CONNECTED_TO_ROOT = 11, 3546 3547 // Duplicated object ID in the file, connections will be wrong. 3548 DUPLICATE_OBJECT_ID = 12, 3549 3550 // Empty face has been removed. 3551 // Use `ufbx_load_opts.allow_empty_faces` if you want to allow them. 3552 EMPTY_FACE_REMOVED = 13, 3553 3554 // Unknown .obj file directive. 3555 UNKNOWN_OBJ_DIRECTIVE = 14, 3556 3557 // Warnings after this one are deduplicated. 3558 // See `ufbx_warning.count` for how many times they happened. 3559 TYPE_FIRST_DEDUPLICATED = 8, 3560 } 3561 3562 WARNING_TYPE_COUNT :: 15 3563 3564 // Warning about a non-fatal issue in the file. 3565 // Often contains information about issues that ufbx has corrected about the 3566 // file but it might indicate something is not working properly. 3567 Warning :: struct { 3568 // Type of the warning. 3569 type: Warning_Type, 3570 3571 // Description of the warning. 3572 description: String, 3573 3574 // The element related to this warning or `UFBX_NO_INDEX` if not related to a specific element. 3575 element_id: u32, 3576 3577 // Number of times this warning was encountered. 3578 count: c.size_t, 3579 } 3580 3581 Warning_List :: struct { 3582 data: ^Warning, 3583 count: c.size_t, 3584 } 3585 3586 Thumbnail_Format :: enum i32 { 3587 UNKNOWN = 0, // < Unknown format 3588 RGB_24 = 1, // < 8-bit RGB pixels, in memory R,G,B 3589 RGBA_32 = 2, // < 8-bit RGBA pixels, in memory R,G,B,A 3590 } 3591 3592 THUMBNAIL_FORMAT_COUNT :: 3 3593 3594 // Specify how unit / coordinate system conversion should be performed. 3595 // Affects how `ufbx_load_opts.target_axes` and `ufbx_load_opts.target_unit_meters` work, 3596 // has no effect if neither is specified. 3597 Space_Conversion :: enum i32 { 3598 // Store the space conversion transform in the root node. 3599 // Sets `ufbx_node.local_transform` of the root node. 3600 TRANSFORM_ROOT = 0, 3601 3602 // Perform the conversion by using "adjust" transforms. 3603 // Compensates for the transforms using `ufbx_node.adjust_pre_rotation` and 3604 // `ufbx_node.adjust_pre_scale`. You don't need to account for these unless 3605 // you are manually building transforms from `ufbx_props`. 3606 ADJUST_TRANSFORMS = 1, 3607 3608 // Perform the conversion by scaling geometry in addition to adjusting transforms. 3609 // Compensates transforms like `UFBX_SPACE_CONVERSION_ADJUST_TRANSFORMS` but 3610 // applies scaling to geometry as well. 3611 MODIFY_GEOMETRY = 2, 3612 } 3613 3614 SPACE_CONVERSION_COUNT :: 3 3615 3616 // Embedded thumbnail in the file, valid if the dimensions are non-zero. 3617 Thumbnail :: struct { 3618 props: Props, 3619 3620 // Extents of the thumbnail 3621 width: u32, 3622 height: u32, 3623 3624 // Format of `ufbx_thumbnail.data`. 3625 format: Thumbnail_Format, 3626 3627 // Thumbnail pixel data, layout as contiguous rows from bottom to top. 3628 // See `ufbx_thumbnail.format` for the pixel format. 3629 data: Blob, 3630 } 3631 3632 // Miscellaneous data related to the loaded file 3633 Metadata :: struct { 3634 // List of non-fatal warnings about the file. 3635 // If you need to only check whether a specific warning was triggered you 3636 // can use `ufbx_metadata.has_warning[]`. 3637 warnings: Warning_List, 3638 3639 // FBX ASCII file format. 3640 ascii: bool, 3641 3642 // FBX version in integer format, eg. 7400 for 7.4. 3643 version: u32, 3644 3645 // File format of the source file. 3646 file_format: File_Format, 3647 3648 // Index arrays may contain `UFBX_NO_INDEX` instead of a valid index 3649 // to indicate gaps. 3650 may_contain_no_index: bool, 3651 3652 // May contain meshes with no defined vertex position. 3653 // NOTE: `ufbx_mesh.vertex_position.exists` may be `false`! 3654 may_contain_missing_vertex_position: bool, 3655 3656 // Arrays may contain items with `NULL` element references. 3657 // See `ufbx_load_opts.connect_broken_elements`. 3658 may_contain_broken_elements: bool, 3659 3660 // Some API guarantees do not apply (depending on unsafe options used). 3661 // Loaded with `ufbx_load_opts.allow_unsafe` enabled. 3662 is_unsafe: bool, 3663 3664 // Flag for each possible warning type. 3665 // See `ufbx_metadata.warnings[]` for detailed warning information. 3666 has_warning: [15]bool, 3667 creator: String, 3668 big_endian: bool, 3669 filename: String, 3670 relative_root: String, 3671 raw_filename: Blob, 3672 raw_relative_root: Blob, 3673 exporter: Exporter, 3674 exporter_version: u32, 3675 scene_props: Props, 3676 original_application: Application, 3677 latest_application: Application, 3678 thumbnail: Thumbnail, 3679 geometry_ignored: bool, 3680 animation_ignored: bool, 3681 embedded_ignored: bool, 3682 max_face_triangles: c.size_t, 3683 result_memory_used: c.size_t, 3684 temp_memory_used: c.size_t, 3685 result_allocs: c.size_t, 3686 temp_allocs: c.size_t, 3687 element_buffer_size: c.size_t, 3688 num_shader_textures: c.size_t, 3689 bone_prop_size_unit: Real, 3690 bone_prop_limb_length_relative: bool, 3691 ortho_size_unit: Real, 3692 ktime_second: i64, // < One second in internal KTime units 3693 original_file_path: String, 3694 raw_original_file_path: Blob, 3695 3696 // Space conversion method used on the scene. 3697 space_conversion: Space_Conversion, 3698 3699 // Transform that has been applied to root for axis/unit conversion. 3700 root_rotation: Quat, 3701 root_scale: Real, 3702 3703 // Axis that the scene has been mirrored by. 3704 // All geometry has been mirrored in this axis. 3705 mirror_axis: Mirror_Axis, 3706 3707 // Amount geometry has been scaled. 3708 // See `UFBX_SPACE_CONVERSION_MODIFY_GEOMETRY`. 3709 geometry_scale: Real, 3710 } 3711 3712 Time_Mode :: enum i32 { 3713 DEFAULT = 0, 3714 _120_FPS = 1, 3715 _100_FPS = 2, 3716 _60_FPS = 3, 3717 _50_FPS = 4, 3718 _48_FPS = 5, 3719 _30_FPS = 6, 3720 _30_FPS_DROP = 7, 3721 NTSC_DROP_FRAME = 8, 3722 NTSC_FULL_FRAME = 9, 3723 PAL = 10, 3724 _24_FPS = 11, 3725 _1000_FPS = 12, 3726 FILM_FULL_FRAME = 13, 3727 CUSTOM = 14, 3728 _96_FPS = 15, 3729 _72_FPS = 16, 3730 _59_94_FPS = 17, 3731 } 3732 3733 TIME_MODE_COUNT :: 18 3734 3735 Time_Protocol :: enum i32 { 3736 SMPTE = 0, 3737 FRAME_COUNT = 1, 3738 DEFAULT = 2, 3739 } 3740 3741 TIME_PROTOCOL_COUNT :: 3 3742 3743 Snap_Mode :: enum i32 { 3744 NONE = 0, 3745 SNAP = 1, 3746 PLAY = 2, 3747 SNAP_AND_PLAY = 3, 3748 } 3749 3750 SNAP_MODE_COUNT :: 4 3751 3752 // Global settings: Axes and time/unit scales 3753 Scene_Settings :: struct { 3754 props: Props, 3755 3756 // Mapping of X/Y/Z axes to world-space directions. 3757 // HINT: Use `ufbx_load_opts.target_axes` to normalize this. 3758 // NOTE: This contains the _original_ axes even if you supply `ufbx_load_opts.target_axes`. 3759 axes: Coordinate_Axes, 3760 3761 // How many meters does a single world-space unit represent. 3762 // FBX files usually default to centimeters, reported as `0.01` here. 3763 // HINT: Use `ufbx_load_opts.target_unit_meters` to normalize this. 3764 unit_meters: Real, 3765 3766 // Frames per second the animation is defined at. 3767 frames_per_second: f64, 3768 ambient_color: Vec3, 3769 default_camera: String, 3770 3771 // Animation user interface settings. 3772 // HINT: Use `ufbx_scene_settings.frames_per_second` instead of interpreting these yourself. 3773 time_mode: Time_Mode, 3774 time_protocol: Time_Protocol, 3775 snap_mode: Snap_Mode, 3776 3777 // Original settings (?) 3778 original_axis_up: Coordinate_Axis, 3779 original_unit_meters: Real, 3780 } 3781 3782 Scene :: struct { 3783 metadata: Metadata, 3784 3785 // Global settings 3786 settings: Scene_Settings, 3787 3788 // Node instances in the scene 3789 root_node: ^Node, 3790 3791 // Default animation descriptor 3792 anim: ^Anim, 3793 3794 using _: struct #raw_union { 3795 using _: struct { 3796 unknowns: Unknown_List, 3797 3798 // Nodes 3799 nodes: Node_List, 3800 3801 // Node attributes (common) 3802 meshes: Mesh_List, 3803 lights: Light_List, 3804 cameras: Camera_List, 3805 bones: Bone_List, 3806 empties: Empty_List, 3807 3808 // Node attributes (curves/surfaces) 3809 line_curves: Line_Curve_List, 3810 nurbs_curves: Nurbs_Curve_List, 3811 nurbs_surfaces: Nurbs_Surface_List, 3812 nurbs_trim_surfaces: Nurbs_Trim_Surface_List, 3813 nurbs_trim_boundaries: Nurbs_Trim_Boundary_List, 3814 3815 // Node attributes (advanced) 3816 procedural_geometries: Procedural_Geometry_List, 3817 stereo_cameras: Stereo_Camera_List, 3818 camera_switchers: Camera_Switcher_List, 3819 markers: Marker_List, 3820 lod_groups: Lod_Group_List, 3821 3822 // Deformers 3823 skin_deformers: Skin_Deformer_List, 3824 skin_clusters: Skin_Cluster_List, 3825 blend_deformers: Blend_Deformer_List, 3826 blend_channels: Blend_Channel_List, 3827 blend_shapes: Blend_Shape_List, 3828 cache_deformers: Cache_Deformer_List, 3829 cache_files: Cache_File_List, 3830 3831 // Materials 3832 materials: Material_List, 3833 textures: Texture_List, 3834 videos: Video_List, 3835 shaders: Shader_List, 3836 shader_bindings: Shader_Binding_List, 3837 3838 // Animation 3839 anim_stacks: Anim_Stack_List, 3840 anim_layers: Anim_Layer_List, 3841 anim_values: Anim_Value_List, 3842 anim_curves: Anim_Curve_List, 3843 3844 // Collections 3845 display_layers: Display_Layer_List, 3846 selection_sets: Selection_Set_List, 3847 selection_nodes: Selection_Node_List, 3848 3849 // Constraints 3850 characters: Character_List, 3851 constraints: Constraint_List, 3852 3853 // Audio 3854 audio_layers: Audio_Layer_List, 3855 audio_clips: Audio_Clip_List, 3856 3857 // Miscellaneous 3858 poses: Pose_List, 3859 metadata_objects: Metadata_Object_List, 3860 }, 3861 3862 elements_by_type: [42]Element_List, 3863 }, 3864 3865 // Unique texture files referenced by the scene. 3866 texture_files: Texture_File_List, 3867 3868 // All elements and connections in the whole file 3869 elements: Element_List, // < Sorted by `id` 3870 connections_src: Connection_List, // < Sorted by `src,src_prop` 3871 connections_dst: Connection_List, // < Sorted by `dst,dst_prop` 3872 3873 // Elements sorted by name, type 3874 elements_by_name: Name_Element_List, 3875 3876 // Enabled if `ufbx_load_opts.retain_dom == true`. 3877 dom_root: ^Dom_Node, 3878 } 3879 3880 // -- Curves 3881 Curve_Point :: struct { 3882 valid: bool, 3883 position: Vec3, 3884 derivative: Vec3, 3885 } 3886 3887 Surface_Point :: struct { 3888 valid: bool, 3889 position: Vec3, 3890 derivative_u: Vec3, 3891 derivative_v: Vec3, 3892 } 3893 3894 // -- Mesh topology 3895 Topo_Flags :: enum i32 { 3896 UFBX_TOPO_NON_MANIFOLD = 1, // < Edge with three or more faces 3897 } 3898 3899 Topo_Edge :: struct { 3900 index: u32, // < Starting index of the edge, always defined 3901 next: u32, // < Ending index of the edge / next per-face `ufbx_topo_edge`, always defined 3902 prev: u32, // < Previous per-face `ufbx_topo_edge`, always defined 3903 twin: u32, // < `ufbx_topo_edge` on the opposite side, `UFBX_NO_INDEX` if not found 3904 face: u32, // < Index into `mesh->faces[]`, always defined 3905 edge: u32, // < Index into `mesh->edges[]`, `UFBX_NO_INDEX` if not found 3906 flags: Topo_Flags, 3907 } 3908 3909 // Vertex data array for `ufbx_generate_indices()`. 3910 // NOTE: `ufbx_generate_indices()` compares the vertices using `memcmp()`, so 3911 // any padding should be cleared to zero. 3912 Vertex_Stream :: struct { 3913 data: rawptr, // < Data pointer of shape `char[vertex_count][vertex_size]`. 3914 vertex_count: c.size_t, // < Number of vertices in this stream, for sanity checking. 3915 vertex_size: c.size_t, // < Size of a vertex in bytes. 3916 } 3917 3918 // Allocate `size` bytes, must be at least 8 byte aligned 3919 Alloc_Fn :: proc "c" (user: rawptr, size: c.size_t) -> rawptr 3920 3921 // Reallocate `old_ptr` from `old_size` to `new_size` 3922 // NOTE: If omit `alloc_fn` and `free_fn` they will be translated to: 3923 // `alloc(size)` -> `realloc_fn(user, NULL, 0, size)` 3924 // `free_fn(ptr, size)` -> `realloc_fn(user, ptr, size, 0)` 3925 Realloc_Fn :: proc "c" (user: rawptr, old_ptr: rawptr, old_size: c.size_t, new_size: c.size_t) -> rawptr 3926 3927 // Free pointer `ptr` (of `size` bytes) returned by `alloc_fn` or `realloc_fn` 3928 Free_Fn :: proc "c" (user: rawptr, ptr: rawptr, size: c.size_t) 3929 3930 // Free the allocator itself 3931 Free_Allocator_Fn :: proc "c" (user: rawptr) 3932 3933 // Allocator callbacks and user context 3934 // NOTE: The allocator will be stored to the loaded scene and will be called 3935 // again from `ufbx_free_scene()` so make sure `user` outlives that! 3936 // You can use `free_allocator_fn()` to free the allocator yourself. 3937 Allocator :: struct { 3938 // Callback functions, see `typedef`s above for information 3939 alloc_fn: Alloc_Fn, 3940 realloc_fn: Realloc_Fn, 3941 free_fn: Free_Fn, 3942 free_allocator_fn: Free_Allocator_Fn, 3943 user: rawptr, 3944 } 3945 3946 Allocator_Opts :: struct { 3947 // Allocator callbacks 3948 allocator: Allocator, 3949 3950 // Maximum number of bytes to allocate before failing 3951 memory_limit: c.size_t, 3952 3953 // Maximum number of allocations to attempt before failing 3954 allocation_limit: c.size_t, 3955 3956 // Threshold to swap from batched allocations to individual ones 3957 // Defaults to 1MB if set to zero 3958 // NOTE: If set to `1` ufbx will allocate everything in the smallest 3959 // possible chunks which may be useful for debugging (eg. ASAN) 3960 huge_threshold: c.size_t, 3961 3962 // Maximum size of a single allocation containing sub-allocations. 3963 // Defaults to 16MB if set to zero 3964 // The maximum amount of wasted memory depends on `max_chunk_size` and 3965 // `huge_threshold`: each chunk can waste up to `huge_threshold` bytes 3966 // internally and the last chunk might be incomplete. So for example 3967 // with the defaults we can waste around 1MB/16MB = 6.25% overall plus 3968 // up to 32MB due to the two incomplete blocks. The actual amounts differ 3969 // slightly as the chunks start out at 4kB and double in size each time, 3970 // meaning that the maximum fixed overhead (up to 32MB with defaults) is 3971 // at most ~30% of the total allocation size. 3972 max_chunk_size: c.size_t, 3973 } 3974 3975 // Try to read up to `size` bytes to `data`, return the amount of read bytes. 3976 // Return `SIZE_MAX` to indicate an IO error. 3977 Read_Fn :: proc "c" (user: rawptr, data: rawptr, size: c.size_t) -> c.size_t 3978 3979 // Skip `size` bytes in the file. 3980 Skip_Fn :: proc "c" (user: rawptr, size: c.size_t) -> bool 3981 3982 // Get the size of the file. 3983 // Return `0` if unknown, `UINT64_MAX` if error. 3984 Size_Fn :: proc "c" (user: rawptr) -> u64 3985 3986 // Close the file 3987 Close_Fn :: proc "c" (user: rawptr) 3988 3989 Stream :: struct { 3990 read_fn: Read_Fn, // < Required 3991 skip_fn: Skip_Fn, // < Optional: Will use `read_fn()` if missing 3992 size_fn: Size_Fn, // < Optional 3993 close_fn: Close_Fn, // < Optional 3994 3995 // Context passed to other functions 3996 user: rawptr, 3997 } 3998 3999 Open_File_Type :: enum i32 { 4000 MAIN_MODEL = 0, // < Main model file 4001 GEOMETRY_CACHE = 1, // < Unknown geometry cache file 4002 OBJ_MTL = 2, // < .mtl material library file 4003 } 4004 4005 OPEN_FILE_TYPE_COUNT :: 3 4006 4007 Open_File_Context :: c.uintptr_t 4008 4009 Open_File_Info :: struct { 4010 // Context that can be passed to the following functions to use a shared allocator: 4011 // ufbx_open_file_ctx() 4012 // ufbx_open_memory_ctx() 4013 _context: Open_File_Context, 4014 4015 // Kind of file to load. 4016 type: Open_File_Type, 4017 4018 // Original filename in the file, not resolved or UTF-8 encoded. 4019 // NOTE: Not necessarily NULL-terminated! 4020 original_filename: Blob, 4021 } 4022 4023 // Callback for opening an external file from the filesystem 4024 Open_File_Fn :: proc "c" (user: rawptr, stream: ^Stream, path: cstring, path_len: c.size_t, info: ^Open_File_Info) -> bool 4025 4026 Open_File_Cb :: struct { 4027 fn: Open_File_Fn, 4028 user: rawptr, 4029 } 4030 4031 // Options for `ufbx_open_file()`. 4032 Open_File_Opts :: struct { 4033 _begin_zero: u32, 4034 4035 // Allocator to allocate the memory with. 4036 allocator: Allocator_Opts, 4037 4038 // The filename is guaranteed to be NULL-terminated. 4039 filename_null_terminated: bool, 4040 _end_zero: u32, 4041 } 4042 4043 // Memory stream options 4044 Close_Memory_Fn :: proc "c" (user: rawptr, data: rawptr, data_size: c.size_t) 4045 4046 Close_Memory_Cb :: struct { 4047 fn: Close_Memory_Fn, 4048 user: rawptr, 4049 } 4050 4051 // Options for `ufbx_open_memory()`. 4052 Open_Memory_Opts :: struct { 4053 _begin_zero: u32, 4054 4055 // Allocator to allocate the memory with. 4056 // NOTE: Used even if no copy is made to allocate a small metadata block. 4057 allocator: Allocator_Opts, 4058 4059 // Do not copy the memory. 4060 // You can use `close_cb` to free the memory when the stream is closed. 4061 // NOTE: This means the provided data pointer is referenced after creating 4062 // the memory stream, make sure the data stays valid until the stream is closed! 4063 no_copy: bool, 4064 4065 // Callback to free the memory blob. 4066 close_cb: Close_Memory_Cb, 4067 _end_zero: u32, 4068 } 4069 4070 // Detailed error stack frame. 4071 // NOTE: You must compile `ufbx.c` with `UFBX_ENABLE_ERROR_STACK` to enable the error stack. 4072 Error_Frame :: struct { 4073 source_line: u32, 4074 function: String, 4075 description: String, 4076 } 4077 4078 // Error causes (and `UFBX_ERROR_NONE` for no error). 4079 Error_Type :: enum i32 { 4080 // No error, operation has been performed successfully. 4081 NONE = 0, 4082 4083 // Unspecified error, most likely caused by an invalid FBX file or a file 4084 // that contains something ufbx can't handle. 4085 UNKNOWN = 1, 4086 4087 // File not found. 4088 FILE_NOT_FOUND = 2, 4089 4090 // Empty file. 4091 EMPTY_FILE = 3, 4092 4093 // External file not found. 4094 // See `ufbx_load_opts.load_external_files` for more information. 4095 EXTERNAL_FILE_NOT_FOUND = 4, 4096 4097 // Out of memory (allocator returned `NULL`). 4098 OUT_OF_MEMORY = 5, 4099 4100 // `ufbx_allocator_opts.memory_limit` exhausted. 4101 MEMORY_LIMIT = 6, 4102 4103 // `ufbx_allocator_opts.allocation_limit` exhausted. 4104 ALLOCATION_LIMIT = 7, 4105 4106 // File ended abruptly. 4107 TRUNCATED_FILE = 8, 4108 4109 // IO read error. 4110 // eg. returning `SIZE_MAX` from `ufbx_stream.read_fn` or stdio `ferror()` condition. 4111 IO = 9, 4112 4113 // User cancelled the loading via `ufbx_load_opts.progress_cb` returning `UFBX_PROGRESS_CANCEL`. 4114 CANCELLED = 10, 4115 4116 // Could not detect file format from file data or filename. 4117 // HINT: You can supply it manually using `ufbx_load_opts.file_format` or use `ufbx_load_opts.filename` 4118 // when using `ufbx_load_memory()` to let ufbx guess the format from the extension. 4119 UNRECOGNIZED_FILE_FORMAT = 11, 4120 UNINITIALIZED_OPTIONS = 12, 4121 4122 // The vertex streams in `ufbx_generate_indices()` are empty. 4123 ZERO_VERTEX_SIZE = 13, 4124 4125 // Vertex stream passed to `ufbx_generate_indices()`. 4126 TRUNCATED_VERTEX_STREAM = 14, 4127 4128 // Invalid UTF-8 encountered in a file when loading with `UFBX_UNICODE_ERROR_HANDLING_ABORT_LOADING`. 4129 INVALID_UTF8 = 15, 4130 4131 // Feature needed for the operation has been compiled out. 4132 FEATURE_DISABLED = 16, 4133 4134 // Attempting to tessellate an invalid NURBS object. 4135 // See `ufbx_nurbs_basis.valid`. 4136 BAD_NURBS = 17, 4137 4138 // Out of bounds index in the file when loading with `UFBX_INDEX_ERROR_HANDLING_ABORT_LOADING`. 4139 BAD_INDEX = 18, 4140 4141 // Node is deeper than `ufbx_load_opts.node_depth_limit` in the hierarchy. 4142 NODE_DEPTH_LIMIT = 19, 4143 4144 // Error parsing ASCII array in a thread. 4145 // Threaded ASCII parsing is slightly more strict than non-threaded, for cursed files, 4146 // set `ufbx_load_opts.force_single_thread_ascii_parsing` to `true`. 4147 THREADED_ASCII_PARSE = 20, 4148 4149 // Unsafe options specified without enabling `ufbx_load_opts.allow_unsafe`. 4150 UNSAFE_OPTIONS = 21, 4151 4152 // Duplicated override property in `ufbx_create_anim()` 4153 DUPLICATE_OVERRIDE = 22, 4154 4155 // Unsupported file format version. 4156 // ufbx still tries to load files with unsupported versions, see `UFBX_WARNING_UNSUPPORTED_VERSION`. 4157 UNSUPPORTED_VERSION = 23, 4158 } 4159 4160 ERROR_TYPE_COUNT :: 24 4161 4162 // Error description with detailed stack trace 4163 // HINT: You can use `ufbx_format_error()` for formatting the error 4164 Error :: struct { 4165 // Type of the error, or `UFBX_ERROR_NONE` if successful. 4166 type: Error_Type, 4167 4168 // Description of the error type. 4169 description: String, 4170 4171 // Internal error stack. 4172 // NOTE: You must compile `ufbx.c` with `UFBX_ENABLE_ERROR_STACK` to enable the error stack. 4173 stack_size: u32, 4174 stack: [8]Error_Frame, 4175 4176 // Additional error information, such as missing file filename. 4177 // `info` is a NULL-terminated UTF-8 string containing `info_length` bytes, excluding the trailing `'\0'`. 4178 info_length: c.size_t, 4179 info: [256]i8, 4180 } 4181 4182 // Loading progress information. 4183 Progress :: struct { 4184 bytes_read: u64, 4185 bytes_total: u64, 4186 } 4187 4188 // Progress result returned from `ufbx_progress_fn()` callback. 4189 // Determines whether ufbx should continue or abort the loading. 4190 Progress_Result :: enum i32 { 4191 // Continue loading the file. 4192 CONTINUE = 256, 4193 4194 // Cancel loading and fail with `UFBX_ERROR_CANCELLED`. 4195 CANCEL = 512, 4196 } 4197 4198 // Called periodically with the current progress. 4199 // Return `UFBX_PROGRESS_CANCEL` to cancel further processing. 4200 Progress_Fn :: proc "c" (user: rawptr, progress: ^Progress) -> Progress_Result 4201 4202 Progress_Cb :: struct { 4203 fn: Progress_Fn, 4204 user: rawptr, 4205 } 4206 4207 // Source data/stream to decompress with `ufbx_inflate()` 4208 Inflate_Input :: struct { 4209 // Total size of the data in bytes 4210 total_size: c.size_t, 4211 4212 // (optional) Initial or complete data chunk 4213 data: rawptr, 4214 data_size: c.size_t, 4215 4216 // (optional) Temporary buffer, defaults to 256b stack buffer 4217 buffer: rawptr, 4218 buffer_size: c.size_t, 4219 4220 // (optional) Streaming read function, concatenated after `data` 4221 read_fn: Read_Fn, 4222 read_user: rawptr, 4223 4224 // (optional) Progress reporting 4225 progress_cb: Progress_Cb, 4226 progress_interval_hint: u64, // < Bytes between progress report calls 4227 4228 // (optional) Change the progress scope 4229 progress_size_before: u64, 4230 progress_size_after: u64, 4231 4232 // (optional) No the DEFLATE header 4233 no_header: bool, 4234 4235 // (optional) No the Adler32 checksum 4236 no_checksum: bool, 4237 4238 // (optional) Force internal fast lookup bit amount 4239 internal_fast_bits: c.size_t, 4240 } 4241 4242 // Persistent data between `ufbx_inflate()` calls 4243 // NOTE: You must set `initialized` to `false`, but `data` may be uninitialized 4244 Inflate_Retain :: struct { 4245 initialized: bool, 4246 data: [1024]u64, 4247 } 4248 4249 Index_Error_Handling :: enum i32 { 4250 // Clamp to a valid value. 4251 CLAMP = 0, 4252 4253 // Set bad indices to `UFBX_NO_INDEX`. 4254 // This is the recommended way if you need to deal with files with gaps in information. 4255 // HINT: If you use this `ufbx_get_vertex_TYPE()` functions will return zero 4256 // on invalid indices instead of failing. 4257 NO_INDEX = 1, 4258 4259 // Fail loading entierely when encountering a bad index. 4260 ABORT_LOADING = 2, 4261 4262 // Pass bad indices through as-is. 4263 // Requires `ufbx_load_opts.allow_unsafe`. 4264 // UNSAFE: Breaks any API guarantees regarding indexes being in bounds and makes 4265 // `ufbx_get_vertex_TYPE()` memory-unsafe to use. 4266 UNSAFE_IGNORE = 3, 4267 } 4268 4269 INDEX_ERROR_HANDLING_COUNT :: 4 4270 4271 Unicode_Error_Handling :: enum i32 { 4272 // Replace errors with U+FFFD "Replacement Character" 4273 REPLACEMENT_CHARACTER = 0, 4274 4275 // Replace errors with '_' U+5F "Low Line" 4276 UNDERSCORE = 1, 4277 4278 // Replace errors with '?' U+3F "Question Mark" 4279 QUESTION_MARK = 2, 4280 4281 // Remove errors from the output 4282 REMOVE = 3, 4283 4284 // Fail loading on encountering an Unicode error 4285 ABORT_LOADING = 4, 4286 4287 // Ignore and pass-through non-UTF-8 string data. 4288 // Requires `ufbx_load_opts.allow_unsafe`. 4289 // UNSAFE: Breaks API guarantee that `ufbx_string` is UTF-8 encoded. 4290 UNSAFE_IGNORE = 5, 4291 } 4292 4293 UNICODE_ERROR_HANDLING_COUNT :: 6 4294 4295 // How to handle FBX node geometry transforms. 4296 // FBX nodes can have "geometry transforms" that affect only the attached meshes, 4297 // but not the children. This is not allowed in many scene representations so 4298 // ufbx provides some ways to simplify them. 4299 // Geometry transforms can also be used to transform any other attributes such 4300 // as lights or cameras. 4301 Geometry_Transform_Handling :: enum i32 { 4302 // Preserve the geometry transforms as-is. 4303 // To be correct for all files you have to use `ufbx_node.geometry_transform`, 4304 // `ufbx_node.geometry_to_node`, or `ufbx_node.geometry_to_world` to compensate 4305 // for any potential geometry transforms. 4306 PRESERVE = 0, 4307 4308 // Add helper nodes between the nodes and geometry where needed. 4309 // The created nodes have `ufbx_node.is_geometry_transform_helper` set and are 4310 // named `ufbx_load_opts.geometry_transform_helper_name`. 4311 HELPER_NODES = 1, 4312 4313 // Modify the geometry of meshes attached to nodes with geometry transforms. 4314 // Will add helper nodes like `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES` if 4315 // necessary, for example if there are multiple instances of the same mesh with 4316 // geometry transforms. 4317 MODIFY_GEOMETRY = 2, 4318 4319 // Modify the geometry of meshes attached to nodes with geometry transforms. 4320 // NOTE: This will not work correctly for instanced geometry. 4321 MODIFY_GEOMETRY_NO_FALLBACK = 3, 4322 } 4323 4324 GEOMETRY_TRANSFORM_HANDLING_COUNT :: 4 4325 4326 // How to handle FBX transform inherit modes. 4327 Inherit_Mode_Handling :: enum i32 { 4328 // Preserve inherit mode in `ufbx_node.inherit_mode`. 4329 // NOTE: To correctly handle all scenes you would need to handle the 4330 // non-standard inherit modes. 4331 PRESERVE = 0, 4332 4333 // Create scale helper nodes parented to nodes that need special inheritance. 4334 // Scale helper nodes will have `ufbx_node.is_scale_helper` and parents of 4335 // scale helpers will have `ufbx_node.scale_helper` pointing to it. 4336 HELPER_NODES = 1, 4337 4338 // Attempt to compensate for bone scale by inversely scaling children. 4339 // NOTE: This only works for uniform non-animated scaling, if scale is 4340 // non-uniform or animated, ufbx will add scale helpers in the same way 4341 // as `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`. 4342 COMPENSATE = 2, 4343 4344 // Attempt to compensate for bone scale by inversely scaling children. 4345 // Will never create helper nodes. 4346 COMPENSATE_NO_FALLBACK = 3, 4347 4348 // Ignore non-standard inheritance modes. 4349 // Forces all nodes to have `UFBX_INHERIT_MODE_NORMAL` regardless of the 4350 // inherit mode specified in the file. This can be useful for emulating 4351 // results from importers/programs that don't support inherit modes. 4352 IGNORE = 4, 4353 } 4354 4355 INHERIT_MODE_HANDLING_COUNT :: 5 4356 4357 // How to handle FBX transform pivots. 4358 Pivot_Handling :: enum i32 { 4359 // Take pivots into account when computing the transform. 4360 RETAIN = 0, 4361 4362 // Translate objects to be located at their pivot. 4363 // NOTE: Only applied if rotation and scaling pivots are equal. 4364 // NOTE: Results in geometric translation. Use `ufbx_geometry_transform_handling` 4365 // to interpret these in a standard scene graph. 4366 ADJUST_TO_PIVOT = 1, 4367 } 4368 4369 PIVOT_HANDLING_COUNT :: 2 4370 4371 Baked_Key_Flag :: enum i32 { 4372 // This keyframe represents a constant step from the left side 4373 STEP_LEFT = 0, 4374 4375 // This keyframe represents a constant step from the right side 4376 STEP_RIGHT = 1, 4377 4378 // This keyframe is the main part of a step 4379 // Bordering either `UFBX_BAKED_KEY_STEP_LEFT` or `UFBX_BAKED_KEY_STEP_RIGHT`. 4380 STEP_KEY = 2, 4381 4382 // This keyframe is a real keyframe in the source animation 4383 KEYFRAME = 3, 4384 4385 // This keyframe has been reduced by maximum sample rate. 4386 // See `ufbx_bake_opts.maximum_sample_rate`. 4387 REDUCED = 4, 4388 } 4389 4390 Baked_Key_Flags :: bit_set[Baked_Key_Flag; i32] 4391 4392 Baked_Vec3 :: struct { 4393 time: f64, // < Time of the keyframe, in seconds 4394 value: Vec3, // < Value at `time`, can be linearly interpolated 4395 flags: Baked_Key_Flags, // < Additional information about the keyframe 4396 } 4397 4398 Baked_Vec3_List :: struct { 4399 data: ^Baked_Vec3, 4400 count: c.size_t, 4401 } 4402 4403 Baked_Quat :: struct { 4404 time: f64, // < Time of the keyframe, in seconds 4405 value: Quat, // < Value at `time`, can be (spherically) linearly interpolated 4406 flags: Baked_Key_Flags, // < Additional information about the keyframe 4407 } 4408 4409 Baked_Quat_List :: struct { 4410 data: ^Baked_Quat, 4411 count: c.size_t, 4412 } 4413 4414 // Baked transform animation for a single node. 4415 Baked_Node :: struct { 4416 // Typed ID of the node, maps to `ufbx_scene.nodes[]`. 4417 typed_id: u32, 4418 4419 // Element ID of the element, maps to `ufbx_scene.elements[]`. 4420 element_id: u32, 4421 4422 // The translation channel has constant values for the whole animation. 4423 constant_translation: bool, 4424 4425 // The rotation channel has constant values for the whole animation. 4426 constant_rotation: bool, 4427 4428 // The scale channel has constant values for the whole animation. 4429 constant_scale: bool, 4430 4431 // Translation keys for the animation, maps to `ufbx_node.local_transform.translation`. 4432 translation_keys: Baked_Vec3_List, 4433 4434 // Rotation keyframes, maps to `ufbx_node.local_transform.rotation`. 4435 rotation_keys: Baked_Quat_List, 4436 4437 // Scale keyframes, maps to `ufbx_node.local_transform.scale`. 4438 scale_keys: Baked_Vec3_List, 4439 } 4440 4441 Baked_Node_List :: struct { 4442 data: ^Baked_Node, 4443 count: c.size_t, 4444 } 4445 4446 // Baked property animation. 4447 Baked_Prop :: struct { 4448 // Name of the property, eg. `"Visibility"`. 4449 name: String, 4450 4451 // The value of the property is constant for the whole animation. 4452 constant_value: bool, 4453 4454 // Property value keys. 4455 keys: Baked_Vec3_List, 4456 } 4457 4458 Baked_Prop_List :: struct { 4459 data: ^Baked_Prop, 4460 count: c.size_t, 4461 } 4462 4463 // Baked property animation for a single element. 4464 Baked_Element :: struct { 4465 // Element ID of the element, maps to `ufbx_scene.elements[]`. 4466 element_id: u32, 4467 4468 // List of properties the animation modifies. 4469 props: Baked_Prop_List, 4470 } 4471 4472 Baked_Element_List :: struct { 4473 data: ^Baked_Element, 4474 count: c.size_t, 4475 } 4476 4477 Baked_Anim_Metadata :: struct { 4478 // Memory statistics 4479 result_memory_used: c.size_t, 4480 temp_memory_used: c.size_t, 4481 result_allocs: c.size_t, 4482 temp_allocs: c.size_t, 4483 } 4484 4485 // Animation baked into linearly interpolated keyframes. 4486 // See `ufbx_bake_anim()`. 4487 Baked_Anim :: struct { 4488 // Nodes that are modified by the animation. 4489 // Some nodes may be missing if the specified animation does not transform them. 4490 // Conversely, some non-obviously animated nodes may be included as exporters 4491 // often may add dummy keyframes for objects. 4492 nodes: Baked_Node_List, 4493 4494 // Element properties modified by the animation. 4495 elements: Baked_Element_List, 4496 4497 // Playback time range for the animation. 4498 playback_time_begin: f64, 4499 playback_time_end: f64, 4500 playback_duration: f64, 4501 4502 // Keyframe time range. 4503 key_time_min: f64, 4504 key_time_max: f64, 4505 4506 // Additional bake information. 4507 metadata: Baked_Anim_Metadata, 4508 } 4509 4510 // Internal thread pool handle. 4511 // Passed to `ufbx_thread_pool_run_task()` from an user thread to run ufbx tasks. 4512 // HINT: This context can store a user pointer via `ufbx_thread_pool_set_user_ptr()`. 4513 Thread_Pool_Context :: c.uintptr_t 4514 4515 // Thread pool creation information from ufbx. 4516 Thread_Pool_Info :: struct { 4517 max_concurrent_tasks: u32, 4518 } 4519 4520 // Initialize the thread pool. 4521 // Return `true` on success. 4522 Thread_Pool_Init_Fn :: proc "c" (user: rawptr, ctx: Thread_Pool_Context, info: ^Thread_Pool_Info) -> bool 4523 4524 // Run tasks `count` tasks in threads. 4525 // You must call `ufbx_thread_pool_run_task()` with indices `[start_index, start_index + count)`. 4526 // The threads are launched in batches indicated by `group`, see `UFBX_THREAD_GROUP_COUNT` for more information. 4527 // Ideally, you should run all the task indices in parallel within each `ufbx_thread_pool_run_fn()` call. 4528 Thread_Pool_Run_Fn :: proc "c" (user: rawptr, ctx: Thread_Pool_Context, group: u32, start_index: u32, count: u32) 4529 4530 // Wait for previous tasks spawned in `ufbx_thread_pool_run_fn()` to finish. 4531 // `group` specifies the batch to wait for, `max_index` contains `start_index + count` from that group instance. 4532 Thread_Pool_Wait_Fn :: proc "c" (user: rawptr, ctx: Thread_Pool_Context, group: u32, max_index: u32) 4533 4534 // Free the thread pool. 4535 Thread_Pool_Free_Fn :: proc "c" (user: rawptr, ctx: Thread_Pool_Context) 4536 4537 // Thread pool interface. 4538 // See functions above for more information. 4539 // 4540 // Hypothetical example of calls, where `UFBX_THREAD_GROUP_COUNT=2` for simplicity: 4541 // 4542 // run_fn(group=0, start_index=0, count=4) -> t0 := threaded { ufbx_thread_pool_run_task(0..3) } 4543 // run_fn(group=1, start_index=4, count=10) -> t1 := threaded { ufbx_thread_pool_run_task(4..10) } 4544 // wait_fn(group=0, max_index=4) -> wait_threads(t0) 4545 // run_fn(group=0, start_index=10, count=15) -> t0 := threaded { ufbx_thread_pool_run_task(10..14) } 4546 // wait_fn(group=1, max_index=10) -> wait_threads(t1) 4547 // wait_fn(group=0, max_index=15) -> wait_threads(t0) 4548 // 4549 Thread_Pool :: struct { 4550 init_fn: Thread_Pool_Init_Fn, // < Optional 4551 run_fn: Thread_Pool_Run_Fn, // < Required 4552 wait_fn: Thread_Pool_Wait_Fn, // < Required 4553 free_fn: Thread_Pool_Free_Fn, // < Optional 4554 user: rawptr, 4555 } 4556 4557 // Thread pool options. 4558 Thread_Opts :: struct { 4559 // Thread pool interface. 4560 // HINT: You can use `extra/ufbx_os.h` to provide a thread pool. 4561 pool: Thread_Pool, 4562 4563 // Maximum of tasks to have in-flight. 4564 // Default: 2048 4565 num_tasks: c.size_t, 4566 4567 // Maximum amount of memory to use for batched threaded processing. 4568 // Default: 32MB 4569 // NOTE: The actual used memory usage might be higher, if there are individual tasks 4570 // that rqeuire a high amount of memory. 4571 memory_limit: c.size_t, 4572 } 4573 4574 // Flags to control nanimation evaluation functions. 4575 Evaluate_Flags :: enum i32 { 4576 // Do not extrapolate past the keyframes. 4577 UFBX_EVALUATE_FLAG_NO_EXTRAPOLATION = 1, 4578 } 4579 4580 // Options for `ufbx_load_file/memory/stream/stdio()` 4581 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 4582 Load_Opts :: struct { 4583 _begin_zero: u32, 4584 temp_allocator: Allocator_Opts, // < Allocator used during loading 4585 result_allocator: Allocator_Opts, // < Allocator used for the final scene 4586 thread_opts: Thread_Opts, // < Threading options 4587 4588 // Preferences 4589 ignore_geometry: bool, // < Do not load geometry datsa (vertices, indices, etc) 4590 ignore_animation: bool, // < Do not load animation curves 4591 ignore_embedded: bool, // < Do not load embedded content 4592 ignore_all_content: bool, // < Do not load any content (geometry, animation, embedded) 4593 evaluate_skinning: bool, // < Evaluate skinning (see ufbx_mesh.skinned_vertices) 4594 evaluate_caches: bool, // < Evaluate vertex caches (see ufbx_mesh.skinned_vertices) 4595 4596 // Try to open external files referenced by the main file automatically. 4597 // Applies to geometry caches and .mtl files for OBJ. 4598 // NOTE: This may be risky for untrusted data as the input files may contain 4599 // references to arbitrary paths in the filesystem. 4600 // NOTE: This only applies to files *implicitly* referenced by the scene, if 4601 // you request additional files via eg. `ufbx_load_opts.obj_mtl_path` they 4602 // are still loaded. 4603 // NOTE: Will fail loading if any external files are not found by default, use 4604 // `ufbx_load_opts.ignore_missing_external_files` to suppress this, in this case 4605 // you can find the errors at `ufbx_metadata.warnings[]` as `UFBX_WARNING_MISSING_EXTERNAL_FILE`. 4606 load_external_files: bool, 4607 4608 // Don't fail loading if external files are not found. 4609 ignore_missing_external_files: bool, 4610 4611 // Don't compute `ufbx_skin_deformer` `vertices` and `weights` arrays saving 4612 // a bit of memory and time if not needed 4613 skip_skin_vertices: bool, 4614 4615 // Skip computing `ufbx_mesh.material_parts[]` and `ufbx_mesh.face_group_parts[]`. 4616 skip_mesh_parts: bool, 4617 4618 // Clean-up skin weights by removing negative, zero and NAN weights. 4619 clean_skin_weights: bool, 4620 4621 // Read Blender materials as PBR values. 4622 // Blender converts PBR materials to legacy FBX Phong materials in a deterministic way. 4623 // If this setting is enabled, such materials will be read as `UFBX_SHADER_BLENDER_PHONG`, 4624 // which means ufbx will be able to parse roughness and metallic textures. 4625 use_blender_pbr_material: bool, 4626 4627 // Don't adjust reading the FBX file depending on the detected exporter 4628 disable_quirks: bool, 4629 4630 // Don't allow partially broken FBX files to load 4631 strict: bool, 4632 4633 // Force ASCII parsing to use a single thread. 4634 // The multi-threaded ASCII parsing is slightly more lenient as it ignores 4635 // the self-reported size of ASCII arrays, that threaded parsing depends on. 4636 force_single_thread_ascii_parsing: bool, 4637 4638 // UNSAFE: If enabled allows using unsafe options that may fundamentally 4639 // break the API guarantees. 4640 allow_unsafe: bool, 4641 4642 // Specify how to handle broken indices. 4643 index_error_handling: Index_Error_Handling, 4644 4645 // Connect related elements even if they are broken. If `false` (default) 4646 // `ufbx_skin_cluster` with a missing `bone` field are _not_ included in 4647 // the `ufbx_skin_deformer.clusters[]` array for example. 4648 connect_broken_elements: bool, 4649 4650 // Allow nodes that are not connected in any way to the root. Conversely if 4651 // disabled, all lone nodes will be parented under `ufbx_scene.root_node`. 4652 allow_nodes_out_of_root: bool, 4653 4654 // Allow meshes with no vertex position attribute. 4655 // NOTE: If this is set `ufbx_mesh.vertex_position.exists` may be `false`. 4656 allow_missing_vertex_position: bool, 4657 4658 // Allow faces with zero indices. 4659 allow_empty_faces: bool, 4660 4661 // Generate vertex normals for a meshes that are missing normals. 4662 // You can see if the normals have been generated from `ufbx_mesh.generated_normals`. 4663 generate_missing_normals: bool, 4664 4665 // Ignore `open_file_cb` when loading the main file. 4666 open_main_file_with_default: bool, 4667 4668 // Path separator character, defaults to '\' on Windows and '/' otherwise. 4669 path_separator: i8, 4670 4671 // Maximum depth of the node hirerachy. 4672 // Will fail with `UFBX_ERROR_NODE_DEPTH_LIMIT` if a node is deeper than this limit. 4673 // NOTE: The default of 0 allows arbitrarily deep hierarchies. Be careful if using 4674 // recursive algorithms without setting this limit. 4675 node_depth_limit: u32, 4676 4677 // Estimated file size for progress reporting 4678 file_size_estimate: u64, 4679 4680 // Buffer size in bytes to use for reading from files or IO callbacks 4681 read_buffer_size: c.size_t, 4682 4683 // Filename to use as a base for relative file paths if not specified using 4684 // `ufbx_load_file()`. Use `length = SIZE_MAX` for NULL-terminated strings. 4685 // `raw_filename` will be derived from this if empty. 4686 filename: String, 4687 4688 // Raw non-UTF8 filename. Does not support NULL termination. 4689 // `filename` will be derived from this if empty. 4690 raw_filename: Blob, 4691 4692 // Progress reporting 4693 progress_cb: Progress_Cb, 4694 progress_interval_hint: u64, // < Bytes between progress report calls 4695 4696 // External file callbacks (defaults to stdio.h) 4697 open_file_cb: Open_File_Cb, 4698 4699 // How to handle geometry transforms in the nodes. 4700 // See `ufbx_geometry_transform_handling` for an explanation. 4701 geometry_transform_handling: Geometry_Transform_Handling, 4702 4703 // How to handle unconventional transform inherit modes. 4704 // See `ufbx_inherit_mode_handling` for an explanation. 4705 inherit_mode_handling: Inherit_Mode_Handling, 4706 4707 // How to handle pivots. 4708 // See `ufbx_pivot_handling` for an explanation. 4709 pivot_handling: Pivot_Handling, 4710 4711 // How to perform space conversion by `target_axes` and `target_unit_meters`. 4712 // See `ufbx_space_conversion` for an explanation. 4713 space_conversion: Space_Conversion, 4714 4715 // Axis used to mirror for conversion between left-handed and right-handed coordinates. 4716 handedness_conversion_axis: Mirror_Axis, 4717 4718 // Do not change winding of faces when converting handedness. 4719 handedness_conversion_retain_winding: bool, 4720 4721 // Reverse winding of all faces. 4722 // If `handedness_conversion_retain_winding` is not specified, mirrored meshes 4723 // will retain their original winding. 4724 reverse_winding: bool, 4725 4726 // Apply an implicit root transformation to match axes. 4727 // Used if `ufbx_coordinate_axes_valid(target_axes)`. 4728 target_axes: Coordinate_Axes, 4729 4730 // Scale the scene so that one world-space unit is `target_unit_meters` meters. 4731 // By default units are not scaled. 4732 target_unit_meters: Real, 4733 4734 // Target space for camera. 4735 // By default FBX cameras point towards the positive X axis. 4736 // Used if `ufbx_coordinate_axes_valid(target_camera_axes)`. 4737 target_camera_axes: Coordinate_Axes, 4738 4739 // Target space for directed lights. 4740 // By default FBX lights point towards the negative Y axis. 4741 // Used if `ufbx_coordinate_axes_valid(target_light_axes)`. 4742 target_light_axes: Coordinate_Axes, 4743 4744 // Name for dummy geometry transform helper nodes. 4745 // See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`. 4746 geometry_transform_helper_name: String, 4747 4748 // Name for dummy scale helper nodes. 4749 // See `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`. 4750 scale_helper_name: String, 4751 4752 // Normalize vertex normals. 4753 normalize_normals: bool, 4754 4755 // Normalize tangents and bitangents. 4756 normalize_tangents: bool, 4757 4758 // Override for the root transform 4759 use_root_transform: bool, 4760 root_transform: Transform, 4761 4762 // Animation keyframe clamp threshold, only applies to specific interpolation modes. 4763 key_clamp_threshold: f64, 4764 4765 // Specify how to handle Unicode errors in strings. 4766 unicode_error_handling: Unicode_Error_Handling, 4767 4768 // Retain the 'W' component of mesh normal/tangent/bitangent. 4769 // See `ufbx_vertex_attrib.values_w`. 4770 retain_vertex_attrib_w: bool, 4771 4772 // Retain the raw document structure using `ufbx_dom_node`. 4773 retain_dom: bool, 4774 4775 // Force a specific file format instead of detecting it. 4776 file_format: File_Format, 4777 4778 // How far to read into the file to determine the file format. 4779 // Default: 16kB 4780 file_format_lookahead: c.size_t, 4781 4782 // Do not attempt to detect file format from file content. 4783 no_format_from_content: bool, 4784 4785 // Do not attempt to detect file format from filename extension. 4786 // ufbx primarily detects file format from the file header, 4787 // this is just used as a fallback. 4788 no_format_from_extension: bool, 4789 4790 // (.obj) Try to find .mtl file with matching filename as the .obj file. 4791 // Used if the file specified `mtllib` line is not found, eg. for a file called 4792 // `model.obj` that contains the line `usemtl materials.mtl`, ufbx would first 4793 // try to open `materials.mtl` and if that fails it tries to open `model.mtl`. 4794 obj_search_mtl_by_filename: bool, 4795 4796 // (.obj) Don't split geometry into meshes by object. 4797 obj_merge_objects: bool, 4798 4799 // (.obj) Don't split geometry into meshes by groups. 4800 obj_merge_groups: bool, 4801 4802 // (.obj) Force splitting groups even on object boundaries. 4803 obj_split_groups: bool, 4804 4805 // (.obj) Path to the .mtl file. 4806 // Use `length = SIZE_MAX` for NULL-terminated strings. 4807 // NOTE: This is used _instead_ of the one in the file even if not found 4808 // and sidesteps `load_external_files` as it's _explicitly_ requested. 4809 obj_mtl_path: String, 4810 4811 // (.obj) Data for the .mtl file. 4812 obj_mtl_data: Blob, 4813 4814 // The world unit in meters that .obj files are assumed to be in. 4815 // .obj files do not define the working units. By default the unit scale 4816 // is read as zero, and no unit conversion is performed. 4817 obj_unit_meters: Real, 4818 4819 // Coordinate space .obj files are assumed to be in. 4820 // .obj files do not define the coordinate space they use. By default no 4821 // coordinate space is assumed and no conversion is performed. 4822 obj_axes: Coordinate_Axes, 4823 _end_zero: u32, 4824 } 4825 4826 // Options for `ufbx_evaluate_scene()` 4827 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 4828 Evaluate_Opts :: struct { 4829 _begin_zero: u32, 4830 temp_allocator: Allocator_Opts, // < Allocator used during evaluation 4831 result_allocator: Allocator_Opts, // < Allocator used for the final scene 4832 evaluate_skinning: bool, // < Evaluate skinning (see ufbx_mesh.skinned_vertices) 4833 evaluate_caches: bool, // < Evaluate vertex caches (see ufbx_mesh.skinned_vertices) 4834 4835 // Evaluation flags. 4836 // See `ufbx_evaluate_flags` for information. 4837 evaluate_flags: u32, 4838 4839 // WARNING: Potentially unsafe! Try to open external files such as geometry caches 4840 load_external_files: bool, 4841 4842 // External file callbacks (defaults to stdio.h) 4843 open_file_cb: Open_File_Cb, 4844 _end_zero: u32, 4845 } 4846 4847 Const_Uint32_List :: struct { 4848 data: ^u32, 4849 count: c.size_t, 4850 } 4851 4852 Const_Real_List :: struct { 4853 data: ^Real, 4854 count: c.size_t, 4855 } 4856 4857 Prop_Override_Desc :: struct { 4858 // Element (`ufbx_element.element_id`) to override the property from 4859 element_id: u32, 4860 4861 // Property name to override. 4862 prop_name: String, 4863 4864 // Override value, use `value.x` for scalars. `value_int` is initialized 4865 // from `value.x` if zero so keep `value` zeroed even if you don't need it! 4866 value: Vec4, 4867 value_str: String, 4868 value_int: i64, 4869 } 4870 4871 Const_Prop_Override_Desc_List :: struct { 4872 data: ^Prop_Override_Desc, 4873 count: c.size_t, 4874 } 4875 4876 Const_Transform_Override_List :: struct { 4877 data: ^Transform_Override, 4878 count: c.size_t, 4879 } 4880 4881 Anim_Opts :: struct { 4882 _begin_zero: u32, 4883 4884 // Animation layers indices. 4885 // Corresponding to `ufbx_scene.anim_layers[]`, aka `ufbx_anim_layer.typed_id`. 4886 layer_ids: Const_Uint32_List, 4887 4888 // Override layer weights, parallel to `ufbx_anim_opts.layer_ids[]`. 4889 override_layer_weights: Const_Real_List, 4890 4891 // Property overrides. 4892 // These allow you to override FBX properties, such as 'UFBX_Lcl_Rotation`. 4893 prop_overrides: Const_Prop_Override_Desc_List, 4894 4895 // Transform overrides. 4896 // These allow you to override individual nodes' `ufbx_node.local_transform`. 4897 transform_overrides: Const_Transform_Override_List, 4898 4899 // Ignore connected properties 4900 ignore_connections: bool, 4901 result_allocator: Allocator_Opts, // < Allocator used to create the `ufbx_anim` 4902 _end_zero: u32, 4903 } 4904 4905 // Specifies how to handle stepped tangents. 4906 Bake_Step_Handling :: enum i32 { 4907 // One millisecond default step duration, with potential extra slack for converting to `float`. 4908 DEFAULT = 0, 4909 4910 // Use a custom interpolation duration for the constant step. 4911 // See `ufbx_bake_opts.step_custom_duration` and optionally `ufbx_bake_opts.step_custom_epsilon`. 4912 CUSTOM_DURATION = 1, 4913 4914 // Stepped keyframes are represented as keyframes at the exact same time. 4915 // Use flags `UFBX_BAKED_KEY_STEP_LEFT` and `UFBX_BAKED_KEY_STEP_RIGHT` to differentiate 4916 // between the primary key and edge limits. 4917 IDENTICAL_TIME = 2, 4918 4919 // Represent stepped keyframe times as the previous/next representable `double` value. 4920 // Using this and robust linear interpolation will handle stepped tangents correctly 4921 // without having to look at the key flags. 4922 // NOTE: Casting these values to `float` or otherwise modifying them can collapse 4923 // the keyframes to have the identical time. 4924 ADJACENT_DOUBLE = 3, 4925 4926 // Treat all stepped tangents as linearly interpolated. 4927 IGNORE = 4, 4928 } 4929 4930 BAKE_STEP_HANDLING_COUNT :: 5 4931 4932 Bake_Opts :: struct { 4933 _begin_zero: u32, 4934 temp_allocator: Allocator_Opts, // < Allocator used during loading 4935 result_allocator: Allocator_Opts, // < Allocator used for the final baked animation 4936 4937 // Move the keyframe times to start from zero regardless of the animation start time. 4938 // For example, for an animation spanning between frames [30, 60] will be moved to 4939 // [0, 30] in the baked animation. 4940 // NOTE: This is in general not equivalent to subtracting `ufbx_anim.time_begin` 4941 // from each keyframe, as this trimming is done exactly using internal FBX ticks. 4942 trim_start_time: bool, 4943 4944 // Samples per second to use for resampling non-linear animation. 4945 // Default: 30 4946 resample_rate: f64, 4947 4948 // Minimum sample rate to not resample. 4949 // Many exporters resample animation by default. To avoid double-resampling 4950 // keyframe rates higher or equal to this will not be resampled. 4951 // Default: 19.5 4952 minimum_sample_rate: f64, 4953 4954 // Maximum sample rate to use, this will remove keys if they are too close together. 4955 // Default: unlimited 4956 maximum_sample_rate: f64, 4957 4958 // Bake the raw versions of properties related to transforms. 4959 bake_transform_props: bool, 4960 4961 // Do not bake node transforms. 4962 skip_node_transforms: bool, 4963 4964 // Do not resample linear rotation keyframes. 4965 // FBX interpolates rotation in Euler angles, so this might cause incorrect interpolation. 4966 no_resample_rotation: bool, 4967 4968 // Ignore layer weight animation. 4969 ignore_layer_weight_animation: bool, 4970 4971 // Maximum number of segments to generate from one keyframe. 4972 // Default: 32 4973 max_keyframe_segments: c.size_t, 4974 4975 // How to handle stepped tangents. 4976 step_handling: Bake_Step_Handling, 4977 4978 // Interpolation duration used by `UFBX_BAKE_STEP_HANDLING_CUSTOM_DURATION`. 4979 step_custom_duration: f64, 4980 4981 // Interpolation epsilon used by `UFBX_BAKE_STEP_HANDLING_CUSTOM_DURATION`. 4982 // Defined as the minimum fractional decrease/increase in key time, ie. 4983 // `time / (1.0 + step_custom_epsilon)` and `time * (1.0 + step_custom_epsilon)`. 4984 step_custom_epsilon: f64, 4985 4986 // Flags passed to animation evaluation functions. 4987 // See `ufbx_evaluate_flags`. 4988 evaluate_flags: u32, 4989 4990 // Enable key reduction. 4991 key_reduction_enabled: bool, 4992 4993 // Enable key reduction for non-constant rotations. 4994 // Assumes rotations will be interpolated using a spherical linear interpolation at runtime. 4995 key_reduction_rotation: bool, 4996 4997 // Threshold for reducing keys for linear segments. 4998 // Default `0.000001`, use negative to disable. 4999 key_reduction_threshold: f64, 5000 5001 // Maximum passes over the keys to reduce. 5002 // Every pass can potentially halve the the amount of keys. 5003 // Default: `4` 5004 key_reduction_passes: c.size_t, 5005 _end_zero: u32, 5006 } 5007 5008 // Options for `ufbx_tessellate_nurbs_curve()` 5009 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5010 Tessellate_Curve_Opts :: struct { 5011 _begin_zero: u32, 5012 temp_allocator: Allocator_Opts, // < Allocator used during tessellation 5013 result_allocator: Allocator_Opts, // < Allocator used for the final line curve 5014 5015 // How many segments tessellate each span in `ufbx_nurbs_basis.spans`. 5016 span_subdivision: c.size_t, 5017 _end_zero: u32, 5018 } 5019 5020 // Options for `ufbx_tessellate_nurbs_surface()` 5021 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5022 Tessellate_Surface_Opts :: struct { 5023 _begin_zero: u32, 5024 temp_allocator: Allocator_Opts, // < Allocator used during tessellation 5025 result_allocator: Allocator_Opts, // < Allocator used for the final mesh 5026 5027 // How many segments tessellate each span in `ufbx_nurbs_basis.spans`. 5028 // NOTE: Default is `4`, _not_ `ufbx_nurbs_surface.span_subdivision_u/v` as that 5029 // would make it easy to create an FBX file with an absurdly high subdivision 5030 // rate (similar to mesh subdivision). Please enforce copy the value yourself 5031 // enforcing whatever limits you deem reasonable. 5032 span_subdivision_u: c.size_t, 5033 span_subdivision_v: c.size_t, 5034 5035 // Skip computing `ufbx_mesh.material_parts[]` 5036 skip_mesh_parts: bool, 5037 _end_zero: u32, 5038 } 5039 5040 // Options for `ufbx_subdivide_mesh()` 5041 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5042 Subdivide_Opts :: struct { 5043 _begin_zero: u32, 5044 temp_allocator: Allocator_Opts, // < Allocator used during subdivision 5045 result_allocator: Allocator_Opts, // < Allocator used for the final mesh 5046 boundary: Subdivision_Boundary, 5047 uv_boundary: Subdivision_Boundary, 5048 5049 // Do not generate normals 5050 ignore_normals: bool, 5051 5052 // Interpolate existing normals using the subdivision rules 5053 // instead of generating new normals 5054 interpolate_normals: bool, 5055 5056 // Subdivide also tangent attributes 5057 interpolate_tangents: bool, 5058 5059 // Map subdivided vertices into weighted original vertices. 5060 // NOTE: May be O(n^2) if `max_source_vertices` is not specified! 5061 evaluate_source_vertices: bool, 5062 5063 // Limit source vertices per subdivided vertex. 5064 max_source_vertices: c.size_t, 5065 5066 // Calculate bone influences over subdivided vertices (if applicable). 5067 // NOTE: May be O(n^2) if `max_skin_weights` is not specified! 5068 evaluate_skin_weights: bool, 5069 5070 // Limit bone influences per subdivided vertex. 5071 max_skin_weights: c.size_t, 5072 5073 // Index of the skin deformer to use for `evaluate_skin_weights`. 5074 skin_deformer_index: c.size_t, 5075 _end_zero: u32, 5076 } 5077 5078 // Options for `ufbx_load_geometry_cache()` 5079 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5080 Geometry_Cache_Opts :: struct { 5081 _begin_zero: u32, 5082 temp_allocator: Allocator_Opts, // < Allocator used during loading 5083 result_allocator: Allocator_Opts, // < Allocator used for the final scene 5084 5085 // External file callbacks (defaults to stdio.h) 5086 open_file_cb: Open_File_Cb, 5087 5088 // FPS value for converting frame times to seconds 5089 frames_per_second: f64, 5090 5091 // Axis to mirror the geometry by. 5092 mirror_axis: Mirror_Axis, 5093 5094 // Enable scaling `scale_factor` all geometry by. 5095 use_scale_factor: bool, 5096 5097 // Factor to scale the geometry by. 5098 scale_factor: Real, 5099 _end_zero: u32, 5100 } 5101 5102 // Options for `ufbx_read_geometry_cache_TYPE()` 5103 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5104 Geometry_Cache_Data_Opts :: struct { 5105 _begin_zero: u32, 5106 5107 // External file callbacks (defaults to stdio.h) 5108 open_file_cb: Open_File_Cb, 5109 additive: bool, 5110 use_weight: bool, 5111 weight: Real, 5112 5113 // Ignore scene transform. 5114 ignore_transform: bool, 5115 _end_zero: u32, 5116 } 5117 5118 Panic :: struct { 5119 did_panic: bool, 5120 message_length: c.size_t, 5121 message: [128]i8, 5122 } 5123 5124 Transform_Flag :: enum i32 { 5125 // Ignore parent scale helper. 5126 IGNORE_SCALE_HELPER = 0, 5127 5128 // Ignore componentwise scale. 5129 // Note that if you don't specify this, ufbx will have to potentially 5130 // evaluate the entire parent chain in the worst case. 5131 IGNORE_COMPONENTWISE_SCALE = 1, 5132 5133 // Require explicit components 5134 EXPLICIT_INCLUDES = 2, 5135 5136 // If `UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES`: Evaluate `ufbx_transform.translation`. 5137 INCLUDE_TRANSLATION = 4, 5138 5139 // If `UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES`: Evaluate `ufbx_transform.rotation`. 5140 INCLUDE_ROTATION = 5, 5141 5142 // If `UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES`: Evaluate `ufbx_transform.scale`. 5143 INCLUDE_SCALE = 6, 5144 5145 // Do not extrapolate keyframes. 5146 // See `UFBX_EVALUATE_FLAG_NO_EXTRAPOLATION`. 5147 NO_EXTRAPOLATION = 7, 5148 } 5149 5150 // Flags to control `ufbx_evaluate_transform_flags()`. 5151 Transform_Flags :: bit_set[Transform_Flag; i32] 5152 5153 // bindgen-enable 5154 5155 // -- Properties 5156 5157 // Names of common properties in `ufbx_props`. 5158 // Some of these differ from ufbx interpretations. 5159 5160 // Local translation. 5161 // Used by: `ufbx_node` 5162 Lcl_Translation :: "Lcl Translation" 5163 5164 // Local rotation expressed in Euler degrees. 5165 // Used by: `ufbx_node` 5166 // The rotation order is defined by the `UFBX_RotationOrder` property. 5167 Lcl_Rotation :: "Lcl Rotation" 5168 5169 // Local scaling factor, 3D vector. 5170 // Used by: `ufbx_node` 5171 Lcl_Scaling :: "Lcl Scaling" 5172 5173 // Euler rotation interpretation, used by `UFBX_Lcl_Rotation`. 5174 // Used by: `ufbx_node`, enum value `ufbx_rotation_order`. 5175 RotationOrder :: "RotationOrder" 5176 5177 // Scaling pivot: point around which scaling is performed. 5178 // Used by: `ufbx_node`. 5179 ScalingPivot :: "ScalingPivot" 5180 5181 // Scaling pivot: point around which rotation is performed. 5182 // Used by: `ufbx_node`. 5183 RotationPivot :: "RotationPivot" 5184 5185 // Scaling offset: translation added after scaling is performed. 5186 // Used by: `ufbx_node`. 5187 ScalingOffset :: "ScalingOffset" 5188 5189 // Rotation offset: translation added after rotation is performed. 5190 // Used by: `ufbx_node`. 5191 RotationOffset :: "RotationOffset" 5192 5193 // Pre-rotation: Rotation applied _after_ `UFBX_Lcl_Rotation`. 5194 // Used by: `ufbx_node`. 5195 // Affected by `UFBX_RotationPivot` but not `UFBX_RotationOrder`. 5196 PreRotation :: "PreRotation" 5197 5198 // Post-rotation: Rotation applied _before_ `UFBX_Lcl_Rotation`. 5199 // Used by: `ufbx_node`. 5200 // Affected by `UFBX_RotationPivot` but not `UFBX_RotationOrder`. 5201 PostRotation :: "PostRotation" 5202 5203 // Controls whether the node should be displayed or not. 5204 // Used by: `ufbx_node`. 5205 Visibility :: "Visibility" 5206 5207 // Weight of an animation layer in percentage (100.0 being full). 5208 // Used by: `ufbx_anim_layer`. 5209 Weight :: "Weight" 5210 5211 // Blend shape deformation weight (100.0 being full). 5212 // Used by: `ufbx_blend_channel`. 5213 DeformPercent :: "DeformPercent" 5214 5215 @(default_calling_convention="c", link_prefix="ufbx_") 5216 foreign lib { 5217 // Practically always `true` (see below), if not you need to be careful with threads. 5218 // 5219 // Guaranteed to be `true` in _any_ of the following conditions: 5220 // - ufbx.c has been compiled using: GCC / Clang / MSVC / ICC / EMCC / TCC 5221 // - ufbx.c has been compiled as C++11 or later 5222 // - ufbx.c has been compiled as C11 or later with `<stdatomic.h>` support 5223 // 5224 // If `false` you can't call the following functions concurrently: 5225 // ufbx_evaluate_scene() 5226 // ufbx_free_scene() 5227 // ufbx_subdivide_mesh() 5228 // ufbx_tessellate_nurbs_surface() 5229 // ufbx_free_mesh() 5230 is_thread_safe :: proc() -> bool --- 5231 5232 // Load a scene from a `size` byte memory buffer at `data` 5233 load_memory :: proc(data: rawptr, data_size: c.size_t, opts: ^Load_Opts, error: ^Error) -> ^Scene --- 5234 5235 // Load a scene by opening a file named `filename` 5236 load_file :: proc(filename: cstring, opts: ^Load_Opts, error: ^Error) -> ^Scene --- 5237 load_file_len :: proc(filename: cstring, filename_len: c.size_t, opts: ^Load_Opts, error: ^Error) -> ^Scene --- 5238 5239 // Load a scene by reading from an `FILE *file` stream 5240 // NOTE: `file` is passed as a `void` pointer to avoid including <stdio.h> 5241 load_stdio :: proc(file: rawptr, opts: ^Load_Opts, error: ^Error) -> ^Scene --- 5242 5243 // Load a scene by reading from an `FILE *file` stream with a prefix 5244 // NOTE: `file` is passed as a `void` pointer to avoid including <stdio.h> 5245 load_stdio_prefix :: proc(file: rawptr, prefix: rawptr, prefix_size: c.size_t, opts: ^Load_Opts, error: ^Error) -> ^Scene --- 5246 5247 // Load a scene from a user-specified stream 5248 load_stream :: proc(stream: ^Stream, opts: ^Load_Opts, error: ^Error) -> ^Scene --- 5249 5250 // Load a scene from a user-specified stream with a prefix 5251 load_stream_prefix :: proc(stream: ^Stream, prefix: rawptr, prefix_size: c.size_t, opts: ^Load_Opts, error: ^Error) -> ^Scene --- 5252 5253 // Free a previously loaded or evaluated scene 5254 free_scene :: proc(scene: ^Scene) --- 5255 5256 // Increment `scene` refcount 5257 retain_scene :: proc(scene: ^Scene) --- 5258 5259 // Format a textual description of `error`. 5260 // Always produces a NULL-terminated string to `char dst[dst_size]`, truncating if 5261 // necessary. Returns the number of characters written not including the NULL terminator. 5262 format_error :: proc(dst: cstring, dst_size: c.size_t, error: ^Error) -> c.size_t --- 5263 5264 // Find a property `name` from `props`, returns `NULL` if not found. 5265 // Searches through `ufbx_props.defaults` as well. 5266 find_prop_len :: proc(props: ^Props, name: cstring, name_len: c.size_t) -> ^Prop --- 5267 find_prop :: proc(props: ^Props, name: cstring) -> ^Prop --- 5268 5269 // Utility functions for finding the value of a property, returns `def` if not found. 5270 // NOTE: For `ufbx_string` you need to ensure the lifetime of the default is 5271 // sufficient as no copy is made. 5272 find_real_len :: proc(props: ^Props, name: cstring, name_len: c.size_t, def: Real) -> Real --- 5273 find_real :: proc(props: ^Props, name: cstring, def: Real) -> Real --- 5274 find_vec3_len :: proc(props: ^Props, name: cstring, name_len: c.size_t, def: Vec3) -> Vec3 --- 5275 find_vec3 :: proc(props: ^Props, name: cstring, def: Vec3) -> Vec3 --- 5276 find_int_len :: proc(props: ^Props, name: cstring, name_len: c.size_t, def: i64) -> i64 --- 5277 find_int :: proc(props: ^Props, name: cstring, def: i64) -> i64 --- 5278 find_bool_len :: proc(props: ^Props, name: cstring, name_len: c.size_t, def: bool) -> bool --- 5279 find_bool :: proc(props: ^Props, name: cstring, def: bool) -> bool --- 5280 find_string_len :: proc(props: ^Props, name: cstring, name_len: c.size_t, def: String) -> String --- 5281 find_string :: proc(props: ^Props, name: cstring, def: String) -> String --- 5282 find_blob_len :: proc(props: ^Props, name: cstring, name_len: c.size_t, def: Blob) -> Blob --- 5283 find_blob :: proc(props: ^Props, name: cstring, def: Blob) -> Blob --- 5284 5285 // Find property in `props` with concatenated `parts[num_parts]`. 5286 find_prop_concat :: proc(props: ^Props, parts: ^String, num_parts: c.size_t) -> ^Prop --- 5287 5288 // Get an element connected to a property. 5289 get_prop_element :: proc(element: ^Element, prop: ^Prop, type: Element_Type) -> ^Element --- 5290 5291 // Find an element connected to a property by name. 5292 find_prop_element_len :: proc(element: ^Element, name: cstring, name_len: c.size_t, type: Element_Type) -> ^Element --- 5293 find_prop_element :: proc(element: ^Element, name: cstring, type: Element_Type) -> ^Element --- 5294 5295 // Find any element of type `type` in `scene` by `name`. 5296 // For example if you want to find `ufbx_material` named `Mat`: 5297 // (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Mat"); 5298 find_element_len :: proc(scene: ^Scene, type: Element_Type, name: cstring, name_len: c.size_t) -> ^Element --- 5299 find_element :: proc(scene: ^Scene, type: Element_Type, name: cstring) -> ^Element --- 5300 5301 // Find node in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_NODE)`). 5302 find_node_len :: proc(scene: ^Scene, name: cstring, name_len: c.size_t) -> ^Node --- 5303 find_node :: proc(scene: ^Scene, name: cstring) -> ^Node --- 5304 5305 // Find an animation stack in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_ANIM_STACK)`) 5306 find_anim_stack_len :: proc(scene: ^Scene, name: cstring, name_len: c.size_t) -> ^Anim_Stack --- 5307 find_anim_stack :: proc(scene: ^Scene, name: cstring) -> ^Anim_Stack --- 5308 5309 // Find a material in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_MATERIAL)`). 5310 find_material_len :: proc(scene: ^Scene, name: cstring, name_len: c.size_t) -> ^Material --- 5311 find_material :: proc(scene: ^Scene, name: cstring) -> ^Material --- 5312 5313 // Find a single animated property `prop` of `element` in `layer`. 5314 // Returns `NULL` if not found. 5315 find_anim_prop_len :: proc(layer: ^Anim_Layer, element: ^Element, prop: cstring, prop_len: c.size_t) -> ^Anim_Prop --- 5316 find_anim_prop :: proc(layer: ^Anim_Layer, element: ^Element, prop: cstring) -> ^Anim_Prop --- 5317 5318 // Find all animated properties of `element` in `layer`. 5319 find_anim_props :: proc(layer: ^Anim_Layer, element: ^Element) -> Anim_Prop_List --- 5320 5321 // Get a matrix that transforms normals in the same way as Autodesk software. 5322 // NOTE: The resulting normals are slightly incorrect as this function deliberately 5323 // inverts geometric transformation wrong. For better results use 5324 // `ufbx_matrix_for_normals(&node->geometry_to_world)`. 5325 get_compatible_matrix_for_normals :: proc(node: ^Node) -> Matrix --- 5326 5327 // Decompress a DEFLATE compressed buffer. 5328 // Returns the decompressed size or a negative error code (see source for details). 5329 // NOTE: You must supply a valid `retain` with `ufbx_inflate_retain.initialized == false` 5330 // but the rest can be uninitialized. 5331 inflate :: proc(dst: rawptr, dst_size: c.size_t, input: ^Inflate_Input, retain: ^Inflate_Retain) -> c.ptrdiff_t --- 5332 5333 // Same as `ufbx_open_file()` but compatible with the callback in `ufbx_open_file_fn`. 5334 // The `user` parameter is actually not used here. 5335 default_open_file :: proc(user: rawptr, stream: ^Stream, path: cstring, path_len: c.size_t, info: ^Open_File_Info) -> bool --- 5336 5337 // Open a `ufbx_stream` from a file. 5338 // Use `path_len == SIZE_MAX` for NULL terminated string. 5339 open_file :: proc(stream: ^Stream, path: cstring, path_len: c.size_t, opts: ^Open_File_Opts, error: ^Error) -> bool --- 5340 open_file_ctx :: proc(stream: ^Stream, ctx: Open_File_Context, path: cstring, path_len: c.size_t, opts: ^Open_File_Opts, error: ^Error) -> bool --- 5341 5342 // NOTE: Uses the default ufbx allocator! 5343 open_memory :: proc(stream: ^Stream, data: rawptr, data_size: c.size_t, opts: ^Open_Memory_Opts, error: ^Error) -> bool --- 5344 open_memory_ctx :: proc(stream: ^Stream, ctx: Open_File_Context, data: rawptr, data_size: c.size_t, opts: ^Open_Memory_Opts, error: ^Error) -> bool --- 5345 5346 // Evaluate a single animation `curve` at a `time`. 5347 // Returns `default_value` only if `curve == NULL` or it has no keyframes. 5348 evaluate_curve :: proc(curve: ^Anim_Curve, time: f64, default_value: Real) -> Real --- 5349 evaluate_curve_flags :: proc(curve: ^Anim_Curve, time: f64, default_value: Real, flags: u32) -> Real --- 5350 5351 // Evaluate a value from bundled animation curves. 5352 evaluate_anim_value_real :: proc(anim_value: ^Anim_Value, time: f64) -> Real --- 5353 evaluate_anim_value_vec3 :: proc(anim_value: ^Anim_Value, time: f64) -> Vec3 --- 5354 evaluate_anim_value_real_flags :: proc(anim_value: ^Anim_Value, time: f64, flags: u32) -> Real --- 5355 evaluate_anim_value_vec3_flags :: proc(anim_value: ^Anim_Value, time: f64, flags: u32) -> Vec3 --- 5356 5357 // Evaluate an animated property `name` from `element` at `time`. 5358 // NOTE: If the property is not found it will have the flag `UFBX_PROP_FLAG_NOT_FOUND`. 5359 evaluate_prop_len :: proc(anim: ^Anim, element: ^Element, name: cstring, name_len: c.size_t, time: f64) -> Prop --- 5360 evaluate_prop :: proc(anim: ^Anim, element: ^Element, name: cstring, time: f64) -> Prop --- 5361 evaluate_prop_len_flags :: proc(anim: ^Anim, element: ^Element, name: cstring, name_len: c.size_t, time: f64, flags: u32) -> Prop --- 5362 evaluate_prop_flags :: proc(anim: ^Anim, element: ^Element, name: cstring, time: f64, flags: u32) -> Prop --- 5363 5364 // Evaluate all _animated_ properties of `element`. 5365 // HINT: This function returns an `ufbx_props` structure with the original properties as 5366 // `ufbx_props.defaults`. This lets you use `ufbx_find_prop/value()` for the results. 5367 evaluate_props :: proc(anim: ^Anim, element: ^Element, time: f64, buffer: ^Prop, buffer_size: c.size_t) -> Props --- 5368 evaluate_props_flags :: proc(anim: ^Anim, element: ^Element, time: f64, buffer: ^Prop, buffer_size: c.size_t, flags: u32) -> Props --- 5369 5370 // Evaluate the animated transform of a node given a time. 5371 // The returned transform is the local transform of the node (ie. relative to the parent), 5372 // comparable to `ufbx_node.local_transform`. 5373 evaluate_transform :: proc(anim: ^Anim, node: ^Node, time: f64) -> Transform --- 5374 evaluate_transform_flags :: proc(anim: ^Anim, node: ^Node, time: f64, flags: u32) -> Transform --- 5375 5376 // Evaluate the blend shape weight of a blend channel. 5377 // NOTE: Return value uses `1.0` for full weight, instead of `100.0` that the internal property `UFBX_Weight` uses. 5378 evaluate_blend_weight :: proc(anim: ^Anim, channel: ^Blend_Channel, time: f64) -> Real --- 5379 evaluate_blend_weight_flags :: proc(anim: ^Anim, channel: ^Blend_Channel, time: f64, flags: u32) -> Real --- 5380 5381 // Evaluate the whole `scene` at a specific `time` in the animation `anim`. 5382 // The returned scene behaves as if it had been exported at a specific time 5383 // in the specified animation, except that animated elements' properties contain 5384 // only the animated values, the original ones are in `props->defaults`. 5385 // 5386 // NOTE: The returned scene refers to the original `scene` so the original 5387 // scene cannot be freed until all evaluated scenes are freed. 5388 evaluate_scene :: proc(scene: ^Scene, anim: ^Anim, time: f64, opts: ^Evaluate_Opts, error: ^Error) -> ^Scene --- 5389 5390 // Create a custom animation descriptor. 5391 // `ufbx_anim_opts` is used to specify animation layers and weights. 5392 // HINT: You can also leave `ufbx_anim_opts.layer_ids[]` empty and only specify 5393 // overrides to evaluate the scene with different properties or local transforms. 5394 create_anim :: proc(scene: ^Scene, opts: ^Anim_Opts, error: ^Error) -> ^Anim --- 5395 5396 // Free an animation returned by `ufbx_create_anim()`. 5397 free_anim :: proc(anim: ^Anim) --- 5398 5399 // Increase the animation reference count. 5400 retain_anim :: proc(anim: ^Anim) --- 5401 5402 // "Bake" an animation to linearly interpolated keyframes. 5403 // Composites the FBX transformation chain into quaternion rotations. 5404 bake_anim :: proc(scene: ^Scene, anim: ^Anim, opts: ^Bake_Opts, error: ^Error) -> ^Baked_Anim --- 5405 retain_baked_anim :: proc(bake: ^Baked_Anim) --- 5406 free_baked_anim :: proc(bake: ^Baked_Anim) --- 5407 find_baked_node_by_typed_id :: proc(bake: ^Baked_Anim, typed_id: u32) -> ^Baked_Node --- 5408 find_baked_node :: proc(bake: ^Baked_Anim, node: ^Node) -> ^Baked_Node --- 5409 find_baked_element_by_element_id :: proc(bake: ^Baked_Anim, element_id: u32) -> ^Baked_Element --- 5410 find_baked_element :: proc(bake: ^Baked_Anim, element: ^Element) -> ^Baked_Element --- 5411 5412 // Evaluate baked animation `keyframes` at `time`. 5413 // Internally linearly interpolates between two adjacent keyframes. 5414 // Handles stepped tangents cleanly, which is not strictly necessary for custom interpolation. 5415 evaluate_baked_vec3 :: proc(keyframes: Baked_Vec3_List, time: f64) -> Vec3 --- 5416 5417 // Evaluate baked animation `keyframes` at `time`. 5418 // Internally spherically interpolates (`ufbx_quat_slerp()`) between two adjacent keyframes. 5419 // Handles stepped tangents cleanly, which is not strictly necessary for custom interpolation. 5420 evaluate_baked_quat :: proc(keyframes: Baked_Quat_List, time: f64) -> Quat --- 5421 5422 // Retrieve the bone pose for `node`. 5423 // Returns `NULL` if the pose does not contain `node`. 5424 get_bone_pose :: proc(pose: ^Pose, node: ^Node) -> ^Bone_Pose --- 5425 5426 // Find a texture for a given material FBX property. 5427 find_prop_texture_len :: proc(material: ^Material, name: cstring, name_len: c.size_t) -> ^Texture --- 5428 find_prop_texture :: proc(material: ^Material, name: cstring) -> ^Texture --- 5429 5430 // Find a texture for a given shader property. 5431 find_shader_prop_len :: proc(shader: ^Shader, name: cstring, name_len: c.size_t) -> String --- 5432 find_shader_prop :: proc(shader: ^Shader, name: cstring) -> String --- 5433 5434 // Map from a shader property to material property. 5435 find_shader_prop_bindings_len :: proc(shader: ^Shader, name: cstring, name_len: c.size_t) -> Shader_Prop_Binding_List --- 5436 find_shader_prop_bindings :: proc(shader: ^Shader, name: cstring) -> Shader_Prop_Binding_List --- 5437 5438 // Find an input in a shader texture. 5439 find_shader_texture_input_len :: proc(shader: ^Shader_Texture, name: cstring, name_len: c.size_t) -> ^Shader_Texture_Input --- 5440 find_shader_texture_input :: proc(shader: ^Shader_Texture, name: cstring) -> ^Shader_Texture_Input --- 5441 5442 // Returns `true` if `axes` forms a valid coordinate space. 5443 coordinate_axes_valid :: proc(axes: Coordinate_Axes) -> bool --- 5444 5445 // Vector math utility functions. 5446 vec3_normalize :: proc(v: Vec3) -> Vec3 --- 5447 5448 // Quaternion math utility functions. 5449 quat_dot :: proc(a: Quat, b: Quat) -> Real --- 5450 quat_mul :: proc(a: Quat, b: Quat) -> Quat --- 5451 quat_normalize :: proc(q: Quat) -> Quat --- 5452 quat_fix_antipodal :: proc(q: Quat, reference: Quat) -> Quat --- 5453 quat_slerp :: proc(a: Quat, b: Quat, t: Real) -> Quat --- 5454 quat_rotate_vec3 :: proc(q: Quat, v: Vec3) -> Vec3 --- 5455 quat_to_euler :: proc(q: Quat, order: Rotation_Order) -> Vec3 --- 5456 euler_to_quat :: proc(v: Vec3, order: Rotation_Order) -> Quat --- 5457 5458 // Matrix math utility functions. 5459 matrix_mul :: proc(a: ^Matrix, b: ^Matrix) -> Matrix --- 5460 matrix_determinant :: proc(m: ^Matrix) -> Real --- 5461 matrix_invert :: proc(m: ^Matrix) -> Matrix --- 5462 5463 // Get a matrix that can be used to transform geometry normals. 5464 // NOTE: You must normalize the normals after transforming them with this matrix, 5465 // eg. using `ufbx_vec3_normalize()`. 5466 // NOTE: This function flips the normals if the determinant is negative. 5467 matrix_for_normals :: proc(m: ^Matrix) -> Matrix --- 5468 5469 // Matrix transformation utilities. 5470 transform_position :: proc(m: ^Matrix, v: Vec3) -> Vec3 --- 5471 transform_direction :: proc(m: ^Matrix, v: Vec3) -> Vec3 --- 5472 5473 // Conversions between `ufbx_matrix` and `ufbx_transform`. 5474 transform_to_matrix :: proc(t: ^Transform) -> Matrix --- 5475 matrix_to_transform :: proc(m: ^Matrix) -> Transform --- 5476 5477 // Get a matrix representing the deformation for a single vertex. 5478 // Returns `fallback` if the vertex is not skinned. 5479 catch_get_skin_vertex_matrix :: proc(panic: ^Panic, skin: ^Skin_Deformer, vertex: c.size_t, fallback: ^Matrix) -> Matrix --- 5480 5481 // Resolve the index into `ufbx_blend_shape.position_offsets[]` given a vertex. 5482 // Returns `UFBX_NO_INDEX` if the vertex is not included in the blend shape. 5483 get_blend_shape_offset_index :: proc(shape: ^Blend_Shape, vertex: c.size_t) -> u32 --- 5484 5485 // Get the offset for a given vertex in the blend shape. 5486 // Returns `ufbx_zero_vec3` if the vertex is not a included in the blend shape. 5487 get_blend_shape_vertex_offset :: proc(shape: ^Blend_Shape, vertex: c.size_t) -> Vec3 --- 5488 5489 // Get the _current_ blend offset given a blend deformer. 5490 // NOTE: This depends on the current animated blend weight of the deformer. 5491 get_blend_vertex_offset :: proc(blend: ^Blend_Deformer, vertex: c.size_t) -> Vec3 --- 5492 5493 // Apply the blend shape with `weight` to given vertices. 5494 add_blend_shape_vertex_offsets :: proc(shape: ^Blend_Shape, vertices: ^Vec3, num_vertices: c.size_t, weight: Real) --- 5495 5496 // Apply the blend deformer with `weight` to given vertices. 5497 // NOTE: This depends on the current animated blend weight of the deformer. 5498 add_blend_vertex_offsets :: proc(blend: ^Blend_Deformer, vertices: ^Vec3, num_vertices: c.size_t, weight: Real) --- 5499 5500 // Low-level utility to evaluate NURBS the basis functions. 5501 evaluate_nurbs_basis :: proc(basis: ^Nurbs_Basis, u: Real, weights: ^Real, num_weights: c.size_t, derivatives: ^Real, num_derivatives: c.size_t) -> c.size_t --- 5502 5503 // Evaluate a point on a NURBS curve given the parameter `u`. 5504 evaluate_nurbs_curve :: proc(curve: ^Nurbs_Curve, u: Real) -> Curve_Point --- 5505 5506 // Evaluate a point on a NURBS surface given the parameter `u` and `v`. 5507 evaluate_nurbs_surface :: proc(surface: ^Nurbs_Surface, u: Real, v: Real) -> Surface_Point --- 5508 5509 // Tessellate a NURBS curve into a polyline. 5510 tessellate_nurbs_curve :: proc(curve: ^Nurbs_Curve, opts: ^Tessellate_Curve_Opts, error: ^Error) -> ^Line_Curve --- 5511 5512 // Tessellate a NURBS surface into a mesh. 5513 tessellate_nurbs_surface :: proc(surface: ^Nurbs_Surface, opts: ^Tessellate_Surface_Opts, error: ^Error) -> ^Mesh --- 5514 5515 // Free a line returned by `ufbx_tessellate_nurbs_curve()`. 5516 free_line_curve :: proc(curve: ^Line_Curve) --- 5517 5518 // Increase the refcount of the line. 5519 retain_line_curve :: proc(curve: ^Line_Curve) --- 5520 5521 // Find the face that contains a given `index`. 5522 // Returns `UFBX_NO_INDEX` if out of bounds. 5523 find_face_index :: proc(mesh: ^Mesh, index: c.size_t) -> u32 --- 5524 5525 // Triangulate a mesh face, returning the number of triangles. 5526 // NOTE: You need to space for `(face.num_indices - 2) * 3 - 1` indices! 5527 // HINT: Using `ufbx_mesh.max_face_triangles * 3` is always safe. 5528 catch_triangulate_face :: proc(panic: ^Panic, indices: ^u32, num_indices: c.size_t, mesh: ^Mesh, face: Face) -> u32 --- 5529 triangulate_face :: proc(indices: ^u32, num_indices: c.size_t, mesh: ^Mesh, face: Face) -> u32 --- 5530 5531 // Generate the half-edge representation of `mesh` to `topo[mesh->num_indices]` 5532 catch_compute_topology :: proc(panic: ^Panic, mesh: ^Mesh, topo: ^Topo_Edge, num_topo: c.size_t) --- 5533 compute_topology :: proc(mesh: ^Mesh, topo: ^Topo_Edge, num_topo: c.size_t) --- 5534 5535 // Get the next half-edge in `topo`. 5536 catch_topo_next_vertex_edge :: proc(panic: ^Panic, topo: ^Topo_Edge, num_topo: c.size_t, index: u32) -> u32 --- 5537 topo_next_vertex_edge :: proc(topo: ^Topo_Edge, num_topo: c.size_t, index: u32) -> u32 --- 5538 5539 // Get the previous half-edge in `topo`. 5540 catch_topo_prev_vertex_edge :: proc(panic: ^Panic, topo: ^Topo_Edge, num_topo: c.size_t, index: u32) -> u32 --- 5541 topo_prev_vertex_edge :: proc(topo: ^Topo_Edge, num_topo: c.size_t, index: u32) -> u32 --- 5542 5543 // Calculate a normal for a given face. 5544 // The returned normal is weighted by face area. 5545 catch_get_weighted_face_normal :: proc(panic: ^Panic, positions: ^Vertex_Vec3, face: Face) -> Vec3 --- 5546 get_weighted_face_normal :: proc(positions: ^Vertex_Vec3, face: Face) -> Vec3 --- 5547 5548 // Generate indices for normals from the topology. 5549 // Respects smoothing groups. 5550 catch_generate_normal_mapping :: proc(panic: ^Panic, mesh: ^Mesh, topo: ^Topo_Edge, num_topo: c.size_t, normal_indices: ^u32, num_normal_indices: c.size_t, assume_smooth: bool) -> c.size_t --- 5551 generate_normal_mapping :: proc(mesh: ^Mesh, topo: ^Topo_Edge, num_topo: c.size_t, normal_indices: ^u32, num_normal_indices: c.size_t, assume_smooth: bool) -> c.size_t --- 5552 5553 // Compute normals given normal indices. 5554 // You can use `ufbx_generate_normal_mapping()` to generate the normal indices. 5555 catch_compute_normals :: proc(panic: ^Panic, mesh: ^Mesh, positions: ^Vertex_Vec3, normal_indices: ^u32, num_normal_indices: c.size_t, normals: ^Vec3, num_normals: c.size_t) --- 5556 compute_normals :: proc(mesh: ^Mesh, positions: ^Vertex_Vec3, normal_indices: ^u32, num_normal_indices: c.size_t, normals: ^Vec3, num_normals: c.size_t) --- 5557 5558 // Subdivide a mesh using the Catmull-Clark subdivision `level` times. 5559 subdivide_mesh :: proc(mesh: ^Mesh, level: c.size_t, opts: ^Subdivide_Opts, error: ^Error) -> ^Mesh --- 5560 5561 // Free a mesh returned from `ufbx_subdivide_mesh()` or `ufbx_tessellate_nurbs_surface()`. 5562 free_mesh :: proc(mesh: ^Mesh) --- 5563 5564 // Increase the mesh reference count. 5565 retain_mesh :: proc(mesh: ^Mesh) --- 5566 5567 // Load geometry cache information from a file. 5568 // As geometry caches can be massive, this does not actually read the data, but 5569 // only seeks through the files to form the metadata. 5570 load_geometry_cache :: proc(filename: cstring, opts: ^Geometry_Cache_Opts, error: ^Error) -> ^Geometry_Cache --- 5571 load_geometry_cache_len :: proc(filename: cstring, filename_len: c.size_t, opts: ^Geometry_Cache_Opts, error: ^Error) -> ^Geometry_Cache --- 5572 5573 // Free a geometry cache returned from `ufbx_load_geometry_cache()`. 5574 free_geometry_cache :: proc(cache: ^Geometry_Cache) --- 5575 5576 // Increase the geometry cache reference count. 5577 retain_geometry_cache :: proc(cache: ^Geometry_Cache) --- 5578 5579 // Read a frame from a geometry cache. 5580 read_geometry_cache_real :: proc(frame: ^Cache_Frame, data: ^Real, num_data: c.size_t, opts: ^Geometry_Cache_Data_Opts) -> c.size_t --- 5581 read_geometry_cache_vec3 :: proc(frame: ^Cache_Frame, data: ^Vec3, num_data: c.size_t, opts: ^Geometry_Cache_Data_Opts) -> c.size_t --- 5582 5583 // Sample the a geometry cache channel, linearly blending between adjacent frames. 5584 sample_geometry_cache_real :: proc(channel: ^Cache_Channel, time: f64, data: ^Real, num_data: c.size_t, opts: ^Geometry_Cache_Data_Opts) -> c.size_t --- 5585 sample_geometry_cache_vec3 :: proc(channel: ^Cache_Channel, time: f64, data: ^Vec3, num_data: c.size_t, opts: ^Geometry_Cache_Data_Opts) -> c.size_t --- 5586 5587 // Find a DOM node given a name. 5588 dom_find_len :: proc(parent: ^Dom_Node, name: cstring, name_len: c.size_t) -> ^Dom_Node --- 5589 dom_find :: proc(parent: ^Dom_Node, name: cstring) -> ^Dom_Node --- 5590 5591 // Generate an index buffer for a flat vertex buffer. 5592 // `streams` specifies one or more vertex data arrays, each stream must contain `num_indices` vertices. 5593 // This function compacts the data within `streams` in-place, writing the deduplicated indices to `indices`. 5594 generate_indices :: proc(streams: [^]Vertex_Stream, num_streams: c.size_t, indices: ^u32, num_indices: c.size_t, allocator: ^Allocator_Opts, error: ^Error) -> c.size_t --- 5595 5596 // Run a single thread pool task. 5597 // See `ufbx_thread_pool_run_fn` for more information. 5598 thread_pool_run_task :: proc(ctx: Thread_Pool_Context, index: u32) --- 5599 5600 // Get or set an arbitrary user pointer for the thread pool context. 5601 // `ufbx_thread_pool_get_user_ptr()` returns `NULL` if unset. 5602 thread_pool_set_user_ptr :: proc(ctx: Thread_Pool_Context, user_ptr: rawptr) --- 5603 thread_pool_get_user_ptr :: proc(ctx: Thread_Pool_Context) -> rawptr --- 5604 5605 // Utility functions for reading geometry data for a single index. 5606 catch_get_vertex_real :: proc(panic: ^Panic, v: ^Vertex_Real, index: c.size_t) -> Real --- 5607 catch_get_vertex_vec2 :: proc(panic: ^Panic, v: ^Vertex_Vec2, index: c.size_t) -> Vec2 --- 5608 catch_get_vertex_vec3 :: proc(panic: ^Panic, v: ^Vertex_Vec3, index: c.size_t) -> Vec3 --- 5609 catch_get_vertex_vec4 :: proc(panic: ^Panic, v: ^Vertex_Vec4, index: c.size_t) -> Vec4 --- 5610 catch_get_vertex_w_vec3 :: proc(panic: ^Panic, v: ^Vertex_Vec3, index: c.size_t) -> Real --- 5611 5612 // Functions for converting an untyped `ufbx_element` to a concrete type. 5613 // Returns `NULL` if the element is not that type. 5614 as_unknown :: proc(element: ^Element) -> ^Unknown --- 5615 as_node :: proc(element: ^Element) -> ^Node --- 5616 as_mesh :: proc(element: ^Element) -> ^Mesh --- 5617 as_light :: proc(element: ^Element) -> ^Light --- 5618 as_camera :: proc(element: ^Element) -> ^Camera --- 5619 as_bone :: proc(element: ^Element) -> ^Bone --- 5620 as_empty :: proc(element: ^Element) -> ^Empty --- 5621 as_line_curve :: proc(element: ^Element) -> ^Line_Curve --- 5622 as_nurbs_curve :: proc(element: ^Element) -> ^Nurbs_Curve --- 5623 as_nurbs_surface :: proc(element: ^Element) -> ^Nurbs_Surface --- 5624 as_nurbs_trim_surface :: proc(element: ^Element) -> ^Nurbs_Trim_Surface --- 5625 as_nurbs_trim_boundary :: proc(element: ^Element) -> ^Nurbs_Trim_Boundary --- 5626 as_procedural_geometry :: proc(element: ^Element) -> ^Procedural_Geometry --- 5627 as_stereo_camera :: proc(element: ^Element) -> ^Stereo_Camera --- 5628 as_camera_switcher :: proc(element: ^Element) -> ^Camera_Switcher --- 5629 as_marker :: proc(element: ^Element) -> ^Marker --- 5630 as_lod_group :: proc(element: ^Element) -> ^Lod_Group --- 5631 as_skin_deformer :: proc(element: ^Element) -> ^Skin_Deformer --- 5632 as_skin_cluster :: proc(element: ^Element) -> ^Skin_Cluster --- 5633 as_blend_deformer :: proc(element: ^Element) -> ^Blend_Deformer --- 5634 as_blend_channel :: proc(element: ^Element) -> ^Blend_Channel --- 5635 as_blend_shape :: proc(element: ^Element) -> ^Blend_Shape --- 5636 as_cache_deformer :: proc(element: ^Element) -> ^Cache_Deformer --- 5637 as_cache_file :: proc(element: ^Element) -> ^Cache_File --- 5638 as_material :: proc(element: ^Element) -> ^Material --- 5639 as_texture :: proc(element: ^Element) -> ^Texture --- 5640 as_video :: proc(element: ^Element) -> ^Video --- 5641 as_shader :: proc(element: ^Element) -> ^Shader --- 5642 as_shader_binding :: proc(element: ^Element) -> ^Shader_Binding --- 5643 as_anim_stack :: proc(element: ^Element) -> ^Anim_Stack --- 5644 as_anim_layer :: proc(element: ^Element) -> ^Anim_Layer --- 5645 as_anim_value :: proc(element: ^Element) -> ^Anim_Value --- 5646 as_anim_curve :: proc(element: ^Element) -> ^Anim_Curve --- 5647 as_display_layer :: proc(element: ^Element) -> ^Display_Layer --- 5648 as_selection_set :: proc(element: ^Element) -> ^Selection_Set --- 5649 as_selection_node :: proc(element: ^Element) -> ^Selection_Node --- 5650 as_character :: proc(element: ^Element) -> ^Character --- 5651 as_constraint :: proc(element: ^Element) -> ^Constraint --- 5652 as_audio_layer :: proc(element: ^Element) -> ^Audio_Layer --- 5653 as_audio_clip :: proc(element: ^Element) -> ^Audio_Clip --- 5654 as_pose :: proc(element: ^Element) -> ^Pose --- 5655 as_metadata_object :: proc(element: ^Element) -> ^Metadata_Object --- 5656 } 5657