babylonjs-loaders 9.25.0 → 9.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8878,6 +8878,424 @@ declare namespace BABYLON.GLTF1 {
8878
8878
  }
8879
8879
  declare namespace BABYLON {
8880
8880
 
8881
+ export interface WorkerAsset {
8882
+ bytes: Uint8Array;
8883
+ fileName: string;
8884
+ files?: Record<string, Uint8Array>;
8885
+ resolveByFileName: boolean;
8886
+ glueUrl?: string;
8887
+ wasmUrl?: string;
8888
+ dataUrl?: string;
8889
+ }
8890
+ export interface ExtractRequest {
8891
+ type: "extract";
8892
+ requestId: number;
8893
+ asset: WorkerAsset;
8894
+ }
8895
+ export interface WorkerTimings {
8896
+ totalMs: number;
8897
+ stageOpenMs: number;
8898
+ stageReadMs: number;
8899
+ preparationMs: number;
8900
+ packingMs: number;
8901
+ heapCopyMs: number;
8902
+ }
8903
+ export interface WorkerStatistics {
8904
+ nodes: number;
8905
+ meshes: number;
8906
+ analyticPrimitives: number;
8907
+ instances: number;
8908
+ materials: number;
8909
+ vertices: number;
8910
+ triangles: number;
8911
+ commandBytes: number;
8912
+ dataBytes: number;
8913
+ }
8914
+ export type WorkerResponse = {
8915
+ type: "progress";
8916
+ requestId: number;
8917
+ progress: USDLoadProgress;
8918
+ } | {
8919
+ type: "log";
8920
+ requestId: number;
8921
+ level: number;
8922
+ message: string;
8923
+ } | {
8924
+ type: "result";
8925
+ requestId: number;
8926
+ commands: ArrayBuffer;
8927
+ data: ArrayBuffer;
8928
+ timings: WorkerTimings;
8929
+ statistics: WorkerStatistics;
8930
+ missingAssets: string[];
8931
+ } | {
8932
+ type: "error";
8933
+ requestId: number;
8934
+ message: string;
8935
+ stack?: string;
8936
+ };
8937
+
8938
+
8939
+ export interface MaterializationResult {
8940
+ container: AbstractAssetContainer & {
8941
+ dispose(): void;
8942
+ };
8943
+ materializeMs: number;
8944
+ }
8945
+ export function materializeCommandBuffers(scene: Scene, commandBuffer: ArrayBuffer, dataBuffer: ArrayBuffer, addToScene: boolean, signal?: AbortSignal): Promise<MaterializationResult>;
8946
+
8947
+
8948
+ /**
8949
+ * Binary input accepted for supporting USD layers and assets.
8950
+ */
8951
+ export type USDBinaryInput = ArrayBuffer | ArrayBufferView;
8952
+ /**
8953
+ * Virtual files supplied alongside the root USD layer, keyed by their path relative to the
8954
+ * root layer.
8955
+ */
8956
+ export type USDVirtualFiles = Readonly<Record<string, USDBinaryInput>>;
8957
+ /**
8958
+ * Progress phases reported by the USD worker and Babylon materializer.
8959
+ */
8960
+ export interface USDLoadProgress {
8961
+ /**
8962
+ * Current importer phase.
8963
+ */
8964
+ phase: "initializing" | "staging" | "extracting" | "materializing";
8965
+ /**
8966
+ * Human-readable phase description.
8967
+ */
8968
+ message: string;
8969
+ }
8970
+ /**
8971
+ * Options for the OpenUSD scene loader.
8972
+ */
8973
+ export interface USDFileLoaderOptions {
8974
+ /**
8975
+ * Virtual path used to stage the root layer. Set this when supporting files need
8976
+ * to resolve relative to a directory hierarchy.
8977
+ */
8978
+ rootFileName?: string;
8979
+ /**
8980
+ * Supporting layers, payloads, and textures keyed by virtual path in the same
8981
+ * virtual file system as `rootFileName`.
8982
+ */
8983
+ files?: USDVirtualFiles;
8984
+ /**
8985
+ * Enables conservative file-name fallback for unresolved absolute references.
8986
+ * Defaults to true.
8987
+ */
8988
+ resolveByFileName?: boolean;
8989
+ /**
8990
+ * URL of the module worker. Defaults to the protocol-versioned worker hosted on the Babylon.js CDN.
8991
+ */
8992
+ workerUrl?: string | URL;
8993
+ /**
8994
+ * URL of the generated Emscripten JavaScript module.
8995
+ */
8996
+ glueUrl?: string;
8997
+ /**
8998
+ * URL of the OpenUSD WebAssembly binary.
8999
+ */
9000
+ wasmUrl?: string;
9001
+ /**
9002
+ * URL of the OpenUSD preloaded resource bundle.
9003
+ */
9004
+ dataUrl?: string;
9005
+ /**
9006
+ * Called when the importer moves to a new processing phase.
9007
+ */
9008
+ onProgress?: (progress: USDLoadProgress) => void;
9009
+ /**
9010
+ * Called for OpenUSD diagnostic messages.
9011
+ */
9012
+ onLog?: (level: "info" | "warning" | "error", message: string) => void;
9013
+ /**
9014
+ * Called after extraction and Babylon.js object creation complete.
9015
+ */
9016
+ onComplete?: (diagnostics: USDImportDiagnostics) => void;
9017
+ }
9018
+ /**
9019
+ * Timing data measured by the OpenUSD worker and Babylon materializer.
9020
+ */
9021
+ export interface USDImportTimings {
9022
+ /** Total extraction time, including the final Wasm heap copy. */
9023
+ totalMs: number;
9024
+ /** Time spent opening and composing the USD stage. */
9025
+ stageOpenMs: number;
9026
+ /** Time spent traversing the composed stage. */
9027
+ stageReadMs: number;
9028
+ /** Time spent preparing renderable vertex streams. */
9029
+ preparationMs: number;
9030
+ /** Time spent packing the command and raw-data buffers. */
9031
+ packingMs: number;
9032
+ /** Time spent copying command and data buffers from the Wasm heap. */
9033
+ heapCopyMs: number;
9034
+ /** Time spent creating Babylon.js objects. */
9035
+ materializeMs: number;
9036
+ }
9037
+ /**
9038
+ * Statistics reported for an imported USD stage.
9039
+ */
9040
+ export interface USDImportStatistics {
9041
+ /** Number of transform nodes extracted from the composed stage. */
9042
+ nodes: number;
9043
+ /** Number of polygonal `UsdGeomMesh` sources. */
9044
+ meshes: number;
9045
+ /** Number of analytic cube, sphere, cylinder, and cone sources. */
9046
+ analyticPrimitives: number;
9047
+ /** Number of native Babylon instances created from shared USD geometry. */
9048
+ instances: number;
9049
+ /** Number of authored USD materials translated. */
9050
+ materials: number;
9051
+ /** Number of unique vertices in polygonal source meshes. */
9052
+ vertices: number;
9053
+ /** Number of unique triangles in polygonal source meshes. */
9054
+ triangles: number;
9055
+ /** Size of the command buffer in bytes. */
9056
+ commandBytes: number;
9057
+ /** Size of the raw-data buffer in bytes. */
9058
+ dataBytes: number;
9059
+ }
9060
+ /**
9061
+ * Diagnostics reported after a USD import completes.
9062
+ */
9063
+ export interface USDImportDiagnostics {
9064
+ /** Timing data for extraction and Babylon.js object creation. */
9065
+ timings: USDImportTimings;
9066
+ /** Counts and buffer sizes reported by the OpenUSD extractor. */
9067
+ statistics: USDImportStatistics;
9068
+ /** Asset references OpenUSD could not resolve from the supplied virtual files. */
9069
+ missingAssets: readonly string[];
9070
+ }
9071
+
9072
+
9073
+ interface SceneLoaderPluginOptions {
9074
+ /**
9075
+ * Defines options for the USD loader.
9076
+ */
9077
+ [USDFileLoaderMetadata.name]: Partial<USDFileLoaderOptions>;
9078
+ }
9079
+
9080
+
9081
+ /** This file must only contain pure code and pure imports */
9082
+ /**
9083
+ * OpenUSD scene loader backed by a WebAssembly command-buffer extractor.
9084
+ */
9085
+ export class USDFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
9086
+ /**
9087
+ * Default URLs for the prebuilt OpenUSD importer assets.
9088
+ */
9089
+ static DefaultConfiguration: {
9090
+ glueUrl: string;
9091
+ wasmUrl: string;
9092
+ dataUrl: string;
9093
+ workerUrl: string;
9094
+ };
9095
+ /**
9096
+ * Defines the name of the plugin.
9097
+ */
9098
+ readonly name: "usd";
9099
+ /**
9100
+ * Defines the extensions the plugin can load.
9101
+ */
9102
+ readonly extensions: {
9103
+ readonly ".usd": {
9104
+ readonly isBinary: true;
9105
+ };
9106
+ readonly ".usda": {
9107
+ readonly isBinary: true;
9108
+ };
9109
+ readonly ".usdc": {
9110
+ readonly isBinary: true;
9111
+ };
9112
+ readonly ".usdz": {
9113
+ readonly isBinary: true;
9114
+ };
9115
+ };
9116
+ private readonly _options;
9117
+ private _worker;
9118
+ private _workerUrl;
9119
+ private _workerBlobUrl;
9120
+ private _nextRequestId;
9121
+ private readonly _pending;
9122
+ private readonly _activeLoads;
9123
+ /**
9124
+ * Creates a USD loader.
9125
+ * @param options Options controlling worker assets, supporting files, and diagnostics.
9126
+ */
9127
+ constructor(options?: Partial<USDFileLoaderOptions>);
9128
+ /**
9129
+ * Creates a configured plugin instance for a SceneLoader operation.
9130
+ * @param options SceneLoader plugin options.
9131
+ * @returns The configured USD loader.
9132
+ */
9133
+ createPlugin(options: SceneLoaderPluginOptions): ISceneLoaderPluginAsync;
9134
+ /**
9135
+ * Imports all objects from a USD stage into a scene.
9136
+ * @param _meshesNames Mesh name filtering is not currently supported.
9137
+ * @param scene The scene receiving the imported objects.
9138
+ * @param data The USD, USDA, USDC, or USDZ bytes.
9139
+ * @param rootUrl The source root URL.
9140
+ * @param onProgress SceneLoader progress callback.
9141
+ * @param fileName Name of the root USD layer.
9142
+ * @returns The imported Babylon.js objects.
9143
+ */
9144
+ importMeshAsync(_meshesNames: string | readonly string[] | null | undefined, scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<ISceneLoaderAsyncResult>;
9145
+ /**
9146
+ * Loads a USD stage into a scene.
9147
+ * @param scene The scene receiving the imported objects.
9148
+ * @param data The USD, USDA, USDC, or USDZ bytes.
9149
+ * @param rootUrl The source root URL.
9150
+ * @param onProgress SceneLoader progress callback.
9151
+ * @param fileName Name of the root USD layer.
9152
+ */
9153
+ loadAsync(scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<void>;
9154
+ /**
9155
+ * Loads a USD stage into an asset container.
9156
+ * @param scene The scene used to create imported objects.
9157
+ * @param data The USD, USDA, USDC, or USDZ bytes.
9158
+ * @param rootUrl The source root URL.
9159
+ * @param onProgress SceneLoader progress callback.
9160
+ * @param fileName Name of the root USD layer.
9161
+ * @returns The populated asset container.
9162
+ */
9163
+ loadAssetContainerAsync(scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<AssetContainer>;
9164
+ /**
9165
+ * Releases the worker and rejects pending loads.
9166
+ */
9167
+ dispose(): void;
9168
+ private _loadAsync;
9169
+ private _getWorker;
9170
+ private _terminateWorker;
9171
+ }
9172
+ /** @internal */
9173
+ export function _RegisterUSDLoaderDependencies(): void;
9174
+ /**
9175
+ * Registers the USD scene loader plugin and its Babylon.js runtime dependencies.
9176
+ * Safe to call multiple times; only the first call has an effect.
9177
+ */
9178
+ export function RegisterUSDFileLoader(): void;
9179
+
9180
+
9181
+ /**
9182
+ * Defines the USD loader plugin metadata.
9183
+ */
9184
+ export var USDFileLoaderMetadata: {
9185
+ readonly name: "usd";
9186
+ readonly extensions: {
9187
+ readonly ".usd": {
9188
+ readonly isBinary: true;
9189
+ };
9190
+ readonly ".usda": {
9191
+ readonly isBinary: true;
9192
+ };
9193
+ readonly ".usdc": {
9194
+ readonly isBinary: true;
9195
+ };
9196
+ readonly ".usdz": {
9197
+ readonly isBinary: true;
9198
+ };
9199
+ };
9200
+ };
9201
+
9202
+
9203
+ /**
9204
+ * Re-exports the pure implementation and applies the runtime registration side effect.
9205
+ * Import "./usdFileLoader.pure" for tree-shakeable, side-effect-free usage.
9206
+ */
9207
+
9208
+
9209
+ export const COMMAND_MAGIC = 1111774037;
9210
+ export const PROTOCOL_VERSION = 5;
9211
+ export const MISSING_OFFSET = 4294967295;
9212
+ export enum Command {
9213
+ Scene = 1,
9214
+ Texture = 2,
9215
+ Material = 3,
9216
+ TransformNode = 4,
9217
+ Skeleton = 5,
9218
+ Geometry = 6,
9219
+ Mesh = 7,
9220
+ Instance = 8,
9221
+ Animation = 9,
9222
+ AnalyticPrimitive = 10,
9223
+ ThinInstances = 11,
9224
+ MorphTarget = 12
9225
+ }
9226
+ export enum AnalyticPrimitiveType {
9227
+ Cube = 0,
9228
+ Sphere = 1,
9229
+ Cylinder = 2,
9230
+ Cone = 3
9231
+ }
9232
+ export enum PrimitiveAxis {
9233
+ X = 0,
9234
+ Y = 1,
9235
+ Z = 2
9236
+ }
9237
+ export enum AnimationTarget {
9238
+ Node = 0,
9239
+ Bone = 1,
9240
+ MorphTarget = 2
9241
+ }
9242
+ export enum AnimationProperty {
9243
+ Position = 0,
9244
+ RotationQuaternion = 1,
9245
+ Scaling = 2,
9246
+ Matrix = 3,
9247
+ Influence = 4
9248
+ }
9249
+ export enum MaterialFlags {
9250
+ DoubleSided = 1,
9251
+ Unlit = 2,
9252
+ AlphaBlend = 4
9253
+ }
9254
+ export enum TextureOutputChannel {
9255
+ R = 0,
9256
+ G = 1,
9257
+ B = 2,
9258
+ A = 3,
9259
+ RGB = 4
9260
+ }
9261
+ export enum USDTextureColorSpace {
9262
+ Auto = 0,
9263
+ Raw = 1,
9264
+ SRGB = 2
9265
+ }
9266
+ export enum MeshFlags {
9267
+ DoubleSided = 1,
9268
+ LeftHanded = 2
9269
+ }
9270
+ export enum GeometryFlags {
9271
+ Normals = 1,
9272
+ Tangents = 2,
9273
+ Uv0 = 4,
9274
+ Colors = 8,
9275
+ Skin0 = 16,
9276
+ Skin1 = 32
9277
+ }
9278
+ export interface CommandRecord {
9279
+ opcode: Command;
9280
+ flags: number;
9281
+ payloadOffset: number;
9282
+ payloadLength: number;
9283
+ }
9284
+ export function readCommands(buffer: ArrayBuffer): CommandRecord[];
9285
+ export class PayloadReader {
9286
+ #private;
9287
+ offset: number;
9288
+ constructor(buffer: ArrayBuffer, offset: number, length: number);
9289
+ u32(): number;
9290
+ f32(): number;
9291
+ }
9292
+
9293
+
9294
+ /** Pure barrel — re-exports only side-effect-free modules */
9295
+
9296
+
9297
+
9298
+
8881
9299
  interface SceneLoaderPluginOptions {
8882
9300
  /**
8883
9301
  * Defines options for the stl loader.
@@ -9846,6 +10264,18 @@ declare namespace BABYLON {
9846
10264
  * Selects which LOD value drives the {@link GaussianSplattingStream} debug wireframe colors.
9847
10265
  */
9848
10266
  export type GaussianSplattingStreamDebugLodSource = "optimal" | "current";
10267
+ /**
10268
+ * Immutable metadata-resolution state for a stream's total number of finest-LOD splats.
10269
+ * @experimental
10270
+ */
10271
+ export type GaussianSplattingStreamLod0SplatCount = Readonly<{
10272
+ status: "pending";
10273
+ }> | Readonly<{
10274
+ status: "available";
10275
+ count: number;
10276
+ }> | Readonly<{
10277
+ status: "unavailable";
10278
+ }>;
9849
10279
  /**
9850
10280
  * Options for {@link GaussianSplattingStream}.
9851
10281
  */
@@ -9965,6 +10395,7 @@ declare namespace BABYLON {
9965
10395
  private readonly _rootUrl;
9966
10396
  private readonly _streamOptions;
9967
10397
  private readonly _leafNodes;
10398
+ private _lod0SplatCount;
9968
10399
  private _lodBaseDistance;
9969
10400
  private _lodMultiplier;
9970
10401
  private _lodBehindPenalty;
@@ -10129,6 +10560,19 @@ declare namespace BABYLON {
10129
10560
  * @experimental
10130
10561
  */
10131
10562
  get effectiveSplatBudget(): number;
10563
+ /**
10564
+ * The resolved maximum number of splats kept resident in the work buffer. This combines
10565
+ * {@link IGaussianSplattingStreamOptions.maxResidentSplats} and {@link IGaussianSplattingStreamOptions.memoryBudgetMb},
10566
+ * taking the smaller limit when both are configured. `0` means the resident budget is disabled.
10567
+ * @experimental
10568
+ */
10569
+ get residentSplatBudget(): number;
10570
+ /**
10571
+ * The total number of splats represented by valid level-0 leaf entries. This remains pending while source
10572
+ * metadata is loading and is unavailable when no applicable level-0 entries exist or required metadata fails.
10573
+ * @experimental
10574
+ */
10575
+ get lod0SplatCount(): GaussianSplattingStreamLod0SplatCount;
10132
10576
  /**
10133
10577
  * Resolves the raw {@link splatBudget} option to a concrete cap: `undefined` ⇒ 0 (disabled), `"auto"` ⇒ a
10134
10578
  * device-tiered default, a positive number ⇒ itself (floored).
@@ -10298,6 +10742,11 @@ declare namespace BABYLON {
10298
10742
  * @returns sorted unique file indices
10299
10743
  */
10300
10744
  private _collectAllFileIds;
10745
+ /**
10746
+ * Settles the level-0 diagnostic from normalized renderable leaf entries after their source metadata resolves.
10747
+ * A file may back several leaf ranges, so its source count is deliberately not used in the total.
10748
+ */
10749
+ private _resolveLod0SplatCount;
10301
10750
  /**
10302
10751
  * Fetches the environment bundle and every referenced file's metadata to learn splat counts, caching
10303
10752
  * each file's parsed metadata for the later on-demand decode. Metadata fetches run in parallel.
@@ -11455,12 +11904,83 @@ declare namespace BABYLON {
11455
11904
  * Defines options for the FBX loader.
11456
11905
  */
11457
11906
  export interface FBXFileLoaderOptions {
11907
+ /**
11908
+ * Bundle of defaults for the options that change what the loaded scene looks like.
11909
+ * - "compatible" (default): the behaviour of the loader as first shipped: StandardMaterial for every material,
11910
+ * one Babylon geometry per model, curve geometry skipped, constraints recorded as metadata only, clips rebased
11911
+ * to start at frame 0, cameras and lights placed in world space.
11912
+ * - "full": everything the loader can do: PBRMaterial for physically based shaders, geometry shared between
11913
+ * instances, curves as lines meshes, constraints solved at runtime, authored clip times, cameras and lights
11914
+ * parented to their nodes so they animate.
11915
+ * An option set explicitly always wins over the preset.
11916
+ */
11917
+ preset?: "compatible" | "full";
11458
11918
  /**
11459
11919
  * Source convention for tangent-space normal maps connected through FBX normal-map slots.
11460
11920
  * FBX does not standardize this convention, so the loader defaults to the glTF/USD-style Y-up convention.
11461
11921
  * Set to "y-down" for assets authored with inverted green/Y normal maps.
11462
11922
  */
11463
11923
  normalMapCoordinateSystem?: FBXNormalMapCoordinateSystem;
11924
+ /**
11925
+ * Which Babylon material to build.
11926
+ * - "standard" (default, "full" preset: "auto"): always StandardMaterial (PBR parameters are approximated).
11927
+ * - "auto": PBRMaterial for physically based FBX materials (Standard Surface, Arnold, 3ds Max Physical,
11928
+ * 3ds Max PBR, glTF, OpenPBR, Stingray PBS) and StandardMaterial for classic Lambert/Phong materials.
11929
+ * - "pbr": always PBRMaterial (Lambert/Phong parameters are converted).
11930
+ */
11931
+ materials?: "auto" | "standard" | "pbr";
11932
+ /**
11933
+ * Unit conversion applied at the root of the loaded hierarchy.
11934
+ * - "preserve" (default): keep the file's units (1 Babylon unit = 1 FBX unit).
11935
+ * - "meters": scale so that 1 Babylon unit is 1 meter, using the file's UnitScaleFactor.
11936
+ * - a number: centimeters per Babylon unit (100 = meters, 1 = centimeters, 2.54 = inches).
11937
+ */
11938
+ unitScale?: "preserve" | "meters" | number;
11939
+ /**
11940
+ * Share vertex data between models that reference the same FBX geometry (default false, "full" preset: true).
11941
+ * Skinned meshes are never shared.
11942
+ */
11943
+ shareGeometry?: boolean;
11944
+ /**
11945
+ * Called for every recoverable issue found while loading (unsupported features, malformed data that was
11946
+ * skipped, approximations). The same list is stored on the root node's metadata as `fbxDiagnostics`.
11947
+ */
11948
+ onWarning?: (warning: FBXLoaderWarning) => void;
11949
+ /**
11950
+ * Segments per knot span when tessellating NURBS surfaces. Zero or undefined uses the subdivision stored in
11951
+ * the file (usually 4), capped at 16.
11952
+ */
11953
+ nurbsSubdivision?: number;
11954
+ /** How curve geometry (Line, NurbsCurve) is imported: skipped (default) or as lines meshes ("full" preset). */
11955
+ curves?: "lines" | "skip";
11956
+ /**
11957
+ * Constraints (aim, parent, position, rotation, scale): "metadata" (default) only records them on the nodes,
11958
+ * "apply" ("full" preset) attaches an `FBXConstraintBehavior` to each constrained node so it is solved before
11959
+ * every render. IK chains are always metadata only.
11960
+ */
11961
+ constraints?: "apply" | "metadata";
11962
+ /**
11963
+ * Shift every clip so its first keyframe sits at frame 0 (default true). With false ("full" preset) keys keep
11964
+ * the times authored in the file, so clips of one file stay aligned with each other and with their declared
11965
+ * ranges.
11966
+ */
11967
+ rebaseAnimations?: boolean;
11968
+ /**
11969
+ * Parent cameras and lights to their FBX node so they follow its animation (default false, "full" preset:
11970
+ * true). Otherwise they are created at the node's world position and orientation, unparented.
11971
+ */
11972
+ attachCamerasAndLights?: boolean;
11973
+ }
11974
+ /** A recoverable issue reported while loading an FBX file. */
11975
+ export interface FBXLoaderWarning {
11976
+ /** Which part of the loader reported the issue */
11977
+ source: "scene" | "model" | "geometry" | "skin" | "rig" | "animation" | "blendShape" | "camera" | "light";
11978
+ /** Human readable description */
11979
+ message: string;
11980
+ /** Name of the affected object, when known */
11981
+ objectName?: string;
11982
+ /** Structured details from the interpreter, when any */
11983
+ details?: unknown;
11464
11984
  }
11465
11985
  /**
11466
11986
  * FBX file loader plugin for Babylon.js.
@@ -11483,6 +12003,22 @@ declare namespace BABYLON {
11483
12003
  private readonly _bindRestBones;
11484
12004
  private readonly _sourceBonesBySkeleton;
11485
12005
  private readonly _scaleCompensationHelpersBySkeleton;
12006
+ /** Frame rate of the file being loaded (GlobalSettings TimeMode); animation is baked at this rate. */
12007
+ private _frameRate;
12008
+ /** Layers of the animation stack currently being converted; used by the transform samplers. */
12009
+ private _activeLayers;
12010
+ /** Parent model per model id, for inherit-mode aware sampling. */
12011
+ private _parentModelById;
12012
+ /** Curve nodes per model id for the stack currently being converted. */
12013
+ private _curveNodesByModelId;
12014
+ /** Helper nodes inserted above models whose InheritType is not RSrs. */
12015
+ private _inheritScaleHelpers;
12016
+ /** First mesh built per (geometry, geometric transform), for geometry sharing between instances. */
12017
+ private _meshByGeometryKey;
12018
+ /** Instance mesh -> source mesh whose geometry it shares. */
12019
+ private _instanceSource;
12020
+ /** Property curve nodes that were mapped onto Babylon animations; their "not evaluated" diagnostics are dropped. */
12021
+ private _evaluatedCurveNodeIds;
11486
12022
  /**
11487
12023
  * Creates a new FBX loader.
11488
12024
  * @param options - Options controlling FBX loading behavior
@@ -11525,6 +12061,11 @@ declare namespace BABYLON {
11525
12061
  * @returns A promise containing the loaded asset container
11526
12062
  */
11527
12063
  loadAssetContainerAsync(scene: Scene, data: unknown, rootUrl: string, _onProgress?: (event: ISceneLoaderProgressEvent) => void, _fileName?: string): Promise<AssetContainer>;
12064
+ /**
12065
+ * Parses and interprets the file. Parsing is synchronous, so no progress events are emitted: the scene loader's
12066
+ * progress callback reports download bytes and must not be fed synthetic counts.
12067
+ */
12068
+ private _parseAndInterpret;
11528
12069
  private _parse;
11529
12070
  private _parseFromArrayBuffer;
11530
12071
  private _buildScene;
@@ -11536,6 +12077,15 @@ declare namespace BABYLON {
11536
12077
  private _linkSkeletonsToTransformNodes;
11537
12078
  private static _modelSubtreeMatchesNameFilter;
11538
12079
  private static _applyModelMetadata;
12080
+ /**
12081
+ * Wires a LodGroup's children as Babylon LOD levels: the first child holds the highest detail; every further
12082
+ * child replaces it beyond the group's threshold distance (or screen coverage when thresholds are percentages).
12083
+ * Each child's display mode is honoured first: level 1 (show) stays visible outside the LOD chain, level 2
12084
+ * (hide) is disabled, and only level 0 (use LOD) children take part in the distance switching.
12085
+ */
12086
+ private static _applyLodGroup;
12087
+ /** Builds a lines mesh from Line or tessellated NurbsCurve geometry, applying the model's geometric transform. */
12088
+ private _createLinesMesh;
11539
12089
  private _createMesh;
11540
12090
  /**
11541
12091
  * Apply multi-material to a mesh by creating sub-meshes grouped by material index.
@@ -11559,6 +12109,11 @@ declare namespace BABYLON {
11559
12109
  */
11560
12110
  private _buildSkinningData;
11561
12111
  private _createMaterial;
12112
+ private _createPbrMaterial;
12113
+ /** Alpha of a classic Lambert/Phong material: Opacity when present, otherwise 1 - TransparentColor * TransparencyFactor. */
12114
+ private static _alphaFromClassicTransparency;
12115
+ private static _applyTextureSettings;
12116
+ private _createStandardMaterial;
11562
12117
  private _configureNormalTexture;
11563
12118
  private _getNormalMapTangentHandednessScale;
11564
12119
  private static _isSupportedMaterialTextureSlot;
@@ -11582,11 +12137,27 @@ declare namespace BABYLON {
11582
12137
  private _createCamera;
11583
12138
  private _createLight;
11584
12139
  private _createSkeleton;
12140
+ private _rigBoneModelIds;
12141
+ private _isRigBone;
11585
12142
  private _getSourceBone;
11586
12143
  private _getScaleCompensationHelper;
11587
12144
  private static _computeFBXAbsoluteMatrices;
12145
+ /**
12146
+ * Effective ("inherit") scale of every bone, following the FBX SDK: the local scale for RSrs bones, and for
12147
+ * RrSs / Rrs bones the local scale multiplied by the scale of the bone's inherit-scale node (the parent for RrSs,
12148
+ * the parent's inherit-scale node for Rrs). Bones are ordered parents first.
12149
+ */
12150
+ private static _computeBoneInheritScales;
12151
+ private static _getBoneInheritScaleNode;
12152
+ /** Scale a bone inherits into its own scale (RrSs chains), or unit scale. */
12153
+ private static _getBoneInheritedScale;
11588
12154
  private static _computeFBXRuntimeLocalMatrix;
11589
12155
  private static _applyParentScaleCompensation;
12156
+ /**
12157
+ * Splits a bone's FBX local matrix into a helper (which cancels the parent scale and carries the translation,
12158
+ * so the translation still follows the parent scale as the SDK does) and the bone's own rotation/scale. For RrSs
12159
+ * bones the inherited scale is folded into the bone scale.
12160
+ */
11590
12161
  private static _splitParentScaleCompensatedLocalMatrix;
11591
12162
  private static _safeInverseScale;
11592
12163
  private static _getInverseScaleVector;
@@ -11603,13 +12174,8 @@ declare namespace BABYLON {
11603
12174
  * In row-vector convention: v' = v * M
11604
12175
  */
11605
12176
  private static _computeFBXLocalMatrix;
11606
- /**
11607
- * Apply the FBX transform chain to a Babylon TransformNode or Mesh.
11608
- * Decomposes the full local matrix into position/rotation/scale.
11609
- */
11610
- private static _applyFBXTransform;
12177
+ private _applyRestTRS;
11611
12178
  private static _computeFBXModelLocalMatrix;
11612
- private static _getBoneReferenceWorldMatrix;
11613
12179
  private static _applyMatrixToTransform;
11614
12180
  private _createAnimationGroup;
11615
12181
  private _buildInheritedRigBoneAnimations;
@@ -11619,9 +12185,61 @@ declare namespace BABYLON {
11619
12185
  * Computes the full FBX transform matrix at each keyframe and decomposes into TRS.
11620
12186
  */
11621
12187
  private _buildNodeAnimations;
12188
+ /**
12189
+ * Baked keys are interpolated linearly by Babylon. Between two frames an FBX cubic segment can deviate from that
12190
+ * line, so sample times are refined (midpoints inserted, up to two levels) wherever the interpolated transform
12191
+ * differs noticeably from the curve. Flat and linear segments stay at frame resolution.
12192
+ */
12193
+ private static _refineSampleTimes;
12194
+ /**
12195
+ * Keys of a scalar property animated by one or more layers: the authored keys when a single layer drives it,
12196
+ * otherwise the frame grid evaluated through the layer stack.
12197
+ * @param sources - Per-layer curves of the property (each with at least one curve)
12198
+ * @param animStack - Stack being converted
12199
+ * @param mapValue - Conversion from the FBX value to the Babylon property value
12200
+ * @returns Animation keys
12201
+ */
12202
+ private _layeredScalarKeys;
12203
+ /**
12204
+ * Maps an animated FBX property (anything other than node transforms and blend shape weights) onto the Babylon
12205
+ * property that carries it: mesh visibility, camera field of view and clip planes, light intensity, colour and
12206
+ * cone angles, and material colours, alpha, roughness and metalness. `group` holds the curve nodes of every
12207
+ * layer animating that property, in layer order; several layers are evaluated through the layer stack.
12208
+ */
12209
+ private _buildPropertyAnimations;
12210
+ /** Records constraints on their nodes and, unless disabled, attaches the runtime behavior that solves them. */
12211
+ private _applyConstraints;
12212
+ /** Collects every recoverable issue the interpreter recorded, stores it on the root node and notifies the caller. */
12213
+ private _reportDiagnostics;
12214
+ /** Curve nodes affecting the inherit scale of a model: its own scale curves and those of its inherit-scale chain. */
12215
+ private _collectInheritScaleCurves;
11622
12216
  private _isVector3KeysConstant;
12217
+ /** Samples the animated Lcl Translation / Rotation / Scaling of a model, blending all layers of the active stack. */
12218
+ private _sampleModelTRS;
12219
+ /**
12220
+ * Local position/rotation/scale of a model from FBX Lcl values. Without pivots and offsets the components map
12221
+ * directly (rotation = pre * lcl * post⁻¹), which keeps zero and negative scales exact. With pivots the full
12222
+ * matrix is built and decomposed.
12223
+ */
12224
+ private static _computeLocalTRS;
12225
+ /** Applies inherit-mode adjustments to a local TRS (see _computeInheritAwareLocalMatrix). */
12226
+ private _adjustTRSForInheritMode;
11623
12227
  private _sampleModelLocalMatrix;
11624
12228
  private _sampleModelScale;
12229
+ /**
12230
+ * Effective scale of a model for inherit-mode math (`inherit_scale` in ufbx terms): its own local scale, multiplied
12231
+ * componentwise by the inherited scale when the model uses RrSs inheritance. `time` samples animation; undefined
12232
+ * uses the rest pose.
12233
+ */
12234
+ private _getInheritScale;
12235
+ /** RrSs nodes inherit scale from their parent; Rrs nodes skip their immediate parent (chaining through Rrs parents). */
12236
+ private _getInheritScaleNode;
12237
+ /**
12238
+ * Local matrix of a model relative to its Babylon parent frame, accounting for inherit modes. For RSrs (the
12239
+ * default) this is the FBX local matrix. For RrSs / Rrs the node sits under a helper that removes the parent's
12240
+ * scale, so translation is pre-scaled by the parent scale and (for RrSs) scale accumulates componentwise.
12241
+ */
12242
+ private _computeInheritAwareLocalMatrix;
11625
12243
  /**
11626
12244
  * Build matrix-baked bone animation from full FBX local transforms.
11627
12245
  * The bind matrix carries the skinning offset, so animation curves drive
@@ -11656,6 +12274,189 @@ declare namespace BABYLON {
11656
12274
  */
11657
12275
 
11658
12276
 
12277
+ /**
12278
+ * Runtime evaluation of FBX constraints. An `FBXConstraintBehavior` is attached to each constrained node; all
12279
+ * behaviors of a scene register with one `FBXConstraintSolver`, which solves them in dependency order (a constraint
12280
+ * whose target or parent is driven by another constraint is solved after it) and reuses scratch objects, so solving
12281
+ * allocates nothing per frame.
12282
+ *
12283
+ * The solver brackets the scene's animation phase: before animations run it writes each node's unconstrained
12284
+ * transform back, after they ran it captures the result as the new unconstrained transform and solves. A partial
12285
+ * weight therefore always blends from what animation (or nothing) produced this frame, never from the previous
12286
+ * solve's output, so a 50% weight stays a 50% blend instead of converging on the target.
12287
+ *
12288
+ * All maths happen in FBX space, i.e. relative to the loader's root node, so the handedness conversion applied
12289
+ * at the root never enters the solve.
12290
+ */
12291
+ /** Resolved target of a constraint. */
12292
+ export interface FBXConstraintBehaviorTarget {
12293
+ /** Target node */
12294
+ node: TransformNode;
12295
+ /** Normalized target weight (0..1) */
12296
+ weight: number;
12297
+ /** Offset matrix for parent constraints (in the target's space) */
12298
+ offset: Matrix;
12299
+ }
12300
+ /** Options resolved by the loader when creating the behavior. */
12301
+ export interface FBXConstraintBehaviorOptions {
12302
+ /** Root of the loaded asset; world matrices are made relative to it */
12303
+ root: TransformNode;
12304
+ /** Resolved targets of the constraint, in file order */
12305
+ targets: FBXConstraintBehaviorTarget[];
12306
+ /** World up object of an aim constraint, when it has one */
12307
+ upNode: Nullable<TransformNode>;
12308
+ /** Scene up axis in FBX space */
12309
+ sceneUp: Vector3;
12310
+ }
12311
+ /**
12312
+ * Solves every FBX constraint of a scene once per frame, in dependency order, from the scene's animation phase
12313
+ * observers (`beginFrame` before animations, `solve` after them). Created on demand by the first
12314
+ * `FBXConstraintBehavior` attached in the scene and removed with the last one.
12315
+ */
12316
+ export class FBXConstraintSolver {
12317
+ private readonly _scene;
12318
+ private readonly _behaviors;
12319
+ private _ordered;
12320
+ private _cyclic;
12321
+ private _dirty;
12322
+ private _beforeAnimations;
12323
+ private _afterAnimations;
12324
+ private constructor();
12325
+ /**
12326
+ * Solver of a scene, if any constraint behavior is attached in it.
12327
+ * @param scene - Scene to look up
12328
+ * @returns The solver, or undefined
12329
+ */
12330
+ static Get(scene: Scene): FBXConstraintSolver | undefined;
12331
+ /**
12332
+ * Solver of a scene, created when missing.
12333
+ * @param scene - Scene to look up
12334
+ * @returns The solver
12335
+ */
12336
+ static GetOrCreate(scene: Scene): FBXConstraintSolver;
12337
+ /** Registered behaviors in solve order (a target's constraint before the constraints that read it). */
12338
+ get constraints(): readonly FBXConstraintBehavior[];
12339
+ /**
12340
+ * Behaviors that take part in a dependency cycle (A targets B while B targets A). They are solved after all
12341
+ * acyclic constraints, in registration order, so each sees the other's result from the previous solve.
12342
+ */
12343
+ get cyclicConstraints(): readonly FBXConstraintBehavior[];
12344
+ /**
12345
+ * Adds a behavior to the solve set.
12346
+ * @param behavior - Behavior to add
12347
+ */
12348
+ register(behavior: FBXConstraintBehavior): void;
12349
+ /**
12350
+ * Removes a behavior from the solve set; the solver disposes itself with the last one.
12351
+ * @param behavior - Behavior to remove
12352
+ */
12353
+ unregister(behavior: FBXConstraintBehavior): void;
12354
+ /** Marks the solve order stale, e.g. after re-parenting a constrained node. */
12355
+ invalidateOrder(): void;
12356
+ /**
12357
+ * Start of a frame, before animations run: every constrained node gets its unconstrained transform back, so
12358
+ * that animation either overwrites it or leaves it untouched.
12359
+ */
12360
+ beginFrame(): void;
12361
+ /**
12362
+ * End of the animation phase: takes every constrained node's current transform as its unconstrained value,
12363
+ * then solves every registered constraint once, in dependency order.
12364
+ */
12365
+ solve(): void;
12366
+ private _ensureOrder;
12367
+ private static _IsAncestorOrSelf;
12368
+ }
12369
+ /** Babylon behavior evaluating an FBX aim, parent, position, rotation or scale constraint. */
12370
+ export class FBXConstraintBehavior implements Behavior<TransformNode> {
12371
+ /** Constraint data extracted from the file */
12372
+ readonly constraint: FBXConstraintData;
12373
+ private readonly _options;
12374
+ /** Behavior name (`fbxConstraint:` followed by the constraint name) */
12375
+ readonly name: string;
12376
+ /** Node the behavior is attached to */
12377
+ attachedNode: Nullable<TransformNode>;
12378
+ /** Set to false to pause the constraint without detaching it */
12379
+ enabled: boolean;
12380
+ private readonly _offsetTranslation;
12381
+ private readonly _offsetRotation;
12382
+ private readonly _offsetScale;
12383
+ private readonly _localBasisTransposed;
12384
+ /** Unconstrained transform of the current frame (what animation produced), blended towards the constraint's result. */
12385
+ private readonly _base;
12386
+ private _hasBase;
12387
+ /**
12388
+ * Creates the behavior.
12389
+ * @param constraint - Constraint data extracted from the file
12390
+ * @param _options - Resolved targets and scene information
12391
+ */
12392
+ constructor(
12393
+ /** Constraint data extracted from the file */
12394
+ constraint: FBXConstraintData, _options: FBXConstraintBehaviorOptions);
12395
+ /** Nothing to initialize */
12396
+ init(): void;
12397
+ /**
12398
+ * Registers the behavior with the scene's solver, takes the node's current transform as the unconstrained
12399
+ * value and solves the constraint once.
12400
+ * @param target - Node to constrain
12401
+ */
12402
+ attach(target: TransformNode): void;
12403
+ /** Unregisters the behavior; the node keeps its last solved transform. */
12404
+ detach(): void;
12405
+ /**
12406
+ * Takes the node's current transform as the unconstrained value the next solve blends from. The solver calls
12407
+ * this after the scene's animations ran; call it yourself after writing a transform by hand.
12408
+ */
12409
+ captureBase(): void;
12410
+ /**
12411
+ * Writes the unconstrained transform back to the node. The solver calls this before the scene's animations
12412
+ * run, so a node nothing animates keeps its unconstrained value between frames instead of the solved one.
12413
+ */
12414
+ restoreBase(): void;
12415
+ /**
12416
+ * Nodes whose world transform the solve reads: the targets, the up node and the constrained node's parent.
12417
+ * @returns The nodes, used by the solver to order constraints
12418
+ */
12419
+ dependencyNodes(): Nullable<Node>[];
12420
+ /**
12421
+ * Solves the constraint from the captured unconstrained transform and writes the node's local transform.
12422
+ * Blends are relative to the value captured by `captureBase`, not to whatever the node holds now.
12423
+ */
12424
+ evaluate(): void;
12425
+ /**
12426
+ * World matrix of a node relative to the asset root (FBX space).
12427
+ * @param node - node to evaluate
12428
+ * @param out - matrix receiving the result
12429
+ * @returns `out`
12430
+ */
12431
+ private _fbxWorld;
12432
+ /**
12433
+ * Weighted blend of the targets' world transforms (relative to the root).
12434
+ * @param position - Receives the blended translation
12435
+ * @param rotation - Receives the blended rotation
12436
+ * @param scale - Receives the blended scale
12437
+ * @returns The total target weight, 0 when no target contributes
12438
+ */
12439
+ private _blendTargets;
12440
+ private _applyWeighted;
12441
+ private _applyRotation;
12442
+ private _writePosition;
12443
+ private _writeScaling;
12444
+ private _solvePosition;
12445
+ private _solveRotation;
12446
+ private _solveScale;
12447
+ private _solveParent;
12448
+ private _solveAim;
12449
+ /**
12450
+ * Builds a rotation matrix whose rows are `first`, `second` made orthogonal to it, and their cross product.
12451
+ * @param first - primary axis
12452
+ * @param second - secondary axis
12453
+ * @param out - matrix receiving the basis
12454
+ * @returns false when the axes are parallel or degenerate (`out` is then unchanged)
12455
+ */
12456
+ private static _OrthonormalBasisToRef;
12457
+ }
12458
+
12459
+
11659
12460
  /**
11660
12461
  * Intermediate representation for parsed FBX data.
11661
12462
  * Both binary and ASCII parsers produce this same structure.
@@ -11670,6 +12471,11 @@ declare namespace BABYLON {
11670
12471
  type: FBXPropertyType;
11671
12472
  /** Parsed property value. */
11672
12473
  value: FBXPropertyValue;
12474
+ /**
12475
+ * Exact decimal text of an int64 whose magnitude exceeds 2^53; `value` then holds the rounded double. Object
12476
+ * ids are the only int64 values where the last bits matter, and `resolveConnections` keys them by this text.
12477
+ */
12478
+ raw?: string;
11673
12479
  }
11674
12480
  /** A node in the FBX document tree */
11675
12481
  export interface FBXNode {
@@ -11696,11 +12502,22 @@ declare namespace BABYLON {
11696
12502
  /** Extract a property value by index, with type narrowing */
11697
12503
  export function getPropertyValue<T extends FBXPropertyValue>(node: FBXNode, index: number): T | undefined;
11698
12504
  /**
11699
- * Converts an FBX object ID value to a safe JavaScript number.
12505
+ * Validates an FBX object ID value: IDs are 64-bit integers, so anything non-numeric, non-finite or fractional is
12506
+ * rejected. IDs beyond 2^53 are carried losslessly through the property's `raw` text by `resolveConnections`.
11700
12507
  * @param value - Parsed FBX object ID value
11701
- * @returns The object ID, or undefined when the value is not numeric
12508
+ * @returns The object ID, or undefined when the value cannot be an ID
11702
12509
  */
11703
12510
  export function getSafeFBXObjectId(value: unknown): number | undefined;
12511
+ /** Typed array payload types produced by the parsers. */
12512
+ export type FBXArrayValue = Float32Array | Float64Array | Int32Array | Uint8Array;
12513
+ /**
12514
+ * Returns the array payload of a node.
12515
+ * FBX 7.x stores arrays as a single array property. FBX 6.x (and some 7.x ASCII exporters) store them as a run of
12516
+ * scalar properties, and a one-element array degenerates to a single scalar. All of these are coalesced here.
12517
+ * @param node - Node whose properties hold the array
12518
+ * @returns The array, or null when the node has no numeric payload
12519
+ */
12520
+ export function getNodeArray(node: FBXNode | undefined | null): FBXArrayValue | null;
11704
12521
  /** Get the numeric ID from a node (first property is typically the int64 UID) */
11705
12522
  export function getNodeId(node: FBXNode): number | undefined;
11706
12523
  /**
@@ -11828,25 +12645,9 @@ declare namespace BABYLON {
11828
12645
  /** Recoverable skinning/bind diagnostics */
11829
12646
  diagnostics: FBXSkinDiagnostic[];
11830
12647
  }
11831
- /**
11832
- * Extract all skin deformers from the FBX scene.
11833
- * Returns skin data including bone hierarchy and vertex weights.
11834
- */
11835
- export function extractSkins(objectMap: FBXObjectMap): FBXSkinData[];
12648
+ export function extractSkins(objectMap: FBXObjectMap, propertyTemplates?: FBXPropertyTemplateMap): FBXSkinData[];
11836
12649
  export function isSkeletonModel(modelNode: FBXNode): boolean;
11837
- export function extractBoneTransform(modelNode: FBXNode): {
11838
- translation: [number, number, number];
11839
- rotation: [number, number, number];
11840
- preRotation: [number, number, number];
11841
- postRotation: [number, number, number];
11842
- rotationPivot: [number, number, number];
11843
- scalingPivot: [number, number, number];
11844
- rotationOffset: [number, number, number];
11845
- scalingOffset: [number, number, number];
11846
- scale: [number, number, number];
11847
- rotationOrder: number;
11848
- inheritType: number;
11849
- };
12650
+ export function extractBoneTransform(modelNode: FBXNode, template?: FBXPropertyTemplate): FBXNodeTransformData;
11850
12651
 
11851
12652
 
11852
12653
  export type FBXSceneDiagnosticType = "unsupported-constraint" | "unsupported-helper" | "unsupported-deformer" | "unsupported-node-attribute" | "unsupported-pose" | "unsupported-layered-texture" | "connection-graph";
@@ -11905,6 +12706,160 @@ declare namespace BABYLON {
11905
12706
  export function resolveVector2Property(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: [number, number]): [number, number];
11906
12707
  export function resolveVector3Property(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: [number, number, number]): [number, number, number];
11907
12708
  export function resolvePropertyValues(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string): FBXPropertyValue[] | undefined;
12709
+ /** A property from a Properties70 ("P") or Properties60 ("Property") block. */
12710
+ export interface FBXPropertyEntry {
12711
+ name: string;
12712
+ type: string;
12713
+ flags: string;
12714
+ values: FBXPropertyValue[];
12715
+ }
12716
+ /**
12717
+ * Lists the properties declared directly on an object, from both the 7.x and 6.x property blocks.
12718
+ * @param node - Object node
12719
+ * @returns Property entries in declaration order (empty when the node has no property block)
12720
+ */
12721
+ export function getPropertyEntries(node: FBXNode | undefined): FBXPropertyEntry[];
12722
+ /** Value of a user property: scalars as-is, vectors and colours as number arrays. */
12723
+ export type FBXUserPropertyValue = string | number | boolean | number[];
12724
+ /**
12725
+ * User-defined properties of an object: those flagged "U" (user) in the property flags. Every DCC exports custom
12726
+ * attributes this way (Maya extra attributes, 3ds Max user properties, Blender custom properties).
12727
+ * @param node - Object node
12728
+ * @returns Map of property name to value, or undefined when the object has none
12729
+ */
12730
+ export function extractUserProperties(node: FBXNode): Record<string, FBXUserPropertyValue> | undefined;
12731
+ export function userPropertyValue(values: FBXPropertyValue[], typeName?: string): FBXUserPropertyValue | undefined;
12732
+
12733
+
12734
+ /**
12735
+ * NURBS curves and surfaces, and polyline ("Line") geometry.
12736
+ *
12737
+ * The basis evaluation and tessellation follow the FBX SDK conventions as implemented by ufbx: knot spans are
12738
+ * subdivided uniformly, closed and periodic curves wrap their control points, and surfaces are tessellated into
12739
+ * quads (degenerate quads at poles become triangles) with welded positions along the wrapped edges.
12740
+ */
12741
+ export type FBXNurbsTopology = "open" | "closed" | "periodic";
12742
+ /** Knot vector and derived data of one parametric direction. */
12743
+ export interface FBXNurbsBasis {
12744
+ order: number;
12745
+ topology: FBXNurbsTopology;
12746
+ knots: Float64Array;
12747
+ /** Parameter range that the curve is defined on */
12748
+ tMin: number;
12749
+ tMax: number;
12750
+ /** Distinct knot values inside [tMin, tMax], i.e. the boundaries of the non-empty spans */
12751
+ spans: Float64Array;
12752
+ /** False when the knot vector is too short or not monotonic */
12753
+ valid: boolean;
12754
+ }
12755
+ /** NURBS curve: homogeneous control points (x, y, z, w) and a basis. */
12756
+ export interface FBXNurbsCurveData {
12757
+ basis: FBXNurbsBasis;
12758
+ /** Control points as x,y,z,w */
12759
+ controlPoints: Float64Array;
12760
+ numControlPoints: number;
12761
+ }
12762
+ /** NURBS surface: control points laid out as `v * numU + u`. */
12763
+ export interface FBXNurbsSurfaceData {
12764
+ basisU: FBXNurbsBasis;
12765
+ basisV: FBXNurbsBasis;
12766
+ numU: number;
12767
+ numV: number;
12768
+ /** Control points as x,y,z,w */
12769
+ controlPoints: Float64Array;
12770
+ flipNormals: boolean;
12771
+ /** Span subdivision stored in the file (Step), 0 when absent */
12772
+ stepU: number;
12773
+ stepV: number;
12774
+ }
12775
+ /** Polyline geometry ready for a lines mesh: one or more open or closed point runs. */
12776
+ export interface FBXCurveGeometryData {
12777
+ id: number;
12778
+ name: string;
12779
+ kind: "line" | "nurbsCurve";
12780
+ /** Each polyline as x,y,z triples; closed runs repeat their first point at the end */
12781
+ polylines: Float64Array[];
12782
+ /** Display colour from the geometry's Color property */
12783
+ color: [number, number, number] | null;
12784
+ diagnostics: FBXGeometryDiagnostic[];
12785
+ }
12786
+ export function createNurbsBasis(order: number, form: string | undefined, knots: Float64Array): FBXNurbsBasis;
12787
+ /**
12788
+ * Evaluates the basis functions (and their derivatives) that are non-zero at `u`.
12789
+ * @returns index of the first influencing control point, or -1 when the basis cannot be evaluated
12790
+ */
12791
+ export function evaluateNurbsBasis(basis: FBXNurbsBasis, u: number, weights: Float64Array, derivatives: Float64Array | null): number;
12792
+ /** Evaluates a curve point; `out` receives position (0..2) and derivative (3..5). */
12793
+ export function evaluateNurbsCurve(curve: FBXNurbsCurveData, u: number, out: Float64Array, weights: Float64Array, derivs: Float64Array): boolean;
12794
+ /** Evaluates a surface point; `out` receives position (0..2), du (3..5) and dv (6..8). */
12795
+ export function evaluateNurbsSurface(surface: FBXNurbsSurfaceData, u: number, v: number, out: Float64Array, scratch: {
12796
+ wu: Float64Array;
12797
+ wv: Float64Array;
12798
+ du: Float64Array;
12799
+ dv: Float64Array;
12800
+ }): boolean;
12801
+ /**
12802
+ * Tessellates a curve into a polyline with `subdivision` segments per knot span. Closed and periodic curves
12803
+ * end on a copy of their first point.
12804
+ */
12805
+ export function tessellateNurbsCurve(curve: FBXNurbsCurveData, subdivision?: number): Float64Array | null;
12806
+ /** Span subdivision to use for a surface direction: an explicit override, else the file's Step, else 4. */
12807
+ export function resolveSpanSubdivision(fileStep: number, override: number | undefined): number;
12808
+ /**
12809
+ * Tessellates a surface into triangles. Positions on wrapped (closed/periodic) edges and at poles are welded
12810
+ * exactly like the FBX SDK does, so degenerate quads collapse into triangles.
12811
+ */
12812
+ export function tessellateNurbsSurface(surface: FBXNurbsSurfaceData, subU: number, subV: number): {
12813
+ positions: Float64Array;
12814
+ indices: Uint32Array;
12815
+ normals: Float64Array;
12816
+ uvs: Float64Array;
12817
+ } | null;
12818
+ /** Reads a NurbsCurve geometry node. */
12819
+ export function extractNurbsCurve(node: FBXNode): FBXNurbsCurveData | null;
12820
+ /** Reads a NurbsSurface geometry node. */
12821
+ export function extractNurbsSurface(node: FBXNode): FBXNurbsSurfaceData | null;
12822
+ /** Tessellates a NurbsSurface geometry node into mesh geometry. */
12823
+ export function nurbsSurfaceToGeometry(node: FBXNode, geometryId: number, subdivisionOverride: number | undefined): FBXGeometryData | null;
12824
+ /** Reads a NurbsCurve geometry node into a tessellated polyline. */
12825
+ export function extractNurbsCurveGeometry(node: FBXNode, geometryId: number, subdivision?: number): FBXCurveGeometryData;
12826
+ /**
12827
+ * Reads a Line geometry node: Points plus PointsIndex where a negative index (~index) ends a segment, as in
12828
+ * polygon vertex indices.
12829
+ */
12830
+ export function extractLineGeometry(node: FBXNode, geometryId: number): FBXCurveGeometryData;
12831
+
12832
+
12833
+ /** Transform properties resolved from an FBX Model, with template defaults applied. */
12834
+ export interface FBXNodeTransformData {
12835
+ translation: [number, number, number];
12836
+ rotation: [number, number, number];
12837
+ scale: [number, number, number];
12838
+ preRotation: [number, number, number];
12839
+ postRotation: [number, number, number];
12840
+ rotationPivot: [number, number, number];
12841
+ scalingPivot: [number, number, number];
12842
+ rotationOffset: [number, number, number];
12843
+ scalingOffset: [number, number, number];
12844
+ geometricTranslation: [number, number, number];
12845
+ geometricRotation: [number, number, number];
12846
+ geometricScaling: [number, number, number];
12847
+ /** Rotation order: 0=XYZ, 1=XZY, 2=YZX, 3=YXZ, 4=ZXY, 5=ZYX, 6=SphericXYZ */
12848
+ rotationOrder: number;
12849
+ /** FBX transform inheritance mode. 0=RrSs, 1=RSrs, 2=Rrs */
12850
+ inheritType: number;
12851
+ /** Whether the rotation space (rotation order, pre/post rotation) is active for this node */
12852
+ rotationActive: boolean;
12853
+ diagnostics: string[];
12854
+ }
12855
+ /**
12856
+ * Resolves the transform properties of a Model node the way the FBX SDK evaluates them.
12857
+ *
12858
+ * `RotationActive` gates the whole rotation space: when it is false (the FbxNode template default), the SDK
12859
+ * composes `Lcl Rotation` in plain XYZ order and ignores `RotationOrder`, `PreRotation` and `PostRotation`.
12860
+ * `RotationSpaceForLimitOnly` restricts the rotation space to limits, which has the same effect for us.
12861
+ */
12862
+ export function extractNodeTransform(modelNode: FBXNode, template?: FBXPropertyTemplate): FBXNodeTransformData;
11908
12863
 
11909
12864
 
11910
12865
  /** Parsed material data */
@@ -11914,6 +12869,10 @@ declare namespace BABYLON {
11914
12869
  type: "Lambert" | "Phong";
11915
12870
  properties: FBXMaterialProperties;
11916
12871
  textures: FBXTextureRef[];
12872
+ /** Unified classic + PBR parameter model resolved from whichever shader flavour the file uses */
12873
+ model: FBXMaterialModel<FBXTextureRef>;
12874
+ /** User-defined properties */
12875
+ userProperties?: Record<string, FBXUserPropertyValue>;
11917
12876
  }
11918
12877
  export interface FBXMaterialProperties {
11919
12878
  diffuseColor?: [number, number, number];
@@ -11949,11 +12908,102 @@ declare namespace BABYLON {
11949
12908
  uvSetIndex?: number;
11950
12909
  /** Which named UV set this texture uses */
11951
12910
  uvSetName?: string;
12911
+ /** WrapModeU: 0 = repeat, 1 = clamp */
12912
+ wrapU?: number;
12913
+ /** WrapModeV: 0 = repeat, 1 = clamp */
12914
+ wrapV?: number;
12915
+ /** Set when the texture came from a LayeredTexture (only the first layer is used) */
12916
+ layeredTextureId?: number;
11952
12917
  }
11953
12918
  /**
11954
12919
  * Extract material data from an FBX Material node.
11955
12920
  */
11956
12921
  export function extractMaterial(materialNode: FBXNode, materialId: number, objectMap: FBXObjectMap, templates?: FBXPropertyTemplateMap): FBXMaterialData;
12922
+ export function extractTextureRef(id: number, node: FBXNode, propertyName: string | undefined, objectMap: FBXObjectMap, template?: FBXPropertyTemplate): FBXTextureRef;
12923
+
12924
+
12925
+ /**
12926
+ * Unified material model.
12927
+ *
12928
+ * FBX materials come in many vendor flavours: the classic FbxSurfaceLambert / FbxSurfacePhong, Autodesk Standard
12929
+ * Surface (OSL), Arnold aiStandardSurface, 3ds Max Physical Material, 3ds Max PBR (metal/rough and spec/gloss),
12930
+ * the 3ds Max glTF material, OpenPBR, and Maya's Stingray PBS ShaderFX graph. Each stores its parameters under
12931
+ * different property names, sometimes behind a shader binding table.
12932
+ *
12933
+ * This module resolves any of them into two parameter sets, mirroring how the FBX SDK / ufbx expose materials:
12934
+ * `fbx` (the classic Lambert/Phong parameters) and `pbr` (a physically based parameter set), plus feature flags.
12935
+ */
12936
+ export type FBXShaderType = "unknown" | "fbxLambert" | "fbxPhong" | "oslStandardSurface" | "arnoldStandardSurface" | "3dsMaxPhysicalMaterial" | "3dsMaxPbrMetalRough" | "3dsMaxPbrSpecGloss" | "gltfMaterial" | "openPbrMaterial" | "shaderFxGraph";
12937
+ /** One resolved material parameter: a constant value and/or a texture. */
12938
+ export interface FBXMaterialMap<TTexture> {
12939
+ /** Constant value (r,g,b,a for colours, x for scalars) */
12940
+ value?: number[];
12941
+ /** Number of meaningful components in `value` (1 for scalars, 3 or 4 for colours) */
12942
+ valueComponents: number;
12943
+ /** Texture bound to the parameter */
12944
+ texture?: TTexture;
12945
+ /** Whether the texture is enabled (some vendors carry an explicit toggle) */
12946
+ textureEnabled: boolean;
12947
+ }
12948
+ export type FBXFbxMapName = "diffuseFactor" | "diffuseColor" | "specularFactor" | "specularColor" | "specularExponent" | "reflectionFactor" | "reflectionColor" | "transparencyFactor" | "transparencyColor" | "emissionFactor" | "emissionColor" | "ambientFactor" | "ambientColor" | "normalMap" | "bump" | "bumpFactor" | "displacement" | "displacementFactor" | "vectorDisplacement" | "vectorDisplacementFactor";
12949
+ export type FBXPbrMapName = "baseFactor" | "baseColor" | "roughness" | "metalness" | "diffuseRoughness" | "specularFactor" | "specularColor" | "specularIor" | "specularAnisotropy" | "specularRotation" | "transmissionFactor" | "transmissionColor" | "transmissionDepth" | "transmissionScatter" | "transmissionScatterAnisotropy" | "transmissionDispersion" | "transmissionRoughness" | "transmissionExtraRoughness" | "transmissionPriority" | "transmissionEnableInAov" | "subsurfaceFactor" | "subsurfaceColor" | "subsurfaceRadius" | "subsurfaceScale" | "subsurfaceAnisotropy" | "subsurfaceTintColor" | "subsurfaceType" | "sheenFactor" | "sheenColor" | "sheenRoughness" | "coatFactor" | "coatColor" | "coatRoughness" | "coatIor" | "coatAnisotropy" | "coatRotation" | "coatNormal" | "coatAffectBaseColor" | "coatAffectBaseRoughness" | "thinFilmFactor" | "thinFilmThickness" | "thinFilmIor" | "emissionFactor" | "emissionColor" | "opacity" | "indirectDiffuse" | "indirectSpecular" | "normalMap" | "tangentMap" | "displacementMap" | "matteFactor" | "matteColor" | "ambientOcclusion" | "glossiness" | "coatGlossiness" | "transmissionGlossiness";
12950
+ export type FBXMaterialFeatureName = "pbr" | "metalness" | "diffuse" | "specular" | "emission" | "transmission" | "coat" | "sheen" | "opacity" | "ambientOcclusion" | "matte" | "unlit" | "ior" | "diffuseRoughness" | "transmissionRoughness" | "thinWalled" | "caustics" | "exitToBackground" | "internalReflections" | "doubleSided" | "roughnessAsGlossiness" | "coatRoughnessAsGlossiness" | "transmissionRoughnessAsGlossiness";
12951
+ export interface FBXMaterialModel<TTexture> {
12952
+ shaderType: FBXShaderType;
12953
+ /** Prefix material property names carry for this shader (e.g. "3dsMax|Parameters|") */
12954
+ shaderPropPrefix: string;
12955
+ fbx: Partial<Record<FBXFbxMapName, FBXMaterialMap<TTexture>>>;
12956
+ pbr: Partial<Record<FBXPbrMapName, FBXMaterialMap<TTexture>>>;
12957
+ features: Partial<Record<FBXMaterialFeatureName, {
12958
+ enabled: boolean;
12959
+ explicit: boolean;
12960
+ }>>;
12961
+ }
12962
+ /** Inputs needed to resolve a material, independent of the parse representation. */
12963
+ export interface FBXMaterialSource<TTexture> {
12964
+ /** "lambert", "phong", "unknown", ... as written in the file */
12965
+ shadingModelName: string;
12966
+ /** Property values by full property name (e.g. "DiffuseColor", "Maya|baseColor", "3dsMax|Parameters|roughness") */
12967
+ props: Map<string, {
12968
+ type: string;
12969
+ values: FBXPropertyValue[];
12970
+ }>;
12971
+ /** Textures connected to the material by property name (OP connection property) */
12972
+ texturesByProp: Map<string, TTexture>;
12973
+ /** Connected shader implementation, when any */
12974
+ shader?: {
12975
+ renderApi: string;
12976
+ /** shader semantic name -> material property names */
12977
+ bindings: Map<string, string[]>;
12978
+ };
12979
+ }
12980
+ /** Shader types whose parameters are physically based; the loader emits PBR materials for them by default. */
12981
+ export function isPbrShaderType(type: FBXShaderType): boolean;
12982
+ /** Detects the shader flavour of a material from its shading model name, connected shader and 3ds Max class ids. */
12983
+ export function detectShaderType<T>(source: FBXMaterialSource<T>): {
12984
+ shaderType: FBXShaderType;
12985
+ shaderPropPrefix: string;
12986
+ };
12987
+ /**
12988
+ * Resolves the unified material model from raw material data.
12989
+ */
12990
+ export function resolveMaterialModel<T>(source: FBXMaterialSource<T>): FBXMaterialModel<T>;
12991
+ /** Colour (first three components) of a map, or undefined. */
12992
+ export function mapColor<T>(map: FBXMaterialMap<T> | undefined): [number, number, number] | undefined;
12993
+ /** Scalar (first component) of a map, or undefined. */
12994
+ export function mapScalar<T>(map: FBXMaterialMap<T> | undefined): number | undefined;
12995
+
12996
+
12997
+ /**
12998
+ * FBX 5.x (and older) documents store everything at the top level: one `Model` node per object with inline
12999
+ * geometry, materials, skin links, lights and cameras, and `Children` lists instead of connections. This module
13000
+ * rewrites such a document into the 6.x layout (`Objects`, `Connections`, `Takes`) so the rest of the importer
13001
+ * can treat both the same way. The rules follow the FBX SDK's legacy reader as implemented by ufbx.
13002
+ */
13003
+ /** True for pre-6000 files: no `Objects` section but top-level `Model` nodes. */
13004
+ export function isLegacyDocument(doc: FBXDocument): boolean;
13005
+ /** Rewrites a legacy document into the 6.x object/connection layout. */
13006
+ export function upgradeLegacyDocument(doc: FBXDocument): FBXDocument;
11957
13007
 
11958
13008
 
11959
13009
  /** A named UV set */
@@ -11966,7 +13016,7 @@ declare namespace BABYLON {
11966
13016
  /** Recoverable geometry import issue. */
11967
13017
  export interface FBXGeometryDiagnostic {
11968
13018
  /** Diagnostic category. */
11969
- type: "degenerate-polygon" | "triangulation-fallback" | "layer-index-out-of-bounds" | "layer-data-too-short";
13019
+ type: "degenerate-polygon" | "triangulation-fallback" | "layer-index-out-of-bounds" | "layer-data-too-short" | "nurbs-invalid" | "nurbs-trim-ignored" | "nurbs-deformer-ignored";
11970
13020
  /** Human-readable diagnostic message. */
11971
13021
  message: string;
11972
13022
  /** Polygon index associated with the diagnostic, if applicable. */
@@ -12017,8 +13067,10 @@ declare namespace BABYLON {
12017
13067
  id: number;
12018
13068
  name: string;
12019
13069
  subType: string;
12020
- /** Geometry attached to this model (if it's a Mesh type) */
13070
+ /** Geometry attached to this model (meshes and tessellated NURBS surfaces) */
12021
13071
  geometry?: FBXGeometryData;
13072
+ /** Curve geometry attached to this model (Line and NurbsCurve) */
13073
+ curve?: FBXCurveGeometryData;
12022
13074
  /** Materials assigned to this model */
12023
13075
  materials: FBXMaterialData[];
12024
13076
  /** Child models */
@@ -12050,18 +13102,68 @@ declare namespace BABYLON {
12050
13102
  /** Whether backface culling is disabled ("CullingOff") */
12051
13103
  cullingOff: boolean;
12052
13104
  /** User-defined custom properties from Properties70 */
12053
- customProperties?: Record<string, string | number | boolean>;
13105
+ customProperties?: Record<string, FBXUserPropertyValue>;
13106
+ /** LOD group settings when this model is a LodGroup; children are the levels in order */
13107
+ lodGroup?: FBXLodGroupData;
13108
+ /** Display layer (CollectionExclusive) the model belongs to */
13109
+ displayLayer?: FBXDisplayLayerData;
12054
13110
  /** Recoverable model import diagnostics */
12055
13111
  diagnostics: string[];
12056
13112
  }
13113
+ /** LOD group settings (NodeAttribute "LodGroup") */
13114
+ export interface FBXLodGroupData {
13115
+ /** Switch distance for level i+1 (level 0 has none). In scene units, or percent of screen when `relative`. */
13116
+ thresholds: number[];
13117
+ /** ThresholdsUsedAsPercentage */
13118
+ relative: boolean;
13119
+ /** DisplayLevels|LevelN: 0 use LOD, 1 show, 2 hide */
13120
+ displayLevels: number[];
13121
+ }
13122
+ /** Display layer (CollectionExclusive "DisplayLayer") */
13123
+ export interface FBXDisplayLayerData {
13124
+ id: number;
13125
+ name: string;
13126
+ show: boolean;
13127
+ freeze: boolean;
13128
+ color: [number, number, number];
13129
+ modelIds: number[];
13130
+ }
13131
+ /** One member of a selection set: a model, optionally with a component selection on its mesh */
13132
+ export interface FBXSelectionNodeData {
13133
+ modelId: number;
13134
+ /** IsTheNodeInSet: the whole node is selected (as opposed to only components) */
13135
+ includeNode: boolean;
13136
+ /** Selected control point indices (VertexIndexArray) */
13137
+ vertices?: number[];
13138
+ /** Selected edge indices (EdgeIndexArray) */
13139
+ edges?: number[];
13140
+ /** Selected polygon indices (PolygonIndexArray) */
13141
+ faces?: number[];
13142
+ }
13143
+ /** Selection set (Collection "SelectionSet") */
13144
+ export interface FBXSelectionSetData {
13145
+ id: number;
13146
+ name: string;
13147
+ members: FBXSelectionNodeData[];
13148
+ }
12057
13149
  /** Camera data extracted from FBX */
12058
13150
  export interface FBXCameraData {
12059
13151
  /** Model ID this camera is attached to */
12060
13152
  modelId: number;
13153
+ /** NodeAttribute object ID (animation curves target this) */
13154
+ attributeId: number;
12061
13155
  /** Camera name */
12062
13156
  name: string;
12063
- /** Field of view in degrees */
13157
+ /** Vertical field of view in degrees */
12064
13158
  fieldOfView: number;
13159
+ /** Horizontal field of view in degrees */
13160
+ fieldOfViewX: number;
13161
+ /** ApertureMode: 0 horizontal and vertical, 1 horizontal, 2 vertical, 3 focal length */
13162
+ apertureMode: number;
13163
+ /** Aperture (film gate after gate fit) size in inches */
13164
+ apertureSizeInch: [number, number];
13165
+ /** Orthographic view size (width, height) in scene units */
13166
+ orthographicSize: [number, number];
12065
13167
  /** Near clip plane */
12066
13168
  nearPlane: number;
12067
13169
  /** Far clip plane */
@@ -12080,6 +13182,8 @@ declare namespace BABYLON {
12080
13182
  orthoZoom?: number;
12081
13183
  /** Camera roll in degrees when present */
12082
13184
  roll?: number;
13185
+ /** User-defined properties on the camera attribute */
13186
+ userProperties?: Record<string, FBXUserPropertyValue>;
12083
13187
  /** Known unsupported or unrecognized camera properties */
12084
13188
  unknownProperties: string[];
12085
13189
  /** Recoverable camera import diagnostics */
@@ -12089,6 +13193,8 @@ declare namespace BABYLON {
12089
13193
  export interface FBXLightData {
12090
13194
  /** Model ID this light is attached to */
12091
13195
  modelId: number;
13196
+ /** NodeAttribute object ID (animation curves target this) */
13197
+ attributeId: number;
12092
13198
  /** Light name */
12093
13199
  name: string;
12094
13200
  /** Light type: 0=Point, 1=Directional, 2=Spot */
@@ -12113,6 +13219,15 @@ declare namespace BABYLON {
12113
13219
  enableFarAttenuation?: boolean;
12114
13220
  /** Whether the source light requested shadow casting */
12115
13221
  castShadows?: boolean;
13222
+ /** Near/far attenuation ranges in scene units (when enabled) */
13223
+ nearAttenuationStart?: number;
13224
+ nearAttenuationEnd?: number;
13225
+ farAttenuationStart?: number;
13226
+ farAttenuationEnd?: number;
13227
+ /** Area light shape: 0 rectangle, 1 sphere */
13228
+ areaLightShape?: number;
13229
+ /** User-defined properties on the light attribute */
13230
+ userProperties?: Record<string, FBXUserPropertyValue>;
12116
13231
  /** Known unsupported or unrecognized light properties */
12117
13232
  unknownProperties: string[];
12118
13233
  /** Recoverable light import diagnostics */
@@ -12124,6 +13239,8 @@ declare namespace BABYLON {
12124
13239
  rootModels: FBXModelData[];
12125
13240
  /** All geometries in the scene */
12126
13241
  geometries: FBXGeometryData[];
13242
+ /** All curve geometries (lines and tessellated NURBS curves) */
13243
+ curves: FBXCurveGeometryData[];
12127
13244
  /** All materials in the scene */
12128
13245
  materials: FBXMaterialData[];
12129
13246
  /** Skin deformers (skeletons + vertex weights) */
@@ -12140,6 +13257,12 @@ declare namespace BABYLON {
12140
13257
  lights: FBXLightData[];
12141
13258
  /** Scene-level unsupported feature diagnostics */
12142
13259
  diagnostics: FBXSceneDiagnostic[];
13260
+ /** Constraints (aim, parent, position, rotation, scale, IK) */
13261
+ constraints: FBXConstraintData[];
13262
+ /** Display layers */
13263
+ displayLayers: FBXDisplayLayerData[];
13264
+ /** Selection sets */
13265
+ selectionSets: FBXSelectionSetData[];
12143
13266
  /** Global settings */
12144
13267
  upAxis: number;
12145
13268
  upAxisSign: number;
@@ -12148,11 +13271,89 @@ declare namespace BABYLON {
12148
13271
  coordAxis: number;
12149
13272
  coordAxisSign: number;
12150
13273
  unitScaleFactor: number;
13274
+ /** Scene frame rate derived from GlobalSettings TimeMode / CustomFrameRate */
13275
+ frameRate: number;
12151
13276
  }
12152
13277
  /**
12153
13278
  * Interpret a parsed FBX document into scene data.
12154
13279
  */
12155
- export function interpretFBX(doc: FBXDocument): FBXSceneData;
13280
+ /** Options controlling how the document is interpreted. */
13281
+ export interface FBXInterpretOptions {
13282
+ /** Segments per knot span when tessellating NURBS surfaces; defaults to the Step stored in the file */
13283
+ nurbsSubdivision?: number;
13284
+ /** Shift every clip so its first key sits at time 0 (default true); false keeps the authored times */
13285
+ rebaseKeyframes?: boolean;
13286
+ }
13287
+ export function interpretFBX(doc: FBXDocument, options?: FBXInterpretOptions): FBXSceneData;
13288
+
13289
+
13290
+ export type FBXConstraintType = "aim" | "parent" | "position" | "rotation" | "scale" | "singleChainIK" | "unknown";
13291
+ export type Vec3 = [number, number, number];
13292
+ export type Bool3 = [boolean, boolean, boolean];
13293
+ /** One weighted target of a constraint. */
13294
+ export interface FBXConstraintTarget {
13295
+ /** Model id of the target node */
13296
+ modelId: number;
13297
+ /** Normalized weight (file value / 100, or as-is for IK pole targets) */
13298
+ weight: number;
13299
+ /** Parent constraint translation offset expressed in the target's space */
13300
+ offsetTranslation: Vec3;
13301
+ /** Parent constraint rotation offset in degrees, expressed in the target's space */
13302
+ offsetRotation: Vec3;
13303
+ /** Parent constraint scale offset expressed in the target's space */
13304
+ offsetScale: Vec3;
13305
+ }
13306
+ /** A constraint object of the file, with its targets and parameters resolved. */
13307
+ export interface FBXConstraintData {
13308
+ /** Constraint object id */
13309
+ id: number;
13310
+ /** Constraint name */
13311
+ name: string;
13312
+ /** Resolved constraint kind */
13313
+ type: FBXConstraintType;
13314
+ /** Constraint type name as written in the file (e.g. "Parent-Child") */
13315
+ typeName: string;
13316
+ /** Constrained model */
13317
+ nodeId?: number;
13318
+ /** Weighted targets in file order */
13319
+ targets: FBXConstraintTarget[];
13320
+ /** Global weight (file value / 100) */
13321
+ weight: number;
13322
+ /** False when the constraint is switched off in the file */
13323
+ active: boolean;
13324
+ /** Which translation axes the constraint drives */
13325
+ affectTranslation: Bool3;
13326
+ /** Which rotation axes the constraint drives */
13327
+ affectRotation: Bool3;
13328
+ /** Which scale axes the constraint drives */
13329
+ affectScale: Bool3;
13330
+ /** Translation offset of the constrained node */
13331
+ offsetTranslation: Vec3;
13332
+ /** Rotation offset of the constrained node, in degrees */
13333
+ offsetRotation: Vec3;
13334
+ /** Scale offset of the constrained node */
13335
+ offsetScale: Vec3;
13336
+ /** Aim: local axis that points at the target */
13337
+ aimVector: Vec3;
13338
+ /** Aim: local axis aligned with the up direction */
13339
+ upVector: Vec3;
13340
+ /** Aim: world up direction (world up modes 2 and 3) */
13341
+ worldUpVector: Vec3;
13342
+ /** Aim: 0 scene up, 1 aim up node, 2 align to node, 3 vector, 4 none */
13343
+ worldUpType: number;
13344
+ /** Aim: model id of the world up object (world up modes 1 and 2) */
13345
+ worldUpNodeId?: number;
13346
+ /** Single chain IK: model id of the first joint of the chain */
13347
+ ikFirstJointId?: number;
13348
+ /** Single chain IK: model id of the last joint of the chain */
13349
+ ikEndJointId?: number;
13350
+ /** Single chain IK: model id of the effector */
13351
+ ikEffectorId?: number;
13352
+ /** Single chain IK: pole vector */
13353
+ ikPoleVector: Vec3;
13354
+ }
13355
+ /** Reads every constraint object of the scene. */
13356
+ export function extractConstraints(objectMap: FBXObjectMap): FBXConstraintData[];
12156
13357
 
12157
13358
 
12158
13359
  /** Connection type: OO = object-to-object, OP = object-to-property */
@@ -12175,7 +13376,7 @@ declare namespace BABYLON {
12175
13376
  /** Object node. */
12176
13377
  node: FBXNode;
12177
13378
  /** Source of the object entry. */
12178
- source: "Objects" | "legacySyntheticGeometry";
13379
+ source: "Objects" | "legacySyntheticGeometry" | "legacySyntheticAttribute" | "legacySyntheticBlendShape";
12179
13380
  /** Legacy string object name, when applicable. */
12180
13381
  legacyName?: string;
12181
13382
  /** True if the object was synthesized for legacy compatibility. */
@@ -12296,7 +13497,23 @@ declare namespace BABYLON {
12296
13497
  export function extractBlendShapes(objectMap: FBXObjectMap): FBXBlendShapeData[];
12297
13498
 
12298
13499
 
13500
+ /**
13501
+ * FBX animation curve model and evaluator.
13502
+ *
13503
+ * Keys carry cubic Bezier tangents expressed the way the FBX SDK stores them: a left and right tangent with a time
13504
+ * extent (dx, as a fraction of the segment scaled by the tangent weight) and a value extent (dy). Linear and constant
13505
+ * segments are represented the same way so that a single evaluator handles every case, including the weighted
13506
+ * tangents Maya and MotionBuilder write, TCB keys, and the pre/post extrapolation modes.
13507
+ */
13508
+ /** FBX time units: 46186158000 ticks per second */
13509
+ export const FBX_TIME_UNIT = 46186158000;
12299
13510
  export type FBXInterpolationType = "constant" | "linear" | "cubic";
13511
+ export type FBXExtrapolationMode = "constant" | "repeat" | "mirror" | "slope" | "repeatRelative";
13512
+ export interface FBXExtrapolation {
13513
+ mode: FBXExtrapolationMode;
13514
+ /** Number of repetitions, or -1 for infinite */
13515
+ repeatCount: number;
13516
+ }
12300
13517
  /** A single keyframe */
12301
13518
  export interface FBXKeyframe {
12302
13519
  /** Time in seconds */
@@ -12307,9 +13524,15 @@ declare namespace BABYLON {
12307
13524
  interpolation: FBXInterpolationType;
12308
13525
  /** Constant interpolation variant */
12309
13526
  constantMode?: "standard" | "next";
12310
- /** Cubic outgoing slope in value units per second */
13527
+ /** Left (incoming) tangent: time extent in seconds and value extent */
13528
+ leftDx: number;
13529
+ leftDy: number;
13530
+ /** Right (outgoing) tangent: time extent in seconds and value extent */
13531
+ rightDx: number;
13532
+ rightDy: number;
13533
+ /** Cubic outgoing slope in value units per second (derived, kept for consumers that export hermite keys) */
12311
13534
  rightSlope?: number;
12312
- /** Cubic incoming slope for the next key, in value units per second */
13535
+ /** Cubic incoming slope for the next key, in value units per second (derived) */
12313
13536
  nextLeftSlope?: number;
12314
13537
  }
12315
13538
  /** An animation curve (one axis of one property) */
@@ -12320,7 +13543,53 @@ declare namespace BABYLON {
12320
13543
  keys: FBXKeyframe[];
12321
13544
  /** True for baked sample curves that should be connected as linear samples */
12322
13545
  isSampled?: boolean;
13546
+ preExtrapolation?: FBXExtrapolation;
13547
+ postExtrapolation?: FBXExtrapolation;
13548
+ }
13549
+ /** Raw key attribute data for one key, after run-length decoding. */
13550
+ export interface FBXKeyAttributes {
13551
+ flags: number;
13552
+ data: [number, number, number, number];
13553
+ }
13554
+ /**
13555
+ * Builds keyframes from parallel time/value arrays and their (run-length encoded) attributes, resolving every
13556
+ * tangent mode the FBX SDK writes: user, broken, auto (with clamp / progressive clamp / time-independent flags and
13557
+ * auto bias), TCB, weighted, linear and constant.
13558
+ */
13559
+ export function buildKeyframes(times: ArrayLike<number>, values: ArrayLike<number>, attributes: (index: number) => FBXKeyAttributes): FBXKeyframe[];
13560
+ /** Auto tangent as the FBX SDK computes it, including clamping and auto bias. */
13561
+ export function solveAutoTangent(prevTime: number, time: number, nextTime: number, prevValue: number, value: number, nextValue: number, weightLeft: number, weightRight: number, autoBias: number, flags: number): number;
13562
+ /** Builds a keyframe list from explicit per-key slopes (legacy Takes and synthetic curves). */
13563
+ export function keyframesFromSlopes(times: number[], values: number[], interpolation: FBXInterpolationType[], constantNext: boolean[], leftSlope: number[], rightSlope: number[], leftWeight?: number[], rightWeight?: number[]): FBXKeyframe[];
13564
+ /** Reads a `Pre-Extrapolation` / `Post-Extrapolation` block: `Type` is a character code, `Repetition` a count. */
13565
+ export function parseExtrapolation(typeValue: unknown, repetitionValue: unknown): FBXExtrapolation;
13566
+ export function evaluateCurve(curve: FBXCurveData | undefined, time: number, defaultValue: number, noExtrapolation?: boolean): number;
13567
+ export type Vec3 = [number, number, number];
13568
+ export type Quat = [number, number, number, number];
13569
+ /** Euler angles in degrees with an FBX rotation order (0=XYZ ... 5=ZYX; spheric falls back to XYZ) to a quaternion. */
13570
+ export function eulerToQuat(v: Vec3, order: number): Quat;
13571
+ /** Quaternion to Euler angles in degrees for an FBX rotation order (inverse of eulerToQuat). */
13572
+ export function quatToEuler(q: Quat, order: number): Vec3;
13573
+ /** Blend semantics of an animation layer, derived from its BlendMode and accumulation modes. */
13574
+ export interface FBXLayerBlend {
13575
+ /** Layer participates in blending (BlendMode Additive or Override Passthrough) */
13576
+ blended: boolean;
13577
+ /** Layer adds onto the result instead of replacing it (BlendMode Additive) */
13578
+ additive: boolean;
13579
+ /** Rotations compose as quaternions (RotationAccumulationMode ByLayer) */
13580
+ composeRotation: boolean;
13581
+ /** Scales compose multiplicatively (ScaleAccumulationMode Multiply) */
13582
+ composeScale: boolean;
13583
+ /** Layer weight in [0, 1] */
13584
+ weight: number;
12323
13585
  }
13586
+ /**
13587
+ * Combines one animation layer's value into the running result, exactly as the FBX SDK evaluator does.
13588
+ * `kind` selects the accumulation rule: "R" rotations (degrees, rotation order given), "S" scales, anything else linear.
13589
+ */
13590
+ export function combineLayerValue(result: Vec3, value: Vec3, layer: FBXLayerBlend, kind: "T" | "R" | "S" | "other", rotationOrder: number): Vec3;
13591
+
13592
+
12324
13593
  /** An animation curve node (T/R/S for one bone) */
12325
13594
  export interface FBXCurveNodeData {
12326
13595
  /** Property type: "T" (translation), "R" (rotation), "S" (scale) */
@@ -12329,13 +13598,19 @@ declare namespace BABYLON {
12329
13598
  targetModelId: number;
12330
13599
  /** Curves for each axis */
12331
13600
  curves: FBXCurveData[];
13601
+ /** Index of the owning layer within the stack's layer list */
13602
+ layerIndex: number;
13603
+ /** Default channel values (`d|X`, `d|Y`, `d|Z`) used for channels without a curve */
13604
+ defaultValues?: [number, number, number];
12332
13605
  }
12333
- /** Unsupported animation curve node preserved for diagnostics and future support. */
13606
+ /** Non-transform animation curve node (property animation), evaluated by the loader when a Babylon mapping exists. */
12334
13607
  export interface FBXUnsupportedCurveNodeData {
12335
13608
  /** Raw AnimationCurveNode property type/name */
12336
13609
  type: string;
12337
13610
  /** CurveNode object ID */
12338
13611
  id: number;
13612
+ /** Index of the owning layer within the stack's layer list */
13613
+ layerIndex: number;
12339
13614
  /** Target object ID if the curve node is connected to an object/property */
12340
13615
  targetId: number | null;
12341
13616
  /** OP connection property name on the target, e.g. Visibility */
@@ -12374,6 +13649,10 @@ declare namespace BABYLON {
12374
13649
  normalizedWeight: number;
12375
13650
  /** Blend mode: 0=Additive, 1=Override, 2=OverridePassthrough */
12376
13651
  blendMode: number;
13652
+ /** Resolved blend semantics used by the evaluator */
13653
+ blend: FBXLayerBlend;
13654
+ /** Animated layer weight (0-100), when the Weight property carries a curve */
13655
+ weightCurve?: FBXCurveData;
12377
13656
  /** Curve nodes in this layer */
12378
13657
  curveNodes: FBXCurveNodeData[];
12379
13658
  /** Unsupported/non-TRS curve nodes preserved for diagnostics */
@@ -12381,6 +13660,14 @@ declare namespace BABYLON {
12381
13660
  /** Recoverable layer diagnostics */
12382
13661
  diagnostics: FBXAnimationDiagnostic[];
12383
13662
  }
13663
+ /** Options for animation extraction. */
13664
+ export interface FBXAnimationExtractOptions {
13665
+ /**
13666
+ * Shift each clip so its first key sits at time 0 (default true). False keeps the times authored in the file, so
13667
+ * clips of one file stay aligned with each other and with the declared stack range.
13668
+ */
13669
+ rebaseKeyframes?: boolean;
13670
+ }
12384
13671
  /** One animation clip (AnimationStack) */
12385
13672
  export interface FBXAnimationStackData {
12386
13673
  /** Animation name */
@@ -12403,13 +13690,7 @@ declare namespace BABYLON {
12403
13690
  /**
12404
13691
  * Extract all animation stacks from the FBX scene.
12405
13692
  */
12406
- export function extractAnimations(objectMap: FBXObjectMap): FBXAnimationStackData[];
12407
- /**
12408
- * Determines whether a key sequence appears to be a uniformly frame-baked sampled curve.
12409
- * @param keys - Keyframes to inspect
12410
- * @returns true if the keys look like sampled frame data rather than authored interpolation
12411
- */
12412
- export function isFrameBakedSampledCurve(keys: readonly FBXKeyframe[]): boolean;
13693
+ export function extractAnimations(objectMap: FBXObjectMap, doc?: FBXDocument, options?: FBXAnimationExtractOptions): FBXAnimationStackData[];
12413
13694
  /**
12414
13695
  * Samples an FBX animation curve at a specific time.
12415
13696
  * @param curveData - Curve data to sample
@@ -12417,6 +13698,54 @@ declare namespace BABYLON {
12417
13698
  * @returns The sampled value, or null when the curve has no keys
12418
13699
  */
12419
13700
  export function sampleFBXCurveAtTime(curveData: FBXCurveData | undefined, time: number): number | null;
13701
+ /**
13702
+ * Pre-7000 files store animation in a top-level `Takes` block instead of AnimationStack/Layer/CurveNode objects:
13703
+ *
13704
+ * Takes: { Take: "name" { LocalTime: start, stop
13705
+ * Model: "Model::joint1" { Channel: "Transform" { Channel: "T" { Channel: "X" { Default, KeyVer, KeyCount, Key } } } } } }
13706
+ *
13707
+ * Each take becomes one animation stack with a single layer. Models are matched through the same legacy string ids
13708
+ * that the connection resolver synthesizes for 6.x objects.
13709
+ */
13710
+ export function extractLegacyTakes(doc: FBXDocument, objectMap: FBXObjectMap, rebaseKeyframes?: boolean): FBXAnimationStackData[];
13711
+ /**
13712
+ * Evaluates one transform channel (T, R or S) of a target at `time`, blending every animation layer of the stack the
13713
+ * way the FBX SDK does: the first layer animating the channel replaces the static value, later layers are combined
13714
+ * according to their blend mode, weight and accumulation modes.
13715
+ * @param curveNodes - Curve nodes targeting this model (any layers, any types)
13716
+ * @param layers - Stack layers, in order
13717
+ * @param type - Channel to evaluate
13718
+ * @param staticValue - Value when nothing animates the channel
13719
+ * @param rotationOrder - Rotation order of the target (for rotation composition)
13720
+ * @param time - Time in seconds
13721
+ */
13722
+ export function evaluateLayeredChannel(curveNodes: readonly FBXCurveNodeData[], layers: readonly FBXAnimationLayerData[], type: "T" | "R" | "S", staticValue: readonly [number, number, number], rotationOrder: number, time: number): [number, number, number];
13723
+ /** Curves of one animated property (or blend shape weight) contributed by one animation layer. */
13724
+ export interface FBXLayeredPropertySource {
13725
+ /** Index of the owning layer within the stack's layer list */
13726
+ layerIndex: number;
13727
+ /** Curves of the property, keyed by channel name (`d|X`, `d|DeformPercent`, ...) */
13728
+ curves: readonly FBXCurveData[];
13729
+ /** Default channel values stored on the curve node */
13730
+ defaultValues?: Record<string, number>;
13731
+ }
13732
+ /**
13733
+ * Evaluates an animated property through the animation layers: the base layer replaces the static value, every
13734
+ * further layer blends onto the running result according to its blend mode and (possibly animated) weight, like
13735
+ * `evaluateLayeredChannel` does for transforms.
13736
+ * @param sources - Per-layer curves of the property
13737
+ * @param layers - Stack layers, in order
13738
+ * @param channels - Channel names to evaluate, in output order
13739
+ * @param staticValue - Value per channel when nothing animates it
13740
+ * @param time - Time in seconds
13741
+ * @returns One value per channel
13742
+ */
13743
+ export function evaluateLayeredProperty(sources: readonly FBXLayeredPropertySource[], layers: readonly FBXAnimationLayerData[], channels: readonly string[], staticValue: readonly number[], time: number): number[];
13744
+ /**
13745
+ * True when every curve of the given channel is inside a constant (stepped) segment at `time`, so a baked key at
13746
+ * that time should hold its value instead of interpolating towards the next sample.
13747
+ */
13748
+ export function isChannelSteppedAt(curveNodes: readonly FBXCurveNodeData[], type: "T" | "R" | "S", time: number): boolean;
12420
13749
 
12421
13750
 
12422
13751
  /** Pure barrel — re-exports only side-effect-free modules */