ufbx.h (221736B)
1 #ifndef UFBX_UFBX_H_INCLUDED 2 #define UFBX_UFBX_H_INCLUDED 3 4 // -- User configuration 5 6 #if defined(UFBX_CONFIG_HEADER) 7 #include UFBX_CONFIG_HEADER 8 #endif 9 10 // -- Headers 11 12 #if !defined(UFBX_NO_LIBC_TYPES) 13 #include <stdint.h> 14 #include <stddef.h> 15 #include <stdbool.h> 16 #endif 17 18 // -- Platform 19 20 #ifndef UFBX_STDC 21 #if defined(__STDC_VERSION__) 22 #define UFBX_STDC __STDC_VERSION__ 23 #else 24 #define UFBX_STDC 0 25 #endif 26 #endif 27 28 #ifndef UFBX_CPP 29 #if defined(__cplusplus) 30 #define UFBX_CPP __cplusplus 31 #else 32 #define UFBX_CPP 0 33 #endif 34 #endif 35 36 #ifndef UFBX_PLATFORM_MSC 37 #if !defined(UFBX_STANDARD_C) && defined(_MSC_VER) 38 #define UFBX_PLATFORM_MSC _MSC_VER 39 #else 40 #define UFBX_PLATFORM_MSC 0 41 #endif 42 #endif 43 44 #ifndef UFBX_PLATFORM_GNUC 45 #if !defined(UFBX_STANDARD_C) && defined(__GNUC__) 46 #define UFBX_PLATFORM_GNUC __GNUC__ 47 #else 48 #define UFBX_PLATFORM_GNUC 0 49 #endif 50 #endif 51 52 #ifndef UFBX_CPP11 53 // MSVC does not advertise C++11 by default so we need special detection 54 #if UFBX_CPP >= 201103L || (UFBX_CPP > 0 && UFBX_PLATFORM_MSC >= 1900) 55 #define UFBX_CPP11 1 56 #else 57 #define UFBX_CPP11 0 58 #endif 59 #endif 60 61 #if defined(_MSC_VER) 62 #pragma warning(push) 63 #pragma warning(disable: 4061) // enumerator 'ENUM' in switch of enum 'enum' is not explicitly handled by a case label 64 #pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union 65 #pragma warning(disable: 4505) // unreferenced local function has been removed 66 #pragma warning(disable: 4820) // type': 'N' bytes padding added after data member 'member' 67 #elif defined(__clang__) 68 #pragma clang diagnostic push 69 #pragma clang diagnostic ignored "-Wpedantic" 70 #pragma clang diagnostic ignored "-Wpadded" 71 #if defined(__cplusplus) 72 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" 73 #pragma clang diagnostic ignored "-Wold-style-cast" 74 #endif 75 #elif defined(__GNUC__) 76 #pragma GCC diagnostic push 77 #pragma GCC diagnostic ignored "-Wpedantic" 78 #pragma GCC diagnostic ignored "-Wpadded" 79 #if defined(__cplusplus) 80 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" 81 #pragma GCC diagnostic ignored "-Wold-style-cast" 82 #else 83 #if __GNUC__ >= 5 84 #pragma GCC diagnostic ignored "-Wc90-c99-compat" 85 #pragma GCC diagnostic ignored "-Wc99-c11-compat" 86 #endif 87 #endif 88 #endif 89 90 #if UFBX_PLATFORM_MSC 91 #define ufbx_inline static __forceinline 92 #elif UFBX_PLATFORM_GNUC 93 #define ufbx_inline static inline __attribute__((always_inline, unused)) 94 #else 95 #define ufbx_inline static 96 #endif 97 98 // Assertion function used in ufbx, defaults to C standard `assert()`. 99 // You can define this to your custom preferred assert macro, but in that case 100 // make sure that it is also used within `ufbx.c`. 101 // Defining `UFBX_NO_ASSERT` to any value disables assertions. 102 #ifndef ufbx_assert 103 #if defined(UFBX_NO_ASSERT) || defined(UFBX_NO_LIBC) 104 #define ufbx_assert(cond) (void)0 105 #else 106 #include <assert.h> 107 #define ufbx_assert(cond) assert(cond) 108 #endif 109 #endif 110 111 // Pointer may be `NULL`. 112 #define ufbx_nullable 113 114 // Changing this value from default or calling this function can lead into 115 // breaking API guarantees. 116 #define ufbx_unsafe 117 118 // Linkage of the main ufbx API functions. 119 // Defaults to nothing, or `static` if `UFBX_STATIC` is defined. 120 // If you want to isolate ufbx to a single translation unit you can do the following: 121 // #define UFBX_STATIC 122 // #include "ufbx.h" 123 // #include "ufbx.c" 124 #ifndef ufbx_abi 125 #if defined(UFBX_STATIC) 126 #define ufbx_abi static 127 #else 128 #define ufbx_abi 129 #endif 130 #endif 131 132 // Linkage of the main ufbx data fields in the header. 133 // Defaults to `extern`, or `static` if `UFBX_STATIC` is defined. 134 #ifndef ufbx_abi_data 135 #if defined(UFBX_STATIC) 136 #define ufbx_abi_data static 137 #else 138 #define ufbx_abi_data extern 139 #endif 140 #endif 141 142 // Linkage of the main ufbx data fields in the source. 143 // Defaults to nothing, or `static` if `UFBX_STATIC` is defined. 144 #ifndef ufbx_abi_data_definition 145 #if defined(UFBX_STATIC) 146 #define ufbx_abi_data_def static 147 #else 148 #define ufbx_abi_data_def 149 #endif 150 #endif 151 152 // -- Configuration 153 154 #ifndef UFBX_REAL_TYPE 155 #if defined(UFBX_REAL_IS_FLOAT) 156 #define UFBX_REAL_TYPE float 157 #else 158 #define UFBX_REAL_TYPE double 159 #endif 160 #endif 161 162 // Limits for embedded arrays within structures. 163 #define UFBX_ERROR_STACK_MAX_DEPTH 8 164 #define UFBX_PANIC_MESSAGE_LENGTH 128 165 #define UFBX_ERROR_INFO_LENGTH 256 166 167 // Number of thread groups to use if threading is enabled. 168 // A thread group processes a number of tasks and is then waited and potentially 169 // re-used later. In essence, this controls the granularity of threading. 170 #define UFBX_THREAD_GROUP_COUNT 4 171 172 // -- Language 173 174 // bindgen-disable 175 176 #if UFBX_CPP11 177 178 template <typename T, typename U> 179 struct ufbxi_type_is { }; 180 181 template <typename T> 182 struct ufbxi_type_is<T, T> { using type = int; }; 183 184 template <typename T> 185 struct ufbx_converter { }; 186 187 #define UFBX_CONVERSION_IMPL(p_name) \ 188 template <typename T, typename S=typename ufbxi_type_is<T, decltype(ufbx_converter<T>::from(*(const p_name*)nullptr))>::type> \ 189 operator T() const { return ufbx_converter<T>::from(*this); } 190 191 #define UFBX_CONVERSION_TO_IMPL(p_name) \ 192 template <typename T, typename S=typename ufbxi_type_is<p_name, decltype(ufbx_converter<T>::to(*(const T*)nullptr))>::type> \ 193 p_name(const T &t) { *this = ufbx_converter<T>::to(t); } 194 195 #define UFBX_CONVERSION_LIST_IMPL(p_name) \ 196 template <typename T, typename S=typename ufbxi_type_is<T, decltype(ufbx_converter<T>::from_list((p_name*)nullptr, (size_t)0))>::type> \ 197 operator T() const { return ufbx_converter<T>::from_list(data, count); } 198 199 #else 200 201 #define UFBX_CONVERSION_IMPL(p_name) 202 #define UFBX_CONVERSION_TO_IMPL(p_name) 203 #define UFBX_CONVERSION_LIST_IMPL(p_name) 204 205 #endif 206 207 #if defined(__cplusplus) 208 #define UFBX_LIST_TYPE(p_name, p_type) struct p_name { p_type *data; size_t count; \ 209 p_type &operator[](size_t index) const { ufbx_assert(index < count); return data[index]; } \ 210 p_type *begin() const { return data; } \ 211 p_type *end() const { return data + count; } \ 212 UFBX_CONVERSION_LIST_IMPL(p_type) \ 213 } 214 #else 215 #define UFBX_LIST_TYPE(p_name, p_type) typedef struct p_name { p_type *data; size_t count; } p_name 216 #endif 217 218 // This cannot be enabled automatically if supported as the source file may be 219 // compiled with a different compiler using different settings than the header 220 // consumers, in practice it should work but it causes issues such as #70. 221 #if (UFBX_STDC >= 202311L || UFBX_CPP11) && defined(UFBX_USE_EXPLICIT_ENUM) 222 #define UFBX_ENUM_REPR : int 223 #define UFBX_ENUM_FORCE_WIDTH(p_prefix) 224 #define UFBX_FLAG_REPR : int 225 #define UFBX_FLAG_FORCE_WIDTH(p_prefix) 226 #define UFBX_HAS_FORCE_32BIT 0 227 #else 228 #define UFBX_ENUM_REPR 229 #define UFBX_ENUM_FORCE_WIDTH(p_prefix) p_prefix##_FORCE_32BIT = 0x7fffffff 230 #define UFBX_FLAG_REPR 231 #define UFBX_FLAG_FORCE_WIDTH(p_prefix) p_prefix##_FORCE_32BIT = 0x7fffffff 232 #define UFBX_HAS_FORCE_32BIT 1 233 #endif 234 235 #define UFBX_ENUM_TYPE(p_name, p_prefix, p_last) \ 236 enum { p_prefix##_COUNT = p_last + 1 } 237 238 #if UFBX_CPP 239 #define UFBX_VERTEX_ATTRIB_IMPL(p_type) \ 240 p_type &operator[](size_t index) const { ufbx_assert(index < indices.count); return values.data[indices.data[index]]; } 241 #else 242 #define UFBX_VERTEX_ATTRIB_IMPL(p_type) 243 #endif 244 245 #if UFBX_CPP11 246 #define UFBX_CALLBACK_IMPL(p_name, p_fn, p_return, p_params, p_args) \ 247 template <typename F> static p_return _cpp_adapter p_params { F &f = *static_cast<F*>(user); return f p_args; } \ 248 p_name() = default; \ 249 p_name(p_fn *f) : fn(f), user(nullptr) { } \ 250 template <typename F> p_name(F *f) : fn(&_cpp_adapter<F>), user(static_cast<void*>(f)) { } 251 #else 252 #define UFBX_CALLBACK_IMPL(p_name, p_fn, p_return, p_params, p_args) 253 #endif 254 255 // bindgen-enable 256 257 // -- Version 258 259 // Packing/unpacking for `UFBX_HEADER_VERSION` and `ufbx_source_version`. 260 #define ufbx_pack_version(major, minor, patch) ((uint32_t)(major)*1000000u + (uint32_t)(minor)*1000u + (uint32_t)(patch)) 261 #define ufbx_version_major(version) ((uint32_t)(version)/1000000u%1000u) 262 #define ufbx_version_minor(version) ((uint32_t)(version)/1000u%1000u) 263 #define ufbx_version_patch(version) ((uint32_t)(version)%1000u) 264 265 // Version of the ufbx header. 266 // `UFBX_VERSION` is simply an alias of `UFBX_HEADER_VERSION`. 267 // `ufbx_source_version` contains the version of the corresponding source file. 268 // HINT: The version can be compared numerically to the result of `ufbx_pack_version()`, 269 // for example `#if UFBX_VERSION >= ufbx_pack_version(0, 12, 0)`. 270 #define UFBX_HEADER_VERSION ufbx_pack_version(0, 18, 0) 271 #define UFBX_VERSION UFBX_HEADER_VERSION 272 273 // -- Basic types 274 275 // Main floating point type used everywhere in ufbx, defaults to `double`. 276 // If you define `UFBX_REAL_IS_FLOAT` to any value, `ufbx_real` will be defined 277 // as `float` instead. 278 // You can also manually define `UFBX_REAL_TYPE` to any floating point type. 279 typedef UFBX_REAL_TYPE ufbx_real; 280 281 // Null-terminated UTF-8 encoded string within an FBX file 282 typedef struct ufbx_string { 283 const char *data; 284 size_t length; 285 286 UFBX_CONVERSION_IMPL(ufbx_string) 287 } ufbx_string; 288 289 // Opaque byte buffer blob 290 typedef struct ufbx_blob { 291 const void *data; 292 size_t size; 293 294 UFBX_CONVERSION_IMPL(ufbx_blob) 295 } ufbx_blob; 296 297 // 2D vector 298 typedef struct ufbx_vec2 { 299 union { 300 struct { ufbx_real x, y; }; 301 ufbx_real v[2]; 302 }; 303 304 UFBX_CONVERSION_IMPL(ufbx_vec2) 305 } ufbx_vec2; 306 307 // 3D vector 308 typedef struct ufbx_vec3 { 309 union { 310 struct { ufbx_real x, y, z; }; 311 ufbx_real v[3]; 312 }; 313 314 UFBX_CONVERSION_IMPL(ufbx_vec3) 315 } ufbx_vec3; 316 317 // 4D vector 318 typedef struct ufbx_vec4 { 319 union { 320 struct { ufbx_real x, y, z, w; }; 321 ufbx_real v[4]; 322 }; 323 324 UFBX_CONVERSION_IMPL(ufbx_vec4) 325 } ufbx_vec4; 326 327 // Quaternion 328 typedef struct ufbx_quat { 329 union { 330 struct { ufbx_real x, y, z, w; }; 331 ufbx_real v[4]; 332 }; 333 334 UFBX_CONVERSION_IMPL(ufbx_quat) 335 } ufbx_quat; 336 337 // Order in which Euler-angle rotation axes are applied for a transform 338 // NOTE: The order in the name refers to the order of axes *applied*, 339 // not the multiplication order: eg. `UFBX_ROTATION_ORDER_XYZ` is `Z*Y*X` 340 // [TODO: Figure out what the spheric rotation order is...] 341 typedef enum ufbx_rotation_order UFBX_ENUM_REPR { 342 UFBX_ROTATION_ORDER_XYZ, 343 UFBX_ROTATION_ORDER_XZY, 344 UFBX_ROTATION_ORDER_YZX, 345 UFBX_ROTATION_ORDER_YXZ, 346 UFBX_ROTATION_ORDER_ZXY, 347 UFBX_ROTATION_ORDER_ZYX, 348 UFBX_ROTATION_ORDER_SPHERIC, 349 350 UFBX_ENUM_FORCE_WIDTH(UFBX_ROTATION_ORDER) 351 } ufbx_rotation_order; 352 353 UFBX_ENUM_TYPE(ufbx_rotation_order, UFBX_ROTATION_ORDER, UFBX_ROTATION_ORDER_SPHERIC); 354 355 // Explicit translation+rotation+scale transformation. 356 // NOTE: Rotation is a quaternion, not Euler angles! 357 typedef struct ufbx_transform { 358 ufbx_vec3 translation; 359 ufbx_quat rotation; 360 ufbx_vec3 scale; 361 362 UFBX_CONVERSION_IMPL(ufbx_transform) 363 } ufbx_transform; 364 365 // 4x3 matrix encoding an affine transformation. 366 // `cols[0..2]` are the X/Y/Z basis vectors, `cols[3]` is the translation 367 typedef struct ufbx_matrix { 368 union { 369 struct { 370 ufbx_real m00, m10, m20; 371 ufbx_real m01, m11, m21; 372 ufbx_real m02, m12, m22; 373 ufbx_real m03, m13, m23; 374 }; 375 ufbx_vec3 cols[4]; 376 ufbx_real v[12]; 377 }; 378 379 UFBX_CONVERSION_IMPL(ufbx_matrix) 380 } ufbx_matrix; 381 382 typedef struct ufbx_void_list { 383 void *data; 384 size_t count; 385 } ufbx_void_list; 386 387 UFBX_LIST_TYPE(ufbx_bool_list, bool); 388 UFBX_LIST_TYPE(ufbx_uint32_list, uint32_t); 389 UFBX_LIST_TYPE(ufbx_real_list, ufbx_real); 390 UFBX_LIST_TYPE(ufbx_vec2_list, ufbx_vec2); 391 UFBX_LIST_TYPE(ufbx_vec3_list, ufbx_vec3); 392 UFBX_LIST_TYPE(ufbx_vec4_list, ufbx_vec4); 393 UFBX_LIST_TYPE(ufbx_string_list, ufbx_string); 394 395 // Sentinel value used to represent a missing index. 396 #define UFBX_NO_INDEX ((uint32_t)~0u) 397 398 // -- Document object model 399 400 typedef enum ufbx_dom_value_type UFBX_ENUM_REPR { 401 UFBX_DOM_VALUE_NUMBER, 402 UFBX_DOM_VALUE_STRING, 403 UFBX_DOM_VALUE_ARRAY_I8, 404 UFBX_DOM_VALUE_ARRAY_I32, 405 UFBX_DOM_VALUE_ARRAY_I64, 406 UFBX_DOM_VALUE_ARRAY_F32, 407 UFBX_DOM_VALUE_ARRAY_F64, 408 UFBX_DOM_VALUE_ARRAY_RAW_STRING, 409 UFBX_DOM_VALUE_ARRAY_IGNORED, 410 411 UFBX_ENUM_FORCE_WIDTH(UFBX_DOM_VALUE_TYPE) 412 } ufbx_dom_value_type; 413 414 UFBX_ENUM_TYPE(ufbx_dom_value_type, UFBX_DOM_VALUE_TYPE, UFBX_DOM_VALUE_ARRAY_IGNORED); 415 416 typedef struct ufbx_dom_node ufbx_dom_node; 417 418 typedef struct ufbx_dom_value { 419 ufbx_dom_value_type type; 420 ufbx_string value_str; 421 ufbx_blob value_blob; 422 int64_t value_int; 423 double value_float; 424 } ufbx_dom_value; 425 426 UFBX_LIST_TYPE(ufbx_dom_node_list, ufbx_dom_node*); 427 UFBX_LIST_TYPE(ufbx_dom_value_list, ufbx_dom_value); 428 429 struct ufbx_dom_node { 430 ufbx_string name; 431 ufbx_dom_node_list children; 432 ufbx_dom_value_list values; 433 }; 434 435 // -- Properties 436 437 // FBX elements have properties which are arbitrary key/value pairs that can 438 // have inherited default values or be animated. In most cases you don't need 439 // to access these unless you need a feature not implemented directly in ufbx. 440 // NOTE: Prefer using `ufbx_find_prop[_len](...)` to search for a property by 441 // name as it can find it from the defaults if necessary. 442 443 typedef struct ufbx_prop ufbx_prop; 444 typedef struct ufbx_props ufbx_props; 445 446 // Data type contained within the property. All the data fields are always 447 // populated regardless of type, so there's no need to switch by type usually 448 // eg. `prop->value_real` and `prop->value_int` have the same value (well, close) 449 // if `prop->type == UFBX_PROP_INTEGER`. String values are not converted from/to. 450 typedef enum ufbx_prop_type UFBX_ENUM_REPR { 451 UFBX_PROP_UNKNOWN, 452 UFBX_PROP_BOOLEAN, 453 UFBX_PROP_INTEGER, 454 UFBX_PROP_NUMBER, 455 UFBX_PROP_VECTOR, 456 UFBX_PROP_COLOR, 457 UFBX_PROP_COLOR_WITH_ALPHA, 458 UFBX_PROP_STRING, 459 UFBX_PROP_DATE_TIME, 460 UFBX_PROP_TRANSLATION, 461 UFBX_PROP_ROTATION, 462 UFBX_PROP_SCALING, 463 UFBX_PROP_DISTANCE, 464 UFBX_PROP_COMPOUND, 465 UFBX_PROP_BLOB, 466 UFBX_PROP_REFERENCE, 467 468 UFBX_ENUM_FORCE_WIDTH(UFBX_PROP_TYPE) 469 } ufbx_prop_type; 470 471 UFBX_ENUM_TYPE(ufbx_prop_type, UFBX_PROP_TYPE, UFBX_PROP_REFERENCE); 472 473 // Property flags: Advanced information about properties, not usually needed. 474 typedef enum ufbx_prop_flags UFBX_FLAG_REPR { 475 // Supports animation. 476 // NOTE: ufbx ignores this and allows animations on non-animatable properties. 477 UFBX_PROP_FLAG_ANIMATABLE = 0x1, 478 479 // User defined (custom) property. 480 UFBX_PROP_FLAG_USER_DEFINED = 0x2, 481 482 // Hidden in UI. 483 UFBX_PROP_FLAG_HIDDEN = 0x4, 484 485 // Disallow modification from UI for components. 486 UFBX_PROP_FLAG_LOCK_X = 0x10, 487 UFBX_PROP_FLAG_LOCK_Y = 0x20, 488 UFBX_PROP_FLAG_LOCK_Z = 0x40, 489 UFBX_PROP_FLAG_LOCK_W = 0x80, 490 491 // Disable animation from components. 492 UFBX_PROP_FLAG_MUTE_X = 0x100, 493 UFBX_PROP_FLAG_MUTE_Y = 0x200, 494 UFBX_PROP_FLAG_MUTE_Z = 0x400, 495 UFBX_PROP_FLAG_MUTE_W = 0x800, 496 497 // Property created by ufbx when an element has a connected `ufbx_anim_prop` 498 // but doesn't contain the `ufbx_prop` it's referring to. 499 // NOTE: The property may have been found in the templated defaults. 500 UFBX_PROP_FLAG_SYNTHETIC = 0x1000, 501 502 // The property has at least one `ufbx_anim_prop` in some layer. 503 UFBX_PROP_FLAG_ANIMATED = 0x2000, 504 505 // Used by `ufbx_evaluate_prop()` to indicate the the property was not found. 506 UFBX_PROP_FLAG_NOT_FOUND = 0x4000, 507 508 // The property is connected to another one. 509 // This use case is relatively rare so `ufbx_prop` does not track connections 510 // directly. You can find connections from `ufbx_element.connections_dst` where 511 // `ufbx_connection.dst_prop` is this property and `ufbx_connection.src_prop` is defined. 512 UFBX_PROP_FLAG_CONNECTED = 0x8000, 513 514 // The value of this property is undefined (represented as zero). 515 UFBX_PROP_FLAG_NO_VALUE = 0x10000, 516 517 // This property has been overridden by the user. 518 // See `ufbx_anim.prop_overrides` for more information. 519 UFBX_PROP_FLAG_OVERRIDDEN = 0x20000, 520 521 // Value type. 522 // `REAL/VEC2/VEC3/VEC4` are mutually exclusive but may coexist with eg. `STRING` 523 // in some rare cases where the string defines the unit for the vector. 524 UFBX_PROP_FLAG_VALUE_REAL = 0x100000, 525 UFBX_PROP_FLAG_VALUE_VEC2 = 0x200000, 526 UFBX_PROP_FLAG_VALUE_VEC3 = 0x400000, 527 UFBX_PROP_FLAG_VALUE_VEC4 = 0x800000, 528 UFBX_PROP_FLAG_VALUE_INT = 0x1000000, 529 UFBX_PROP_FLAG_VALUE_STR = 0x2000000, 530 UFBX_PROP_FLAG_VALUE_BLOB = 0x4000000, 531 532 UFBX_FLAG_FORCE_WIDTH(UFBX_PROP_FLAGS) 533 } ufbx_prop_flags; 534 535 // Single property with name/type/value. 536 struct ufbx_prop { 537 ufbx_string name; 538 539 uint32_t _internal_key; 540 541 ufbx_prop_type type; 542 ufbx_prop_flags flags; 543 544 ufbx_string value_str; 545 ufbx_blob value_blob; 546 int64_t value_int; 547 union { 548 ufbx_real value_real_arr[4]; 549 ufbx_real value_real; 550 ufbx_vec2 value_vec2; 551 ufbx_vec3 value_vec3; 552 ufbx_vec4 value_vec4; 553 }; 554 }; 555 556 UFBX_LIST_TYPE(ufbx_prop_list, ufbx_prop); 557 558 // List of alphabetically sorted properties with potential defaults. 559 // For animated objects in as scene from `ufbx_evaluate_scene()` this list 560 // only has the animated properties, the originals are stored under `defaults`. 561 struct ufbx_props { 562 ufbx_prop_list props; 563 size_t num_animated; 564 565 ufbx_nullable ufbx_props *defaults; 566 }; 567 568 typedef struct ufbx_scene ufbx_scene; 569 570 // -- Elements 571 572 // Element is the lowest level representation of the FBX file in ufbx. 573 // An element contains type, id, name, and properties (see `ufbx_props` above) 574 // Elements may be connected to each other arbitrarily via `ufbx_connection` 575 576 typedef struct ufbx_element ufbx_element; 577 578 // Unknown 579 typedef struct ufbx_unknown ufbx_unknown; 580 581 // Nodes 582 typedef struct ufbx_node ufbx_node; 583 584 // Node attributes (common) 585 typedef struct ufbx_mesh ufbx_mesh; 586 typedef struct ufbx_light ufbx_light; 587 typedef struct ufbx_camera ufbx_camera; 588 typedef struct ufbx_bone ufbx_bone; 589 typedef struct ufbx_empty ufbx_empty; 590 591 // Node attributes (curves/surfaces) 592 typedef struct ufbx_line_curve ufbx_line_curve; 593 typedef struct ufbx_nurbs_curve ufbx_nurbs_curve; 594 typedef struct ufbx_nurbs_surface ufbx_nurbs_surface; 595 typedef struct ufbx_nurbs_trim_surface ufbx_nurbs_trim_surface; 596 typedef struct ufbx_nurbs_trim_boundary ufbx_nurbs_trim_boundary; 597 598 // Node attributes (advanced) 599 typedef struct ufbx_procedural_geometry ufbx_procedural_geometry; 600 typedef struct ufbx_stereo_camera ufbx_stereo_camera; 601 typedef struct ufbx_camera_switcher ufbx_camera_switcher; 602 typedef struct ufbx_marker ufbx_marker; 603 typedef struct ufbx_lod_group ufbx_lod_group; 604 605 // Deformers 606 typedef struct ufbx_skin_deformer ufbx_skin_deformer; 607 typedef struct ufbx_skin_cluster ufbx_skin_cluster; 608 typedef struct ufbx_blend_deformer ufbx_blend_deformer; 609 typedef struct ufbx_blend_channel ufbx_blend_channel; 610 typedef struct ufbx_blend_shape ufbx_blend_shape; 611 typedef struct ufbx_cache_deformer ufbx_cache_deformer; 612 typedef struct ufbx_cache_file ufbx_cache_file; 613 614 // Materials 615 typedef struct ufbx_material ufbx_material; 616 typedef struct ufbx_texture ufbx_texture; 617 typedef struct ufbx_video ufbx_video; 618 typedef struct ufbx_shader ufbx_shader; 619 typedef struct ufbx_shader_binding ufbx_shader_binding; 620 621 // Animation 622 typedef struct ufbx_anim_stack ufbx_anim_stack; 623 typedef struct ufbx_anim_layer ufbx_anim_layer; 624 typedef struct ufbx_anim_value ufbx_anim_value; 625 typedef struct ufbx_anim_curve ufbx_anim_curve; 626 627 // Collections 628 typedef struct ufbx_display_layer ufbx_display_layer; 629 typedef struct ufbx_selection_set ufbx_selection_set; 630 typedef struct ufbx_selection_node ufbx_selection_node; 631 632 // Constraints 633 typedef struct ufbx_character ufbx_character; 634 typedef struct ufbx_constraint ufbx_constraint; 635 636 // Audio 637 typedef struct ufbx_audio_layer ufbx_audio_layer; 638 typedef struct ufbx_audio_clip ufbx_audio_clip; 639 640 // Miscellaneous 641 typedef struct ufbx_pose ufbx_pose; 642 typedef struct ufbx_metadata_object ufbx_metadata_object; 643 644 UFBX_LIST_TYPE(ufbx_element_list, ufbx_element*); 645 UFBX_LIST_TYPE(ufbx_unknown_list, ufbx_unknown*); 646 UFBX_LIST_TYPE(ufbx_node_list, ufbx_node*); 647 UFBX_LIST_TYPE(ufbx_mesh_list, ufbx_mesh*); 648 UFBX_LIST_TYPE(ufbx_light_list, ufbx_light*); 649 UFBX_LIST_TYPE(ufbx_camera_list, ufbx_camera*); 650 UFBX_LIST_TYPE(ufbx_bone_list, ufbx_bone*); 651 UFBX_LIST_TYPE(ufbx_empty_list, ufbx_empty*); 652 UFBX_LIST_TYPE(ufbx_line_curve_list, ufbx_line_curve*); 653 UFBX_LIST_TYPE(ufbx_nurbs_curve_list, ufbx_nurbs_curve*); 654 UFBX_LIST_TYPE(ufbx_nurbs_surface_list, ufbx_nurbs_surface*); 655 UFBX_LIST_TYPE(ufbx_nurbs_trim_surface_list, ufbx_nurbs_trim_surface*); 656 UFBX_LIST_TYPE(ufbx_nurbs_trim_boundary_list, ufbx_nurbs_trim_boundary*); 657 UFBX_LIST_TYPE(ufbx_procedural_geometry_list, ufbx_procedural_geometry*); 658 UFBX_LIST_TYPE(ufbx_stereo_camera_list, ufbx_stereo_camera*); 659 UFBX_LIST_TYPE(ufbx_camera_switcher_list, ufbx_camera_switcher*); 660 UFBX_LIST_TYPE(ufbx_marker_list, ufbx_marker*); 661 UFBX_LIST_TYPE(ufbx_lod_group_list, ufbx_lod_group*); 662 UFBX_LIST_TYPE(ufbx_skin_deformer_list, ufbx_skin_deformer*); 663 UFBX_LIST_TYPE(ufbx_skin_cluster_list, ufbx_skin_cluster*); 664 UFBX_LIST_TYPE(ufbx_blend_deformer_list, ufbx_blend_deformer*); 665 UFBX_LIST_TYPE(ufbx_blend_channel_list, ufbx_blend_channel*); 666 UFBX_LIST_TYPE(ufbx_blend_shape_list, ufbx_blend_shape*); 667 UFBX_LIST_TYPE(ufbx_cache_deformer_list, ufbx_cache_deformer*); 668 UFBX_LIST_TYPE(ufbx_cache_file_list, ufbx_cache_file*); 669 UFBX_LIST_TYPE(ufbx_material_list, ufbx_material*); 670 UFBX_LIST_TYPE(ufbx_texture_list, ufbx_texture*); 671 UFBX_LIST_TYPE(ufbx_video_list, ufbx_video*); 672 UFBX_LIST_TYPE(ufbx_shader_list, ufbx_shader*); 673 UFBX_LIST_TYPE(ufbx_shader_binding_list, ufbx_shader_binding*); 674 UFBX_LIST_TYPE(ufbx_anim_stack_list, ufbx_anim_stack*); 675 UFBX_LIST_TYPE(ufbx_anim_layer_list, ufbx_anim_layer*); 676 UFBX_LIST_TYPE(ufbx_anim_value_list, ufbx_anim_value*); 677 UFBX_LIST_TYPE(ufbx_anim_curve_list, ufbx_anim_curve*); 678 UFBX_LIST_TYPE(ufbx_display_layer_list, ufbx_display_layer*); 679 UFBX_LIST_TYPE(ufbx_selection_set_list, ufbx_selection_set*); 680 UFBX_LIST_TYPE(ufbx_selection_node_list, ufbx_selection_node*); 681 UFBX_LIST_TYPE(ufbx_character_list, ufbx_character*); 682 UFBX_LIST_TYPE(ufbx_constraint_list, ufbx_constraint*); 683 UFBX_LIST_TYPE(ufbx_audio_layer_list, ufbx_audio_layer*); 684 UFBX_LIST_TYPE(ufbx_audio_clip_list, ufbx_audio_clip*); 685 UFBX_LIST_TYPE(ufbx_pose_list, ufbx_pose*); 686 UFBX_LIST_TYPE(ufbx_metadata_object_list, ufbx_metadata_object*); 687 688 typedef enum ufbx_element_type UFBX_ENUM_REPR { 689 UFBX_ELEMENT_UNKNOWN, // < `ufbx_unknown` 690 UFBX_ELEMENT_NODE, // < `ufbx_node` 691 UFBX_ELEMENT_MESH, // < `ufbx_mesh` 692 UFBX_ELEMENT_LIGHT, // < `ufbx_light` 693 UFBX_ELEMENT_CAMERA, // < `ufbx_camera` 694 UFBX_ELEMENT_BONE, // < `ufbx_bone` 695 UFBX_ELEMENT_EMPTY, // < `ufbx_empty` 696 UFBX_ELEMENT_LINE_CURVE, // < `ufbx_line_curve` 697 UFBX_ELEMENT_NURBS_CURVE, // < `ufbx_nurbs_curve` 698 UFBX_ELEMENT_NURBS_SURFACE, // < `ufbx_nurbs_surface` 699 UFBX_ELEMENT_NURBS_TRIM_SURFACE, // < `ufbx_nurbs_trim_surface` 700 UFBX_ELEMENT_NURBS_TRIM_BOUNDARY, // < `ufbx_nurbs_trim_boundary` 701 UFBX_ELEMENT_PROCEDURAL_GEOMETRY, // < `ufbx_procedural_geometry` 702 UFBX_ELEMENT_STEREO_CAMERA, // < `ufbx_stereo_camera` 703 UFBX_ELEMENT_CAMERA_SWITCHER, // < `ufbx_camera_switcher` 704 UFBX_ELEMENT_MARKER, // < `ufbx_marker` 705 UFBX_ELEMENT_LOD_GROUP, // < `ufbx_lod_group` 706 UFBX_ELEMENT_SKIN_DEFORMER, // < `ufbx_skin_deformer` 707 UFBX_ELEMENT_SKIN_CLUSTER, // < `ufbx_skin_cluster` 708 UFBX_ELEMENT_BLEND_DEFORMER, // < `ufbx_blend_deformer` 709 UFBX_ELEMENT_BLEND_CHANNEL, // < `ufbx_blend_channel` 710 UFBX_ELEMENT_BLEND_SHAPE, // < `ufbx_blend_shape` 711 UFBX_ELEMENT_CACHE_DEFORMER, // < `ufbx_cache_deformer` 712 UFBX_ELEMENT_CACHE_FILE, // < `ufbx_cache_file` 713 UFBX_ELEMENT_MATERIAL, // < `ufbx_material` 714 UFBX_ELEMENT_TEXTURE, // < `ufbx_texture` 715 UFBX_ELEMENT_VIDEO, // < `ufbx_video` 716 UFBX_ELEMENT_SHADER, // < `ufbx_shader` 717 UFBX_ELEMENT_SHADER_BINDING, // < `ufbx_shader_binding` 718 UFBX_ELEMENT_ANIM_STACK, // < `ufbx_anim_stack` 719 UFBX_ELEMENT_ANIM_LAYER, // < `ufbx_anim_layer` 720 UFBX_ELEMENT_ANIM_VALUE, // < `ufbx_anim_value` 721 UFBX_ELEMENT_ANIM_CURVE, // < `ufbx_anim_curve` 722 UFBX_ELEMENT_DISPLAY_LAYER, // < `ufbx_display_layer` 723 UFBX_ELEMENT_SELECTION_SET, // < `ufbx_selection_set` 724 UFBX_ELEMENT_SELECTION_NODE, // < `ufbx_selection_node` 725 UFBX_ELEMENT_CHARACTER, // < `ufbx_character` 726 UFBX_ELEMENT_CONSTRAINT, // < `ufbx_constraint` 727 UFBX_ELEMENT_AUDIO_LAYER, // < `ufbx_audio_layer` 728 UFBX_ELEMENT_AUDIO_CLIP, // < `ufbx_audio_clip` 729 UFBX_ELEMENT_POSE, // < `ufbx_pose` 730 UFBX_ELEMENT_METADATA_OBJECT, // < `ufbx_metadata_object` 731 732 UFBX_ELEMENT_TYPE_FIRST_ATTRIB = UFBX_ELEMENT_MESH, 733 UFBX_ELEMENT_TYPE_LAST_ATTRIB = UFBX_ELEMENT_LOD_GROUP, 734 735 UFBX_ENUM_FORCE_WIDTH(UFBX_ELEMENT_TYPE) 736 } ufbx_element_type; 737 738 UFBX_ENUM_TYPE(ufbx_element_type, UFBX_ELEMENT_TYPE, UFBX_ELEMENT_METADATA_OBJECT); 739 740 // Connection between two elements. 741 // Source and destination are somewhat arbitrary but the destination is 742 // often the "container" like a parent node or mesh containing a deformer. 743 typedef struct ufbx_connection { 744 ufbx_element *src; 745 ufbx_element *dst; 746 ufbx_string src_prop; 747 ufbx_string dst_prop; 748 } ufbx_connection; 749 750 UFBX_LIST_TYPE(ufbx_connection_list, ufbx_connection); 751 752 // Element "base-class" common to each element. 753 // Some fields (like `connections_src`) are advanced and not visible 754 // in the specialized element structs. 755 // NOTE: The `element_id` value is consistent when loading the 756 // _same_ file, but re-exporting the file will invalidate them. 757 struct ufbx_element { 758 ufbx_string name; 759 ufbx_props props; 760 uint32_t element_id; 761 uint32_t typed_id; 762 ufbx_node_list instances; 763 ufbx_element_type type; 764 ufbx_connection_list connections_src; 765 ufbx_connection_list connections_dst; 766 ufbx_nullable ufbx_dom_node *dom_node; 767 ufbx_scene *scene; 768 }; 769 770 // -- Unknown 771 772 struct ufbx_unknown { 773 // Shared "base-class" header, see `ufbx_element`. 774 union { ufbx_element element; struct { 775 ufbx_string name; 776 ufbx_props props; 777 uint32_t element_id; 778 uint32_t typed_id; 779 }; }; 780 781 // FBX format specific type information. 782 // In ASCII FBX format: 783 // super_type: ID, "type::name", "sub_type" { ... } 784 ufbx_string type; 785 ufbx_string super_type; 786 ufbx_string sub_type; 787 }; 788 789 // -- Nodes 790 791 // Inherit type specifies how hierarchial node transforms are combined. 792 // This only affects the final scaling, as rotation and translation are always 793 // inherited correctly. 794 // NOTE: These don't map to `"InheritType"` property as there may be new ones for 795 // compatibility with various exporters. 796 typedef enum ufbx_inherit_mode UFBX_ENUM_REPR { 797 798 // Normal matrix composition of hierarchy: `R*S*r*s`. 799 // child.node_to_world = parent.node_to_world * child.node_to_parent; 800 UFBX_INHERIT_MODE_NORMAL, 801 802 // Ignore parent scale when computing the transform: `R*r*s`. 803 // ufbx_transform t = node.local_transform; 804 // t.translation *= parent.inherit_scale; 805 // t.scale *= node.inherit_scale_node.inherit_scale; 806 // child.node_to_world = parent.unscaled_node_to_world * t; 807 // Also known as "Segment scale compensate" in some software. 808 UFBX_INHERIT_MODE_IGNORE_PARENT_SCALE, 809 810 // Apply parent scale component-wise: `R*r*S*s`. 811 // ufbx_transform t = node.local_transform; 812 // t.translation *= parent.inherit_scale; 813 // t.scale *= node.inherit_scale_node.inherit_scale; 814 // child.node_to_world = parent.unscaled_node_to_world * t; 815 UFBX_INHERIT_MODE_COMPONENTWISE_SCALE, 816 817 UFBX_ENUM_FORCE_WIDTH(UFBX_INHERIT_MODE) 818 } ufbx_inherit_mode; 819 820 UFBX_ENUM_TYPE(ufbx_inherit_mode, UFBX_INHERIT_MODE, UFBX_INHERIT_MODE_COMPONENTWISE_SCALE); 821 822 // Axis used to mirror transformations for handedness conversion. 823 typedef enum ufbx_mirror_axis UFBX_ENUM_REPR { 824 825 UFBX_MIRROR_AXIS_NONE, 826 UFBX_MIRROR_AXIS_X, 827 UFBX_MIRROR_AXIS_Y, 828 UFBX_MIRROR_AXIS_Z, 829 830 UFBX_ENUM_FORCE_WIDTH(UFBX_MIRROR_AXIS) 831 } ufbx_mirror_axis; 832 833 UFBX_ENUM_TYPE(ufbx_mirror_axis, UFBX_MIRROR_AXIS, UFBX_MIRROR_AXIS_Z); 834 835 // Nodes form the scene transformation hierarchy and can contain attached 836 // elements such as meshes or lights. In normal cases a single `ufbx_node` 837 // contains only a single attached element, so using `type/mesh/...` is safe. 838 struct ufbx_node { 839 union { ufbx_element element; struct { 840 ufbx_string name; 841 ufbx_props props; 842 uint32_t element_id; 843 uint32_t typed_id; 844 }; }; 845 846 // Node hierarchy 847 848 // Parent node containing this one if not root. 849 // 850 // Always non-`NULL` for non-root nodes unless 851 // `ufbx_load_opts.allow_nodes_out_of_root` is enabled. 852 ufbx_nullable ufbx_node *parent; 853 854 // List of child nodes parented to this node. 855 ufbx_node_list children; 856 857 // Common attached element type and typed pointers. Set to `NULL` if not in 858 // use, so checking `attrib_type` is not required. 859 // 860 // HINT: If you need less common attributes access `ufbx_node.attrib`, you 861 // can use utility functions like `ufbx_as_nurbs_curve(attrib)` to convert 862 // and check the attribute in one step. 863 ufbx_nullable ufbx_mesh *mesh; 864 ufbx_nullable ufbx_light *light; 865 ufbx_nullable ufbx_camera *camera; 866 ufbx_nullable ufbx_bone *bone; 867 868 // Less common attributes use these fields. 869 // 870 // Defined even if it is one of the above, eg. `ufbx_mesh`. In case there 871 // is multiple attributes this will be the first one. 872 ufbx_nullable ufbx_element *attrib; 873 874 // Geometry transform helper if one exists. 875 // See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`. 876 ufbx_nullable ufbx_node *geometry_transform_helper; 877 878 // Scale helper if one exists. 879 // See `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`. 880 ufbx_nullable ufbx_node *scale_helper; 881 882 // `attrib->type` if `attrib` is defined, otherwise `UFBX_ELEMENT_UNKNOWN`. 883 ufbx_element_type attrib_type; 884 885 // List of _all_ attached attribute elements. 886 // 887 // In most cases there is only zero or one attributes per node, but if you 888 // have a very exotic FBX file nodes may have multiple attributes. 889 ufbx_element_list all_attribs; 890 891 // Local transform in parent, geometry transform is a non-inherited 892 // transform applied only to attachments like meshes 893 ufbx_inherit_mode inherit_mode; 894 ufbx_inherit_mode original_inherit_mode; 895 ufbx_transform local_transform; 896 ufbx_transform geometry_transform; 897 898 // Combined scale when using `UFBX_INHERIT_MODE_COMPONENTWISE_SCALE`. 899 // Contains `local_transform.scale` otherwise. 900 ufbx_vec3 inherit_scale; 901 902 // Node where scale is inherited from for `UFBX_INHERIT_MODE_COMPONENTWISE_SCALE` 903 // and even for `UFBX_INHERIT_MODE_IGNORE_PARENT_SCALE`. 904 // For componentwise-scale nodes, this will point to `parent`, for scale ignoring 905 // nodes this will point to the parent of the nearest componentwise-scaled node 906 // in the parent chain. 907 ufbx_nullable ufbx_node *inherit_scale_node; 908 909 // Raw Euler angles in degrees for those who want them 910 911 // Specifies the axis order `euler_rotation` is applied in. 912 ufbx_rotation_order rotation_order; 913 // Rotation around the local X/Y/Z axes in `rotation_order`. 914 // The angles are specified in degrees. 915 ufbx_vec3 euler_rotation; 916 917 // Matrices derived from the transformations, for transforming geometry 918 // prefer using `geometry_to_world` as that supports geometric transforms. 919 920 // Transform from this node to `parent` space. 921 // Equivalent to `ufbx_transform_to_matrix(&local_transform)`. 922 ufbx_matrix node_to_parent; 923 // Transform from this node to the world space, ie. multiplying all the 924 // `node_to_parent` matrices of the parent chain together. 925 ufbx_matrix node_to_world; 926 // Transform from the attribute to this node. Does not affect the transforms 927 // of `children`! 928 // Equivalent to `ufbx_transform_to_matrix(&geometry_transform)`. 929 ufbx_matrix geometry_to_node; 930 // Transform from attribute space to world space. 931 // Equivalent to `ufbx_matrix_mul(&node_to_world, &geometry_to_node)`. 932 ufbx_matrix geometry_to_world; 933 // Transform from this node to world space, ignoring self scaling. 934 ufbx_matrix unscaled_node_to_world; 935 936 // ufbx-specific adjustment for switching between coodrinate/unit systems. 937 // HINT: In most cases you don't need to deal with these as these are baked 938 // into all the transforms above and into `ufbx_evaluate_transform()`. 939 ufbx_vec3 adjust_pre_translation; // < Translation applied between parent and self 940 ufbx_quat adjust_pre_rotation; // < Rotation applied between parent and self 941 ufbx_real adjust_pre_scale; // < Scaling applied between parent and self 942 ufbx_quat adjust_post_rotation; // < Rotation applied in local space at the end 943 ufbx_real adjust_post_scale; // < Scaling applied in local space at the end 944 ufbx_real adjust_translation_scale; // < Scaling applied to translation only 945 ufbx_mirror_axis adjust_mirror_axis; // < Mirror translation and rotation on this axis 946 947 // Materials used by `mesh` or other `attrib`. 948 // There may be multiple copies of a single `ufbx_mesh` with different materials 949 // in the `ufbx_node` instances. 950 ufbx_material_list materials; 951 952 // Bind pose 953 ufbx_nullable ufbx_pose *bind_pose; 954 955 // Visibility state. 956 bool visible; 957 958 // True if this node is the implicit root node of the scene. 959 bool is_root; 960 961 // True if the node has a non-identity `geometry_transform`. 962 bool has_geometry_transform; 963 964 // If `true` the transform is adjusted by ufbx, not enabled by default. 965 // See `adjust_pre_rotation`, `adjust_pre_scale`, `adjust_post_rotation`, 966 // and `adjust_post_scale`. 967 bool has_adjust_transform; 968 969 // Scale is adjusted by root scale. 970 bool has_root_adjust_transform; 971 972 // True if this node is a synthetic geometry transform helper. 973 // See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`. 974 bool is_geometry_transform_helper; 975 976 // True if the node is a synthetic scale compensation helper. 977 // See `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`. 978 bool is_scale_helper; 979 980 // Parent node to children that can compensate for parent scale. 981 bool is_scale_compensate_parent; 982 983 // How deep is this node in the parent hierarchy. Root node is at depth `0` 984 // and the immediate children of root at `1`. 985 uint32_t node_depth; 986 }; 987 988 // Vertex attribute: All attributes are stored in a consistent indexed format 989 // regardless of how it's actually stored in the file. 990 // 991 // `values` is a contiguous array of attribute values. 992 // `indices` maps each mesh index into a value in the `values` array. 993 // 994 // If `unique_per_vertex` is set then the attribute is guaranteed to have a 995 // single defined value per vertex accessible via: 996 // attrib.values.data[attrib.indices.data[mesh->vertex_first_index[vertex_ix]] 997 typedef struct ufbx_vertex_attrib { 998 // Is this attribute defined by the mesh. 999 bool exists; 1000 // List of values the attribute uses. 1001 ufbx_void_list values; 1002 // Indices into `values[]`, indexed up to `ufbx_mesh.num_indices`. 1003 ufbx_uint32_list indices; 1004 // Number of `ufbx_real` entries per value. 1005 size_t value_reals; 1006 // `true` if this attribute is defined per vertex, instead of per index. 1007 bool unique_per_vertex; 1008 // Optional 4th 'W' component for the attribute. 1009 // May be defined for the following: 1010 // ufbx_mesh.vertex_normal 1011 // ufbx_mesh.vertex_tangent / ufbx_uv_set.vertex_tangent 1012 // ufbx_mesh.vertex_bitangent / ufbx_uv_set.vertex_bitangent 1013 // NOTE: This is not loaded by default, set `ufbx_load_opts.retain_vertex_attrib_w`. 1014 ufbx_real_list values_w; 1015 } ufbx_vertex_attrib; 1016 1017 // 1D vertex attribute, see `ufbx_vertex_attrib` for information 1018 typedef struct ufbx_vertex_real { 1019 bool exists; 1020 ufbx_real_list values; 1021 ufbx_uint32_list indices; 1022 size_t value_reals; 1023 bool unique_per_vertex; 1024 ufbx_real_list values_w; 1025 1026 UFBX_VERTEX_ATTRIB_IMPL(ufbx_real) 1027 } ufbx_vertex_real; 1028 1029 // 2D vertex attribute, see `ufbx_vertex_attrib` for information 1030 typedef struct ufbx_vertex_vec2 { 1031 bool exists; 1032 ufbx_vec2_list values; 1033 ufbx_uint32_list indices; 1034 size_t value_reals; 1035 bool unique_per_vertex; 1036 ufbx_real_list values_w; 1037 1038 UFBX_VERTEX_ATTRIB_IMPL(ufbx_vec2) 1039 } ufbx_vertex_vec2; 1040 1041 // 3D vertex attribute, see `ufbx_vertex_attrib` for information 1042 typedef struct ufbx_vertex_vec3 { 1043 bool exists; 1044 ufbx_vec3_list values; 1045 ufbx_uint32_list indices; 1046 size_t value_reals; 1047 bool unique_per_vertex; 1048 ufbx_real_list values_w; 1049 1050 UFBX_VERTEX_ATTRIB_IMPL(ufbx_vec3) 1051 } ufbx_vertex_vec3; 1052 1053 // 4D vertex attribute, see `ufbx_vertex_attrib` for information 1054 typedef struct ufbx_vertex_vec4 { 1055 bool exists; 1056 ufbx_vec4_list values; 1057 ufbx_uint32_list indices; 1058 size_t value_reals; 1059 bool unique_per_vertex; 1060 ufbx_real_list values_w; 1061 1062 UFBX_VERTEX_ATTRIB_IMPL(ufbx_vec4) 1063 } ufbx_vertex_vec4; 1064 1065 // Vertex UV set/layer 1066 typedef struct ufbx_uv_set { 1067 ufbx_string name; 1068 uint32_t index; 1069 1070 // Vertex attributes, see `ufbx_mesh` attributes for more information 1071 ufbx_vertex_vec2 vertex_uv; // < UV / texture coordinates 1072 ufbx_vertex_vec3 vertex_tangent; // < (optional) Tangent vector in UV.x direction 1073 ufbx_vertex_vec3 vertex_bitangent; // < (optional) Tangent vector in UV.y direction 1074 } ufbx_uv_set; 1075 1076 // Vertex color set/layer 1077 typedef struct ufbx_color_set { 1078 ufbx_string name; 1079 uint32_t index; 1080 1081 // Vertex attributes, see `ufbx_mesh` attributes for more information 1082 ufbx_vertex_vec4 vertex_color; // < Per-vertex RGBA color 1083 } ufbx_color_set; 1084 1085 UFBX_LIST_TYPE(ufbx_uv_set_list, ufbx_uv_set); 1086 UFBX_LIST_TYPE(ufbx_color_set_list, ufbx_color_set); 1087 1088 // Edge between two _indices_ in a mesh 1089 typedef struct ufbx_edge { 1090 union { 1091 struct { uint32_t a, b; }; 1092 uint32_t indices[2]; 1093 }; 1094 } ufbx_edge; 1095 1096 UFBX_LIST_TYPE(ufbx_edge_list, ufbx_edge); 1097 1098 // Polygonal face with arbitrary number vertices, a single face contains a 1099 // contiguous range of mesh indices, eg. `{5,3}` would have indices 5, 6, 7 1100 // 1101 // NOTE: `num_indices` maybe less than 3 in which case the face is invalid! 1102 // [TODO #23: should probably remove the bad faces at load time] 1103 typedef struct ufbx_face { 1104 uint32_t index_begin; 1105 uint32_t num_indices; 1106 } ufbx_face; 1107 1108 UFBX_LIST_TYPE(ufbx_face_list, ufbx_face); 1109 1110 // Subset of mesh faces used by a single material or group. 1111 typedef struct ufbx_mesh_part { 1112 1113 // Index of the mesh part. 1114 uint32_t index; 1115 1116 // Sub-set of the geometry 1117 size_t num_faces; // < Number of faces (polygons) 1118 size_t num_triangles; // < Number of triangles if triangulated 1119 1120 size_t num_empty_faces; // < Number of faces with zero vertices 1121 size_t num_point_faces; // < Number of faces with a single vertex 1122 size_t num_line_faces; // < Number of faces with two vertices 1123 1124 // Indices to `ufbx_mesh.faces[]`. 1125 // Always contains `num_faces` elements. 1126 ufbx_uint32_list face_indices; 1127 1128 } ufbx_mesh_part; 1129 1130 UFBX_LIST_TYPE(ufbx_mesh_part_list, ufbx_mesh_part); 1131 1132 typedef struct ufbx_face_group { 1133 int32_t id; // < Numerical ID for this group. 1134 ufbx_string name; // < Name for the face group. 1135 } ufbx_face_group; 1136 1137 UFBX_LIST_TYPE(ufbx_face_group_list, ufbx_face_group); 1138 1139 typedef struct ufbx_subdivision_weight_range { 1140 uint32_t weight_begin; 1141 uint32_t num_weights; 1142 } ufbx_subdivision_weight_range; 1143 1144 UFBX_LIST_TYPE(ufbx_subdivision_weight_range_list, ufbx_subdivision_weight_range); 1145 1146 typedef struct ufbx_subdivision_weight { 1147 ufbx_real weight; 1148 uint32_t index; 1149 } ufbx_subdivision_weight; 1150 1151 UFBX_LIST_TYPE(ufbx_subdivision_weight_list, ufbx_subdivision_weight); 1152 1153 typedef struct ufbx_subdivision_result { 1154 size_t result_memory_used; 1155 size_t temp_memory_used; 1156 size_t result_allocs; 1157 size_t temp_allocs; 1158 1159 // Weights of vertices in the source model. 1160 // Defined if `ufbx_subdivide_opts.evaluate_source_vertices` is set. 1161 ufbx_subdivision_weight_range_list source_vertex_ranges; 1162 ufbx_subdivision_weight_list source_vertex_weights; 1163 1164 // Weights of skin clusters in the source model. 1165 // Defined if `ufbx_subdivide_opts.evaluate_skin_weights` is set. 1166 ufbx_subdivision_weight_range_list skin_cluster_ranges; 1167 ufbx_subdivision_weight_list skin_cluster_weights; 1168 1169 } ufbx_subdivision_result; 1170 1171 typedef enum ufbx_subdivision_display_mode UFBX_ENUM_REPR { 1172 UFBX_SUBDIVISION_DISPLAY_DISABLED, 1173 UFBX_SUBDIVISION_DISPLAY_HULL, 1174 UFBX_SUBDIVISION_DISPLAY_HULL_AND_SMOOTH, 1175 UFBX_SUBDIVISION_DISPLAY_SMOOTH, 1176 1177 UFBX_ENUM_FORCE_WIDTH(UFBX_SUBDIVISION_DISPLAY_MODE) 1178 } ufbx_subdivision_display_mode; 1179 1180 UFBX_ENUM_TYPE(ufbx_subdivision_display_mode, UFBX_SUBDIVISION_DISPLAY_MODE, UFBX_SUBDIVISION_DISPLAY_SMOOTH); 1181 1182 typedef enum ufbx_subdivision_boundary UFBX_ENUM_REPR { 1183 UFBX_SUBDIVISION_BOUNDARY_DEFAULT, 1184 UFBX_SUBDIVISION_BOUNDARY_LEGACY, 1185 // OpenSubdiv: `VTX_BOUNDARY_EDGE_AND_CORNER` / `FVAR_LINEAR_CORNERS_ONLY` 1186 UFBX_SUBDIVISION_BOUNDARY_SHARP_CORNERS, 1187 // OpenSubdiv: `VTX_BOUNDARY_EDGE_ONLY` / `FVAR_LINEAR_NONE` 1188 UFBX_SUBDIVISION_BOUNDARY_SHARP_NONE, 1189 // OpenSubdiv: `FVAR_LINEAR_BOUNDARIES` 1190 UFBX_SUBDIVISION_BOUNDARY_SHARP_BOUNDARY, 1191 // OpenSubdiv: `FVAR_LINEAR_ALL` 1192 UFBX_SUBDIVISION_BOUNDARY_SHARP_INTERIOR, 1193 1194 UFBX_ENUM_FORCE_WIDTH(UFBX_SUBDIVISION_BOUNDARY) 1195 } ufbx_subdivision_boundary; 1196 1197 UFBX_ENUM_TYPE(ufbx_subdivision_boundary, UFBX_SUBDIVISION_BOUNDARY, UFBX_SUBDIVISION_BOUNDARY_SHARP_INTERIOR); 1198 1199 // Polygonal mesh geometry. 1200 // 1201 // Example mesh with two triangles (x, z) and a quad (y). 1202 // The faces have a constant UV coordinate x/y/z. 1203 // The vertices have _per vertex_ normals that point up/down. 1204 // 1205 // ^ ^ ^ 1206 // A---B-----C 1207 // |x / /| 1208 // | / y / | 1209 // |/ / z| 1210 // D-----E---F 1211 // v v v 1212 // 1213 // Attributes may have multiple values within a single vertex, for example a 1214 // UV seam vertex has two UV coordinates. Thus polygons are defined using 1215 // an index that counts each corner of each face polygon. If an attribute is 1216 // defined (even per-vertex) it will always have a valid `indices` array. 1217 // 1218 // {0,3} {3,4} {7,3} faces ({ index_begin, num_indices }) 1219 // 0 1 2 3 4 5 6 7 8 9 index 1220 // 1221 // 0 1 3 1 2 4 3 2 4 5 vertex_indices[index] 1222 // A B D B C E D C E F vertices[vertex_indices[index]] 1223 // 1224 // 0 0 1 0 0 1 1 0 1 1 vertex_normal.indices[index] 1225 // ^ ^ v ^ ^ v v ^ v v vertex_normal.data[vertex_normal.indices[index]] 1226 // 1227 // 0 0 0 1 1 1 1 2 2 2 vertex_uv.indices[index] 1228 // x x x y y y y z z z vertex_uv.data[vertex_uv.indices[index]] 1229 // 1230 // Vertex position can also be accessed uniformly through an accessor: 1231 // 0 1 3 1 2 4 3 2 4 5 vertex_position.indices[index] 1232 // A B D B C E D C E F vertex_position.data[vertex_position.indices[index]] 1233 // 1234 // Some geometry data is specified per logical vertex. Vertex positions are 1235 // the only attribute that is guaranteed to be defined _uniquely_ per vertex. 1236 // Vertex attributes _may_ be defined per vertex if `unique_per_vertex == true`. 1237 // You can access the per-vertex values by first finding the first index that 1238 // refers to the given vertex. 1239 // 1240 // 0 1 2 3 4 5 vertex 1241 // A B C D E F vertices[vertex] 1242 // 1243 // 0 1 4 2 5 9 vertex_first_index[vertex] 1244 // 0 0 0 1 1 1 vertex_normal.indices[vertex_first_index[vertex]] 1245 // ^ ^ ^ v v v vertex_normal.data[vertex_normal.indices[vertex_first_index[vertex]]] 1246 // 1247 struct ufbx_mesh { 1248 union { ufbx_element element; struct { 1249 ufbx_string name; 1250 ufbx_props props; 1251 uint32_t element_id; 1252 uint32_t typed_id; 1253 ufbx_node_list instances; 1254 }; }; 1255 1256 // Number of "logical" vertices that would be treated as a single point, 1257 // one vertex may be split to multiple indices for split attributes, eg. UVs 1258 size_t num_vertices; // < Number of logical "vertex" points 1259 size_t num_indices; // < Number of combiend vertex/attribute tuples 1260 size_t num_faces; // < Number of faces (polygons) in the mesh 1261 size_t num_triangles; // < Number of triangles if triangulated 1262 1263 // Number of edges in the mesh. 1264 // NOTE: May be zero in valid meshes if the file doesn't contain edge adjacency data! 1265 size_t num_edges; 1266 1267 size_t max_face_triangles; // < Maximum number of triangles in a face in this mesh 1268 1269 size_t num_empty_faces; // < Number of faces with zero vertices 1270 size_t num_point_faces; // < Number of faces with a single vertex 1271 size_t num_line_faces; // < Number of faces with two vertices 1272 1273 // Faces and optional per-face extra data 1274 ufbx_face_list faces; // < Face index range 1275 ufbx_bool_list face_smoothing; // < Should the face have soft normals 1276 ufbx_uint32_list face_material; // < Indices to `ufbx_mesh.materials[]` and `ufbx_node.materials[]` 1277 ufbx_uint32_list face_group; // < Face polygon group index, indices to `ufbx_mesh.face_groups[]` 1278 ufbx_bool_list face_hole; // < Should the face be hidden as a "hole" 1279 1280 // Edges and optional per-edge extra data 1281 ufbx_edge_list edges; // < Edge index range 1282 ufbx_bool_list edge_smoothing; // < Should the edge have soft normals 1283 ufbx_real_list edge_crease; // < Crease value for subdivision surfaces 1284 ufbx_bool_list edge_visibility; // < Should the edge be visible 1285 1286 // Logical vertices and positions, alternatively you can use 1287 // `vertex_position` for consistent interface with other attributes. 1288 ufbx_uint32_list vertex_indices; 1289 ufbx_vec3_list vertices; 1290 1291 // First index referring to a given vertex, `UFBX_NO_INDEX` if the vertex is unused. 1292 ufbx_uint32_list vertex_first_index; 1293 1294 // Vertex attributes, see the comment over the struct. 1295 // 1296 // NOTE: Not all meshes have all attributes, in that case `indices/data == NULL`! 1297 // 1298 // NOTE: UV/tangent/bitangent and color are the from first sets, 1299 // use `uv_sets/color_sets` to access the other layers. 1300 ufbx_vertex_vec3 vertex_position; // < Vertex positions 1301 ufbx_vertex_vec3 vertex_normal; // < (optional) Normal vectors, always defined if `ufbx_load_opts.generate_missing_normals` 1302 ufbx_vertex_vec2 vertex_uv; // < (optional) UV / texture coordinates 1303 ufbx_vertex_vec3 vertex_tangent; // < (optional) Tangent vector in UV.x direction 1304 ufbx_vertex_vec3 vertex_bitangent; // < (optional) Tangent vector in UV.y direction 1305 ufbx_vertex_vec4 vertex_color; // < (optional) Per-vertex RGBA color 1306 ufbx_vertex_real vertex_crease; // < (optional) Crease value for subdivision surfaces 1307 1308 // Multiple named UV/color sets 1309 // NOTE: The first set contains the same data as `vertex_uv/color`! 1310 ufbx_uv_set_list uv_sets; 1311 ufbx_color_set_list color_sets; 1312 1313 // Materials used by the mesh. 1314 // NOTE: These can be wrong if you want to support per-instance materials! 1315 // Use `ufbx_node.materials[]` to get the per-instance materials at the same indices. 1316 ufbx_material_list materials; 1317 1318 // Face groups for this mesh. 1319 ufbx_face_group_list face_groups; 1320 1321 // Segments that use a given material. 1322 // Defined even if the mesh doesn't have any materials. 1323 ufbx_mesh_part_list material_parts; 1324 1325 // Segments for each face group. 1326 ufbx_mesh_part_list face_group_parts; 1327 1328 // Order of `material_parts` by first face that refers to it. 1329 // Useful for compatibility with FBX SDK and various importers using it, 1330 // as they use this material order by default. 1331 ufbx_uint32_list material_part_usage_order; 1332 1333 // Skinned vertex positions, for efficiency the skinned positions are the 1334 // same as the static ones for non-skinned meshes and `skinned_is_local` 1335 // is set to true meaning you need to transform them manually using 1336 // `ufbx_transform_position(&node->geometry_to_world, skinned_pos)`! 1337 bool skinned_is_local; 1338 ufbx_vertex_vec3 skinned_position; 1339 ufbx_vertex_vec3 skinned_normal; 1340 1341 // Deformers 1342 ufbx_skin_deformer_list skin_deformers; 1343 ufbx_blend_deformer_list blend_deformers; 1344 ufbx_cache_deformer_list cache_deformers; 1345 ufbx_element_list all_deformers; 1346 1347 // Subdivision 1348 uint32_t subdivision_preview_levels; 1349 uint32_t subdivision_render_levels; 1350 ufbx_subdivision_display_mode subdivision_display_mode; 1351 ufbx_subdivision_boundary subdivision_boundary; 1352 ufbx_subdivision_boundary subdivision_uv_boundary; 1353 1354 // The winding of the faces has been reversed. 1355 bool reversed_winding; 1356 1357 // Normals have been generated instead of evaluated. 1358 // Either from missing normals (via `ufbx_load_opts.generate_missing_normals`), skinning, 1359 // tessellation, or subdivision. 1360 bool generated_normals; 1361 1362 // Subdivision (result) 1363 bool subdivision_evaluated; 1364 ufbx_nullable ufbx_subdivision_result *subdivision_result; 1365 1366 // Tessellation (result) 1367 bool from_tessellated_nurbs; 1368 }; 1369 1370 // The kind of light source 1371 typedef enum ufbx_light_type UFBX_ENUM_REPR { 1372 // Single point at local origin, at `node->world_transform.position` 1373 UFBX_LIGHT_POINT, 1374 // Infinite directional light pointing locally towards `light->local_direction` 1375 // For global: `ufbx_transform_direction(&node->node_to_world, light->local_direction)` 1376 UFBX_LIGHT_DIRECTIONAL, 1377 // Cone shaped light towards `light->local_direction`, between `light->inner/outer_angle`. 1378 // For global: `ufbx_transform_direction(&node->node_to_world, light->local_direction)` 1379 UFBX_LIGHT_SPOT, 1380 // Area light, shape specified by `light->area_shape` 1381 // TODO: Units? 1382 UFBX_LIGHT_AREA, 1383 // Volumetric light source 1384 // TODO: How does this work 1385 UFBX_LIGHT_VOLUME, 1386 1387 UFBX_ENUM_FORCE_WIDTH(UFBX_LIGHT_TYPE) 1388 } ufbx_light_type; 1389 1390 UFBX_ENUM_TYPE(ufbx_light_type, UFBX_LIGHT_TYPE, UFBX_LIGHT_VOLUME); 1391 1392 // How fast does the light intensity decay at a distance 1393 typedef enum ufbx_light_decay UFBX_ENUM_REPR { 1394 UFBX_LIGHT_DECAY_NONE, // < 1 (no decay) 1395 UFBX_LIGHT_DECAY_LINEAR, // < 1 / d 1396 UFBX_LIGHT_DECAY_QUADRATIC, // < 1 / d^2 (physically accurate) 1397 UFBX_LIGHT_DECAY_CUBIC, // < 1 / d^3 1398 1399 UFBX_ENUM_FORCE_WIDTH(UFBX_LIGHT_DECAY) 1400 } ufbx_light_decay; 1401 1402 UFBX_ENUM_TYPE(ufbx_light_decay, UFBX_LIGHT_DECAY, UFBX_LIGHT_DECAY_CUBIC); 1403 1404 typedef enum ufbx_light_area_shape UFBX_ENUM_REPR { 1405 UFBX_LIGHT_AREA_SHAPE_RECTANGLE, 1406 UFBX_LIGHT_AREA_SHAPE_SPHERE, 1407 1408 UFBX_ENUM_FORCE_WIDTH(UFBX_LIGHT_AREA_SHAPE) 1409 } ufbx_light_area_shape; 1410 1411 UFBX_ENUM_TYPE(ufbx_light_area_shape, UFBX_LIGHT_AREA_SHAPE, UFBX_LIGHT_AREA_SHAPE_SPHERE); 1412 1413 // Light source attached to a `ufbx_node` 1414 struct ufbx_light { 1415 union { ufbx_element element; struct { 1416 ufbx_string name; 1417 ufbx_props props; 1418 uint32_t element_id; 1419 uint32_t typed_id; 1420 ufbx_node_list instances; 1421 }; }; 1422 1423 // Color and intensity of the light, usually you want to use `color * intensity` 1424 // NOTE: `intensity` is 0.01x of the property `"Intensity"` as that matches 1425 // matches values in DCC programs before exporting. 1426 ufbx_vec3 color; 1427 ufbx_real intensity; 1428 1429 // Direction the light is aimed at in node's local space, usually -Y 1430 ufbx_vec3 local_direction; 1431 1432 // Type of the light and shape parameters 1433 ufbx_light_type type; 1434 ufbx_light_decay decay; 1435 ufbx_light_area_shape area_shape; 1436 ufbx_real inner_angle; 1437 ufbx_real outer_angle; 1438 1439 bool cast_light; 1440 bool cast_shadows; 1441 }; 1442 1443 typedef enum ufbx_projection_mode UFBX_ENUM_REPR { 1444 // Perspective projection. 1445 UFBX_PROJECTION_MODE_PERSPECTIVE, 1446 1447 // Orthographic projection. 1448 UFBX_PROJECTION_MODE_ORTHOGRAPHIC, 1449 1450 UFBX_ENUM_FORCE_WIDTH(UFBX_PROJECTION_MODE) 1451 } ufbx_projection_mode; 1452 1453 UFBX_ENUM_TYPE(ufbx_projection_mode, UFBX_PROJECTION_MODE, UFBX_PROJECTION_MODE_ORTHOGRAPHIC); 1454 1455 // Method of specifying the rendering resolution from properties 1456 // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly! 1457 typedef enum ufbx_aspect_mode UFBX_ENUM_REPR { 1458 // No defined resolution 1459 UFBX_ASPECT_MODE_WINDOW_SIZE, 1460 // `"AspectWidth"` and `"AspectHeight"` are relative to each other 1461 UFBX_ASPECT_MODE_FIXED_RATIO, 1462 // `"AspectWidth"` and `"AspectHeight"` are both pixels 1463 UFBX_ASPECT_MODE_FIXED_RESOLUTION, 1464 // `"AspectWidth"` is pixels, `"AspectHeight"` is relative to width 1465 UFBX_ASPECT_MODE_FIXED_WIDTH, 1466 // < `"AspectHeight"` is pixels, `"AspectWidth"` is relative to height 1467 UFBX_ASPECT_MODE_FIXED_HEIGHT, 1468 1469 UFBX_ENUM_FORCE_WIDTH(UFBX_ASPECT_MODE) 1470 } ufbx_aspect_mode; 1471 1472 UFBX_ENUM_TYPE(ufbx_aspect_mode, UFBX_ASPECT_MODE, UFBX_ASPECT_MODE_FIXED_HEIGHT); 1473 1474 // Method of specifying the field of view from properties 1475 // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly! 1476 typedef enum ufbx_aperture_mode UFBX_ENUM_REPR { 1477 // Use separate `"FieldOfViewX"` and `"FieldOfViewY"` as horizontal/vertical FOV angles 1478 UFBX_APERTURE_MODE_HORIZONTAL_AND_VERTICAL, 1479 // Use `"FieldOfView"` as horizontal FOV angle, derive vertical angle via aspect ratio 1480 UFBX_APERTURE_MODE_HORIZONTAL, 1481 // Use `"FieldOfView"` as vertical FOV angle, derive horizontal angle via aspect ratio 1482 UFBX_APERTURE_MODE_VERTICAL, 1483 // Compute the field of view from the render gate size and focal length 1484 UFBX_APERTURE_MODE_FOCAL_LENGTH, 1485 1486 UFBX_ENUM_FORCE_WIDTH(UFBX_APERTURE_MODE) 1487 } ufbx_aperture_mode; 1488 1489 UFBX_ENUM_TYPE(ufbx_aperture_mode, UFBX_APERTURE_MODE, UFBX_APERTURE_MODE_FOCAL_LENGTH); 1490 1491 // Method of specifying the render gate size from properties 1492 // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly! 1493 typedef enum ufbx_gate_fit UFBX_ENUM_REPR { 1494 // Use the film/aperture size directly as the render gate 1495 UFBX_GATE_FIT_NONE, 1496 // Fit the render gate to the height of the film, derive width from aspect ratio 1497 UFBX_GATE_FIT_VERTICAL, 1498 // Fit the render gate to the width of the film, derive height from aspect ratio 1499 UFBX_GATE_FIT_HORIZONTAL, 1500 // Fit the render gate so that it is fully contained within the film gate 1501 UFBX_GATE_FIT_FILL, 1502 // Fit the render gate so that it fully contains the film gate 1503 UFBX_GATE_FIT_OVERSCAN, 1504 // Stretch the render gate to match the film gate 1505 // TODO: Does this differ from `UFBX_GATE_FIT_NONE`? 1506 UFBX_GATE_FIT_STRETCH, 1507 1508 UFBX_ENUM_FORCE_WIDTH(UFBX_GATE_FIT) 1509 } ufbx_gate_fit; 1510 1511 UFBX_ENUM_TYPE(ufbx_gate_fit, UFBX_GATE_FIT, UFBX_GATE_FIT_STRETCH); 1512 1513 // Camera film/aperture size defaults 1514 // NOTE: Handled internally by ufbx, ignore unless you interpret `ufbx_props` directly! 1515 typedef enum ufbx_aperture_format UFBX_ENUM_REPR { 1516 UFBX_APERTURE_FORMAT_CUSTOM, // < Use `"FilmWidth"` and `"FilmHeight"` 1517 UFBX_APERTURE_FORMAT_16MM_THEATRICAL, // < 0.404 x 0.295 inches 1518 UFBX_APERTURE_FORMAT_SUPER_16MM, // < 0.493 x 0.292 inches 1519 UFBX_APERTURE_FORMAT_35MM_ACADEMY, // < 0.864 x 0.630 inches 1520 UFBX_APERTURE_FORMAT_35MM_TV_PROJECTION, // < 0.816 x 0.612 inches 1521 UFBX_APERTURE_FORMAT_35MM_FULL_APERTURE, // < 0.980 x 0.735 inches 1522 UFBX_APERTURE_FORMAT_35MM_185_PROJECTION, // < 0.825 x 0.446 inches 1523 UFBX_APERTURE_FORMAT_35MM_ANAMORPHIC, // < 0.864 x 0.732 inches (squeeze ratio: 2) 1524 UFBX_APERTURE_FORMAT_70MM_PROJECTION, // < 2.066 x 0.906 inches 1525 UFBX_APERTURE_FORMAT_VISTAVISION, // < 1.485 x 0.991 inches 1526 UFBX_APERTURE_FORMAT_DYNAVISION, // < 2.080 x 1.480 inches 1527 UFBX_APERTURE_FORMAT_IMAX, // < 2.772 x 2.072 inches 1528 1529 UFBX_ENUM_FORCE_WIDTH(UFBX_APERTURE_FORMAT) 1530 } ufbx_aperture_format; 1531 1532 UFBX_ENUM_TYPE(ufbx_aperture_format, UFBX_APERTURE_FORMAT, UFBX_APERTURE_FORMAT_IMAX); 1533 1534 typedef enum ufbx_coordinate_axis UFBX_ENUM_REPR { 1535 UFBX_COORDINATE_AXIS_POSITIVE_X, 1536 UFBX_COORDINATE_AXIS_NEGATIVE_X, 1537 UFBX_COORDINATE_AXIS_POSITIVE_Y, 1538 UFBX_COORDINATE_AXIS_NEGATIVE_Y, 1539 UFBX_COORDINATE_AXIS_POSITIVE_Z, 1540 UFBX_COORDINATE_AXIS_NEGATIVE_Z, 1541 UFBX_COORDINATE_AXIS_UNKNOWN, 1542 1543 UFBX_ENUM_FORCE_WIDTH(UFBX_COORDINATE_AXIS) 1544 } ufbx_coordinate_axis; 1545 1546 UFBX_ENUM_TYPE(ufbx_coordinate_axis, UFBX_COORDINATE_AXIS, UFBX_COORDINATE_AXIS_UNKNOWN); 1547 1548 // Coordinate axes the scene is represented in. 1549 // NOTE: `front` is the _opposite_ from forward! 1550 typedef struct ufbx_coordinate_axes { 1551 ufbx_coordinate_axis right; 1552 ufbx_coordinate_axis up; 1553 ufbx_coordinate_axis front; 1554 } ufbx_coordinate_axes; 1555 1556 // Camera attached to a `ufbx_node` 1557 struct ufbx_camera { 1558 union { ufbx_element element; struct { 1559 ufbx_string name; 1560 ufbx_props props; 1561 uint32_t element_id; 1562 uint32_t typed_id; 1563 ufbx_node_list instances; 1564 }; }; 1565 1566 // Projection mode (perspective/orthographic). 1567 ufbx_projection_mode projection_mode; 1568 1569 // If set to `true`, `resolution` represents actual pixel values, otherwise 1570 // it's only useful for its aspect ratio. 1571 bool resolution_is_pixels; 1572 1573 // Render resolution, either in pixels or arbitrary units, depending on above 1574 ufbx_vec2 resolution; 1575 1576 // Horizontal/vertical field of view in degrees 1577 // Valid if `projection_mode == UFBX_PROJECTION_MODE_PERSPECTIVE`. 1578 ufbx_vec2 field_of_view_deg; 1579 1580 // Component-wise `tan(field_of_view_deg)`, also represents the size of the 1581 // proection frustum slice at distance of 1. 1582 // Valid if `projection_mode == UFBX_PROJECTION_MODE_PERSPECTIVE`. 1583 ufbx_vec2 field_of_view_tan; 1584 1585 // Orthographic camera extents. 1586 // Valid if `projection_mode == UFBX_PROJECTION_MODE_ORTHOGRAPHIC`. 1587 ufbx_real orthographic_extent; 1588 1589 // Orthographic camera size. 1590 // Valid if `projection_mode == UFBX_PROJECTION_MODE_ORTHOGRAPHIC`. 1591 ufbx_vec2 orthographic_size; 1592 1593 // Size of the projection plane at distance 1. 1594 // Equal to `field_of_view_tan` if perspective, `orthographic_size` if orthographic. 1595 ufbx_vec2 projection_plane; 1596 1597 // Aspect ratio of the camera. 1598 ufbx_real aspect_ratio; 1599 1600 // Near plane of the frustum in units from the camera. 1601 ufbx_real near_plane; 1602 1603 // Far plane of the frustum in units from the camera. 1604 ufbx_real far_plane; 1605 1606 // Coordinate system that the projection uses. 1607 // FBX saves cameras with +X forward and +Y up, but you can override this using 1608 // `ufbx_load_opts.target_camera_axes` and it will be reflected here. 1609 ufbx_coordinate_axes projection_axes; 1610 1611 // Advanced properties used to compute the above 1612 ufbx_aspect_mode aspect_mode; 1613 ufbx_aperture_mode aperture_mode; 1614 ufbx_gate_fit gate_fit; 1615 ufbx_aperture_format aperture_format; 1616 ufbx_real focal_length_mm; // < Focal length in millimeters 1617 ufbx_vec2 film_size_inch; // < Film size in inches 1618 ufbx_vec2 aperture_size_inch; // < Aperture/film gate size in inches 1619 ufbx_real squeeze_ratio; // < Anamoprhic stretch ratio 1620 }; 1621 1622 // Bone attached to a `ufbx_node`, provides the logical length of the bone 1623 // but most interesting information is directly in `ufbx_node`. 1624 struct ufbx_bone { 1625 union { ufbx_element element; struct { 1626 ufbx_string name; 1627 ufbx_props props; 1628 uint32_t element_id; 1629 uint32_t typed_id; 1630 ufbx_node_list instances; 1631 }; }; 1632 1633 // Visual radius of the bone 1634 ufbx_real radius; 1635 1636 // Length of the bone relative to the distance between two nodes 1637 ufbx_real relative_length; 1638 1639 // Is the bone a root bone 1640 bool is_root; 1641 }; 1642 1643 // Empty/NULL/locator connected to a node, actual details in `ufbx_node` 1644 struct ufbx_empty { 1645 union { ufbx_element element; struct { 1646 ufbx_string name; 1647 ufbx_props props; 1648 uint32_t element_id; 1649 uint32_t typed_id; 1650 ufbx_node_list instances; 1651 }; }; 1652 }; 1653 1654 // -- Node attributes (curves/surfaces) 1655 1656 // Segment of a `ufbx_line_curve`, indices refer to `ufbx_line_curve.point_indices[]` 1657 typedef struct ufbx_line_segment { 1658 uint32_t index_begin; 1659 uint32_t num_indices; 1660 } ufbx_line_segment; 1661 1662 UFBX_LIST_TYPE(ufbx_line_segment_list, ufbx_line_segment); 1663 1664 struct ufbx_line_curve { 1665 union { ufbx_element element; struct { 1666 ufbx_string name; 1667 ufbx_props props; 1668 uint32_t element_id; 1669 uint32_t typed_id; 1670 ufbx_node_list instances; 1671 }; }; 1672 1673 ufbx_vec3 color; 1674 1675 ufbx_vec3_list control_points; // < List of possible values the line passes through 1676 ufbx_uint32_list point_indices; // < Indices to `control_points[]` the line goes through 1677 1678 ufbx_line_segment_list segments; 1679 1680 // Tessellation (result) 1681 bool from_tessellated_nurbs; 1682 }; 1683 1684 typedef enum ufbx_nurbs_topology UFBX_ENUM_REPR { 1685 // The endpoints are not connected. 1686 UFBX_NURBS_TOPOLOGY_OPEN, 1687 // Repeats first `ufbx_nurbs_basis.order - 1` control points after the end. 1688 UFBX_NURBS_TOPOLOGY_PERIODIC, 1689 // Repeats the first control point after the end. 1690 UFBX_NURBS_TOPOLOGY_CLOSED, 1691 1692 UFBX_ENUM_FORCE_WIDTH(UFBX_NURBS_TOPOLOGY) 1693 } ufbx_nurbs_topology; 1694 1695 UFBX_ENUM_TYPE(ufbx_nurbs_topology, UFBX_NURBS_TOPOLOGY, UFBX_NURBS_TOPOLOGY_CLOSED); 1696 1697 // NURBS basis functions for an axis 1698 typedef struct ufbx_nurbs_basis { 1699 1700 // Number of control points influencing a point on the curve/surface. 1701 // Equal to the degree plus one. 1702 uint32_t order; 1703 1704 // Topology (periodicity) of the dimension. 1705 ufbx_nurbs_topology topology; 1706 1707 // Subdivision of the parameter range to control points. 1708 ufbx_real_list knot_vector; 1709 1710 // Range for the parameter value. 1711 ufbx_real t_min; 1712 ufbx_real t_max; 1713 1714 // Parameter values of control points. 1715 ufbx_real_list spans; 1716 1717 // `true` if this axis is two-dimensional. 1718 bool is_2d; 1719 1720 // Number of control points that need to be copied to the end. 1721 // This is just for convenience as it could be derived from `topology` and 1722 // `order`. If for example `num_wrap_control_points == 3` you should repeat 1723 // the first 3 control points after the end. 1724 // HINT: You don't need to worry about this if you use ufbx functions 1725 // like `ufbx_evaluate_nurbs_curve()` as they handle this internally. 1726 size_t num_wrap_control_points; 1727 1728 // `true` if the parametrization is well defined. 1729 bool valid; 1730 1731 } ufbx_nurbs_basis; 1732 1733 struct ufbx_nurbs_curve { 1734 union { ufbx_element element; struct { 1735 ufbx_string name; 1736 ufbx_props props; 1737 uint32_t element_id; 1738 uint32_t typed_id; 1739 ufbx_node_list instances; 1740 }; }; 1741 1742 // Basis in the U axis 1743 ufbx_nurbs_basis basis; 1744 1745 // Linear array of control points 1746 // NOTE: The control points are _not_ homogeneous, meaning you have to multiply 1747 // them by `w` before evaluating the surface. 1748 ufbx_vec4_list control_points; 1749 }; 1750 1751 struct ufbx_nurbs_surface { 1752 union { ufbx_element element; struct { 1753 ufbx_string name; 1754 ufbx_props props; 1755 uint32_t element_id; 1756 uint32_t typed_id; 1757 ufbx_node_list instances; 1758 }; }; 1759 1760 // Basis in the U/V axes 1761 ufbx_nurbs_basis basis_u; 1762 ufbx_nurbs_basis basis_v; 1763 1764 // Number of control points for the U/V axes 1765 size_t num_control_points_u; 1766 size_t num_control_points_v; 1767 1768 // 2D array of control points. 1769 // Memory layout: `V * num_control_points_u + U` 1770 // NOTE: The control points are _not_ homogeneous, meaning you have to multiply 1771 // them by `w` before evaluating the surface. 1772 ufbx_vec4_list control_points; 1773 1774 // How many segments tessellate each span in `ufbx_nurbs_basis.spans`. 1775 uint32_t span_subdivision_u; 1776 uint32_t span_subdivision_v; 1777 1778 // If `true` the resulting normals should be flipped when evaluated. 1779 bool flip_normals; 1780 1781 // Material for the whole surface. 1782 // NOTE: May be `NULL`! 1783 ufbx_nullable ufbx_material *material; 1784 }; 1785 1786 struct ufbx_nurbs_trim_surface { 1787 union { ufbx_element element; struct { 1788 ufbx_string name; 1789 ufbx_props props; 1790 uint32_t element_id; 1791 uint32_t typed_id; 1792 ufbx_node_list instances; 1793 }; }; 1794 }; 1795 1796 struct ufbx_nurbs_trim_boundary { 1797 union { ufbx_element element; struct { 1798 ufbx_string name; 1799 ufbx_props props; 1800 uint32_t element_id; 1801 uint32_t typed_id; 1802 ufbx_node_list instances; 1803 }; }; 1804 }; 1805 1806 // -- Node attributes (advanced) 1807 1808 struct ufbx_procedural_geometry { 1809 union { ufbx_element element; struct { 1810 ufbx_string name; 1811 ufbx_props props; 1812 uint32_t element_id; 1813 uint32_t typed_id; 1814 ufbx_node_list instances; 1815 }; }; 1816 }; 1817 1818 struct ufbx_stereo_camera { 1819 union { ufbx_element element; struct { 1820 ufbx_string name; 1821 ufbx_props props; 1822 uint32_t element_id; 1823 uint32_t typed_id; 1824 ufbx_node_list instances; 1825 }; }; 1826 1827 ufbx_nullable ufbx_camera *left; 1828 ufbx_nullable ufbx_camera *right; 1829 }; 1830 1831 struct ufbx_camera_switcher { 1832 union { ufbx_element element; struct { 1833 ufbx_string name; 1834 ufbx_props props; 1835 uint32_t element_id; 1836 uint32_t typed_id; 1837 ufbx_node_list instances; 1838 }; }; 1839 }; 1840 1841 typedef enum ufbx_marker_type UFBX_ENUM_REPR { 1842 UFBX_MARKER_UNKNOWN, // < Unknown marker type 1843 UFBX_MARKER_FK_EFFECTOR, // < FK (Forward Kinematics) effector 1844 UFBX_MARKER_IK_EFFECTOR, // < IK (Inverse Kinematics) effector 1845 1846 UFBX_ENUM_FORCE_WIDTH(UFBX_MARKER_TYPE) 1847 } ufbx_marker_type; 1848 1849 UFBX_ENUM_TYPE(ufbx_marker_type, UFBX_MARKER_TYPE, UFBX_MARKER_IK_EFFECTOR); 1850 1851 // Tracking marker for effectors 1852 struct ufbx_marker { 1853 union { ufbx_element element; struct { 1854 ufbx_string name; 1855 ufbx_props props; 1856 uint32_t element_id; 1857 uint32_t typed_id; 1858 ufbx_node_list instances; 1859 }; }; 1860 1861 // Type of the marker 1862 ufbx_marker_type type; 1863 }; 1864 1865 // LOD level display mode. 1866 typedef enum ufbx_lod_display UFBX_ENUM_REPR { 1867 UFBX_LOD_DISPLAY_USE_LOD, // < Display the LOD level if the distance is appropriate. 1868 UFBX_LOD_DISPLAY_SHOW, // < Always display the LOD level. 1869 UFBX_LOD_DISPLAY_HIDE, // < Never display the LOD level. 1870 1871 UFBX_ENUM_FORCE_WIDTH(UFBX_LOD_DISPLAY) 1872 } ufbx_lod_display; 1873 1874 UFBX_ENUM_TYPE(ufbx_lod_display, UFBX_LOD_DISPLAY, UFBX_LOD_DISPLAY_HIDE); 1875 1876 // Single LOD level within an LOD group. 1877 // Specifies properties of the Nth child of the _node_ containing the LOD group. 1878 typedef struct ufbx_lod_level { 1879 1880 // Minimum distance to show this LOD level. 1881 // NOTE: In world units by default, or in screen percentage if 1882 // `ufbx_lod_group.relative_distances` is set. 1883 ufbx_real distance; 1884 1885 // LOD display mode. 1886 // NOTE: Mostly for editing, you should probably ignore this 1887 // unless making a modeling program. 1888 ufbx_lod_display display; 1889 1890 } ufbx_lod_level; 1891 1892 UFBX_LIST_TYPE(ufbx_lod_level_list, ufbx_lod_level); 1893 1894 // Group of LOD (Level of Detail) levels for an object. 1895 // The actual LOD models are defined in the parent `ufbx_node.children`. 1896 struct ufbx_lod_group { 1897 union { ufbx_element element; struct { 1898 ufbx_string name; 1899 ufbx_props props; 1900 uint32_t element_id; 1901 uint32_t typed_id; 1902 ufbx_node_list instances; 1903 }; }; 1904 1905 // If set to `true`, `ufbx_lod_level.distance` represents a screen size percentage. 1906 bool relative_distances; 1907 1908 // LOD levels matching in order to `ufbx_node.children`. 1909 ufbx_lod_level_list lod_levels; 1910 1911 // If set to `true` don't account for parent transform when computing the distance. 1912 bool ignore_parent_transform; 1913 1914 // If `use_distance_limit` is enabled hide the group if the distance is not between 1915 // `distance_limit_min` and `distance_limit_max`. 1916 bool use_distance_limit; 1917 ufbx_real distance_limit_min; 1918 ufbx_real distance_limit_max; 1919 }; 1920 1921 // -- Deformers 1922 1923 // Method to evaluate the skinning on a per-vertex level 1924 typedef enum ufbx_skinning_method UFBX_ENUM_REPR { 1925 // Linear blend skinning: Blend transformation matrices by vertex weights 1926 UFBX_SKINNING_METHOD_LINEAR, 1927 // One vertex should have only one bone attached 1928 UFBX_SKINNING_METHOD_RIGID, 1929 // Convert the transformations to dual quaternions and blend in that space 1930 UFBX_SKINNING_METHOD_DUAL_QUATERNION, 1931 // Blend between `UFBX_SKINNING_METHOD_LINEAR` and `UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR` 1932 // The blend weight can be found either per-vertex in `ufbx_skin_vertex.dq_weight` 1933 // or in `ufbx_skin_deformer.dq_vertices/dq_weights` (indexed by vertex). 1934 UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR, 1935 1936 UFBX_ENUM_FORCE_WIDTH(UFBX_SKINNING_METHOD) 1937 } ufbx_skinning_method; 1938 1939 UFBX_ENUM_TYPE(ufbx_skinning_method, UFBX_SKINNING_METHOD, UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR); 1940 1941 // Skin weight information for a single mesh vertex 1942 typedef struct ufbx_skin_vertex { 1943 1944 // Each vertex is influenced by weights from `ufbx_skin_deformer.weights[]` 1945 // The weights are sorted by decreasing weight so you can take the first N 1946 // weights to get a cheaper approximation of the vertex. 1947 // NOTE: The weights are not guaranteed to be normalized! 1948 uint32_t weight_begin; // < Index to start from in the `weights[]` array 1949 uint32_t num_weights; // < Number of weights influencing the vertex 1950 1951 // Blend weight between Linear Blend Skinning (0.0) and Dual Quaternion (1.0). 1952 // Should be used if `skinning_method == UFBX_SKINNING_METHOD_BLENDED_DQ_LINEAR` 1953 ufbx_real dq_weight; 1954 1955 } ufbx_skin_vertex; 1956 1957 UFBX_LIST_TYPE(ufbx_skin_vertex_list, ufbx_skin_vertex); 1958 1959 // Single per-vertex per-cluster weight, see `ufbx_skin_vertex` 1960 typedef struct ufbx_skin_weight { 1961 uint32_t cluster_index; // < Index into `ufbx_skin_deformer.clusters[]` 1962 ufbx_real weight; // < Amount this bone influence the vertex 1963 } ufbx_skin_weight; 1964 1965 UFBX_LIST_TYPE(ufbx_skin_weight_list, ufbx_skin_weight); 1966 1967 // Skin deformer specifies a binding between a logical set of bones (a skeleton) 1968 // and a mesh. Each bone is represented by a `ufbx_skin_cluster` that contains 1969 // the binding matrix and a `ufbx_node *bone` that has the current transformation. 1970 struct ufbx_skin_deformer { 1971 union { ufbx_element element; struct { 1972 ufbx_string name; 1973 ufbx_props props; 1974 uint32_t element_id; 1975 uint32_t typed_id; 1976 }; }; 1977 1978 ufbx_skinning_method skinning_method; 1979 1980 // Clusters (bones) in the skin 1981 ufbx_skin_cluster_list clusters; 1982 1983 // Per-vertex weight information 1984 ufbx_skin_vertex_list vertices; 1985 ufbx_skin_weight_list weights; 1986 1987 // Largest amount of weights a single vertex can have 1988 size_t max_weights_per_vertex; 1989 1990 // Blend weights between Linear Blend Skinning (0.0) and Dual Quaternion (1.0). 1991 // HINT: You probably want to use `vertices` and `ufbx_skin_vertex.dq_weight` instead! 1992 // NOTE: These may be out-of-bounds for a given mesh, `vertices` is always safe. 1993 size_t num_dq_weights; 1994 ufbx_uint32_list dq_vertices; 1995 ufbx_real_list dq_weights; 1996 }; 1997 1998 // Cluster of vertices bound to a single bone. 1999 struct ufbx_skin_cluster { 2000 union { ufbx_element element; struct { 2001 ufbx_string name; 2002 ufbx_props props; 2003 uint32_t element_id; 2004 uint32_t typed_id; 2005 }; }; 2006 2007 // The bone node the cluster is attached to 2008 // NOTE: Always valid if found from `ufbx_skin_deformer.clusters[]` unless 2009 // `ufbx_load_opts.connect_broken_elements` is `true`. 2010 ufbx_nullable ufbx_node *bone_node; 2011 2012 // Binding matrix from local mesh vertices to the bone 2013 ufbx_matrix geometry_to_bone; 2014 2015 // Binding matrix from local mesh _node_ to the bone. 2016 // NOTE: Prefer `geometry_to_bone` in most use cases! 2017 ufbx_matrix mesh_node_to_bone; 2018 2019 // Matrix that specifies the rest/bind pose transform of the node, 2020 // not generally needed for skinning, use `geometry_to_bone` instead. 2021 ufbx_matrix bind_to_world; 2022 2023 // Precomputed matrix/transform that accounts for the current bone transform 2024 // ie. `ufbx_matrix_mul(&cluster->bone->node_to_world, &cluster->geometry_to_bone)` 2025 ufbx_matrix geometry_to_world; 2026 ufbx_transform geometry_to_world_transform; 2027 2028 // Raw weights indexed by each _vertex_ of a mesh (not index!) 2029 // HINT: It may be simpler to use `ufbx_skin_deformer.vertices[]/weights[]` instead! 2030 // NOTE: These may be out-of-bounds for a given mesh, `ufbx_skin_deformer.vertices` is always safe. 2031 size_t num_weights; // < Number of vertices in the cluster 2032 ufbx_uint32_list vertices; // < Vertex indices in `ufbx_mesh.vertices[]` 2033 ufbx_real_list weights; // < Per-vertex weight values 2034 }; 2035 2036 // Blend shape deformer can contain multiple channels (think of sliders between morphs) 2037 // that may optionally have in-between keyframes. 2038 struct ufbx_blend_deformer { 2039 union { ufbx_element element; struct { 2040 ufbx_string name; 2041 ufbx_props props; 2042 uint32_t element_id; 2043 uint32_t typed_id; 2044 }; }; 2045 2046 // Independent morph targets of the deformer. 2047 ufbx_blend_channel_list channels; 2048 }; 2049 2050 // Blend shape associated with a target weight in a series of morphs 2051 typedef struct ufbx_blend_keyframe { 2052 // The target blend shape offsets. 2053 ufbx_blend_shape *shape; 2054 2055 // Weight value at which to apply the keyframe at full strength 2056 ufbx_real target_weight; 2057 2058 // The weight the shape should be currently applied with 2059 ufbx_real effective_weight; 2060 } ufbx_blend_keyframe; 2061 2062 UFBX_LIST_TYPE(ufbx_blend_keyframe_list, ufbx_blend_keyframe); 2063 2064 // Blend channel consists of multiple morph-key targets that are interpolated. 2065 // In simple cases there will be only one keyframe that is the target shape. 2066 struct ufbx_blend_channel { 2067 union { ufbx_element element; struct { 2068 ufbx_string name; 2069 ufbx_props props; 2070 uint32_t element_id; 2071 uint32_t typed_id; 2072 }; }; 2073 2074 // Current weight of the channel 2075 ufbx_real weight; 2076 2077 // Key morph targets to blend between depending on `weight` 2078 // In usual cases there's only one target per channel 2079 ufbx_blend_keyframe_list keyframes; 2080 2081 // Final blend shape ignoring any intermediate blend shapes. 2082 ufbx_nullable ufbx_blend_shape *target_shape; 2083 }; 2084 2085 // Blend shape target containing the actual vertex offsets 2086 struct ufbx_blend_shape { 2087 union { ufbx_element element; struct { 2088 ufbx_string name; 2089 ufbx_props props; 2090 uint32_t element_id; 2091 uint32_t typed_id; 2092 }; }; 2093 2094 // Vertex offsets to apply over the base mesh 2095 // NOTE: The `offset_vertices` may be out-of-bounds for a given mesh! 2096 size_t num_offsets; // < Number of vertex offsets in the following arrays 2097 ufbx_uint32_list offset_vertices; // < Indices to `ufbx_mesh.vertices[]` 2098 ufbx_vec3_list position_offsets; // < Always specified per-vertex offsets 2099 ufbx_vec3_list normal_offsets; // < Empty if not specified 2100 }; 2101 2102 typedef enum ufbx_cache_file_format UFBX_ENUM_REPR { 2103 UFBX_CACHE_FILE_FORMAT_UNKNOWN, // < Unknown cache file format 2104 UFBX_CACHE_FILE_FORMAT_PC2, // < .pc2 Point cache file 2105 UFBX_CACHE_FILE_FORMAT_MC, // < .mc/.mcx Maya cache file 2106 2107 UFBX_ENUM_FORCE_WIDTH(UFBX_CACHE_FILE_FORMAT) 2108 } ufbx_cache_file_format; 2109 2110 UFBX_ENUM_TYPE(ufbx_cache_file_format, UFBX_CACHE_FILE_FORMAT, UFBX_CACHE_FILE_FORMAT_MC); 2111 2112 typedef enum ufbx_cache_data_format UFBX_ENUM_REPR { 2113 UFBX_CACHE_DATA_FORMAT_UNKNOWN, // < Unknown data format 2114 UFBX_CACHE_DATA_FORMAT_REAL_FLOAT, // < `float data[]` 2115 UFBX_CACHE_DATA_FORMAT_VEC3_FLOAT, // < `struct { float x, y, z; } data[]` 2116 UFBX_CACHE_DATA_FORMAT_REAL_DOUBLE, // < `double data[]` 2117 UFBX_CACHE_DATA_FORMAT_VEC3_DOUBLE, // < `struct { double x, y, z; } data[]` 2118 2119 UFBX_ENUM_FORCE_WIDTH(UFBX_CACHE_DATA_FORMAT) 2120 } ufbx_cache_data_format; 2121 2122 UFBX_ENUM_TYPE(ufbx_cache_data_format, UFBX_CACHE_DATA_FORMAT, UFBX_CACHE_DATA_FORMAT_VEC3_DOUBLE); 2123 2124 typedef enum ufbx_cache_data_encoding UFBX_ENUM_REPR { 2125 UFBX_CACHE_DATA_ENCODING_UNKNOWN, // < Unknown data encoding 2126 UFBX_CACHE_DATA_ENCODING_LITTLE_ENDIAN, // < Contiguous little-endian array 2127 UFBX_CACHE_DATA_ENCODING_BIG_ENDIAN, // < Contiguous big-endian array 2128 2129 UFBX_ENUM_FORCE_WIDTH(UFBX_CACHE_DATA_ENCODING) 2130 } ufbx_cache_data_encoding; 2131 2132 UFBX_ENUM_TYPE(ufbx_cache_data_encoding, UFBX_CACHE_DATA_ENCODING, UFBX_CACHE_DATA_ENCODING_BIG_ENDIAN); 2133 2134 // Known interpretations of geometry cache data. 2135 typedef enum ufbx_cache_interpretation UFBX_ENUM_REPR { 2136 // Unknown interpretation, see `ufbx_cache_channel.interpretation_name` for more information. 2137 UFBX_CACHE_INTERPRETATION_UNKNOWN, 2138 2139 // Generic "points" interpretation, FBX SDK default. Usually fine to interpret 2140 // as vertex positions if no other cache channels are specified. 2141 UFBX_CACHE_INTERPRETATION_POINTS, 2142 2143 // Vertex positions. 2144 UFBX_CACHE_INTERPRETATION_VERTEX_POSITION, 2145 2146 // Vertex normals. 2147 UFBX_CACHE_INTERPRETATION_VERTEX_NORMAL, 2148 2149 UFBX_ENUM_FORCE_WIDTH(UFBX_CACHE_INTERPRETATION) 2150 } ufbx_cache_interpretation; 2151 2152 UFBX_ENUM_TYPE(ufbx_cache_interpretation, UFBX_CACHE_INTERPRETATION, UFBX_CACHE_INTERPRETATION_VERTEX_NORMAL); 2153 2154 typedef struct ufbx_cache_frame { 2155 2156 // Name of the channel this frame belongs to. 2157 ufbx_string channel; 2158 2159 // Time of this frame in seconds. 2160 double time; 2161 2162 // Name of the file containing the data. 2163 // The specified file may contain multiple frames, use `data_offset` etc. to 2164 // read at the right position. 2165 ufbx_string filename; 2166 2167 // Format of the wrapper file. 2168 ufbx_cache_file_format file_format; 2169 2170 // Axis to mirror the read data by. 2171 ufbx_mirror_axis mirror_axis; 2172 2173 // Factor to scale the geometry by. 2174 ufbx_real scale_factor; 2175 2176 ufbx_cache_data_format data_format; // < Format of the data in the file 2177 ufbx_cache_data_encoding data_encoding; // < Binary encoding of the data 2178 uint64_t data_offset; // < Byte offset into the file 2179 uint32_t data_count; // < Number of data elements 2180 uint32_t data_element_bytes; // < Size of a single data element in bytes 2181 uint64_t data_total_bytes; // < Size of the whole data blob in bytes 2182 } ufbx_cache_frame; 2183 2184 UFBX_LIST_TYPE(ufbx_cache_frame_list, ufbx_cache_frame); 2185 2186 typedef struct ufbx_cache_channel { 2187 2188 // Name of the geometry cache channel. 2189 ufbx_string name; 2190 2191 // What does the data in this channel represent. 2192 ufbx_cache_interpretation interpretation; 2193 2194 // Source name for `interpretation`, especially useful if `interpretation` is 2195 // `UFBX_CACHE_INTERPRETATION_UNKNOWN`. 2196 ufbx_string interpretation_name; 2197 2198 // List of frames belonging to this channel. 2199 // Sorted by time (`ufbx_cache_frame.time`). 2200 ufbx_cache_frame_list frames; 2201 2202 // Axis to mirror the frames by. 2203 ufbx_mirror_axis mirror_axis; 2204 2205 // Factor to scale the geometry by. 2206 ufbx_real scale_factor; 2207 2208 } ufbx_cache_channel; 2209 2210 UFBX_LIST_TYPE(ufbx_cache_channel_list, ufbx_cache_channel); 2211 2212 typedef struct ufbx_geometry_cache { 2213 ufbx_string root_filename; 2214 ufbx_cache_channel_list channels; 2215 ufbx_cache_frame_list frames; 2216 ufbx_string_list extra_info; 2217 } ufbx_geometry_cache; 2218 2219 struct ufbx_cache_deformer { 2220 union { ufbx_element element; struct { 2221 ufbx_string name; 2222 ufbx_props props; 2223 uint32_t element_id; 2224 uint32_t typed_id; 2225 }; }; 2226 2227 ufbx_string channel; 2228 ufbx_nullable ufbx_cache_file *file; 2229 2230 // Only valid if `ufbx_load_opts.load_external_files` is set! 2231 ufbx_nullable ufbx_geometry_cache *external_cache; 2232 ufbx_nullable ufbx_cache_channel *external_channel; 2233 }; 2234 2235 struct ufbx_cache_file { 2236 union { ufbx_element element; struct { 2237 ufbx_string name; 2238 ufbx_props props; 2239 uint32_t element_id; 2240 uint32_t typed_id; 2241 }; }; 2242 2243 // Filename relative to the currently loaded file. 2244 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2245 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2246 ufbx_string filename; 2247 // Absolute filename specified in the file. 2248 ufbx_string absolute_filename; 2249 // Relative filename specified in the file. 2250 // NOTE: May be absolute if the file is saved in a different drive. 2251 ufbx_string relative_filename; 2252 2253 // Filename relative to the loaded file, non-UTF-8 encoded. 2254 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2255 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2256 ufbx_blob raw_filename; 2257 // Absolute filename specified in the file, non-UTF-8 encoded. 2258 ufbx_blob raw_absolute_filename; 2259 // Relative filename specified in the file, non-UTF-8 encoded. 2260 // NOTE: May be absolute if the file is saved in a different drive. 2261 ufbx_blob raw_relative_filename; 2262 2263 ufbx_cache_file_format format; 2264 2265 // Only valid if `ufbx_load_opts.load_external_files` is set! 2266 ufbx_nullable ufbx_geometry_cache *external_cache; 2267 }; 2268 2269 // -- Materials 2270 2271 // Material property, either specified with a constant value or a mapped texture 2272 typedef struct ufbx_material_map { 2273 2274 // Constant value or factor for the map. 2275 // May be specified simultaneously with a texture, in this case most shading models 2276 // use multiplicative tinting of the texture values. 2277 union { 2278 ufbx_real value_real; 2279 ufbx_vec2 value_vec2; 2280 ufbx_vec3 value_vec3; 2281 ufbx_vec4 value_vec4; 2282 }; 2283 int64_t value_int; 2284 2285 // Texture if connected, otherwise `NULL`. 2286 // May be valid but "disabled" (application specific) if `texture_enabled == false`. 2287 ufbx_nullable ufbx_texture *texture; 2288 2289 // `true` if the file has specified any of the values above. 2290 // NOTE: The value may be set to a non-zero default even if `has_value == false`, 2291 // for example missing factors are set to `1.0` if a color is defined. 2292 bool has_value; 2293 2294 // Controls whether shading should use `texture`. 2295 // NOTE: Some shading models allow this to be `true` even if `texture == NULL`. 2296 bool texture_enabled; 2297 2298 // Set to `true` if this feature should be disabled (specific to shader type). 2299 bool feature_disabled; 2300 2301 // Number of components in the value from 1 to 4 if defined, 0 if not. 2302 uint8_t value_components; 2303 2304 } ufbx_material_map; 2305 2306 // Material feature 2307 typedef struct ufbx_material_feature_info { 2308 2309 // Whether the material model uses this feature or not. 2310 // NOTE: The feature can be enabled but still not used if eg. the corresponding factor is at zero! 2311 bool enabled; 2312 2313 // Explicitly enabled/disabled by the material. 2314 bool is_explicit; 2315 2316 } ufbx_material_feature_info; 2317 2318 // Texture attached to an FBX property 2319 typedef struct ufbx_material_texture { 2320 ufbx_string material_prop; // < Name of the property in `ufbx_material.props` 2321 ufbx_string shader_prop; // < Shader-specific property mapping name 2322 2323 // Texture attached to the property. 2324 ufbx_texture *texture; 2325 2326 } ufbx_material_texture; 2327 2328 UFBX_LIST_TYPE(ufbx_material_texture_list, ufbx_material_texture); 2329 2330 // Shading model type 2331 typedef enum ufbx_shader_type UFBX_ENUM_REPR { 2332 // Unknown shading model 2333 UFBX_SHADER_UNKNOWN, 2334 // FBX builtin diffuse material 2335 UFBX_SHADER_FBX_LAMBERT, 2336 // FBX builtin diffuse+specular material 2337 UFBX_SHADER_FBX_PHONG, 2338 // Open Shading Language standard surface 2339 // https://github.com/Autodesk/standard-surface 2340 UFBX_SHADER_OSL_STANDARD_SURFACE, 2341 // Arnold standard surface 2342 // https://docs.arnoldrenderer.com/display/A5AFMUG/Standard+Surface 2343 UFBX_SHADER_ARNOLD_STANDARD_SURFACE, 2344 // 3ds Max Physical Material 2345 // https://knowledge.autodesk.com/support/3ds-max/learn-explore/caas/CloudHelp/cloudhelp/2022/ENU/3DSMax-Lighting-Shading/files/GUID-C1328905-7783-4917-AB86-FC3CC19E8972-htm.html 2346 UFBX_SHADER_3DS_MAX_PHYSICAL_MATERIAL, 2347 // 3ds Max PBR (Metal/Rough) material 2348 // https://knowledge.autodesk.com/support/3ds-max/learn-explore/caas/CloudHelp/cloudhelp/2021/ENU/3DSMax-Lighting-Shading/files/GUID-A16234A5-6500-4662-8B20-A5EC9FE1B255-htm.html 2349 UFBX_SHADER_3DS_MAX_PBR_METAL_ROUGH, 2350 // 3ds Max PBR (Spec/Gloss) material 2351 // https://knowledge.autodesk.com/support/3ds-max/learn-explore/caas/CloudHelp/cloudhelp/2021/ENU/3DSMax-Lighting-Shading/files/GUID-18087194-B2A6-43EF-9B80-8FD1736FAE52-htm.html 2352 UFBX_SHADER_3DS_MAX_PBR_SPEC_GLOSS, 2353 // 3ds glTF Material 2354 // https://help.autodesk.com/view/3DSMAX/2023/ENU/?guid=GUID-7ABFB805-1D9F-417E-9C22-704BFDF160FA 2355 UFBX_SHADER_GLTF_MATERIAL, 2356 // 3ds OpenPBR Material 2357 // https://help.autodesk.com/view/3DSMAX/2025/ENU/?guid=GUID-CD90329C-1E2B-4BBA-9285-3BB46253B9C2 2358 UFBX_SHADER_OPENPBR_MATERIAL, 2359 // Stingray ShaderFX shader graph. 2360 // Contains a serialized `"ShaderGraph"` in `ufbx_props`. 2361 UFBX_SHADER_SHADERFX_GRAPH, 2362 // Variation of the FBX phong shader that can recover PBR properties like 2363 // `metalness` or `roughness` from the FBX non-physical values. 2364 // NOTE: Enable `ufbx_load_opts.use_blender_pbr_material`. 2365 UFBX_SHADER_BLENDER_PHONG, 2366 // Wavefront .mtl format shader (used by .obj files) 2367 UFBX_SHADER_WAVEFRONT_MTL, 2368 2369 UFBX_ENUM_FORCE_WIDTH(UFBX_SHADER_TYPE) 2370 } ufbx_shader_type; 2371 2372 UFBX_ENUM_TYPE(ufbx_shader_type, UFBX_SHADER_TYPE, UFBX_SHADER_WAVEFRONT_MTL); 2373 2374 // FBX builtin material properties, matches maps in `ufbx_material_fbx_maps` 2375 typedef enum ufbx_material_fbx_map UFBX_ENUM_REPR { 2376 UFBX_MATERIAL_FBX_DIFFUSE_FACTOR, 2377 UFBX_MATERIAL_FBX_DIFFUSE_COLOR, 2378 UFBX_MATERIAL_FBX_SPECULAR_FACTOR, 2379 UFBX_MATERIAL_FBX_SPECULAR_COLOR, 2380 UFBX_MATERIAL_FBX_SPECULAR_EXPONENT, 2381 UFBX_MATERIAL_FBX_REFLECTION_FACTOR, 2382 UFBX_MATERIAL_FBX_REFLECTION_COLOR, 2383 UFBX_MATERIAL_FBX_TRANSPARENCY_FACTOR, 2384 UFBX_MATERIAL_FBX_TRANSPARENCY_COLOR, 2385 UFBX_MATERIAL_FBX_EMISSION_FACTOR, 2386 UFBX_MATERIAL_FBX_EMISSION_COLOR, 2387 UFBX_MATERIAL_FBX_AMBIENT_FACTOR, 2388 UFBX_MATERIAL_FBX_AMBIENT_COLOR, 2389 UFBX_MATERIAL_FBX_NORMAL_MAP, 2390 UFBX_MATERIAL_FBX_BUMP, 2391 UFBX_MATERIAL_FBX_BUMP_FACTOR, 2392 UFBX_MATERIAL_FBX_DISPLACEMENT_FACTOR, 2393 UFBX_MATERIAL_FBX_DISPLACEMENT, 2394 UFBX_MATERIAL_FBX_VECTOR_DISPLACEMENT_FACTOR, 2395 UFBX_MATERIAL_FBX_VECTOR_DISPLACEMENT, 2396 2397 UFBX_ENUM_FORCE_WIDTH(UFBX_MATERIAL_FBX_MAP) 2398 } ufbx_material_fbx_map; 2399 2400 UFBX_ENUM_TYPE(ufbx_material_fbx_map, UFBX_MATERIAL_FBX_MAP, UFBX_MATERIAL_FBX_VECTOR_DISPLACEMENT); 2401 2402 // Known PBR material properties, matches maps in `ufbx_material_pbr_maps` 2403 typedef enum ufbx_material_pbr_map UFBX_ENUM_REPR { 2404 UFBX_MATERIAL_PBR_BASE_FACTOR, 2405 UFBX_MATERIAL_PBR_BASE_COLOR, 2406 UFBX_MATERIAL_PBR_ROUGHNESS, 2407 UFBX_MATERIAL_PBR_METALNESS, 2408 UFBX_MATERIAL_PBR_DIFFUSE_ROUGHNESS, 2409 UFBX_MATERIAL_PBR_SPECULAR_FACTOR, 2410 UFBX_MATERIAL_PBR_SPECULAR_COLOR, 2411 UFBX_MATERIAL_PBR_SPECULAR_IOR, 2412 UFBX_MATERIAL_PBR_SPECULAR_ANISOTROPY, 2413 UFBX_MATERIAL_PBR_SPECULAR_ROTATION, 2414 UFBX_MATERIAL_PBR_TRANSMISSION_FACTOR, 2415 UFBX_MATERIAL_PBR_TRANSMISSION_COLOR, 2416 UFBX_MATERIAL_PBR_TRANSMISSION_DEPTH, 2417 UFBX_MATERIAL_PBR_TRANSMISSION_SCATTER, 2418 UFBX_MATERIAL_PBR_TRANSMISSION_SCATTER_ANISOTROPY, 2419 UFBX_MATERIAL_PBR_TRANSMISSION_DISPERSION, 2420 UFBX_MATERIAL_PBR_TRANSMISSION_ROUGHNESS, 2421 UFBX_MATERIAL_PBR_TRANSMISSION_EXTRA_ROUGHNESS, 2422 UFBX_MATERIAL_PBR_TRANSMISSION_PRIORITY, 2423 UFBX_MATERIAL_PBR_TRANSMISSION_ENABLE_IN_AOV, 2424 UFBX_MATERIAL_PBR_SUBSURFACE_FACTOR, 2425 UFBX_MATERIAL_PBR_SUBSURFACE_COLOR, 2426 UFBX_MATERIAL_PBR_SUBSURFACE_RADIUS, 2427 UFBX_MATERIAL_PBR_SUBSURFACE_SCALE, 2428 UFBX_MATERIAL_PBR_SUBSURFACE_ANISOTROPY, 2429 UFBX_MATERIAL_PBR_SUBSURFACE_TINT_COLOR, 2430 UFBX_MATERIAL_PBR_SUBSURFACE_TYPE, 2431 UFBX_MATERIAL_PBR_SHEEN_FACTOR, 2432 UFBX_MATERIAL_PBR_SHEEN_COLOR, 2433 UFBX_MATERIAL_PBR_SHEEN_ROUGHNESS, 2434 UFBX_MATERIAL_PBR_COAT_FACTOR, 2435 UFBX_MATERIAL_PBR_COAT_COLOR, 2436 UFBX_MATERIAL_PBR_COAT_ROUGHNESS, 2437 UFBX_MATERIAL_PBR_COAT_IOR, 2438 UFBX_MATERIAL_PBR_COAT_ANISOTROPY, 2439 UFBX_MATERIAL_PBR_COAT_ROTATION, 2440 UFBX_MATERIAL_PBR_COAT_NORMAL, 2441 UFBX_MATERIAL_PBR_COAT_AFFECT_BASE_COLOR, 2442 UFBX_MATERIAL_PBR_COAT_AFFECT_BASE_ROUGHNESS, 2443 UFBX_MATERIAL_PBR_THIN_FILM_FACTOR, 2444 UFBX_MATERIAL_PBR_THIN_FILM_THICKNESS, 2445 UFBX_MATERIAL_PBR_THIN_FILM_IOR, 2446 UFBX_MATERIAL_PBR_EMISSION_FACTOR, 2447 UFBX_MATERIAL_PBR_EMISSION_COLOR, 2448 UFBX_MATERIAL_PBR_OPACITY, 2449 UFBX_MATERIAL_PBR_INDIRECT_DIFFUSE, 2450 UFBX_MATERIAL_PBR_INDIRECT_SPECULAR, 2451 UFBX_MATERIAL_PBR_NORMAL_MAP, 2452 UFBX_MATERIAL_PBR_TANGENT_MAP, 2453 UFBX_MATERIAL_PBR_DISPLACEMENT_MAP, 2454 UFBX_MATERIAL_PBR_MATTE_FACTOR, 2455 UFBX_MATERIAL_PBR_MATTE_COLOR, 2456 UFBX_MATERIAL_PBR_AMBIENT_OCCLUSION, 2457 UFBX_MATERIAL_PBR_GLOSSINESS, 2458 UFBX_MATERIAL_PBR_COAT_GLOSSINESS, 2459 UFBX_MATERIAL_PBR_TRANSMISSION_GLOSSINESS, 2460 2461 UFBX_ENUM_FORCE_WIDTH(UFBX_MATERIAL_PBR_MAP) 2462 } ufbx_material_pbr_map; 2463 2464 UFBX_ENUM_TYPE(ufbx_material_pbr_map, UFBX_MATERIAL_PBR_MAP, UFBX_MATERIAL_PBR_TRANSMISSION_GLOSSINESS); 2465 2466 // Known material features 2467 typedef enum ufbx_material_feature UFBX_ENUM_REPR { 2468 UFBX_MATERIAL_FEATURE_PBR, 2469 UFBX_MATERIAL_FEATURE_METALNESS, 2470 UFBX_MATERIAL_FEATURE_DIFFUSE, 2471 UFBX_MATERIAL_FEATURE_SPECULAR, 2472 UFBX_MATERIAL_FEATURE_EMISSION, 2473 UFBX_MATERIAL_FEATURE_TRANSMISSION, 2474 UFBX_MATERIAL_FEATURE_COAT, 2475 UFBX_MATERIAL_FEATURE_SHEEN, 2476 UFBX_MATERIAL_FEATURE_OPACITY, 2477 UFBX_MATERIAL_FEATURE_AMBIENT_OCCLUSION, 2478 UFBX_MATERIAL_FEATURE_MATTE, 2479 UFBX_MATERIAL_FEATURE_UNLIT, 2480 UFBX_MATERIAL_FEATURE_IOR, 2481 UFBX_MATERIAL_FEATURE_DIFFUSE_ROUGHNESS, 2482 UFBX_MATERIAL_FEATURE_TRANSMISSION_ROUGHNESS, 2483 UFBX_MATERIAL_FEATURE_THIN_WALLED, 2484 UFBX_MATERIAL_FEATURE_CAUSTICS, 2485 UFBX_MATERIAL_FEATURE_EXIT_TO_BACKGROUND, 2486 UFBX_MATERIAL_FEATURE_INTERNAL_REFLECTIONS, 2487 UFBX_MATERIAL_FEATURE_DOUBLE_SIDED, 2488 UFBX_MATERIAL_FEATURE_ROUGHNESS_AS_GLOSSINESS, 2489 UFBX_MATERIAL_FEATURE_COAT_ROUGHNESS_AS_GLOSSINESS, 2490 UFBX_MATERIAL_FEATURE_TRANSMISSION_ROUGHNESS_AS_GLOSSINESS, 2491 2492 UFBX_ENUM_FORCE_WIDTH(UFBX_MATERIAL_FEATURE) 2493 } ufbx_material_feature; 2494 2495 UFBX_ENUM_TYPE(ufbx_material_feature, UFBX_MATERIAL_FEATURE, UFBX_MATERIAL_FEATURE_TRANSMISSION_ROUGHNESS_AS_GLOSSINESS); 2496 2497 typedef struct ufbx_material_fbx_maps { 2498 union { 2499 ufbx_material_map maps[UFBX_MATERIAL_FBX_MAP_COUNT]; 2500 struct { 2501 ufbx_material_map diffuse_factor; 2502 ufbx_material_map diffuse_color; 2503 ufbx_material_map specular_factor; 2504 ufbx_material_map specular_color; 2505 ufbx_material_map specular_exponent; 2506 ufbx_material_map reflection_factor; 2507 ufbx_material_map reflection_color; 2508 ufbx_material_map transparency_factor; 2509 ufbx_material_map transparency_color; 2510 ufbx_material_map emission_factor; 2511 ufbx_material_map emission_color; 2512 ufbx_material_map ambient_factor; 2513 ufbx_material_map ambient_color; 2514 ufbx_material_map normal_map; 2515 ufbx_material_map bump; 2516 ufbx_material_map bump_factor; 2517 ufbx_material_map displacement_factor; 2518 ufbx_material_map displacement; 2519 ufbx_material_map vector_displacement_factor; 2520 ufbx_material_map vector_displacement; 2521 }; 2522 }; 2523 } ufbx_material_fbx_maps; 2524 2525 typedef struct ufbx_material_pbr_maps { 2526 union { 2527 ufbx_material_map maps[UFBX_MATERIAL_PBR_MAP_COUNT]; 2528 struct { 2529 ufbx_material_map base_factor; 2530 ufbx_material_map base_color; 2531 ufbx_material_map roughness; 2532 ufbx_material_map metalness; 2533 ufbx_material_map diffuse_roughness; 2534 ufbx_material_map specular_factor; 2535 ufbx_material_map specular_color; 2536 ufbx_material_map specular_ior; 2537 ufbx_material_map specular_anisotropy; 2538 ufbx_material_map specular_rotation; 2539 ufbx_material_map transmission_factor; 2540 ufbx_material_map transmission_color; 2541 ufbx_material_map transmission_depth; 2542 ufbx_material_map transmission_scatter; 2543 ufbx_material_map transmission_scatter_anisotropy; 2544 ufbx_material_map transmission_dispersion; 2545 ufbx_material_map transmission_roughness; 2546 ufbx_material_map transmission_extra_roughness; 2547 ufbx_material_map transmission_priority; 2548 ufbx_material_map transmission_enable_in_aov; 2549 ufbx_material_map subsurface_factor; 2550 ufbx_material_map subsurface_color; 2551 ufbx_material_map subsurface_radius; 2552 ufbx_material_map subsurface_scale; 2553 ufbx_material_map subsurface_anisotropy; 2554 ufbx_material_map subsurface_tint_color; 2555 ufbx_material_map subsurface_type; 2556 ufbx_material_map sheen_factor; 2557 ufbx_material_map sheen_color; 2558 ufbx_material_map sheen_roughness; 2559 ufbx_material_map coat_factor; 2560 ufbx_material_map coat_color; 2561 ufbx_material_map coat_roughness; 2562 ufbx_material_map coat_ior; 2563 ufbx_material_map coat_anisotropy; 2564 ufbx_material_map coat_rotation; 2565 ufbx_material_map coat_normal; 2566 ufbx_material_map coat_affect_base_color; 2567 ufbx_material_map coat_affect_base_roughness; 2568 ufbx_material_map thin_film_factor; 2569 ufbx_material_map thin_film_thickness; 2570 ufbx_material_map thin_film_ior; 2571 ufbx_material_map emission_factor; 2572 ufbx_material_map emission_color; 2573 ufbx_material_map opacity; 2574 ufbx_material_map indirect_diffuse; 2575 ufbx_material_map indirect_specular; 2576 ufbx_material_map normal_map; 2577 ufbx_material_map tangent_map; 2578 ufbx_material_map displacement_map; 2579 ufbx_material_map matte_factor; 2580 ufbx_material_map matte_color; 2581 ufbx_material_map ambient_occlusion; 2582 ufbx_material_map glossiness; 2583 ufbx_material_map coat_glossiness; 2584 ufbx_material_map transmission_glossiness; 2585 }; 2586 }; 2587 } ufbx_material_pbr_maps; 2588 2589 typedef struct ufbx_material_features { 2590 union { 2591 ufbx_material_feature_info features[UFBX_MATERIAL_FEATURE_COUNT]; 2592 struct { 2593 ufbx_material_feature_info pbr; 2594 ufbx_material_feature_info metalness; 2595 ufbx_material_feature_info diffuse; 2596 ufbx_material_feature_info specular; 2597 ufbx_material_feature_info emission; 2598 ufbx_material_feature_info transmission; 2599 ufbx_material_feature_info coat; 2600 ufbx_material_feature_info sheen; 2601 ufbx_material_feature_info opacity; 2602 ufbx_material_feature_info ambient_occlusion; 2603 ufbx_material_feature_info matte; 2604 ufbx_material_feature_info unlit; 2605 ufbx_material_feature_info ior; 2606 ufbx_material_feature_info diffuse_roughness; 2607 ufbx_material_feature_info transmission_roughness; 2608 ufbx_material_feature_info thin_walled; 2609 ufbx_material_feature_info caustics; 2610 ufbx_material_feature_info exit_to_background; 2611 ufbx_material_feature_info internal_reflections; 2612 ufbx_material_feature_info double_sided; 2613 ufbx_material_feature_info roughness_as_glossiness; 2614 ufbx_material_feature_info coat_roughness_as_glossiness; 2615 ufbx_material_feature_info transmission_roughness_as_glossiness; 2616 }; 2617 }; 2618 } ufbx_material_features; 2619 2620 // Surface material properties such as color, roughness, etc. Each property may 2621 // be optionally bound to an `ufbx_texture`. 2622 struct ufbx_material { 2623 union { ufbx_element element; struct { 2624 ufbx_string name; 2625 ufbx_props props; 2626 uint32_t element_id; 2627 uint32_t typed_id; 2628 }; }; 2629 2630 // FBX builtin properties 2631 // NOTE: These may be empty if the material is using a custom shader 2632 ufbx_material_fbx_maps fbx; 2633 2634 // PBR material properties, defined for all shading models but may be 2635 // somewhat approximate if `shader == NULL`. 2636 ufbx_material_pbr_maps pbr; 2637 2638 // Material features, primarily applies to `pbr`. 2639 ufbx_material_features features; 2640 2641 // Shading information 2642 ufbx_shader_type shader_type; // < Always defined 2643 ufbx_nullable ufbx_shader *shader; // < Optional extended shader information 2644 ufbx_string shading_model_name; // < Often one of `{ "lambert", "phong", "unknown" }` 2645 2646 // Prefix before shader property names with trailing `|`. 2647 // For example `"3dsMax|Parameters|"` where properties would have names like 2648 // `"3dsMax|Parameters|base_color"`. You can ignore this if you use the built-in 2649 // `ufbx_material_fbx_maps fbx` and `ufbx_material_pbr_maps pbr` structures. 2650 ufbx_string shader_prop_prefix; 2651 2652 // All textures attached to the material, if you want specific maps if might be 2653 // more convenient to use eg. `fbx.diffuse_color.texture` or `pbr.base_color.texture` 2654 ufbx_material_texture_list textures; // < Sorted by `material_prop` 2655 }; 2656 2657 typedef enum ufbx_texture_type UFBX_ENUM_REPR { 2658 2659 // Texture associated with an image file/sequence. `texture->filename` and 2660 // and `texture->relative_filename` contain the texture's path. If the file 2661 // has embedded content `texture->content` may hold `texture->content_size` 2662 // bytes of raw image data. 2663 UFBX_TEXTURE_FILE, 2664 2665 // The texture consists of multiple texture layers blended together. 2666 UFBX_TEXTURE_LAYERED, 2667 2668 // Reserved as these _should_ exist in FBX files. 2669 UFBX_TEXTURE_PROCEDURAL, 2670 2671 // Node in a shader graph. 2672 // Use `ufbx_texture.shader` for more information. 2673 UFBX_TEXTURE_SHADER, 2674 2675 UFBX_ENUM_FORCE_WIDTH(UFBX_TEXTURE_TYPE) 2676 } ufbx_texture_type; 2677 2678 UFBX_ENUM_TYPE(ufbx_texture_type, UFBX_TEXTURE_TYPE, UFBX_TEXTURE_SHADER); 2679 2680 // Blend modes to combine layered textures with, compatible with common blend 2681 // mode definitions in many art programs. Simpler blend modes have equations 2682 // specified below where `src` is the layer to composite over `dst`. 2683 // See eg. https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendingseparable 2684 typedef enum ufbx_blend_mode UFBX_ENUM_REPR { 2685 UFBX_BLEND_TRANSLUCENT, // < `src` effects result alpha 2686 UFBX_BLEND_ADDITIVE, // < `src + dst` 2687 UFBX_BLEND_MULTIPLY, // < `src * dst` 2688 UFBX_BLEND_MULTIPLY_2X, // < `2 * src * dst` 2689 UFBX_BLEND_OVER, // < `src * src_alpha + dst * (1-src_alpha)` 2690 UFBX_BLEND_REPLACE, // < `src` Replace the contents 2691 UFBX_BLEND_DISSOLVE, // < `random() + src_alpha >= 1.0 ? src : dst` 2692 UFBX_BLEND_DARKEN, // < `min(src, dst)` 2693 UFBX_BLEND_COLOR_BURN, // < `src > 0 ? 1 - min(1, (1-dst) / src) : 0` 2694 UFBX_BLEND_LINEAR_BURN, // < `src + dst - 1` 2695 UFBX_BLEND_DARKER_COLOR, // < `value(src) < value(dst) ? src : dst` 2696 UFBX_BLEND_LIGHTEN, // < `max(src, dst)` 2697 UFBX_BLEND_SCREEN, // < `1 - (1-src)*(1-dst)` 2698 UFBX_BLEND_COLOR_DODGE, // < `src < 1 ? dst / (1 - src)` : (dst>0?1:0)` 2699 UFBX_BLEND_LINEAR_DODGE, // < `src + dst` 2700 UFBX_BLEND_LIGHTER_COLOR, // < `value(src) > value(dst) ? src : dst` 2701 UFBX_BLEND_SOFT_LIGHT, // < https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendingsoftlight 2702 UFBX_BLEND_HARD_LIGHT, // < https://www.w3.org/TR/2013/WD-compositing-1-20131010/#blendinghardlight 2703 UFBX_BLEND_VIVID_LIGHT, // < Combination of `COLOR_DODGE` and `COLOR_BURN` 2704 UFBX_BLEND_LINEAR_LIGHT, // < Combination of `LINEAR_DODGE` and `LINEAR_BURN` 2705 UFBX_BLEND_PIN_LIGHT, // < Combination of `DARKEN` and `LIGHTEN` 2706 UFBX_BLEND_HARD_MIX, // < Produces primary colors depending on similarity 2707 UFBX_BLEND_DIFFERENCE, // < `abs(src - dst)` 2708 UFBX_BLEND_EXCLUSION, // < `dst + src - 2 * src * dst` 2709 UFBX_BLEND_SUBTRACT, // < `dst - src` 2710 UFBX_BLEND_DIVIDE, // < `dst / src` 2711 UFBX_BLEND_HUE, // < Replace hue 2712 UFBX_BLEND_SATURATION, // < Replace saturation 2713 UFBX_BLEND_COLOR, // < Replace hue and saturatio 2714 UFBX_BLEND_LUMINOSITY, // < Replace value 2715 UFBX_BLEND_OVERLAY, // < Same as `HARD_LIGHT` but with `src` and `dst` swapped 2716 2717 UFBX_ENUM_FORCE_WIDTH(UFBX_BLEND_MODE) 2718 } ufbx_blend_mode; 2719 2720 UFBX_ENUM_TYPE(ufbx_blend_mode, UFBX_BLEND_MODE, UFBX_BLEND_OVERLAY); 2721 2722 // Blend modes to combine layered textures with, compatible with common blend 2723 typedef enum ufbx_wrap_mode UFBX_ENUM_REPR { 2724 UFBX_WRAP_REPEAT, // < Repeat the texture past the [0,1] range 2725 UFBX_WRAP_CLAMP, // < Clamp the normalized texture coordinates to [0,1] 2726 2727 UFBX_ENUM_FORCE_WIDTH(UFBX_WRAP_MODE) 2728 } ufbx_wrap_mode; 2729 2730 UFBX_ENUM_TYPE(ufbx_wrap_mode, UFBX_WRAP_MODE, UFBX_WRAP_CLAMP); 2731 2732 // Single layer in a layered texture 2733 typedef struct ufbx_texture_layer { 2734 ufbx_texture *texture; // < The inner texture to evaluate, never `NULL` 2735 ufbx_blend_mode blend_mode; // < Equation to combine the layer to the background 2736 ufbx_real alpha; // < Blend weight of this layer 2737 } ufbx_texture_layer; 2738 2739 UFBX_LIST_TYPE(ufbx_texture_layer_list, ufbx_texture_layer); 2740 2741 typedef enum ufbx_shader_texture_type UFBX_ENUM_REPR { 2742 UFBX_SHADER_TEXTURE_UNKNOWN, 2743 2744 // Select an output of a multi-output shader. 2745 // HINT: If this type is used the `ufbx_shader_texture.main_texture` and 2746 // `ufbx_shader_texture.main_texture_output_index` fields are set. 2747 UFBX_SHADER_TEXTURE_SELECT_OUTPUT, 2748 2749 // Open Shading Language (OSL) shader. 2750 // https://github.com/AcademySoftwareFoundation/OpenShadingLanguage 2751 UFBX_SHADER_TEXTURE_OSL, 2752 2753 UFBX_ENUM_FORCE_WIDTH(UFBX_SHADER_TEXTURE_TYPE) 2754 } ufbx_shader_texture_type; 2755 2756 UFBX_ENUM_TYPE(ufbx_shader_texture_type, UFBX_SHADER_TEXTURE_TYPE, UFBX_SHADER_TEXTURE_OSL); 2757 2758 // Input to a shader texture, see `ufbx_shader_texture`. 2759 typedef struct ufbx_shader_texture_input { 2760 2761 // Name of the input. 2762 ufbx_string name; 2763 2764 // Constant value of the input. 2765 union { 2766 ufbx_real value_real; 2767 ufbx_vec2 value_vec2; 2768 ufbx_vec3 value_vec3; 2769 ufbx_vec4 value_vec4; 2770 }; 2771 int64_t value_int; 2772 ufbx_string value_str; 2773 ufbx_blob value_blob; 2774 2775 // Texture connected to this input. 2776 ufbx_nullable ufbx_texture *texture; 2777 2778 // Index of the output to use if `texture` is a multi-output shader node. 2779 int64_t texture_output_index; 2780 2781 // Controls whether shading should use `texture`. 2782 // NOTE: Some shading models allow this to be `true` even if `texture == NULL`. 2783 bool texture_enabled; 2784 2785 // Property representing this input. 2786 ufbx_prop *prop; 2787 2788 // Property representing `texture`. 2789 ufbx_nullable ufbx_prop *texture_prop; 2790 2791 // Property representing `texture_enabled`. 2792 ufbx_nullable ufbx_prop *texture_enabled_prop; 2793 2794 } ufbx_shader_texture_input; 2795 2796 UFBX_LIST_TYPE(ufbx_shader_texture_input_list, ufbx_shader_texture_input); 2797 2798 // Texture that emulates a shader graph node. 2799 // 3ds Max exports some materials as node graphs serialized to textures. 2800 // ufbx can parse a small subset of these, as normal maps are often hidden behind 2801 // some kind of bump node. 2802 // NOTE: These encode a lot of details of 3ds Max internals, not recommended for direct use. 2803 // HINT: `ufbx_texture.file_textures[]` contains a list of "real" textures that are connected 2804 // to the `ufbx_texture` that is pretending to be a shader node. 2805 typedef struct ufbx_shader_texture { 2806 2807 // Type of this shader node. 2808 ufbx_shader_texture_type type; 2809 2810 // Name of the shader to use. 2811 ufbx_string shader_name; 2812 2813 // 64-bit opaque identifier for the shader type. 2814 uint64_t shader_type_id; 2815 2816 // Input values/textures (possibly further shader textures) to the shader. 2817 // Sorted by `ufbx_shader_texture_input.name`. 2818 ufbx_shader_texture_input_list inputs; 2819 2820 // Shader source code if found. 2821 ufbx_string shader_source; 2822 ufbx_blob raw_shader_source; 2823 2824 // Representative texture for this shader. 2825 // Only specified if `main_texture.outputs[main_texture_output_index]` is semantically 2826 // equivalent to this texture. 2827 ufbx_texture *main_texture; 2828 2829 // Output index of `main_texture` if it is a multi-output shader. 2830 int64_t main_texture_output_index; 2831 2832 // Prefix for properties related to this shader in `ufbx_texture`. 2833 // NOTE: Contains the trailing '|' if not empty. 2834 ufbx_string prop_prefix; 2835 2836 } ufbx_shader_texture; 2837 2838 // Unique texture within the file. 2839 typedef struct ufbx_texture_file { 2840 2841 // Index in `ufbx_scene.texture_files[]`. 2842 uint32_t index; 2843 2844 // Paths to the resource. 2845 2846 // Filename relative to the currently loaded file. 2847 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2848 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2849 ufbx_string filename; 2850 // Absolute filename specified in the file. 2851 ufbx_string absolute_filename; 2852 // Relative filename specified in the file. 2853 // NOTE: May be absolute if the file is saved in a different drive. 2854 ufbx_string relative_filename; 2855 2856 // Filename relative to the loaded file, non-UTF-8 encoded. 2857 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2858 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2859 ufbx_blob raw_filename; 2860 // Absolute filename specified in the file, non-UTF-8 encoded. 2861 ufbx_blob raw_absolute_filename; 2862 // Relative filename specified in the file, non-UTF-8 encoded. 2863 // NOTE: May be absolute if the file is saved in a different drive. 2864 ufbx_blob raw_relative_filename; 2865 2866 // Optional embedded content blob, eg. raw .png format data 2867 ufbx_blob content; 2868 2869 } ufbx_texture_file; 2870 2871 UFBX_LIST_TYPE(ufbx_texture_file_list, ufbx_texture_file); 2872 2873 // Texture that controls material appearance 2874 struct ufbx_texture { 2875 union { ufbx_element element; struct { 2876 ufbx_string name; 2877 ufbx_props props; 2878 uint32_t element_id; 2879 uint32_t typed_id; 2880 }; }; 2881 2882 // Texture type (file / layered / procedural / shader) 2883 ufbx_texture_type type; 2884 2885 // FILE: Paths to the resource 2886 2887 // Filename relative to the currently loaded file. 2888 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2889 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2890 ufbx_string filename; 2891 // Absolute filename specified in the file. 2892 ufbx_string absolute_filename; 2893 // Relative filename specified in the file. 2894 // NOTE: May be absolute if the file is saved in a different drive. 2895 ufbx_string relative_filename; 2896 2897 // Filename relative to the loaded file, non-UTF-8 encoded. 2898 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2899 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2900 ufbx_blob raw_filename; 2901 // Absolute filename specified in the file, non-UTF-8 encoded. 2902 ufbx_blob raw_absolute_filename; 2903 // Relative filename specified in the file, non-UTF-8 encoded. 2904 // NOTE: May be absolute if the file is saved in a different drive. 2905 ufbx_blob raw_relative_filename; 2906 2907 // FILE: Optional embedded content blob, eg. raw .png format data 2908 ufbx_blob content; 2909 2910 // FILE: Optional video texture 2911 ufbx_nullable ufbx_video *video; 2912 2913 // FILE: Index into `ufbx_scene.texture_files[]` or `UFBX_NO_INDEX`. 2914 uint32_t file_index; 2915 2916 // FILE: True if `file_index` has a valid value. 2917 bool has_file; 2918 2919 // LAYERED: Inner texture layers, ordered from _bottom_ to _top_ 2920 ufbx_texture_layer_list layers; 2921 2922 // SHADER: Shader information 2923 // NOTE: May be specified even if `type == UFBX_TEXTURE_FILE` if `ufbx_load_opts.disable_quirks` 2924 // is _not_ specified. Some known shaders that represent files are interpreted as `UFBX_TEXTURE_FILE`. 2925 ufbx_nullable ufbx_shader_texture *shader; 2926 2927 // List of file textures representing this texture. 2928 // Defined even if `type == UFBX_TEXTURE_FILE` in which case the array contains only itself. 2929 ufbx_texture_list file_textures; 2930 2931 // Name of the UV set to use 2932 ufbx_string uv_set; 2933 2934 // Wrapping mode 2935 ufbx_wrap_mode wrap_u; 2936 ufbx_wrap_mode wrap_v; 2937 2938 // UV transform 2939 bool has_uv_transform; // < Has a non-identity `transform` and derived matrices. 2940 ufbx_transform uv_transform; // < Texture transformation in UV space 2941 ufbx_matrix texture_to_uv; // < Matrix representation of `transform` 2942 ufbx_matrix uv_to_texture; // < UV coordinate to normalized texture coordinate matrix 2943 }; 2944 2945 // TODO: Video textures 2946 struct ufbx_video { 2947 union { ufbx_element element; struct { 2948 ufbx_string name; 2949 ufbx_props props; 2950 uint32_t element_id; 2951 uint32_t typed_id; 2952 }; }; 2953 2954 // Paths to the resource 2955 2956 // Filename relative to the currently loaded file. 2957 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2958 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2959 ufbx_string filename; 2960 // Absolute filename specified in the file. 2961 ufbx_string absolute_filename; 2962 // Relative filename specified in the file. 2963 // NOTE: May be absolute if the file is saved in a different drive. 2964 ufbx_string relative_filename; 2965 2966 // Filename relative to the loaded file, non-UTF-8 encoded. 2967 // HINT: If using functions other than `ufbx_load_file()`, you can provide 2968 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 2969 ufbx_blob raw_filename; 2970 // Absolute filename specified in the file, non-UTF-8 encoded. 2971 ufbx_blob raw_absolute_filename; 2972 // Relative filename specified in the file, non-UTF-8 encoded. 2973 // NOTE: May be absolute if the file is saved in a different drive. 2974 ufbx_blob raw_relative_filename; 2975 2976 // Optional embedded content blob 2977 ufbx_blob content; 2978 }; 2979 2980 // Shader specifies a shading model and contains `ufbx_shader_binding` elements 2981 // that define how to interpret FBX properties in the shader. 2982 struct ufbx_shader { 2983 union { ufbx_element element; struct { 2984 ufbx_string name; 2985 ufbx_props props; 2986 uint32_t element_id; 2987 uint32_t typed_id; 2988 }; }; 2989 2990 // Known shading model 2991 ufbx_shader_type type; 2992 2993 // TODO: Expose actual properties here 2994 2995 // Bindings from FBX properties to the shader 2996 // HINT: `ufbx_find_shader_prop()` translates shader properties to FBX properties 2997 ufbx_shader_binding_list bindings; 2998 }; 2999 3000 // Binding from a material property to shader implementation 3001 typedef struct ufbx_shader_prop_binding { 3002 ufbx_string shader_prop; // < Property name used by the shader implementation 3003 ufbx_string material_prop; // < Property name inside `ufbx_material.props` 3004 } ufbx_shader_prop_binding; 3005 3006 UFBX_LIST_TYPE(ufbx_shader_prop_binding_list, ufbx_shader_prop_binding); 3007 3008 // Shader binding table 3009 struct ufbx_shader_binding { 3010 union { ufbx_element element; struct { 3011 ufbx_string name; 3012 ufbx_props props; 3013 uint32_t element_id; 3014 uint32_t typed_id; 3015 }; }; 3016 3017 ufbx_shader_prop_binding_list prop_bindings; // < Sorted by `shader_prop` 3018 }; 3019 3020 // -- Animation 3021 3022 typedef struct ufbx_prop_override { 3023 uint32_t element_id; 3024 3025 uint32_t _internal_key; 3026 3027 ufbx_string prop_name; 3028 ufbx_vec4 value; 3029 ufbx_string value_str; 3030 int64_t value_int; 3031 } ufbx_prop_override; 3032 3033 UFBX_LIST_TYPE(ufbx_prop_override_list, ufbx_prop_override); 3034 3035 typedef struct ufbx_transform_override { 3036 uint32_t node_id; 3037 ufbx_transform transform; 3038 } ufbx_transform_override; 3039 3040 UFBX_LIST_TYPE(ufbx_transform_override_list, ufbx_transform_override); 3041 3042 // Animation descriptor used for evaluating animation. 3043 // Usually obtained from `ufbx_scene` via either global animation `ufbx_scene.anim`, 3044 // per-stack animation `ufbx_anim_stack.anim` or per-layer animation `ufbx_anim_layer.anim`. 3045 // 3046 // For advanced usage you can use `ufbx_create_anim()` to create animation descriptors 3047 // with custom layers, property overrides, special flags, etc. 3048 typedef struct ufbx_anim { 3049 3050 // Time begin/end for the animation, both may be zero if absent. 3051 double time_begin; 3052 double time_end; 3053 3054 // List of layers in the animation. 3055 ufbx_anim_layer_list layers; 3056 3057 // Optional overrides for weights for each layer in `layers[]`. 3058 ufbx_real_list override_layer_weights; 3059 3060 // Sorted by `element_id, prop_name` 3061 ufbx_prop_override_list prop_overrides; 3062 3063 // Sorted by `node_id` 3064 ufbx_transform_override_list transform_overrides; 3065 3066 // Evaluate connected properties as if they would not be connected. 3067 bool ignore_connections; 3068 3069 // Custom `ufbx_anim` created by `ufbx_create_anim()`. 3070 bool custom; 3071 3072 } ufbx_anim; 3073 3074 struct ufbx_anim_stack { 3075 union { ufbx_element element; struct { 3076 ufbx_string name; 3077 ufbx_props props; 3078 uint32_t element_id; 3079 uint32_t typed_id; 3080 }; }; 3081 3082 double time_begin; 3083 double time_end; 3084 3085 ufbx_anim_layer_list layers; 3086 ufbx_anim *anim; 3087 }; 3088 3089 typedef struct ufbx_anim_prop { 3090 ufbx_element *element; 3091 3092 uint32_t _internal_key; 3093 3094 ufbx_string prop_name; 3095 ufbx_anim_value *anim_value; 3096 } ufbx_anim_prop; 3097 3098 UFBX_LIST_TYPE(ufbx_anim_prop_list, ufbx_anim_prop); 3099 3100 struct ufbx_anim_layer { 3101 union { ufbx_element element; struct { 3102 ufbx_string name; 3103 ufbx_props props; 3104 uint32_t element_id; 3105 uint32_t typed_id; 3106 }; }; 3107 3108 ufbx_real weight; 3109 bool weight_is_animated; 3110 bool blended; 3111 bool additive; 3112 bool compose_rotation; 3113 bool compose_scale; 3114 3115 ufbx_anim_value_list anim_values; 3116 ufbx_anim_prop_list anim_props; // < Sorted by `element,prop_name` 3117 3118 ufbx_anim *anim; 3119 3120 uint32_t _min_element_id; 3121 uint32_t _max_element_id; 3122 uint32_t _element_id_bitmask[4]; 3123 }; 3124 3125 struct ufbx_anim_value { 3126 union { ufbx_element element; struct { 3127 ufbx_string name; 3128 ufbx_props props; 3129 uint32_t element_id; 3130 uint32_t typed_id; 3131 }; }; 3132 3133 ufbx_vec3 default_value; 3134 ufbx_nullable ufbx_anim_curve *curves[3]; 3135 }; 3136 3137 // Animation curve segment interpolation mode between two keyframes 3138 typedef enum ufbx_interpolation UFBX_ENUM_REPR { 3139 UFBX_INTERPOLATION_CONSTANT_PREV, // < Hold previous key value 3140 UFBX_INTERPOLATION_CONSTANT_NEXT, // < Hold next key value 3141 UFBX_INTERPOLATION_LINEAR, // < Linear interpolation between two keys 3142 UFBX_INTERPOLATION_CUBIC, // < Cubic interpolation, see `ufbx_tangent` 3143 3144 UFBX_ENUM_FORCE_WIDTH(UFBX_INTERPOLATION) 3145 } ufbx_interpolation; 3146 3147 UFBX_ENUM_TYPE(ufbx_interpolation, UFBX_INTERPOLATION, UFBX_INTERPOLATION_CUBIC); 3148 3149 typedef enum ufbx_extrapolation_mode UFBX_ENUM_REPR { 3150 UFBX_EXTRAPOLATION_CONSTANT, // < Use the value of the first/last keyframe 3151 UFBX_EXTRAPOLATION_REPEAT, // < Repeat the whole animation curve 3152 UFBX_EXTRAPOLATION_MIRROR, // < Repeat with mirroring 3153 UFBX_EXTRAPOLATION_SLOPE, // < Use the tangent of the last keyframe to linearly extrapolate 3154 UFBX_EXTRAPOLATION_REPEAT_RELATIVE, // < Repeat the animation curve but connect the first and last keyframe values 3155 3156 UFBX_ENUM_FORCE_WIDTH(UFBX_EXTRAPOLATION) 3157 } ufbx_extrapolation_mode; 3158 3159 UFBX_ENUM_TYPE(ufbx_extrapolation_mode, UFBX_EXTRAPOLATION_MODE, UFBX_EXTRAPOLATION_REPEAT_RELATIVE); 3160 3161 typedef struct ufbx_extrapolation { 3162 ufbx_extrapolation_mode mode; 3163 3164 // Count used for repeating modes. 3165 // Negative values mean infinite repetition. 3166 int32_t repeat_count; 3167 } ufbx_extrapolation; 3168 3169 // Tangent vector at a keyframe, may be split into left/right 3170 typedef struct ufbx_tangent { 3171 float dx; // < Derivative in the time axis 3172 float dy; // < Derivative in the (curve specific) value axis 3173 } ufbx_tangent; 3174 3175 // Single real `value` at a specified `time`, interpolation between two keyframes 3176 // is determined by the `interpolation` field of the _previous_ key. 3177 // If `interpolation == UFBX_INTERPOLATION_CUBIC` the span is evaluated as a 3178 // cubic bezier curve through the following points: 3179 // 3180 // (prev->time, prev->value) 3181 // (prev->time + prev->right.dx, prev->value + prev->right.dy) 3182 // (next->time - next->left.dx, next->value - next->left.dy) 3183 // (next->time, next->value) 3184 // 3185 // HINT: You can use `ufbx_evaluate_curve(ufbx_anim_curve *curve, double time)` 3186 // rather than trying to manually handle all the interpolation modes. 3187 typedef struct ufbx_keyframe { 3188 double time; 3189 ufbx_real value; 3190 ufbx_interpolation interpolation; 3191 ufbx_tangent left; 3192 ufbx_tangent right; 3193 } ufbx_keyframe; 3194 3195 UFBX_LIST_TYPE(ufbx_keyframe_list, ufbx_keyframe); 3196 3197 struct ufbx_anim_curve { 3198 union { ufbx_element element; struct { 3199 ufbx_string name; 3200 ufbx_props props; 3201 uint32_t element_id; 3202 uint32_t typed_id; 3203 }; }; 3204 3205 // List of keyframes that define the curve. 3206 ufbx_keyframe_list keyframes; 3207 3208 // Extrapolation before the curve. 3209 ufbx_extrapolation pre_extrapolation; 3210 // Extrapolation after the curve. 3211 ufbx_extrapolation post_extrapolation; 3212 3213 // Value range for all the keyframes. 3214 ufbx_real min_value; 3215 ufbx_real max_value; 3216 3217 // Time range for all the keyframes. 3218 double min_time; 3219 double max_time; 3220 }; 3221 3222 // -- Collections 3223 3224 // Collection of nodes to hide/freeze 3225 struct ufbx_display_layer { 3226 union { ufbx_element element; struct { 3227 ufbx_string name; 3228 ufbx_props props; 3229 uint32_t element_id; 3230 uint32_t typed_id; 3231 }; }; 3232 3233 // Nodes included in the layer (exclusively at most one layer per node) 3234 ufbx_node_list nodes; 3235 3236 // Layer state 3237 bool visible; // < Contained nodes are visible 3238 bool frozen; // < Contained nodes cannot be edited 3239 3240 ufbx_vec3 ui_color; // < Visual color for UI 3241 }; 3242 3243 // Named set of nodes/geometry features to select. 3244 struct ufbx_selection_set { 3245 union { ufbx_element element; struct { 3246 ufbx_string name; 3247 ufbx_props props; 3248 uint32_t element_id; 3249 uint32_t typed_id; 3250 }; }; 3251 3252 // Included nodes and geometry features 3253 ufbx_selection_node_list nodes; 3254 }; 3255 3256 // Selection state of a node, potentially contains vertex/edge/face selection as well. 3257 struct ufbx_selection_node { 3258 union { ufbx_element element; struct { 3259 ufbx_string name; 3260 ufbx_props props; 3261 uint32_t element_id; 3262 uint32_t typed_id; 3263 }; }; 3264 3265 // Selection targets, possibly `NULL` 3266 ufbx_nullable ufbx_node *target_node; 3267 ufbx_nullable ufbx_mesh *target_mesh; 3268 bool include_node; // < Is `target_node` included in the selection 3269 3270 // Indices to selected components. 3271 // Guaranteed to be valid as per `ufbx_load_opts.index_error_handling` 3272 // if `target_mesh` is not `NULL`. 3273 ufbx_uint32_list vertices; // < Indices to `ufbx_mesh.vertices` 3274 ufbx_uint32_list edges; // < Indices to `ufbx_mesh.edges` 3275 ufbx_uint32_list faces; // < Indices to `ufbx_mesh.faces` 3276 }; 3277 3278 // -- Constraints 3279 3280 struct ufbx_character { 3281 union { ufbx_element element; struct { 3282 ufbx_string name; 3283 ufbx_props props; 3284 uint32_t element_id; 3285 uint32_t typed_id; 3286 }; }; 3287 }; 3288 3289 // Type of property constrain eg. position or look-at 3290 typedef enum ufbx_constraint_type UFBX_ENUM_REPR { 3291 UFBX_CONSTRAINT_UNKNOWN, 3292 UFBX_CONSTRAINT_AIM, 3293 UFBX_CONSTRAINT_PARENT, 3294 UFBX_CONSTRAINT_POSITION, 3295 UFBX_CONSTRAINT_ROTATION, 3296 UFBX_CONSTRAINT_SCALE, 3297 // Inverse kinematic chain to a single effector `ufbx_constraint.ik_effector` 3298 // `targets` optionally contains a list of pole targets! 3299 UFBX_CONSTRAINT_SINGLE_CHAIN_IK, 3300 3301 UFBX_ENUM_FORCE_WIDTH(UFBX_CONSTRAINT_TYPE) 3302 } ufbx_constraint_type; 3303 3304 UFBX_ENUM_TYPE(ufbx_constraint_type, UFBX_CONSTRAINT_TYPE, UFBX_CONSTRAINT_SINGLE_CHAIN_IK); 3305 3306 // Target to follow with a constraint 3307 typedef struct ufbx_constraint_target { 3308 ufbx_node *node; // < Target node reference 3309 ufbx_real weight; // < Relative weight to other targets (does not always sum to 1) 3310 ufbx_transform transform; // < Offset from the actual target 3311 } ufbx_constraint_target; 3312 3313 UFBX_LIST_TYPE(ufbx_constraint_target_list, ufbx_constraint_target); 3314 3315 // Method to determine the up vector in aim constraints 3316 typedef enum ufbx_constraint_aim_up_type UFBX_ENUM_REPR { 3317 UFBX_CONSTRAINT_AIM_UP_SCENE, // < Align the up vector to the scene global up vector 3318 UFBX_CONSTRAINT_AIM_UP_TO_NODE, // < Aim the up vector at `ufbx_constraint.aim_up_node` 3319 UFBX_CONSTRAINT_AIM_UP_ALIGN_NODE, // < Copy the up vector from `ufbx_constraint.aim_up_node` 3320 UFBX_CONSTRAINT_AIM_UP_VECTOR, // < Use `ufbx_constraint.aim_up_vector` as the up vector 3321 UFBX_CONSTRAINT_AIM_UP_NONE, // < Don't align the up vector to anything 3322 3323 UFBX_ENUM_FORCE_WIDTH(UFBX_CONSTRAINT_AIM_UP_TYPE) 3324 } ufbx_constraint_aim_up_type; 3325 3326 UFBX_ENUM_TYPE(ufbx_constraint_aim_up_type, UFBX_CONSTRAINT_AIM_UP_TYPE, UFBX_CONSTRAINT_AIM_UP_NONE); 3327 3328 // Method to determine the up vector in aim constraints 3329 typedef enum ufbx_constraint_ik_pole_type UFBX_ENUM_REPR { 3330 UFBX_CONSTRAINT_IK_POLE_VECTOR, // < Use towards calculated from `ufbx_constraint.targets` 3331 UFBX_CONSTRAINT_IK_POLE_NODE, // < Use `ufbx_constraint.ik_pole_vector` directly 3332 3333 UFBX_ENUM_FORCE_WIDTH(UFBX_CONSTRAINT_IK_POLE_TYPE) 3334 } ufbx_constraint_ik_pole_type; 3335 3336 UFBX_ENUM_TYPE(ufbx_constraint_ik_pole_type, UFBX_CONSTRAINT_IK_POLE_TYPE, UFBX_CONSTRAINT_IK_POLE_NODE); 3337 3338 struct ufbx_constraint { 3339 union { ufbx_element element; struct { 3340 ufbx_string name; 3341 ufbx_props props; 3342 uint32_t element_id; 3343 uint32_t typed_id; 3344 }; }; 3345 3346 // Type of constraint to use 3347 ufbx_constraint_type type; 3348 ufbx_string type_name; 3349 3350 // Node to be constrained 3351 ufbx_nullable ufbx_node *node; 3352 3353 // List of weighted targets for the constraint (pole vectors for IK) 3354 ufbx_constraint_target_list targets; 3355 3356 // State of the constraint 3357 ufbx_real weight; 3358 bool active; 3359 3360 // Translation/rotation/scale axes the constraint is applied to 3361 bool constrain_translation[3]; 3362 bool constrain_rotation[3]; 3363 bool constrain_scale[3]; 3364 3365 // Offset from the constrained position 3366 ufbx_transform transform_offset; 3367 3368 // AIM: Target and up vectors 3369 ufbx_vec3 aim_vector; 3370 ufbx_constraint_aim_up_type aim_up_type; 3371 ufbx_nullable ufbx_node *aim_up_node; 3372 ufbx_vec3 aim_up_vector; 3373 3374 // SINGLE_CHAIN_IK: Target for the IK, `targets` contains pole vectors! 3375 ufbx_nullable ufbx_node *ik_effector; 3376 ufbx_nullable ufbx_node *ik_end_node; 3377 ufbx_vec3 ik_pole_vector; 3378 }; 3379 3380 // -- Audio 3381 3382 struct ufbx_audio_layer { 3383 union { ufbx_element element; struct { 3384 ufbx_string name; 3385 ufbx_props props; 3386 uint32_t element_id; 3387 uint32_t typed_id; 3388 }; }; 3389 3390 // Clips contained in this layer. 3391 ufbx_audio_clip_list clips; 3392 }; 3393 3394 struct ufbx_audio_clip { 3395 union { ufbx_element element; struct { 3396 ufbx_string name; 3397 ufbx_props props; 3398 uint32_t element_id; 3399 uint32_t typed_id; 3400 }; }; 3401 3402 // Filename relative to the currently loaded file. 3403 // HINT: If using functions other than `ufbx_load_file()`, you can provide 3404 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 3405 ufbx_string filename; 3406 // Absolute filename specified in the file. 3407 ufbx_string absolute_filename; 3408 // Relative filename specified in the file. 3409 // NOTE: May be absolute if the file is saved in a different drive. 3410 ufbx_string relative_filename; 3411 3412 // Filename relative to the loaded file, non-UTF-8 encoded. 3413 // HINT: If using functions other than `ufbx_load_file()`, you can provide 3414 // `ufbx_load_opts.filename/raw_filename` to let ufbx resolve this. 3415 ufbx_blob raw_filename; 3416 // Absolute filename specified in the file, non-UTF-8 encoded. 3417 ufbx_blob raw_absolute_filename; 3418 // Relative filename specified in the file, non-UTF-8 encoded. 3419 // NOTE: May be absolute if the file is saved in a different drive. 3420 ufbx_blob raw_relative_filename; 3421 3422 // Optional embedded content blob, eg. raw .png format data 3423 ufbx_blob content; 3424 }; 3425 3426 // -- Miscellaneous 3427 3428 typedef struct ufbx_bone_pose { 3429 3430 // Node to apply the pose to. 3431 ufbx_node *bone_node; 3432 3433 // Matrix from node local space to world space. 3434 ufbx_matrix bone_to_world; 3435 3436 // Matrix from node local space to parent space. 3437 // NOTE: FBX only stores world transformations so this is approximated from 3438 // the parent world transform. 3439 ufbx_matrix bone_to_parent; 3440 3441 } ufbx_bone_pose; 3442 3443 UFBX_LIST_TYPE(ufbx_bone_pose_list, ufbx_bone_pose); 3444 3445 struct ufbx_pose { 3446 union { ufbx_element element; struct { 3447 ufbx_string name; 3448 ufbx_props props; 3449 uint32_t element_id; 3450 uint32_t typed_id; 3451 }; }; 3452 3453 // Set if this pose is marked as a bind pose. 3454 bool is_bind_pose; 3455 3456 // List of bone poses. 3457 // Sorted by `ufbx_node.typed_id`. 3458 ufbx_bone_pose_list bone_poses; 3459 }; 3460 3461 struct ufbx_metadata_object { 3462 union { ufbx_element element; struct { 3463 ufbx_string name; 3464 ufbx_props props; 3465 uint32_t element_id; 3466 uint32_t typed_id; 3467 }; }; 3468 }; 3469 3470 // -- Named elements 3471 3472 typedef struct ufbx_name_element { 3473 ufbx_string name; 3474 ufbx_element_type type; 3475 3476 uint32_t _internal_key; 3477 3478 ufbx_element *element; 3479 } ufbx_name_element; 3480 3481 UFBX_LIST_TYPE(ufbx_name_element_list, ufbx_name_element); 3482 3483 // -- Scene 3484 3485 // Scene is the root object loaded by ufbx that everything is accessed from. 3486 3487 typedef enum ufbx_exporter UFBX_ENUM_REPR { 3488 UFBX_EXPORTER_UNKNOWN, 3489 UFBX_EXPORTER_FBX_SDK, 3490 UFBX_EXPORTER_BLENDER_BINARY, 3491 UFBX_EXPORTER_BLENDER_ASCII, 3492 UFBX_EXPORTER_MOTION_BUILDER, 3493 3494 UFBX_ENUM_FORCE_WIDTH(UFBX_EXPORTER) 3495 } ufbx_exporter; 3496 3497 UFBX_ENUM_TYPE(ufbx_exporter, UFBX_EXPORTER, UFBX_EXPORTER_MOTION_BUILDER); 3498 3499 typedef struct ufbx_application { 3500 ufbx_string vendor; 3501 ufbx_string name; 3502 ufbx_string version; 3503 } ufbx_application; 3504 3505 typedef enum ufbx_file_format UFBX_ENUM_REPR { 3506 UFBX_FILE_FORMAT_UNKNOWN, // < Unknown file format 3507 UFBX_FILE_FORMAT_FBX, // < .fbx Kaydara/Autodesk FBX file 3508 UFBX_FILE_FORMAT_OBJ, // < .obj Wavefront OBJ file 3509 UFBX_FILE_FORMAT_MTL, // < .mtl Wavefront MTL (Material template library) file 3510 3511 UFBX_ENUM_FORCE_WIDTH(UFBX_FILE_FORMAT) 3512 } ufbx_file_format; 3513 3514 UFBX_ENUM_TYPE(ufbx_file_format, UFBX_FILE_FORMAT, UFBX_FILE_FORMAT_MTL); 3515 3516 typedef enum ufbx_warning_type UFBX_ENUM_REPR { 3517 // Missing external file file (for example .mtl for Wavefront .obj file or a 3518 // geometry cache) 3519 UFBX_WARNING_MISSING_EXTERNAL_FILE, 3520 3521 // Loaded a Wavefront .mtl file derived from the filename instead of a proper 3522 // `mtllib` statement. 3523 UFBX_WARNING_IMPLICIT_MTL, 3524 3525 // Truncated array has been auto-expanded. 3526 UFBX_WARNING_TRUNCATED_ARRAY, 3527 3528 // Geometry data has been defined but has no data. 3529 UFBX_WARNING_MISSING_GEOMETRY_DATA, 3530 3531 // Duplicated connection between two elements that shouldn't have. 3532 UFBX_WARNING_DUPLICATE_CONNECTION, 3533 3534 // Vertex 'W' attribute length differs from main attribute. 3535 UFBX_WARNING_BAD_VERTEX_W_ATTRIBUTE, 3536 3537 // Missing polygon mapping type. 3538 UFBX_WARNING_MISSING_POLYGON_MAPPING, 3539 3540 // Unsupported version, loaded but may be incorrect. 3541 // If the loading fails `UFBX_ERROR_UNSUPPORTED_VERSION` is issued instead. 3542 UFBX_WARNING_UNSUPPORTED_VERSION, 3543 3544 // Out-of-bounds index has been clamped to be in-bounds. 3545 // HINT: You can use `ufbx_index_error_handling` to adjust behavior. 3546 UFBX_WARNING_INDEX_CLAMPED, 3547 3548 // Non-UTF8 encoded strings. 3549 // HINT: You can use `ufbx_unicode_error_handling` to adjust behavior. 3550 UFBX_WARNING_BAD_UNICODE, 3551 3552 // Invalid base64-encoded embedded content ignored. 3553 UFBX_WARNING_BAD_BASE64_CONTENT, 3554 3555 // Non-node element connected to root. 3556 UFBX_WARNING_BAD_ELEMENT_CONNECTED_TO_ROOT, 3557 3558 // Duplicated object ID in the file, connections will be wrong. 3559 UFBX_WARNING_DUPLICATE_OBJECT_ID, 3560 3561 // Empty face has been removed. 3562 // Use `ufbx_load_opts.allow_empty_faces` if you want to allow them. 3563 UFBX_WARNING_EMPTY_FACE_REMOVED, 3564 3565 // Unknown .obj file directive. 3566 UFBX_WARNING_UNKNOWN_OBJ_DIRECTIVE, 3567 3568 // Warnings after this one are deduplicated. 3569 // See `ufbx_warning.count` for how many times they happened. 3570 UFBX_WARNING_TYPE_FIRST_DEDUPLICATED = UFBX_WARNING_INDEX_CLAMPED, 3571 3572 UFBX_ENUM_FORCE_WIDTH(UFBX_WARNING_TYPE) 3573 } ufbx_warning_type; 3574 3575 UFBX_ENUM_TYPE(ufbx_warning_type, UFBX_WARNING_TYPE, UFBX_WARNING_UNKNOWN_OBJ_DIRECTIVE); 3576 3577 // Warning about a non-fatal issue in the file. 3578 // Often contains information about issues that ufbx has corrected about the 3579 // file but it might indicate something is not working properly. 3580 typedef struct ufbx_warning { 3581 // Type of the warning. 3582 ufbx_warning_type type; 3583 // Description of the warning. 3584 ufbx_string description; 3585 // The element related to this warning or `UFBX_NO_INDEX` if not related to a specific element. 3586 uint32_t element_id; 3587 // Number of times this warning was encountered. 3588 size_t count; 3589 } ufbx_warning; 3590 3591 UFBX_LIST_TYPE(ufbx_warning_list, ufbx_warning); 3592 3593 typedef enum ufbx_thumbnail_format UFBX_ENUM_REPR { 3594 UFBX_THUMBNAIL_FORMAT_UNKNOWN, // < Unknown format 3595 UFBX_THUMBNAIL_FORMAT_RGB_24, // < 8-bit RGB pixels, in memory R,G,B 3596 UFBX_THUMBNAIL_FORMAT_RGBA_32, // < 8-bit RGBA pixels, in memory R,G,B,A 3597 3598 UFBX_ENUM_FORCE_WIDTH(UFBX_THUMBNAIL_FORMAT) 3599 } ufbx_thumbnail_format; 3600 3601 UFBX_ENUM_TYPE(ufbx_thumbnail_format, UFBX_THUMBNAIL_FORMAT, UFBX_THUMBNAIL_FORMAT_RGBA_32); 3602 3603 // Specify how unit / coordinate system conversion should be performed. 3604 // Affects how `ufbx_load_opts.target_axes` and `ufbx_load_opts.target_unit_meters` work, 3605 // has no effect if neither is specified. 3606 typedef enum ufbx_space_conversion UFBX_ENUM_REPR { 3607 3608 // Store the space conversion transform in the root node. 3609 // Sets `ufbx_node.local_transform` of the root node. 3610 UFBX_SPACE_CONVERSION_TRANSFORM_ROOT, 3611 3612 // Perform the conversion by using "adjust" transforms. 3613 // Compensates for the transforms using `ufbx_node.adjust_pre_rotation` and 3614 // `ufbx_node.adjust_pre_scale`. You don't need to account for these unless 3615 // you are manually building transforms from `ufbx_props`. 3616 UFBX_SPACE_CONVERSION_ADJUST_TRANSFORMS, 3617 3618 // Perform the conversion by scaling geometry in addition to adjusting transforms. 3619 // Compensates transforms like `UFBX_SPACE_CONVERSION_ADJUST_TRANSFORMS` but 3620 // applies scaling to geometry as well. 3621 UFBX_SPACE_CONVERSION_MODIFY_GEOMETRY, 3622 3623 UFBX_ENUM_FORCE_WIDTH(UFBX_SPACE_CONVERSION) 3624 } ufbx_space_conversion; 3625 3626 UFBX_ENUM_TYPE(ufbx_space_conversion, UFBX_SPACE_CONVERSION, UFBX_SPACE_CONVERSION_MODIFY_GEOMETRY); 3627 3628 // Embedded thumbnail in the file, valid if the dimensions are non-zero. 3629 typedef struct ufbx_thumbnail { 3630 ufbx_props props; 3631 3632 // Extents of the thumbnail 3633 uint32_t width; 3634 uint32_t height; 3635 3636 // Format of `ufbx_thumbnail.data`. 3637 ufbx_thumbnail_format format; 3638 3639 // Thumbnail pixel data, layout as contiguous rows from bottom to top. 3640 // See `ufbx_thumbnail.format` for the pixel format. 3641 ufbx_blob data; 3642 } ufbx_thumbnail; 3643 3644 // Miscellaneous data related to the loaded file 3645 typedef struct ufbx_metadata { 3646 3647 // List of non-fatal warnings about the file. 3648 // If you need to only check whether a specific warning was triggered you 3649 // can use `ufbx_metadata.has_warning[]`. 3650 ufbx_warning_list warnings; 3651 3652 // FBX ASCII file format. 3653 bool ascii; 3654 3655 // FBX version in integer format, eg. 7400 for 7.4. 3656 uint32_t version; 3657 3658 // File format of the source file. 3659 ufbx_file_format file_format; 3660 3661 // Index arrays may contain `UFBX_NO_INDEX` instead of a valid index 3662 // to indicate gaps. 3663 bool may_contain_no_index; 3664 3665 // May contain meshes with no defined vertex position. 3666 // NOTE: `ufbx_mesh.vertex_position.exists` may be `false`! 3667 bool may_contain_missing_vertex_position; 3668 3669 // Arrays may contain items with `NULL` element references. 3670 // See `ufbx_load_opts.connect_broken_elements`. 3671 bool may_contain_broken_elements; 3672 3673 // Some API guarantees do not apply (depending on unsafe options used). 3674 // Loaded with `ufbx_load_opts.allow_unsafe` enabled. 3675 bool is_unsafe; 3676 3677 // Flag for each possible warning type. 3678 // See `ufbx_metadata.warnings[]` for detailed warning information. 3679 bool has_warning[UFBX_WARNING_TYPE_COUNT]; 3680 3681 ufbx_string creator; 3682 bool big_endian; 3683 3684 ufbx_string filename; 3685 ufbx_string relative_root; 3686 3687 ufbx_blob raw_filename; 3688 ufbx_blob raw_relative_root; 3689 3690 ufbx_exporter exporter; 3691 uint32_t exporter_version; 3692 3693 ufbx_props scene_props; 3694 3695 ufbx_application original_application; 3696 ufbx_application latest_application; 3697 3698 ufbx_thumbnail thumbnail; 3699 3700 bool geometry_ignored; 3701 bool animation_ignored; 3702 bool embedded_ignored; 3703 3704 size_t max_face_triangles; 3705 3706 size_t result_memory_used; 3707 size_t temp_memory_used; 3708 size_t result_allocs; 3709 size_t temp_allocs; 3710 3711 size_t element_buffer_size; 3712 size_t num_shader_textures; 3713 3714 ufbx_real bone_prop_size_unit; 3715 bool bone_prop_limb_length_relative; 3716 3717 ufbx_real ortho_size_unit; 3718 3719 int64_t ktime_second; // < One second in internal KTime units 3720 3721 ufbx_string original_file_path; 3722 ufbx_blob raw_original_file_path; 3723 3724 // Space conversion method used on the scene. 3725 ufbx_space_conversion space_conversion; 3726 3727 // Transform that has been applied to root for axis/unit conversion. 3728 ufbx_quat root_rotation; 3729 ufbx_real root_scale; 3730 3731 // Axis that the scene has been mirrored by. 3732 // All geometry has been mirrored in this axis. 3733 ufbx_mirror_axis mirror_axis; 3734 3735 // Amount geometry has been scaled. 3736 // See `UFBX_SPACE_CONVERSION_MODIFY_GEOMETRY`. 3737 ufbx_real geometry_scale; 3738 3739 } ufbx_metadata; 3740 3741 typedef enum ufbx_time_mode UFBX_ENUM_REPR { 3742 UFBX_TIME_MODE_DEFAULT, 3743 UFBX_TIME_MODE_120_FPS, 3744 UFBX_TIME_MODE_100_FPS, 3745 UFBX_TIME_MODE_60_FPS, 3746 UFBX_TIME_MODE_50_FPS, 3747 UFBX_TIME_MODE_48_FPS, 3748 UFBX_TIME_MODE_30_FPS, 3749 UFBX_TIME_MODE_30_FPS_DROP, 3750 UFBX_TIME_MODE_NTSC_DROP_FRAME, 3751 UFBX_TIME_MODE_NTSC_FULL_FRAME, 3752 UFBX_TIME_MODE_PAL, 3753 UFBX_TIME_MODE_24_FPS, 3754 UFBX_TIME_MODE_1000_FPS, 3755 UFBX_TIME_MODE_FILM_FULL_FRAME, 3756 UFBX_TIME_MODE_CUSTOM, 3757 UFBX_TIME_MODE_96_FPS, 3758 UFBX_TIME_MODE_72_FPS, 3759 UFBX_TIME_MODE_59_94_FPS, 3760 3761 UFBX_ENUM_FORCE_WIDTH(UFBX_TIME_MODE) 3762 } ufbx_time_mode; 3763 3764 UFBX_ENUM_TYPE(ufbx_time_mode, UFBX_TIME_MODE, UFBX_TIME_MODE_59_94_FPS); 3765 3766 typedef enum ufbx_time_protocol UFBX_ENUM_REPR { 3767 UFBX_TIME_PROTOCOL_SMPTE, 3768 UFBX_TIME_PROTOCOL_FRAME_COUNT, 3769 UFBX_TIME_PROTOCOL_DEFAULT, 3770 3771 UFBX_ENUM_FORCE_WIDTH(UFBX_TIME_PROTOCOL) 3772 } ufbx_time_protocol; 3773 3774 UFBX_ENUM_TYPE(ufbx_time_protocol, UFBX_TIME_PROTOCOL, UFBX_TIME_PROTOCOL_DEFAULT); 3775 3776 typedef enum ufbx_snap_mode UFBX_ENUM_REPR { 3777 UFBX_SNAP_MODE_NONE, 3778 UFBX_SNAP_MODE_SNAP, 3779 UFBX_SNAP_MODE_PLAY, 3780 UFBX_SNAP_MODE_SNAP_AND_PLAY, 3781 3782 UFBX_ENUM_FORCE_WIDTH(UFBX_SNAP_MODE) 3783 } ufbx_snap_mode; 3784 3785 UFBX_ENUM_TYPE(ufbx_snap_mode, UFBX_SNAP_MODE, UFBX_SNAP_MODE_SNAP_AND_PLAY); 3786 3787 // Global settings: Axes and time/unit scales 3788 typedef struct ufbx_scene_settings { 3789 ufbx_props props; 3790 3791 // Mapping of X/Y/Z axes to world-space directions. 3792 // HINT: Use `ufbx_load_opts.target_axes` to normalize this. 3793 // NOTE: This contains the _original_ axes even if you supply `ufbx_load_opts.target_axes`. 3794 ufbx_coordinate_axes axes; 3795 3796 // How many meters does a single world-space unit represent. 3797 // FBX files usually default to centimeters, reported as `0.01` here. 3798 // HINT: Use `ufbx_load_opts.target_unit_meters` to normalize this. 3799 ufbx_real unit_meters; 3800 3801 // Frames per second the animation is defined at. 3802 double frames_per_second; 3803 3804 ufbx_vec3 ambient_color; 3805 ufbx_string default_camera; 3806 3807 // Animation user interface settings. 3808 // HINT: Use `ufbx_scene_settings.frames_per_second` instead of interpreting these yourself. 3809 ufbx_time_mode time_mode; 3810 ufbx_time_protocol time_protocol; 3811 ufbx_snap_mode snap_mode; 3812 3813 // Original settings (?) 3814 ufbx_coordinate_axis original_axis_up; 3815 ufbx_real original_unit_meters; 3816 } ufbx_scene_settings; 3817 3818 struct ufbx_scene { 3819 ufbx_metadata metadata; 3820 3821 // Global settings 3822 ufbx_scene_settings settings; 3823 3824 // Node instances in the scene 3825 ufbx_node *root_node; 3826 3827 // Default animation descriptor 3828 ufbx_anim *anim; 3829 3830 union { 3831 struct { 3832 ufbx_unknown_list unknowns; 3833 3834 // Nodes 3835 ufbx_node_list nodes; 3836 3837 // Node attributes (common) 3838 ufbx_mesh_list meshes; 3839 ufbx_light_list lights; 3840 ufbx_camera_list cameras; 3841 ufbx_bone_list bones; 3842 ufbx_empty_list empties; 3843 3844 // Node attributes (curves/surfaces) 3845 ufbx_line_curve_list line_curves; 3846 ufbx_nurbs_curve_list nurbs_curves; 3847 ufbx_nurbs_surface_list nurbs_surfaces; 3848 ufbx_nurbs_trim_surface_list nurbs_trim_surfaces; 3849 ufbx_nurbs_trim_boundary_list nurbs_trim_boundaries; 3850 3851 // Node attributes (advanced) 3852 ufbx_procedural_geometry_list procedural_geometries; 3853 ufbx_stereo_camera_list stereo_cameras; 3854 ufbx_camera_switcher_list camera_switchers; 3855 ufbx_marker_list markers; 3856 ufbx_lod_group_list lod_groups; 3857 3858 // Deformers 3859 ufbx_skin_deformer_list skin_deformers; 3860 ufbx_skin_cluster_list skin_clusters; 3861 ufbx_blend_deformer_list blend_deformers; 3862 ufbx_blend_channel_list blend_channels; 3863 ufbx_blend_shape_list blend_shapes; 3864 ufbx_cache_deformer_list cache_deformers; 3865 ufbx_cache_file_list cache_files; 3866 3867 // Materials 3868 ufbx_material_list materials; 3869 ufbx_texture_list textures; 3870 ufbx_video_list videos; 3871 ufbx_shader_list shaders; 3872 ufbx_shader_binding_list shader_bindings; 3873 3874 // Animation 3875 ufbx_anim_stack_list anim_stacks; 3876 ufbx_anim_layer_list anim_layers; 3877 ufbx_anim_value_list anim_values; 3878 ufbx_anim_curve_list anim_curves; 3879 3880 // Collections 3881 ufbx_display_layer_list display_layers; 3882 ufbx_selection_set_list selection_sets; 3883 ufbx_selection_node_list selection_nodes; 3884 3885 // Constraints 3886 ufbx_character_list characters; 3887 ufbx_constraint_list constraints; 3888 3889 // Audio 3890 ufbx_audio_layer_list audio_layers; 3891 ufbx_audio_clip_list audio_clips; 3892 3893 // Miscellaneous 3894 ufbx_pose_list poses; 3895 ufbx_metadata_object_list metadata_objects; 3896 }; 3897 3898 ufbx_element_list elements_by_type[UFBX_ELEMENT_TYPE_COUNT]; 3899 }; 3900 3901 // Unique texture files referenced by the scene. 3902 ufbx_texture_file_list texture_files; 3903 3904 // All elements and connections in the whole file 3905 ufbx_element_list elements; // < Sorted by `id` 3906 ufbx_connection_list connections_src; // < Sorted by `src,src_prop` 3907 ufbx_connection_list connections_dst; // < Sorted by `dst,dst_prop` 3908 3909 // Elements sorted by name, type 3910 ufbx_name_element_list elements_by_name; 3911 3912 // Enabled if `ufbx_load_opts.retain_dom == true`. 3913 ufbx_nullable ufbx_dom_node *dom_root; 3914 }; 3915 3916 // -- Curves 3917 3918 typedef struct ufbx_curve_point { 3919 bool valid; 3920 ufbx_vec3 position; 3921 ufbx_vec3 derivative; 3922 } ufbx_curve_point; 3923 3924 typedef struct ufbx_surface_point { 3925 bool valid; 3926 ufbx_vec3 position; 3927 ufbx_vec3 derivative_u; 3928 ufbx_vec3 derivative_v; 3929 } ufbx_surface_point; 3930 3931 // -- Mesh topology 3932 3933 typedef enum ufbx_topo_flags UFBX_FLAG_REPR { 3934 UFBX_TOPO_NON_MANIFOLD = 0x1, // < Edge with three or more faces 3935 3936 UFBX_FLAG_FORCE_WIDTH(UFBX_TOPO_FLAGS) 3937 } ufbx_topo_flags; 3938 3939 typedef struct ufbx_topo_edge { 3940 uint32_t index; // < Starting index of the edge, always defined 3941 uint32_t next; // < Ending index of the edge / next per-face `ufbx_topo_edge`, always defined 3942 uint32_t prev; // < Previous per-face `ufbx_topo_edge`, always defined 3943 uint32_t twin; // < `ufbx_topo_edge` on the opposite side, `UFBX_NO_INDEX` if not found 3944 uint32_t face; // < Index into `mesh->faces[]`, always defined 3945 uint32_t edge; // < Index into `mesh->edges[]`, `UFBX_NO_INDEX` if not found 3946 3947 ufbx_topo_flags flags; 3948 } ufbx_topo_edge; 3949 3950 // Vertex data array for `ufbx_generate_indices()`. 3951 // NOTE: `ufbx_generate_indices()` compares the vertices using `memcmp()`, so 3952 // any padding should be cleared to zero. 3953 typedef struct ufbx_vertex_stream { 3954 void *data; // < Data pointer of shape `char[vertex_count][vertex_size]`. 3955 size_t vertex_count; // < Number of vertices in this stream, for sanity checking. 3956 size_t vertex_size; // < Size of a vertex in bytes. 3957 } ufbx_vertex_stream; 3958 3959 // -- Memory callbacks 3960 3961 // You can optionally provide an allocator to ufbx, the default is to use the 3962 // CRT malloc/realloc/free 3963 3964 // Allocate `size` bytes, must be at least 8 byte aligned 3965 typedef void *ufbx_alloc_fn(void *user, size_t size); 3966 3967 // Reallocate `old_ptr` from `old_size` to `new_size` 3968 // NOTE: If omit `alloc_fn` and `free_fn` they will be translated to: 3969 // `alloc(size)` -> `realloc_fn(user, NULL, 0, size)` 3970 // `free_fn(ptr, size)` -> `realloc_fn(user, ptr, size, 0)` 3971 typedef void *ufbx_realloc_fn(void *user, void *old_ptr, size_t old_size, size_t new_size); 3972 3973 // Free pointer `ptr` (of `size` bytes) returned by `alloc_fn` or `realloc_fn` 3974 typedef void ufbx_free_fn(void *user, void *ptr, size_t size); 3975 3976 // Free the allocator itself 3977 typedef void ufbx_free_allocator_fn(void *user); 3978 3979 // Allocator callbacks and user context 3980 // NOTE: The allocator will be stored to the loaded scene and will be called 3981 // again from `ufbx_free_scene()` so make sure `user` outlives that! 3982 // You can use `free_allocator_fn()` to free the allocator yourself. 3983 typedef struct ufbx_allocator { 3984 // Callback functions, see `typedef`s above for information 3985 ufbx_alloc_fn *alloc_fn; 3986 ufbx_realloc_fn *realloc_fn; 3987 ufbx_free_fn *free_fn; 3988 ufbx_free_allocator_fn *free_allocator_fn; 3989 void *user; 3990 } ufbx_allocator; 3991 3992 typedef struct ufbx_allocator_opts { 3993 // Allocator callbacks 3994 ufbx_allocator allocator; 3995 3996 // Maximum number of bytes to allocate before failing 3997 size_t memory_limit; 3998 3999 // Maximum number of allocations to attempt before failing 4000 size_t allocation_limit; 4001 4002 // Threshold to swap from batched allocations to individual ones 4003 // Defaults to 1MB if set to zero 4004 // NOTE: If set to `1` ufbx will allocate everything in the smallest 4005 // possible chunks which may be useful for debugging (eg. ASAN) 4006 size_t huge_threshold; 4007 4008 // Maximum size of a single allocation containing sub-allocations. 4009 // Defaults to 16MB if set to zero 4010 // The maximum amount of wasted memory depends on `max_chunk_size` and 4011 // `huge_threshold`: each chunk can waste up to `huge_threshold` bytes 4012 // internally and the last chunk might be incomplete. So for example 4013 // with the defaults we can waste around 1MB/16MB = 6.25% overall plus 4014 // up to 32MB due to the two incomplete blocks. The actual amounts differ 4015 // slightly as the chunks start out at 4kB and double in size each time, 4016 // meaning that the maximum fixed overhead (up to 32MB with defaults) is 4017 // at most ~30% of the total allocation size. 4018 size_t max_chunk_size; 4019 4020 } ufbx_allocator_opts; 4021 4022 // -- IO callbacks 4023 4024 // Try to read up to `size` bytes to `data`, return the amount of read bytes. 4025 // Return `SIZE_MAX` to indicate an IO error. 4026 typedef size_t ufbx_read_fn(void *user, void *data, size_t size); 4027 4028 // Skip `size` bytes in the file. 4029 typedef bool ufbx_skip_fn(void *user, size_t size); 4030 4031 // Get the size of the file. 4032 // Return `0` if unknown, `UINT64_MAX` if error. 4033 typedef uint64_t ufbx_size_fn(void *user); 4034 4035 // Close the file 4036 typedef void ufbx_close_fn(void *user); 4037 4038 typedef struct ufbx_stream { 4039 ufbx_read_fn *read_fn; // < Required 4040 ufbx_skip_fn *skip_fn; // < Optional: Will use `read_fn()` if missing 4041 ufbx_size_fn *size_fn; // < Optional 4042 ufbx_close_fn *close_fn; // < Optional 4043 4044 // Context passed to other functions 4045 void *user; 4046 } ufbx_stream; 4047 4048 typedef enum ufbx_open_file_type UFBX_ENUM_REPR { 4049 UFBX_OPEN_FILE_MAIN_MODEL, // < Main model file 4050 UFBX_OPEN_FILE_GEOMETRY_CACHE, // < Unknown geometry cache file 4051 UFBX_OPEN_FILE_OBJ_MTL, // < .mtl material library file 4052 4053 UFBX_ENUM_FORCE_WIDTH(UFBX_OPEN_FILE_TYPE) 4054 } ufbx_open_file_type; 4055 4056 UFBX_ENUM_TYPE(ufbx_open_file_type, UFBX_OPEN_FILE_TYPE, UFBX_OPEN_FILE_OBJ_MTL); 4057 4058 typedef uintptr_t ufbx_open_file_context; 4059 4060 typedef struct ufbx_open_file_info { 4061 // Context that can be passed to the following functions to use a shared allocator: 4062 // ufbx_open_file_ctx() 4063 // ufbx_open_memory_ctx() 4064 ufbx_open_file_context context; 4065 4066 // Kind of file to load. 4067 ufbx_open_file_type type; 4068 4069 // Original filename in the file, not resolved or UTF-8 encoded. 4070 // NOTE: Not necessarily NULL-terminated! 4071 ufbx_blob original_filename; 4072 } ufbx_open_file_info; 4073 4074 // Callback for opening an external file from the filesystem 4075 typedef bool ufbx_open_file_fn(void *user, ufbx_stream *stream, const char *path, size_t path_len, const ufbx_open_file_info *info); 4076 4077 typedef struct ufbx_open_file_cb { 4078 ufbx_open_file_fn *fn; 4079 void *user; 4080 4081 UFBX_CALLBACK_IMPL(ufbx_open_file_cb, ufbx_open_file_fn, bool, 4082 (void *user, ufbx_stream *stream, const char *path, size_t path_len, const ufbx_open_file_info *info), 4083 (stream, path, path_len, info)) 4084 } ufbx_open_file_cb; 4085 4086 // Options for `ufbx_open_file()`. 4087 typedef struct ufbx_open_file_opts { 4088 uint32_t _begin_zero; 4089 4090 // Allocator to allocate the memory with. 4091 ufbx_allocator_opts allocator; 4092 4093 // The filename is guaranteed to be NULL-terminated. 4094 ufbx_unsafe bool filename_null_terminated; 4095 4096 uint32_t _end_zero; 4097 } ufbx_open_file_opts; 4098 4099 // Memory stream options 4100 typedef void ufbx_close_memory_fn(void *user, void *data, size_t data_size); 4101 4102 typedef struct ufbx_close_memory_cb { 4103 ufbx_close_memory_fn *fn; 4104 void *user; 4105 4106 UFBX_CALLBACK_IMPL(ufbx_close_memory_cb, ufbx_close_memory_fn, void, 4107 (void *user, void *data, size_t data_size), 4108 (data, data_size)) 4109 } ufbx_close_memory_cb; 4110 4111 // Options for `ufbx_open_memory()`. 4112 typedef struct ufbx_open_memory_opts { 4113 uint32_t _begin_zero; 4114 4115 // Allocator to allocate the memory with. 4116 // NOTE: Used even if no copy is made to allocate a small metadata block. 4117 ufbx_allocator_opts allocator; 4118 4119 // Do not copy the memory. 4120 // You can use `close_cb` to free the memory when the stream is closed. 4121 // NOTE: This means the provided data pointer is referenced after creating 4122 // the memory stream, make sure the data stays valid until the stream is closed! 4123 ufbx_unsafe bool no_copy; 4124 4125 // Callback to free the memory blob. 4126 ufbx_close_memory_cb close_cb; 4127 4128 uint32_t _end_zero; 4129 } ufbx_open_memory_opts; 4130 4131 // Detailed error stack frame. 4132 // NOTE: You must compile `ufbx.c` with `UFBX_ENABLE_ERROR_STACK` to enable the error stack. 4133 typedef struct ufbx_error_frame { 4134 uint32_t source_line; 4135 ufbx_string function; 4136 ufbx_string description; 4137 } ufbx_error_frame; 4138 4139 // Error causes (and `UFBX_ERROR_NONE` for no error). 4140 typedef enum ufbx_error_type UFBX_ENUM_REPR { 4141 4142 // No error, operation has been performed successfully. 4143 UFBX_ERROR_NONE, 4144 4145 // Unspecified error, most likely caused by an invalid FBX file or a file 4146 // that contains something ufbx can't handle. 4147 UFBX_ERROR_UNKNOWN, 4148 4149 // File not found. 4150 UFBX_ERROR_FILE_NOT_FOUND, 4151 4152 // Empty file. 4153 UFBX_ERROR_EMPTY_FILE, 4154 4155 // External file not found. 4156 // See `ufbx_load_opts.load_external_files` for more information. 4157 UFBX_ERROR_EXTERNAL_FILE_NOT_FOUND, 4158 4159 // Out of memory (allocator returned `NULL`). 4160 UFBX_ERROR_OUT_OF_MEMORY, 4161 4162 // `ufbx_allocator_opts.memory_limit` exhausted. 4163 UFBX_ERROR_MEMORY_LIMIT, 4164 4165 // `ufbx_allocator_opts.allocation_limit` exhausted. 4166 UFBX_ERROR_ALLOCATION_LIMIT, 4167 4168 // File ended abruptly. 4169 UFBX_ERROR_TRUNCATED_FILE, 4170 4171 // IO read error. 4172 // eg. returning `SIZE_MAX` from `ufbx_stream.read_fn` or stdio `ferror()` condition. 4173 UFBX_ERROR_IO, 4174 4175 // User cancelled the loading via `ufbx_load_opts.progress_cb` returning `UFBX_PROGRESS_CANCEL`. 4176 UFBX_ERROR_CANCELLED, 4177 4178 // Could not detect file format from file data or filename. 4179 // HINT: You can supply it manually using `ufbx_load_opts.file_format` or use `ufbx_load_opts.filename` 4180 // when using `ufbx_load_memory()` to let ufbx guess the format from the extension. 4181 UFBX_ERROR_UNRECOGNIZED_FILE_FORMAT, 4182 4183 // Options struct (eg. `ufbx_load_opts`) is not cleared to zero. 4184 // Make sure you initialize the structure to zero via eg. 4185 // ufbx_load_opts opts = { 0 }; // C 4186 // ufbx_load_opts opts = { }; // C++ 4187 UFBX_ERROR_UNINITIALIZED_OPTIONS, 4188 4189 // The vertex streams in `ufbx_generate_indices()` are empty. 4190 UFBX_ERROR_ZERO_VERTEX_SIZE, 4191 4192 // Vertex stream passed to `ufbx_generate_indices()`. 4193 UFBX_ERROR_TRUNCATED_VERTEX_STREAM, 4194 4195 // Invalid UTF-8 encountered in a file when loading with `UFBX_UNICODE_ERROR_HANDLING_ABORT_LOADING`. 4196 UFBX_ERROR_INVALID_UTF8, 4197 4198 // Feature needed for the operation has been compiled out. 4199 UFBX_ERROR_FEATURE_DISABLED, 4200 4201 // Attempting to tessellate an invalid NURBS object. 4202 // See `ufbx_nurbs_basis.valid`. 4203 UFBX_ERROR_BAD_NURBS, 4204 4205 // Out of bounds index in the file when loading with `UFBX_INDEX_ERROR_HANDLING_ABORT_LOADING`. 4206 UFBX_ERROR_BAD_INDEX, 4207 4208 // Node is deeper than `ufbx_load_opts.node_depth_limit` in the hierarchy. 4209 UFBX_ERROR_NODE_DEPTH_LIMIT, 4210 4211 // Error parsing ASCII array in a thread. 4212 // Threaded ASCII parsing is slightly more strict than non-threaded, for cursed files, 4213 // set `ufbx_load_opts.force_single_thread_ascii_parsing` to `true`. 4214 UFBX_ERROR_THREADED_ASCII_PARSE, 4215 4216 // Unsafe options specified without enabling `ufbx_load_opts.allow_unsafe`. 4217 UFBX_ERROR_UNSAFE_OPTIONS, 4218 4219 // Duplicated override property in `ufbx_create_anim()` 4220 UFBX_ERROR_DUPLICATE_OVERRIDE, 4221 4222 // Unsupported file format version. 4223 // ufbx still tries to load files with unsupported versions, see `UFBX_WARNING_UNSUPPORTED_VERSION`. 4224 UFBX_ERROR_UNSUPPORTED_VERSION, 4225 4226 UFBX_ENUM_FORCE_WIDTH(UFBX_ERROR_TYPE) 4227 } ufbx_error_type; 4228 4229 UFBX_ENUM_TYPE(ufbx_error_type, UFBX_ERROR_TYPE, UFBX_ERROR_UNSUPPORTED_VERSION); 4230 4231 // Error description with detailed stack trace 4232 // HINT: You can use `ufbx_format_error()` for formatting the error 4233 typedef struct ufbx_error { 4234 4235 // Type of the error, or `UFBX_ERROR_NONE` if successful. 4236 ufbx_error_type type; 4237 4238 // Description of the error type. 4239 ufbx_string description; 4240 4241 // Internal error stack. 4242 // NOTE: You must compile `ufbx.c` with `UFBX_ENABLE_ERROR_STACK` to enable the error stack. 4243 uint32_t stack_size; 4244 ufbx_error_frame stack[UFBX_ERROR_STACK_MAX_DEPTH]; 4245 4246 // Additional error information, such as missing file filename. 4247 // `info` is a NULL-terminated UTF-8 string containing `info_length` bytes, excluding the trailing `'\0'`. 4248 size_t info_length; 4249 char info[UFBX_ERROR_INFO_LENGTH]; 4250 4251 } ufbx_error; 4252 4253 // -- Progress callbacks 4254 4255 // Loading progress information. 4256 typedef struct ufbx_progress { 4257 uint64_t bytes_read; 4258 uint64_t bytes_total; 4259 } ufbx_progress; 4260 4261 // Progress result returned from `ufbx_progress_fn()` callback. 4262 // Determines whether ufbx should continue or abort the loading. 4263 typedef enum ufbx_progress_result UFBX_ENUM_REPR { 4264 4265 // Continue loading the file. 4266 UFBX_PROGRESS_CONTINUE = 0x100, 4267 4268 // Cancel loading and fail with `UFBX_ERROR_CANCELLED`. 4269 UFBX_PROGRESS_CANCEL = 0x200, 4270 4271 UFBX_ENUM_FORCE_WIDTH(UFBX_PROGRESS_RESULT) 4272 } ufbx_progress_result; 4273 4274 // Called periodically with the current progress. 4275 // Return `UFBX_PROGRESS_CANCEL` to cancel further processing. 4276 typedef ufbx_progress_result ufbx_progress_fn(void *user, const ufbx_progress *progress); 4277 4278 typedef struct ufbx_progress_cb { 4279 ufbx_progress_fn *fn; 4280 void *user; 4281 4282 UFBX_CALLBACK_IMPL(ufbx_progress_cb, ufbx_progress_fn, ufbx_progress_result, 4283 (void *user, const ufbx_progress *progress), 4284 (progress)) 4285 } ufbx_progress_cb; 4286 4287 // -- Inflate 4288 4289 typedef struct ufbx_inflate_input ufbx_inflate_input; 4290 typedef struct ufbx_inflate_retain ufbx_inflate_retain; 4291 4292 // Source data/stream to decompress with `ufbx_inflate()` 4293 struct ufbx_inflate_input { 4294 // Total size of the data in bytes 4295 size_t total_size; 4296 4297 // (optional) Initial or complete data chunk 4298 const void *data; 4299 size_t data_size; 4300 4301 // (optional) Temporary buffer, defaults to 256b stack buffer 4302 void *buffer; 4303 size_t buffer_size; 4304 4305 // (optional) Streaming read function, concatenated after `data` 4306 ufbx_read_fn *read_fn; 4307 void *read_user; 4308 4309 // (optional) Progress reporting 4310 ufbx_progress_cb progress_cb; 4311 uint64_t progress_interval_hint; // < Bytes between progress report calls 4312 4313 // (optional) Change the progress scope 4314 uint64_t progress_size_before; 4315 uint64_t progress_size_after; 4316 4317 // (optional) No the DEFLATE header 4318 bool no_header; 4319 4320 // (optional) No the Adler32 checksum 4321 bool no_checksum; 4322 4323 // (optional) Force internal fast lookup bit amount 4324 size_t internal_fast_bits; 4325 }; 4326 4327 // Persistent data between `ufbx_inflate()` calls 4328 // NOTE: You must set `initialized` to `false`, but `data` may be uninitialized 4329 struct ufbx_inflate_retain { 4330 bool initialized; 4331 uint64_t data[1024]; 4332 }; 4333 4334 typedef enum ufbx_index_error_handling UFBX_ENUM_REPR { 4335 // Clamp to a valid value. 4336 UFBX_INDEX_ERROR_HANDLING_CLAMP, 4337 // Set bad indices to `UFBX_NO_INDEX`. 4338 // This is the recommended way if you need to deal with files with gaps in information. 4339 // HINT: If you use this `ufbx_get_vertex_TYPE()` functions will return zero 4340 // on invalid indices instead of failing. 4341 UFBX_INDEX_ERROR_HANDLING_NO_INDEX, 4342 // Fail loading entierely when encountering a bad index. 4343 UFBX_INDEX_ERROR_HANDLING_ABORT_LOADING, 4344 // Pass bad indices through as-is. 4345 // Requires `ufbx_load_opts.allow_unsafe`. 4346 // UNSAFE: Breaks any API guarantees regarding indexes being in bounds and makes 4347 // `ufbx_get_vertex_TYPE()` memory-unsafe to use. 4348 UFBX_INDEX_ERROR_HANDLING_UNSAFE_IGNORE, 4349 4350 UFBX_ENUM_FORCE_WIDTH(UFBX_INDEX_ERROR_HANDLING) 4351 } ufbx_index_error_handling; 4352 4353 UFBX_ENUM_TYPE(ufbx_index_error_handling, UFBX_INDEX_ERROR_HANDLING, UFBX_INDEX_ERROR_HANDLING_UNSAFE_IGNORE); 4354 4355 typedef enum ufbx_unicode_error_handling UFBX_ENUM_REPR { 4356 // Replace errors with U+FFFD "Replacement Character" 4357 UFBX_UNICODE_ERROR_HANDLING_REPLACEMENT_CHARACTER, 4358 // Replace errors with '_' U+5F "Low Line" 4359 UFBX_UNICODE_ERROR_HANDLING_UNDERSCORE, 4360 // Replace errors with '?' U+3F "Question Mark" 4361 UFBX_UNICODE_ERROR_HANDLING_QUESTION_MARK, 4362 // Remove errors from the output 4363 UFBX_UNICODE_ERROR_HANDLING_REMOVE, 4364 // Fail loading on encountering an Unicode error 4365 UFBX_UNICODE_ERROR_HANDLING_ABORT_LOADING, 4366 // Ignore and pass-through non-UTF-8 string data. 4367 // Requires `ufbx_load_opts.allow_unsafe`. 4368 // UNSAFE: Breaks API guarantee that `ufbx_string` is UTF-8 encoded. 4369 UFBX_UNICODE_ERROR_HANDLING_UNSAFE_IGNORE, 4370 4371 UFBX_ENUM_FORCE_WIDTH(UFBX_UNICODE_ERROR_HANDLING) 4372 } ufbx_unicode_error_handling; 4373 4374 UFBX_ENUM_TYPE(ufbx_unicode_error_handling, UFBX_UNICODE_ERROR_HANDLING, UFBX_UNICODE_ERROR_HANDLING_UNSAFE_IGNORE); 4375 4376 // How to handle FBX node geometry transforms. 4377 // FBX nodes can have "geometry transforms" that affect only the attached meshes, 4378 // but not the children. This is not allowed in many scene representations so 4379 // ufbx provides some ways to simplify them. 4380 // Geometry transforms can also be used to transform any other attributes such 4381 // as lights or cameras. 4382 typedef enum ufbx_geometry_transform_handling UFBX_ENUM_REPR { 4383 4384 // Preserve the geometry transforms as-is. 4385 // To be correct for all files you have to use `ufbx_node.geometry_transform`, 4386 // `ufbx_node.geometry_to_node`, or `ufbx_node.geometry_to_world` to compensate 4387 // for any potential geometry transforms. 4388 UFBX_GEOMETRY_TRANSFORM_HANDLING_PRESERVE, 4389 4390 // Add helper nodes between the nodes and geometry where needed. 4391 // The created nodes have `ufbx_node.is_geometry_transform_helper` set and are 4392 // named `ufbx_load_opts.geometry_transform_helper_name`. 4393 UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES, 4394 4395 // Modify the geometry of meshes attached to nodes with geometry transforms. 4396 // Will add helper nodes like `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES` if 4397 // necessary, for example if there are multiple instances of the same mesh with 4398 // geometry transforms. 4399 UFBX_GEOMETRY_TRANSFORM_HANDLING_MODIFY_GEOMETRY, 4400 4401 // Modify the geometry of meshes attached to nodes with geometry transforms. 4402 // NOTE: This will not work correctly for instanced geometry. 4403 UFBX_GEOMETRY_TRANSFORM_HANDLING_MODIFY_GEOMETRY_NO_FALLBACK, 4404 4405 UFBX_ENUM_FORCE_WIDTH(UFBX_GEOMETRY_TRANSFORM_HANDLING) 4406 } ufbx_geometry_transform_handling; 4407 4408 UFBX_ENUM_TYPE(ufbx_geometry_transform_handling, UFBX_GEOMETRY_TRANSFORM_HANDLING, UFBX_GEOMETRY_TRANSFORM_HANDLING_MODIFY_GEOMETRY_NO_FALLBACK); 4409 4410 // How to handle FBX transform inherit modes. 4411 typedef enum ufbx_inherit_mode_handling UFBX_ENUM_REPR { 4412 4413 // Preserve inherit mode in `ufbx_node.inherit_mode`. 4414 // NOTE: To correctly handle all scenes you would need to handle the 4415 // non-standard inherit modes. 4416 UFBX_INHERIT_MODE_HANDLING_PRESERVE, 4417 4418 // Create scale helper nodes parented to nodes that need special inheritance. 4419 // Scale helper nodes will have `ufbx_node.is_scale_helper` and parents of 4420 // scale helpers will have `ufbx_node.scale_helper` pointing to it. 4421 UFBX_INHERIT_MODE_HANDLING_HELPER_NODES, 4422 4423 // Attempt to compensate for bone scale by inversely scaling children. 4424 // NOTE: This only works for uniform non-animated scaling, if scale is 4425 // non-uniform or animated, ufbx will add scale helpers in the same way 4426 // as `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`. 4427 UFBX_INHERIT_MODE_HANDLING_COMPENSATE, 4428 4429 // Attempt to compensate for bone scale by inversely scaling children. 4430 // Will never create helper nodes. 4431 UFBX_INHERIT_MODE_HANDLING_COMPENSATE_NO_FALLBACK, 4432 4433 // Ignore non-standard inheritance modes. 4434 // Forces all nodes to have `UFBX_INHERIT_MODE_NORMAL` regardless of the 4435 // inherit mode specified in the file. This can be useful for emulating 4436 // results from importers/programs that don't support inherit modes. 4437 UFBX_INHERIT_MODE_HANDLING_IGNORE, 4438 4439 UFBX_ENUM_FORCE_WIDTH(UFBX_INHERIT_MODE_HANDLING) 4440 } ufbx_inherit_mode_handling; 4441 4442 UFBX_ENUM_TYPE(ufbx_inherit_mode_handling, UFBX_INHERIT_MODE_HANDLING, UFBX_INHERIT_MODE_HANDLING_IGNORE); 4443 4444 // How to handle FBX transform pivots. 4445 typedef enum ufbx_pivot_handling UFBX_ENUM_REPR { 4446 4447 // Take pivots into account when computing the transform. 4448 UFBX_PIVOT_HANDLING_RETAIN, 4449 4450 // Translate objects to be located at their pivot. 4451 // NOTE: Only applied if rotation and scaling pivots are equal. 4452 // NOTE: Results in geometric translation. Use `ufbx_geometry_transform_handling` 4453 // to interpret these in a standard scene graph. 4454 UFBX_PIVOT_HANDLING_ADJUST_TO_PIVOT, 4455 4456 UFBX_ENUM_FORCE_WIDTH(UFBX_PIVOT_HANDLING) 4457 } ufbx_pivot_handling; 4458 4459 UFBX_ENUM_TYPE(ufbx_pivot_handling, UFBX_PIVOT_HANDLING, UFBX_PIVOT_HANDLING_ADJUST_TO_PIVOT); 4460 4461 typedef enum ufbx_baked_key_flags UFBX_FLAG_REPR { 4462 // This keyframe represents a constant step from the left side 4463 UFBX_BAKED_KEY_STEP_LEFT = 0x1, 4464 // This keyframe represents a constant step from the right side 4465 UFBX_BAKED_KEY_STEP_RIGHT = 0x2, 4466 // This keyframe is the main part of a step 4467 // Bordering either `UFBX_BAKED_KEY_STEP_LEFT` or `UFBX_BAKED_KEY_STEP_RIGHT`. 4468 UFBX_BAKED_KEY_STEP_KEY = 0x4, 4469 // This keyframe is a real keyframe in the source animation 4470 UFBX_BAKED_KEY_KEYFRAME = 0x8, 4471 // This keyframe has been reduced by maximum sample rate. 4472 // See `ufbx_bake_opts.maximum_sample_rate`. 4473 UFBX_BAKED_KEY_REDUCED = 0x10, 4474 4475 UFBX_FLAG_FORCE_WIDTH(UFBX_BAKED_KEY) 4476 } ufbx_baked_key_flags; 4477 4478 typedef struct ufbx_baked_vec3 { 4479 double time; // < Time of the keyframe, in seconds 4480 ufbx_vec3 value; // < Value at `time`, can be linearly interpolated 4481 ufbx_baked_key_flags flags; // < Additional information about the keyframe 4482 } ufbx_baked_vec3; 4483 4484 UFBX_LIST_TYPE(ufbx_baked_vec3_list, ufbx_baked_vec3); 4485 4486 typedef struct ufbx_baked_quat { 4487 double time; // < Time of the keyframe, in seconds 4488 ufbx_quat value; // < Value at `time`, can be (spherically) linearly interpolated 4489 ufbx_baked_key_flags flags; // < Additional information about the keyframe 4490 } ufbx_baked_quat; 4491 4492 UFBX_LIST_TYPE(ufbx_baked_quat_list, ufbx_baked_quat); 4493 4494 // Baked transform animation for a single node. 4495 typedef struct ufbx_baked_node { 4496 4497 // Typed ID of the node, maps to `ufbx_scene.nodes[]`. 4498 uint32_t typed_id; 4499 // Element ID of the element, maps to `ufbx_scene.elements[]`. 4500 uint32_t element_id; 4501 4502 // The translation channel has constant values for the whole animation. 4503 bool constant_translation; 4504 // The rotation channel has constant values for the whole animation. 4505 bool constant_rotation; 4506 // The scale channel has constant values for the whole animation. 4507 bool constant_scale; 4508 4509 // Translation keys for the animation, maps to `ufbx_node.local_transform.translation`. 4510 ufbx_baked_vec3_list translation_keys; 4511 // Rotation keyframes, maps to `ufbx_node.local_transform.rotation`. 4512 ufbx_baked_quat_list rotation_keys; 4513 // Scale keyframes, maps to `ufbx_node.local_transform.scale`. 4514 ufbx_baked_vec3_list scale_keys; 4515 4516 } ufbx_baked_node; 4517 4518 UFBX_LIST_TYPE(ufbx_baked_node_list, ufbx_baked_node); 4519 4520 // Baked property animation. 4521 typedef struct ufbx_baked_prop { 4522 // Name of the property, eg. `"Visibility"`. 4523 ufbx_string name; 4524 // The value of the property is constant for the whole animation. 4525 bool constant_value; 4526 // Property value keys. 4527 ufbx_baked_vec3_list keys; 4528 } ufbx_baked_prop; 4529 4530 UFBX_LIST_TYPE(ufbx_baked_prop_list, ufbx_baked_prop); 4531 4532 // Baked property animation for a single element. 4533 typedef struct ufbx_baked_element { 4534 // Element ID of the element, maps to `ufbx_scene.elements[]`. 4535 uint32_t element_id; 4536 // List of properties the animation modifies. 4537 ufbx_baked_prop_list props; 4538 } ufbx_baked_element; 4539 4540 UFBX_LIST_TYPE(ufbx_baked_element_list, ufbx_baked_element); 4541 4542 typedef struct ufbx_baked_anim_metadata { 4543 // Memory statistics 4544 size_t result_memory_used; 4545 size_t temp_memory_used; 4546 size_t result_allocs; 4547 size_t temp_allocs; 4548 } ufbx_baked_anim_metadata; 4549 4550 // Animation baked into linearly interpolated keyframes. 4551 // See `ufbx_bake_anim()`. 4552 typedef struct ufbx_baked_anim { 4553 4554 // Nodes that are modified by the animation. 4555 // Some nodes may be missing if the specified animation does not transform them. 4556 // Conversely, some non-obviously animated nodes may be included as exporters 4557 // often may add dummy keyframes for objects. 4558 ufbx_baked_node_list nodes; 4559 4560 // Element properties modified by the animation. 4561 ufbx_baked_element_list elements; 4562 4563 // Playback time range for the animation. 4564 double playback_time_begin; 4565 double playback_time_end; 4566 double playback_duration; 4567 4568 // Keyframe time range. 4569 double key_time_min; 4570 double key_time_max; 4571 4572 // Additional bake information. 4573 ufbx_baked_anim_metadata metadata; 4574 4575 } ufbx_baked_anim; 4576 4577 // -- Thread API 4578 4579 // Internal thread pool handle. 4580 // Passed to `ufbx_thread_pool_run_task()` from an user thread to run ufbx tasks. 4581 // HINT: This context can store a user pointer via `ufbx_thread_pool_set_user_ptr()`. 4582 typedef uintptr_t ufbx_thread_pool_context; 4583 4584 // Thread pool creation information from ufbx. 4585 typedef struct ufbx_thread_pool_info { 4586 uint32_t max_concurrent_tasks; 4587 } ufbx_thread_pool_info; 4588 4589 // Initialize the thread pool. 4590 // Return `true` on success. 4591 typedef bool ufbx_thread_pool_init_fn(void *user, ufbx_thread_pool_context ctx, const ufbx_thread_pool_info *info); 4592 4593 // Run tasks `count` tasks in threads. 4594 // You must call `ufbx_thread_pool_run_task()` with indices `[start_index, start_index + count)`. 4595 // The threads are launched in batches indicated by `group`, see `UFBX_THREAD_GROUP_COUNT` for more information. 4596 // Ideally, you should run all the task indices in parallel within each `ufbx_thread_pool_run_fn()` call. 4597 typedef void ufbx_thread_pool_run_fn(void *user, ufbx_thread_pool_context ctx, uint32_t group, uint32_t start_index, uint32_t count); 4598 4599 // Wait for previous tasks spawned in `ufbx_thread_pool_run_fn()` to finish. 4600 // `group` specifies the batch to wait for, `max_index` contains `start_index + count` from that group instance. 4601 typedef void ufbx_thread_pool_wait_fn(void *user, ufbx_thread_pool_context ctx, uint32_t group, uint32_t max_index); 4602 4603 // Free the thread pool. 4604 typedef void ufbx_thread_pool_free_fn(void *user, ufbx_thread_pool_context ctx); 4605 4606 // Thread pool interface. 4607 // See functions above for more information. 4608 // 4609 // Hypothetical example of calls, where `UFBX_THREAD_GROUP_COUNT=2` for simplicity: 4610 // 4611 // run_fn(group=0, start_index=0, count=4) -> t0 := threaded { ufbx_thread_pool_run_task(0..3) } 4612 // run_fn(group=1, start_index=4, count=10) -> t1 := threaded { ufbx_thread_pool_run_task(4..10) } 4613 // wait_fn(group=0, max_index=4) -> wait_threads(t0) 4614 // run_fn(group=0, start_index=10, count=15) -> t0 := threaded { ufbx_thread_pool_run_task(10..14) } 4615 // wait_fn(group=1, max_index=10) -> wait_threads(t1) 4616 // wait_fn(group=0, max_index=15) -> wait_threads(t0) 4617 // 4618 typedef struct ufbx_thread_pool { 4619 ufbx_thread_pool_init_fn *init_fn; // < Optional 4620 ufbx_thread_pool_run_fn *run_fn; // < Required 4621 ufbx_thread_pool_wait_fn *wait_fn; // < Required 4622 ufbx_thread_pool_free_fn *free_fn; // < Optional 4623 void *user; 4624 } ufbx_thread_pool; 4625 4626 // Thread pool options. 4627 typedef struct ufbx_thread_opts { 4628 4629 // Thread pool interface. 4630 // HINT: You can use `extra/ufbx_os.h` to provide a thread pool. 4631 ufbx_thread_pool pool; 4632 4633 // Maximum of tasks to have in-flight. 4634 // Default: 2048 4635 size_t num_tasks; 4636 4637 // Maximum amount of memory to use for batched threaded processing. 4638 // Default: 32MB 4639 // NOTE: The actual used memory usage might be higher, if there are individual tasks 4640 // that rqeuire a high amount of memory. 4641 size_t memory_limit; 4642 4643 } ufbx_thread_opts; 4644 4645 // Flags to control nanimation evaluation functions. 4646 typedef enum ufbx_evaluate_flags UFBX_FLAG_REPR { 4647 4648 // Do not extrapolate past the keyframes. 4649 UFBX_EVALUATE_FLAG_NO_EXTRAPOLATION = 0x1, 4650 4651 UFBX_FLAG_FORCE_WIDTH(ufbx_evaluate_flags) 4652 } ufbx_evaluate_flags; 4653 4654 // -- Main API 4655 4656 // Options for `ufbx_load_file/memory/stream/stdio()` 4657 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 4658 typedef struct ufbx_load_opts { 4659 uint32_t _begin_zero; 4660 4661 ufbx_allocator_opts temp_allocator; // < Allocator used during loading 4662 ufbx_allocator_opts result_allocator; // < Allocator used for the final scene 4663 ufbx_thread_opts thread_opts; // < Threading options 4664 4665 // Preferences 4666 bool ignore_geometry; // < Do not load geometry datsa (vertices, indices, etc) 4667 bool ignore_animation; // < Do not load animation curves 4668 bool ignore_embedded; // < Do not load embedded content 4669 bool ignore_all_content; // < Do not load any content (geometry, animation, embedded) 4670 4671 bool evaluate_skinning; // < Evaluate skinning (see ufbx_mesh.skinned_vertices) 4672 bool evaluate_caches; // < Evaluate vertex caches (see ufbx_mesh.skinned_vertices) 4673 4674 // Try to open external files referenced by the main file automatically. 4675 // Applies to geometry caches and .mtl files for OBJ. 4676 // NOTE: This may be risky for untrusted data as the input files may contain 4677 // references to arbitrary paths in the filesystem. 4678 // NOTE: This only applies to files *implicitly* referenced by the scene, if 4679 // you request additional files via eg. `ufbx_load_opts.obj_mtl_path` they 4680 // are still loaded. 4681 // NOTE: Will fail loading if any external files are not found by default, use 4682 // `ufbx_load_opts.ignore_missing_external_files` to suppress this, in this case 4683 // you can find the errors at `ufbx_metadata.warnings[]` as `UFBX_WARNING_MISSING_EXTERNAL_FILE`. 4684 bool load_external_files; 4685 4686 // Don't fail loading if external files are not found. 4687 bool ignore_missing_external_files; 4688 4689 // Don't compute `ufbx_skin_deformer` `vertices` and `weights` arrays saving 4690 // a bit of memory and time if not needed 4691 bool skip_skin_vertices; 4692 4693 // Skip computing `ufbx_mesh.material_parts[]` and `ufbx_mesh.face_group_parts[]`. 4694 bool skip_mesh_parts; 4695 4696 // Clean-up skin weights by removing negative, zero and NAN weights. 4697 bool clean_skin_weights; 4698 4699 // Read Blender materials as PBR values. 4700 // Blender converts PBR materials to legacy FBX Phong materials in a deterministic way. 4701 // If this setting is enabled, such materials will be read as `UFBX_SHADER_BLENDER_PHONG`, 4702 // which means ufbx will be able to parse roughness and metallic textures. 4703 bool use_blender_pbr_material; 4704 4705 // Don't adjust reading the FBX file depending on the detected exporter 4706 bool disable_quirks; 4707 4708 // Don't allow partially broken FBX files to load 4709 bool strict; 4710 4711 // Force ASCII parsing to use a single thread. 4712 // The multi-threaded ASCII parsing is slightly more lenient as it ignores 4713 // the self-reported size of ASCII arrays, that threaded parsing depends on. 4714 bool force_single_thread_ascii_parsing; 4715 4716 // UNSAFE: If enabled allows using unsafe options that may fundamentally 4717 // break the API guarantees. 4718 ufbx_unsafe bool allow_unsafe; 4719 4720 // Specify how to handle broken indices. 4721 ufbx_index_error_handling index_error_handling; 4722 4723 // Connect related elements even if they are broken. If `false` (default) 4724 // `ufbx_skin_cluster` with a missing `bone` field are _not_ included in 4725 // the `ufbx_skin_deformer.clusters[]` array for example. 4726 bool connect_broken_elements; 4727 4728 // Allow nodes that are not connected in any way to the root. Conversely if 4729 // disabled, all lone nodes will be parented under `ufbx_scene.root_node`. 4730 bool allow_nodes_out_of_root; 4731 4732 // Allow meshes with no vertex position attribute. 4733 // NOTE: If this is set `ufbx_mesh.vertex_position.exists` may be `false`. 4734 bool allow_missing_vertex_position; 4735 4736 // Allow faces with zero indices. 4737 bool allow_empty_faces; 4738 4739 // Generate vertex normals for a meshes that are missing normals. 4740 // You can see if the normals have been generated from `ufbx_mesh.generated_normals`. 4741 bool generate_missing_normals; 4742 4743 // Ignore `open_file_cb` when loading the main file. 4744 bool open_main_file_with_default; 4745 4746 // Path separator character, defaults to '\' on Windows and '/' otherwise. 4747 char path_separator; 4748 4749 // Maximum depth of the node hirerachy. 4750 // Will fail with `UFBX_ERROR_NODE_DEPTH_LIMIT` if a node is deeper than this limit. 4751 // NOTE: The default of 0 allows arbitrarily deep hierarchies. Be careful if using 4752 // recursive algorithms without setting this limit. 4753 uint32_t node_depth_limit; 4754 4755 // Estimated file size for progress reporting 4756 uint64_t file_size_estimate; 4757 4758 // Buffer size in bytes to use for reading from files or IO callbacks 4759 size_t read_buffer_size; 4760 4761 // Filename to use as a base for relative file paths if not specified using 4762 // `ufbx_load_file()`. Use `length = SIZE_MAX` for NULL-terminated strings. 4763 // `raw_filename` will be derived from this if empty. 4764 ufbx_string filename; 4765 4766 // Raw non-UTF8 filename. Does not support NULL termination. 4767 // `filename` will be derived from this if empty. 4768 ufbx_blob raw_filename; 4769 4770 // Progress reporting 4771 ufbx_progress_cb progress_cb; 4772 uint64_t progress_interval_hint; // < Bytes between progress report calls 4773 4774 // External file callbacks (defaults to stdio.h) 4775 ufbx_open_file_cb open_file_cb; 4776 4777 // How to handle geometry transforms in the nodes. 4778 // See `ufbx_geometry_transform_handling` for an explanation. 4779 ufbx_geometry_transform_handling geometry_transform_handling; 4780 4781 // How to handle unconventional transform inherit modes. 4782 // See `ufbx_inherit_mode_handling` for an explanation. 4783 ufbx_inherit_mode_handling inherit_mode_handling; 4784 4785 // How to handle pivots. 4786 // See `ufbx_pivot_handling` for an explanation. 4787 ufbx_pivot_handling pivot_handling; 4788 4789 // How to perform space conversion by `target_axes` and `target_unit_meters`. 4790 // See `ufbx_space_conversion` for an explanation. 4791 ufbx_space_conversion space_conversion; 4792 4793 // Axis used to mirror for conversion between left-handed and right-handed coordinates. 4794 ufbx_mirror_axis handedness_conversion_axis; 4795 4796 // Do not change winding of faces when converting handedness. 4797 bool handedness_conversion_retain_winding; 4798 4799 // Reverse winding of all faces. 4800 // If `handedness_conversion_retain_winding` is not specified, mirrored meshes 4801 // will retain their original winding. 4802 bool reverse_winding; 4803 4804 // Apply an implicit root transformation to match axes. 4805 // Used if `ufbx_coordinate_axes_valid(target_axes)`. 4806 ufbx_coordinate_axes target_axes; 4807 4808 // Scale the scene so that one world-space unit is `target_unit_meters` meters. 4809 // By default units are not scaled. 4810 ufbx_real target_unit_meters; 4811 4812 // Target space for camera. 4813 // By default FBX cameras point towards the positive X axis. 4814 // Used if `ufbx_coordinate_axes_valid(target_camera_axes)`. 4815 ufbx_coordinate_axes target_camera_axes; 4816 4817 // Target space for directed lights. 4818 // By default FBX lights point towards the negative Y axis. 4819 // Used if `ufbx_coordinate_axes_valid(target_light_axes)`. 4820 ufbx_coordinate_axes target_light_axes; 4821 4822 // Name for dummy geometry transform helper nodes. 4823 // See `UFBX_GEOMETRY_TRANSFORM_HANDLING_HELPER_NODES`. 4824 ufbx_string geometry_transform_helper_name; 4825 4826 // Name for dummy scale helper nodes. 4827 // See `UFBX_INHERIT_MODE_HANDLING_HELPER_NODES`. 4828 ufbx_string scale_helper_name; 4829 4830 // Normalize vertex normals. 4831 bool normalize_normals; 4832 4833 // Normalize tangents and bitangents. 4834 bool normalize_tangents; 4835 4836 // Override for the root transform 4837 bool use_root_transform; 4838 ufbx_transform root_transform; 4839 4840 // Animation keyframe clamp threshold, only applies to specific interpolation modes. 4841 double key_clamp_threshold; 4842 4843 // Specify how to handle Unicode errors in strings. 4844 ufbx_unicode_error_handling unicode_error_handling; 4845 4846 // Retain the 'W' component of mesh normal/tangent/bitangent. 4847 // See `ufbx_vertex_attrib.values_w`. 4848 bool retain_vertex_attrib_w; 4849 4850 // Retain the raw document structure using `ufbx_dom_node`. 4851 bool retain_dom; 4852 4853 // Force a specific file format instead of detecting it. 4854 ufbx_file_format file_format; 4855 4856 // How far to read into the file to determine the file format. 4857 // Default: 16kB 4858 size_t file_format_lookahead; 4859 4860 // Do not attempt to detect file format from file content. 4861 bool no_format_from_content; 4862 4863 // Do not attempt to detect file format from filename extension. 4864 // ufbx primarily detects file format from the file header, 4865 // this is just used as a fallback. 4866 bool no_format_from_extension; 4867 4868 // (.obj) Try to find .mtl file with matching filename as the .obj file. 4869 // Used if the file specified `mtllib` line is not found, eg. for a file called 4870 // `model.obj` that contains the line `usemtl materials.mtl`, ufbx would first 4871 // try to open `materials.mtl` and if that fails it tries to open `model.mtl`. 4872 bool obj_search_mtl_by_filename; 4873 4874 // (.obj) Don't split geometry into meshes by object. 4875 bool obj_merge_objects; 4876 4877 // (.obj) Don't split geometry into meshes by groups. 4878 bool obj_merge_groups; 4879 4880 // (.obj) Force splitting groups even on object boundaries. 4881 bool obj_split_groups; 4882 4883 // (.obj) Path to the .mtl file. 4884 // Use `length = SIZE_MAX` for NULL-terminated strings. 4885 // NOTE: This is used _instead_ of the one in the file even if not found 4886 // and sidesteps `load_external_files` as it's _explicitly_ requested. 4887 ufbx_string obj_mtl_path; 4888 4889 // (.obj) Data for the .mtl file. 4890 ufbx_blob obj_mtl_data; 4891 4892 // The world unit in meters that .obj files are assumed to be in. 4893 // .obj files do not define the working units. By default the unit scale 4894 // is read as zero, and no unit conversion is performed. 4895 ufbx_real obj_unit_meters; 4896 4897 // Coordinate space .obj files are assumed to be in. 4898 // .obj files do not define the coordinate space they use. By default no 4899 // coordinate space is assumed and no conversion is performed. 4900 ufbx_coordinate_axes obj_axes; 4901 4902 uint32_t _end_zero; 4903 } ufbx_load_opts; 4904 4905 // Options for `ufbx_evaluate_scene()` 4906 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 4907 typedef struct ufbx_evaluate_opts { 4908 uint32_t _begin_zero; 4909 4910 ufbx_allocator_opts temp_allocator; // < Allocator used during evaluation 4911 ufbx_allocator_opts result_allocator; // < Allocator used for the final scene 4912 4913 bool evaluate_skinning; // < Evaluate skinning (see ufbx_mesh.skinned_vertices) 4914 bool evaluate_caches; // < Evaluate vertex caches (see ufbx_mesh.skinned_vertices) 4915 4916 // Evaluation flags. 4917 // See `ufbx_evaluate_flags` for information. 4918 uint32_t evaluate_flags; 4919 4920 // WARNING: Potentially unsafe! Try to open external files such as geometry caches 4921 bool load_external_files; 4922 4923 // External file callbacks (defaults to stdio.h) 4924 ufbx_open_file_cb open_file_cb; 4925 4926 uint32_t _end_zero; 4927 } ufbx_evaluate_opts; 4928 4929 UFBX_LIST_TYPE(ufbx_const_uint32_list, const uint32_t); 4930 UFBX_LIST_TYPE(ufbx_const_real_list, const ufbx_real); 4931 4932 typedef struct ufbx_prop_override_desc { 4933 // Element (`ufbx_element.element_id`) to override the property from 4934 uint32_t element_id; 4935 4936 // Property name to override. 4937 ufbx_string prop_name; 4938 4939 // Override value, use `value.x` for scalars. `value_int` is initialized 4940 // from `value.x` if zero so keep `value` zeroed even if you don't need it! 4941 ufbx_vec4 value; 4942 ufbx_string value_str; 4943 int64_t value_int; 4944 } ufbx_prop_override_desc; 4945 4946 UFBX_LIST_TYPE(ufbx_const_prop_override_desc_list, const ufbx_prop_override_desc); 4947 4948 UFBX_LIST_TYPE(ufbx_const_transform_override_list, const ufbx_transform_override); 4949 4950 typedef struct ufbx_anim_opts { 4951 uint32_t _begin_zero; 4952 4953 // Animation layers indices. 4954 // Corresponding to `ufbx_scene.anim_layers[]`, aka `ufbx_anim_layer.typed_id`. 4955 ufbx_const_uint32_list layer_ids; 4956 4957 // Override layer weights, parallel to `ufbx_anim_opts.layer_ids[]`. 4958 ufbx_const_real_list override_layer_weights; 4959 4960 // Property overrides. 4961 // These allow you to override FBX properties, such as 'UFBX_Lcl_Rotation`. 4962 ufbx_const_prop_override_desc_list prop_overrides; 4963 4964 // Transform overrides. 4965 // These allow you to override individual nodes' `ufbx_node.local_transform`. 4966 ufbx_const_transform_override_list transform_overrides; 4967 4968 // Ignore connected properties 4969 bool ignore_connections; 4970 4971 ufbx_allocator_opts result_allocator; // < Allocator used to create the `ufbx_anim` 4972 4973 uint32_t _end_zero; 4974 } ufbx_anim_opts; 4975 4976 // Specifies how to handle stepped tangents. 4977 typedef enum ufbx_bake_step_handling UFBX_ENUM_REPR { 4978 4979 // One millisecond default step duration, with potential extra slack for converting to `float`. 4980 UFBX_BAKE_STEP_HANDLING_DEFAULT, 4981 4982 // Use a custom interpolation duration for the constant step. 4983 // See `ufbx_bake_opts.step_custom_duration` and optionally `ufbx_bake_opts.step_custom_epsilon`. 4984 UFBX_BAKE_STEP_HANDLING_CUSTOM_DURATION, 4985 4986 // Stepped keyframes are represented as keyframes at the exact same time. 4987 // Use flags `UFBX_BAKED_KEY_STEP_LEFT` and `UFBX_BAKED_KEY_STEP_RIGHT` to differentiate 4988 // between the primary key and edge limits. 4989 UFBX_BAKE_STEP_HANDLING_IDENTICAL_TIME, 4990 4991 // Represent stepped keyframe times as the previous/next representable `double` value. 4992 // Using this and robust linear interpolation will handle stepped tangents correctly 4993 // without having to look at the key flags. 4994 // NOTE: Casting these values to `float` or otherwise modifying them can collapse 4995 // the keyframes to have the identical time. 4996 UFBX_BAKE_STEP_HANDLING_ADJACENT_DOUBLE, 4997 4998 // Treat all stepped tangents as linearly interpolated. 4999 UFBX_BAKE_STEP_HANDLING_IGNORE, 5000 5001 UFBX_ENUM_FORCE_WIDTH(ufbx_bake_step_handling) 5002 } ufbx_bake_step_handling; 5003 5004 UFBX_ENUM_TYPE(ufbx_bake_step_handling, UFBX_BAKE_STEP_HANDLING, UFBX_BAKE_STEP_HANDLING_IGNORE); 5005 5006 typedef struct ufbx_bake_opts { 5007 uint32_t _begin_zero; 5008 5009 ufbx_allocator_opts temp_allocator; // < Allocator used during loading 5010 ufbx_allocator_opts result_allocator; // < Allocator used for the final baked animation 5011 5012 // Move the keyframe times to start from zero regardless of the animation start time. 5013 // For example, for an animation spanning between frames [30, 60] will be moved to 5014 // [0, 30] in the baked animation. 5015 // NOTE: This is in general not equivalent to subtracting `ufbx_anim.time_begin` 5016 // from each keyframe, as this trimming is done exactly using internal FBX ticks. 5017 bool trim_start_time; 5018 5019 // Samples per second to use for resampling non-linear animation. 5020 // Default: 30 5021 double resample_rate; 5022 5023 // Minimum sample rate to not resample. 5024 // Many exporters resample animation by default. To avoid double-resampling 5025 // keyframe rates higher or equal to this will not be resampled. 5026 // Default: 19.5 5027 double minimum_sample_rate; 5028 5029 // Maximum sample rate to use, this will remove keys if they are too close together. 5030 // Default: unlimited 5031 double maximum_sample_rate; 5032 5033 // Bake the raw versions of properties related to transforms. 5034 bool bake_transform_props; 5035 5036 // Do not bake node transforms. 5037 bool skip_node_transforms; 5038 5039 // Do not resample linear rotation keyframes. 5040 // FBX interpolates rotation in Euler angles, so this might cause incorrect interpolation. 5041 bool no_resample_rotation; 5042 5043 // Ignore layer weight animation. 5044 bool ignore_layer_weight_animation; 5045 5046 // Maximum number of segments to generate from one keyframe. 5047 // Default: 32 5048 size_t max_keyframe_segments; 5049 5050 // How to handle stepped tangents. 5051 ufbx_bake_step_handling step_handling; 5052 5053 // Interpolation duration used by `UFBX_BAKE_STEP_HANDLING_CUSTOM_DURATION`. 5054 double step_custom_duration; 5055 5056 // Interpolation epsilon used by `UFBX_BAKE_STEP_HANDLING_CUSTOM_DURATION`. 5057 // Defined as the minimum fractional decrease/increase in key time, ie. 5058 // `time / (1.0 + step_custom_epsilon)` and `time * (1.0 + step_custom_epsilon)`. 5059 double step_custom_epsilon; 5060 5061 // Flags passed to animation evaluation functions. 5062 // See `ufbx_evaluate_flags`. 5063 uint32_t evaluate_flags; 5064 5065 // Enable key reduction. 5066 bool key_reduction_enabled; 5067 5068 // Enable key reduction for non-constant rotations. 5069 // Assumes rotations will be interpolated using a spherical linear interpolation at runtime. 5070 bool key_reduction_rotation; 5071 5072 // Threshold for reducing keys for linear segments. 5073 // Default `0.000001`, use negative to disable. 5074 double key_reduction_threshold; 5075 5076 // Maximum passes over the keys to reduce. 5077 // Every pass can potentially halve the the amount of keys. 5078 // Default: `4` 5079 size_t key_reduction_passes; 5080 5081 uint32_t _end_zero; 5082 } ufbx_bake_opts; 5083 5084 // Options for `ufbx_tessellate_nurbs_curve()` 5085 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5086 typedef struct ufbx_tessellate_curve_opts { 5087 uint32_t _begin_zero; 5088 5089 ufbx_allocator_opts temp_allocator; // < Allocator used during tessellation 5090 ufbx_allocator_opts result_allocator; // < Allocator used for the final line curve 5091 5092 // How many segments tessellate each span in `ufbx_nurbs_basis.spans`. 5093 size_t span_subdivision; 5094 5095 uint32_t _end_zero; 5096 } ufbx_tessellate_curve_opts; 5097 5098 // Options for `ufbx_tessellate_nurbs_surface()` 5099 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5100 typedef struct ufbx_tessellate_surface_opts { 5101 uint32_t _begin_zero; 5102 5103 ufbx_allocator_opts temp_allocator; // < Allocator used during tessellation 5104 ufbx_allocator_opts result_allocator; // < Allocator used for the final mesh 5105 5106 // How many segments tessellate each span in `ufbx_nurbs_basis.spans`. 5107 // NOTE: Default is `4`, _not_ `ufbx_nurbs_surface.span_subdivision_u/v` as that 5108 // would make it easy to create an FBX file with an absurdly high subdivision 5109 // rate (similar to mesh subdivision). Please enforce copy the value yourself 5110 // enforcing whatever limits you deem reasonable. 5111 size_t span_subdivision_u; 5112 size_t span_subdivision_v; 5113 5114 // Skip computing `ufbx_mesh.material_parts[]` 5115 bool skip_mesh_parts; 5116 5117 uint32_t _end_zero; 5118 } ufbx_tessellate_surface_opts; 5119 5120 // Options for `ufbx_subdivide_mesh()` 5121 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5122 typedef struct ufbx_subdivide_opts { 5123 uint32_t _begin_zero; 5124 5125 ufbx_allocator_opts temp_allocator; // < Allocator used during subdivision 5126 ufbx_allocator_opts result_allocator; // < Allocator used for the final mesh 5127 5128 ufbx_subdivision_boundary boundary; 5129 ufbx_subdivision_boundary uv_boundary; 5130 5131 // Do not generate normals 5132 bool ignore_normals; 5133 5134 // Interpolate existing normals using the subdivision rules 5135 // instead of generating new normals 5136 bool interpolate_normals; 5137 5138 // Subdivide also tangent attributes 5139 bool interpolate_tangents; 5140 5141 // Map subdivided vertices into weighted original vertices. 5142 // NOTE: May be O(n^2) if `max_source_vertices` is not specified! 5143 bool evaluate_source_vertices; 5144 5145 // Limit source vertices per subdivided vertex. 5146 size_t max_source_vertices; 5147 5148 // Calculate bone influences over subdivided vertices (if applicable). 5149 // NOTE: May be O(n^2) if `max_skin_weights` is not specified! 5150 bool evaluate_skin_weights; 5151 5152 // Limit bone influences per subdivided vertex. 5153 size_t max_skin_weights; 5154 5155 // Index of the skin deformer to use for `evaluate_skin_weights`. 5156 size_t skin_deformer_index; 5157 5158 uint32_t _end_zero; 5159 } ufbx_subdivide_opts; 5160 5161 // Options for `ufbx_load_geometry_cache()` 5162 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5163 typedef struct ufbx_geometry_cache_opts { 5164 uint32_t _begin_zero; 5165 5166 ufbx_allocator_opts temp_allocator; // < Allocator used during loading 5167 ufbx_allocator_opts result_allocator; // < Allocator used for the final scene 5168 5169 // External file callbacks (defaults to stdio.h) 5170 ufbx_open_file_cb open_file_cb; 5171 5172 // FPS value for converting frame times to seconds 5173 double frames_per_second; 5174 5175 // Axis to mirror the geometry by. 5176 ufbx_mirror_axis mirror_axis; 5177 5178 // Enable scaling `scale_factor` all geometry by. 5179 bool use_scale_factor; 5180 5181 // Factor to scale the geometry by. 5182 ufbx_real scale_factor; 5183 5184 uint32_t _end_zero; 5185 } ufbx_geometry_cache_opts; 5186 5187 // Options for `ufbx_read_geometry_cache_TYPE()` 5188 // NOTE: Initialize to zero with `{ 0 }` (C) or `{ }` (C++) 5189 typedef struct ufbx_geometry_cache_data_opts { 5190 uint32_t _begin_zero; 5191 5192 // External file callbacks (defaults to stdio.h) 5193 ufbx_open_file_cb open_file_cb; 5194 5195 bool additive; 5196 bool use_weight; 5197 ufbx_real weight; 5198 5199 // Ignore scene transform. 5200 bool ignore_transform; 5201 5202 uint32_t _end_zero; 5203 } ufbx_geometry_cache_data_opts; 5204 5205 typedef struct ufbx_panic { 5206 bool did_panic; 5207 size_t message_length; 5208 char message[UFBX_PANIC_MESSAGE_LENGTH]; 5209 } ufbx_panic; 5210 5211 // -- API 5212 5213 #ifdef __cplusplus 5214 extern "C" { 5215 #endif 5216 5217 // Various zero/empty/identity values 5218 ufbx_abi_data const ufbx_string ufbx_empty_string; 5219 ufbx_abi_data const ufbx_blob ufbx_empty_blob; 5220 ufbx_abi_data const ufbx_matrix ufbx_identity_matrix; 5221 ufbx_abi_data const ufbx_transform ufbx_identity_transform; 5222 ufbx_abi_data const ufbx_vec2 ufbx_zero_vec2; 5223 ufbx_abi_data const ufbx_vec3 ufbx_zero_vec3; 5224 ufbx_abi_data const ufbx_vec4 ufbx_zero_vec4; 5225 ufbx_abi_data const ufbx_quat ufbx_identity_quat; 5226 5227 // Commonly used coordinate axes. 5228 ufbx_abi_data const ufbx_coordinate_axes ufbx_axes_right_handed_y_up; 5229 ufbx_abi_data const ufbx_coordinate_axes ufbx_axes_right_handed_z_up; 5230 ufbx_abi_data const ufbx_coordinate_axes ufbx_axes_left_handed_y_up; 5231 ufbx_abi_data const ufbx_coordinate_axes ufbx_axes_left_handed_z_up; 5232 5233 // Sizes of element types. eg `sizeof(ufbx_node)` 5234 ufbx_abi_data const size_t ufbx_element_type_size[UFBX_ELEMENT_TYPE_COUNT]; 5235 5236 // Version of the source file, comparable to `UFBX_HEADER_VERSION` 5237 ufbx_abi_data const uint32_t ufbx_source_version; 5238 5239 5240 // Practically always `true` (see below), if not you need to be careful with threads. 5241 // 5242 // Guaranteed to be `true` in _any_ of the following conditions: 5243 // - ufbx.c has been compiled using: GCC / Clang / MSVC / ICC / EMCC / TCC 5244 // - ufbx.c has been compiled as C++11 or later 5245 // - ufbx.c has been compiled as C11 or later with `<stdatomic.h>` support 5246 // 5247 // If `false` you can't call the following functions concurrently: 5248 // ufbx_evaluate_scene() 5249 // ufbx_free_scene() 5250 // ufbx_subdivide_mesh() 5251 // ufbx_tessellate_nurbs_surface() 5252 // ufbx_free_mesh() 5253 ufbx_abi bool ufbx_is_thread_safe(void); 5254 5255 // Load a scene from a `size` byte memory buffer at `data` 5256 ufbx_abi ufbx_scene *ufbx_load_memory( 5257 const void *data, size_t data_size, 5258 const ufbx_load_opts *opts, ufbx_error *error); 5259 5260 // Load a scene by opening a file named `filename` 5261 ufbx_abi ufbx_scene *ufbx_load_file( 5262 const char *filename, 5263 const ufbx_load_opts *opts, ufbx_error *error); 5264 ufbx_abi ufbx_scene *ufbx_load_file_len( 5265 const char *filename, size_t filename_len, 5266 const ufbx_load_opts *opts, ufbx_error *error); 5267 5268 // Load a scene by reading from an `FILE *file` stream 5269 // NOTE: `file` is passed as a `void` pointer to avoid including <stdio.h> 5270 ufbx_abi ufbx_scene *ufbx_load_stdio( 5271 void *file, 5272 const ufbx_load_opts *opts, ufbx_error *error); 5273 5274 // Load a scene by reading from an `FILE *file` stream with a prefix 5275 // NOTE: `file` is passed as a `void` pointer to avoid including <stdio.h> 5276 ufbx_abi ufbx_scene *ufbx_load_stdio_prefix( 5277 void *file, 5278 const void *prefix, size_t prefix_size, 5279 const ufbx_load_opts *opts, ufbx_error *error); 5280 5281 // Load a scene from a user-specified stream 5282 ufbx_abi ufbx_scene *ufbx_load_stream( 5283 const ufbx_stream *stream, 5284 const ufbx_load_opts *opts, ufbx_error *error); 5285 5286 // Load a scene from a user-specified stream with a prefix 5287 ufbx_abi ufbx_scene *ufbx_load_stream_prefix( 5288 const ufbx_stream *stream, 5289 const void *prefix, size_t prefix_size, 5290 const ufbx_load_opts *opts, ufbx_error *error); 5291 5292 // Free a previously loaded or evaluated scene 5293 ufbx_abi void ufbx_free_scene(ufbx_scene *scene); 5294 5295 // Increment `scene` refcount 5296 ufbx_abi void ufbx_retain_scene(ufbx_scene *scene); 5297 5298 // Format a textual description of `error`. 5299 // Always produces a NULL-terminated string to `char dst[dst_size]`, truncating if 5300 // necessary. Returns the number of characters written not including the NULL terminator. 5301 ufbx_abi size_t ufbx_format_error(char *dst, size_t dst_size, const ufbx_error *error); 5302 5303 // Query 5304 5305 // Find a property `name` from `props`, returns `NULL` if not found. 5306 // Searches through `ufbx_props.defaults` as well. 5307 ufbx_abi ufbx_prop *ufbx_find_prop_len(const ufbx_props *props, const char *name, size_t name_len); 5308 ufbx_abi ufbx_prop *ufbx_find_prop(const ufbx_props *props, const char *name); 5309 5310 // Utility functions for finding the value of a property, returns `def` if not found. 5311 // NOTE: For `ufbx_string` you need to ensure the lifetime of the default is 5312 // sufficient as no copy is made. 5313 ufbx_abi ufbx_real ufbx_find_real_len(const ufbx_props *props, const char *name, size_t name_len, ufbx_real def); 5314 ufbx_abi ufbx_real ufbx_find_real(const ufbx_props *props, const char *name, ufbx_real def); 5315 ufbx_abi ufbx_vec3 ufbx_find_vec3_len(const ufbx_props *props, const char *name, size_t name_len, ufbx_vec3 def); 5316 ufbx_abi ufbx_vec3 ufbx_find_vec3(const ufbx_props *props, const char *name, ufbx_vec3 def); 5317 ufbx_abi int64_t ufbx_find_int_len(const ufbx_props *props, const char *name, size_t name_len, int64_t def); 5318 ufbx_abi int64_t ufbx_find_int(const ufbx_props *props, const char *name, int64_t def); 5319 ufbx_abi bool ufbx_find_bool_len(const ufbx_props *props, const char *name, size_t name_len, bool def); 5320 ufbx_abi bool ufbx_find_bool(const ufbx_props *props, const char *name, bool def); 5321 ufbx_abi ufbx_string ufbx_find_string_len(const ufbx_props *props, const char *name, size_t name_len, ufbx_string def); 5322 ufbx_abi ufbx_string ufbx_find_string(const ufbx_props *props, const char *name, ufbx_string def); 5323 ufbx_abi ufbx_blob ufbx_find_blob_len(const ufbx_props *props, const char *name, size_t name_len, ufbx_blob def); 5324 ufbx_abi ufbx_blob ufbx_find_blob(const ufbx_props *props, const char *name, ufbx_blob def); 5325 5326 // Find property in `props` with concatenated `parts[num_parts]`. 5327 ufbx_abi ufbx_prop *ufbx_find_prop_concat(const ufbx_props *props, const ufbx_string *parts, size_t num_parts); 5328 5329 // Get an element connected to a property. 5330 ufbx_abi ufbx_element *ufbx_get_prop_element(const ufbx_element *element, const ufbx_prop *prop, ufbx_element_type type); 5331 5332 // Find an element connected to a property by name. 5333 ufbx_abi ufbx_element *ufbx_find_prop_element_len(const ufbx_element *element, const char *name, size_t name_len, ufbx_element_type type); 5334 ufbx_abi ufbx_element *ufbx_find_prop_element(const ufbx_element *element, const char *name, ufbx_element_type type); 5335 5336 // Find any element of type `type` in `scene` by `name`. 5337 // For example if you want to find `ufbx_material` named `Mat`: 5338 // (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Mat"); 5339 ufbx_abi ufbx_element *ufbx_find_element_len(const ufbx_scene *scene, ufbx_element_type type, const char *name, size_t name_len); 5340 ufbx_abi ufbx_element *ufbx_find_element(const ufbx_scene *scene, ufbx_element_type type, const char *name); 5341 5342 // Find node in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_NODE)`). 5343 ufbx_abi ufbx_node *ufbx_find_node_len(const ufbx_scene *scene, const char *name, size_t name_len); 5344 ufbx_abi ufbx_node *ufbx_find_node(const ufbx_scene *scene, const char *name); 5345 5346 // Find an animation stack in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_ANIM_STACK)`) 5347 ufbx_abi ufbx_anim_stack *ufbx_find_anim_stack_len(const ufbx_scene *scene, const char *name, size_t name_len); 5348 ufbx_abi ufbx_anim_stack *ufbx_find_anim_stack(const ufbx_scene *scene, const char *name); 5349 5350 // Find a material in `scene` by `name` (shorthand for `ufbx_find_element(UFBX_ELEMENT_MATERIAL)`). 5351 ufbx_abi ufbx_material *ufbx_find_material_len(const ufbx_scene *scene, const char *name, size_t name_len); 5352 ufbx_abi ufbx_material *ufbx_find_material(const ufbx_scene *scene, const char *name); 5353 5354 // Find a single animated property `prop` of `element` in `layer`. 5355 // Returns `NULL` if not found. 5356 ufbx_abi ufbx_anim_prop *ufbx_find_anim_prop_len(const ufbx_anim_layer *layer, const ufbx_element *element, const char *prop, size_t prop_len); 5357 ufbx_abi ufbx_anim_prop *ufbx_find_anim_prop(const ufbx_anim_layer *layer, const ufbx_element *element, const char *prop); 5358 5359 // Find all animated properties of `element` in `layer`. 5360 ufbx_abi ufbx_anim_prop_list ufbx_find_anim_props(const ufbx_anim_layer *layer, const ufbx_element *element); 5361 5362 // Get a matrix that transforms normals in the same way as Autodesk software. 5363 // NOTE: The resulting normals are slightly incorrect as this function deliberately 5364 // inverts geometric transformation wrong. For better results use 5365 // `ufbx_matrix_for_normals(&node->geometry_to_world)`. 5366 ufbx_abi ufbx_matrix ufbx_get_compatible_matrix_for_normals(const ufbx_node *node); 5367 5368 // Utility 5369 5370 // Decompress a DEFLATE compressed buffer. 5371 // Returns the decompressed size or a negative error code (see source for details). 5372 // NOTE: You must supply a valid `retain` with `ufbx_inflate_retain.initialized == false` 5373 // but the rest can be uninitialized. 5374 ufbx_abi ptrdiff_t ufbx_inflate(void *dst, size_t dst_size, const ufbx_inflate_input *input, ufbx_inflate_retain *retain); 5375 5376 // Same as `ufbx_open_file()` but compatible with the callback in `ufbx_open_file_fn`. 5377 // The `user` parameter is actually not used here. 5378 ufbx_abi bool ufbx_default_open_file(void *user, ufbx_stream *stream, const char *path, size_t path_len, const ufbx_open_file_info *info); 5379 5380 // Open a `ufbx_stream` from a file. 5381 // Use `path_len == SIZE_MAX` for NULL terminated string. 5382 ufbx_abi bool ufbx_open_file(ufbx_stream *stream, const char *path, size_t path_len, const ufbx_open_file_opts *opts, ufbx_error *error); 5383 ufbx_unsafe ufbx_abi bool ufbx_open_file_ctx(ufbx_stream *stream, ufbx_open_file_context ctx, const char *path, size_t path_len, const ufbx_open_file_opts *opts, ufbx_error *error); 5384 5385 // NOTE: Uses the default ufbx allocator! 5386 ufbx_abi bool ufbx_open_memory(ufbx_stream *stream, const void *data, size_t data_size, const ufbx_open_memory_opts *opts, ufbx_error *error); 5387 ufbx_unsafe ufbx_abi bool ufbx_open_memory_ctx(ufbx_stream *stream, ufbx_open_file_context ctx, const void *data, size_t data_size, const ufbx_open_memory_opts *opts, ufbx_error *error); 5388 5389 // Animation evaluation 5390 5391 // Evaluate a single animation `curve` at a `time`. 5392 // Returns `default_value` only if `curve == NULL` or it has no keyframes. 5393 ufbx_abi ufbx_real ufbx_evaluate_curve(const ufbx_anim_curve *curve, double time, ufbx_real default_value); 5394 ufbx_abi ufbx_real ufbx_evaluate_curve_flags(const ufbx_anim_curve *curve, double time, ufbx_real default_value, uint32_t flags); 5395 5396 // Evaluate a value from bundled animation curves. 5397 ufbx_abi ufbx_real ufbx_evaluate_anim_value_real(const ufbx_anim_value *anim_value, double time); 5398 ufbx_abi ufbx_vec3 ufbx_evaluate_anim_value_vec3(const ufbx_anim_value *anim_value, double time); 5399 ufbx_abi ufbx_real ufbx_evaluate_anim_value_real_flags(const ufbx_anim_value *anim_value, double time, uint32_t flags); 5400 ufbx_abi ufbx_vec3 ufbx_evaluate_anim_value_vec3_flags(const ufbx_anim_value *anim_value, double time, uint32_t flags); 5401 5402 // Evaluate an animated property `name` from `element` at `time`. 5403 // NOTE: If the property is not found it will have the flag `UFBX_PROP_FLAG_NOT_FOUND`. 5404 ufbx_abi ufbx_prop ufbx_evaluate_prop_len(const ufbx_anim *anim, const ufbx_element *element, const char *name, size_t name_len, double time); 5405 ufbx_abi ufbx_prop ufbx_evaluate_prop(const ufbx_anim *anim, const ufbx_element *element, const char *name, double time); 5406 ufbx_abi ufbx_prop ufbx_evaluate_prop_len_flags(const ufbx_anim *anim, const ufbx_element *element, const char *name, size_t name_len, double time, uint32_t flags); 5407 ufbx_abi ufbx_prop ufbx_evaluate_prop_flags(const ufbx_anim *anim, const ufbx_element *element, const char *name, double time, uint32_t flags); 5408 5409 // Evaluate all _animated_ properties of `element`. 5410 // HINT: This function returns an `ufbx_props` structure with the original properties as 5411 // `ufbx_props.defaults`. This lets you use `ufbx_find_prop/value()` for the results. 5412 ufbx_abi ufbx_props ufbx_evaluate_props(const ufbx_anim *anim, const ufbx_element *element, double time, ufbx_prop *buffer, size_t buffer_size); 5413 ufbx_abi ufbx_props ufbx_evaluate_props_flags(const ufbx_anim *anim, const ufbx_element *element, double time, ufbx_prop *buffer, size_t buffer_size, uint32_t flags); 5414 5415 // Flags to control `ufbx_evaluate_transform_flags()`. 5416 typedef enum ufbx_transform_flags UFBX_FLAG_REPR { 5417 5418 // Ignore parent scale helper. 5419 UFBX_TRANSFORM_FLAG_IGNORE_SCALE_HELPER = 0x1, 5420 5421 // Ignore componentwise scale. 5422 // Note that if you don't specify this, ufbx will have to potentially 5423 // evaluate the entire parent chain in the worst case. 5424 UFBX_TRANSFORM_FLAG_IGNORE_COMPONENTWISE_SCALE = 0x2, 5425 5426 // Require explicit components 5427 UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES = 0x4, 5428 5429 // If `UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES`: Evaluate `ufbx_transform.translation`. 5430 UFBX_TRANSFORM_FLAG_INCLUDE_TRANSLATION = 0x10, 5431 // If `UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES`: Evaluate `ufbx_transform.rotation`. 5432 UFBX_TRANSFORM_FLAG_INCLUDE_ROTATION = 0x20, 5433 // If `UFBX_TRANSFORM_FLAG_EXPLICIT_INCLUDES`: Evaluate `ufbx_transform.scale`. 5434 UFBX_TRANSFORM_FLAG_INCLUDE_SCALE = 0x40, 5435 5436 // Do not extrapolate keyframes. 5437 // See `UFBX_EVALUATE_FLAG_NO_EXTRAPOLATION`. 5438 UFBX_TRANSFORM_FLAG_NO_EXTRAPOLATION = 0x80, 5439 5440 UFBX_FLAG_FORCE_WIDTH(UFBX_TRANSFORM_FLAGS) 5441 } ufbx_transform_flags; 5442 5443 // Evaluate the animated transform of a node given a time. 5444 // The returned transform is the local transform of the node (ie. relative to the parent), 5445 // comparable to `ufbx_node.local_transform`. 5446 ufbx_abi ufbx_transform ufbx_evaluate_transform(const ufbx_anim *anim, const ufbx_node *node, double time); 5447 ufbx_abi ufbx_transform ufbx_evaluate_transform_flags(const ufbx_anim *anim, const ufbx_node *node, double time, uint32_t flags); 5448 5449 // Evaluate the blend shape weight of a blend channel. 5450 // NOTE: Return value uses `1.0` for full weight, instead of `100.0` that the internal property `UFBX_Weight` uses. 5451 ufbx_abi ufbx_real ufbx_evaluate_blend_weight(const ufbx_anim *anim, const ufbx_blend_channel *channel, double time); 5452 ufbx_abi ufbx_real ufbx_evaluate_blend_weight_flags(const ufbx_anim *anim, const ufbx_blend_channel *channel, double time, uint32_t flags); 5453 5454 // Evaluate the whole `scene` at a specific `time` in the animation `anim`. 5455 // The returned scene behaves as if it had been exported at a specific time 5456 // in the specified animation, except that animated elements' properties contain 5457 // only the animated values, the original ones are in `props->defaults`. 5458 // 5459 // NOTE: The returned scene refers to the original `scene` so the original 5460 // scene cannot be freed until all evaluated scenes are freed. 5461 ufbx_abi ufbx_scene *ufbx_evaluate_scene(const ufbx_scene *scene, const ufbx_anim *anim, double time, const ufbx_evaluate_opts *opts, ufbx_error *error); 5462 5463 // Create a custom animation descriptor. 5464 // `ufbx_anim_opts` is used to specify animation layers and weights. 5465 // HINT: You can also leave `ufbx_anim_opts.layer_ids[]` empty and only specify 5466 // overrides to evaluate the scene with different properties or local transforms. 5467 ufbx_abi ufbx_anim *ufbx_create_anim(const ufbx_scene *scene, const ufbx_anim_opts *opts, ufbx_error *error); 5468 5469 // Free an animation returned by `ufbx_create_anim()`. 5470 ufbx_abi void ufbx_free_anim(ufbx_anim *anim); 5471 5472 // Increase the animation reference count. 5473 ufbx_abi void ufbx_retain_anim(ufbx_anim *anim); 5474 5475 // Animation baking 5476 5477 // "Bake" an animation to linearly interpolated keyframes. 5478 // Composites the FBX transformation chain into quaternion rotations. 5479 ufbx_abi ufbx_baked_anim *ufbx_bake_anim(const ufbx_scene *scene, const ufbx_anim *anim, const ufbx_bake_opts *opts, ufbx_error *error); 5480 5481 ufbx_abi void ufbx_retain_baked_anim(ufbx_baked_anim *bake); 5482 ufbx_abi void ufbx_free_baked_anim(ufbx_baked_anim *bake); 5483 5484 ufbx_abi ufbx_baked_node *ufbx_find_baked_node_by_typed_id(ufbx_baked_anim *bake, uint32_t typed_id); 5485 ufbx_abi ufbx_baked_node *ufbx_find_baked_node(ufbx_baked_anim *bake, ufbx_node *node); 5486 5487 ufbx_abi ufbx_baked_element *ufbx_find_baked_element_by_element_id(ufbx_baked_anim *bake, uint32_t element_id); 5488 ufbx_abi ufbx_baked_element *ufbx_find_baked_element(ufbx_baked_anim *bake, ufbx_element *element); 5489 5490 // Evaluate baked animation `keyframes` at `time`. 5491 // Internally linearly interpolates between two adjacent keyframes. 5492 // Handles stepped tangents cleanly, which is not strictly necessary for custom interpolation. 5493 ufbx_abi ufbx_vec3 ufbx_evaluate_baked_vec3(ufbx_baked_vec3_list keyframes, double time); 5494 5495 // Evaluate baked animation `keyframes` at `time`. 5496 // Internally spherically interpolates (`ufbx_quat_slerp()`) between two adjacent keyframes. 5497 // Handles stepped tangents cleanly, which is not strictly necessary for custom interpolation. 5498 ufbx_abi ufbx_quat ufbx_evaluate_baked_quat(ufbx_baked_quat_list keyframes, double time); 5499 5500 // Poses 5501 5502 // Retrieve the bone pose for `node`. 5503 // Returns `NULL` if the pose does not contain `node`. 5504 ufbx_abi ufbx_bone_pose *ufbx_get_bone_pose(const ufbx_pose *pose, const ufbx_node *node); 5505 5506 // Materials 5507 5508 // Find a texture for a given material FBX property. 5509 ufbx_abi ufbx_texture *ufbx_find_prop_texture_len(const ufbx_material *material, const char *name, size_t name_len); 5510 ufbx_abi ufbx_texture *ufbx_find_prop_texture(const ufbx_material *material, const char *name); 5511 5512 // Find a texture for a given shader property. 5513 ufbx_abi ufbx_string ufbx_find_shader_prop_len(const ufbx_shader *shader, const char *name, size_t name_len); 5514 ufbx_abi ufbx_string ufbx_find_shader_prop(const ufbx_shader *shader, const char *name); 5515 5516 // Map from a shader property to material property. 5517 ufbx_abi ufbx_shader_prop_binding_list ufbx_find_shader_prop_bindings_len(const ufbx_shader *shader, const char *name, size_t name_len); 5518 ufbx_abi ufbx_shader_prop_binding_list ufbx_find_shader_prop_bindings(const ufbx_shader *shader, const char *name); 5519 5520 // Find an input in a shader texture. 5521 ufbx_abi ufbx_shader_texture_input *ufbx_find_shader_texture_input_len(const ufbx_shader_texture *shader, const char *name, size_t name_len); 5522 ufbx_abi ufbx_shader_texture_input *ufbx_find_shader_texture_input(const ufbx_shader_texture *shader, const char *name); 5523 5524 // Math 5525 5526 // Returns `true` if `axes` forms a valid coordinate space. 5527 ufbx_abi bool ufbx_coordinate_axes_valid(ufbx_coordinate_axes axes); 5528 5529 // Vector math utility functions. 5530 ufbx_abi ufbx_vec3 ufbx_vec3_normalize(ufbx_vec3 v); 5531 5532 // Quaternion math utility functions. 5533 ufbx_abi ufbx_real ufbx_quat_dot(ufbx_quat a, ufbx_quat b); 5534 ufbx_abi ufbx_quat ufbx_quat_mul(ufbx_quat a, ufbx_quat b); 5535 ufbx_abi ufbx_quat ufbx_quat_normalize(ufbx_quat q); 5536 ufbx_abi ufbx_quat ufbx_quat_fix_antipodal(ufbx_quat q, ufbx_quat reference); 5537 ufbx_abi ufbx_quat ufbx_quat_slerp(ufbx_quat a, ufbx_quat b, ufbx_real t); 5538 ufbx_abi ufbx_vec3 ufbx_quat_rotate_vec3(ufbx_quat q, ufbx_vec3 v); 5539 ufbx_abi ufbx_vec3 ufbx_quat_to_euler(ufbx_quat q, ufbx_rotation_order order); 5540 ufbx_abi ufbx_quat ufbx_euler_to_quat(ufbx_vec3 v, ufbx_rotation_order order); 5541 5542 // Matrix math utility functions. 5543 ufbx_abi ufbx_matrix ufbx_matrix_mul(const ufbx_matrix *a, const ufbx_matrix *b); 5544 ufbx_abi ufbx_real ufbx_matrix_determinant(const ufbx_matrix *m); 5545 ufbx_abi ufbx_matrix ufbx_matrix_invert(const ufbx_matrix *m); 5546 5547 // Get a matrix that can be used to transform geometry normals. 5548 // NOTE: You must normalize the normals after transforming them with this matrix, 5549 // eg. using `ufbx_vec3_normalize()`. 5550 // NOTE: This function flips the normals if the determinant is negative. 5551 ufbx_abi ufbx_matrix ufbx_matrix_for_normals(const ufbx_matrix *m); 5552 5553 // Matrix transformation utilities. 5554 ufbx_abi ufbx_vec3 ufbx_transform_position(const ufbx_matrix *m, ufbx_vec3 v); 5555 ufbx_abi ufbx_vec3 ufbx_transform_direction(const ufbx_matrix *m, ufbx_vec3 v); 5556 5557 // Conversions between `ufbx_matrix` and `ufbx_transform`. 5558 ufbx_abi ufbx_matrix ufbx_transform_to_matrix(const ufbx_transform *t); 5559 ufbx_abi ufbx_transform ufbx_matrix_to_transform(const ufbx_matrix *m); 5560 5561 // Skinning 5562 5563 // Get a matrix representing the deformation for a single vertex. 5564 // Returns `fallback` if the vertex is not skinned. 5565 ufbx_abi ufbx_matrix ufbx_catch_get_skin_vertex_matrix(ufbx_panic *panic, const ufbx_skin_deformer *skin, size_t vertex, const ufbx_matrix *fallback); 5566 ufbx_inline ufbx_matrix ufbx_get_skin_vertex_matrix(const ufbx_skin_deformer *skin, size_t vertex, const ufbx_matrix *fallback) { 5567 return ufbx_catch_get_skin_vertex_matrix(NULL, skin, vertex, fallback); 5568 } 5569 5570 // Resolve the index into `ufbx_blend_shape.position_offsets[]` given a vertex. 5571 // Returns `UFBX_NO_INDEX` if the vertex is not included in the blend shape. 5572 ufbx_abi uint32_t ufbx_get_blend_shape_offset_index(const ufbx_blend_shape *shape, size_t vertex); 5573 5574 // Get the offset for a given vertex in the blend shape. 5575 // Returns `ufbx_zero_vec3` if the vertex is not a included in the blend shape. 5576 ufbx_abi ufbx_vec3 ufbx_get_blend_shape_vertex_offset(const ufbx_blend_shape *shape, size_t vertex); 5577 5578 // Get the _current_ blend offset given a blend deformer. 5579 // NOTE: This depends on the current animated blend weight of the deformer. 5580 ufbx_abi ufbx_vec3 ufbx_get_blend_vertex_offset(const ufbx_blend_deformer *blend, size_t vertex); 5581 5582 // Apply the blend shape with `weight` to given vertices. 5583 ufbx_abi void ufbx_add_blend_shape_vertex_offsets(const ufbx_blend_shape *shape, ufbx_vec3 *vertices, size_t num_vertices, ufbx_real weight); 5584 5585 // Apply the blend deformer with `weight` to given vertices. 5586 // NOTE: This depends on the current animated blend weight of the deformer. 5587 ufbx_abi void ufbx_add_blend_vertex_offsets(const ufbx_blend_deformer *blend, ufbx_vec3 *vertices, size_t num_vertices, ufbx_real weight); 5588 5589 // Curves/surfaces 5590 5591 // Low-level utility to evaluate NURBS the basis functions. 5592 ufbx_abi size_t ufbx_evaluate_nurbs_basis(const ufbx_nurbs_basis *basis, ufbx_real u, ufbx_real *weights, size_t num_weights, ufbx_real *derivatives, size_t num_derivatives); 5593 5594 // Evaluate a point on a NURBS curve given the parameter `u`. 5595 ufbx_abi ufbx_curve_point ufbx_evaluate_nurbs_curve(const ufbx_nurbs_curve *curve, ufbx_real u); 5596 5597 // Evaluate a point on a NURBS surface given the parameter `u` and `v`. 5598 ufbx_abi ufbx_surface_point ufbx_evaluate_nurbs_surface(const ufbx_nurbs_surface *surface, ufbx_real u, ufbx_real v); 5599 5600 // Tessellate a NURBS curve into a polyline. 5601 ufbx_abi ufbx_line_curve *ufbx_tessellate_nurbs_curve(const ufbx_nurbs_curve *curve, const ufbx_tessellate_curve_opts *opts, ufbx_error *error); 5602 5603 // Tessellate a NURBS surface into a mesh. 5604 ufbx_abi ufbx_mesh *ufbx_tessellate_nurbs_surface(const ufbx_nurbs_surface *surface, const ufbx_tessellate_surface_opts *opts, ufbx_error *error); 5605 5606 // Free a line returned by `ufbx_tessellate_nurbs_curve()`. 5607 ufbx_abi void ufbx_free_line_curve(ufbx_line_curve *curve); 5608 5609 // Increase the refcount of the line. 5610 ufbx_abi void ufbx_retain_line_curve(ufbx_line_curve *curve); 5611 5612 // Mesh Topology 5613 5614 // Find the face that contains a given `index`. 5615 // Returns `UFBX_NO_INDEX` if out of bounds. 5616 ufbx_abi uint32_t ufbx_find_face_index(ufbx_mesh *mesh, size_t index); 5617 5618 // Triangulate a mesh face, returning the number of triangles. 5619 // NOTE: You need to space for `(face.num_indices - 2) * 3 - 1` indices! 5620 // HINT: Using `ufbx_mesh.max_face_triangles * 3` is always safe. 5621 ufbx_abi uint32_t ufbx_catch_triangulate_face(ufbx_panic *panic, uint32_t *indices, size_t num_indices, const ufbx_mesh *mesh, ufbx_face face); 5622 ufbx_abi uint32_t ufbx_triangulate_face(uint32_t *indices, size_t num_indices, const ufbx_mesh *mesh, ufbx_face face); 5623 5624 // Generate the half-edge representation of `mesh` to `topo[mesh->num_indices]` 5625 ufbx_abi void ufbx_catch_compute_topology(ufbx_panic *panic, const ufbx_mesh *mesh, ufbx_topo_edge *topo, size_t num_topo); 5626 ufbx_abi void ufbx_compute_topology(const ufbx_mesh *mesh, ufbx_topo_edge *topo, size_t num_topo); 5627 5628 // Get the next/previous edge around a vertex 5629 // NOTE: Does not return the half-edge on the opposite side (ie. `topo[index].twin`) 5630 5631 // Get the next half-edge in `topo`. 5632 ufbx_abi uint32_t ufbx_catch_topo_next_vertex_edge(ufbx_panic *panic, const ufbx_topo_edge *topo, size_t num_topo, uint32_t index); 5633 ufbx_abi uint32_t ufbx_topo_next_vertex_edge(const ufbx_topo_edge *topo, size_t num_topo, uint32_t index); 5634 5635 // Get the previous half-edge in `topo`. 5636 ufbx_abi uint32_t ufbx_catch_topo_prev_vertex_edge(ufbx_panic *panic, const ufbx_topo_edge *topo, size_t num_topo, uint32_t index); 5637 ufbx_abi uint32_t ufbx_topo_prev_vertex_edge(const ufbx_topo_edge *topo, size_t num_topo, uint32_t index); 5638 5639 // Calculate a normal for a given face. 5640 // The returned normal is weighted by face area. 5641 ufbx_abi ufbx_vec3 ufbx_catch_get_weighted_face_normal(ufbx_panic *panic, const ufbx_vertex_vec3 *positions, ufbx_face face); 5642 ufbx_abi ufbx_vec3 ufbx_get_weighted_face_normal(const ufbx_vertex_vec3 *positions, ufbx_face face); 5643 5644 // Generate indices for normals from the topology. 5645 // Respects smoothing groups. 5646 ufbx_abi size_t ufbx_catch_generate_normal_mapping(ufbx_panic *panic, const ufbx_mesh *mesh, 5647 const ufbx_topo_edge *topo, size_t num_topo, 5648 uint32_t *normal_indices, size_t num_normal_indices, bool assume_smooth); 5649 ufbx_abi size_t ufbx_generate_normal_mapping(const ufbx_mesh *mesh, 5650 const ufbx_topo_edge *topo, size_t num_topo, 5651 uint32_t *normal_indices, size_t num_normal_indices, bool assume_smooth); 5652 5653 // Compute normals given normal indices. 5654 // You can use `ufbx_generate_normal_mapping()` to generate the normal indices. 5655 ufbx_abi void ufbx_catch_compute_normals(ufbx_panic *panic, const ufbx_mesh *mesh, const ufbx_vertex_vec3 *positions, 5656 const uint32_t *normal_indices, size_t num_normal_indices, 5657 ufbx_vec3 *normals, size_t num_normals); 5658 ufbx_abi void ufbx_compute_normals(const ufbx_mesh *mesh, const ufbx_vertex_vec3 *positions, 5659 const uint32_t *normal_indices, size_t num_normal_indices, 5660 ufbx_vec3 *normals, size_t num_normals); 5661 5662 // Subdivide a mesh using the Catmull-Clark subdivision `level` times. 5663 ufbx_abi ufbx_mesh *ufbx_subdivide_mesh(const ufbx_mesh *mesh, size_t level, const ufbx_subdivide_opts *opts, ufbx_error *error); 5664 5665 // Free a mesh returned from `ufbx_subdivide_mesh()` or `ufbx_tessellate_nurbs_surface()`. 5666 ufbx_abi void ufbx_free_mesh(ufbx_mesh *mesh); 5667 5668 // Increase the mesh reference count. 5669 ufbx_abi void ufbx_retain_mesh(ufbx_mesh *mesh); 5670 5671 // Geometry caches 5672 5673 // Load geometry cache information from a file. 5674 // As geometry caches can be massive, this does not actually read the data, but 5675 // only seeks through the files to form the metadata. 5676 ufbx_abi ufbx_geometry_cache *ufbx_load_geometry_cache( 5677 const char *filename, 5678 const ufbx_geometry_cache_opts *opts, ufbx_error *error); 5679 ufbx_abi ufbx_geometry_cache *ufbx_load_geometry_cache_len( 5680 const char *filename, size_t filename_len, 5681 const ufbx_geometry_cache_opts *opts, ufbx_error *error); 5682 5683 // Free a geometry cache returned from `ufbx_load_geometry_cache()`. 5684 ufbx_abi void ufbx_free_geometry_cache(ufbx_geometry_cache *cache); 5685 // Increase the geometry cache reference count. 5686 ufbx_abi void ufbx_retain_geometry_cache(ufbx_geometry_cache *cache); 5687 5688 // Read a frame from a geometry cache. 5689 ufbx_abi size_t ufbx_read_geometry_cache_real(const ufbx_cache_frame *frame, ufbx_real *data, size_t num_data, const ufbx_geometry_cache_data_opts *opts); 5690 ufbx_abi size_t ufbx_read_geometry_cache_vec3(const ufbx_cache_frame *frame, ufbx_vec3 *data, size_t num_data, const ufbx_geometry_cache_data_opts *opts); 5691 // Sample the a geometry cache channel, linearly blending between adjacent frames. 5692 ufbx_abi size_t ufbx_sample_geometry_cache_real(const ufbx_cache_channel *channel, double time, ufbx_real *data, size_t num_data, const ufbx_geometry_cache_data_opts *opts); 5693 ufbx_abi size_t ufbx_sample_geometry_cache_vec3(const ufbx_cache_channel *channel, double time, ufbx_vec3 *data, size_t num_data, const ufbx_geometry_cache_data_opts *opts); 5694 5695 // DOM 5696 5697 // Find a DOM node given a name. 5698 ufbx_abi ufbx_dom_node *ufbx_dom_find_len(const ufbx_dom_node *parent, const char *name, size_t name_len); 5699 ufbx_abi ufbx_dom_node *ufbx_dom_find(const ufbx_dom_node *parent, const char *name); 5700 5701 // Utility 5702 5703 // Generate an index buffer for a flat vertex buffer. 5704 // `streams` specifies one or more vertex data arrays, each stream must contain `num_indices` vertices. 5705 // This function compacts the data within `streams` in-place, writing the deduplicated indices to `indices`. 5706 ufbx_abi size_t ufbx_generate_indices(const ufbx_vertex_stream *streams, size_t num_streams, uint32_t *indices, size_t num_indices, const ufbx_allocator_opts *allocator, ufbx_error *error); 5707 5708 // Thread pool 5709 5710 // Run a single thread pool task. 5711 // See `ufbx_thread_pool_run_fn` for more information. 5712 ufbx_unsafe ufbx_abi void ufbx_thread_pool_run_task(ufbx_thread_pool_context ctx, uint32_t index); 5713 5714 // Get or set an arbitrary user pointer for the thread pool context. 5715 // `ufbx_thread_pool_get_user_ptr()` returns `NULL` if unset. 5716 ufbx_unsafe ufbx_abi void ufbx_thread_pool_set_user_ptr(ufbx_thread_pool_context ctx, void *user_ptr); 5717 ufbx_unsafe ufbx_abi void *ufbx_thread_pool_get_user_ptr(ufbx_thread_pool_context ctx); 5718 5719 // -- Inline API 5720 5721 // Utility functions for reading geometry data for a single index. 5722 ufbx_abi ufbx_real ufbx_catch_get_vertex_real(ufbx_panic *panic, const ufbx_vertex_real *v, size_t index); 5723 ufbx_abi ufbx_vec2 ufbx_catch_get_vertex_vec2(ufbx_panic *panic, const ufbx_vertex_vec2 *v, size_t index); 5724 ufbx_abi ufbx_vec3 ufbx_catch_get_vertex_vec3(ufbx_panic *panic, const ufbx_vertex_vec3 *v, size_t index); 5725 ufbx_abi ufbx_vec4 ufbx_catch_get_vertex_vec4(ufbx_panic *panic, const ufbx_vertex_vec4 *v, size_t index); 5726 5727 // Utility functions for reading geometry data for a single index. 5728 ufbx_inline ufbx_real ufbx_get_vertex_real(const ufbx_vertex_real *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values.data[(int32_t)v->indices.data[index]]; } 5729 ufbx_inline ufbx_vec2 ufbx_get_vertex_vec2(const ufbx_vertex_vec2 *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values.data[(int32_t)v->indices.data[index]]; } 5730 ufbx_inline ufbx_vec3 ufbx_get_vertex_vec3(const ufbx_vertex_vec3 *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values.data[(int32_t)v->indices.data[index]]; } 5731 ufbx_inline ufbx_vec4 ufbx_get_vertex_vec4(const ufbx_vertex_vec4 *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values.data[(int32_t)v->indices.data[index]]; } 5732 5733 ufbx_abi ufbx_real ufbx_catch_get_vertex_w_vec3(ufbx_panic *panic, const ufbx_vertex_vec3 *v, size_t index); 5734 ufbx_inline ufbx_real ufbx_get_vertex_w_vec3(const ufbx_vertex_vec3 *v, size_t index) { ufbx_assert(index < v->indices.count); return v->values_w.count > 0 ? v->values_w.data[(int32_t)v->indices.data[index]] : 0.0f; } 5735 5736 // Functions for converting an untyped `ufbx_element` to a concrete type. 5737 // Returns `NULL` if the element is not that type. 5738 ufbx_abi ufbx_unknown *ufbx_as_unknown(const ufbx_element *element); 5739 ufbx_abi ufbx_node *ufbx_as_node(const ufbx_element *element); 5740 ufbx_abi ufbx_mesh *ufbx_as_mesh(const ufbx_element *element); 5741 ufbx_abi ufbx_light *ufbx_as_light(const ufbx_element *element); 5742 ufbx_abi ufbx_camera *ufbx_as_camera(const ufbx_element *element); 5743 ufbx_abi ufbx_bone *ufbx_as_bone(const ufbx_element *element); 5744 ufbx_abi ufbx_empty *ufbx_as_empty(const ufbx_element *element); 5745 ufbx_abi ufbx_line_curve *ufbx_as_line_curve(const ufbx_element *element); 5746 ufbx_abi ufbx_nurbs_curve *ufbx_as_nurbs_curve(const ufbx_element *element); 5747 ufbx_abi ufbx_nurbs_surface *ufbx_as_nurbs_surface(const ufbx_element *element); 5748 ufbx_abi ufbx_nurbs_trim_surface *ufbx_as_nurbs_trim_surface(const ufbx_element *element); 5749 ufbx_abi ufbx_nurbs_trim_boundary *ufbx_as_nurbs_trim_boundary(const ufbx_element *element); 5750 ufbx_abi ufbx_procedural_geometry *ufbx_as_procedural_geometry(const ufbx_element *element); 5751 ufbx_abi ufbx_stereo_camera *ufbx_as_stereo_camera(const ufbx_element *element); 5752 ufbx_abi ufbx_camera_switcher *ufbx_as_camera_switcher(const ufbx_element *element); 5753 ufbx_abi ufbx_marker *ufbx_as_marker(const ufbx_element *element); 5754 ufbx_abi ufbx_lod_group *ufbx_as_lod_group(const ufbx_element *element); 5755 ufbx_abi ufbx_skin_deformer *ufbx_as_skin_deformer(const ufbx_element *element); 5756 ufbx_abi ufbx_skin_cluster *ufbx_as_skin_cluster(const ufbx_element *element); 5757 ufbx_abi ufbx_blend_deformer *ufbx_as_blend_deformer(const ufbx_element *element); 5758 ufbx_abi ufbx_blend_channel *ufbx_as_blend_channel(const ufbx_element *element); 5759 ufbx_abi ufbx_blend_shape *ufbx_as_blend_shape(const ufbx_element *element); 5760 ufbx_abi ufbx_cache_deformer *ufbx_as_cache_deformer(const ufbx_element *element); 5761 ufbx_abi ufbx_cache_file *ufbx_as_cache_file(const ufbx_element *element); 5762 ufbx_abi ufbx_material *ufbx_as_material(const ufbx_element *element); 5763 ufbx_abi ufbx_texture *ufbx_as_texture(const ufbx_element *element); 5764 ufbx_abi ufbx_video *ufbx_as_video(const ufbx_element *element); 5765 ufbx_abi ufbx_shader *ufbx_as_shader(const ufbx_element *element); 5766 ufbx_abi ufbx_shader_binding *ufbx_as_shader_binding(const ufbx_element *element); 5767 ufbx_abi ufbx_anim_stack *ufbx_as_anim_stack(const ufbx_element *element); 5768 ufbx_abi ufbx_anim_layer *ufbx_as_anim_layer(const ufbx_element *element); 5769 ufbx_abi ufbx_anim_value *ufbx_as_anim_value(const ufbx_element *element); 5770 ufbx_abi ufbx_anim_curve *ufbx_as_anim_curve(const ufbx_element *element); 5771 ufbx_abi ufbx_display_layer *ufbx_as_display_layer(const ufbx_element *element); 5772 ufbx_abi ufbx_selection_set *ufbx_as_selection_set(const ufbx_element *element); 5773 ufbx_abi ufbx_selection_node *ufbx_as_selection_node(const ufbx_element *element); 5774 ufbx_abi ufbx_character *ufbx_as_character(const ufbx_element *element); 5775 ufbx_abi ufbx_constraint *ufbx_as_constraint(const ufbx_element *element); 5776 ufbx_abi ufbx_audio_layer *ufbx_as_audio_layer(const ufbx_element *element); 5777 ufbx_abi ufbx_audio_clip *ufbx_as_audio_clip(const ufbx_element *element); 5778 ufbx_abi ufbx_pose *ufbx_as_pose(const ufbx_element *element); 5779 ufbx_abi ufbx_metadata_object *ufbx_as_metadata_object(const ufbx_element *element); 5780 5781 #ifdef __cplusplus 5782 } 5783 #endif 5784 5785 // bindgen-disable 5786 5787 #if UFBX_CPP11 5788 5789 struct ufbx_string_view { 5790 const char *data; 5791 size_t length; 5792 5793 ufbx_string_view() : data(nullptr), length(0) { } 5794 ufbx_string_view(const char *data_, size_t length_) : data(data_), length(length_) { } 5795 UFBX_CONVERSION_TO_IMPL(ufbx_string_view) 5796 }; 5797 5798 ufbx_inline ufbx_scene *ufbx_load_file(ufbx_string_view filename, const ufbx_load_opts *opts, ufbx_error *error) { return ufbx_load_file_len(filename.data, filename.length, opts, error); } 5799 ufbx_inline ufbx_prop *ufbx_find_prop(const ufbx_props *props, ufbx_string_view name) { return ufbx_find_prop_len(props, name.data, name.length); } 5800 ufbx_inline ufbx_real ufbx_find_real(const ufbx_props *props, ufbx_string_view name, ufbx_real def) { return ufbx_find_real_len(props, name.data, name.length, def); } 5801 ufbx_inline ufbx_vec3 ufbx_find_vec3(const ufbx_props *props, ufbx_string_view name, ufbx_vec3 def) { return ufbx_find_vec3_len(props, name.data, name.length, def); } 5802 ufbx_inline int64_t ufbx_find_int(const ufbx_props *props, ufbx_string_view name, int64_t def) { return ufbx_find_int_len(props, name.data, name.length, def); } 5803 ufbx_inline bool ufbx_find_bool(const ufbx_props *props, ufbx_string_view name, bool def) { return ufbx_find_bool_len(props, name.data, name.length, def); } 5804 ufbx_inline ufbx_string ufbx_find_string(const ufbx_props *props, ufbx_string_view name, ufbx_string def) { return ufbx_find_string_len(props, name.data, name.length, def); } 5805 ufbx_inline ufbx_blob ufbx_find_blob(const ufbx_props *props, ufbx_string_view name, ufbx_blob def) { return ufbx_find_blob_len(props, name.data, name.length, def); } 5806 ufbx_inline ufbx_element *ufbx_find_prop_element(const ufbx_element *element, ufbx_string_view name, ufbx_element_type type) { return ufbx_find_prop_element_len(element, name.data, name.length, type); } 5807 ufbx_inline ufbx_element *ufbx_find_element(const ufbx_scene *scene, ufbx_element_type type, ufbx_string_view name) { return ufbx_find_element_len(scene, type, name.data, name.length); } 5808 ufbx_inline ufbx_node *ufbx_find_node(const ufbx_scene *scene, ufbx_string_view name) { return ufbx_find_node_len(scene, name.data, name.length); } 5809 ufbx_inline ufbx_anim_stack *ufbx_find_anim_stack(const ufbx_scene *scene, ufbx_string_view name) { return ufbx_find_anim_stack_len(scene, name.data, name.length); } 5810 ufbx_inline ufbx_material *ufbx_find_material(const ufbx_scene *scene, ufbx_string_view name) { return ufbx_find_material_len(scene, name.data, name.length); } 5811 ufbx_inline ufbx_anim_prop *ufbx_find_anim_prop(const ufbx_anim_layer *layer, const ufbx_element *element, ufbx_string_view prop) { return ufbx_find_anim_prop_len(layer, element, prop.data, prop.length); } 5812 ufbx_inline ufbx_prop ufbx_evaluate_prop(const ufbx_anim *anim, const ufbx_element *element, ufbx_string_view name, double time) { return ufbx_evaluate_prop_len(anim, element, name.data, name.length, time); } 5813 ufbx_inline ufbx_texture *ufbx_find_prop_texture(const ufbx_material *material, ufbx_string_view name) { return ufbx_find_prop_texture_len(material, name.data, name.length); } 5814 ufbx_inline ufbx_string ufbx_find_shader_prop(const ufbx_shader *shader, ufbx_string_view name) { return ufbx_find_shader_prop_len(shader, name.data, name.length); } 5815 ufbx_inline ufbx_shader_prop_binding_list ufbx_find_shader_prop_bindings(const ufbx_shader *shader, ufbx_string_view name) { return ufbx_find_shader_prop_bindings_len(shader, name.data, name.length); } 5816 ufbx_inline ufbx_shader_texture_input *ufbx_find_shader_texture_input(const ufbx_shader_texture *shader, ufbx_string_view name) { return ufbx_find_shader_texture_input_len(shader, name.data, name.length); } 5817 ufbx_inline ufbx_geometry_cache *ufbx_load_geometry_cache(ufbx_string_view filename, const ufbx_geometry_cache_opts *opts, ufbx_error *error) { return ufbx_load_geometry_cache_len(filename.data, filename.length, opts, error); } 5818 ufbx_inline ufbx_dom_node *ufbx_dom_find(const ufbx_dom_node *parent, ufbx_string_view name) { return ufbx_dom_find_len(parent, name.data, name.length); } 5819 5820 #endif 5821 5822 #if UFBX_CPP11 5823 5824 template <typename T> 5825 struct ufbx_type_traits { enum { valid = 0 }; }; 5826 5827 template<> struct ufbx_type_traits<ufbx_scene> { 5828 enum { valid = 1 }; 5829 static void retain(ufbx_scene *ptr) { ufbx_retain_scene(ptr); } 5830 static void free(ufbx_scene *ptr) { ufbx_free_scene(ptr); } 5831 }; 5832 5833 template<> struct ufbx_type_traits<ufbx_mesh> { 5834 enum { valid = 1 }; 5835 static void retain(ufbx_mesh *ptr) { ufbx_retain_mesh(ptr); } 5836 static void free(ufbx_mesh *ptr) { ufbx_free_mesh(ptr); } 5837 }; 5838 5839 template<> struct ufbx_type_traits<ufbx_line_curve> { 5840 enum { valid = 1 }; 5841 static void retain(ufbx_line_curve *ptr) { ufbx_retain_line_curve(ptr); } 5842 static void free(ufbx_line_curve *ptr) { ufbx_free_line_curve(ptr); } 5843 }; 5844 5845 template<> struct ufbx_type_traits<ufbx_geometry_cache> { 5846 enum { valid = 1 }; 5847 static void retain(ufbx_geometry_cache *ptr) { ufbx_retain_geometry_cache(ptr); } 5848 static void free(ufbx_geometry_cache *ptr) { ufbx_free_geometry_cache(ptr); } 5849 }; 5850 5851 template<> struct ufbx_type_traits<ufbx_anim> { 5852 enum { valid = 1 }; 5853 static void retain(ufbx_anim *ptr) { ufbx_retain_anim(ptr); } 5854 static void free(ufbx_anim *ptr) { ufbx_free_anim(ptr); } 5855 }; 5856 5857 template<> struct ufbx_type_traits<ufbx_baked_anim> { 5858 enum { valid = 1 }; 5859 static void retain(ufbx_baked_anim *ptr) { ufbx_retain_baked_anim(ptr); } 5860 static void free(ufbx_baked_anim *ptr) { ufbx_free_baked_anim(ptr); } 5861 }; 5862 5863 class ufbx_deleter { 5864 public: 5865 template <typename T> 5866 void operator()(T *ptr) const { 5867 static_assert(ufbx_type_traits<T>::valid, "ufbx_deleter() unsupported for type"); 5868 ufbx_type_traits<T>::free(ptr); 5869 } 5870 }; 5871 5872 // RAII wrapper over refcounted ufbx types. 5873 5874 // Behaves like `std::unique_ptr<T>`. 5875 template <typename T> 5876 class ufbx_unique_ptr { 5877 T *ptr; 5878 using traits = ufbx_type_traits<T>; 5879 static_assert(ufbx_type_traits<T>::valid, "ufbx_unique_ptr unsupported for type"); 5880 public: 5881 ufbx_unique_ptr() noexcept : ptr(nullptr) { } 5882 explicit ufbx_unique_ptr(T *ptr_) noexcept : ptr(ptr_) { } 5883 ufbx_unique_ptr(ufbx_unique_ptr &&ref) noexcept : ptr(ref.ptr) { ref.ptr = nullptr; } 5884 ~ufbx_unique_ptr() { traits::free(ptr); } 5885 5886 ufbx_unique_ptr &operator=(ufbx_unique_ptr &&ref) noexcept { 5887 if (&ref == this) return *this; 5888 ptr = ref.ptr; 5889 ref.ptr = nullptr; 5890 return *this; 5891 } 5892 5893 void reset(T *new_ptr=nullptr) noexcept { 5894 traits::free(ptr); 5895 ptr = new_ptr; 5896 } 5897 5898 void swap(ufbx_unique_ptr &ref) noexcept { 5899 T *tmp = ptr; 5900 ptr = ref.ptr; 5901 ref.ptr = tmp; 5902 } 5903 5904 T &operator*() const noexcept { return *ptr; } 5905 T *operator->() const noexcept { return ptr; } 5906 T *get() const noexcept { return ptr; } 5907 explicit operator bool() const noexcept { return ptr != nullptr; } 5908 }; 5909 5910 // Behaves like `std::shared_ptr<T>` except uses ufbx's internal reference counting, 5911 // so it is half the size of a standard `shared_ptr` but might be marginally slower. 5912 template <typename T> 5913 class ufbx_shared_ptr { 5914 T *ptr; 5915 using traits = ufbx_type_traits<T>; 5916 static_assert(ufbx_type_traits<T>::valid, "ufbx_shared_ptr unsupported for type"); 5917 public: 5918 5919 ufbx_shared_ptr() noexcept : ptr(nullptr) { } 5920 explicit ufbx_shared_ptr(T *ptr_) noexcept : ptr(ptr_) { } 5921 ufbx_shared_ptr(const ufbx_shared_ptr &ref) noexcept : ptr(ref.ptr) { traits::retain(ref.ptr); } 5922 ufbx_shared_ptr(ufbx_shared_ptr &&ref) noexcept : ptr(ref.ptr) { ref.ptr = nullptr; } 5923 ~ufbx_shared_ptr() { traits::free(ptr); } 5924 5925 ufbx_shared_ptr &operator=(const ufbx_shared_ptr &ref) noexcept { 5926 if (&ref == this) return *this; 5927 traits::free(ptr); 5928 traits::retain(ref.ptr); 5929 ptr = ref.ptr; 5930 return *this; 5931 } 5932 5933 ufbx_shared_ptr &operator=(ufbx_shared_ptr &&ref) noexcept { 5934 if (&ref == this) return *this; 5935 ptr = ref.ptr; 5936 ref.ptr = nullptr; 5937 return *this; 5938 } 5939 5940 void reset(T *new_ptr=nullptr) noexcept { 5941 traits::free(ptr); 5942 ptr = new_ptr; 5943 } 5944 5945 void swap(ufbx_shared_ptr &ref) noexcept { 5946 T *tmp = ptr; 5947 ptr = ref.ptr; 5948 ref.ptr = tmp; 5949 } 5950 5951 T &operator*() const noexcept { return *ptr; } 5952 T *operator->() const noexcept { return ptr; } 5953 T *get() const noexcept { return ptr; } 5954 explicit operator bool() const noexcept { return ptr != nullptr; } 5955 }; 5956 5957 #endif 5958 // bindgen-enable 5959 5960 // -- Properties 5961 5962 // Names of common properties in `ufbx_props`. 5963 // Some of these differ from ufbx interpretations. 5964 5965 // Local translation. 5966 // Used by: `ufbx_node` 5967 #define UFBX_Lcl_Translation "Lcl Translation" 5968 5969 // Local rotation expressed in Euler degrees. 5970 // Used by: `ufbx_node` 5971 // The rotation order is defined by the `UFBX_RotationOrder` property. 5972 #define UFBX_Lcl_Rotation "Lcl Rotation" 5973 5974 // Local scaling factor, 3D vector. 5975 // Used by: `ufbx_node` 5976 #define UFBX_Lcl_Scaling "Lcl Scaling" 5977 5978 // Euler rotation interpretation, used by `UFBX_Lcl_Rotation`. 5979 // Used by: `ufbx_node`, enum value `ufbx_rotation_order`. 5980 #define UFBX_RotationOrder "RotationOrder" 5981 5982 // Scaling pivot: point around which scaling is performed. 5983 // Used by: `ufbx_node`. 5984 #define UFBX_ScalingPivot "ScalingPivot" 5985 5986 // Scaling pivot: point around which rotation is performed. 5987 // Used by: `ufbx_node`. 5988 #define UFBX_RotationPivot "RotationPivot" 5989 5990 // Scaling offset: translation added after scaling is performed. 5991 // Used by: `ufbx_node`. 5992 #define UFBX_ScalingOffset "ScalingOffset" 5993 5994 // Rotation offset: translation added after rotation is performed. 5995 // Used by: `ufbx_node`. 5996 #define UFBX_RotationOffset "RotationOffset" 5997 5998 // Pre-rotation: Rotation applied _after_ `UFBX_Lcl_Rotation`. 5999 // Used by: `ufbx_node`. 6000 // Affected by `UFBX_RotationPivot` but not `UFBX_RotationOrder`. 6001 #define UFBX_PreRotation "PreRotation" 6002 6003 // Post-rotation: Rotation applied _before_ `UFBX_Lcl_Rotation`. 6004 // Used by: `ufbx_node`. 6005 // Affected by `UFBX_RotationPivot` but not `UFBX_RotationOrder`. 6006 #define UFBX_PostRotation "PostRotation" 6007 6008 // Controls whether the node should be displayed or not. 6009 // Used by: `ufbx_node`. 6010 #define UFBX_Visibility "Visibility" 6011 6012 // Weight of an animation layer in percentage (100.0 being full). 6013 // Used by: `ufbx_anim_layer`. 6014 #define UFBX_Weight "Weight" 6015 6016 // Blend shape deformation weight (100.0 being full). 6017 // Used by: `ufbx_blend_channel`. 6018 #define UFBX_DeformPercent "DeformPercent" 6019 6020 #if defined(_MSC_VER) 6021 #pragma warning(pop) 6022 #elif defined(__clang__) 6023 #pragma clang diagnostic pop 6024 #elif defined(__GNUC__) 6025 #pragma GCC diagnostic pop 6026 #endif 6027 6028 #endif