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.
@@ -7,6 +7,7 @@ export * from "babylonjs-loaders/glTF/pure";
7
7
  export * from "babylonjs-loaders/OBJ/pure";
8
8
  export * from "babylonjs-loaders/STL/pure";
9
9
  export * from "babylonjs-loaders/SPLAT/pure";
10
+ export * from "babylonjs-loaders/USD/pure";
10
11
  export * from "babylonjs-loaders/dynamic";
11
12
 
12
13
  }
@@ -17,6 +18,7 @@ export * from "babylonjs-loaders/glTF/index";
17
18
  export * from "babylonjs-loaders/OBJ/index";
18
19
  export * from "babylonjs-loaders/STL/index";
19
20
  export * from "babylonjs-loaders/SPLAT/index";
21
+ export * from "babylonjs-loaders/USD/index";
20
22
  export * from "babylonjs-loaders/dynamic";
21
23
 
22
24
  }
@@ -8731,6 +8733,452 @@ declare module "babylonjs-loaders/glTF/1.0/glTFBinaryExtension" {
8731
8733
  export * from "babylonjs-loaders/glTF/1.0/glTFBinaryExtension.pure";
8732
8734
  import "babylonjs-loaders/glTF/1.0/glTFLoader";
8733
8735
 
8736
+ }
8737
+ declare module "babylonjs-loaders/USD/usdWorkerMessages" {
8738
+ import { USDLoadProgress } from "babylonjs-loaders/USD/usdLoadingOptions";
8739
+ export interface WorkerAsset {
8740
+ bytes: Uint8Array;
8741
+ fileName: string;
8742
+ files?: Record<string, Uint8Array>;
8743
+ resolveByFileName: boolean;
8744
+ glueUrl?: string;
8745
+ wasmUrl?: string;
8746
+ dataUrl?: string;
8747
+ }
8748
+ export interface ExtractRequest {
8749
+ type: "extract";
8750
+ requestId: number;
8751
+ asset: WorkerAsset;
8752
+ }
8753
+ export interface WorkerTimings {
8754
+ totalMs: number;
8755
+ stageOpenMs: number;
8756
+ stageReadMs: number;
8757
+ preparationMs: number;
8758
+ packingMs: number;
8759
+ heapCopyMs: number;
8760
+ }
8761
+ export interface WorkerStatistics {
8762
+ nodes: number;
8763
+ meshes: number;
8764
+ analyticPrimitives: number;
8765
+ instances: number;
8766
+ materials: number;
8767
+ vertices: number;
8768
+ triangles: number;
8769
+ commandBytes: number;
8770
+ dataBytes: number;
8771
+ }
8772
+ export type WorkerResponse = {
8773
+ type: "progress";
8774
+ requestId: number;
8775
+ progress: USDLoadProgress;
8776
+ } | {
8777
+ type: "log";
8778
+ requestId: number;
8779
+ level: number;
8780
+ message: string;
8781
+ } | {
8782
+ type: "result";
8783
+ requestId: number;
8784
+ commands: ArrayBuffer;
8785
+ data: ArrayBuffer;
8786
+ timings: WorkerTimings;
8787
+ statistics: WorkerStatistics;
8788
+ missingAssets: string[];
8789
+ } | {
8790
+ type: "error";
8791
+ requestId: number;
8792
+ message: string;
8793
+ stack?: string;
8794
+ };
8795
+
8796
+ }
8797
+ declare module "babylonjs-loaders/USD/usdSceneMaterializer" {
8798
+ import { AbstractAssetContainer } from "babylonjs/assetContainer";
8799
+ import { Scene } from "babylonjs/scene.pure";
8800
+ export interface MaterializationResult {
8801
+ container: AbstractAssetContainer & {
8802
+ dispose(): void;
8803
+ };
8804
+ materializeMs: number;
8805
+ }
8806
+ export function materializeCommandBuffers(scene: Scene, commandBuffer: ArrayBuffer, dataBuffer: ArrayBuffer, addToScene: boolean, signal?: AbortSignal): Promise<MaterializationResult>;
8807
+
8808
+ }
8809
+ declare module "babylonjs-loaders/USD/usdLoadingOptions" {
8810
+ /**
8811
+ * Binary input accepted for supporting USD layers and assets.
8812
+ */
8813
+ export type USDBinaryInput = ArrayBuffer | ArrayBufferView;
8814
+ /**
8815
+ * Virtual files supplied alongside the root USD layer, keyed by their path relative to the
8816
+ * root layer.
8817
+ */
8818
+ export type USDVirtualFiles = Readonly<Record<string, USDBinaryInput>>;
8819
+ /**
8820
+ * Progress phases reported by the USD worker and Babylon materializer.
8821
+ */
8822
+ export interface USDLoadProgress {
8823
+ /**
8824
+ * Current importer phase.
8825
+ */
8826
+ phase: "initializing" | "staging" | "extracting" | "materializing";
8827
+ /**
8828
+ * Human-readable phase description.
8829
+ */
8830
+ message: string;
8831
+ }
8832
+ /**
8833
+ * Options for the OpenUSD scene loader.
8834
+ */
8835
+ export interface USDFileLoaderOptions {
8836
+ /**
8837
+ * Virtual path used to stage the root layer. Set this when supporting files need
8838
+ * to resolve relative to a directory hierarchy.
8839
+ */
8840
+ rootFileName?: string;
8841
+ /**
8842
+ * Supporting layers, payloads, and textures keyed by virtual path in the same
8843
+ * virtual file system as `rootFileName`.
8844
+ */
8845
+ files?: USDVirtualFiles;
8846
+ /**
8847
+ * Enables conservative file-name fallback for unresolved absolute references.
8848
+ * Defaults to true.
8849
+ */
8850
+ resolveByFileName?: boolean;
8851
+ /**
8852
+ * URL of the module worker. Defaults to the protocol-versioned worker hosted on the Babylon.js CDN.
8853
+ */
8854
+ workerUrl?: string | URL;
8855
+ /**
8856
+ * URL of the generated Emscripten JavaScript module.
8857
+ */
8858
+ glueUrl?: string;
8859
+ /**
8860
+ * URL of the OpenUSD WebAssembly binary.
8861
+ */
8862
+ wasmUrl?: string;
8863
+ /**
8864
+ * URL of the OpenUSD preloaded resource bundle.
8865
+ */
8866
+ dataUrl?: string;
8867
+ /**
8868
+ * Called when the importer moves to a new processing phase.
8869
+ */
8870
+ onProgress?: (progress: USDLoadProgress) => void;
8871
+ /**
8872
+ * Called for OpenUSD diagnostic messages.
8873
+ */
8874
+ onLog?: (level: "info" | "warning" | "error", message: string) => void;
8875
+ /**
8876
+ * Called after extraction and Babylon.js object creation complete.
8877
+ */
8878
+ onComplete?: (diagnostics: USDImportDiagnostics) => void;
8879
+ }
8880
+ /**
8881
+ * Timing data measured by the OpenUSD worker and Babylon materializer.
8882
+ */
8883
+ export interface USDImportTimings {
8884
+ /** Total extraction time, including the final Wasm heap copy. */
8885
+ totalMs: number;
8886
+ /** Time spent opening and composing the USD stage. */
8887
+ stageOpenMs: number;
8888
+ /** Time spent traversing the composed stage. */
8889
+ stageReadMs: number;
8890
+ /** Time spent preparing renderable vertex streams. */
8891
+ preparationMs: number;
8892
+ /** Time spent packing the command and raw-data buffers. */
8893
+ packingMs: number;
8894
+ /** Time spent copying command and data buffers from the Wasm heap. */
8895
+ heapCopyMs: number;
8896
+ /** Time spent creating Babylon.js objects. */
8897
+ materializeMs: number;
8898
+ }
8899
+ /**
8900
+ * Statistics reported for an imported USD stage.
8901
+ */
8902
+ export interface USDImportStatistics {
8903
+ /** Number of transform nodes extracted from the composed stage. */
8904
+ nodes: number;
8905
+ /** Number of polygonal `UsdGeomMesh` sources. */
8906
+ meshes: number;
8907
+ /** Number of analytic cube, sphere, cylinder, and cone sources. */
8908
+ analyticPrimitives: number;
8909
+ /** Number of native Babylon instances created from shared USD geometry. */
8910
+ instances: number;
8911
+ /** Number of authored USD materials translated. */
8912
+ materials: number;
8913
+ /** Number of unique vertices in polygonal source meshes. */
8914
+ vertices: number;
8915
+ /** Number of unique triangles in polygonal source meshes. */
8916
+ triangles: number;
8917
+ /** Size of the command buffer in bytes. */
8918
+ commandBytes: number;
8919
+ /** Size of the raw-data buffer in bytes. */
8920
+ dataBytes: number;
8921
+ }
8922
+ /**
8923
+ * Diagnostics reported after a USD import completes.
8924
+ */
8925
+ export interface USDImportDiagnostics {
8926
+ /** Timing data for extraction and Babylon.js object creation. */
8927
+ timings: USDImportTimings;
8928
+ /** Counts and buffer sizes reported by the OpenUSD extractor. */
8929
+ statistics: USDImportStatistics;
8930
+ /** Asset references OpenUSD could not resolve from the supplied virtual files. */
8931
+ missingAssets: readonly string[];
8932
+ }
8933
+
8934
+ }
8935
+ declare module "babylonjs-loaders/USD/usdFileLoader.types" {
8936
+ export {};
8937
+ import { USDFileLoaderMetadata } from "babylonjs-loaders/USD/usdFileLoader.metadata";
8938
+ import { USDFileLoaderOptions } from "babylonjs-loaders/USD/usdLoadingOptions";
8939
+ module "babylonjs/Loading/sceneLoader" {
8940
+ interface SceneLoaderPluginOptions {
8941
+ /**
8942
+ * Defines options for the USD loader.
8943
+ */
8944
+ [USDFileLoaderMetadata.name]: Partial<USDFileLoaderOptions>;
8945
+ }
8946
+ }
8947
+
8948
+ }
8949
+ declare module "babylonjs-loaders/USD/usdFileLoader.pure" {
8950
+ /** This file must only contain pure code and pure imports */
8951
+ import { AssetContainer } from "babylonjs/assetContainer";
8952
+ import { ISceneLoaderAsyncResult, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory, ISceneLoaderProgressEvent, SceneLoaderPluginOptions } from "babylonjs/Loading/sceneLoader";
8953
+ import { Scene } from "babylonjs/scene.pure";
8954
+ import { USDFileLoaderOptions } from "babylonjs-loaders/USD/usdLoadingOptions";
8955
+ /**
8956
+ * OpenUSD scene loader backed by a WebAssembly command-buffer extractor.
8957
+ */
8958
+ export class USDFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
8959
+ /**
8960
+ * Default URLs for the prebuilt OpenUSD importer assets.
8961
+ */
8962
+ static DefaultConfiguration: {
8963
+ glueUrl: string;
8964
+ wasmUrl: string;
8965
+ dataUrl: string;
8966
+ workerUrl: string;
8967
+ };
8968
+ /**
8969
+ * Defines the name of the plugin.
8970
+ */
8971
+ readonly name: "usd";
8972
+ /**
8973
+ * Defines the extensions the plugin can load.
8974
+ */
8975
+ readonly extensions: {
8976
+ readonly ".usd": {
8977
+ readonly isBinary: true;
8978
+ };
8979
+ readonly ".usda": {
8980
+ readonly isBinary: true;
8981
+ };
8982
+ readonly ".usdc": {
8983
+ readonly isBinary: true;
8984
+ };
8985
+ readonly ".usdz": {
8986
+ readonly isBinary: true;
8987
+ };
8988
+ };
8989
+ private readonly _options;
8990
+ private _worker;
8991
+ private _workerUrl;
8992
+ private _workerBlobUrl;
8993
+ private _nextRequestId;
8994
+ private readonly _pending;
8995
+ private readonly _activeLoads;
8996
+ /**
8997
+ * Creates a USD loader.
8998
+ * @param options Options controlling worker assets, supporting files, and diagnostics.
8999
+ */
9000
+ constructor(options?: Partial<USDFileLoaderOptions>);
9001
+ /**
9002
+ * Creates a configured plugin instance for a SceneLoader operation.
9003
+ * @param options SceneLoader plugin options.
9004
+ * @returns The configured USD loader.
9005
+ */
9006
+ createPlugin(options: SceneLoaderPluginOptions): ISceneLoaderPluginAsync;
9007
+ /**
9008
+ * Imports all objects from a USD stage into a scene.
9009
+ * @param _meshesNames Mesh name filtering is not currently supported.
9010
+ * @param scene The scene receiving the imported objects.
9011
+ * @param data The USD, USDA, USDC, or USDZ bytes.
9012
+ * @param rootUrl The source root URL.
9013
+ * @param onProgress SceneLoader progress callback.
9014
+ * @param fileName Name of the root USD layer.
9015
+ * @returns The imported Babylon.js objects.
9016
+ */
9017
+ importMeshAsync(_meshesNames: string | readonly string[] | null | undefined, scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<ISceneLoaderAsyncResult>;
9018
+ /**
9019
+ * Loads a USD stage into a scene.
9020
+ * @param scene The scene receiving the imported objects.
9021
+ * @param data The USD, USDA, USDC, or USDZ bytes.
9022
+ * @param rootUrl The source root URL.
9023
+ * @param onProgress SceneLoader progress callback.
9024
+ * @param fileName Name of the root USD layer.
9025
+ */
9026
+ loadAsync(scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<void>;
9027
+ /**
9028
+ * Loads a USD stage into an asset container.
9029
+ * @param scene The scene used to create imported objects.
9030
+ * @param data The USD, USDA, USDC, or USDZ bytes.
9031
+ * @param rootUrl The source root URL.
9032
+ * @param onProgress SceneLoader progress callback.
9033
+ * @param fileName Name of the root USD layer.
9034
+ * @returns The populated asset container.
9035
+ */
9036
+ loadAssetContainerAsync(scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<AssetContainer>;
9037
+ /**
9038
+ * Releases the worker and rejects pending loads.
9039
+ */
9040
+ dispose(): void;
9041
+ private _loadAsync;
9042
+ private _getWorker;
9043
+ private _terminateWorker;
9044
+ }
9045
+ /** @internal */
9046
+ export function _RegisterUSDLoaderDependencies(): void;
9047
+ /**
9048
+ * Registers the USD scene loader plugin and its Babylon.js runtime dependencies.
9049
+ * Safe to call multiple times; only the first call has an effect.
9050
+ */
9051
+ export function RegisterUSDFileLoader(): void;
9052
+
9053
+ }
9054
+ declare module "babylonjs-loaders/USD/usdFileLoader.metadata" {
9055
+ /**
9056
+ * Defines the USD loader plugin metadata.
9057
+ */
9058
+ export const USDFileLoaderMetadata: {
9059
+ readonly name: "usd";
9060
+ readonly extensions: {
9061
+ readonly ".usd": {
9062
+ readonly isBinary: true;
9063
+ };
9064
+ readonly ".usda": {
9065
+ readonly isBinary: true;
9066
+ };
9067
+ readonly ".usdc": {
9068
+ readonly isBinary: true;
9069
+ };
9070
+ readonly ".usdz": {
9071
+ readonly isBinary: true;
9072
+ };
9073
+ };
9074
+ };
9075
+
9076
+ }
9077
+ declare module "babylonjs-loaders/USD/usdFileLoader" {
9078
+ /**
9079
+ * Re-exports the pure implementation and applies the runtime registration side effect.
9080
+ * Import "./usdFileLoader.pure" for tree-shakeable, side-effect-free usage.
9081
+ */
9082
+ export * from "babylonjs-loaders/USD/usdFileLoader.types";
9083
+ export * from "babylonjs-loaders/USD/usdFileLoader.pure";
9084
+
9085
+ }
9086
+ declare module "babylonjs-loaders/USD/usdCommandProtocol" {
9087
+ export const COMMAND_MAGIC = 1111774037;
9088
+ export const PROTOCOL_VERSION = 5;
9089
+ export const MISSING_OFFSET = 4294967295;
9090
+ export enum Command {
9091
+ Scene = 1,
9092
+ Texture = 2,
9093
+ Material = 3,
9094
+ TransformNode = 4,
9095
+ Skeleton = 5,
9096
+ Geometry = 6,
9097
+ Mesh = 7,
9098
+ Instance = 8,
9099
+ Animation = 9,
9100
+ AnalyticPrimitive = 10,
9101
+ ThinInstances = 11,
9102
+ MorphTarget = 12
9103
+ }
9104
+ export enum AnalyticPrimitiveType {
9105
+ Cube = 0,
9106
+ Sphere = 1,
9107
+ Cylinder = 2,
9108
+ Cone = 3
9109
+ }
9110
+ export enum PrimitiveAxis {
9111
+ X = 0,
9112
+ Y = 1,
9113
+ Z = 2
9114
+ }
9115
+ export enum AnimationTarget {
9116
+ Node = 0,
9117
+ Bone = 1,
9118
+ MorphTarget = 2
9119
+ }
9120
+ export enum AnimationProperty {
9121
+ Position = 0,
9122
+ RotationQuaternion = 1,
9123
+ Scaling = 2,
9124
+ Matrix = 3,
9125
+ Influence = 4
9126
+ }
9127
+ export enum MaterialFlags {
9128
+ DoubleSided = 1,
9129
+ Unlit = 2,
9130
+ AlphaBlend = 4
9131
+ }
9132
+ export enum TextureOutputChannel {
9133
+ R = 0,
9134
+ G = 1,
9135
+ B = 2,
9136
+ A = 3,
9137
+ RGB = 4
9138
+ }
9139
+ export enum USDTextureColorSpace {
9140
+ Auto = 0,
9141
+ Raw = 1,
9142
+ SRGB = 2
9143
+ }
9144
+ export enum MeshFlags {
9145
+ DoubleSided = 1,
9146
+ LeftHanded = 2
9147
+ }
9148
+ export enum GeometryFlags {
9149
+ Normals = 1,
9150
+ Tangents = 2,
9151
+ Uv0 = 4,
9152
+ Colors = 8,
9153
+ Skin0 = 16,
9154
+ Skin1 = 32
9155
+ }
9156
+ export interface CommandRecord {
9157
+ opcode: Command;
9158
+ flags: number;
9159
+ payloadOffset: number;
9160
+ payloadLength: number;
9161
+ }
9162
+ export function readCommands(buffer: ArrayBuffer): CommandRecord[];
9163
+ export class PayloadReader {
9164
+ #private;
9165
+ offset: number;
9166
+ constructor(buffer: ArrayBuffer, offset: number, length: number);
9167
+ u32(): number;
9168
+ f32(): number;
9169
+ }
9170
+
9171
+ }
9172
+ declare module "babylonjs-loaders/USD/pure" {
9173
+ /** Pure barrel — re-exports only side-effect-free modules */
9174
+ export * from "babylonjs-loaders/USD/usdFileLoader.pure";
9175
+ export * from "babylonjs-loaders/USD/usdLoadingOptions";
9176
+
9177
+ }
9178
+ declare module "babylonjs-loaders/USD/index" {
9179
+ export * from "babylonjs-loaders/USD/usdFileLoader";
9180
+ export * from "babylonjs-loaders/USD/usdLoadingOptions";
9181
+
8734
9182
  }
8735
9183
  declare module "babylonjs-loaders/STL/stlFileLoader.types" {
8736
9184
  export {};
@@ -9776,6 +10224,18 @@ export interface ISOGLODMetadata {
9776
10224
  * Selects which LOD value drives the {@link GaussianSplattingStream} debug wireframe colors.
9777
10225
  */
9778
10226
  export type GaussianSplattingStreamDebugLodSource = "optimal" | "current";
10227
+ /**
10228
+ * Immutable metadata-resolution state for a stream's total number of finest-LOD splats.
10229
+ * @experimental
10230
+ */
10231
+ export type GaussianSplattingStreamLod0SplatCount = Readonly<{
10232
+ status: "pending";
10233
+ }> | Readonly<{
10234
+ status: "available";
10235
+ count: number;
10236
+ }> | Readonly<{
10237
+ status: "unavailable";
10238
+ }>;
9779
10239
  /**
9780
10240
  * Options for {@link GaussianSplattingStream}.
9781
10241
  */
@@ -9895,6 +10355,7 @@ export class GaussianSplattingStream extends GaussianSplattingMesh implements IG
9895
10355
  private readonly _rootUrl;
9896
10356
  private readonly _streamOptions;
9897
10357
  private readonly _leafNodes;
10358
+ private _lod0SplatCount;
9898
10359
  private _lodBaseDistance;
9899
10360
  private _lodMultiplier;
9900
10361
  private _lodBehindPenalty;
@@ -10059,6 +10520,19 @@ export class GaussianSplattingStream extends GaussianSplattingMesh implements IG
10059
10520
  * @experimental
10060
10521
  */
10061
10522
  get effectiveSplatBudget(): number;
10523
+ /**
10524
+ * The resolved maximum number of splats kept resident in the work buffer. This combines
10525
+ * {@link IGaussianSplattingStreamOptions.maxResidentSplats} and {@link IGaussianSplattingStreamOptions.memoryBudgetMb},
10526
+ * taking the smaller limit when both are configured. `0` means the resident budget is disabled.
10527
+ * @experimental
10528
+ */
10529
+ get residentSplatBudget(): number;
10530
+ /**
10531
+ * The total number of splats represented by valid level-0 leaf entries. This remains pending while source
10532
+ * metadata is loading and is unavailable when no applicable level-0 entries exist or required metadata fails.
10533
+ * @experimental
10534
+ */
10535
+ get lod0SplatCount(): GaussianSplattingStreamLod0SplatCount;
10062
10536
  /**
10063
10537
  * Resolves the raw {@link splatBudget} option to a concrete cap: `undefined` ⇒ 0 (disabled), `"auto"` ⇒ a
10064
10538
  * device-tiered default, a positive number ⇒ itself (floored).
@@ -10228,6 +10702,11 @@ export class GaussianSplattingStream extends GaussianSplattingMesh implements IG
10228
10702
  * @returns sorted unique file indices
10229
10703
  */
10230
10704
  private _collectAllFileIds;
10705
+ /**
10706
+ * Settles the level-0 diagnostic from normalized renderable leaf entries after their source metadata resolves.
10707
+ * A file may back several leaf ranges, so its source count is deliberately not used in the total.
10708
+ */
10709
+ private _resolveLod0SplatCount;
10231
10710
  /**
10232
10711
  * Fetches the environment bundle and every referenced file's metadata to learn splat counts, caching
10233
10712
  * each file's parsed metadata for the later on-demand decode. Metadata fetches run in parallel.
@@ -11413,12 +11892,16 @@ declare module "babylonjs-loaders/FBX/pure" {
11413
11892
  /** Pure barrel — re-exports only side-effect-free modules */
11414
11893
  export { FBXFileLoader } from "babylonjs-loaders/FBX/fbxFileLoader.pure";
11415
11894
  export { FBXFileLoaderMetadata } from "babylonjs-loaders/FBX/fbxFileLoader.metadata";
11895
+ export { FBXConstraintBehavior, FBXConstraintSolver } from "babylonjs-loaders/FBX/fbxConstraintBehavior";
11416
11896
 
11417
11897
  }
11418
11898
  declare module "babylonjs-loaders/FBX/index" {
11419
11899
  export { FBXFileLoader } from "babylonjs-loaders/FBX/fbxFileLoader";
11420
- export type { FBXFileLoaderOptions, FBXNormalMapCoordinateSystem } from "babylonjs-loaders/FBX/fbxFileLoader";
11900
+ export type { FBXFileLoaderOptions, FBXNormalMapCoordinateSystem, FBXLoaderWarning } from "babylonjs-loaders/FBX/fbxFileLoader";
11421
11901
  export { FBXFileLoaderMetadata } from "babylonjs-loaders/FBX/fbxFileLoader.metadata";
11902
+ export { FBXConstraintBehavior, FBXConstraintSolver } from "babylonjs-loaders/FBX/fbxConstraintBehavior";
11903
+ export type { FBXConstraintBehaviorOptions, FBXConstraintBehaviorTarget } from "babylonjs-loaders/FBX/fbxConstraintBehavior";
11904
+ export type { FBXConstraintData, FBXConstraintTarget, FBXConstraintType } from "babylonjs-loaders/FBX/interpreter/constraints";
11422
11905
 
11423
11906
  }
11424
11907
  declare module "babylonjs-loaders/FBX/fbxFileLoader.types" {
@@ -11447,12 +11930,83 @@ export type FBXNormalMapCoordinateSystem = "y-up" | "y-down";
11447
11930
  * Defines options for the FBX loader.
11448
11931
  */
11449
11932
  export interface FBXFileLoaderOptions {
11933
+ /**
11934
+ * Bundle of defaults for the options that change what the loaded scene looks like.
11935
+ * - "compatible" (default): the behaviour of the loader as first shipped: StandardMaterial for every material,
11936
+ * one Babylon geometry per model, curve geometry skipped, constraints recorded as metadata only, clips rebased
11937
+ * to start at frame 0, cameras and lights placed in world space.
11938
+ * - "full": everything the loader can do: PBRMaterial for physically based shaders, geometry shared between
11939
+ * instances, curves as lines meshes, constraints solved at runtime, authored clip times, cameras and lights
11940
+ * parented to their nodes so they animate.
11941
+ * An option set explicitly always wins over the preset.
11942
+ */
11943
+ preset?: "compatible" | "full";
11450
11944
  /**
11451
11945
  * Source convention for tangent-space normal maps connected through FBX normal-map slots.
11452
11946
  * FBX does not standardize this convention, so the loader defaults to the glTF/USD-style Y-up convention.
11453
11947
  * Set to "y-down" for assets authored with inverted green/Y normal maps.
11454
11948
  */
11455
11949
  normalMapCoordinateSystem?: FBXNormalMapCoordinateSystem;
11950
+ /**
11951
+ * Which Babylon material to build.
11952
+ * - "standard" (default, "full" preset: "auto"): always StandardMaterial (PBR parameters are approximated).
11953
+ * - "auto": PBRMaterial for physically based FBX materials (Standard Surface, Arnold, 3ds Max Physical,
11954
+ * 3ds Max PBR, glTF, OpenPBR, Stingray PBS) and StandardMaterial for classic Lambert/Phong materials.
11955
+ * - "pbr": always PBRMaterial (Lambert/Phong parameters are converted).
11956
+ */
11957
+ materials?: "auto" | "standard" | "pbr";
11958
+ /**
11959
+ * Unit conversion applied at the root of the loaded hierarchy.
11960
+ * - "preserve" (default): keep the file's units (1 Babylon unit = 1 FBX unit).
11961
+ * - "meters": scale so that 1 Babylon unit is 1 meter, using the file's UnitScaleFactor.
11962
+ * - a number: centimeters per Babylon unit (100 = meters, 1 = centimeters, 2.54 = inches).
11963
+ */
11964
+ unitScale?: "preserve" | "meters" | number;
11965
+ /**
11966
+ * Share vertex data between models that reference the same FBX geometry (default false, "full" preset: true).
11967
+ * Skinned meshes are never shared.
11968
+ */
11969
+ shareGeometry?: boolean;
11970
+ /**
11971
+ * Called for every recoverable issue found while loading (unsupported features, malformed data that was
11972
+ * skipped, approximations). The same list is stored on the root node's metadata as `fbxDiagnostics`.
11973
+ */
11974
+ onWarning?: (warning: FBXLoaderWarning) => void;
11975
+ /**
11976
+ * Segments per knot span when tessellating NURBS surfaces. Zero or undefined uses the subdivision stored in
11977
+ * the file (usually 4), capped at 16.
11978
+ */
11979
+ nurbsSubdivision?: number;
11980
+ /** How curve geometry (Line, NurbsCurve) is imported: skipped (default) or as lines meshes ("full" preset). */
11981
+ curves?: "lines" | "skip";
11982
+ /**
11983
+ * Constraints (aim, parent, position, rotation, scale): "metadata" (default) only records them on the nodes,
11984
+ * "apply" ("full" preset) attaches an `FBXConstraintBehavior` to each constrained node so it is solved before
11985
+ * every render. IK chains are always metadata only.
11986
+ */
11987
+ constraints?: "apply" | "metadata";
11988
+ /**
11989
+ * Shift every clip so its first keyframe sits at frame 0 (default true). With false ("full" preset) keys keep
11990
+ * the times authored in the file, so clips of one file stay aligned with each other and with their declared
11991
+ * ranges.
11992
+ */
11993
+ rebaseAnimations?: boolean;
11994
+ /**
11995
+ * Parent cameras and lights to their FBX node so they follow its animation (default false, "full" preset:
11996
+ * true). Otherwise they are created at the node's world position and orientation, unparented.
11997
+ */
11998
+ attachCamerasAndLights?: boolean;
11999
+ }
12000
+ /** A recoverable issue reported while loading an FBX file. */
12001
+ export interface FBXLoaderWarning {
12002
+ /** Which part of the loader reported the issue */
12003
+ source: "scene" | "model" | "geometry" | "skin" | "rig" | "animation" | "blendShape" | "camera" | "light";
12004
+ /** Human readable description */
12005
+ message: string;
12006
+ /** Name of the affected object, when known */
12007
+ objectName?: string;
12008
+ /** Structured details from the interpreter, when any */
12009
+ details?: unknown;
11456
12010
  }
11457
12011
  /**
11458
12012
  * FBX file loader plugin for Babylon.js.
@@ -11475,6 +12029,22 @@ export class FBXFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
11475
12029
  private readonly _bindRestBones;
11476
12030
  private readonly _sourceBonesBySkeleton;
11477
12031
  private readonly _scaleCompensationHelpersBySkeleton;
12032
+ /** Frame rate of the file being loaded (GlobalSettings TimeMode); animation is baked at this rate. */
12033
+ private _frameRate;
12034
+ /** Layers of the animation stack currently being converted; used by the transform samplers. */
12035
+ private _activeLayers;
12036
+ /** Parent model per model id, for inherit-mode aware sampling. */
12037
+ private _parentModelById;
12038
+ /** Curve nodes per model id for the stack currently being converted. */
12039
+ private _curveNodesByModelId;
12040
+ /** Helper nodes inserted above models whose InheritType is not RSrs. */
12041
+ private _inheritScaleHelpers;
12042
+ /** First mesh built per (geometry, geometric transform), for geometry sharing between instances. */
12043
+ private _meshByGeometryKey;
12044
+ /** Instance mesh -> source mesh whose geometry it shares. */
12045
+ private _instanceSource;
12046
+ /** Property curve nodes that were mapped onto Babylon animations; their "not evaluated" diagnostics are dropped. */
12047
+ private _evaluatedCurveNodeIds;
11478
12048
  /**
11479
12049
  * Creates a new FBX loader.
11480
12050
  * @param options - Options controlling FBX loading behavior
@@ -11517,6 +12087,11 @@ export class FBXFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
11517
12087
  * @returns A promise containing the loaded asset container
11518
12088
  */
11519
12089
  loadAssetContainerAsync(scene: Scene, data: unknown, rootUrl: string, _onProgress?: (event: ISceneLoaderProgressEvent) => void, _fileName?: string): Promise<AssetContainer>;
12090
+ /**
12091
+ * Parses and interprets the file. Parsing is synchronous, so no progress events are emitted: the scene loader's
12092
+ * progress callback reports download bytes and must not be fed synthetic counts.
12093
+ */
12094
+ private _parseAndInterpret;
11520
12095
  private _parse;
11521
12096
  private _parseFromArrayBuffer;
11522
12097
  private _buildScene;
@@ -11528,6 +12103,15 @@ export class FBXFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
11528
12103
  private _linkSkeletonsToTransformNodes;
11529
12104
  private static _modelSubtreeMatchesNameFilter;
11530
12105
  private static _applyModelMetadata;
12106
+ /**
12107
+ * Wires a LodGroup's children as Babylon LOD levels: the first child holds the highest detail; every further
12108
+ * child replaces it beyond the group's threshold distance (or screen coverage when thresholds are percentages).
12109
+ * Each child's display mode is honoured first: level 1 (show) stays visible outside the LOD chain, level 2
12110
+ * (hide) is disabled, and only level 0 (use LOD) children take part in the distance switching.
12111
+ */
12112
+ private static _applyLodGroup;
12113
+ /** Builds a lines mesh from Line or tessellated NurbsCurve geometry, applying the model's geometric transform. */
12114
+ private _createLinesMesh;
11531
12115
  private _createMesh;
11532
12116
  /**
11533
12117
  * Apply multi-material to a mesh by creating sub-meshes grouped by material index.
@@ -11551,6 +12135,11 @@ export class FBXFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
11551
12135
  */
11552
12136
  private _buildSkinningData;
11553
12137
  private _createMaterial;
12138
+ private _createPbrMaterial;
12139
+ /** Alpha of a classic Lambert/Phong material: Opacity when present, otherwise 1 - TransparentColor * TransparencyFactor. */
12140
+ private static _alphaFromClassicTransparency;
12141
+ private static _applyTextureSettings;
12142
+ private _createStandardMaterial;
11554
12143
  private _configureNormalTexture;
11555
12144
  private _getNormalMapTangentHandednessScale;
11556
12145
  private static _isSupportedMaterialTextureSlot;
@@ -11574,11 +12163,27 @@ export class FBXFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
11574
12163
  private _createCamera;
11575
12164
  private _createLight;
11576
12165
  private _createSkeleton;
12166
+ private _rigBoneModelIds;
12167
+ private _isRigBone;
11577
12168
  private _getSourceBone;
11578
12169
  private _getScaleCompensationHelper;
11579
12170
  private static _computeFBXAbsoluteMatrices;
12171
+ /**
12172
+ * Effective ("inherit") scale of every bone, following the FBX SDK: the local scale for RSrs bones, and for
12173
+ * RrSs / Rrs bones the local scale multiplied by the scale of the bone's inherit-scale node (the parent for RrSs,
12174
+ * the parent's inherit-scale node for Rrs). Bones are ordered parents first.
12175
+ */
12176
+ private static _computeBoneInheritScales;
12177
+ private static _getBoneInheritScaleNode;
12178
+ /** Scale a bone inherits into its own scale (RrSs chains), or unit scale. */
12179
+ private static _getBoneInheritedScale;
11580
12180
  private static _computeFBXRuntimeLocalMatrix;
11581
12181
  private static _applyParentScaleCompensation;
12182
+ /**
12183
+ * Splits a bone's FBX local matrix into a helper (which cancels the parent scale and carries the translation,
12184
+ * so the translation still follows the parent scale as the SDK does) and the bone's own rotation/scale. For RrSs
12185
+ * bones the inherited scale is folded into the bone scale.
12186
+ */
11582
12187
  private static _splitParentScaleCompensatedLocalMatrix;
11583
12188
  private static _safeInverseScale;
11584
12189
  private static _getInverseScaleVector;
@@ -11595,13 +12200,8 @@ export class FBXFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
11595
12200
  * In row-vector convention: v' = v * M
11596
12201
  */
11597
12202
  private static _computeFBXLocalMatrix;
11598
- /**
11599
- * Apply the FBX transform chain to a Babylon TransformNode or Mesh.
11600
- * Decomposes the full local matrix into position/rotation/scale.
11601
- */
11602
- private static _applyFBXTransform;
12203
+ private _applyRestTRS;
11603
12204
  private static _computeFBXModelLocalMatrix;
11604
- private static _getBoneReferenceWorldMatrix;
11605
12205
  private static _applyMatrixToTransform;
11606
12206
  private _createAnimationGroup;
11607
12207
  private _buildInheritedRigBoneAnimations;
@@ -11611,9 +12211,61 @@ export class FBXFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
11611
12211
  * Computes the full FBX transform matrix at each keyframe and decomposes into TRS.
11612
12212
  */
11613
12213
  private _buildNodeAnimations;
12214
+ /**
12215
+ * Baked keys are interpolated linearly by Babylon. Between two frames an FBX cubic segment can deviate from that
12216
+ * line, so sample times are refined (midpoints inserted, up to two levels) wherever the interpolated transform
12217
+ * differs noticeably from the curve. Flat and linear segments stay at frame resolution.
12218
+ */
12219
+ private static _refineSampleTimes;
12220
+ /**
12221
+ * Keys of a scalar property animated by one or more layers: the authored keys when a single layer drives it,
12222
+ * otherwise the frame grid evaluated through the layer stack.
12223
+ * @param sources - Per-layer curves of the property (each with at least one curve)
12224
+ * @param animStack - Stack being converted
12225
+ * @param mapValue - Conversion from the FBX value to the Babylon property value
12226
+ * @returns Animation keys
12227
+ */
12228
+ private _layeredScalarKeys;
12229
+ /**
12230
+ * Maps an animated FBX property (anything other than node transforms and blend shape weights) onto the Babylon
12231
+ * property that carries it: mesh visibility, camera field of view and clip planes, light intensity, colour and
12232
+ * cone angles, and material colours, alpha, roughness and metalness. `group` holds the curve nodes of every
12233
+ * layer animating that property, in layer order; several layers are evaluated through the layer stack.
12234
+ */
12235
+ private _buildPropertyAnimations;
12236
+ /** Records constraints on their nodes and, unless disabled, attaches the runtime behavior that solves them. */
12237
+ private _applyConstraints;
12238
+ /** Collects every recoverable issue the interpreter recorded, stores it on the root node and notifies the caller. */
12239
+ private _reportDiagnostics;
12240
+ /** Curve nodes affecting the inherit scale of a model: its own scale curves and those of its inherit-scale chain. */
12241
+ private _collectInheritScaleCurves;
11614
12242
  private _isVector3KeysConstant;
12243
+ /** Samples the animated Lcl Translation / Rotation / Scaling of a model, blending all layers of the active stack. */
12244
+ private _sampleModelTRS;
12245
+ /**
12246
+ * Local position/rotation/scale of a model from FBX Lcl values. Without pivots and offsets the components map
12247
+ * directly (rotation = pre * lcl * post⁻¹), which keeps zero and negative scales exact. With pivots the full
12248
+ * matrix is built and decomposed.
12249
+ */
12250
+ private static _computeLocalTRS;
12251
+ /** Applies inherit-mode adjustments to a local TRS (see _computeInheritAwareLocalMatrix). */
12252
+ private _adjustTRSForInheritMode;
11615
12253
  private _sampleModelLocalMatrix;
11616
12254
  private _sampleModelScale;
12255
+ /**
12256
+ * Effective scale of a model for inherit-mode math (`inherit_scale` in ufbx terms): its own local scale, multiplied
12257
+ * componentwise by the inherited scale when the model uses RrSs inheritance. `time` samples animation; undefined
12258
+ * uses the rest pose.
12259
+ */
12260
+ private _getInheritScale;
12261
+ /** RrSs nodes inherit scale from their parent; Rrs nodes skip their immediate parent (chaining through Rrs parents). */
12262
+ private _getInheritScaleNode;
12263
+ /**
12264
+ * Local matrix of a model relative to its Babylon parent frame, accounting for inherit modes. For RSrs (the
12265
+ * default) this is the FBX local matrix. For RrSs / Rrs the node sits under a helper that removes the parent's
12266
+ * scale, so translation is pre-scaled by the parent scale and (for RrSs) scale accumulates componentwise.
12267
+ */
12268
+ private _computeInheritAwareLocalMatrix;
11617
12269
  /**
11618
12270
  * Build matrix-baked bone animation from full FBX local transforms.
11619
12271
  * The bind matrix carries the skinning offset, so animation curves drive
@@ -11651,6 +12303,197 @@ declare module "babylonjs-loaders/FBX/fbxFileLoader" {
11651
12303
  export * from "babylonjs-loaders/FBX/fbxFileLoader.types";
11652
12304
  export * from "babylonjs-loaders/FBX/fbxFileLoader.pure";
11653
12305
 
12306
+ }
12307
+ declare module "babylonjs-loaders/FBX/fbxConstraintBehavior" {
12308
+ /**
12309
+ * Runtime evaluation of FBX constraints. An `FBXConstraintBehavior` is attached to each constrained node; all
12310
+ * behaviors of a scene register with one `FBXConstraintSolver`, which solves them in dependency order (a constraint
12311
+ * whose target or parent is driven by another constraint is solved after it) and reuses scratch objects, so solving
12312
+ * allocates nothing per frame.
12313
+ *
12314
+ * The solver brackets the scene's animation phase: before animations run it writes each node's unconstrained
12315
+ * transform back, after they ran it captures the result as the new unconstrained transform and solves. A partial
12316
+ * weight therefore always blends from what animation (or nothing) produced this frame, never from the previous
12317
+ * solve's output, so a 50% weight stays a 50% blend instead of converging on the target.
12318
+ *
12319
+ * All maths happen in FBX space, i.e. relative to the loader's root node, so the handedness conversion applied
12320
+ * at the root never enters the solve.
12321
+ */
12322
+ import { Behavior } from "babylonjs/Behaviors/behavior";
12323
+ import { Nullable } from "babylonjs/types";
12324
+ import { Node } from "babylonjs/node";
12325
+ import { Scene } from "babylonjs/scene";
12326
+ import { Matrix, Vector3 } from "babylonjs/Maths/math.vector.pure";
12327
+ import { TransformNode } from "babylonjs/Meshes/transformNode.pure";
12328
+ import { FBXConstraintData } from "babylonjs-loaders/FBX/interpreter/constraints";
12329
+ /** Resolved target of a constraint. */
12330
+ export interface FBXConstraintBehaviorTarget {
12331
+ /** Target node */
12332
+ node: TransformNode;
12333
+ /** Normalized target weight (0..1) */
12334
+ weight: number;
12335
+ /** Offset matrix for parent constraints (in the target's space) */
12336
+ offset: Matrix;
12337
+ }
12338
+ /** Options resolved by the loader when creating the behavior. */
12339
+ export interface FBXConstraintBehaviorOptions {
12340
+ /** Root of the loaded asset; world matrices are made relative to it */
12341
+ root: TransformNode;
12342
+ /** Resolved targets of the constraint, in file order */
12343
+ targets: FBXConstraintBehaviorTarget[];
12344
+ /** World up object of an aim constraint, when it has one */
12345
+ upNode: Nullable<TransformNode>;
12346
+ /** Scene up axis in FBX space */
12347
+ sceneUp: Vector3;
12348
+ }
12349
+ /**
12350
+ * Solves every FBX constraint of a scene once per frame, in dependency order, from the scene's animation phase
12351
+ * observers (`beginFrame` before animations, `solve` after them). Created on demand by the first
12352
+ * `FBXConstraintBehavior` attached in the scene and removed with the last one.
12353
+ */
12354
+ export class FBXConstraintSolver {
12355
+ private readonly _scene;
12356
+ private readonly _behaviors;
12357
+ private _ordered;
12358
+ private _cyclic;
12359
+ private _dirty;
12360
+ private _beforeAnimations;
12361
+ private _afterAnimations;
12362
+ private constructor();
12363
+ /**
12364
+ * Solver of a scene, if any constraint behavior is attached in it.
12365
+ * @param scene - Scene to look up
12366
+ * @returns The solver, or undefined
12367
+ */
12368
+ static Get(scene: Scene): FBXConstraintSolver | undefined;
12369
+ /**
12370
+ * Solver of a scene, created when missing.
12371
+ * @param scene - Scene to look up
12372
+ * @returns The solver
12373
+ */
12374
+ static GetOrCreate(scene: Scene): FBXConstraintSolver;
12375
+ /** Registered behaviors in solve order (a target's constraint before the constraints that read it). */
12376
+ get constraints(): readonly FBXConstraintBehavior[];
12377
+ /**
12378
+ * Behaviors that take part in a dependency cycle (A targets B while B targets A). They are solved after all
12379
+ * acyclic constraints, in registration order, so each sees the other's result from the previous solve.
12380
+ */
12381
+ get cyclicConstraints(): readonly FBXConstraintBehavior[];
12382
+ /**
12383
+ * Adds a behavior to the solve set.
12384
+ * @param behavior - Behavior to add
12385
+ */
12386
+ register(behavior: FBXConstraintBehavior): void;
12387
+ /**
12388
+ * Removes a behavior from the solve set; the solver disposes itself with the last one.
12389
+ * @param behavior - Behavior to remove
12390
+ */
12391
+ unregister(behavior: FBXConstraintBehavior): void;
12392
+ /** Marks the solve order stale, e.g. after re-parenting a constrained node. */
12393
+ invalidateOrder(): void;
12394
+ /**
12395
+ * Start of a frame, before animations run: every constrained node gets its unconstrained transform back, so
12396
+ * that animation either overwrites it or leaves it untouched.
12397
+ */
12398
+ beginFrame(): void;
12399
+ /**
12400
+ * End of the animation phase: takes every constrained node's current transform as its unconstrained value,
12401
+ * then solves every registered constraint once, in dependency order.
12402
+ */
12403
+ solve(): void;
12404
+ private _ensureOrder;
12405
+ private static _IsAncestorOrSelf;
12406
+ }
12407
+ /** Babylon behavior evaluating an FBX aim, parent, position, rotation or scale constraint. */
12408
+ export class FBXConstraintBehavior implements Behavior<TransformNode> {
12409
+ /** Constraint data extracted from the file */
12410
+ readonly constraint: FBXConstraintData;
12411
+ private readonly _options;
12412
+ /** Behavior name (`fbxConstraint:` followed by the constraint name) */
12413
+ readonly name: string;
12414
+ /** Node the behavior is attached to */
12415
+ attachedNode: Nullable<TransformNode>;
12416
+ /** Set to false to pause the constraint without detaching it */
12417
+ enabled: boolean;
12418
+ private readonly _offsetTranslation;
12419
+ private readonly _offsetRotation;
12420
+ private readonly _offsetScale;
12421
+ private readonly _localBasisTransposed;
12422
+ /** Unconstrained transform of the current frame (what animation produced), blended towards the constraint's result. */
12423
+ private readonly _base;
12424
+ private _hasBase;
12425
+ /**
12426
+ * Creates the behavior.
12427
+ * @param constraint - Constraint data extracted from the file
12428
+ * @param _options - Resolved targets and scene information
12429
+ */
12430
+ constructor(
12431
+ /** Constraint data extracted from the file */
12432
+ constraint: FBXConstraintData, _options: FBXConstraintBehaviorOptions);
12433
+ /** Nothing to initialize */
12434
+ init(): void;
12435
+ /**
12436
+ * Registers the behavior with the scene's solver, takes the node's current transform as the unconstrained
12437
+ * value and solves the constraint once.
12438
+ * @param target - Node to constrain
12439
+ */
12440
+ attach(target: TransformNode): void;
12441
+ /** Unregisters the behavior; the node keeps its last solved transform. */
12442
+ detach(): void;
12443
+ /**
12444
+ * Takes the node's current transform as the unconstrained value the next solve blends from. The solver calls
12445
+ * this after the scene's animations ran; call it yourself after writing a transform by hand.
12446
+ */
12447
+ captureBase(): void;
12448
+ /**
12449
+ * Writes the unconstrained transform back to the node. The solver calls this before the scene's animations
12450
+ * run, so a node nothing animates keeps its unconstrained value between frames instead of the solved one.
12451
+ */
12452
+ restoreBase(): void;
12453
+ /**
12454
+ * Nodes whose world transform the solve reads: the targets, the up node and the constrained node's parent.
12455
+ * @returns The nodes, used by the solver to order constraints
12456
+ */
12457
+ dependencyNodes(): Nullable<Node>[];
12458
+ /**
12459
+ * Solves the constraint from the captured unconstrained transform and writes the node's local transform.
12460
+ * Blends are relative to the value captured by `captureBase`, not to whatever the node holds now.
12461
+ */
12462
+ evaluate(): void;
12463
+ /**
12464
+ * World matrix of a node relative to the asset root (FBX space).
12465
+ * @param node - node to evaluate
12466
+ * @param out - matrix receiving the result
12467
+ * @returns `out`
12468
+ */
12469
+ private _fbxWorld;
12470
+ /**
12471
+ * Weighted blend of the targets' world transforms (relative to the root).
12472
+ * @param position - Receives the blended translation
12473
+ * @param rotation - Receives the blended rotation
12474
+ * @param scale - Receives the blended scale
12475
+ * @returns The total target weight, 0 when no target contributes
12476
+ */
12477
+ private _blendTargets;
12478
+ private _applyWeighted;
12479
+ private _applyRotation;
12480
+ private _writePosition;
12481
+ private _writeScaling;
12482
+ private _solvePosition;
12483
+ private _solveRotation;
12484
+ private _solveScale;
12485
+ private _solveParent;
12486
+ private _solveAim;
12487
+ /**
12488
+ * Builds a rotation matrix whose rows are `first`, `second` made orthogonal to it, and their cross product.
12489
+ * @param first - primary axis
12490
+ * @param second - secondary axis
12491
+ * @param out - matrix receiving the basis
12492
+ * @returns false when the axes are parallel or degenerate (`out` is then unchanged)
12493
+ */
12494
+ private static _OrthonormalBasisToRef;
12495
+ }
12496
+
11654
12497
  }
11655
12498
  declare module "babylonjs-loaders/FBX/types/fbxTypes" {
11656
12499
  /**
@@ -11667,6 +12510,11 @@ export interface FBXProperty {
11667
12510
  type: FBXPropertyType;
11668
12511
  /** Parsed property value. */
11669
12512
  value: FBXPropertyValue;
12513
+ /**
12514
+ * Exact decimal text of an int64 whose magnitude exceeds 2^53; `value` then holds the rounded double. Object
12515
+ * ids are the only int64 values where the last bits matter, and `resolveConnections` keys them by this text.
12516
+ */
12517
+ raw?: string;
11670
12518
  }
11671
12519
  /** A node in the FBX document tree */
11672
12520
  export interface FBXNode {
@@ -11693,11 +12541,22 @@ export function findDocumentNode(doc: FBXDocument, name: string): FBXNode | unde
11693
12541
  /** Extract a property value by index, with type narrowing */
11694
12542
  export function getPropertyValue<T extends FBXPropertyValue>(node: FBXNode, index: number): T | undefined;
11695
12543
  /**
11696
- * Converts an FBX object ID value to a safe JavaScript number.
12544
+ * Validates an FBX object ID value: IDs are 64-bit integers, so anything non-numeric, non-finite or fractional is
12545
+ * rejected. IDs beyond 2^53 are carried losslessly through the property's `raw` text by `resolveConnections`.
11697
12546
  * @param value - Parsed FBX object ID value
11698
- * @returns The object ID, or undefined when the value is not numeric
12547
+ * @returns The object ID, or undefined when the value cannot be an ID
11699
12548
  */
11700
12549
  export function getSafeFBXObjectId(value: unknown): number | undefined;
12550
+ /** Typed array payload types produced by the parsers. */
12551
+ export type FBXArrayValue = Float32Array | Float64Array | Int32Array | Uint8Array;
12552
+ /**
12553
+ * Returns the array payload of a node.
12554
+ * 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
12555
+ * scalar properties, and a one-element array degenerates to a single scalar. All of these are coalesced here.
12556
+ * @param node - Node whose properties hold the array
12557
+ * @returns The array, or null when the node has no numeric payload
12558
+ */
12559
+ export function getNodeArray(node: FBXNode | undefined | null): FBXArrayValue | null;
11701
12560
  /** Get the numeric ID from a node (first property is typically the int64 UID) */
11702
12561
  export function getNodeId(node: FBXNode): number | undefined;
11703
12562
  /**
@@ -11761,6 +12620,8 @@ export function computeFBXLocalMatrix(components: FBXTransformComponents): Matri
11761
12620
 
11762
12621
  }
11763
12622
  declare module "babylonjs-loaders/FBX/interpreter/skeleton" {
12623
+ import { FBXNodeTransformData } from "babylonjs-loaders/FBX/interpreter/nodeTransform";
12624
+ import { FBXPropertyTemplate, FBXPropertyTemplateMap } from "babylonjs-loaders/FBX/interpreter/propertyTemplates";
11764
12625
  import { FBXNode } from "babylonjs-loaders/FBX/types/fbxTypes";
11765
12626
  import { FBXObjectMap } from "babylonjs-loaders/FBX/interpreter/connections";
11766
12627
  export type FBXClusterMode = "Normalize" | "Additive" | "TotalOne" | "Unknown";
@@ -11835,25 +12696,9 @@ export interface FBXSkinData {
11835
12696
  /** Recoverable skinning/bind diagnostics */
11836
12697
  diagnostics: FBXSkinDiagnostic[];
11837
12698
  }
11838
- /**
11839
- * Extract all skin deformers from the FBX scene.
11840
- * Returns skin data including bone hierarchy and vertex weights.
11841
- */
11842
- export function extractSkins(objectMap: FBXObjectMap): FBXSkinData[];
12699
+ export function extractSkins(objectMap: FBXObjectMap, propertyTemplates?: FBXPropertyTemplateMap): FBXSkinData[];
11843
12700
  export function isSkeletonModel(modelNode: FBXNode): boolean;
11844
- export function extractBoneTransform(modelNode: FBXNode): {
11845
- translation: [number, number, number];
11846
- rotation: [number, number, number];
11847
- preRotation: [number, number, number];
11848
- postRotation: [number, number, number];
11849
- rotationPivot: [number, number, number];
11850
- scalingPivot: [number, number, number];
11851
- rotationOffset: [number, number, number];
11852
- scalingOffset: [number, number, number];
11853
- scale: [number, number, number];
11854
- rotationOrder: number;
11855
- inheritType: number;
11856
- };
12701
+ export function extractBoneTransform(modelNode: FBXNode, template?: FBXPropertyTemplate): FBXNodeTransformData;
11857
12702
 
11858
12703
  }
11859
12704
  declare module "babylonjs-loaders/FBX/interpreter/sceneDiagnostics" {
@@ -11919,12 +12764,173 @@ export function resolveNumberProperty(node: FBXNode, template: FBXPropertyTempla
11919
12764
  export function resolveVector2Property(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: [number, number]): [number, number];
11920
12765
  export function resolveVector3Property(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: [number, number, number]): [number, number, number];
11921
12766
  export function resolvePropertyValues(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string): FBXPropertyValue[] | undefined;
12767
+ /** A property from a Properties70 ("P") or Properties60 ("Property") block. */
12768
+ export interface FBXPropertyEntry {
12769
+ name: string;
12770
+ type: string;
12771
+ flags: string;
12772
+ values: FBXPropertyValue[];
12773
+ }
12774
+ /**
12775
+ * Lists the properties declared directly on an object, from both the 7.x and 6.x property blocks.
12776
+ * @param node - Object node
12777
+ * @returns Property entries in declaration order (empty when the node has no property block)
12778
+ */
12779
+ export function getPropertyEntries(node: FBXNode | undefined): FBXPropertyEntry[];
12780
+ /** Value of a user property: scalars as-is, vectors and colours as number arrays. */
12781
+ export type FBXUserPropertyValue = string | number | boolean | number[];
12782
+ /**
12783
+ * User-defined properties of an object: those flagged "U" (user) in the property flags. Every DCC exports custom
12784
+ * attributes this way (Maya extra attributes, 3ds Max user properties, Blender custom properties).
12785
+ * @param node - Object node
12786
+ * @returns Map of property name to value, or undefined when the object has none
12787
+ */
12788
+ export function extractUserProperties(node: FBXNode): Record<string, FBXUserPropertyValue> | undefined;
12789
+ export function userPropertyValue(values: FBXPropertyValue[], typeName?: string): FBXUserPropertyValue | undefined;
12790
+
12791
+ }
12792
+ declare module "babylonjs-loaders/FBX/interpreter/nurbs" {
12793
+ /**
12794
+ * NURBS curves and surfaces, and polyline ("Line") geometry.
12795
+ *
12796
+ * The basis evaluation and tessellation follow the FBX SDK conventions as implemented by ufbx: knot spans are
12797
+ * subdivided uniformly, closed and periodic curves wrap their control points, and surfaces are tessellated into
12798
+ * quads (degenerate quads at poles become triangles) with welded positions along the wrapped edges.
12799
+ */
12800
+ import { FBXNode } from "babylonjs-loaders/FBX/types/fbxTypes";
12801
+ import { FBXGeometryData, FBXGeometryDiagnostic } from "babylonjs-loaders/FBX/interpreter/geometry";
12802
+ export type FBXNurbsTopology = "open" | "closed" | "periodic";
12803
+ /** Knot vector and derived data of one parametric direction. */
12804
+ export interface FBXNurbsBasis {
12805
+ order: number;
12806
+ topology: FBXNurbsTopology;
12807
+ knots: Float64Array;
12808
+ /** Parameter range that the curve is defined on */
12809
+ tMin: number;
12810
+ tMax: number;
12811
+ /** Distinct knot values inside [tMin, tMax], i.e. the boundaries of the non-empty spans */
12812
+ spans: Float64Array;
12813
+ /** False when the knot vector is too short or not monotonic */
12814
+ valid: boolean;
12815
+ }
12816
+ /** NURBS curve: homogeneous control points (x, y, z, w) and a basis. */
12817
+ export interface FBXNurbsCurveData {
12818
+ basis: FBXNurbsBasis;
12819
+ /** Control points as x,y,z,w */
12820
+ controlPoints: Float64Array;
12821
+ numControlPoints: number;
12822
+ }
12823
+ /** NURBS surface: control points laid out as `v * numU + u`. */
12824
+ export interface FBXNurbsSurfaceData {
12825
+ basisU: FBXNurbsBasis;
12826
+ basisV: FBXNurbsBasis;
12827
+ numU: number;
12828
+ numV: number;
12829
+ /** Control points as x,y,z,w */
12830
+ controlPoints: Float64Array;
12831
+ flipNormals: boolean;
12832
+ /** Span subdivision stored in the file (Step), 0 when absent */
12833
+ stepU: number;
12834
+ stepV: number;
12835
+ }
12836
+ /** Polyline geometry ready for a lines mesh: one or more open or closed point runs. */
12837
+ export interface FBXCurveGeometryData {
12838
+ id: number;
12839
+ name: string;
12840
+ kind: "line" | "nurbsCurve";
12841
+ /** Each polyline as x,y,z triples; closed runs repeat their first point at the end */
12842
+ polylines: Float64Array[];
12843
+ /** Display colour from the geometry's Color property */
12844
+ color: [number, number, number] | null;
12845
+ diagnostics: FBXGeometryDiagnostic[];
12846
+ }
12847
+ export function createNurbsBasis(order: number, form: string | undefined, knots: Float64Array): FBXNurbsBasis;
12848
+ /**
12849
+ * Evaluates the basis functions (and their derivatives) that are non-zero at `u`.
12850
+ * @returns index of the first influencing control point, or -1 when the basis cannot be evaluated
12851
+ */
12852
+ export function evaluateNurbsBasis(basis: FBXNurbsBasis, u: number, weights: Float64Array, derivatives: Float64Array | null): number;
12853
+ /** Evaluates a curve point; `out` receives position (0..2) and derivative (3..5). */
12854
+ export function evaluateNurbsCurve(curve: FBXNurbsCurveData, u: number, out: Float64Array, weights: Float64Array, derivs: Float64Array): boolean;
12855
+ /** Evaluates a surface point; `out` receives position (0..2), du (3..5) and dv (6..8). */
12856
+ export function evaluateNurbsSurface(surface: FBXNurbsSurfaceData, u: number, v: number, out: Float64Array, scratch: {
12857
+ wu: Float64Array;
12858
+ wv: Float64Array;
12859
+ du: Float64Array;
12860
+ dv: Float64Array;
12861
+ }): boolean;
12862
+ /**
12863
+ * Tessellates a curve into a polyline with `subdivision` segments per knot span. Closed and periodic curves
12864
+ * end on a copy of their first point.
12865
+ */
12866
+ export function tessellateNurbsCurve(curve: FBXNurbsCurveData, subdivision?: number): Float64Array | null;
12867
+ /** Span subdivision to use for a surface direction: an explicit override, else the file's Step, else 4. */
12868
+ export function resolveSpanSubdivision(fileStep: number, override: number | undefined): number;
12869
+ /**
12870
+ * Tessellates a surface into triangles. Positions on wrapped (closed/periodic) edges and at poles are welded
12871
+ * exactly like the FBX SDK does, so degenerate quads collapse into triangles.
12872
+ */
12873
+ export function tessellateNurbsSurface(surface: FBXNurbsSurfaceData, subU: number, subV: number): {
12874
+ positions: Float64Array;
12875
+ indices: Uint32Array;
12876
+ normals: Float64Array;
12877
+ uvs: Float64Array;
12878
+ } | null;
12879
+ /** Reads a NurbsCurve geometry node. */
12880
+ export function extractNurbsCurve(node: FBXNode): FBXNurbsCurveData | null;
12881
+ /** Reads a NurbsSurface geometry node. */
12882
+ export function extractNurbsSurface(node: FBXNode): FBXNurbsSurfaceData | null;
12883
+ /** Tessellates a NurbsSurface geometry node into mesh geometry. */
12884
+ export function nurbsSurfaceToGeometry(node: FBXNode, geometryId: number, subdivisionOverride: number | undefined): FBXGeometryData | null;
12885
+ /** Reads a NurbsCurve geometry node into a tessellated polyline. */
12886
+ export function extractNurbsCurveGeometry(node: FBXNode, geometryId: number, subdivision?: number): FBXCurveGeometryData;
12887
+ /**
12888
+ * Reads a Line geometry node: Points plus PointsIndex where a negative index (~index) ends a segment, as in
12889
+ * polygon vertex indices.
12890
+ */
12891
+ export function extractLineGeometry(node: FBXNode, geometryId: number): FBXCurveGeometryData;
12892
+
12893
+ }
12894
+ declare module "babylonjs-loaders/FBX/interpreter/nodeTransform" {
12895
+ import { FBXNode } from "babylonjs-loaders/FBX/types/fbxTypes";
12896
+ import { FBXPropertyTemplate } from "babylonjs-loaders/FBX/interpreter/propertyTemplates";
12897
+ /** Transform properties resolved from an FBX Model, with template defaults applied. */
12898
+ export interface FBXNodeTransformData {
12899
+ translation: [number, number, number];
12900
+ rotation: [number, number, number];
12901
+ scale: [number, number, number];
12902
+ preRotation: [number, number, number];
12903
+ postRotation: [number, number, number];
12904
+ rotationPivot: [number, number, number];
12905
+ scalingPivot: [number, number, number];
12906
+ rotationOffset: [number, number, number];
12907
+ scalingOffset: [number, number, number];
12908
+ geometricTranslation: [number, number, number];
12909
+ geometricRotation: [number, number, number];
12910
+ geometricScaling: [number, number, number];
12911
+ /** Rotation order: 0=XYZ, 1=XZY, 2=YZX, 3=YXZ, 4=ZXY, 5=ZYX, 6=SphericXYZ */
12912
+ rotationOrder: number;
12913
+ /** FBX transform inheritance mode. 0=RrSs, 1=RSrs, 2=Rrs */
12914
+ inheritType: number;
12915
+ /** Whether the rotation space (rotation order, pre/post rotation) is active for this node */
12916
+ rotationActive: boolean;
12917
+ diagnostics: string[];
12918
+ }
12919
+ /**
12920
+ * Resolves the transform properties of a Model node the way the FBX SDK evaluates them.
12921
+ *
12922
+ * `RotationActive` gates the whole rotation space: when it is false (the FbxNode template default), the SDK
12923
+ * composes `Lcl Rotation` in plain XYZ order and ignores `RotationOrder`, `PreRotation` and `PostRotation`.
12924
+ * `RotationSpaceForLimitOnly` restricts the rotation space to limits, which has the same effect for us.
12925
+ */
12926
+ export function extractNodeTransform(modelNode: FBXNode, template?: FBXPropertyTemplate): FBXNodeTransformData;
11922
12927
 
11923
12928
  }
11924
12929
  declare module "babylonjs-loaders/FBX/interpreter/materials" {
11925
12930
  import { FBXNode } from "babylonjs-loaders/FBX/types/fbxTypes";
11926
12931
  import { FBXObjectMap } from "babylonjs-loaders/FBX/interpreter/connections";
11927
- import { FBXPropertyTemplateMap } from "babylonjs-loaders/FBX/interpreter/propertyTemplates";
12932
+ import { FBXPropertyTemplate, FBXPropertyTemplateMap, FBXUserPropertyValue } from "babylonjs-loaders/FBX/interpreter/propertyTemplates";
12933
+ import { FBXMaterialModel } from "babylonjs-loaders/FBX/interpreter/materialModel";
11928
12934
  /** Parsed material data */
11929
12935
  export interface FBXMaterialData {
11930
12936
  id: number;
@@ -11932,6 +12938,10 @@ export interface FBXMaterialData {
11932
12938
  type: "Lambert" | "Phong";
11933
12939
  properties: FBXMaterialProperties;
11934
12940
  textures: FBXTextureRef[];
12941
+ /** Unified classic + PBR parameter model resolved from whichever shader flavour the file uses */
12942
+ model: FBXMaterialModel<FBXTextureRef>;
12943
+ /** User-defined properties */
12944
+ userProperties?: Record<string, FBXUserPropertyValue>;
11935
12945
  }
11936
12946
  export interface FBXMaterialProperties {
11937
12947
  diffuseColor?: [number, number, number];
@@ -11967,11 +12977,106 @@ export interface FBXTextureRef {
11967
12977
  uvSetIndex?: number;
11968
12978
  /** Which named UV set this texture uses */
11969
12979
  uvSetName?: string;
12980
+ /** WrapModeU: 0 = repeat, 1 = clamp */
12981
+ wrapU?: number;
12982
+ /** WrapModeV: 0 = repeat, 1 = clamp */
12983
+ wrapV?: number;
12984
+ /** Set when the texture came from a LayeredTexture (only the first layer is used) */
12985
+ layeredTextureId?: number;
11970
12986
  }
11971
12987
  /**
11972
12988
  * Extract material data from an FBX Material node.
11973
12989
  */
11974
12990
  export function extractMaterial(materialNode: FBXNode, materialId: number, objectMap: FBXObjectMap, templates?: FBXPropertyTemplateMap): FBXMaterialData;
12991
+ export function extractTextureRef(id: number, node: FBXNode, propertyName: string | undefined, objectMap: FBXObjectMap, template?: FBXPropertyTemplate): FBXTextureRef;
12992
+
12993
+ }
12994
+ declare module "babylonjs-loaders/FBX/interpreter/materialModel" {
12995
+ /**
12996
+ * Unified material model.
12997
+ *
12998
+ * FBX materials come in many vendor flavours: the classic FbxSurfaceLambert / FbxSurfacePhong, Autodesk Standard
12999
+ * Surface (OSL), Arnold aiStandardSurface, 3ds Max Physical Material, 3ds Max PBR (metal/rough and spec/gloss),
13000
+ * the 3ds Max glTF material, OpenPBR, and Maya's Stingray PBS ShaderFX graph. Each stores its parameters under
13001
+ * different property names, sometimes behind a shader binding table.
13002
+ *
13003
+ * This module resolves any of them into two parameter sets, mirroring how the FBX SDK / ufbx expose materials:
13004
+ * `fbx` (the classic Lambert/Phong parameters) and `pbr` (a physically based parameter set), plus feature flags.
13005
+ */
13006
+ import { FBXPropertyValue } from "babylonjs-loaders/FBX/types/fbxTypes";
13007
+ export type FBXShaderType = "unknown" | "fbxLambert" | "fbxPhong" | "oslStandardSurface" | "arnoldStandardSurface" | "3dsMaxPhysicalMaterial" | "3dsMaxPbrMetalRough" | "3dsMaxPbrSpecGloss" | "gltfMaterial" | "openPbrMaterial" | "shaderFxGraph";
13008
+ /** One resolved material parameter: a constant value and/or a texture. */
13009
+ export interface FBXMaterialMap<TTexture> {
13010
+ /** Constant value (r,g,b,a for colours, x for scalars) */
13011
+ value?: number[];
13012
+ /** Number of meaningful components in `value` (1 for scalars, 3 or 4 for colours) */
13013
+ valueComponents: number;
13014
+ /** Texture bound to the parameter */
13015
+ texture?: TTexture;
13016
+ /** Whether the texture is enabled (some vendors carry an explicit toggle) */
13017
+ textureEnabled: boolean;
13018
+ }
13019
+ export type FBXFbxMapName = "diffuseFactor" | "diffuseColor" | "specularFactor" | "specularColor" | "specularExponent" | "reflectionFactor" | "reflectionColor" | "transparencyFactor" | "transparencyColor" | "emissionFactor" | "emissionColor" | "ambientFactor" | "ambientColor" | "normalMap" | "bump" | "bumpFactor" | "displacement" | "displacementFactor" | "vectorDisplacement" | "vectorDisplacementFactor";
13020
+ 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";
13021
+ 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";
13022
+ export interface FBXMaterialModel<TTexture> {
13023
+ shaderType: FBXShaderType;
13024
+ /** Prefix material property names carry for this shader (e.g. "3dsMax|Parameters|") */
13025
+ shaderPropPrefix: string;
13026
+ fbx: Partial<Record<FBXFbxMapName, FBXMaterialMap<TTexture>>>;
13027
+ pbr: Partial<Record<FBXPbrMapName, FBXMaterialMap<TTexture>>>;
13028
+ features: Partial<Record<FBXMaterialFeatureName, {
13029
+ enabled: boolean;
13030
+ explicit: boolean;
13031
+ }>>;
13032
+ }
13033
+ /** Inputs needed to resolve a material, independent of the parse representation. */
13034
+ export interface FBXMaterialSource<TTexture> {
13035
+ /** "lambert", "phong", "unknown", ... as written in the file */
13036
+ shadingModelName: string;
13037
+ /** Property values by full property name (e.g. "DiffuseColor", "Maya|baseColor", "3dsMax|Parameters|roughness") */
13038
+ props: Map<string, {
13039
+ type: string;
13040
+ values: FBXPropertyValue[];
13041
+ }>;
13042
+ /** Textures connected to the material by property name (OP connection property) */
13043
+ texturesByProp: Map<string, TTexture>;
13044
+ /** Connected shader implementation, when any */
13045
+ shader?: {
13046
+ renderApi: string;
13047
+ /** shader semantic name -> material property names */
13048
+ bindings: Map<string, string[]>;
13049
+ };
13050
+ }
13051
+ /** Shader types whose parameters are physically based; the loader emits PBR materials for them by default. */
13052
+ export function isPbrShaderType(type: FBXShaderType): boolean;
13053
+ /** Detects the shader flavour of a material from its shading model name, connected shader and 3ds Max class ids. */
13054
+ export function detectShaderType<T>(source: FBXMaterialSource<T>): {
13055
+ shaderType: FBXShaderType;
13056
+ shaderPropPrefix: string;
13057
+ };
13058
+ /**
13059
+ * Resolves the unified material model from raw material data.
13060
+ */
13061
+ export function resolveMaterialModel<T>(source: FBXMaterialSource<T>): FBXMaterialModel<T>;
13062
+ /** Colour (first three components) of a map, or undefined. */
13063
+ export function mapColor<T>(map: FBXMaterialMap<T> | undefined): [number, number, number] | undefined;
13064
+ /** Scalar (first component) of a map, or undefined. */
13065
+ export function mapScalar<T>(map: FBXMaterialMap<T> | undefined): number | undefined;
13066
+
13067
+ }
13068
+ declare module "babylonjs-loaders/FBX/interpreter/legacyDocument" {
13069
+ /**
13070
+ * FBX 5.x (and older) documents store everything at the top level: one `Model` node per object with inline
13071
+ * geometry, materials, skin links, lights and cameras, and `Children` lists instead of connections. This module
13072
+ * rewrites such a document into the 6.x layout (`Objects`, `Connections`, `Takes`) so the rest of the importer
13073
+ * can treat both the same way. The rules follow the FBX SDK's legacy reader as implemented by ufbx.
13074
+ */
13075
+ import { FBXDocument } from "babylonjs-loaders/FBX/types/fbxTypes";
13076
+ /** True for pre-6000 files: no `Objects` section but top-level `Model` nodes. */
13077
+ export function isLegacyDocument(doc: FBXDocument): boolean;
13078
+ /** Rewrites a legacy document into the 6.x object/connection layout. */
13079
+ export function upgradeLegacyDocument(doc: FBXDocument): FBXDocument;
11975
13080
 
11976
13081
  }
11977
13082
  declare module "babylonjs-loaders/FBX/interpreter/geometry" {
@@ -11986,7 +13091,7 @@ export interface FBXUVSet {
11986
13091
  /** Recoverable geometry import issue. */
11987
13092
  export interface FBXGeometryDiagnostic {
11988
13093
  /** Diagnostic category. */
11989
- type: "degenerate-polygon" | "triangulation-fallback" | "layer-index-out-of-bounds" | "layer-data-too-short";
13094
+ type: "degenerate-polygon" | "triangulation-fallback" | "layer-index-out-of-bounds" | "layer-data-too-short" | "nurbs-invalid" | "nurbs-trim-ignored" | "nurbs-deformer-ignored";
11990
13095
  /** Human-readable diagnostic message. */
11991
13096
  message: string;
11992
13097
  /** Polygon index associated with the diagnostic, if applicable. */
@@ -12033,8 +13138,11 @@ export function extractGeometry(geometryNode: FBXNode, nodeId: number): FBXGeome
12033
13138
 
12034
13139
  }
12035
13140
  declare module "babylonjs-loaders/FBX/interpreter/fbxInterpreter" {
13141
+ import { FBXUserPropertyValue } from "babylonjs-loaders/FBX/interpreter/propertyTemplates";
12036
13142
  import { FBXDocument } from "babylonjs-loaders/FBX/types/fbxTypes";
12037
13143
  import { FBXGeometryData } from "babylonjs-loaders/FBX/interpreter/geometry";
13144
+ import { FBXCurveGeometryData } from "babylonjs-loaders/FBX/interpreter/nurbs";
13145
+ import { FBXConstraintData } from "babylonjs-loaders/FBX/interpreter/constraints";
12038
13146
  import { FBXMaterialData } from "babylonjs-loaders/FBX/interpreter/materials";
12039
13147
  import { FBXSkinData } from "babylonjs-loaders/FBX/interpreter/skeleton";
12040
13148
  import { FBXRigData } from "babylonjs-loaders/FBX/interpreter/rig";
@@ -12046,8 +13154,10 @@ export interface FBXModelData {
12046
13154
  id: number;
12047
13155
  name: string;
12048
13156
  subType: string;
12049
- /** Geometry attached to this model (if it's a Mesh type) */
13157
+ /** Geometry attached to this model (meshes and tessellated NURBS surfaces) */
12050
13158
  geometry?: FBXGeometryData;
13159
+ /** Curve geometry attached to this model (Line and NurbsCurve) */
13160
+ curve?: FBXCurveGeometryData;
12051
13161
  /** Materials assigned to this model */
12052
13162
  materials: FBXMaterialData[];
12053
13163
  /** Child models */
@@ -12079,18 +13189,68 @@ export interface FBXModelData {
12079
13189
  /** Whether backface culling is disabled ("CullingOff") */
12080
13190
  cullingOff: boolean;
12081
13191
  /** User-defined custom properties from Properties70 */
12082
- customProperties?: Record<string, string | number | boolean>;
13192
+ customProperties?: Record<string, FBXUserPropertyValue>;
13193
+ /** LOD group settings when this model is a LodGroup; children are the levels in order */
13194
+ lodGroup?: FBXLodGroupData;
13195
+ /** Display layer (CollectionExclusive) the model belongs to */
13196
+ displayLayer?: FBXDisplayLayerData;
12083
13197
  /** Recoverable model import diagnostics */
12084
13198
  diagnostics: string[];
12085
13199
  }
13200
+ /** LOD group settings (NodeAttribute "LodGroup") */
13201
+ export interface FBXLodGroupData {
13202
+ /** Switch distance for level i+1 (level 0 has none). In scene units, or percent of screen when `relative`. */
13203
+ thresholds: number[];
13204
+ /** ThresholdsUsedAsPercentage */
13205
+ relative: boolean;
13206
+ /** DisplayLevels|LevelN: 0 use LOD, 1 show, 2 hide */
13207
+ displayLevels: number[];
13208
+ }
13209
+ /** Display layer (CollectionExclusive "DisplayLayer") */
13210
+ export interface FBXDisplayLayerData {
13211
+ id: number;
13212
+ name: string;
13213
+ show: boolean;
13214
+ freeze: boolean;
13215
+ color: [number, number, number];
13216
+ modelIds: number[];
13217
+ }
13218
+ /** One member of a selection set: a model, optionally with a component selection on its mesh */
13219
+ export interface FBXSelectionNodeData {
13220
+ modelId: number;
13221
+ /** IsTheNodeInSet: the whole node is selected (as opposed to only components) */
13222
+ includeNode: boolean;
13223
+ /** Selected control point indices (VertexIndexArray) */
13224
+ vertices?: number[];
13225
+ /** Selected edge indices (EdgeIndexArray) */
13226
+ edges?: number[];
13227
+ /** Selected polygon indices (PolygonIndexArray) */
13228
+ faces?: number[];
13229
+ }
13230
+ /** Selection set (Collection "SelectionSet") */
13231
+ export interface FBXSelectionSetData {
13232
+ id: number;
13233
+ name: string;
13234
+ members: FBXSelectionNodeData[];
13235
+ }
12086
13236
  /** Camera data extracted from FBX */
12087
13237
  export interface FBXCameraData {
12088
13238
  /** Model ID this camera is attached to */
12089
13239
  modelId: number;
13240
+ /** NodeAttribute object ID (animation curves target this) */
13241
+ attributeId: number;
12090
13242
  /** Camera name */
12091
13243
  name: string;
12092
- /** Field of view in degrees */
13244
+ /** Vertical field of view in degrees */
12093
13245
  fieldOfView: number;
13246
+ /** Horizontal field of view in degrees */
13247
+ fieldOfViewX: number;
13248
+ /** ApertureMode: 0 horizontal and vertical, 1 horizontal, 2 vertical, 3 focal length */
13249
+ apertureMode: number;
13250
+ /** Aperture (film gate after gate fit) size in inches */
13251
+ apertureSizeInch: [number, number];
13252
+ /** Orthographic view size (width, height) in scene units */
13253
+ orthographicSize: [number, number];
12094
13254
  /** Near clip plane */
12095
13255
  nearPlane: number;
12096
13256
  /** Far clip plane */
@@ -12109,6 +13269,8 @@ export interface FBXCameraData {
12109
13269
  orthoZoom?: number;
12110
13270
  /** Camera roll in degrees when present */
12111
13271
  roll?: number;
13272
+ /** User-defined properties on the camera attribute */
13273
+ userProperties?: Record<string, FBXUserPropertyValue>;
12112
13274
  /** Known unsupported or unrecognized camera properties */
12113
13275
  unknownProperties: string[];
12114
13276
  /** Recoverable camera import diagnostics */
@@ -12118,6 +13280,8 @@ export interface FBXCameraData {
12118
13280
  export interface FBXLightData {
12119
13281
  /** Model ID this light is attached to */
12120
13282
  modelId: number;
13283
+ /** NodeAttribute object ID (animation curves target this) */
13284
+ attributeId: number;
12121
13285
  /** Light name */
12122
13286
  name: string;
12123
13287
  /** Light type: 0=Point, 1=Directional, 2=Spot */
@@ -12142,6 +13306,15 @@ export interface FBXLightData {
12142
13306
  enableFarAttenuation?: boolean;
12143
13307
  /** Whether the source light requested shadow casting */
12144
13308
  castShadows?: boolean;
13309
+ /** Near/far attenuation ranges in scene units (when enabled) */
13310
+ nearAttenuationStart?: number;
13311
+ nearAttenuationEnd?: number;
13312
+ farAttenuationStart?: number;
13313
+ farAttenuationEnd?: number;
13314
+ /** Area light shape: 0 rectangle, 1 sphere */
13315
+ areaLightShape?: number;
13316
+ /** User-defined properties on the light attribute */
13317
+ userProperties?: Record<string, FBXUserPropertyValue>;
12145
13318
  /** Known unsupported or unrecognized light properties */
12146
13319
  unknownProperties: string[];
12147
13320
  /** Recoverable light import diagnostics */
@@ -12153,6 +13326,8 @@ export interface FBXSceneData {
12153
13326
  rootModels: FBXModelData[];
12154
13327
  /** All geometries in the scene */
12155
13328
  geometries: FBXGeometryData[];
13329
+ /** All curve geometries (lines and tessellated NURBS curves) */
13330
+ curves: FBXCurveGeometryData[];
12156
13331
  /** All materials in the scene */
12157
13332
  materials: FBXMaterialData[];
12158
13333
  /** Skin deformers (skeletons + vertex weights) */
@@ -12169,6 +13344,12 @@ export interface FBXSceneData {
12169
13344
  lights: FBXLightData[];
12170
13345
  /** Scene-level unsupported feature diagnostics */
12171
13346
  diagnostics: FBXSceneDiagnostic[];
13347
+ /** Constraints (aim, parent, position, rotation, scale, IK) */
13348
+ constraints: FBXConstraintData[];
13349
+ /** Display layers */
13350
+ displayLayers: FBXDisplayLayerData[];
13351
+ /** Selection sets */
13352
+ selectionSets: FBXSelectionSetData[];
12172
13353
  /** Global settings */
12173
13354
  upAxis: number;
12174
13355
  upAxisSign: number;
@@ -12177,11 +13358,91 @@ export interface FBXSceneData {
12177
13358
  coordAxis: number;
12178
13359
  coordAxisSign: number;
12179
13360
  unitScaleFactor: number;
13361
+ /** Scene frame rate derived from GlobalSettings TimeMode / CustomFrameRate */
13362
+ frameRate: number;
12180
13363
  }
12181
13364
  /**
12182
13365
  * Interpret a parsed FBX document into scene data.
12183
13366
  */
12184
- export function interpretFBX(doc: FBXDocument): FBXSceneData;
13367
+ /** Options controlling how the document is interpreted. */
13368
+ export interface FBXInterpretOptions {
13369
+ /** Segments per knot span when tessellating NURBS surfaces; defaults to the Step stored in the file */
13370
+ nurbsSubdivision?: number;
13371
+ /** Shift every clip so its first key sits at time 0 (default true); false keeps the authored times */
13372
+ rebaseKeyframes?: boolean;
13373
+ }
13374
+ export function interpretFBX(doc: FBXDocument, options?: FBXInterpretOptions): FBXSceneData;
13375
+
13376
+ }
13377
+ declare module "babylonjs-loaders/FBX/interpreter/constraints" {
13378
+ import { FBXObjectMap } from "babylonjs-loaders/FBX/interpreter/connections";
13379
+ export type FBXConstraintType = "aim" | "parent" | "position" | "rotation" | "scale" | "singleChainIK" | "unknown";
13380
+ export type Vec3 = [number, number, number];
13381
+ export type Bool3 = [boolean, boolean, boolean];
13382
+ /** One weighted target of a constraint. */
13383
+ export interface FBXConstraintTarget {
13384
+ /** Model id of the target node */
13385
+ modelId: number;
13386
+ /** Normalized weight (file value / 100, or as-is for IK pole targets) */
13387
+ weight: number;
13388
+ /** Parent constraint translation offset expressed in the target's space */
13389
+ offsetTranslation: Vec3;
13390
+ /** Parent constraint rotation offset in degrees, expressed in the target's space */
13391
+ offsetRotation: Vec3;
13392
+ /** Parent constraint scale offset expressed in the target's space */
13393
+ offsetScale: Vec3;
13394
+ }
13395
+ /** A constraint object of the file, with its targets and parameters resolved. */
13396
+ export interface FBXConstraintData {
13397
+ /** Constraint object id */
13398
+ id: number;
13399
+ /** Constraint name */
13400
+ name: string;
13401
+ /** Resolved constraint kind */
13402
+ type: FBXConstraintType;
13403
+ /** Constraint type name as written in the file (e.g. "Parent-Child") */
13404
+ typeName: string;
13405
+ /** Constrained model */
13406
+ nodeId?: number;
13407
+ /** Weighted targets in file order */
13408
+ targets: FBXConstraintTarget[];
13409
+ /** Global weight (file value / 100) */
13410
+ weight: number;
13411
+ /** False when the constraint is switched off in the file */
13412
+ active: boolean;
13413
+ /** Which translation axes the constraint drives */
13414
+ affectTranslation: Bool3;
13415
+ /** Which rotation axes the constraint drives */
13416
+ affectRotation: Bool3;
13417
+ /** Which scale axes the constraint drives */
13418
+ affectScale: Bool3;
13419
+ /** Translation offset of the constrained node */
13420
+ offsetTranslation: Vec3;
13421
+ /** Rotation offset of the constrained node, in degrees */
13422
+ offsetRotation: Vec3;
13423
+ /** Scale offset of the constrained node */
13424
+ offsetScale: Vec3;
13425
+ /** Aim: local axis that points at the target */
13426
+ aimVector: Vec3;
13427
+ /** Aim: local axis aligned with the up direction */
13428
+ upVector: Vec3;
13429
+ /** Aim: world up direction (world up modes 2 and 3) */
13430
+ worldUpVector: Vec3;
13431
+ /** Aim: 0 scene up, 1 aim up node, 2 align to node, 3 vector, 4 none */
13432
+ worldUpType: number;
13433
+ /** Aim: model id of the world up object (world up modes 1 and 2) */
13434
+ worldUpNodeId?: number;
13435
+ /** Single chain IK: model id of the first joint of the chain */
13436
+ ikFirstJointId?: number;
13437
+ /** Single chain IK: model id of the last joint of the chain */
13438
+ ikEndJointId?: number;
13439
+ /** Single chain IK: model id of the effector */
13440
+ ikEffectorId?: number;
13441
+ /** Single chain IK: pole vector */
13442
+ ikPoleVector: Vec3;
13443
+ }
13444
+ /** Reads every constraint object of the scene. */
13445
+ export function extractConstraints(objectMap: FBXObjectMap): FBXConstraintData[];
12185
13446
 
12186
13447
  }
12187
13448
  declare module "babylonjs-loaders/FBX/interpreter/connections" {
@@ -12206,7 +13467,7 @@ export interface FBXObjectEntry {
12206
13467
  /** Object node. */
12207
13468
  node: FBXNode;
12208
13469
  /** Source of the object entry. */
12209
- source: "Objects" | "legacySyntheticGeometry";
13470
+ source: "Objects" | "legacySyntheticGeometry" | "legacySyntheticAttribute" | "legacySyntheticBlendShape";
12210
13471
  /** Legacy string object name, when applicable. */
12211
13472
  legacyName?: string;
12212
13473
  /** True if the object was synthesized for legacy compatibility. */
@@ -12329,9 +13590,24 @@ export interface FBXBlendShapeData {
12329
13590
  export function extractBlendShapes(objectMap: FBXObjectMap): FBXBlendShapeData[];
12330
13591
 
12331
13592
  }
12332
- declare module "babylonjs-loaders/FBX/interpreter/animation" {
12333
- import { FBXObjectMap } from "babylonjs-loaders/FBX/interpreter/connections";
13593
+ declare module "babylonjs-loaders/FBX/interpreter/animationCurve" {
13594
+ /**
13595
+ * FBX animation curve model and evaluator.
13596
+ *
13597
+ * Keys carry cubic Bezier tangents expressed the way the FBX SDK stores them: a left and right tangent with a time
13598
+ * extent (dx, as a fraction of the segment scaled by the tangent weight) and a value extent (dy). Linear and constant
13599
+ * segments are represented the same way so that a single evaluator handles every case, including the weighted
13600
+ * tangents Maya and MotionBuilder write, TCB keys, and the pre/post extrapolation modes.
13601
+ */
13602
+ /** FBX time units: 46186158000 ticks per second */
13603
+ export const FBX_TIME_UNIT = 46186158000;
12334
13604
  export type FBXInterpolationType = "constant" | "linear" | "cubic";
13605
+ export type FBXExtrapolationMode = "constant" | "repeat" | "mirror" | "slope" | "repeatRelative";
13606
+ export interface FBXExtrapolation {
13607
+ mode: FBXExtrapolationMode;
13608
+ /** Number of repetitions, or -1 for infinite */
13609
+ repeatCount: number;
13610
+ }
12335
13611
  /** A single keyframe */
12336
13612
  export interface FBXKeyframe {
12337
13613
  /** Time in seconds */
@@ -12342,9 +13618,15 @@ export interface FBXKeyframe {
12342
13618
  interpolation: FBXInterpolationType;
12343
13619
  /** Constant interpolation variant */
12344
13620
  constantMode?: "standard" | "next";
12345
- /** Cubic outgoing slope in value units per second */
13621
+ /** Left (incoming) tangent: time extent in seconds and value extent */
13622
+ leftDx: number;
13623
+ leftDy: number;
13624
+ /** Right (outgoing) tangent: time extent in seconds and value extent */
13625
+ rightDx: number;
13626
+ rightDy: number;
13627
+ /** Cubic outgoing slope in value units per second (derived, kept for consumers that export hermite keys) */
12346
13628
  rightSlope?: number;
12347
- /** Cubic incoming slope for the next key, in value units per second */
13629
+ /** Cubic incoming slope for the next key, in value units per second (derived) */
12348
13630
  nextLeftSlope?: number;
12349
13631
  }
12350
13632
  /** An animation curve (one axis of one property) */
@@ -12355,7 +13637,60 @@ export interface FBXCurveData {
12355
13637
  keys: FBXKeyframe[];
12356
13638
  /** True for baked sample curves that should be connected as linear samples */
12357
13639
  isSampled?: boolean;
13640
+ preExtrapolation?: FBXExtrapolation;
13641
+ postExtrapolation?: FBXExtrapolation;
13642
+ }
13643
+ /** Raw key attribute data for one key, after run-length decoding. */
13644
+ export interface FBXKeyAttributes {
13645
+ flags: number;
13646
+ data: [number, number, number, number];
13647
+ }
13648
+ /**
13649
+ * Builds keyframes from parallel time/value arrays and their (run-length encoded) attributes, resolving every
13650
+ * tangent mode the FBX SDK writes: user, broken, auto (with clamp / progressive clamp / time-independent flags and
13651
+ * auto bias), TCB, weighted, linear and constant.
13652
+ */
13653
+ export function buildKeyframes(times: ArrayLike<number>, values: ArrayLike<number>, attributes: (index: number) => FBXKeyAttributes): FBXKeyframe[];
13654
+ /** Auto tangent as the FBX SDK computes it, including clamping and auto bias. */
13655
+ export function solveAutoTangent(prevTime: number, time: number, nextTime: number, prevValue: number, value: number, nextValue: number, weightLeft: number, weightRight: number, autoBias: number, flags: number): number;
13656
+ /** Builds a keyframe list from explicit per-key slopes (legacy Takes and synthetic curves). */
13657
+ export function keyframesFromSlopes(times: number[], values: number[], interpolation: FBXInterpolationType[], constantNext: boolean[], leftSlope: number[], rightSlope: number[], leftWeight?: number[], rightWeight?: number[]): FBXKeyframe[];
13658
+ /** Reads a `Pre-Extrapolation` / `Post-Extrapolation` block: `Type` is a character code, `Repetition` a count. */
13659
+ export function parseExtrapolation(typeValue: unknown, repetitionValue: unknown): FBXExtrapolation;
13660
+ export function evaluateCurve(curve: FBXCurveData | undefined, time: number, defaultValue: number, noExtrapolation?: boolean): number;
13661
+ export type Vec3 = [number, number, number];
13662
+ export type Quat = [number, number, number, number];
13663
+ /** Euler angles in degrees with an FBX rotation order (0=XYZ ... 5=ZYX; spheric falls back to XYZ) to a quaternion. */
13664
+ export function eulerToQuat(v: Vec3, order: number): Quat;
13665
+ /** Quaternion to Euler angles in degrees for an FBX rotation order (inverse of eulerToQuat). */
13666
+ export function quatToEuler(q: Quat, order: number): Vec3;
13667
+ /** Blend semantics of an animation layer, derived from its BlendMode and accumulation modes. */
13668
+ export interface FBXLayerBlend {
13669
+ /** Layer participates in blending (BlendMode Additive or Override Passthrough) */
13670
+ blended: boolean;
13671
+ /** Layer adds onto the result instead of replacing it (BlendMode Additive) */
13672
+ additive: boolean;
13673
+ /** Rotations compose as quaternions (RotationAccumulationMode ByLayer) */
13674
+ composeRotation: boolean;
13675
+ /** Scales compose multiplicatively (ScaleAccumulationMode Multiply) */
13676
+ composeScale: boolean;
13677
+ /** Layer weight in [0, 1] */
13678
+ weight: number;
13679
+ }
13680
+ /**
13681
+ * Combines one animation layer's value into the running result, exactly as the FBX SDK evaluator does.
13682
+ * `kind` selects the accumulation rule: "R" rotations (degrees, rotation order given), "S" scales, anything else linear.
13683
+ */
13684
+ export function combineLayerValue(result: Vec3, value: Vec3, layer: FBXLayerBlend, kind: "T" | "R" | "S" | "other", rotationOrder: number): Vec3;
13685
+
12358
13686
  }
13687
+ declare module "babylonjs-loaders/FBX/interpreter/animation" {
13688
+ import { FBXDocument } from "babylonjs-loaders/FBX/types/fbxTypes";
13689
+ import { FBXObjectMap } from "babylonjs-loaders/FBX/interpreter/connections";
13690
+ import { FBXCurveData, FBXLayerBlend } from "babylonjs-loaders/FBX/interpreter/animationCurve";
13691
+ export { FBX_TIME_UNIT } from "babylonjs-loaders/FBX/interpreter/animationCurve";
13692
+ export type { FBXCurveData, FBXExtrapolation, FBXExtrapolationMode, FBXInterpolationType, FBXKeyframe, FBXLayerBlend } from "babylonjs-loaders/FBX/interpreter/animationCurve";
13693
+ export { combineLayerValue, evaluateCurve, eulerToQuat, quatToEuler } from "babylonjs-loaders/FBX/interpreter/animationCurve";
12359
13694
  /** An animation curve node (T/R/S for one bone) */
12360
13695
  export interface FBXCurveNodeData {
12361
13696
  /** Property type: "T" (translation), "R" (rotation), "S" (scale) */
@@ -12364,13 +13699,19 @@ export interface FBXCurveNodeData {
12364
13699
  targetModelId: number;
12365
13700
  /** Curves for each axis */
12366
13701
  curves: FBXCurveData[];
13702
+ /** Index of the owning layer within the stack's layer list */
13703
+ layerIndex: number;
13704
+ /** Default channel values (`d|X`, `d|Y`, `d|Z`) used for channels without a curve */
13705
+ defaultValues?: [number, number, number];
12367
13706
  }
12368
- /** Unsupported animation curve node preserved for diagnostics and future support. */
13707
+ /** Non-transform animation curve node (property animation), evaluated by the loader when a Babylon mapping exists. */
12369
13708
  export interface FBXUnsupportedCurveNodeData {
12370
13709
  /** Raw AnimationCurveNode property type/name */
12371
13710
  type: string;
12372
13711
  /** CurveNode object ID */
12373
13712
  id: number;
13713
+ /** Index of the owning layer within the stack's layer list */
13714
+ layerIndex: number;
12374
13715
  /** Target object ID if the curve node is connected to an object/property */
12375
13716
  targetId: number | null;
12376
13717
  /** OP connection property name on the target, e.g. Visibility */
@@ -12409,6 +13750,10 @@ export interface FBXAnimationLayerData {
12409
13750
  normalizedWeight: number;
12410
13751
  /** Blend mode: 0=Additive, 1=Override, 2=OverridePassthrough */
12411
13752
  blendMode: number;
13753
+ /** Resolved blend semantics used by the evaluator */
13754
+ blend: FBXLayerBlend;
13755
+ /** Animated layer weight (0-100), when the Weight property carries a curve */
13756
+ weightCurve?: FBXCurveData;
12412
13757
  /** Curve nodes in this layer */
12413
13758
  curveNodes: FBXCurveNodeData[];
12414
13759
  /** Unsupported/non-TRS curve nodes preserved for diagnostics */
@@ -12416,6 +13761,14 @@ export interface FBXAnimationLayerData {
12416
13761
  /** Recoverable layer diagnostics */
12417
13762
  diagnostics: FBXAnimationDiagnostic[];
12418
13763
  }
13764
+ /** Options for animation extraction. */
13765
+ export interface FBXAnimationExtractOptions {
13766
+ /**
13767
+ * Shift each clip so its first key sits at time 0 (default true). False keeps the times authored in the file, so
13768
+ * clips of one file stay aligned with each other and with the declared stack range.
13769
+ */
13770
+ rebaseKeyframes?: boolean;
13771
+ }
12419
13772
  /** One animation clip (AnimationStack) */
12420
13773
  export interface FBXAnimationStackData {
12421
13774
  /** Animation name */
@@ -12438,13 +13791,7 @@ export interface FBXAnimationStackData {
12438
13791
  /**
12439
13792
  * Extract all animation stacks from the FBX scene.
12440
13793
  */
12441
- export function extractAnimations(objectMap: FBXObjectMap): FBXAnimationStackData[];
12442
- /**
12443
- * Determines whether a key sequence appears to be a uniformly frame-baked sampled curve.
12444
- * @param keys - Keyframes to inspect
12445
- * @returns true if the keys look like sampled frame data rather than authored interpolation
12446
- */
12447
- export function isFrameBakedSampledCurve(keys: readonly FBXKeyframe[]): boolean;
13794
+ export function extractAnimations(objectMap: FBXObjectMap, doc?: FBXDocument, options?: FBXAnimationExtractOptions): FBXAnimationStackData[];
12448
13795
  /**
12449
13796
  * Samples an FBX animation curve at a specific time.
12450
13797
  * @param curveData - Curve data to sample
@@ -12452,6 +13799,54 @@ export function isFrameBakedSampledCurve(keys: readonly FBXKeyframe[]): boolean;
12452
13799
  * @returns The sampled value, or null when the curve has no keys
12453
13800
  */
12454
13801
  export function sampleFBXCurveAtTime(curveData: FBXCurveData | undefined, time: number): number | null;
13802
+ /**
13803
+ * Pre-7000 files store animation in a top-level `Takes` block instead of AnimationStack/Layer/CurveNode objects:
13804
+ *
13805
+ * Takes: { Take: "name" { LocalTime: start, stop
13806
+ * Model: "Model::joint1" { Channel: "Transform" { Channel: "T" { Channel: "X" { Default, KeyVer, KeyCount, Key } } } } } }
13807
+ *
13808
+ * Each take becomes one animation stack with a single layer. Models are matched through the same legacy string ids
13809
+ * that the connection resolver synthesizes for 6.x objects.
13810
+ */
13811
+ export function extractLegacyTakes(doc: FBXDocument, objectMap: FBXObjectMap, rebaseKeyframes?: boolean): FBXAnimationStackData[];
13812
+ /**
13813
+ * Evaluates one transform channel (T, R or S) of a target at `time`, blending every animation layer of the stack the
13814
+ * way the FBX SDK does: the first layer animating the channel replaces the static value, later layers are combined
13815
+ * according to their blend mode, weight and accumulation modes.
13816
+ * @param curveNodes - Curve nodes targeting this model (any layers, any types)
13817
+ * @param layers - Stack layers, in order
13818
+ * @param type - Channel to evaluate
13819
+ * @param staticValue - Value when nothing animates the channel
13820
+ * @param rotationOrder - Rotation order of the target (for rotation composition)
13821
+ * @param time - Time in seconds
13822
+ */
13823
+ 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];
13824
+ /** Curves of one animated property (or blend shape weight) contributed by one animation layer. */
13825
+ export interface FBXLayeredPropertySource {
13826
+ /** Index of the owning layer within the stack's layer list */
13827
+ layerIndex: number;
13828
+ /** Curves of the property, keyed by channel name (`d|X`, `d|DeformPercent`, ...) */
13829
+ curves: readonly FBXCurveData[];
13830
+ /** Default channel values stored on the curve node */
13831
+ defaultValues?: Record<string, number>;
13832
+ }
13833
+ /**
13834
+ * Evaluates an animated property through the animation layers: the base layer replaces the static value, every
13835
+ * further layer blends onto the running result according to its blend mode and (possibly animated) weight, like
13836
+ * `evaluateLayeredChannel` does for transforms.
13837
+ * @param sources - Per-layer curves of the property
13838
+ * @param layers - Stack layers, in order
13839
+ * @param channels - Channel names to evaluate, in output order
13840
+ * @param staticValue - Value per channel when nothing animates it
13841
+ * @param time - Time in seconds
13842
+ * @returns One value per channel
13843
+ */
13844
+ export function evaluateLayeredProperty(sources: readonly FBXLayeredPropertySource[], layers: readonly FBXAnimationLayerData[], channels: readonly string[], staticValue: readonly number[], time: number): number[];
13845
+ /**
13846
+ * True when every curve of the given channel is inside a constant (stepped) segment at `time`, so a baked key at
13847
+ * that time should hold its value instead of interpolating towards the next sample.
13848
+ */
13849
+ export function isChannelSteppedAt(curveNodes: readonly FBXCurveNodeData[], type: "T" | "R" | "S", time: number): boolean;
12455
13850
 
12456
13851
  }
12457
13852
  declare module "babylonjs-loaders/BVH/pure" {
@@ -21468,28 +22863,446 @@ declare namespace BABYLON.GLTF1 {
21468
22863
  loadShaderStringAsync(gltfRuntime: BABYLON.GLTF1.IGLTFRuntime, id: string, onSuccess: (shaderString: string) => void): boolean;
21469
22864
  }
21470
22865
  /**
21471
- * Registers the KHR_binary_glTF extension.
22866
+ * Registers the KHR_binary_glTF extension.
22867
+ * Safe to call multiple times; only the first call has an effect.
22868
+ */
22869
+ export function RegisterGLTFBinaryExtension(): void;
22870
+
22871
+
22872
+
22873
+ }
22874
+ declare namespace BABYLON {
22875
+
22876
+
22877
+ }
22878
+ declare namespace BABYLON.GLTF1 {
22879
+ /**
22880
+ * Re-exports the pure implementation and applies the runtime registration side effect.
22881
+ * Import "./glTFBinaryExtension.pure" for tree-shakeable, side-effect-free usage.
22882
+ */
22883
+
22884
+
22885
+
22886
+ }
22887
+ declare namespace BABYLON {
22888
+
22889
+ export interface WorkerAsset {
22890
+ bytes: Uint8Array;
22891
+ fileName: string;
22892
+ files?: Record<string, Uint8Array>;
22893
+ resolveByFileName: boolean;
22894
+ glueUrl?: string;
22895
+ wasmUrl?: string;
22896
+ dataUrl?: string;
22897
+ }
22898
+ export interface ExtractRequest {
22899
+ type: "extract";
22900
+ requestId: number;
22901
+ asset: WorkerAsset;
22902
+ }
22903
+ export interface WorkerTimings {
22904
+ totalMs: number;
22905
+ stageOpenMs: number;
22906
+ stageReadMs: number;
22907
+ preparationMs: number;
22908
+ packingMs: number;
22909
+ heapCopyMs: number;
22910
+ }
22911
+ export interface WorkerStatistics {
22912
+ nodes: number;
22913
+ meshes: number;
22914
+ analyticPrimitives: number;
22915
+ instances: number;
22916
+ materials: number;
22917
+ vertices: number;
22918
+ triangles: number;
22919
+ commandBytes: number;
22920
+ dataBytes: number;
22921
+ }
22922
+ export type WorkerResponse = {
22923
+ type: "progress";
22924
+ requestId: number;
22925
+ progress: USDLoadProgress;
22926
+ } | {
22927
+ type: "log";
22928
+ requestId: number;
22929
+ level: number;
22930
+ message: string;
22931
+ } | {
22932
+ type: "result";
22933
+ requestId: number;
22934
+ commands: ArrayBuffer;
22935
+ data: ArrayBuffer;
22936
+ timings: WorkerTimings;
22937
+ statistics: WorkerStatistics;
22938
+ missingAssets: string[];
22939
+ } | {
22940
+ type: "error";
22941
+ requestId: number;
22942
+ message: string;
22943
+ stack?: string;
22944
+ };
22945
+
22946
+
22947
+ export interface MaterializationResult {
22948
+ container: AbstractAssetContainer & {
22949
+ dispose(): void;
22950
+ };
22951
+ materializeMs: number;
22952
+ }
22953
+ export function materializeCommandBuffers(scene: Scene, commandBuffer: ArrayBuffer, dataBuffer: ArrayBuffer, addToScene: boolean, signal?: AbortSignal): Promise<MaterializationResult>;
22954
+
22955
+
22956
+ /**
22957
+ * Binary input accepted for supporting USD layers and assets.
22958
+ */
22959
+ export type USDBinaryInput = ArrayBuffer | ArrayBufferView;
22960
+ /**
22961
+ * Virtual files supplied alongside the root USD layer, keyed by their path relative to the
22962
+ * root layer.
22963
+ */
22964
+ export type USDVirtualFiles = Readonly<Record<string, USDBinaryInput>>;
22965
+ /**
22966
+ * Progress phases reported by the USD worker and Babylon materializer.
22967
+ */
22968
+ export interface USDLoadProgress {
22969
+ /**
22970
+ * Current importer phase.
22971
+ */
22972
+ phase: "initializing" | "staging" | "extracting" | "materializing";
22973
+ /**
22974
+ * Human-readable phase description.
22975
+ */
22976
+ message: string;
22977
+ }
22978
+ /**
22979
+ * Options for the OpenUSD scene loader.
22980
+ */
22981
+ export interface USDFileLoaderOptions {
22982
+ /**
22983
+ * Virtual path used to stage the root layer. Set this when supporting files need
22984
+ * to resolve relative to a directory hierarchy.
22985
+ */
22986
+ rootFileName?: string;
22987
+ /**
22988
+ * Supporting layers, payloads, and textures keyed by virtual path in the same
22989
+ * virtual file system as `rootFileName`.
22990
+ */
22991
+ files?: USDVirtualFiles;
22992
+ /**
22993
+ * Enables conservative file-name fallback for unresolved absolute references.
22994
+ * Defaults to true.
22995
+ */
22996
+ resolveByFileName?: boolean;
22997
+ /**
22998
+ * URL of the module worker. Defaults to the protocol-versioned worker hosted on the Babylon.js CDN.
22999
+ */
23000
+ workerUrl?: string | URL;
23001
+ /**
23002
+ * URL of the generated Emscripten JavaScript module.
23003
+ */
23004
+ glueUrl?: string;
23005
+ /**
23006
+ * URL of the OpenUSD WebAssembly binary.
23007
+ */
23008
+ wasmUrl?: string;
23009
+ /**
23010
+ * URL of the OpenUSD preloaded resource bundle.
23011
+ */
23012
+ dataUrl?: string;
23013
+ /**
23014
+ * Called when the importer moves to a new processing phase.
23015
+ */
23016
+ onProgress?: (progress: USDLoadProgress) => void;
23017
+ /**
23018
+ * Called for OpenUSD diagnostic messages.
23019
+ */
23020
+ onLog?: (level: "info" | "warning" | "error", message: string) => void;
23021
+ /**
23022
+ * Called after extraction and Babylon.js object creation complete.
23023
+ */
23024
+ onComplete?: (diagnostics: USDImportDiagnostics) => void;
23025
+ }
23026
+ /**
23027
+ * Timing data measured by the OpenUSD worker and Babylon materializer.
23028
+ */
23029
+ export interface USDImportTimings {
23030
+ /** Total extraction time, including the final Wasm heap copy. */
23031
+ totalMs: number;
23032
+ /** Time spent opening and composing the USD stage. */
23033
+ stageOpenMs: number;
23034
+ /** Time spent traversing the composed stage. */
23035
+ stageReadMs: number;
23036
+ /** Time spent preparing renderable vertex streams. */
23037
+ preparationMs: number;
23038
+ /** Time spent packing the command and raw-data buffers. */
23039
+ packingMs: number;
23040
+ /** Time spent copying command and data buffers from the Wasm heap. */
23041
+ heapCopyMs: number;
23042
+ /** Time spent creating Babylon.js objects. */
23043
+ materializeMs: number;
23044
+ }
23045
+ /**
23046
+ * Statistics reported for an imported USD stage.
23047
+ */
23048
+ export interface USDImportStatistics {
23049
+ /** Number of transform nodes extracted from the composed stage. */
23050
+ nodes: number;
23051
+ /** Number of polygonal `UsdGeomMesh` sources. */
23052
+ meshes: number;
23053
+ /** Number of analytic cube, sphere, cylinder, and cone sources. */
23054
+ analyticPrimitives: number;
23055
+ /** Number of native Babylon instances created from shared USD geometry. */
23056
+ instances: number;
23057
+ /** Number of authored USD materials translated. */
23058
+ materials: number;
23059
+ /** Number of unique vertices in polygonal source meshes. */
23060
+ vertices: number;
23061
+ /** Number of unique triangles in polygonal source meshes. */
23062
+ triangles: number;
23063
+ /** Size of the command buffer in bytes. */
23064
+ commandBytes: number;
23065
+ /** Size of the raw-data buffer in bytes. */
23066
+ dataBytes: number;
23067
+ }
23068
+ /**
23069
+ * Diagnostics reported after a USD import completes.
23070
+ */
23071
+ export interface USDImportDiagnostics {
23072
+ /** Timing data for extraction and Babylon.js object creation. */
23073
+ timings: USDImportTimings;
23074
+ /** Counts and buffer sizes reported by the OpenUSD extractor. */
23075
+ statistics: USDImportStatistics;
23076
+ /** Asset references OpenUSD could not resolve from the supplied virtual files. */
23077
+ missingAssets: readonly string[];
23078
+ }
23079
+
23080
+
23081
+ interface SceneLoaderPluginOptions {
23082
+ /**
23083
+ * Defines options for the USD loader.
23084
+ */
23085
+ [USDFileLoaderMetadata.name]: Partial<USDFileLoaderOptions>;
23086
+ }
23087
+
23088
+
23089
+ /** This file must only contain pure code and pure imports */
23090
+ /**
23091
+ * OpenUSD scene loader backed by a WebAssembly command-buffer extractor.
23092
+ */
23093
+ export class USDFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
23094
+ /**
23095
+ * Default URLs for the prebuilt OpenUSD importer assets.
23096
+ */
23097
+ static DefaultConfiguration: {
23098
+ glueUrl: string;
23099
+ wasmUrl: string;
23100
+ dataUrl: string;
23101
+ workerUrl: string;
23102
+ };
23103
+ /**
23104
+ * Defines the name of the plugin.
23105
+ */
23106
+ readonly name: "usd";
23107
+ /**
23108
+ * Defines the extensions the plugin can load.
23109
+ */
23110
+ readonly extensions: {
23111
+ readonly ".usd": {
23112
+ readonly isBinary: true;
23113
+ };
23114
+ readonly ".usda": {
23115
+ readonly isBinary: true;
23116
+ };
23117
+ readonly ".usdc": {
23118
+ readonly isBinary: true;
23119
+ };
23120
+ readonly ".usdz": {
23121
+ readonly isBinary: true;
23122
+ };
23123
+ };
23124
+ private readonly _options;
23125
+ private _worker;
23126
+ private _workerUrl;
23127
+ private _workerBlobUrl;
23128
+ private _nextRequestId;
23129
+ private readonly _pending;
23130
+ private readonly _activeLoads;
23131
+ /**
23132
+ * Creates a USD loader.
23133
+ * @param options Options controlling worker assets, supporting files, and diagnostics.
23134
+ */
23135
+ constructor(options?: Partial<USDFileLoaderOptions>);
23136
+ /**
23137
+ * Creates a configured plugin instance for a SceneLoader operation.
23138
+ * @param options SceneLoader plugin options.
23139
+ * @returns The configured USD loader.
23140
+ */
23141
+ createPlugin(options: SceneLoaderPluginOptions): ISceneLoaderPluginAsync;
23142
+ /**
23143
+ * Imports all objects from a USD stage into a scene.
23144
+ * @param _meshesNames Mesh name filtering is not currently supported.
23145
+ * @param scene The scene receiving the imported objects.
23146
+ * @param data The USD, USDA, USDC, or USDZ bytes.
23147
+ * @param rootUrl The source root URL.
23148
+ * @param onProgress SceneLoader progress callback.
23149
+ * @param fileName Name of the root USD layer.
23150
+ * @returns The imported Babylon.js objects.
23151
+ */
23152
+ importMeshAsync(_meshesNames: string | readonly string[] | null | undefined, scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<ISceneLoaderAsyncResult>;
23153
+ /**
23154
+ * Loads a USD stage into a scene.
23155
+ * @param scene The scene receiving the imported objects.
23156
+ * @param data The USD, USDA, USDC, or USDZ bytes.
23157
+ * @param rootUrl The source root URL.
23158
+ * @param onProgress SceneLoader progress callback.
23159
+ * @param fileName Name of the root USD layer.
23160
+ */
23161
+ loadAsync(scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<void>;
23162
+ /**
23163
+ * Loads a USD stage into an asset container.
23164
+ * @param scene The scene used to create imported objects.
23165
+ * @param data The USD, USDA, USDC, or USDZ bytes.
23166
+ * @param rootUrl The source root URL.
23167
+ * @param onProgress SceneLoader progress callback.
23168
+ * @param fileName Name of the root USD layer.
23169
+ * @returns The populated asset container.
23170
+ */
23171
+ loadAssetContainerAsync(scene: Scene, data: unknown, rootUrl: string, onProgress?: (event: ISceneLoaderProgressEvent) => void, fileName?: string): Promise<AssetContainer>;
23172
+ /**
23173
+ * Releases the worker and rejects pending loads.
23174
+ */
23175
+ dispose(): void;
23176
+ private _loadAsync;
23177
+ private _getWorker;
23178
+ private _terminateWorker;
23179
+ }
23180
+ /** @internal */
23181
+ export function _RegisterUSDLoaderDependencies(): void;
23182
+ /**
23183
+ * Registers the USD scene loader plugin and its Babylon.js runtime dependencies.
21472
23184
  * Safe to call multiple times; only the first call has an effect.
21473
23185
  */
21474
- export function RegisterGLTFBinaryExtension(): void;
23186
+ export function RegisterUSDFileLoader(): void;
21475
23187
 
21476
23188
 
21477
-
21478
- }
21479
- declare namespace BABYLON {
23189
+ /**
23190
+ * Defines the USD loader plugin metadata.
23191
+ */
23192
+ export var USDFileLoaderMetadata: {
23193
+ readonly name: "usd";
23194
+ readonly extensions: {
23195
+ readonly ".usd": {
23196
+ readonly isBinary: true;
23197
+ };
23198
+ readonly ".usda": {
23199
+ readonly isBinary: true;
23200
+ };
23201
+ readonly ".usdc": {
23202
+ readonly isBinary: true;
23203
+ };
23204
+ readonly ".usdz": {
23205
+ readonly isBinary: true;
23206
+ };
23207
+ };
23208
+ };
21480
23209
 
21481
23210
 
21482
- }
21483
- declare namespace BABYLON.GLTF1 {
21484
- /**
23211
+ /**
21485
23212
  * Re-exports the pure implementation and applies the runtime registration side effect.
21486
- * Import "./glTFBinaryExtension.pure" for tree-shakeable, side-effect-free usage.
21487
- */
23213
+ * Import "./usdFileLoader.pure" for tree-shakeable, side-effect-free usage.
23214
+ */
23215
+
23216
+
23217
+ export const COMMAND_MAGIC = 1111774037;
23218
+ export const PROTOCOL_VERSION = 5;
23219
+ export const MISSING_OFFSET = 4294967295;
23220
+ export enum Command {
23221
+ Scene = 1,
23222
+ Texture = 2,
23223
+ Material = 3,
23224
+ TransformNode = 4,
23225
+ Skeleton = 5,
23226
+ Geometry = 6,
23227
+ Mesh = 7,
23228
+ Instance = 8,
23229
+ Animation = 9,
23230
+ AnalyticPrimitive = 10,
23231
+ ThinInstances = 11,
23232
+ MorphTarget = 12
23233
+ }
23234
+ export enum AnalyticPrimitiveType {
23235
+ Cube = 0,
23236
+ Sphere = 1,
23237
+ Cylinder = 2,
23238
+ Cone = 3
23239
+ }
23240
+ export enum PrimitiveAxis {
23241
+ X = 0,
23242
+ Y = 1,
23243
+ Z = 2
23244
+ }
23245
+ export enum AnimationTarget {
23246
+ Node = 0,
23247
+ Bone = 1,
23248
+ MorphTarget = 2
23249
+ }
23250
+ export enum AnimationProperty {
23251
+ Position = 0,
23252
+ RotationQuaternion = 1,
23253
+ Scaling = 2,
23254
+ Matrix = 3,
23255
+ Influence = 4
23256
+ }
23257
+ export enum MaterialFlags {
23258
+ DoubleSided = 1,
23259
+ Unlit = 2,
23260
+ AlphaBlend = 4
23261
+ }
23262
+ export enum TextureOutputChannel {
23263
+ R = 0,
23264
+ G = 1,
23265
+ B = 2,
23266
+ A = 3,
23267
+ RGB = 4
23268
+ }
23269
+ export enum USDTextureColorSpace {
23270
+ Auto = 0,
23271
+ Raw = 1,
23272
+ SRGB = 2
23273
+ }
23274
+ export enum MeshFlags {
23275
+ DoubleSided = 1,
23276
+ LeftHanded = 2
23277
+ }
23278
+ export enum GeometryFlags {
23279
+ Normals = 1,
23280
+ Tangents = 2,
23281
+ Uv0 = 4,
23282
+ Colors = 8,
23283
+ Skin0 = 16,
23284
+ Skin1 = 32
23285
+ }
23286
+ export interface CommandRecord {
23287
+ opcode: Command;
23288
+ flags: number;
23289
+ payloadOffset: number;
23290
+ payloadLength: number;
23291
+ }
23292
+ export function readCommands(buffer: ArrayBuffer): CommandRecord[];
23293
+ export class PayloadReader {
23294
+ #private;
23295
+ offset: number;
23296
+ constructor(buffer: ArrayBuffer, offset: number, length: number);
23297
+ u32(): number;
23298
+ f32(): number;
23299
+ }
23300
+
23301
+
23302
+ /** Pure barrel — re-exports only side-effect-free modules */
21488
23303
 
21489
23304
 
21490
23305
 
21491
- }
21492
- declare namespace BABYLON {
21493
23306
 
21494
23307
  interface SceneLoaderPluginOptions {
21495
23308
  /**
@@ -22459,6 +24272,18 @@ declare namespace BABYLON {
22459
24272
  * Selects which LOD value drives the {@link GaussianSplattingStream} debug wireframe colors.
22460
24273
  */
22461
24274
  export type GaussianSplattingStreamDebugLodSource = "optimal" | "current";
24275
+ /**
24276
+ * Immutable metadata-resolution state for a stream's total number of finest-LOD splats.
24277
+ * @experimental
24278
+ */
24279
+ export type GaussianSplattingStreamLod0SplatCount = Readonly<{
24280
+ status: "pending";
24281
+ }> | Readonly<{
24282
+ status: "available";
24283
+ count: number;
24284
+ }> | Readonly<{
24285
+ status: "unavailable";
24286
+ }>;
22462
24287
  /**
22463
24288
  * Options for {@link GaussianSplattingStream}.
22464
24289
  */
@@ -22578,6 +24403,7 @@ declare namespace BABYLON {
22578
24403
  private readonly _rootUrl;
22579
24404
  private readonly _streamOptions;
22580
24405
  private readonly _leafNodes;
24406
+ private _lod0SplatCount;
22581
24407
  private _lodBaseDistance;
22582
24408
  private _lodMultiplier;
22583
24409
  private _lodBehindPenalty;
@@ -22742,6 +24568,19 @@ declare namespace BABYLON {
22742
24568
  * @experimental
22743
24569
  */
22744
24570
  get effectiveSplatBudget(): number;
24571
+ /**
24572
+ * The resolved maximum number of splats kept resident in the work buffer. This combines
24573
+ * {@link IGaussianSplattingStreamOptions.maxResidentSplats} and {@link IGaussianSplattingStreamOptions.memoryBudgetMb},
24574
+ * taking the smaller limit when both are configured. `0` means the resident budget is disabled.
24575
+ * @experimental
24576
+ */
24577
+ get residentSplatBudget(): number;
24578
+ /**
24579
+ * The total number of splats represented by valid level-0 leaf entries. This remains pending while source
24580
+ * metadata is loading and is unavailable when no applicable level-0 entries exist or required metadata fails.
24581
+ * @experimental
24582
+ */
24583
+ get lod0SplatCount(): GaussianSplattingStreamLod0SplatCount;
22745
24584
  /**
22746
24585
  * Resolves the raw {@link splatBudget} option to a concrete cap: `undefined` ⇒ 0 (disabled), `"auto"` ⇒ a
22747
24586
  * device-tiered default, a positive number ⇒ itself (floored).
@@ -22911,6 +24750,11 @@ declare namespace BABYLON {
22911
24750
  * @returns sorted unique file indices
22912
24751
  */
22913
24752
  private _collectAllFileIds;
24753
+ /**
24754
+ * Settles the level-0 diagnostic from normalized renderable leaf entries after their source metadata resolves.
24755
+ * A file may back several leaf ranges, so its source count is deliberately not used in the total.
24756
+ */
24757
+ private _resolveLod0SplatCount;
22914
24758
  /**
22915
24759
  * Fetches the environment bundle and every referenced file's metadata to learn splat counts, caching
22916
24760
  * each file's parsed metadata for the later on-demand decode. Metadata fetches run in parallel.
@@ -24068,12 +25912,83 @@ declare namespace BABYLON {
24068
25912
  * Defines options for the FBX loader.
24069
25913
  */
24070
25914
  export interface FBXFileLoaderOptions {
25915
+ /**
25916
+ * Bundle of defaults for the options that change what the loaded scene looks like.
25917
+ * - "compatible" (default): the behaviour of the loader as first shipped: StandardMaterial for every material,
25918
+ * one Babylon geometry per model, curve geometry skipped, constraints recorded as metadata only, clips rebased
25919
+ * to start at frame 0, cameras and lights placed in world space.
25920
+ * - "full": everything the loader can do: PBRMaterial for physically based shaders, geometry shared between
25921
+ * instances, curves as lines meshes, constraints solved at runtime, authored clip times, cameras and lights
25922
+ * parented to their nodes so they animate.
25923
+ * An option set explicitly always wins over the preset.
25924
+ */
25925
+ preset?: "compatible" | "full";
24071
25926
  /**
24072
25927
  * Source convention for tangent-space normal maps connected through FBX normal-map slots.
24073
25928
  * FBX does not standardize this convention, so the loader defaults to the glTF/USD-style Y-up convention.
24074
25929
  * Set to "y-down" for assets authored with inverted green/Y normal maps.
24075
25930
  */
24076
25931
  normalMapCoordinateSystem?: FBXNormalMapCoordinateSystem;
25932
+ /**
25933
+ * Which Babylon material to build.
25934
+ * - "standard" (default, "full" preset: "auto"): always StandardMaterial (PBR parameters are approximated).
25935
+ * - "auto": PBRMaterial for physically based FBX materials (Standard Surface, Arnold, 3ds Max Physical,
25936
+ * 3ds Max PBR, glTF, OpenPBR, Stingray PBS) and StandardMaterial for classic Lambert/Phong materials.
25937
+ * - "pbr": always PBRMaterial (Lambert/Phong parameters are converted).
25938
+ */
25939
+ materials?: "auto" | "standard" | "pbr";
25940
+ /**
25941
+ * Unit conversion applied at the root of the loaded hierarchy.
25942
+ * - "preserve" (default): keep the file's units (1 Babylon unit = 1 FBX unit).
25943
+ * - "meters": scale so that 1 Babylon unit is 1 meter, using the file's UnitScaleFactor.
25944
+ * - a number: centimeters per Babylon unit (100 = meters, 1 = centimeters, 2.54 = inches).
25945
+ */
25946
+ unitScale?: "preserve" | "meters" | number;
25947
+ /**
25948
+ * Share vertex data between models that reference the same FBX geometry (default false, "full" preset: true).
25949
+ * Skinned meshes are never shared.
25950
+ */
25951
+ shareGeometry?: boolean;
25952
+ /**
25953
+ * Called for every recoverable issue found while loading (unsupported features, malformed data that was
25954
+ * skipped, approximations). The same list is stored on the root node's metadata as `fbxDiagnostics`.
25955
+ */
25956
+ onWarning?: (warning: FBXLoaderWarning) => void;
25957
+ /**
25958
+ * Segments per knot span when tessellating NURBS surfaces. Zero or undefined uses the subdivision stored in
25959
+ * the file (usually 4), capped at 16.
25960
+ */
25961
+ nurbsSubdivision?: number;
25962
+ /** How curve geometry (Line, NurbsCurve) is imported: skipped (default) or as lines meshes ("full" preset). */
25963
+ curves?: "lines" | "skip";
25964
+ /**
25965
+ * Constraints (aim, parent, position, rotation, scale): "metadata" (default) only records them on the nodes,
25966
+ * "apply" ("full" preset) attaches an `FBXConstraintBehavior` to each constrained node so it is solved before
25967
+ * every render. IK chains are always metadata only.
25968
+ */
25969
+ constraints?: "apply" | "metadata";
25970
+ /**
25971
+ * Shift every clip so its first keyframe sits at frame 0 (default true). With false ("full" preset) keys keep
25972
+ * the times authored in the file, so clips of one file stay aligned with each other and with their declared
25973
+ * ranges.
25974
+ */
25975
+ rebaseAnimations?: boolean;
25976
+ /**
25977
+ * Parent cameras and lights to their FBX node so they follow its animation (default false, "full" preset:
25978
+ * true). Otherwise they are created at the node's world position and orientation, unparented.
25979
+ */
25980
+ attachCamerasAndLights?: boolean;
25981
+ }
25982
+ /** A recoverable issue reported while loading an FBX file. */
25983
+ export interface FBXLoaderWarning {
25984
+ /** Which part of the loader reported the issue */
25985
+ source: "scene" | "model" | "geometry" | "skin" | "rig" | "animation" | "blendShape" | "camera" | "light";
25986
+ /** Human readable description */
25987
+ message: string;
25988
+ /** Name of the affected object, when known */
25989
+ objectName?: string;
25990
+ /** Structured details from the interpreter, when any */
25991
+ details?: unknown;
24077
25992
  }
24078
25993
  /**
24079
25994
  * FBX file loader plugin for Babylon.js.
@@ -24096,6 +26011,22 @@ declare namespace BABYLON {
24096
26011
  private readonly _bindRestBones;
24097
26012
  private readonly _sourceBonesBySkeleton;
24098
26013
  private readonly _scaleCompensationHelpersBySkeleton;
26014
+ /** Frame rate of the file being loaded (GlobalSettings TimeMode); animation is baked at this rate. */
26015
+ private _frameRate;
26016
+ /** Layers of the animation stack currently being converted; used by the transform samplers. */
26017
+ private _activeLayers;
26018
+ /** Parent model per model id, for inherit-mode aware sampling. */
26019
+ private _parentModelById;
26020
+ /** Curve nodes per model id for the stack currently being converted. */
26021
+ private _curveNodesByModelId;
26022
+ /** Helper nodes inserted above models whose InheritType is not RSrs. */
26023
+ private _inheritScaleHelpers;
26024
+ /** First mesh built per (geometry, geometric transform), for geometry sharing between instances. */
26025
+ private _meshByGeometryKey;
26026
+ /** Instance mesh -> source mesh whose geometry it shares. */
26027
+ private _instanceSource;
26028
+ /** Property curve nodes that were mapped onto Babylon animations; their "not evaluated" diagnostics are dropped. */
26029
+ private _evaluatedCurveNodeIds;
24099
26030
  /**
24100
26031
  * Creates a new FBX loader.
24101
26032
  * @param options - Options controlling FBX loading behavior
@@ -24138,6 +26069,11 @@ declare namespace BABYLON {
24138
26069
  * @returns A promise containing the loaded asset container
24139
26070
  */
24140
26071
  loadAssetContainerAsync(scene: Scene, data: unknown, rootUrl: string, _onProgress?: (event: ISceneLoaderProgressEvent) => void, _fileName?: string): Promise<AssetContainer>;
26072
+ /**
26073
+ * Parses and interprets the file. Parsing is synchronous, so no progress events are emitted: the scene loader's
26074
+ * progress callback reports download bytes and must not be fed synthetic counts.
26075
+ */
26076
+ private _parseAndInterpret;
24141
26077
  private _parse;
24142
26078
  private _parseFromArrayBuffer;
24143
26079
  private _buildScene;
@@ -24149,6 +26085,15 @@ declare namespace BABYLON {
24149
26085
  private _linkSkeletonsToTransformNodes;
24150
26086
  private static _modelSubtreeMatchesNameFilter;
24151
26087
  private static _applyModelMetadata;
26088
+ /**
26089
+ * Wires a LodGroup's children as Babylon LOD levels: the first child holds the highest detail; every further
26090
+ * child replaces it beyond the group's threshold distance (or screen coverage when thresholds are percentages).
26091
+ * Each child's display mode is honoured first: level 1 (show) stays visible outside the LOD chain, level 2
26092
+ * (hide) is disabled, and only level 0 (use LOD) children take part in the distance switching.
26093
+ */
26094
+ private static _applyLodGroup;
26095
+ /** Builds a lines mesh from Line or tessellated NurbsCurve geometry, applying the model's geometric transform. */
26096
+ private _createLinesMesh;
24152
26097
  private _createMesh;
24153
26098
  /**
24154
26099
  * Apply multi-material to a mesh by creating sub-meshes grouped by material index.
@@ -24172,6 +26117,11 @@ declare namespace BABYLON {
24172
26117
  */
24173
26118
  private _buildSkinningData;
24174
26119
  private _createMaterial;
26120
+ private _createPbrMaterial;
26121
+ /** Alpha of a classic Lambert/Phong material: Opacity when present, otherwise 1 - TransparentColor * TransparencyFactor. */
26122
+ private static _alphaFromClassicTransparency;
26123
+ private static _applyTextureSettings;
26124
+ private _createStandardMaterial;
24175
26125
  private _configureNormalTexture;
24176
26126
  private _getNormalMapTangentHandednessScale;
24177
26127
  private static _isSupportedMaterialTextureSlot;
@@ -24195,11 +26145,27 @@ declare namespace BABYLON {
24195
26145
  private _createCamera;
24196
26146
  private _createLight;
24197
26147
  private _createSkeleton;
26148
+ private _rigBoneModelIds;
26149
+ private _isRigBone;
24198
26150
  private _getSourceBone;
24199
26151
  private _getScaleCompensationHelper;
24200
26152
  private static _computeFBXAbsoluteMatrices;
26153
+ /**
26154
+ * Effective ("inherit") scale of every bone, following the FBX SDK: the local scale for RSrs bones, and for
26155
+ * RrSs / Rrs bones the local scale multiplied by the scale of the bone's inherit-scale node (the parent for RrSs,
26156
+ * the parent's inherit-scale node for Rrs). Bones are ordered parents first.
26157
+ */
26158
+ private static _computeBoneInheritScales;
26159
+ private static _getBoneInheritScaleNode;
26160
+ /** Scale a bone inherits into its own scale (RrSs chains), or unit scale. */
26161
+ private static _getBoneInheritedScale;
24201
26162
  private static _computeFBXRuntimeLocalMatrix;
24202
26163
  private static _applyParentScaleCompensation;
26164
+ /**
26165
+ * Splits a bone's FBX local matrix into a helper (which cancels the parent scale and carries the translation,
26166
+ * so the translation still follows the parent scale as the SDK does) and the bone's own rotation/scale. For RrSs
26167
+ * bones the inherited scale is folded into the bone scale.
26168
+ */
24203
26169
  private static _splitParentScaleCompensatedLocalMatrix;
24204
26170
  private static _safeInverseScale;
24205
26171
  private static _getInverseScaleVector;
@@ -24216,13 +26182,8 @@ declare namespace BABYLON {
24216
26182
  * In row-vector convention: v' = v * M
24217
26183
  */
24218
26184
  private static _computeFBXLocalMatrix;
24219
- /**
24220
- * Apply the FBX transform chain to a Babylon TransformNode or Mesh.
24221
- * Decomposes the full local matrix into position/rotation/scale.
24222
- */
24223
- private static _applyFBXTransform;
26185
+ private _applyRestTRS;
24224
26186
  private static _computeFBXModelLocalMatrix;
24225
- private static _getBoneReferenceWorldMatrix;
24226
26187
  private static _applyMatrixToTransform;
24227
26188
  private _createAnimationGroup;
24228
26189
  private _buildInheritedRigBoneAnimations;
@@ -24232,9 +26193,61 @@ declare namespace BABYLON {
24232
26193
  * Computes the full FBX transform matrix at each keyframe and decomposes into TRS.
24233
26194
  */
24234
26195
  private _buildNodeAnimations;
26196
+ /**
26197
+ * Baked keys are interpolated linearly by Babylon. Between two frames an FBX cubic segment can deviate from that
26198
+ * line, so sample times are refined (midpoints inserted, up to two levels) wherever the interpolated transform
26199
+ * differs noticeably from the curve. Flat and linear segments stay at frame resolution.
26200
+ */
26201
+ private static _refineSampleTimes;
26202
+ /**
26203
+ * Keys of a scalar property animated by one or more layers: the authored keys when a single layer drives it,
26204
+ * otherwise the frame grid evaluated through the layer stack.
26205
+ * @param sources - Per-layer curves of the property (each with at least one curve)
26206
+ * @param animStack - Stack being converted
26207
+ * @param mapValue - Conversion from the FBX value to the Babylon property value
26208
+ * @returns Animation keys
26209
+ */
26210
+ private _layeredScalarKeys;
26211
+ /**
26212
+ * Maps an animated FBX property (anything other than node transforms and blend shape weights) onto the Babylon
26213
+ * property that carries it: mesh visibility, camera field of view and clip planes, light intensity, colour and
26214
+ * cone angles, and material colours, alpha, roughness and metalness. `group` holds the curve nodes of every
26215
+ * layer animating that property, in layer order; several layers are evaluated through the layer stack.
26216
+ */
26217
+ private _buildPropertyAnimations;
26218
+ /** Records constraints on their nodes and, unless disabled, attaches the runtime behavior that solves them. */
26219
+ private _applyConstraints;
26220
+ /** Collects every recoverable issue the interpreter recorded, stores it on the root node and notifies the caller. */
26221
+ private _reportDiagnostics;
26222
+ /** Curve nodes affecting the inherit scale of a model: its own scale curves and those of its inherit-scale chain. */
26223
+ private _collectInheritScaleCurves;
24235
26224
  private _isVector3KeysConstant;
26225
+ /** Samples the animated Lcl Translation / Rotation / Scaling of a model, blending all layers of the active stack. */
26226
+ private _sampleModelTRS;
26227
+ /**
26228
+ * Local position/rotation/scale of a model from FBX Lcl values. Without pivots and offsets the components map
26229
+ * directly (rotation = pre * lcl * post⁻¹), which keeps zero and negative scales exact. With pivots the full
26230
+ * matrix is built and decomposed.
26231
+ */
26232
+ private static _computeLocalTRS;
26233
+ /** Applies inherit-mode adjustments to a local TRS (see _computeInheritAwareLocalMatrix). */
26234
+ private _adjustTRSForInheritMode;
24236
26235
  private _sampleModelLocalMatrix;
24237
26236
  private _sampleModelScale;
26237
+ /**
26238
+ * Effective scale of a model for inherit-mode math (`inherit_scale` in ufbx terms): its own local scale, multiplied
26239
+ * componentwise by the inherited scale when the model uses RrSs inheritance. `time` samples animation; undefined
26240
+ * uses the rest pose.
26241
+ */
26242
+ private _getInheritScale;
26243
+ /** RrSs nodes inherit scale from their parent; Rrs nodes skip their immediate parent (chaining through Rrs parents). */
26244
+ private _getInheritScaleNode;
26245
+ /**
26246
+ * Local matrix of a model relative to its Babylon parent frame, accounting for inherit modes. For RSrs (the
26247
+ * default) this is the FBX local matrix. For RrSs / Rrs the node sits under a helper that removes the parent's
26248
+ * scale, so translation is pre-scaled by the parent scale and (for RrSs) scale accumulates componentwise.
26249
+ */
26250
+ private _computeInheritAwareLocalMatrix;
24238
26251
  /**
24239
26252
  * Build matrix-baked bone animation from full FBX local transforms.
24240
26253
  * The bind matrix carries the skinning offset, so animation curves drive
@@ -24269,6 +26282,189 @@ declare namespace BABYLON {
24269
26282
  */
24270
26283
 
24271
26284
 
26285
+ /**
26286
+ * Runtime evaluation of FBX constraints. An `FBXConstraintBehavior` is attached to each constrained node; all
26287
+ * behaviors of a scene register with one `FBXConstraintSolver`, which solves them in dependency order (a constraint
26288
+ * whose target or parent is driven by another constraint is solved after it) and reuses scratch objects, so solving
26289
+ * allocates nothing per frame.
26290
+ *
26291
+ * The solver brackets the scene's animation phase: before animations run it writes each node's unconstrained
26292
+ * transform back, after they ran it captures the result as the new unconstrained transform and solves. A partial
26293
+ * weight therefore always blends from what animation (or nothing) produced this frame, never from the previous
26294
+ * solve's output, so a 50% weight stays a 50% blend instead of converging on the target.
26295
+ *
26296
+ * All maths happen in FBX space, i.e. relative to the loader's root node, so the handedness conversion applied
26297
+ * at the root never enters the solve.
26298
+ */
26299
+ /** Resolved target of a constraint. */
26300
+ export interface FBXConstraintBehaviorTarget {
26301
+ /** Target node */
26302
+ node: TransformNode;
26303
+ /** Normalized target weight (0..1) */
26304
+ weight: number;
26305
+ /** Offset matrix for parent constraints (in the target's space) */
26306
+ offset: Matrix;
26307
+ }
26308
+ /** Options resolved by the loader when creating the behavior. */
26309
+ export interface FBXConstraintBehaviorOptions {
26310
+ /** Root of the loaded asset; world matrices are made relative to it */
26311
+ root: TransformNode;
26312
+ /** Resolved targets of the constraint, in file order */
26313
+ targets: FBXConstraintBehaviorTarget[];
26314
+ /** World up object of an aim constraint, when it has one */
26315
+ upNode: Nullable<TransformNode>;
26316
+ /** Scene up axis in FBX space */
26317
+ sceneUp: Vector3;
26318
+ }
26319
+ /**
26320
+ * Solves every FBX constraint of a scene once per frame, in dependency order, from the scene's animation phase
26321
+ * observers (`beginFrame` before animations, `solve` after them). Created on demand by the first
26322
+ * `FBXConstraintBehavior` attached in the scene and removed with the last one.
26323
+ */
26324
+ export class FBXConstraintSolver {
26325
+ private readonly _scene;
26326
+ private readonly _behaviors;
26327
+ private _ordered;
26328
+ private _cyclic;
26329
+ private _dirty;
26330
+ private _beforeAnimations;
26331
+ private _afterAnimations;
26332
+ private constructor();
26333
+ /**
26334
+ * Solver of a scene, if any constraint behavior is attached in it.
26335
+ * @param scene - Scene to look up
26336
+ * @returns The solver, or undefined
26337
+ */
26338
+ static Get(scene: Scene): FBXConstraintSolver | undefined;
26339
+ /**
26340
+ * Solver of a scene, created when missing.
26341
+ * @param scene - Scene to look up
26342
+ * @returns The solver
26343
+ */
26344
+ static GetOrCreate(scene: Scene): FBXConstraintSolver;
26345
+ /** Registered behaviors in solve order (a target's constraint before the constraints that read it). */
26346
+ get constraints(): readonly FBXConstraintBehavior[];
26347
+ /**
26348
+ * Behaviors that take part in a dependency cycle (A targets B while B targets A). They are solved after all
26349
+ * acyclic constraints, in registration order, so each sees the other's result from the previous solve.
26350
+ */
26351
+ get cyclicConstraints(): readonly FBXConstraintBehavior[];
26352
+ /**
26353
+ * Adds a behavior to the solve set.
26354
+ * @param behavior - Behavior to add
26355
+ */
26356
+ register(behavior: FBXConstraintBehavior): void;
26357
+ /**
26358
+ * Removes a behavior from the solve set; the solver disposes itself with the last one.
26359
+ * @param behavior - Behavior to remove
26360
+ */
26361
+ unregister(behavior: FBXConstraintBehavior): void;
26362
+ /** Marks the solve order stale, e.g. after re-parenting a constrained node. */
26363
+ invalidateOrder(): void;
26364
+ /**
26365
+ * Start of a frame, before animations run: every constrained node gets its unconstrained transform back, so
26366
+ * that animation either overwrites it or leaves it untouched.
26367
+ */
26368
+ beginFrame(): void;
26369
+ /**
26370
+ * End of the animation phase: takes every constrained node's current transform as its unconstrained value,
26371
+ * then solves every registered constraint once, in dependency order.
26372
+ */
26373
+ solve(): void;
26374
+ private _ensureOrder;
26375
+ private static _IsAncestorOrSelf;
26376
+ }
26377
+ /** Babylon behavior evaluating an FBX aim, parent, position, rotation or scale constraint. */
26378
+ export class FBXConstraintBehavior implements Behavior<TransformNode> {
26379
+ /** Constraint data extracted from the file */
26380
+ readonly constraint: FBXConstraintData;
26381
+ private readonly _options;
26382
+ /** Behavior name (`fbxConstraint:` followed by the constraint name) */
26383
+ readonly name: string;
26384
+ /** Node the behavior is attached to */
26385
+ attachedNode: Nullable<TransformNode>;
26386
+ /** Set to false to pause the constraint without detaching it */
26387
+ enabled: boolean;
26388
+ private readonly _offsetTranslation;
26389
+ private readonly _offsetRotation;
26390
+ private readonly _offsetScale;
26391
+ private readonly _localBasisTransposed;
26392
+ /** Unconstrained transform of the current frame (what animation produced), blended towards the constraint's result. */
26393
+ private readonly _base;
26394
+ private _hasBase;
26395
+ /**
26396
+ * Creates the behavior.
26397
+ * @param constraint - Constraint data extracted from the file
26398
+ * @param _options - Resolved targets and scene information
26399
+ */
26400
+ constructor(
26401
+ /** Constraint data extracted from the file */
26402
+ constraint: FBXConstraintData, _options: FBXConstraintBehaviorOptions);
26403
+ /** Nothing to initialize */
26404
+ init(): void;
26405
+ /**
26406
+ * Registers the behavior with the scene's solver, takes the node's current transform as the unconstrained
26407
+ * value and solves the constraint once.
26408
+ * @param target - Node to constrain
26409
+ */
26410
+ attach(target: TransformNode): void;
26411
+ /** Unregisters the behavior; the node keeps its last solved transform. */
26412
+ detach(): void;
26413
+ /**
26414
+ * Takes the node's current transform as the unconstrained value the next solve blends from. The solver calls
26415
+ * this after the scene's animations ran; call it yourself after writing a transform by hand.
26416
+ */
26417
+ captureBase(): void;
26418
+ /**
26419
+ * Writes the unconstrained transform back to the node. The solver calls this before the scene's animations
26420
+ * run, so a node nothing animates keeps its unconstrained value between frames instead of the solved one.
26421
+ */
26422
+ restoreBase(): void;
26423
+ /**
26424
+ * Nodes whose world transform the solve reads: the targets, the up node and the constrained node's parent.
26425
+ * @returns The nodes, used by the solver to order constraints
26426
+ */
26427
+ dependencyNodes(): Nullable<Node>[];
26428
+ /**
26429
+ * Solves the constraint from the captured unconstrained transform and writes the node's local transform.
26430
+ * Blends are relative to the value captured by `captureBase`, not to whatever the node holds now.
26431
+ */
26432
+ evaluate(): void;
26433
+ /**
26434
+ * World matrix of a node relative to the asset root (FBX space).
26435
+ * @param node - node to evaluate
26436
+ * @param out - matrix receiving the result
26437
+ * @returns `out`
26438
+ */
26439
+ private _fbxWorld;
26440
+ /**
26441
+ * Weighted blend of the targets' world transforms (relative to the root).
26442
+ * @param position - Receives the blended translation
26443
+ * @param rotation - Receives the blended rotation
26444
+ * @param scale - Receives the blended scale
26445
+ * @returns The total target weight, 0 when no target contributes
26446
+ */
26447
+ private _blendTargets;
26448
+ private _applyWeighted;
26449
+ private _applyRotation;
26450
+ private _writePosition;
26451
+ private _writeScaling;
26452
+ private _solvePosition;
26453
+ private _solveRotation;
26454
+ private _solveScale;
26455
+ private _solveParent;
26456
+ private _solveAim;
26457
+ /**
26458
+ * Builds a rotation matrix whose rows are `first`, `second` made orthogonal to it, and their cross product.
26459
+ * @param first - primary axis
26460
+ * @param second - secondary axis
26461
+ * @param out - matrix receiving the basis
26462
+ * @returns false when the axes are parallel or degenerate (`out` is then unchanged)
26463
+ */
26464
+ private static _OrthonormalBasisToRef;
26465
+ }
26466
+
26467
+
24272
26468
  /**
24273
26469
  * Intermediate representation for parsed FBX data.
24274
26470
  * Both binary and ASCII parsers produce this same structure.
@@ -24283,6 +26479,11 @@ declare namespace BABYLON {
24283
26479
  type: FBXPropertyType;
24284
26480
  /** Parsed property value. */
24285
26481
  value: FBXPropertyValue;
26482
+ /**
26483
+ * Exact decimal text of an int64 whose magnitude exceeds 2^53; `value` then holds the rounded double. Object
26484
+ * ids are the only int64 values where the last bits matter, and `resolveConnections` keys them by this text.
26485
+ */
26486
+ raw?: string;
24286
26487
  }
24287
26488
  /** A node in the FBX document tree */
24288
26489
  export interface FBXNode {
@@ -24309,11 +26510,22 @@ declare namespace BABYLON {
24309
26510
  /** Extract a property value by index, with type narrowing */
24310
26511
  export function getPropertyValue<T extends FBXPropertyValue>(node: FBXNode, index: number): T | undefined;
24311
26512
  /**
24312
- * Converts an FBX object ID value to a safe JavaScript number.
26513
+ * Validates an FBX object ID value: IDs are 64-bit integers, so anything non-numeric, non-finite or fractional is
26514
+ * rejected. IDs beyond 2^53 are carried losslessly through the property's `raw` text by `resolveConnections`.
24313
26515
  * @param value - Parsed FBX object ID value
24314
- * @returns The object ID, or undefined when the value is not numeric
26516
+ * @returns The object ID, or undefined when the value cannot be an ID
24315
26517
  */
24316
26518
  export function getSafeFBXObjectId(value: unknown): number | undefined;
26519
+ /** Typed array payload types produced by the parsers. */
26520
+ export type FBXArrayValue = Float32Array | Float64Array | Int32Array | Uint8Array;
26521
+ /**
26522
+ * Returns the array payload of a node.
26523
+ * 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
26524
+ * scalar properties, and a one-element array degenerates to a single scalar. All of these are coalesced here.
26525
+ * @param node - Node whose properties hold the array
26526
+ * @returns The array, or null when the node has no numeric payload
26527
+ */
26528
+ export function getNodeArray(node: FBXNode | undefined | null): FBXArrayValue | null;
24317
26529
  /** Get the numeric ID from a node (first property is typically the int64 UID) */
24318
26530
  export function getNodeId(node: FBXNode): number | undefined;
24319
26531
  /**
@@ -24441,25 +26653,9 @@ declare namespace BABYLON {
24441
26653
  /** Recoverable skinning/bind diagnostics */
24442
26654
  diagnostics: FBXSkinDiagnostic[];
24443
26655
  }
24444
- /**
24445
- * Extract all skin deformers from the FBX scene.
24446
- * Returns skin data including bone hierarchy and vertex weights.
24447
- */
24448
- export function extractSkins(objectMap: FBXObjectMap): FBXSkinData[];
26656
+ export function extractSkins(objectMap: FBXObjectMap, propertyTemplates?: FBXPropertyTemplateMap): FBXSkinData[];
24449
26657
  export function isSkeletonModel(modelNode: FBXNode): boolean;
24450
- export function extractBoneTransform(modelNode: FBXNode): {
24451
- translation: [number, number, number];
24452
- rotation: [number, number, number];
24453
- preRotation: [number, number, number];
24454
- postRotation: [number, number, number];
24455
- rotationPivot: [number, number, number];
24456
- scalingPivot: [number, number, number];
24457
- rotationOffset: [number, number, number];
24458
- scalingOffset: [number, number, number];
24459
- scale: [number, number, number];
24460
- rotationOrder: number;
24461
- inheritType: number;
24462
- };
26658
+ export function extractBoneTransform(modelNode: FBXNode, template?: FBXPropertyTemplate): FBXNodeTransformData;
24463
26659
 
24464
26660
 
24465
26661
  export type FBXSceneDiagnosticType = "unsupported-constraint" | "unsupported-helper" | "unsupported-deformer" | "unsupported-node-attribute" | "unsupported-pose" | "unsupported-layered-texture" | "connection-graph";
@@ -24518,6 +26714,160 @@ declare namespace BABYLON {
24518
26714
  export function resolveVector2Property(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: [number, number]): [number, number];
24519
26715
  export function resolveVector3Property(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: [number, number, number]): [number, number, number];
24520
26716
  export function resolvePropertyValues(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string): FBXPropertyValue[] | undefined;
26717
+ /** A property from a Properties70 ("P") or Properties60 ("Property") block. */
26718
+ export interface FBXPropertyEntry {
26719
+ name: string;
26720
+ type: string;
26721
+ flags: string;
26722
+ values: FBXPropertyValue[];
26723
+ }
26724
+ /**
26725
+ * Lists the properties declared directly on an object, from both the 7.x and 6.x property blocks.
26726
+ * @param node - Object node
26727
+ * @returns Property entries in declaration order (empty when the node has no property block)
26728
+ */
26729
+ export function getPropertyEntries(node: FBXNode | undefined): FBXPropertyEntry[];
26730
+ /** Value of a user property: scalars as-is, vectors and colours as number arrays. */
26731
+ export type FBXUserPropertyValue = string | number | boolean | number[];
26732
+ /**
26733
+ * User-defined properties of an object: those flagged "U" (user) in the property flags. Every DCC exports custom
26734
+ * attributes this way (Maya extra attributes, 3ds Max user properties, Blender custom properties).
26735
+ * @param node - Object node
26736
+ * @returns Map of property name to value, or undefined when the object has none
26737
+ */
26738
+ export function extractUserProperties(node: FBXNode): Record<string, FBXUserPropertyValue> | undefined;
26739
+ export function userPropertyValue(values: FBXPropertyValue[], typeName?: string): FBXUserPropertyValue | undefined;
26740
+
26741
+
26742
+ /**
26743
+ * NURBS curves and surfaces, and polyline ("Line") geometry.
26744
+ *
26745
+ * The basis evaluation and tessellation follow the FBX SDK conventions as implemented by ufbx: knot spans are
26746
+ * subdivided uniformly, closed and periodic curves wrap their control points, and surfaces are tessellated into
26747
+ * quads (degenerate quads at poles become triangles) with welded positions along the wrapped edges.
26748
+ */
26749
+ export type FBXNurbsTopology = "open" | "closed" | "periodic";
26750
+ /** Knot vector and derived data of one parametric direction. */
26751
+ export interface FBXNurbsBasis {
26752
+ order: number;
26753
+ topology: FBXNurbsTopology;
26754
+ knots: Float64Array;
26755
+ /** Parameter range that the curve is defined on */
26756
+ tMin: number;
26757
+ tMax: number;
26758
+ /** Distinct knot values inside [tMin, tMax], i.e. the boundaries of the non-empty spans */
26759
+ spans: Float64Array;
26760
+ /** False when the knot vector is too short or not monotonic */
26761
+ valid: boolean;
26762
+ }
26763
+ /** NURBS curve: homogeneous control points (x, y, z, w) and a basis. */
26764
+ export interface FBXNurbsCurveData {
26765
+ basis: FBXNurbsBasis;
26766
+ /** Control points as x,y,z,w */
26767
+ controlPoints: Float64Array;
26768
+ numControlPoints: number;
26769
+ }
26770
+ /** NURBS surface: control points laid out as `v * numU + u`. */
26771
+ export interface FBXNurbsSurfaceData {
26772
+ basisU: FBXNurbsBasis;
26773
+ basisV: FBXNurbsBasis;
26774
+ numU: number;
26775
+ numV: number;
26776
+ /** Control points as x,y,z,w */
26777
+ controlPoints: Float64Array;
26778
+ flipNormals: boolean;
26779
+ /** Span subdivision stored in the file (Step), 0 when absent */
26780
+ stepU: number;
26781
+ stepV: number;
26782
+ }
26783
+ /** Polyline geometry ready for a lines mesh: one or more open or closed point runs. */
26784
+ export interface FBXCurveGeometryData {
26785
+ id: number;
26786
+ name: string;
26787
+ kind: "line" | "nurbsCurve";
26788
+ /** Each polyline as x,y,z triples; closed runs repeat their first point at the end */
26789
+ polylines: Float64Array[];
26790
+ /** Display colour from the geometry's Color property */
26791
+ color: [number, number, number] | null;
26792
+ diagnostics: FBXGeometryDiagnostic[];
26793
+ }
26794
+ export function createNurbsBasis(order: number, form: string | undefined, knots: Float64Array): FBXNurbsBasis;
26795
+ /**
26796
+ * Evaluates the basis functions (and their derivatives) that are non-zero at `u`.
26797
+ * @returns index of the first influencing control point, or -1 when the basis cannot be evaluated
26798
+ */
26799
+ export function evaluateNurbsBasis(basis: FBXNurbsBasis, u: number, weights: Float64Array, derivatives: Float64Array | null): number;
26800
+ /** Evaluates a curve point; `out` receives position (0..2) and derivative (3..5). */
26801
+ export function evaluateNurbsCurve(curve: FBXNurbsCurveData, u: number, out: Float64Array, weights: Float64Array, derivs: Float64Array): boolean;
26802
+ /** Evaluates a surface point; `out` receives position (0..2), du (3..5) and dv (6..8). */
26803
+ export function evaluateNurbsSurface(surface: FBXNurbsSurfaceData, u: number, v: number, out: Float64Array, scratch: {
26804
+ wu: Float64Array;
26805
+ wv: Float64Array;
26806
+ du: Float64Array;
26807
+ dv: Float64Array;
26808
+ }): boolean;
26809
+ /**
26810
+ * Tessellates a curve into a polyline with `subdivision` segments per knot span. Closed and periodic curves
26811
+ * end on a copy of their first point.
26812
+ */
26813
+ export function tessellateNurbsCurve(curve: FBXNurbsCurveData, subdivision?: number): Float64Array | null;
26814
+ /** Span subdivision to use for a surface direction: an explicit override, else the file's Step, else 4. */
26815
+ export function resolveSpanSubdivision(fileStep: number, override: number | undefined): number;
26816
+ /**
26817
+ * Tessellates a surface into triangles. Positions on wrapped (closed/periodic) edges and at poles are welded
26818
+ * exactly like the FBX SDK does, so degenerate quads collapse into triangles.
26819
+ */
26820
+ export function tessellateNurbsSurface(surface: FBXNurbsSurfaceData, subU: number, subV: number): {
26821
+ positions: Float64Array;
26822
+ indices: Uint32Array;
26823
+ normals: Float64Array;
26824
+ uvs: Float64Array;
26825
+ } | null;
26826
+ /** Reads a NurbsCurve geometry node. */
26827
+ export function extractNurbsCurve(node: FBXNode): FBXNurbsCurveData | null;
26828
+ /** Reads a NurbsSurface geometry node. */
26829
+ export function extractNurbsSurface(node: FBXNode): FBXNurbsSurfaceData | null;
26830
+ /** Tessellates a NurbsSurface geometry node into mesh geometry. */
26831
+ export function nurbsSurfaceToGeometry(node: FBXNode, geometryId: number, subdivisionOverride: number | undefined): FBXGeometryData | null;
26832
+ /** Reads a NurbsCurve geometry node into a tessellated polyline. */
26833
+ export function extractNurbsCurveGeometry(node: FBXNode, geometryId: number, subdivision?: number): FBXCurveGeometryData;
26834
+ /**
26835
+ * Reads a Line geometry node: Points plus PointsIndex where a negative index (~index) ends a segment, as in
26836
+ * polygon vertex indices.
26837
+ */
26838
+ export function extractLineGeometry(node: FBXNode, geometryId: number): FBXCurveGeometryData;
26839
+
26840
+
26841
+ /** Transform properties resolved from an FBX Model, with template defaults applied. */
26842
+ export interface FBXNodeTransformData {
26843
+ translation: [number, number, number];
26844
+ rotation: [number, number, number];
26845
+ scale: [number, number, number];
26846
+ preRotation: [number, number, number];
26847
+ postRotation: [number, number, number];
26848
+ rotationPivot: [number, number, number];
26849
+ scalingPivot: [number, number, number];
26850
+ rotationOffset: [number, number, number];
26851
+ scalingOffset: [number, number, number];
26852
+ geometricTranslation: [number, number, number];
26853
+ geometricRotation: [number, number, number];
26854
+ geometricScaling: [number, number, number];
26855
+ /** Rotation order: 0=XYZ, 1=XZY, 2=YZX, 3=YXZ, 4=ZXY, 5=ZYX, 6=SphericXYZ */
26856
+ rotationOrder: number;
26857
+ /** FBX transform inheritance mode. 0=RrSs, 1=RSrs, 2=Rrs */
26858
+ inheritType: number;
26859
+ /** Whether the rotation space (rotation order, pre/post rotation) is active for this node */
26860
+ rotationActive: boolean;
26861
+ diagnostics: string[];
26862
+ }
26863
+ /**
26864
+ * Resolves the transform properties of a Model node the way the FBX SDK evaluates them.
26865
+ *
26866
+ * `RotationActive` gates the whole rotation space: when it is false (the FbxNode template default), the SDK
26867
+ * composes `Lcl Rotation` in plain XYZ order and ignores `RotationOrder`, `PreRotation` and `PostRotation`.
26868
+ * `RotationSpaceForLimitOnly` restricts the rotation space to limits, which has the same effect for us.
26869
+ */
26870
+ export function extractNodeTransform(modelNode: FBXNode, template?: FBXPropertyTemplate): FBXNodeTransformData;
24521
26871
 
24522
26872
 
24523
26873
  /** Parsed material data */
@@ -24527,6 +26877,10 @@ declare namespace BABYLON {
24527
26877
  type: "Lambert" | "Phong";
24528
26878
  properties: FBXMaterialProperties;
24529
26879
  textures: FBXTextureRef[];
26880
+ /** Unified classic + PBR parameter model resolved from whichever shader flavour the file uses */
26881
+ model: FBXMaterialModel<FBXTextureRef>;
26882
+ /** User-defined properties */
26883
+ userProperties?: Record<string, FBXUserPropertyValue>;
24530
26884
  }
24531
26885
  export interface FBXMaterialProperties {
24532
26886
  diffuseColor?: [number, number, number];
@@ -24562,11 +26916,102 @@ declare namespace BABYLON {
24562
26916
  uvSetIndex?: number;
24563
26917
  /** Which named UV set this texture uses */
24564
26918
  uvSetName?: string;
26919
+ /** WrapModeU: 0 = repeat, 1 = clamp */
26920
+ wrapU?: number;
26921
+ /** WrapModeV: 0 = repeat, 1 = clamp */
26922
+ wrapV?: number;
26923
+ /** Set when the texture came from a LayeredTexture (only the first layer is used) */
26924
+ layeredTextureId?: number;
24565
26925
  }
24566
26926
  /**
24567
26927
  * Extract material data from an FBX Material node.
24568
26928
  */
24569
26929
  export function extractMaterial(materialNode: FBXNode, materialId: number, objectMap: FBXObjectMap, templates?: FBXPropertyTemplateMap): FBXMaterialData;
26930
+ export function extractTextureRef(id: number, node: FBXNode, propertyName: string | undefined, objectMap: FBXObjectMap, template?: FBXPropertyTemplate): FBXTextureRef;
26931
+
26932
+
26933
+ /**
26934
+ * Unified material model.
26935
+ *
26936
+ * FBX materials come in many vendor flavours: the classic FbxSurfaceLambert / FbxSurfacePhong, Autodesk Standard
26937
+ * Surface (OSL), Arnold aiStandardSurface, 3ds Max Physical Material, 3ds Max PBR (metal/rough and spec/gloss),
26938
+ * the 3ds Max glTF material, OpenPBR, and Maya's Stingray PBS ShaderFX graph. Each stores its parameters under
26939
+ * different property names, sometimes behind a shader binding table.
26940
+ *
26941
+ * This module resolves any of them into two parameter sets, mirroring how the FBX SDK / ufbx expose materials:
26942
+ * `fbx` (the classic Lambert/Phong parameters) and `pbr` (a physically based parameter set), plus feature flags.
26943
+ */
26944
+ export type FBXShaderType = "unknown" | "fbxLambert" | "fbxPhong" | "oslStandardSurface" | "arnoldStandardSurface" | "3dsMaxPhysicalMaterial" | "3dsMaxPbrMetalRough" | "3dsMaxPbrSpecGloss" | "gltfMaterial" | "openPbrMaterial" | "shaderFxGraph";
26945
+ /** One resolved material parameter: a constant value and/or a texture. */
26946
+ export interface FBXMaterialMap<TTexture> {
26947
+ /** Constant value (r,g,b,a for colours, x for scalars) */
26948
+ value?: number[];
26949
+ /** Number of meaningful components in `value` (1 for scalars, 3 or 4 for colours) */
26950
+ valueComponents: number;
26951
+ /** Texture bound to the parameter */
26952
+ texture?: TTexture;
26953
+ /** Whether the texture is enabled (some vendors carry an explicit toggle) */
26954
+ textureEnabled: boolean;
26955
+ }
26956
+ export type FBXFbxMapName = "diffuseFactor" | "diffuseColor" | "specularFactor" | "specularColor" | "specularExponent" | "reflectionFactor" | "reflectionColor" | "transparencyFactor" | "transparencyColor" | "emissionFactor" | "emissionColor" | "ambientFactor" | "ambientColor" | "normalMap" | "bump" | "bumpFactor" | "displacement" | "displacementFactor" | "vectorDisplacement" | "vectorDisplacementFactor";
26957
+ 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";
26958
+ 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";
26959
+ export interface FBXMaterialModel<TTexture> {
26960
+ shaderType: FBXShaderType;
26961
+ /** Prefix material property names carry for this shader (e.g. "3dsMax|Parameters|") */
26962
+ shaderPropPrefix: string;
26963
+ fbx: Partial<Record<FBXFbxMapName, FBXMaterialMap<TTexture>>>;
26964
+ pbr: Partial<Record<FBXPbrMapName, FBXMaterialMap<TTexture>>>;
26965
+ features: Partial<Record<FBXMaterialFeatureName, {
26966
+ enabled: boolean;
26967
+ explicit: boolean;
26968
+ }>>;
26969
+ }
26970
+ /** Inputs needed to resolve a material, independent of the parse representation. */
26971
+ export interface FBXMaterialSource<TTexture> {
26972
+ /** "lambert", "phong", "unknown", ... as written in the file */
26973
+ shadingModelName: string;
26974
+ /** Property values by full property name (e.g. "DiffuseColor", "Maya|baseColor", "3dsMax|Parameters|roughness") */
26975
+ props: Map<string, {
26976
+ type: string;
26977
+ values: FBXPropertyValue[];
26978
+ }>;
26979
+ /** Textures connected to the material by property name (OP connection property) */
26980
+ texturesByProp: Map<string, TTexture>;
26981
+ /** Connected shader implementation, when any */
26982
+ shader?: {
26983
+ renderApi: string;
26984
+ /** shader semantic name -> material property names */
26985
+ bindings: Map<string, string[]>;
26986
+ };
26987
+ }
26988
+ /** Shader types whose parameters are physically based; the loader emits PBR materials for them by default. */
26989
+ export function isPbrShaderType(type: FBXShaderType): boolean;
26990
+ /** Detects the shader flavour of a material from its shading model name, connected shader and 3ds Max class ids. */
26991
+ export function detectShaderType<T>(source: FBXMaterialSource<T>): {
26992
+ shaderType: FBXShaderType;
26993
+ shaderPropPrefix: string;
26994
+ };
26995
+ /**
26996
+ * Resolves the unified material model from raw material data.
26997
+ */
26998
+ export function resolveMaterialModel<T>(source: FBXMaterialSource<T>): FBXMaterialModel<T>;
26999
+ /** Colour (first three components) of a map, or undefined. */
27000
+ export function mapColor<T>(map: FBXMaterialMap<T> | undefined): [number, number, number] | undefined;
27001
+ /** Scalar (first component) of a map, or undefined. */
27002
+ export function mapScalar<T>(map: FBXMaterialMap<T> | undefined): number | undefined;
27003
+
27004
+
27005
+ /**
27006
+ * FBX 5.x (and older) documents store everything at the top level: one `Model` node per object with inline
27007
+ * geometry, materials, skin links, lights and cameras, and `Children` lists instead of connections. This module
27008
+ * rewrites such a document into the 6.x layout (`Objects`, `Connections`, `Takes`) so the rest of the importer
27009
+ * can treat both the same way. The rules follow the FBX SDK's legacy reader as implemented by ufbx.
27010
+ */
27011
+ /** True for pre-6000 files: no `Objects` section but top-level `Model` nodes. */
27012
+ export function isLegacyDocument(doc: FBXDocument): boolean;
27013
+ /** Rewrites a legacy document into the 6.x object/connection layout. */
27014
+ export function upgradeLegacyDocument(doc: FBXDocument): FBXDocument;
24570
27015
 
24571
27016
 
24572
27017
  /** A named UV set */
@@ -24579,7 +27024,7 @@ declare namespace BABYLON {
24579
27024
  /** Recoverable geometry import issue. */
24580
27025
  export interface FBXGeometryDiagnostic {
24581
27026
  /** Diagnostic category. */
24582
- type: "degenerate-polygon" | "triangulation-fallback" | "layer-index-out-of-bounds" | "layer-data-too-short";
27027
+ type: "degenerate-polygon" | "triangulation-fallback" | "layer-index-out-of-bounds" | "layer-data-too-short" | "nurbs-invalid" | "nurbs-trim-ignored" | "nurbs-deformer-ignored";
24583
27028
  /** Human-readable diagnostic message. */
24584
27029
  message: string;
24585
27030
  /** Polygon index associated with the diagnostic, if applicable. */
@@ -24630,8 +27075,10 @@ declare namespace BABYLON {
24630
27075
  id: number;
24631
27076
  name: string;
24632
27077
  subType: string;
24633
- /** Geometry attached to this model (if it's a Mesh type) */
27078
+ /** Geometry attached to this model (meshes and tessellated NURBS surfaces) */
24634
27079
  geometry?: FBXGeometryData;
27080
+ /** Curve geometry attached to this model (Line and NurbsCurve) */
27081
+ curve?: FBXCurveGeometryData;
24635
27082
  /** Materials assigned to this model */
24636
27083
  materials: FBXMaterialData[];
24637
27084
  /** Child models */
@@ -24663,18 +27110,68 @@ declare namespace BABYLON {
24663
27110
  /** Whether backface culling is disabled ("CullingOff") */
24664
27111
  cullingOff: boolean;
24665
27112
  /** User-defined custom properties from Properties70 */
24666
- customProperties?: Record<string, string | number | boolean>;
27113
+ customProperties?: Record<string, FBXUserPropertyValue>;
27114
+ /** LOD group settings when this model is a LodGroup; children are the levels in order */
27115
+ lodGroup?: FBXLodGroupData;
27116
+ /** Display layer (CollectionExclusive) the model belongs to */
27117
+ displayLayer?: FBXDisplayLayerData;
24667
27118
  /** Recoverable model import diagnostics */
24668
27119
  diagnostics: string[];
24669
27120
  }
27121
+ /** LOD group settings (NodeAttribute "LodGroup") */
27122
+ export interface FBXLodGroupData {
27123
+ /** Switch distance for level i+1 (level 0 has none). In scene units, or percent of screen when `relative`. */
27124
+ thresholds: number[];
27125
+ /** ThresholdsUsedAsPercentage */
27126
+ relative: boolean;
27127
+ /** DisplayLevels|LevelN: 0 use LOD, 1 show, 2 hide */
27128
+ displayLevels: number[];
27129
+ }
27130
+ /** Display layer (CollectionExclusive "DisplayLayer") */
27131
+ export interface FBXDisplayLayerData {
27132
+ id: number;
27133
+ name: string;
27134
+ show: boolean;
27135
+ freeze: boolean;
27136
+ color: [number, number, number];
27137
+ modelIds: number[];
27138
+ }
27139
+ /** One member of a selection set: a model, optionally with a component selection on its mesh */
27140
+ export interface FBXSelectionNodeData {
27141
+ modelId: number;
27142
+ /** IsTheNodeInSet: the whole node is selected (as opposed to only components) */
27143
+ includeNode: boolean;
27144
+ /** Selected control point indices (VertexIndexArray) */
27145
+ vertices?: number[];
27146
+ /** Selected edge indices (EdgeIndexArray) */
27147
+ edges?: number[];
27148
+ /** Selected polygon indices (PolygonIndexArray) */
27149
+ faces?: number[];
27150
+ }
27151
+ /** Selection set (Collection "SelectionSet") */
27152
+ export interface FBXSelectionSetData {
27153
+ id: number;
27154
+ name: string;
27155
+ members: FBXSelectionNodeData[];
27156
+ }
24670
27157
  /** Camera data extracted from FBX */
24671
27158
  export interface FBXCameraData {
24672
27159
  /** Model ID this camera is attached to */
24673
27160
  modelId: number;
27161
+ /** NodeAttribute object ID (animation curves target this) */
27162
+ attributeId: number;
24674
27163
  /** Camera name */
24675
27164
  name: string;
24676
- /** Field of view in degrees */
27165
+ /** Vertical field of view in degrees */
24677
27166
  fieldOfView: number;
27167
+ /** Horizontal field of view in degrees */
27168
+ fieldOfViewX: number;
27169
+ /** ApertureMode: 0 horizontal and vertical, 1 horizontal, 2 vertical, 3 focal length */
27170
+ apertureMode: number;
27171
+ /** Aperture (film gate after gate fit) size in inches */
27172
+ apertureSizeInch: [number, number];
27173
+ /** Orthographic view size (width, height) in scene units */
27174
+ orthographicSize: [number, number];
24678
27175
  /** Near clip plane */
24679
27176
  nearPlane: number;
24680
27177
  /** Far clip plane */
@@ -24693,6 +27190,8 @@ declare namespace BABYLON {
24693
27190
  orthoZoom?: number;
24694
27191
  /** Camera roll in degrees when present */
24695
27192
  roll?: number;
27193
+ /** User-defined properties on the camera attribute */
27194
+ userProperties?: Record<string, FBXUserPropertyValue>;
24696
27195
  /** Known unsupported or unrecognized camera properties */
24697
27196
  unknownProperties: string[];
24698
27197
  /** Recoverable camera import diagnostics */
@@ -24702,6 +27201,8 @@ declare namespace BABYLON {
24702
27201
  export interface FBXLightData {
24703
27202
  /** Model ID this light is attached to */
24704
27203
  modelId: number;
27204
+ /** NodeAttribute object ID (animation curves target this) */
27205
+ attributeId: number;
24705
27206
  /** Light name */
24706
27207
  name: string;
24707
27208
  /** Light type: 0=Point, 1=Directional, 2=Spot */
@@ -24726,6 +27227,15 @@ declare namespace BABYLON {
24726
27227
  enableFarAttenuation?: boolean;
24727
27228
  /** Whether the source light requested shadow casting */
24728
27229
  castShadows?: boolean;
27230
+ /** Near/far attenuation ranges in scene units (when enabled) */
27231
+ nearAttenuationStart?: number;
27232
+ nearAttenuationEnd?: number;
27233
+ farAttenuationStart?: number;
27234
+ farAttenuationEnd?: number;
27235
+ /** Area light shape: 0 rectangle, 1 sphere */
27236
+ areaLightShape?: number;
27237
+ /** User-defined properties on the light attribute */
27238
+ userProperties?: Record<string, FBXUserPropertyValue>;
24729
27239
  /** Known unsupported or unrecognized light properties */
24730
27240
  unknownProperties: string[];
24731
27241
  /** Recoverable light import diagnostics */
@@ -24737,6 +27247,8 @@ declare namespace BABYLON {
24737
27247
  rootModels: FBXModelData[];
24738
27248
  /** All geometries in the scene */
24739
27249
  geometries: FBXGeometryData[];
27250
+ /** All curve geometries (lines and tessellated NURBS curves) */
27251
+ curves: FBXCurveGeometryData[];
24740
27252
  /** All materials in the scene */
24741
27253
  materials: FBXMaterialData[];
24742
27254
  /** Skin deformers (skeletons + vertex weights) */
@@ -24753,6 +27265,12 @@ declare namespace BABYLON {
24753
27265
  lights: FBXLightData[];
24754
27266
  /** Scene-level unsupported feature diagnostics */
24755
27267
  diagnostics: FBXSceneDiagnostic[];
27268
+ /** Constraints (aim, parent, position, rotation, scale, IK) */
27269
+ constraints: FBXConstraintData[];
27270
+ /** Display layers */
27271
+ displayLayers: FBXDisplayLayerData[];
27272
+ /** Selection sets */
27273
+ selectionSets: FBXSelectionSetData[];
24756
27274
  /** Global settings */
24757
27275
  upAxis: number;
24758
27276
  upAxisSign: number;
@@ -24761,11 +27279,89 @@ declare namespace BABYLON {
24761
27279
  coordAxis: number;
24762
27280
  coordAxisSign: number;
24763
27281
  unitScaleFactor: number;
27282
+ /** Scene frame rate derived from GlobalSettings TimeMode / CustomFrameRate */
27283
+ frameRate: number;
24764
27284
  }
24765
27285
  /**
24766
27286
  * Interpret a parsed FBX document into scene data.
24767
27287
  */
24768
- export function interpretFBX(doc: FBXDocument): FBXSceneData;
27288
+ /** Options controlling how the document is interpreted. */
27289
+ export interface FBXInterpretOptions {
27290
+ /** Segments per knot span when tessellating NURBS surfaces; defaults to the Step stored in the file */
27291
+ nurbsSubdivision?: number;
27292
+ /** Shift every clip so its first key sits at time 0 (default true); false keeps the authored times */
27293
+ rebaseKeyframes?: boolean;
27294
+ }
27295
+ export function interpretFBX(doc: FBXDocument, options?: FBXInterpretOptions): FBXSceneData;
27296
+
27297
+
27298
+ export type FBXConstraintType = "aim" | "parent" | "position" | "rotation" | "scale" | "singleChainIK" | "unknown";
27299
+ export type Vec3 = [number, number, number];
27300
+ export type Bool3 = [boolean, boolean, boolean];
27301
+ /** One weighted target of a constraint. */
27302
+ export interface FBXConstraintTarget {
27303
+ /** Model id of the target node */
27304
+ modelId: number;
27305
+ /** Normalized weight (file value / 100, or as-is for IK pole targets) */
27306
+ weight: number;
27307
+ /** Parent constraint translation offset expressed in the target's space */
27308
+ offsetTranslation: Vec3;
27309
+ /** Parent constraint rotation offset in degrees, expressed in the target's space */
27310
+ offsetRotation: Vec3;
27311
+ /** Parent constraint scale offset expressed in the target's space */
27312
+ offsetScale: Vec3;
27313
+ }
27314
+ /** A constraint object of the file, with its targets and parameters resolved. */
27315
+ export interface FBXConstraintData {
27316
+ /** Constraint object id */
27317
+ id: number;
27318
+ /** Constraint name */
27319
+ name: string;
27320
+ /** Resolved constraint kind */
27321
+ type: FBXConstraintType;
27322
+ /** Constraint type name as written in the file (e.g. "Parent-Child") */
27323
+ typeName: string;
27324
+ /** Constrained model */
27325
+ nodeId?: number;
27326
+ /** Weighted targets in file order */
27327
+ targets: FBXConstraintTarget[];
27328
+ /** Global weight (file value / 100) */
27329
+ weight: number;
27330
+ /** False when the constraint is switched off in the file */
27331
+ active: boolean;
27332
+ /** Which translation axes the constraint drives */
27333
+ affectTranslation: Bool3;
27334
+ /** Which rotation axes the constraint drives */
27335
+ affectRotation: Bool3;
27336
+ /** Which scale axes the constraint drives */
27337
+ affectScale: Bool3;
27338
+ /** Translation offset of the constrained node */
27339
+ offsetTranslation: Vec3;
27340
+ /** Rotation offset of the constrained node, in degrees */
27341
+ offsetRotation: Vec3;
27342
+ /** Scale offset of the constrained node */
27343
+ offsetScale: Vec3;
27344
+ /** Aim: local axis that points at the target */
27345
+ aimVector: Vec3;
27346
+ /** Aim: local axis aligned with the up direction */
27347
+ upVector: Vec3;
27348
+ /** Aim: world up direction (world up modes 2 and 3) */
27349
+ worldUpVector: Vec3;
27350
+ /** Aim: 0 scene up, 1 aim up node, 2 align to node, 3 vector, 4 none */
27351
+ worldUpType: number;
27352
+ /** Aim: model id of the world up object (world up modes 1 and 2) */
27353
+ worldUpNodeId?: number;
27354
+ /** Single chain IK: model id of the first joint of the chain */
27355
+ ikFirstJointId?: number;
27356
+ /** Single chain IK: model id of the last joint of the chain */
27357
+ ikEndJointId?: number;
27358
+ /** Single chain IK: model id of the effector */
27359
+ ikEffectorId?: number;
27360
+ /** Single chain IK: pole vector */
27361
+ ikPoleVector: Vec3;
27362
+ }
27363
+ /** Reads every constraint object of the scene. */
27364
+ export function extractConstraints(objectMap: FBXObjectMap): FBXConstraintData[];
24769
27365
 
24770
27366
 
24771
27367
  /** Connection type: OO = object-to-object, OP = object-to-property */
@@ -24788,7 +27384,7 @@ declare namespace BABYLON {
24788
27384
  /** Object node. */
24789
27385
  node: FBXNode;
24790
27386
  /** Source of the object entry. */
24791
- source: "Objects" | "legacySyntheticGeometry";
27387
+ source: "Objects" | "legacySyntheticGeometry" | "legacySyntheticAttribute" | "legacySyntheticBlendShape";
24792
27388
  /** Legacy string object name, when applicable. */
24793
27389
  legacyName?: string;
24794
27390
  /** True if the object was synthesized for legacy compatibility. */
@@ -24909,7 +27505,23 @@ declare namespace BABYLON {
24909
27505
  export function extractBlendShapes(objectMap: FBXObjectMap): FBXBlendShapeData[];
24910
27506
 
24911
27507
 
27508
+ /**
27509
+ * FBX animation curve model and evaluator.
27510
+ *
27511
+ * Keys carry cubic Bezier tangents expressed the way the FBX SDK stores them: a left and right tangent with a time
27512
+ * extent (dx, as a fraction of the segment scaled by the tangent weight) and a value extent (dy). Linear and constant
27513
+ * segments are represented the same way so that a single evaluator handles every case, including the weighted
27514
+ * tangents Maya and MotionBuilder write, TCB keys, and the pre/post extrapolation modes.
27515
+ */
27516
+ /** FBX time units: 46186158000 ticks per second */
27517
+ export const FBX_TIME_UNIT = 46186158000;
24912
27518
  export type FBXInterpolationType = "constant" | "linear" | "cubic";
27519
+ export type FBXExtrapolationMode = "constant" | "repeat" | "mirror" | "slope" | "repeatRelative";
27520
+ export interface FBXExtrapolation {
27521
+ mode: FBXExtrapolationMode;
27522
+ /** Number of repetitions, or -1 for infinite */
27523
+ repeatCount: number;
27524
+ }
24913
27525
  /** A single keyframe */
24914
27526
  export interface FBXKeyframe {
24915
27527
  /** Time in seconds */
@@ -24920,9 +27532,15 @@ declare namespace BABYLON {
24920
27532
  interpolation: FBXInterpolationType;
24921
27533
  /** Constant interpolation variant */
24922
27534
  constantMode?: "standard" | "next";
24923
- /** Cubic outgoing slope in value units per second */
27535
+ /** Left (incoming) tangent: time extent in seconds and value extent */
27536
+ leftDx: number;
27537
+ leftDy: number;
27538
+ /** Right (outgoing) tangent: time extent in seconds and value extent */
27539
+ rightDx: number;
27540
+ rightDy: number;
27541
+ /** Cubic outgoing slope in value units per second (derived, kept for consumers that export hermite keys) */
24924
27542
  rightSlope?: number;
24925
- /** Cubic incoming slope for the next key, in value units per second */
27543
+ /** Cubic incoming slope for the next key, in value units per second (derived) */
24926
27544
  nextLeftSlope?: number;
24927
27545
  }
24928
27546
  /** An animation curve (one axis of one property) */
@@ -24933,7 +27551,53 @@ declare namespace BABYLON {
24933
27551
  keys: FBXKeyframe[];
24934
27552
  /** True for baked sample curves that should be connected as linear samples */
24935
27553
  isSampled?: boolean;
27554
+ preExtrapolation?: FBXExtrapolation;
27555
+ postExtrapolation?: FBXExtrapolation;
27556
+ }
27557
+ /** Raw key attribute data for one key, after run-length decoding. */
27558
+ export interface FBXKeyAttributes {
27559
+ flags: number;
27560
+ data: [number, number, number, number];
27561
+ }
27562
+ /**
27563
+ * Builds keyframes from parallel time/value arrays and their (run-length encoded) attributes, resolving every
27564
+ * tangent mode the FBX SDK writes: user, broken, auto (with clamp / progressive clamp / time-independent flags and
27565
+ * auto bias), TCB, weighted, linear and constant.
27566
+ */
27567
+ export function buildKeyframes(times: ArrayLike<number>, values: ArrayLike<number>, attributes: (index: number) => FBXKeyAttributes): FBXKeyframe[];
27568
+ /** Auto tangent as the FBX SDK computes it, including clamping and auto bias. */
27569
+ export function solveAutoTangent(prevTime: number, time: number, nextTime: number, prevValue: number, value: number, nextValue: number, weightLeft: number, weightRight: number, autoBias: number, flags: number): number;
27570
+ /** Builds a keyframe list from explicit per-key slopes (legacy Takes and synthetic curves). */
27571
+ export function keyframesFromSlopes(times: number[], values: number[], interpolation: FBXInterpolationType[], constantNext: boolean[], leftSlope: number[], rightSlope: number[], leftWeight?: number[], rightWeight?: number[]): FBXKeyframe[];
27572
+ /** Reads a `Pre-Extrapolation` / `Post-Extrapolation` block: `Type` is a character code, `Repetition` a count. */
27573
+ export function parseExtrapolation(typeValue: unknown, repetitionValue: unknown): FBXExtrapolation;
27574
+ export function evaluateCurve(curve: FBXCurveData | undefined, time: number, defaultValue: number, noExtrapolation?: boolean): number;
27575
+ export type Vec3 = [number, number, number];
27576
+ export type Quat = [number, number, number, number];
27577
+ /** Euler angles in degrees with an FBX rotation order (0=XYZ ... 5=ZYX; spheric falls back to XYZ) to a quaternion. */
27578
+ export function eulerToQuat(v: Vec3, order: number): Quat;
27579
+ /** Quaternion to Euler angles in degrees for an FBX rotation order (inverse of eulerToQuat). */
27580
+ export function quatToEuler(q: Quat, order: number): Vec3;
27581
+ /** Blend semantics of an animation layer, derived from its BlendMode and accumulation modes. */
27582
+ export interface FBXLayerBlend {
27583
+ /** Layer participates in blending (BlendMode Additive or Override Passthrough) */
27584
+ blended: boolean;
27585
+ /** Layer adds onto the result instead of replacing it (BlendMode Additive) */
27586
+ additive: boolean;
27587
+ /** Rotations compose as quaternions (RotationAccumulationMode ByLayer) */
27588
+ composeRotation: boolean;
27589
+ /** Scales compose multiplicatively (ScaleAccumulationMode Multiply) */
27590
+ composeScale: boolean;
27591
+ /** Layer weight in [0, 1] */
27592
+ weight: number;
24936
27593
  }
27594
+ /**
27595
+ * Combines one animation layer's value into the running result, exactly as the FBX SDK evaluator does.
27596
+ * `kind` selects the accumulation rule: "R" rotations (degrees, rotation order given), "S" scales, anything else linear.
27597
+ */
27598
+ export function combineLayerValue(result: Vec3, value: Vec3, layer: FBXLayerBlend, kind: "T" | "R" | "S" | "other", rotationOrder: number): Vec3;
27599
+
27600
+
24937
27601
  /** An animation curve node (T/R/S for one bone) */
24938
27602
  export interface FBXCurveNodeData {
24939
27603
  /** Property type: "T" (translation), "R" (rotation), "S" (scale) */
@@ -24942,13 +27606,19 @@ declare namespace BABYLON {
24942
27606
  targetModelId: number;
24943
27607
  /** Curves for each axis */
24944
27608
  curves: FBXCurveData[];
27609
+ /** Index of the owning layer within the stack's layer list */
27610
+ layerIndex: number;
27611
+ /** Default channel values (`d|X`, `d|Y`, `d|Z`) used for channels without a curve */
27612
+ defaultValues?: [number, number, number];
24945
27613
  }
24946
- /** Unsupported animation curve node preserved for diagnostics and future support. */
27614
+ /** Non-transform animation curve node (property animation), evaluated by the loader when a Babylon mapping exists. */
24947
27615
  export interface FBXUnsupportedCurveNodeData {
24948
27616
  /** Raw AnimationCurveNode property type/name */
24949
27617
  type: string;
24950
27618
  /** CurveNode object ID */
24951
27619
  id: number;
27620
+ /** Index of the owning layer within the stack's layer list */
27621
+ layerIndex: number;
24952
27622
  /** Target object ID if the curve node is connected to an object/property */
24953
27623
  targetId: number | null;
24954
27624
  /** OP connection property name on the target, e.g. Visibility */
@@ -24987,6 +27657,10 @@ declare namespace BABYLON {
24987
27657
  normalizedWeight: number;
24988
27658
  /** Blend mode: 0=Additive, 1=Override, 2=OverridePassthrough */
24989
27659
  blendMode: number;
27660
+ /** Resolved blend semantics used by the evaluator */
27661
+ blend: FBXLayerBlend;
27662
+ /** Animated layer weight (0-100), when the Weight property carries a curve */
27663
+ weightCurve?: FBXCurveData;
24990
27664
  /** Curve nodes in this layer */
24991
27665
  curveNodes: FBXCurveNodeData[];
24992
27666
  /** Unsupported/non-TRS curve nodes preserved for diagnostics */
@@ -24994,6 +27668,14 @@ declare namespace BABYLON {
24994
27668
  /** Recoverable layer diagnostics */
24995
27669
  diagnostics: FBXAnimationDiagnostic[];
24996
27670
  }
27671
+ /** Options for animation extraction. */
27672
+ export interface FBXAnimationExtractOptions {
27673
+ /**
27674
+ * Shift each clip so its first key sits at time 0 (default true). False keeps the times authored in the file, so
27675
+ * clips of one file stay aligned with each other and with the declared stack range.
27676
+ */
27677
+ rebaseKeyframes?: boolean;
27678
+ }
24997
27679
  /** One animation clip (AnimationStack) */
24998
27680
  export interface FBXAnimationStackData {
24999
27681
  /** Animation name */
@@ -25016,13 +27698,7 @@ declare namespace BABYLON {
25016
27698
  /**
25017
27699
  * Extract all animation stacks from the FBX scene.
25018
27700
  */
25019
- export function extractAnimations(objectMap: FBXObjectMap): FBXAnimationStackData[];
25020
- /**
25021
- * Determines whether a key sequence appears to be a uniformly frame-baked sampled curve.
25022
- * @param keys - Keyframes to inspect
25023
- * @returns true if the keys look like sampled frame data rather than authored interpolation
25024
- */
25025
- export function isFrameBakedSampledCurve(keys: readonly FBXKeyframe[]): boolean;
27701
+ export function extractAnimations(objectMap: FBXObjectMap, doc?: FBXDocument, options?: FBXAnimationExtractOptions): FBXAnimationStackData[];
25026
27702
  /**
25027
27703
  * Samples an FBX animation curve at a specific time.
25028
27704
  * @param curveData - Curve data to sample
@@ -25030,6 +27706,54 @@ declare namespace BABYLON {
25030
27706
  * @returns The sampled value, or null when the curve has no keys
25031
27707
  */
25032
27708
  export function sampleFBXCurveAtTime(curveData: FBXCurveData | undefined, time: number): number | null;
27709
+ /**
27710
+ * Pre-7000 files store animation in a top-level `Takes` block instead of AnimationStack/Layer/CurveNode objects:
27711
+ *
27712
+ * Takes: { Take: "name" { LocalTime: start, stop
27713
+ * Model: "Model::joint1" { Channel: "Transform" { Channel: "T" { Channel: "X" { Default, KeyVer, KeyCount, Key } } } } } }
27714
+ *
27715
+ * Each take becomes one animation stack with a single layer. Models are matched through the same legacy string ids
27716
+ * that the connection resolver synthesizes for 6.x objects.
27717
+ */
27718
+ export function extractLegacyTakes(doc: FBXDocument, objectMap: FBXObjectMap, rebaseKeyframes?: boolean): FBXAnimationStackData[];
27719
+ /**
27720
+ * Evaluates one transform channel (T, R or S) of a target at `time`, blending every animation layer of the stack the
27721
+ * way the FBX SDK does: the first layer animating the channel replaces the static value, later layers are combined
27722
+ * according to their blend mode, weight and accumulation modes.
27723
+ * @param curveNodes - Curve nodes targeting this model (any layers, any types)
27724
+ * @param layers - Stack layers, in order
27725
+ * @param type - Channel to evaluate
27726
+ * @param staticValue - Value when nothing animates the channel
27727
+ * @param rotationOrder - Rotation order of the target (for rotation composition)
27728
+ * @param time - Time in seconds
27729
+ */
27730
+ 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];
27731
+ /** Curves of one animated property (or blend shape weight) contributed by one animation layer. */
27732
+ export interface FBXLayeredPropertySource {
27733
+ /** Index of the owning layer within the stack's layer list */
27734
+ layerIndex: number;
27735
+ /** Curves of the property, keyed by channel name (`d|X`, `d|DeformPercent`, ...) */
27736
+ curves: readonly FBXCurveData[];
27737
+ /** Default channel values stored on the curve node */
27738
+ defaultValues?: Record<string, number>;
27739
+ }
27740
+ /**
27741
+ * Evaluates an animated property through the animation layers: the base layer replaces the static value, every
27742
+ * further layer blends onto the running result according to its blend mode and (possibly animated) weight, like
27743
+ * `evaluateLayeredChannel` does for transforms.
27744
+ * @param sources - Per-layer curves of the property
27745
+ * @param layers - Stack layers, in order
27746
+ * @param channels - Channel names to evaluate, in output order
27747
+ * @param staticValue - Value per channel when nothing animates it
27748
+ * @param time - Time in seconds
27749
+ * @returns One value per channel
27750
+ */
27751
+ export function evaluateLayeredProperty(sources: readonly FBXLayeredPropertySource[], layers: readonly FBXAnimationLayerData[], channels: readonly string[], staticValue: readonly number[], time: number): number[];
27752
+ /**
27753
+ * True when every curve of the given channel is inside a constant (stepped) segment at `time`, so a baked key at
27754
+ * that time should hold its value instead of interpolating towards the next sample.
27755
+ */
27756
+ export function isChannelSteppedAt(curveNodes: readonly FBXCurveNodeData[], type: "T" | "R" | "S", time: number): boolean;
25033
27757
 
25034
27758
 
25035
27759
  /** Pure barrel — re-exports only side-effect-free modules */