babylonjs-toolkit 9.34.10 → 9.35.0

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.
package/lib/index.d.ts CHANGED
@@ -7,7 +7,7 @@ declare namespace TOOLKIT {
7
7
  * @class SceneManager - All rights reserved (c) 2024 Mackey Kinard
8
8
  */
9
9
  class SceneManager {
10
- /** Gets the toolkit framework version string (9.34.10 - R1) */
10
+ /** Gets the toolkit framework version string (9.35.0 - R1) */
11
11
  static get Version(): string;
12
12
  /** Gets the toolkit framework copyright notice */
13
13
  static get Copyright(): string;
@@ -4318,7 +4318,8 @@ declare namespace TOOLKIT {
4318
4318
  * and `distances[N-1]` doubles as the cull threshold. Unchanged HYBRID strategy: every level one mesh =>
4319
4319
  * native `master.addLODLevel(distances[i-1], mesh)` plus a final `addLODLevel(cull, null)` band (an
4320
4320
  * InstancedMesh master keeps the legacy dispose of its unused detail levels); any level with >1 mesh =>
4321
- * the scene's shared switcher (`_setupLevelOfDetailSwitcher`).
4321
+ * the scene's shared switcher (`_setupLevelOfDetailSwitcher`), as has a level authored away from LOD0, because
4322
+ * Babylon draws a native level with its master's matrix (`UnityLodGroups.RequiresSwitcher`).
4322
4323
  * - `coverages` only (every headless export - there is no scene-view camera to turn heights into
4323
4324
  * distances, F-M.57): Unity's own rule, `UnityLodAndLights.SelectCoverageLevel` on the screen-relative
4324
4325
  * height `worldSize * lodBias / (2 * tan(vfov / 2) * distance)` of the group, through the same switcher.
@@ -6236,7 +6237,12 @@ declare namespace TOOLKIT {
6236
6237
  static RegisterShaders(): void;
6237
6238
  /** The head-of-chain pass that writes min(c, MaxRadiance) and replaces NaN with 0 (WGSL on WebGPU). */
6238
6239
  static CreateSanitizePass(scene: BABYLON.Scene, camera: BABYLON.Camera, textureType: number): BABYLON.PostProcess;
6239
- private static SceneMetadata;
6240
+ /**
6241
+ * The scene's exported toolkit metadata.
6242
+ * @param scene The scene.
6243
+ * @returns The metadata, or null.
6244
+ */
6245
+ static SceneMetadata(scene: BABYLON.Scene): any;
6240
6246
  private static State;
6241
6247
  private static ApplyBinding;
6242
6248
  }
@@ -6454,6 +6460,14 @@ declare namespace TOOLKIT {
6454
6460
  * @param light A Babylon light (reads `diffuse` and `metadata.toolkit.colorTemperature`), or null.
6455
6461
  */
6456
6462
  static UnityLinearLightColor(light: any): BABYLON.Color3;
6463
+ /**
6464
+ * Gives a toolkit light the colour Unity lights with in a Linear project (`UnityLinearLightColor`) and marks it, so every later
6465
+ * conversion returns it unchanged. An HDRP parity export and a Gamma project keep the exported colour.
6466
+ * @param light A Babylon light built from an export, with `metadata.toolkit`.
6467
+ * @param scene The scene, whose toolkit metadata names the colour space.
6468
+ * @returns True when the colour was converted.
6469
+ */
6470
+ static LinearizeLightColor(light: BABYLON.Light, scene: BABYLON.Scene): boolean;
6457
6471
  /** Keys already warned about, so a per-parse or per-frame code path reports each problem once. */
6458
6472
  private static Warned;
6459
6473
  /**
@@ -6733,6 +6747,17 @@ declare namespace TOOLKIT {
6733
6747
  * not a clamp, brings it to the display.
6734
6748
  */
6735
6749
  static SpecularEnvironmentLevel(reflection: number, units: string, levelMax: number): number;
6750
+ /**
6751
+ * The scale for Unity's ambient probe on a scene environment. A physical environment's level is its sky's normalisation (the sky's
6752
+ * mean luminance), and PBR multiplies the locked SH by that level too, so the probe must carry its inverse or the ambient drops by
6753
+ * the sky's mean. A parity scene does this while it binds the SH, and a relative environment keeps its level. Pure.
6754
+ * @param ambientIntensity The scene's ambient intensity.
6755
+ * @param environmentLevel The environment texture's level, or null when the export has no environment file.
6756
+ * @param units The normalised `environment.units`.
6757
+ * @param isParity True on an HDRP parity scene.
6758
+ * @returns The scale for `generateSphericalHarmonics`.
6759
+ */
6760
+ static EnvironmentAmbientScale(ambientIntensity: number, environmentLevel: number, units: string, isParity: boolean): number;
6736
6761
  /**
6737
6762
  * Warns once when an export marks its sky as baked but carries no environment block (hdrp-sky D19) - the
6738
6763
  * silent failure this feature closed. Returns true when it warned. The skybox fallback still runs.
@@ -6842,7 +6867,7 @@ declare namespace TOOLKIT {
6842
6867
  /** Set once the invisible-light skip is installed, so it is never wrapped twice. */
6843
6868
  _tkSkipInvisible?: boolean;
6844
6869
  /**
6845
- * True while PREWARM's WebGPU pipeline stage draws this map with all its casters (SceneShaderWarmup.DrawPunctualShadowMapsFully):
6870
+ * True while PREWARM's WebGPU pipeline stage draws this map with all its casters (SceneShaderWarmup.DrawShadowMapsFully):
6846
6871
  * the invisible-light skip is bypassed, so a light out of view at the reveal still builds its caster pipelines.
6847
6872
  */
6848
6873
  _tkPrewarmDrawAll?: boolean;
@@ -7635,6 +7660,21 @@ declare namespace TOOLKIT {
7635
7660
  static ShadowMapsRendered(scene: BABYLON.Scene, camera: BABYLON.Camera): boolean;
7636
7661
  /** T12.5: fill the targets by copying the main pass's colour target before its transparents (URP's CopyColorPass). False = re-render the opaque scene (the T12.4 path). */
7637
7662
  static UseCopy: boolean;
7663
+ /** `BABYLON.ConversionMode.None`. */
7664
+ private static readonly COPY_PLAIN;
7665
+ /** `BABYLON.ConversionMode.ToLinearSpace`. */
7666
+ private static readonly COPY_TO_LINEAR;
7667
+ /**
7668
+ * The conversion the copy needs so the target stays linear, as Unity's opaque texture is. A camera without HDR leaves image
7669
+ * processing to the materials (Babylon's LDR chain), so the colour target the copy reads holds display-encoded colour; a graph
7670
+ * that took that for linear reads Scene Color about three times too bright in the shadows. Pure.
7671
+ * @param imageProcessing The scene's image processing configuration, or null.
7672
+ * @returns The conversion mode to pass to `CopyTextureToTexture.copy`.
7673
+ */
7674
+ static CopyConversionFor(imageProcessing: {
7675
+ isEnabled: boolean;
7676
+ applyByPostProcess: boolean;
7677
+ }): number;
7638
7678
  /** Whether a rendering group's transparent queue holds a sub-mesh drawn with one of `materials` (the copy's trigger). Pure. */
7639
7679
  static QueueSamples(subMeshes: any, materials: any): boolean;
7640
7680
  /**
@@ -7648,6 +7688,41 @@ declare namespace TOOLKIT {
7648
7688
  private static CopyNow;
7649
7689
  }
7650
7690
  }
7691
+ declare namespace TOOLKIT {
7692
+ /** The `metadata.urp` scene block (DR-4.6). Its sky and fog keep the `hdrp` block shapes, which the sky code reads untyped. */
7693
+ interface IUrpSceneBlock {
7694
+ version: number;
7695
+ sky?: any;
7696
+ fog?: any;
7697
+ clouds?: any;
7698
+ }
7699
+ /**
7700
+ * One place that answers "which physical sky block does this export carry", so the sky and fog code stays free of pipeline
7701
+ * checks. An HDRP parity export reads `metadata.hdrp`, and a URP export reads `metadata.urp`.
7702
+ */
7703
+ class PhysicalSkyBlock {
7704
+ /** Lowest `urp` block version this runtime reads. */
7705
+ static readonly UrpBlockVersion: number;
7706
+ /**
7707
+ * The scene's `urp` block.
7708
+ * @param metadata - Scene metadata, which is untyped across the toolkit.
7709
+ * @returns The block, or null when the export has none.
7710
+ */
7711
+ static UrpBlock(metadata: any): TOOLKIT.IUrpSceneBlock;
7712
+ /**
7713
+ * The physical sky block of an export.
7714
+ * @param metadata - Scene metadata.
7715
+ * @returns `hdrp.sky` on an HDRP parity export, `urp.sky` on a URP export, otherwise null.
7716
+ */
7717
+ static SkyOf(metadata: any): any;
7718
+ /**
7719
+ * The fog block read by the physical sky's fog pass.
7720
+ * @param metadata - Scene metadata.
7721
+ * @returns `hdrp.fog` on an HDRP parity export, `urp.fog` on a URP export, otherwise null.
7722
+ */
7723
+ static FogOf(metadata: any): any;
7724
+ }
7725
+ }
7651
7726
  /** Babylon Toolkit Namespace */
7652
7727
  declare namespace TOOLKIT {
7653
7728
  /**
@@ -8688,6 +8763,13 @@ declare namespace TOOLKIT {
8688
8763
  * uniform and non-uniform; a game registers its pooled copies).
8689
8764
  */
8690
8765
  static WarmScaleVariantsOnReveal: boolean;
8766
+ /**
8767
+ * False leaves the levels of a native LOD group (Babylon `addLODLevel`) to the camera's distance during the WebGPU pipeline stage: a
8768
+ * level no warm camera selected at the reveal (a stump's LOD1 on a hillside the opening view sees only at LOD0 or culled) then built
8769
+ * its GPU pipeline the first time the game's camera came into its band. True (default) has every frame of the stage select the next
8770
+ * level of every native LOD group in turn (CycleNativeLodLevels), in the main pass and in every shadow map.
8771
+ */
8772
+ static WarmNativeLodLevelsOnReveal: boolean;
8691
8773
  /**
8692
8774
  * Optional units (hidden meshes, render passes) are given up this long (ms) after every required unit is ready and no unit
8693
8775
  * has become ready since, once each was checked: the grace restarts whenever a unit becomes ready, so a queue still finishing
@@ -9544,21 +9626,33 @@ declare namespace TOOLKIT {
9544
9626
  */
9545
9627
  private static RestoreShadowCasterLists;
9546
9628
  /**
9547
- * Makes every point and spot shadow map gated by LightingConversions.SkipInvisiblePunctualShadowMap draw all its casters during
9548
- * the pipeline stage. The gate skips a map whose light is out of view, so on WebGPU a light the camera cannot see at the reveal
9549
- * built no caster pipelines and they compiled the first time it came into view (a late compile mid-race). Each gated map gets
9550
- * `_tkPrewarmDrawAll` (the gate then asks Babylon only), its caster culling list is set aside (Babylon draws the whole
9551
- * renderList), and it renders again on the next frame. Directional maps are left alone. RestorePunctualShadowMaps undoes it.
9629
+ * Makes every shadow map that culls its casters, or whose render is skipped, draw all its casters during the pipeline stage:
9630
+ * - a point or spot map gated by LightingConversions.SkipInvisiblePunctualShadowMap is skipped while its light is out of view, so
9631
+ * on WebGPU a light the camera cannot see at the reveal built no caster pipelines and they compiled the first time it came into
9632
+ * view (a late compile mid-race); it gets `_tkPrewarmDrawAll` (the gate then asks Babylon only);
9633
+ * - a map with one of the toolkit's caster culling lists (HasCasterCullingList: the Unity culling, or the terrain's) drops every
9634
+ * caster outside its pass, so a directional cascade drew only the casters near the opening view and a prop the camera reached
9635
+ * later built its shadow pipeline then (a late pipeline after a camera cut).
9636
+ * Each such map has its caster culling list set aside (Babylon draws the whole renderList) and renders again on the next frame.
9637
+ * RestoreFullShadowMaps undoes it.
9552
9638
  * @param scene - The scene being prewarmed.
9553
- * @returns What was changed, for RestorePunctualShadowMaps.
9639
+ * @returns What was changed, for RestoreFullShadowMaps.
9554
9640
  */
9555
- private static DrawPunctualShadowMapsFully;
9641
+ private static DrawShadowMapsFully;
9556
9642
  /**
9557
- * Puts back what DrawPunctualShadowMapsFully changed: the draw-all flag is cleared and each map gets its caster culling list
9558
- * back, unless something else installed a list meanwhile.
9559
- * @param draws - What DrawPunctualShadowMapsFully changed.
9643
+ * True when the shadow map's custom render list is one of the toolkit's caster cullings: LightingConversions.ApplyUnityCasterCulling
9644
+ * marks its function `tkCasterCulling`, and TerrainBuilder.InstallCasterCulling, which wraps it on a scene with terrain, marks
9645
+ * its own `tkTerrainCulling`.
9646
+ * @param shadowMap - The shadow map.
9647
+ * @returns True for a caster-culled map.
9560
9648
  */
9561
- private static RestorePunctualShadowMaps;
9649
+ static HasCasterCullingList(shadowMap: BABYLON.RenderTargetTexture): boolean;
9650
+ /**
9651
+ * Puts back what DrawShadowMapsFully changed: the draw-all flag is cleared and each map gets its caster culling list back, unless
9652
+ * something else installed a list meanwhile.
9653
+ * @param draws - What DrawShadowMapsFully changed.
9654
+ */
9655
+ private static RestoreFullShadowMaps;
9562
9656
  /** Frames each material of a material variant is drawn for in a row by the pipeline stage (AlternateMaterialVariants). */
9563
9657
  private static readonly MATERIAL_VARIANT_FRAMES;
9564
9658
  /** Per scene: meshes that also draw with another material during play (WarmMaterialVariant). */
@@ -9702,6 +9796,28 @@ declare namespace TOOLKIT {
9702
9796
  * @param draw - What AlternateScaleVariants changed (null: nothing).
9703
9797
  */
9704
9798
  private static RestoreScaleVariants;
9799
+ /**
9800
+ * The meshes a native LOD master can draw (Babylon `addLODLevel`): the master itself, then each level's mesh in order. The cull
9801
+ * band's null level and a mesh listed twice are left out.
9802
+ * @param mesh - Any mesh.
9803
+ * @returns The sequence, or an empty array when the mesh has no LOD levels.
9804
+ */
9805
+ static NativeLodSequence(mesh: BABYLON.AbstractMesh): BABYLON.AbstractMesh[];
9806
+ /**
9807
+ * Makes the frames of the reveal-time pipeline stage select every native LOD level in turn: frame n draws level n modulo the
9808
+ * group's level count for every native LOD master, through `scene.customLODSelector`, which Babylon asks for the main pass and for
9809
+ * every render target (shadow maps included). Without it a level drew only where a warm camera's distance selected it, so a LOD1
9810
+ * the opening view never reached built its GPU pipeline after the reveal. Meshes without levels keep the scene's own selection.
9811
+ * @param scene - The scene being prewarmed.
9812
+ * @returns What to undo (RestoreNativeLodLevels), or null when the scene has no native LOD group or WarmNativeLodLevelsOnReveal is false.
9813
+ */
9814
+ static CycleNativeLodLevels(scene: BABYLON.Scene): TOOLKIT.INativeLodCycle;
9815
+ /**
9816
+ * Ends CycleNativeLodLevels: the scene's own LOD selector is given back, unless something else replaced the cycle's meanwhile.
9817
+ * @param scene - The scene being prewarmed.
9818
+ * @param cycle - What CycleNativeLodLevels changed (null: nothing).
9819
+ */
9820
+ static RestoreNativeLodLevels(scene: BABYLON.Scene, cycle: TOOLKIT.INativeLodCycle): void;
9705
9821
  /**
9706
9822
  * Forces (or stops forcing) each mesh's other scaling state. While forced, the mesh's own `_updateNonUniformScalingState` property
9707
9823
  * keeps the other state through the frame's world-matrix updates (and the state is set at once for a mesh whose matrix is not
@@ -9796,6 +9912,7 @@ declare namespace TOOLKIT {
9796
9912
  * @param deadline - SceneShaderWarmup.NowMs() after which the stage stops waiting.
9797
9913
  * @param phases - The camera phases, in order; null draws the game's own camera(s).
9798
9914
  * @param onProgress - Called after each frame with the compiled and requested pipeline counts.
9915
+ * @param settleFrames - Consecutive quiet frames that end a phase (a LOD cycle needs one full cycle; default PIPELINE_SETTLE_FRAMES).
9799
9916
  * @returns Resolves true when the deadline passed before every phase was quiet.
9800
9917
  */
9801
9918
  private static WaitForPipelinesPerCamera;
@@ -9812,8 +9929,9 @@ declare namespace TOOLKIT {
9812
9929
  */
9813
9930
  private static RunCameraPhasesAsync;
9814
9931
  /**
9815
- * Renders frames (the render loop keeps running) until the scene's draws request no new pipeline for PIPELINE_SETTLE_FRAMES
9816
- * frames and none is still compiling, or the deadline passes. Reports `onProgress(compiled, requested)` after each frame.
9932
+ * Renders frames (the render loop keeps running) until the scene's draws request no new pipeline for `settleFrames` consecutive
9933
+ * frames (default PIPELINE_SETTLE_FRAMES) and none is still compiling, or the deadline passes. Reports `onProgress(compiled,
9934
+ * requested)` after each frame.
9817
9935
  */
9818
9936
  private static WaitForPipelines;
9819
9937
  /**
@@ -10531,6 +10649,21 @@ declare namespace TOOLKIT {
10531
10649
  /** The frame observer that switches the variant. */
10532
10650
  frameObserver: BABYLON.Observer<BABYLON.Scene>;
10533
10651
  }
10652
+ /** @hidden The native LOD selection the reveal-time pipeline stage forces in turn (CycleNativeLodLevels). */
10653
+ interface INativeLodCycle {
10654
+ /** Each native LOD master and the meshes it can draw, master first (NativeLodSequence). */
10655
+ sequences: Map<BABYLON.AbstractMesh, BABYLON.AbstractMesh[]>;
10656
+ /** The longest sequence: the frames one full cycle takes. */
10657
+ length: number;
10658
+ /** Frames drawn since the cycle began; frame n selects level n modulo a sequence's length. */
10659
+ frameIndex: number;
10660
+ /** The scene's own LOD selector, given back by RestoreNativeLodLevels (null when it had none). */
10661
+ previousSelector: (mesh: BABYLON.AbstractMesh, camera: BABYLON.Camera) => BABYLON.Nullable<BABYLON.AbstractMesh>;
10662
+ /** The selector the cycle installed. */
10663
+ selector: (mesh: BABYLON.AbstractMesh, camera: BABYLON.Camera) => BABYLON.Nullable<BABYLON.AbstractMesh>;
10664
+ /** The frame observer that advances frameIndex. */
10665
+ frameObserver: BABYLON.Observer<BABYLON.Scene>;
10666
+ }
10534
10667
  /** @hidden A hidden particle emitter the particle stage lets draw (ShowHiddenEmittersForDraws). */
10535
10668
  interface IHiddenEmitterDraw {
10536
10669
  /** The emitter node. */
@@ -10591,6 +10724,13 @@ declare namespace TOOLKIT {
10591
10724
  }
10592
10725
  /** @hidden A render target's custom render list (RenderTargetTexture.getCustomRenderList). */
10593
10726
  type CustomRenderListFunction = (layerOrFace: number, renderList: readonly BABYLON.AbstractMesh[], renderListLength: number) => BABYLON.AbstractMesh[];
10727
+ /** @hidden The marks the toolkit's caster culling lists carry on their function (SceneShaderWarmup.HasCasterCullingList). */
10728
+ interface ICasterCullingListMarks {
10729
+ /** Set by LightingConversions.ApplyUnityCasterCulling. */
10730
+ tkCasterCulling?: boolean;
10731
+ /** Set by TerrainBuilder.InstallCasterCulling. */
10732
+ tkTerrainCulling?: boolean;
10733
+ }
10594
10734
  /** @hidden A shadow map whose custom render list the reveal-time pipeline stage wrapped (KeepHiddenCastersInShadowMaps). */
10595
10735
  interface IShadowCasterListWrap {
10596
10736
  /** The shadow map. */
@@ -10600,8 +10740,8 @@ declare namespace TOOLKIT {
10600
10740
  /** The wrapper that keeps the shown hidden casters. */
10601
10741
  keptList: TOOLKIT.CustomRenderListFunction;
10602
10742
  }
10603
- /** @hidden A point or spot shadow map the reveal-time pipeline stage draws with all its casters (DrawPunctualShadowMapsFully). */
10604
- interface IPunctualShadowMapDraw {
10743
+ /** @hidden A gated or caster-culled shadow map the reveal-time pipeline stage draws with all its casters (DrawShadowMapsFully). */
10744
+ interface IShadowMapFullDraw {
10605
10745
  /** The shadow map. */
10606
10746
  shadowMap: BABYLON.RenderTargetTexture;
10607
10747
  /** Its caster culling list, set aside during the stage. */
@@ -11769,6 +11909,17 @@ declare namespace TOOLKIT {
11769
11909
  smoothDeltaTime: number;
11770
11910
  frame: number;
11771
11911
  }
11912
+ /** One shader global component advanced every frame by scene time, for values Unity's scripts drive at runtime. */
11913
+ interface IShaderGlobalDriver {
11914
+ /** The global's Unity reference name. */
11915
+ name: string;
11916
+ /** The vector component advanced: 0 x, 1 y, 2 z, 3 w. */
11917
+ component: number;
11918
+ /** Units per second. */
11919
+ rate: number;
11920
+ /** The value is wrapped by subtracting this when it passes it. Zero means no wrap. */
11921
+ wrap: number;
11922
+ }
11772
11923
  /**
11773
11924
  * Unity's shader globals for transpiled Shader Graph classes (shadergraph-transpiler-complete-coverage D16, D18).
11774
11925
  *
@@ -11787,6 +11938,8 @@ declare namespace TOOLKIT {
11787
11938
  * generated material of a scene animates in lockstep.
11788
11939
  */
11789
11940
  class ShaderGlobals {
11941
+ /** The Vector4 member each `IShaderGlobalDriver.component` index names. */
11942
+ private static readonly DriverComponentNames;
11790
11943
  private static _version;
11791
11944
  private static _floats;
11792
11945
  private static _vectors;
@@ -11820,6 +11973,19 @@ declare namespace TOOLKIT {
11820
11973
  * scene's first frame.
11821
11974
  */
11822
11975
  static LoadSceneGlobals(scene: BABYLON.Scene, block: any): void;
11976
+ /**
11977
+ * Advances exported shader globals every frame, so a value Unity's scripts drive at runtime keeps moving in the browser.
11978
+ * Adds one observer per scene, and only when the export lists a driver.
11979
+ * @param scene - The scene whose clock drives the values.
11980
+ * @param drivers - The exported drivers, or null.
11981
+ */
11982
+ static LoadSceneDrivers(scene: BABYLON.Scene, drivers: TOOLKIT.IShaderGlobalDriver[]): void;
11983
+ /**
11984
+ * Advances one driver in place. The stored Vector4 is mutated, so a frame allocates nothing. Bumps the version.
11985
+ * @param driver - The driver to advance.
11986
+ * @param deltaSeconds - Seconds since the last frame.
11987
+ */
11988
+ private static AdvanceDriver;
11823
11989
  /** The scene clock (registered on first use, removed when the scene is disposed). */
11824
11990
  static GetClock(scene: BABYLON.Scene): TOOLKIT.IShaderClock;
11825
11991
  }
@@ -12167,6 +12333,15 @@ declare namespace TOOLKIT {
12167
12333
  static ApplyInstanceBlock(instance: BABYLON.InstancedMesh, block: any, sub?: number): boolean;
12168
12334
  /** The clone of one material with a property block applied (null when the material is not a toolkit custom material). */
12169
12335
  static CloneWithBlock(material: BABYLON.Material, block: any, meshId: number, loadTexture?: (info: any, done: (texture: BABYLON.BaseTexture) => void) => void): BABYLON.Material;
12336
+ /**
12337
+ * Keeps the exporter's "not carried" list for the scene summary. Schedules the summary itself,
12338
+ * so a scene with no graph material still prints it.
12339
+ * @param scene - The scene the export belongs to.
12340
+ * @param entries - The `exportreport` metadata list; absent or empty when the export lost nothing.
12341
+ */
12342
+ static RecordExportReport(scene: BABYLON.Scene, entries: TOOLKIT.IExportReportEntry[]): void;
12343
+ /** Prints the exporter's list as one collapsed group, then forgets it so a later flush does not repeat it. */
12344
+ private static PrintExportReport;
12170
12345
  /** One warning for the missing classes, then one console.groupCollapsed per scene; clears the record. */
12171
12346
  static FlushSceneSummary(scene: BABYLON.Scene): void;
12172
12347
  }
@@ -12190,6 +12365,19 @@ declare namespace TOOLKIT {
12190
12365
  /** T32.1: the pending quiet-period timer and its latest flush time. */
12191
12366
  timer?: any;
12192
12367
  deadline?: number;
12368
+ /** The exporter's "not carried" list, until the summary prints it. */
12369
+ exportReport?: IExportReportEntry[];
12370
+ }
12371
+ /** One line of `metadata.exportreport`: something the export could not carry to the browser. */
12372
+ interface IExportReportEntry {
12373
+ /** The report group, such as `Renderer features`. */
12374
+ feature: string;
12375
+ /** Why the items do not reach the browser. */
12376
+ reason: string;
12377
+ /** Every distinct item name. */
12378
+ items: string[];
12379
+ /** How many times the exporter met this, which can exceed `items.length`. */
12380
+ count: number;
12193
12381
  }
12194
12382
  /**
12195
12383
  * shadergraph-transpiler-complete-coverage X2: the ShadowDepthWrapper of a graph class that casts through its own shader
@@ -14124,10 +14312,18 @@ declare namespace TOOLKIT {
14124
14312
  static readonly FADE_SPEEDTREE: number;
14125
14313
  /** Unity's LODGroup.crossFadeAnimationDuration default (the terrain trees use the same, TerrainTrees.FADE_SECONDS). */
14126
14314
  static FADE_SECONDS: number;
14315
+ /** Largest offset, in meters, at which a level still draws correctly with its master's world matrix. */
14316
+ static readonly NATIVE_TRANSFORM_TOLERANCE_METERS: number;
14317
+ /** Largest difference in one rotation or scale matrix element between a level and its master. */
14318
+ static readonly NATIVE_BASIS_TOLERANCE: number;
14319
+ /** The indices of a matrix's rotation and scale elements. */
14320
+ private static readonly BASIS_ELEMENTS;
14127
14321
  /**
14128
14322
  * H-a: the group's world size and local reference point from the exported `lodsize` (LODGroup.size, local) and
14129
- * `lodcenter` (LODGroup.localReferencePoint in the node's glTF local space). Unity's world size is the size times
14130
- * the largest absolute lossy scale. Null when the export has neither (older exports: the mesh boxes are used).
14323
+ * `lodcenter` (LODGroup.localReferencePoint with its x negated). The node's world matrix takes Unity's local axes, so
14324
+ * x is negated back here: the world point then equals Unity's `transform.TransformPoint(localReferencePoint)`.
14325
+ * Unity's world size is the size times the largest absolute lossy scale. Null when the export has neither (older
14326
+ * exports: the mesh boxes are used).
14131
14327
  */
14132
14328
  static ExportedSize(root: BABYLON.TransformNode, metadata: any): {
14133
14329
  worldSize: number;
@@ -14138,6 +14334,32 @@ declare namespace TOOLKIT {
14138
14334
  useDistances: boolean;
14139
14335
  thresholds: number[];
14140
14336
  };
14337
+ /**
14338
+ * Whether every level can be drawn by Babylon's native LOD, which draws a detail level with its master's world
14339
+ * matrix and ignores the detail's own. Levels authored with different pivots must use the shared switcher, or they
14340
+ * appear displaced by the difference. Reads each node's own matrix, so a mesh that is already a detail level is
14341
+ * judged by its own transform too.
14342
+ * @param master The LOD0 mesh.
14343
+ * @param details The lower levels' meshes.
14344
+ * @returns True when each detail's world transform matches the master's within the tolerances.
14345
+ */
14346
+ static LevelsShareTransform(master: BABYLON.AbstractMesh, details: BABYLON.AbstractMesh[]): boolean;
14347
+ /**
14348
+ * Whether two world matrices place a mesh at the same spot within the native tolerances.
14349
+ * @param first One world matrix.
14350
+ * @param second The other world matrix.
14351
+ * @returns True when their translations and their rotation and scale elements match.
14352
+ */
14353
+ private static MatricesShareTransform;
14354
+ /**
14355
+ * Whether a group must run on the shared switcher instead of Babylon's native LOD, on either native entry point
14356
+ * (coverages or the legacy distances): it cross-fades, a level has several renderers, or a level sits away from
14357
+ * LOD0's world transform. Instanced masters answer like any other: their legacy handling stays with the caller.
14358
+ * @param meshLevels The resolved meshes of each level, LOD0 first.
14359
+ * @param fadeMode The group's FADE_* mode.
14360
+ * @returns True when only the switcher can draw the group as authored.
14361
+ */
14362
+ static RequiresSwitcher(meshLevels: BABYLON.AbstractMesh[][], fadeMode: number): boolean;
14141
14363
  /** Exported fade mode name => FADE_*. */
14142
14364
  static ParseFadeMode(mode: string): number;
14143
14365
  /** Scene-wide QualitySettings.lodBias (the exported `lodbias`, 1 when absent). */
@@ -14198,7 +14420,10 @@ declare namespace TOOLKIT {
14198
14420
  * group culls below the last coverage, and an orthographic camera (whose Babylon LOD distance is minZ) gets
14199
14421
  * 0 / 1e30 thresholds that pick Unity's distance-independent level. They are recomputed only when the camera,
14200
14422
  * its fov / fov mode / aspect / projection / ortho size, or the LOD bias change.
14201
- * `details[k - 1]` is level k's mesh. Returns false (nothing registered) when the levels cannot be native.
14423
+ * `details[k - 1]` is level k's mesh. Returns false (nothing registered) when the levels cannot be native: a level
14424
+ * authored away from LOD0 (LevelsShareTransform), or a master with instances. An InstancedMesh follows its source's
14425
+ * LOD levels while the switcher toggles that same instance, so such a master joins its instances on the switcher and
14426
+ * every level has one owner.
14202
14427
  */
14203
14428
  addNativeGroup(master: BABYLON.Mesh, details: BABYLON.Mesh[], coverages: number[], worldSize: number): boolean;
14204
14429
  get nativeGroupCount(): number;
@@ -17166,6 +17391,8 @@ declare namespace TOOLKIT {
17166
17391
  transports: TOOLKIT.GameServerTransports;
17167
17392
  /** True when joins need an auth token. */
17168
17393
  authRequired: boolean;
17394
+ /** True when players can sign in with Discord (Babylon Game Server discordSignIn). */
17395
+ discordSignIn?: boolean;
17169
17396
  }
17170
17397
  /** The connections a game server accepts. */
17171
17398
  interface GameServerTransports {
@@ -23669,6 +23896,629 @@ declare namespace TOOLKIT {
23669
23896
  restoreSceneObjects(token: HostMigrationToken): void;
23670
23897
  }
23671
23898
  }
23899
+ declare namespace TOOLKIT {
23900
+ /** Which scores rank first: "lowerIsBetter" for times, "higherIsBetter" for points and counters. */
23901
+ type LeaderboardSortOrder = "higherIsBetter" | "lowerIsBetter";
23902
+ /** How a score is shown: a plain integer, milliseconds shown as a time, or points. Scores are integers (D12). */
23903
+ type LeaderboardScoreFormat = "integer" | "timeMilliseconds" | "points";
23904
+ /** What a new score does to a player's entry: keep the best, keep the latest, or add to a running total (D14). */
23905
+ type LeaderboardKeepPolicy = "best" | "latest" | "sum";
23906
+ /** How far a submission can be trusted (D9): signed by the game client, confirmed by session presence, or sent by a server API key. */
23907
+ type LeaderboardTrustLevel = "client" | "session" | "server";
23908
+ /** Why a request or one score was refused. */
23909
+ type LeaderboardRefusalReason = "invalidRequest" | "authRequired" | "authRefused" | "banned" | "invalidPlayer" | "rateLimited" | "tooManyScores" | "unknownBoard" | "variantNotAllowed" | "scoreNotInteger" | "scoreOutOfRange" | "trustLevelNotAccepted" | "implausibleDuration" | "metadataTooLarge" | "nameInvalid" | "nameBlocked" | "nameManaged";
23910
+ /** What a write did to the player's stored entry (D14). */
23911
+ type LeaderboardWriteOutcome = "created" | "improved" | "replaced" | "added" | "kept";
23912
+ /** A JSON value allowed in entry metadata (display-only details next to a score). */
23913
+ type LeaderboardMetadataValue = string | number | boolean | null | LeaderboardMetadataValue[] | {
23914
+ [key: string]: LeaderboardMetadataValue;
23915
+ };
23916
+ /** Free-form, size-capped details stored with an entry; never ranked or queried. */
23917
+ type LeaderboardMetadata = {
23918
+ [key: string]: LeaderboardMetadataValue;
23919
+ };
23920
+ /** One way a board's rankings are split (a "map", a "difficulty"), with the values a submission may use (D16). */
23921
+ interface LeaderboardVariantDimension {
23922
+ /** Key in a submission's variant object. */
23923
+ name: string;
23924
+ /** Label shown in the console and in games. */
23925
+ label: string;
23926
+ /** Allowed values, in display order. */
23927
+ values: string[];
23928
+ }
23929
+ /** A board as game clients see it. */
23930
+ interface LeaderboardPublicBoardView {
23931
+ boardId: string;
23932
+ displayName: string;
23933
+ description: string;
23934
+ sortOrder: LeaderboardSortOrder;
23935
+ scoreFormat: LeaderboardScoreFormat;
23936
+ keepPolicy: LeaderboardKeepPolicy;
23937
+ dimensions: LeaderboardVariantDimension[];
23938
+ currentSeasonId: number;
23939
+ currentSeasonStartedAt: string;
23940
+ /** ISO time of the next scheduled reset, or null. */
23941
+ nextResetAt: string | null;
23942
+ }
23943
+ /** One season of a board. */
23944
+ interface LeaderboardSeasonView {
23945
+ /** 1, 2, 3 … */
23946
+ seasonId: number;
23947
+ /** ISO start. */
23948
+ startedAt: string;
23949
+ /** ISO end, or null for the current season. */
23950
+ endedAt: string | null;
23951
+ isCurrent: boolean;
23952
+ }
23953
+ /** One ranked entry. */
23954
+ interface LeaderboardEntryView {
23955
+ /** 1-based rank in its ranking. */
23956
+ rank: number;
23957
+ playerId: string;
23958
+ /** The name the player had when the entry was written (console renames update it). */
23959
+ displayName: string;
23960
+ /** The player's avatar claim (a Discord avatar hash for user:discord: players), or null. */
23961
+ avatar?: string | null;
23962
+ score: number;
23963
+ metadata: LeaderboardMetadata | null;
23964
+ trustLevel: LeaderboardTrustLevel;
23965
+ /** ISO time of the last accepted submission. */
23966
+ submittedAt: string;
23967
+ /** ISO time the stored score was reached (tie-break, D13). */
23968
+ achievedAt: string;
23969
+ }
23970
+ /** A page of one ranking. */
23971
+ interface LeaderboardEntriesPage {
23972
+ boardId: string;
23973
+ seasonId: number;
23974
+ variantKey: string;
23975
+ /** Entries in the ranking. */
23976
+ total: number;
23977
+ /** Zero-based index of the first entry. */
23978
+ offset: number;
23979
+ entries: LeaderboardEntryView[];
23980
+ }
23981
+ /** A window around one player; `playerRank` is null when the player has no entry. */
23982
+ interface LeaderboardAroundPage extends LeaderboardEntriesPage {
23983
+ playerRank: number | null;
23984
+ }
23985
+ /** A player as games see them. */
23986
+ interface LeaderboardPlayerView {
23987
+ playerId: string;
23988
+ displayName: string;
23989
+ kind: "anonymous" | "user" | "manual";
23990
+ createdAt: string;
23991
+ }
23992
+ /** The answer to POST players: the player and, only when it was just created anonymously, its one-time key. */
23993
+ interface LeaderboardPlayerSession {
23994
+ player: LeaderboardPlayerView;
23995
+ playerKey: string | null;
23996
+ }
23997
+ /** One score in a submission. */
23998
+ interface LeaderboardScoreSubmission {
23999
+ boardId: string;
24000
+ /** Dimension values; null or {} for a board without dimensions. */
24001
+ variant: Record<string, string> | null;
24002
+ score: number;
24003
+ metadata: LeaderboardMetadata | null;
24004
+ }
24005
+ /** POST submissions: the envelope every game sends at a key stage (spec D13). */
24006
+ interface LeaderboardSubmissionRequest {
24007
+ /** The anonymous player's key, or omitted for an auth user. */
24008
+ playerKey?: string;
24009
+ /** Client-made unique id, 8–64 of `[A-Za-z0-9-]` (exactly-once, D15). */
24010
+ submissionId: string;
24011
+ /** The game's mode name, at most 64 characters, or null. */
24012
+ gameMode: string | null;
24013
+ /** The game's build version, at most 64 characters, or null. */
24014
+ buildVersion: string | null;
24015
+ /** The network session name when the scores come from a network game, or null. */
24016
+ sessionName: string | null;
24017
+ /** How long the run lasted, in milliseconds, or null. */
24018
+ durationMs: number | null;
24019
+ /** The client's ISO clock (informational only; the server stamps its own time). */
24020
+ clientTime: string | null;
24021
+ /** 1–maximumScoresPerSubmission scores. */
24022
+ scores: LeaderboardScoreSubmission[];
24023
+ }
24024
+ /** What happened to one score. */
24025
+ interface LeaderboardScoreResult {
24026
+ boardId: string;
24027
+ variantKey: string | null;
24028
+ status: "accepted" | "duplicate" | "refused";
24029
+ outcome: LeaderboardWriteOutcome | null;
24030
+ /** The stored score after the keep policy, or null when refused. */
24031
+ score: number | null;
24032
+ previousScore: number | null;
24033
+ /** True when this submission created or improved the player's entry (or changed a latest/sum entry). */
24034
+ isPersonalBest: boolean;
24035
+ rank: number | null;
24036
+ total: number | null;
24037
+ seasonId: number | null;
24038
+ trustLevel: LeaderboardTrustLevel | null;
24039
+ refusal: LeaderboardRefusalReason | null;
24040
+ }
24041
+ /** The answer to POST submissions. */
24042
+ interface LeaderboardSubmissionResponse {
24043
+ submissionId: string;
24044
+ playerId: string;
24045
+ results: LeaderboardScoreResult[];
24046
+ }
24047
+ /** One ranking a player asks about. */
24048
+ interface LeaderboardTarget {
24049
+ boardId: string;
24050
+ variant: Record<string, string> | null;
24051
+ /** A season, or omitted for the current one. */
24052
+ seasonId?: number;
24053
+ }
24054
+ /** A player's entry in one ranking (null when they have none). */
24055
+ interface LeaderboardTargetEntry {
24056
+ boardId: string;
24057
+ variantKey: string;
24058
+ seasonId: number;
24059
+ total: number;
24060
+ entry: LeaderboardEntryView | null;
24061
+ }
24062
+ /** The error body of a refused public request. */
24063
+ interface LeaderboardErrorBody {
24064
+ error: string;
24065
+ reason: LeaderboardRefusalReason;
24066
+ }
24067
+ /** The part of the Web Storage API the client keeps its player key and unsent scores in (window.localStorage fits). */
24068
+ interface LeaderboardStorage {
24069
+ getItem(key: string): string | null;
24070
+ setItem(key: string, value: string): void;
24071
+ removeItem(key: string): void;
24072
+ }
24073
+ /** A fetch function (globalThis.fetch fits; tests pass a stub). */
24074
+ type LeaderboardFetch = (url: string, init: RequestInit) => Promise<Response>;
24075
+ /** Options of a LeaderboardClient. */
24076
+ interface LeaderboardClientOptions {
24077
+ /** The game's session server URL (ws://, wss://, http:// or https://), the same URL its network sessions use. */
24078
+ serverUrl: string;
24079
+ /** The server's auth token (the one startGame takes), or omitted when the server's auth is off. */
24080
+ authToken?: string;
24081
+ /** The game's build version, sent with every submission. */
24082
+ buildVersion?: string;
24083
+ /** Where the key and unsent scores are kept; default window.localStorage, null keeps nothing. */
24084
+ storage?: LeaderboardStorage | null;
24085
+ /** The fetch to use; default globalThis.fetch. */
24086
+ fetchFunction?: LeaderboardFetch;
24087
+ /** Milliseconds before a request counts as not sent; default 8000. */
24088
+ requestTimeoutMs?: number;
24089
+ /** Most unsent submissions kept on the device; default 50 (the oldest is dropped). */
24090
+ maximumPendingSubmissions?: number;
24091
+ }
24092
+ /** What a game passes at a key stage: its scores and the run's facts; the client adds the rest of the envelope. */
24093
+ interface LeaderboardSubmission {
24094
+ scores: TOOLKIT.LeaderboardScoreSubmission[];
24095
+ /** The game's mode name. */
24096
+ gameMode?: string;
24097
+ /** The network session name, when the scores come from a network game. */
24098
+ sessionName?: string;
24099
+ /** How long the run lasted, in milliseconds. */
24100
+ durationMs?: number;
24101
+ }
24102
+ /** The result of a read or profile call: the value, a refusal, or not sent (offline, timeout, server error). */
24103
+ type LeaderboardCallResult<Value> = {
24104
+ status: "ok";
24105
+ value: Value;
24106
+ } | {
24107
+ status: "refused";
24108
+ reason: TOOLKIT.LeaderboardRefusalReason;
24109
+ message: string;
24110
+ } | {
24111
+ status: "notSent";
24112
+ message: string;
24113
+ };
24114
+ /** The result of a submission: sent, queued for later (offline), or refused. Never thrown. */
24115
+ type LeaderboardSubmitResult = {
24116
+ status: "sent";
24117
+ response: TOOLKIT.LeaderboardSubmissionResponse;
24118
+ } | {
24119
+ status: "queued";
24120
+ submissionId: string;
24121
+ message: string;
24122
+ } | {
24123
+ status: "refused";
24124
+ reason: TOOLKIT.LeaderboardRefusalReason;
24125
+ message: string;
24126
+ };
24127
+ /** A read of one ranking. */
24128
+ interface LeaderboardRangeQuery {
24129
+ variant?: Record<string, string> | null;
24130
+ seasonId?: number;
24131
+ offset?: number;
24132
+ limit?: number;
24133
+ }
24134
+ /**
24135
+ * Talks to the Babylon Game Server's leaderboard service over HTTP (game-server-leaderboards D7, D8). It needs no
24136
+ * network session, so single-player screens use it too, and it never loads the Colyseus client. Submit at key
24137
+ * stages only (a match, round or level finish; the end of a multi-part run), one call per stage with every board that
24138
+ * stage updates. Failed submissions wait on the device and are sent, once, on a later call.
24139
+ * @example
24140
+ * const client: TOOLKIT.LeaderboardClient = new TOOLKIT.LeaderboardClient({ serverUrl: "wss://game.example.com", authToken: token });
24141
+ * const result: TOOLKIT.LeaderboardSubmitResult = await client.submit({ gameMode: "arena", durationMs: 92500, scores: [
24142
+ * { boardId: "arena-high-score", variant: { map: "harbor" }, score: 1840, metadata: { hero: "knight" } }
24143
+ * ] });
24144
+ */
24145
+ class LeaderboardClient {
24146
+ /** Milliseconds before a request counts as not sent, when the options name none. */
24147
+ static readonly DEFAULT_REQUEST_TIMEOUT_MS: number;
24148
+ /** Most unsent submissions kept on the device, when the options name none. */
24149
+ static readonly DEFAULT_MAXIMUM_PENDING_SUBMISSIONS: number;
24150
+ /** The server path every leaderboard route sits under. */
24151
+ static readonly API_PATH: string;
24152
+ /** Prefix of every storage key the client writes. */
24153
+ static readonly STORAGE_PREFIX: string;
24154
+ /** Storage key suffix of the anonymous identity. */
24155
+ private static readonly PLAYER_STORAGE_SUFFIX;
24156
+ /** Storage key suffix of the unsent submissions. */
24157
+ private static readonly PENDING_STORAGE_SUFFIX;
24158
+ /** Bytes of randomness in a submission id made from crypto.getRandomValues. */
24159
+ private static readonly SUBMISSION_ID_RANDOM_BYTES;
24160
+ /** Shortest submission id the server accepts. */
24161
+ private static readonly MINIMUM_SUBMISSION_ID_LENGTH;
24162
+ /** Random decimal digits appended to the clock in the last-resort submission id. */
24163
+ private static readonly FALLBACK_RANDOM_DIGITS;
24164
+ /** First HTTP status that is not a success. */
24165
+ private static readonly HTTP_FIRST_FAILURE_STATUS;
24166
+ /** HTTP status of a rate-limited request: sent again later, never refused. */
24167
+ private static readonly HTTP_TOO_MANY_REQUESTS;
24168
+ /** First HTTP status of a server error: sent again later, never refused. */
24169
+ private static readonly HTTP_FIRST_SERVER_ERROR;
24170
+ /** Message of a call made where no fetch exists. */
24171
+ private static readonly NO_FETCH_MESSAGE;
24172
+ /** Message of a queued submission. */
24173
+ private static readonly QUEUED_MESSAGE;
24174
+ /** The server's HTTP(S) address. */
24175
+ private readonly endpoint;
24176
+ /** The server's auth token, or an empty string to send none (setAuthToken changes it). */
24177
+ private authToken;
24178
+ /** The game's build version, or null. */
24179
+ private readonly buildVersion;
24180
+ /** Where the identity and unsent submissions are kept, or null for memory only. */
24181
+ private readonly storage;
24182
+ /** The fetch from the options, or null for globalThis.fetch at call time. */
24183
+ private readonly fetchFunction;
24184
+ /** Milliseconds before a request counts as not sent. */
24185
+ private readonly requestTimeoutMs;
24186
+ /** Most unsent submissions kept. */
24187
+ private readonly maximumPendingSubmissions;
24188
+ /** The identity as last written, used when the storage is missing or throws. */
24189
+ private memoryPlayer;
24190
+ /** The unsent submissions as last written, used when the storage is missing or throws. */
24191
+ private memoryPending;
24192
+ /** True once a storage call has thrown: from then on the identity and the waiting list live in memory only. */
24193
+ private storageFailed;
24194
+ /** The flush running now, shared by calls that overlap it, or null. */
24195
+ private flushInFlight;
24196
+ /**
24197
+ * Creates a client for one game server. Nothing is sent until a method is called.
24198
+ * @param options The server URL, auth token, build version, storage, fetch and limits.
24199
+ */
24200
+ constructor(options: TOOLKIT.LeaderboardClientOptions);
24201
+ /** The server's HTTP(S) address (ws:// → http://, wss:// → https://). */
24202
+ get httpEndpoint(): string;
24203
+ /** Unsent submissions waiting on this device. */
24204
+ get pendingCount(): number;
24205
+ /**
24206
+ * This device's anonymous player key for this server, or null before the first identity call or when nothing
24207
+ * is stored. Send it only to the game's own server (for example so a sign-in can move the anonymous history);
24208
+ * never show or log it.
24209
+ */
24210
+ get playerKey(): string | null;
24211
+ /**
24212
+ * The HTTP(S) address of a session server URL: ws:// maps to http://, wss:// to https://, anything else is kept.
24213
+ * @param serverUrl The game's session server URL.
24214
+ * @returns The HTTP(S) address.
24215
+ */
24216
+ static toHttpEndpoint(serverUrl: string): string;
24217
+ /**
24218
+ * Changes the token every later request sends, for a game whose player signs in or out without a reload.
24219
+ * Waiting submissions stay queued and are sent with the new token.
24220
+ * @param token The new token; null or an empty string sends none.
24221
+ */
24222
+ setAuthToken(token: string | null): void;
24223
+ /**
24224
+ * Forgets this device's anonymous player key for this server, in memory and in the storage, for a game whose
24225
+ * anonymous player was moved into a signed-in player (the server erased it, so the key would only be refused).
24226
+ * The next identity call makes a new anonymous player. Never throws.
24227
+ */
24228
+ forgetPlayerKey(): void;
24229
+ /**
24230
+ * Reads this device's player (POST players), creating an anonymous identity the first time. A new key is stored;
24231
+ * a stored key the server no longer knows is forgotten and a new identity is made, once.
24232
+ * @returns The player, a refusal, or not sent. Never throws.
24233
+ */
24234
+ getPlayer(): Promise<TOOLKIT.LeaderboardCallResult<TOOLKIT.LeaderboardPlayerView>>;
24235
+ /**
24236
+ * Changes the player's display name (POST players/me/name), creating the identity first when there is none.
24237
+ * @param displayName The new name; the server checks its length and blocked words.
24238
+ * @returns The renamed player, a refusal (nameInvalid, nameBlocked …), or not sent. Never throws.
24239
+ */
24240
+ setDisplayName(displayName: string): Promise<TOOLKIT.LeaderboardCallResult<TOOLKIT.LeaderboardPlayerView>>;
24241
+ /**
24242
+ * Submits the scores of one key stage. Waiting submissions are flushed first, then the identity is ensured, then
24243
+ * this one is posted. Offline, timed out, rate limited or a server error: it is queued and sent once on a later call.
24244
+ * An auth refusal keeps the submission queued, so it is sent once the game has a token the server accepts.
24245
+ * @param submission The scores and the run's facts.
24246
+ * @returns Sent with the server's per-score results, queued, or refused. Never throws.
24247
+ */
24248
+ submit(submission: TOOLKIT.LeaderboardSubmission): Promise<TOOLKIT.LeaderboardSubmitResult>;
24249
+ /**
24250
+ * Sends the waiting submissions, oldest first, with the current identity. It stops at the first one that is not
24251
+ * sent or that the server refuses for its token (keeping it and the rest) and drops other refused ones. Overlapping
24252
+ * calls share one flush.
24253
+ * @returns How many were sent. Never throws.
24254
+ */
24255
+ flushPending(): Promise<number>;
24256
+ /**
24257
+ * Lists the public boards (GET boards).
24258
+ * @returns The boards, a refusal, or not sent. Never throws.
24259
+ */
24260
+ listBoards(): Promise<TOOLKIT.LeaderboardCallResult<TOOLKIT.LeaderboardPublicBoardView[]>>;
24261
+ /**
24262
+ * Lists a board's seasons (GET boards/:boardId/seasons).
24263
+ * @param boardId The board.
24264
+ * @returns The seasons, a refusal, or not sent. Never throws.
24265
+ */
24266
+ listSeasons(boardId: string): Promise<TOOLKIT.LeaderboardCallResult<TOOLKIT.LeaderboardSeasonView[]>>;
24267
+ /**
24268
+ * Reads a page of one ranking from the top (GET boards/:boardId/entries).
24269
+ * @param boardId The board.
24270
+ * @param query The variant, season (default current), offset (default 0) and page size (the server's default).
24271
+ * @returns The page, a refusal, or not sent. Never throws.
24272
+ */
24273
+ getTop(boardId: string, query?: TOOLKIT.LeaderboardRangeQuery): Promise<TOOLKIT.LeaderboardCallResult<TOOLKIT.LeaderboardEntriesPage>>;
24274
+ /**
24275
+ * Reads the entries around this device's player in one ranking (POST boards/:boardId/around).
24276
+ * @param boardId The board.
24277
+ * @param variant The ranking's dimension values, or null for a board without dimensions.
24278
+ * @param window Entries above and below the player (the server's default when omitted).
24279
+ * @param seasonId A season, or omitted for the current one.
24280
+ * @returns The page with the player's rank (null without an entry), a refusal, or not sent. Never throws.
24281
+ */
24282
+ getAroundMe(boardId: string, variant: Record<string, string> | null, window?: number, seasonId?: number): Promise<TOOLKIT.LeaderboardCallResult<TOOLKIT.LeaderboardAroundPage>>;
24283
+ /**
24284
+ * Reads this device's player's entry in several rankings at once (POST entries/mine).
24285
+ * @param targets The rankings.
24286
+ * @returns One answer per target (entry null where the player has none), a refusal, or not sent. Never throws.
24287
+ */
24288
+ getMyEntries(targets: TOOLKIT.LeaderboardTarget[]): Promise<TOOLKIT.LeaderboardCallResult<TOOLKIT.LeaderboardTargetEntry[]>>;
24289
+ /**
24290
+ * Reads the entries of chosen players in one ranking (POST boards/:boardId/players), e.g. the players of a session.
24291
+ * @param boardId The board.
24292
+ * @param playerIds The players (at most 50).
24293
+ * @param variant The ranking's dimension values, or null for a board without dimensions.
24294
+ * @param seasonId A season, or omitted for the current one.
24295
+ * @returns The players' entries (players without one are absent), a refusal, or not sent. Never throws.
24296
+ */
24297
+ getPlayersEntries(boardId: string, playerIds: string[], variant?: Record<string, string> | null, seasonId?: number): Promise<TOOLKIT.LeaderboardCallResult<TOOLKIT.LeaderboardEntryView[]>>;
24298
+ /**
24299
+ * Erases this device's player and every entry of theirs on the server (POST players/me/delete). On success the
24300
+ * stored identity and the waiting submissions are forgotten too.
24301
+ * @returns How many entries were erased, a refusal, or not sent. Never throws.
24302
+ */
24303
+ deleteMyData(): Promise<TOOLKIT.LeaderboardCallResult<number>>;
24304
+ /**
24305
+ * Posts a JSON body.
24306
+ * @param path The route after API_PATH.
24307
+ * @param body The body.
24308
+ * @returns The answer.
24309
+ */
24310
+ private postJson;
24311
+ /**
24312
+ * Reads a route.
24313
+ * @param path The route after API_PATH, with its query string.
24314
+ * @returns The answer.
24315
+ */
24316
+ private getJson;
24317
+ /**
24318
+ * Sends one request and sorts its answer: 2xx is ok, 429 and 5xx are not sent, any other 4xx is refused with the
24319
+ * body's reason (invalidRequest when it has none). A network failure or timeout is not sent.
24320
+ * @param method The HTTP method.
24321
+ * @param path The route after API_PATH.
24322
+ * @param body The JSON body, or null for none.
24323
+ * @returns The answer. Never throws.
24324
+ */
24325
+ private send;
24326
+ /**
24327
+ * The full URL of a route.
24328
+ * @param path The route after API_PATH.
24329
+ * @returns The URL.
24330
+ */
24331
+ private routeUrl;
24332
+ /**
24333
+ * The fetch options of a request: plain-object headers (JSON content type on bodies, the bearer token when auth
24334
+ * is on) and a timeout signal when the environment has one.
24335
+ * @param method The HTTP method.
24336
+ * @param body The JSON body, or null for none.
24337
+ * @returns The options.
24338
+ */
24339
+ private requestInit;
24340
+ /**
24341
+ * Posts a route that names a player, with the stored key when there is one. A key the server no longer knows is
24342
+ * forgotten.
24343
+ * @param path The route after API_PATH.
24344
+ * @param fields The body without the key.
24345
+ * @returns The answer.
24346
+ */
24347
+ private postAsStoredPlayer;
24348
+ /**
24349
+ * Posts a route that names a player after making sure the device has an identity. A key the server no longer
24350
+ * knows is forgotten, a new identity is made and the post is repeated once.
24351
+ * @param path The route after API_PATH.
24352
+ * @param fields The body without the key.
24353
+ * @returns The answer.
24354
+ */
24355
+ private postAsIdentifiedPlayer;
24356
+ /**
24357
+ * Ensures the identity, then posts with its key.
24358
+ * @param path The route after API_PATH.
24359
+ * @param fields The body without the key.
24360
+ * @returns The answer and whether a key was sent.
24361
+ */
24362
+ private postWithIdentity;
24363
+ /**
24364
+ * Makes sure the device can name its player: a stored key is enough; otherwise POST players (an auth user, or a
24365
+ * new anonymous identity).
24366
+ * @returns Ok, or why there is no identity.
24367
+ */
24368
+ private ensureIdentity;
24369
+ /**
24370
+ * POST players with a key or without one; a key in the answer is stored.
24371
+ * @param storedPlayer The identity whose key is sent, or null to send none.
24372
+ * @returns The player.
24373
+ */
24374
+ private requestPlayerSession;
24375
+ /**
24376
+ * Posts one submission envelope as the device's player.
24377
+ * @param request The envelope, without a key.
24378
+ * @returns The server's per-score results, a refusal, or not sent.
24379
+ */
24380
+ private postSubmission;
24381
+ /**
24382
+ * Builds the full envelope of a submission.
24383
+ * @param submission What the game passed.
24384
+ * @returns The envelope, without a key.
24385
+ */
24386
+ private buildSubmissionRequest;
24387
+ /**
24388
+ * Sends the waiting submissions (flushPending's work).
24389
+ * @returns How many were sent. Never throws.
24390
+ */
24391
+ private flushQueue;
24392
+ /**
24393
+ * Puts a submission at the end of the waiting list, dropping the oldest beyond the limit.
24394
+ * @param request The envelope, without a key.
24395
+ * @returns The queued result.
24396
+ */
24397
+ private queueSubmission;
24398
+ /**
24399
+ * Takes one submission off the waiting list.
24400
+ * @param submissionId Its id.
24401
+ */
24402
+ private removePending;
24403
+ /**
24404
+ * The stored anonymous identity.
24405
+ * @returns The identity, or null when there is none (memory's copy when the storage is missing or has thrown).
24406
+ */
24407
+ private readStoredPlayer;
24408
+ /**
24409
+ * Keeps the anonymous identity, in memory and in the storage.
24410
+ * @param player The identity.
24411
+ */
24412
+ private storePlayer;
24413
+ /** Forgets the anonymous identity, in memory and in the storage. */
24414
+ private forgetPlayer;
24415
+ /**
24416
+ * The waiting submissions, oldest first.
24417
+ * @returns The envelopes, without keys.
24418
+ */
24419
+ private readPending;
24420
+ /**
24421
+ * Replaces the waiting submissions, in memory and in the storage (an empty list removes the storage item).
24422
+ * @param pending The envelopes, without keys, oldest first.
24423
+ */
24424
+ private writePending;
24425
+ /**
24426
+ * A storage key of this server.
24427
+ * @param suffix The item's suffix.
24428
+ * @returns The key.
24429
+ */
24430
+ private storageKey;
24431
+ /**
24432
+ * Reads a storage item.
24433
+ * @param key The key.
24434
+ * @returns The text, null when the item is absent, or undefined when there is no usable storage (read memory).
24435
+ */
24436
+ private readStorageItem;
24437
+ /**
24438
+ * Writes a storage item; a missing or throwing storage keeps nothing (memory keeps it).
24439
+ * @param key The key.
24440
+ * @param value The text.
24441
+ */
24442
+ private writeStorageItem;
24443
+ /**
24444
+ * Removes a storage item; a missing or throwing storage keeps nothing (memory keeps it).
24445
+ * @param key The key.
24446
+ */
24447
+ private removeStorageItem;
24448
+ /**
24449
+ * A new submission id of 8–64 characters from `[A-Za-z0-9-]`: crypto.randomUUID(), else 16 random bytes in hex
24450
+ * from crypto.getRandomValues, else the clock and Math.random digits.
24451
+ * @returns The id.
24452
+ */
24453
+ private static newSubmissionId;
24454
+ /**
24455
+ * A signal that aborts the request after requestTimeoutMs, when the environment has AbortSignal.timeout.
24456
+ * @returns The signal, or null.
24457
+ */
24458
+ private timeoutSignal;
24459
+ /**
24460
+ * A query string built with encodeURIComponent; parameters without a value are left out.
24461
+ * @param parameters Names and values.
24462
+ * @returns "?name=value&…", or an empty string.
24463
+ */
24464
+ private static queryString;
24465
+ /**
24466
+ * window.localStorage when the page has one and it can be reached.
24467
+ * @returns The storage, or null.
24468
+ */
24469
+ private static defaultStorage;
24470
+ /**
24471
+ * globalThis.fetch, bound to the global object.
24472
+ * @returns The fetch, or null when the environment has none.
24473
+ */
24474
+ private static globalFetch;
24475
+ /**
24476
+ * A body with the identity's key added (never in a header or the URL, D6).
24477
+ * @param fields The body without the key.
24478
+ * @param storedPlayer The identity, or null to add no key.
24479
+ * @returns A new body.
24480
+ */
24481
+ private static withPlayerKey;
24482
+ /**
24483
+ * Reads a response's JSON body.
24484
+ * @param response The response.
24485
+ * @returns The parsed body, or null when it is empty or not JSON.
24486
+ */
24487
+ private static readBody;
24488
+ /**
24489
+ * Sorts an HTTP answer into ok, refused or not sent.
24490
+ * @param status The HTTP status.
24491
+ * @param body The parsed body.
24492
+ * @returns The call result.
24493
+ */
24494
+ private static sortAnswer;
24495
+ /**
24496
+ * Whether an answer says the sent player key is unknown.
24497
+ * @param answer The answer.
24498
+ * @returns True for a refusal with reason invalidPlayer.
24499
+ */
24500
+ private static isInvalidPlayer;
24501
+ /**
24502
+ * Whether an answer is the server refusing the token itself (the player's session ended or changed), which must
24503
+ * never cost a waiting score.
24504
+ * @param answer The answer.
24505
+ * @returns True for a refusal with reason authRequired or authRefused.
24506
+ */
24507
+ private static isAuthRefusal;
24508
+ /**
24509
+ * A not-sent result for something thrown.
24510
+ * @param error What was thrown.
24511
+ * @returns The result.
24512
+ */
24513
+ private static notSent;
24514
+ /**
24515
+ * A one-line description of something thrown.
24516
+ * @param error What was thrown.
24517
+ * @returns Its message.
24518
+ */
24519
+ private static describeError;
24520
+ }
24521
+ }
23672
24522
  declare namespace TOOLKIT {
23673
24523
  /** Marks a kart that this client does not simulate (a network replica) so local karts still bump it (D16). */
23674
24524
  class KartBumpTarget extends TOOLKIT.ScriptComponent {
@@ -23729,6 +24579,11 @@ declare namespace TOOLKIT {
23729
24579
  const DRIVER_HAS_ITEM_PARAMETER: string;
23730
24580
  /** Reversing: the driver turns to look behind (`Player.cs:1479-1489`, `Driver.SetBool("Reverse", …)`). */
23731
24581
  const DRIVER_REVERSE_PARAMETER: string;
24582
+ /**
24583
+ * The driver's trick triggers, in the order Unity fires them: `Player.cs:2557-2600` `trickJump()` cycles
24584
+ * `trickAnimCounter` 0 → 1 → 2 → 0 and sets `Driver.SetTrigger("JumpTrick1")`, `"JumpTrick2"`, `"GliderTrick"`.
24585
+ */
24586
+ const DRIVER_TRICK_TRIGGERS: readonly string[];
23732
24587
  /** Which way the driver leans this frame. Both false is the upright `New State`. */
23733
24588
  interface IDriverLeanState {
23734
24589
  /** The `TurnLeft` bool. */
@@ -23787,6 +24642,8 @@ declare namespace TOOLKIT {
23787
24642
  private hasWrittenHead;
23788
24643
  /** The `Reverse` value last delivered to at least one Animator; the bool is written only when it changes. */
23789
24644
  private reverseWritten;
24645
+ /** Index into `DRIVER_TRICK_TRIGGERS` of the next trick pose (Unity's `trickAnimCounter`). */
24646
+ private trickAnimationIndex;
23790
24647
  /** Scratch values, so the per-frame work allocates nothing. */
23791
24648
  private readonly lookRotation;
23792
24649
  private readonly localAxis;
@@ -23872,6 +24729,14 @@ declare namespace TOOLKIT {
23872
24729
  * @param animators The rig Animators; each that declares `Reverse` receives it.
23873
24730
  */
23874
24731
  private writeReverse;
24732
+ /**
24733
+ * `Player.cs:2557-2600`. Fires the next trick pose in Unity's rotation (`JumpTrick1`, `JumpTrick2`, `GliderTrick`,
24734
+ * then round again) on every rig Animator that declares it, and advances the rotation whether or not any did —
24735
+ * an Animator without the triggers plays nothing, as in Unity.
24736
+ * @param animators The rig Animators, as `updateFrame` receives them.
24737
+ * @returns The trigger name fired.
24738
+ */
24739
+ playTrick(animators: TOOLKIT.Animator[]): string;
23875
24740
  /**
23876
24741
  * Turns the steering wheel about its own column: Unity writes `localEulerAngles = (0, 180 ± 25, 0)` onto a
23877
24742
  * wheel whose rest is `(0, 180, 0)`, so the turn is the rest followed by a local yaw.
@@ -27012,7 +27877,10 @@ declare namespace TOOLKIT {
27012
27877
  * moment the race camera takes over, before the countdown starts charging the launch.
27013
27878
  */
27014
27879
  isRevvingOnGrid?(): boolean;
27015
- /** `RACE_MANAGER.RACE_COMPLETED` (`Player.cs:1193`) — silences the glider trick voice. */
27880
+ /**
27881
+ * `RACE_MANAGER.RACE_COMPLETED` (`Player.cs:1193`) — silences the glider trick voice and fades the engine out
27882
+ * (`PlayerSounds.cs:147-151`).
27883
+ */
27016
27884
  isRaceCompleted?(): boolean;
27017
27885
  /**
27018
27886
  * `RACE_STARTED` — the green light. Optional: the player's idle starts fading in at the latest here when the game
@@ -27061,6 +27929,13 @@ declare namespace TOOLKIT {
27061
27929
  driftAudioEnabled: boolean;
27062
27930
  /** The engine and idle loops (`PlayerSounds.kart_sounds`). */
27063
27931
  engineAudioEnabled: boolean;
27932
+ /**
27933
+ * `RACE_MANAGER.RACE_COMPLETED` for this kart's engine: true fades the engine out (`PlayerSounds.cs:147-151`,
27934
+ * `ComputerDriverSounds.cs:122-125`), false brings it back to its road level. Unity's flag is one static set when
27935
+ * the player finishes, so every kart's engine fades together; a kart's own `isRaceCompleted()` fades it without
27936
+ * this, so the game sets it on the other karts when its player finishes, and clears it for a new race.
27937
+ */
27938
+ raceCompleted: boolean;
27064
27939
  /** The payout voice (`Mario_Boost_Sounds`). */
27065
27940
  boostAudioEnabled: boolean;
27066
27941
  /** The hop blip (`effectSounds[6]`). Separate from `driftAudioEnabled` — see `tickHopAudio`. */
@@ -27233,6 +28108,8 @@ declare namespace TOOLKIT {
27233
28108
  protected enginePlayhead: KartEnginePlayhead;
27234
28109
  /** `kartSound.pitch` (`PlayerSounds.cs:122`). */
27235
28110
  protected enginePitch: number;
28111
+ /** `kartSound.volume` while it fades after the race (`PlayerSounds.cs:147-151`), before the master gain; null while racing. */
28112
+ protected raceEndEngineVolume: number | null;
27236
28113
  /** `kartIdle.volume` before the master gain: the player's eases from 0 to 0.8, an opponent's is 1 (D2). */
27237
28114
  protected idleLevel: number;
27238
28115
  /** `PlayerSounds.SceneEntryFinished` — the race intro has handed off, so the player's idle fades in. */
@@ -27797,6 +28674,22 @@ declare namespace TOOLKIT {
27797
28674
  * @returns The volume, `[0..1]`.
27798
28675
  */
27799
28676
  protected engineVolume(gliding: boolean): number;
28677
+ /**
28678
+ * This frame's engine volume before the master gain (`PlayerSounds.cs:138-151`). While racing it is the road level
28679
+ * or the glider duck, written every frame. Once the race is completed Unity stops writing those levels and takes
28680
+ * 0.01 off the volume every frame instead, down to silence, so the engine fades out while the race-end drive still
28681
+ * holds the kart at speed.
28682
+ * @param gliding Whether the kart is gliding.
28683
+ * @param deltaSeconds Frame time, seconds.
28684
+ * @returns The volume, `[0..1]`.
28685
+ */
28686
+ protected stepEngineLevel(gliding: boolean, deltaSeconds: number): number;
28687
+ /**
28688
+ * Whether the engine fades for a completed race: the game says so (`raceCompleted`, Unity's one static flag), or
28689
+ * the kart's own race is completed.
28690
+ * @returns True once the race is completed for this kart's engine.
28691
+ */
28692
+ protected isEngineRaceCompleted(): boolean;
27800
28693
  /**
27801
28694
  * D2: gives the engine and idle sources the rig's spatial values, whatever container they came from — so a person
27802
28695
  * driving Luigi (an AI-rig container) still hears a 2D engine, and a remote Mario (a player-rig container) is heard
@@ -28826,7 +29719,10 @@ declare namespace TOOLKIT {
28826
29719
  * volume nudges the kart's heading, it does not snap it.
28827
29720
  */
28828
29721
  const JUMP_PANEL_ROTATE_RATE: number;
28829
- /** `Player.cs:229`. Minimum `REALCURRENTSPEED` a trick needs — the ACTUAL nose-local speed. */
29722
+ /**
29723
+ * Minimum `REALCURRENTSPEED` a trick needs — the ACTUAL nose-local speed. Unity's `Player.cs:229` gate is 40; the
29724
+ * game lowers it to 30 (user, 2026-11-10) so tricks are easier to hit.
29725
+ */
28830
29726
  const TRICK_MIN_SPEED: number;
28831
29727
  /** How long the trick's upward push lasts, seconds. */
28832
29728
  const TRICK_SECONDS: number;
@@ -28845,7 +29741,10 @@ declare namespace TOOLKIT {
28845
29741
  const TRICK_FORCE_FLOOR: number;
28846
29742
  /** `Player.cs:539-541`. Seconds of boost a landed trick FLOORS `Boost_time` at. Never assigns. */
28847
29743
  const TRICK_LANDING_BOOST: number;
28848
- /** `Player.cs:1109-1214`. Above this `REALCURRENTSPEED` a glider deploy plays the trick variant. */
29744
+ /**
29745
+ * Above this `REALCURRENTSPEED` a glider deploy plays the trick variant (`Player.cs:1109-1214`). Unity's gate is 60;
29746
+ * the game lowers it to 50 (user, 2026-11-10) so glider tricks are easier to hit.
29747
+ */
28849
29748
  const GLIDER_TRICK_SPEED: number;
28850
29749
  /** The trick variant's pause before the canopy opens, seconds. */
28851
29750
  const GLIDER_TRICK_OPEN_DELAY: number;
@@ -30184,12 +31083,32 @@ declare namespace TOOLKIT {
30184
31083
  protected inputTrick: boolean;
30185
31084
  /** Seconds into the trick's upward push, or `-1` when no trick is running. */
30186
31085
  protected trickTime: number;
30187
- /** A `TrickCollider` has been touched, so a trick is allowed. Cleared on landing. */
31086
+ /**
31087
+ * Inside a `TrickCollider`, so a trick press is allowed (Unity's `trickAvailable`). Set on entering the volume,
31088
+ * cleared on leaving it and when a trick starts (`Player.cs:1030`, `:1221`, `:232`).
31089
+ */
30188
31090
  protected trickArmed: boolean;
30189
- /** A trick was performed this flight and its landing still owes the 0.9 s boost floor. */
31091
+ /**
31092
+ * A trick has started and its landing still owes the 0.9 s boost floor. Survives the end of the push window (the
31093
+ * landing normally comes later); cleared on landing, or when the window ends without the kart leaving the ground.
31094
+ */
30190
31095
  protected trickPerformed: boolean;
30191
- /** Edge-detect for the trick button: a trick fires on the PRESS, not on the hold. */
31096
+ /** The kart has left the ground since the running trick started; only a ground contact after this lands it. */
31097
+ protected trickLeftGround: boolean;
31098
+ /** A `Ground`/`Dirt`/`AntiGravity` contact arrived since the last step. Read and cleared by `trackTrickGroundContact`. */
31099
+ protected trickGroundContact: boolean;
31100
+ /** Edge-detect for the trick button, read in `drive()`: a trick fires on the PRESS, not on the hold. */
30192
31101
  protected trickPressed: boolean;
31102
+ /**
31103
+ * A trick press `drive()` saw that no physics step has read yet. Set on the press, cleared by the next step.
31104
+ *
31105
+ * WHY A QUEUE: `drive()` runs once per rendered frame, and the physics runs on a fixed 0.02 s step (0..N steps a
31106
+ * frame). A press is true for one frame only, so a frame that runs no step lost it — 17 % of frames at 60 Hz,
31107
+ * 58 % at 120 Hz, 65 % at 144 Hz. That made the trick hit or miss on the same ramp.
31108
+ */
31109
+ protected trickPressQueued: boolean;
31110
+ /** The driver trick trigger the last trick fired (`DRIVER_TRICK_TRIGGERS`), or null before the first one. */
31111
+ protected lastTrickTrigger: string | null;
30193
31112
  /** Set each step by `move()`: does a vertical push survive into the next step? See its note there. */
30194
31113
  protected verticalAccumulates: boolean;
30195
31114
  /**
@@ -30721,12 +31640,20 @@ declare namespace TOOLKIT {
30721
31640
  /** Ends a jump-panel flight. `Player.cs:494`/`529` — contact with `Ground` or `Dirt`. */
30722
31641
  protected endJumpPanel(): void;
30723
31642
  /**
30724
- * `Player.cs:229`. Starts a trick if all three gates pass, otherwise does nothing at all.
30725
- *
30726
- * Returns whether one started, because "the trick did nothing" is a thing the bench and the
30727
- * tests need to be able to assert positively rather than infer from an unchanged trajectory.
31643
+ * `Player.cs:229-232`. Starts a trick on the button press when every gate passes, otherwise does nothing at all.
31644
+ * A started trick disarms its volume (`trickAvailable = false`, `:232`), so a second press in it does nothing.
31645
+ * @returns Whether a trick started — so the bench and the tests can assert "nothing happened" positively.
30728
31646
  */
30729
31647
  protected tryTrick(): boolean;
31648
+ /**
31649
+ * Once per step, before the trick button is read: notes whether a trick in flight has left the ground, and clears
31650
+ * the per-step contact flag.
31651
+ *
31652
+ * "Left the ground" is the first step with no `Ground`/`Dirt`/`AntiGravity` contact (the contact analogue of Unity's
31653
+ * `OnCollisionExit`) or the ground probe reporting airborne, whichever comes first. The probe alone reaches
31654
+ * `activeGroundRayDist` (2 units) down and still reports grounded for a while past the lip.
31655
+ */
31656
+ protected trackTrickGroundContact(): void;
30730
31657
  /**
30731
31658
  * One step of the trick's upward push.
30732
31659
  *
@@ -30735,6 +31662,10 @@ declare namespace TOOLKIT {
30735
31662
  * which is the same curve sampled differently. The floor is what makes the last third of the
30736
31663
  * trick a gentle hold rather than the force going negative and hauling the kart down.
30737
31664
  *
31665
+ * When the window runs out the push stops but the landing is still owed (`trickPerformed`
31666
+ * survives), because the window normally ends mid-air. Only a trick whose kart never left the
31667
+ * ground ends there with nothing owed.
31668
+ *
30738
31669
  * HOW IT IS DELIVERED DEPENDS ON THE FRAME, not on the mode — see the branch in the body and
30739
31670
  * `verticalAccumulates`. This doc used to say "a STEP VELOCITY, not an acceleration, because the
30740
31671
  * clamp never lets the heading ADD vertical speed, so an upward force cannot accumulate in ANY
@@ -30742,10 +31673,15 @@ declare namespace TOOLKIT {
30742
31673
  * clamp, so it lands in the body, and the clamp then preserves the body's `y` on every frame
30743
31674
  * where the nose is pitched above it — which is every frame of a ramp jump. The claim was wrong,
30744
31675
  * and the code that followed from it made a trick 3.87x higher at 144 Hz than at 30 Hz.
31676
+ * @param dt Step length, seconds.
30745
31677
  */
30746
31678
  protected tickTrick(dt: number): void;
30747
31679
  /**
30748
- * `Player.cs:539-541`. Landing after a trick floors the boost at 0.9 s.
31680
+ * `Player.cs:537-545`. A trick's landing: the first `Ground`/`Dirt`/`AntiGravity` contact after the kart left the
31681
+ * ground ends the trick and floors the boost at 0.9 s. `AntiGravity` is a deliberate departure from Unity's
31682
+ * OnCollisionEnter list (mario-kart-trick-fixes F5): a ramp onto an anti-gravity road pays on that landing.
31683
+ * Called from `onSurfaceContact` on every contact step, enter and stay alike; a contact before the kart has left
31684
+ * the ground (the ramp it is still on) neither ends the trick nor pays.
30749
31685
  *
30750
31686
  * **A FLOOR, NEVER AN ASSIGNMENT** (§E.4). Landing a trick in the middle of a 2.5 s drift
30751
31687
  * payout must not cut it to 0.9, which is what an assignment would do and what would make
@@ -30753,6 +31689,13 @@ declare namespace TOOLKIT {
30753
31689
  * when it is called.
30754
31690
  */
30755
31691
  protected landTrick(): void;
31692
+ /**
31693
+ * `Player.cs:2557-2600`. Fires the driver's next trick pose on the rig Animators and remembers which. Only a
31694
+ * player trick calls it — the glider trick's payout does not.
31695
+ */
31696
+ protected playTrickAnimation(): void;
31697
+ /** Ends the running trick with nothing owed: no push, no pending landing, no flight noted. */
31698
+ protected clearTrickState(): void;
30756
31699
  /**
30757
31700
  * `Player.cs:1109-1214`. Leaving a `GliderPanelFly` volume deploys the glider.
30758
31701
  *
@@ -33069,9 +34012,15 @@ declare namespace TOOLKIT {
33069
34012
  isTricking(): boolean;
33070
34013
  /** Seconds into the trick push, or `-1`. */
33071
34014
  getTrickTime(): number;
33072
- /** A `TrickCollider` has been touched, so a trick is allowed until the next landing. */
34015
+ /**
34016
+ * The driver trick trigger the last trick fired — `JumpTrick1`, `JumpTrick2` or `GliderTrick`, in Unity's rotation —
34017
+ * or null before the first trick. Set even when no rig Animator declares it (only some racers have the poses).
34018
+ * @returns The trigger name, or null.
34019
+ */
34020
+ getLastTrickTrigger(): string | null;
34021
+ /** The kart is inside a `TrickCollider` it has not tricked in yet, so a trick press is allowed. */
33073
34022
  isTrickArmed(): boolean;
33074
- /** A trick was performed this flight and its landing still owes the 0.9 s boost floor. */
34023
+ /** A trick has started and its landing still owes the 0.9 s boost floor. */
33075
34024
  isTrickPending(): boolean;
33076
34025
  /** Front-wheel steer angle, degrees. Presentation only — see `updateWheels`. */
33077
34026
  getWheelSteer(): number;
@@ -34735,129 +35684,6 @@ declare namespace PROJECT {
34735
35684
  bindForSubMesh(uniformBuffer: BABYLON.UniformBuffer, scene: BABYLON.Scene, engine: BABYLON.AbstractEngine, subMesh: BABYLON.SubMesh): void;
34736
35685
  }
34737
35686
  }
34738
- declare namespace PROJECT {
34739
- /**
34740
- * Babylon toolkit default camera system class
34741
- * @class DefaultCameraSystem - All rights reserved (c) 2020 Mackey Kinard
34742
- * @deprecated This class is considered legacy and may be removed in future versions.
34743
- */
34744
- class DefaultCameraSystem extends TOOLKIT.ScriptComponent {
34745
- protected static PlayerOneCamera: BABYLON.FreeCamera;
34746
- protected static PlayerTwoCamera: BABYLON.FreeCamera;
34747
- protected static PlayerThreeCamera: BABYLON.FreeCamera;
34748
- protected static PlayerFourCamera: BABYLON.FreeCamera;
34749
- protected static XRExperienceHelper: BABYLON.WebXRDefaultExperience;
34750
- private static multiPlayerView;
34751
- private static multiPlayerCount;
34752
- private static multiPlayerCameras;
34753
- private static stereoCameras;
34754
- private static startupMode;
34755
- private static cameraReady;
34756
- private static cameraInstance;
34757
- static IsCameraSystemReady(): boolean;
34758
- /** Register handler that is triggered when the webxr experience helper has been created */
34759
- static OnXRExperienceHelperObservable: BABYLON.Observable<BABYLON.WebXRDefaultExperience>;
34760
- /** Default Follow Speed */
34761
- static FOLLOW_SPEED: number;
34762
- private mainCamera;
34763
- private cameraType;
34764
- private cameraInertia;
34765
- private cameraController;
34766
- private immersiveOptions;
34767
- private arcRotateConfig;
34768
- private multiPlayerSetup;
34769
- private fullScreenToggle;
34770
- private setPointerLock;
34771
- private setCameraTarget;
34772
- private setSpatialAudio;
34773
- protected m_cameraRig: BABYLON.TargetCamera;
34774
- isMainCamera(): boolean;
34775
- getCameraType(): number;
34776
- getTargetTransform(): BABYLON.TransformNode;
34777
- setTargetTransform(target: BABYLON.TransformNode): void;
34778
- enableSpatialAudio(value: boolean): void;
34779
- constructor(transform: BABYLON.TransformNode, scene: BABYLON.Scene, properties?: any, alias?: string);
34780
- protected awake(): void;
34781
- protected start(): void;
34782
- protected update(): void;
34783
- protected destroy(): void;
34784
- protected awakeCameraSystemState(): void;
34785
- protected startCameraSystemState(): Promise<void>;
34786
- protected updateCameraSystemState(): void;
34787
- protected cleanCameraSystemState(): void;
34788
- protected destroyCameraSystemState(): void;
34789
- /*********************************************/
34790
- /** Follow Target Camera Controller Helpers */
34791
- /*********************************************/
34792
- targetCameraOffset: BABYLON.Vector3;
34793
- getCameraPivotPosition(): BABYLON.Vector3;
34794
- getCameraPivotRotation(): BABYLON.Quaternion;
34795
- getCameraBoomNode(): BABYLON.TransformNode;
34796
- getCameraTransform(): BABYLON.TransformNode;
34797
- private cameraNode;
34798
- private cameraPivot;
34799
- private cameraDistance;
34800
- private cameraPivotOffset;
34801
- private cameraBoomPosition;
34802
- private dollyDirection;
34803
- private rotationEulers;
34804
- private scaledCamDirection;
34805
- private scaledMaxDirection;
34806
- private parentNodePosition;
34807
- private maximumCameraPos;
34808
- private cameraRaycastShape;
34809
- private targetRotationVector;
34810
- private resetCameraRotation;
34811
- private updateCameraController;
34812
- getBoomArmMaxDistance(): number;
34813
- setBoomArmMaxDistance(distance: number): void;
34814
- setSmoothBoomArmLength(length: number, speed: number, updateMaxDistance?: boolean): void;
34815
- private smoothBoomArmLength;
34816
- private smoothBoomArmSpeed;
34817
- private updateSmoothBoomArmLength;
34818
- static EnableTracking(value: boolean): void;
34819
- static IsTrackingEnabled(): boolean;
34820
- static SetAutoUpdate(value: boolean): void;
34821
- static IsAutoUpdateEnabled(): boolean;
34822
- static GetFollowTarget(): BABYLON.TransformNode;
34823
- static SetFollowTarget(target: BABYLON.TransformNode): void;
34824
- static ResetFollowTarget(): void;
34825
- static UpdateFollowTarget(): void;
34826
- /** Get the WebXR default experience helper */
34827
- static GetWebXR(): BABYLON.WebXRDefaultExperience;
34828
- /** Is universal camera system in WebXR mode */
34829
- static IsInWebXR(): boolean;
34830
- /** Setup navigation mesh for WebXR */
34831
- private static SetupNavigationWebXR;
34832
- /** Get main camera rig for the scene */
34833
- static GetMainCamera(scene: BABYLON.Scene, detach?: boolean): BABYLON.FreeCamera;
34834
- /** Get universal camera rig for desired player */
34835
- static GetPlayerCamera(scene: BABYLON.Scene, player?: TOOLKIT.PlayerNumber, detach?: boolean): BABYLON.FreeCamera;
34836
- /** Get camera transform node for desired player */
34837
- static GetCameraTransform(scene: BABYLON.Scene, player?: TOOLKIT.PlayerNumber): BABYLON.TransformNode;
34838
- /** Are stereo side side camera services available. */
34839
- static IsStereoCameras(): boolean;
34840
- /** Are local multi player view services available. */
34841
- static IsMultiPlayerView(): boolean;
34842
- /** Get the current local multi player count */
34843
- static GetMultiPlayerCount(): number;
34844
- /** Activates current local multi player cameras. */
34845
- static ActivateMultiPlayerCameras(scene: BABYLON.Scene): boolean;
34846
- /** Disposes current local multiplayer cameras */
34847
- static DisposeMultiPlayerCameras(): void;
34848
- /** Sets the multi player camera view layout */
34849
- static SetMultiPlayerViewLayout(scene: BABYLON.Scene, totalNumPlayers: number): boolean;
34850
- }
34851
- /*********************************************/
34852
- /** Camera Editor Properties Support Classes */
34853
- /*********************************************/
34854
- interface IEditorArcRtotate {
34855
- alpha: number;
34856
- beta: number;
34857
- radius: number;
34858
- target: TOOLKIT.IUnityVector3;
34859
- }
34860
- }
34861
35687
  declare namespace PROJECT {
34862
35688
  /**
34863
35689
  * Babylon Script Component
@@ -35061,811 +35887,6 @@ declare namespace PROJECT {
35061
35887
  protected destroy(): void;
35062
35888
  }
35063
35889
  }
35064
- declare namespace PROJECT {
35065
- /**
35066
- * Babylon Script Component (LEGACY)
35067
- * @class RemotePlayerController
35068
- * @deprecated This class is considered legacy and may be removed in future versions.
35069
- */
35070
- class RemotePlayerController extends TOOLKIT.ScriptComponent {
35071
- updateStateParams: boolean;
35072
- smoothMotionTime: number;
35073
- smoothInputVectors: boolean;
35074
- private animator;
35075
- private animationStateParams;
35076
- constructor(transform: BABYLON.TransformNode, scene: BABYLON.Scene, properties?: any, alias?: string);
35077
- protected awake(): void;
35078
- protected update(): void;
35079
- protected destroy(): void;
35080
- /** Finds the remote player's `TOOLKIT.Animator`, on this node or on the first child that carries one. */
35081
- private attachAnimationController;
35082
- private validateAnimationStateParams;
35083
- }
35084
- }
35085
- declare namespace PROJECT {
35086
- /**
35087
- * Babylon toolkit standard player controller class (LEGACY)
35088
- * @class StandardPlayerController - All rights reserved (c) 2020 Mackey Kinard
35089
- * @deprecated This class is considered legacy and may be removed in future versions.
35090
- */
35091
- class StandardPlayerController extends TOOLKIT.ScriptComponent {
35092
- static MIN_VERTICAL_VELOCITY: number;
35093
- static MIN_GROUND_DISTANCE: number;
35094
- static MIN_MOVE_EPSILON: number;
35095
- static MIN_TIMER_OFFSET: number;
35096
- static MIN_SLOPE_LIMIT: number;
35097
- static PLAYER_HEIGHT: string;
35098
- enableInput: boolean;
35099
- attachCamera: boolean;
35100
- rotateCamera: boolean;
35101
- mouseWheel: boolean;
35102
- toggleView: boolean;
35103
- freeLooking: boolean;
35104
- requireSprintButton: boolean;
35105
- gravitationalForce: number;
35106
- minFallVelocity: number;
35107
- verticalStepSpeed: number;
35108
- minStepUpHeight: number;
35109
- rigidBodyMass: number;
35110
- airbornTimeout: number;
35111
- maxAngle: number;
35112
- speedFactor: number;
35113
- rootMotion: boolean;
35114
- moveSpeed: number;
35115
- walkSpeed: number;
35116
- lookSpeed: number;
35117
- jumpSpeed: number;
35118
- jumpDelay: number;
35119
- eyesHeight: number;
35120
- pivotHeight: number;
35121
- maxDistance: number;
35122
- scrollSpeed: number;
35123
- topLookLimit: number;
35124
- downLookLimit: number;
35125
- lowTurnSpeed: number;
35126
- highTurnSpeed: number;
35127
- smoothDampTime: number;
35128
- smoothInputVectors: boolean;
35129
- smoothAcceleration: boolean;
35130
- accelerationSpeed: number;
35131
- decelerationSpeed: number;
35132
- avatarSkinTag: string;
35133
- climbVolumeTag: string;
35134
- vaultVolumeTag: string;
35135
- maxHeightRanges: any;
35136
- useClimbSystem: boolean;
35137
- distanceFactor: number;
35138
- cameraSmoothing: number;
35139
- cameraCollisions: boolean;
35140
- inputMagnitude: number;
35141
- /** Unity StarterAssetsInputs.analogMovement: true drives the MotionSpeed parameter with the input magnitude (gamepad sticks), false keeps it at 1 (keyboard). */
35142
- analogMovement: boolean;
35143
- landingEpsilon: number;
35144
- minimumDistance: number;
35145
- movementAllowed: boolean;
35146
- playerInputX: number;
35147
- playerInputZ: number;
35148
- playerMouseX: number;
35149
- playerMouseY: number;
35150
- runKeyRequired: boolean;
35151
- buttonRun: number;
35152
- keyboardRun: number;
35153
- buttonJump: number;
35154
- keyboardJump: number;
35155
- buttonCamera: number;
35156
- keyboardCamera: number;
35157
- postNetworkAttributes: boolean;
35158
- playerNumber: TOOLKIT.PlayerNumber;
35159
- boomPosition: BABYLON.Vector3;
35160
- airbornVelocity: BABYLON.Vector3;
35161
- movementVelocity: BABYLON.Vector3;
35162
- targetCameraOffset: BABYLON.Vector3;
35163
- isAnimationEnabled(): boolean;
35164
- isRunButtonPressed(): boolean;
35165
- isJumpButtonPressed(): boolean;
35166
- getPlayerJumped(): boolean;
35167
- getPlayerJumping(): boolean;
35168
- getPlayerFalling(): boolean;
35169
- getPlayerSliding(): boolean;
35170
- getPlayerGrounded(): boolean;
35171
- getFallTriggered(): boolean;
35172
- getMovementSpeed(): number;
35173
- getCameraBoomNode(): BABYLON.TransformNode;
35174
- getCameraTransform(): BABYLON.TransformNode;
35175
- getAnimator(): TOOLKIT.Animator;
35176
- getVerticalVelocity(): number;
35177
- getCharacterController(): TOOLKIT.CharacterController;
35178
- getPlayerLookRotation(): BABYLON.Vector3;
35179
- getPlayerMoveDirection(): PROJECT.PlayerMoveDirection;
35180
- getInputMovementVector(): BABYLON.Vector3;
35181
- getInputMagnitudeValue(): number;
35182
- getCameraPivotPosition(): BABYLON.Vector3;
35183
- getCameraPivotRotation(): BABYLON.Quaternion;
35184
- rayClimbOffset: number;
35185
- rayClimbLength: number;
35186
- getClimbContact(): boolean;
35187
- getClimbContactNode(): BABYLON.TransformNode;
35188
- getClimbContactPoint(): BABYLON.Vector3;
35189
- getClimbContactAngle(): number;
35190
- getClimbContactNormal(): BABYLON.Vector3;
35191
- getClimbContactDistance(): number;
35192
- canClimbObstaclePredicate: (action: number) => boolean;
35193
- rayHeightOffset: number;
35194
- rayHeightLength: number;
35195
- getHeightContact(): boolean;
35196
- getHeightContactNode(): BABYLON.TransformNode;
35197
- getHeightContactPoint(): BABYLON.Vector3;
35198
- getHeightContactAngle(): number;
35199
- getHeightContactNormal(): BABYLON.Vector3;
35200
- getHeightContactDistance(): number;
35201
- private abstractMesh;
35202
- private cameraDistance;
35203
- private forwardCamera;
35204
- private avatarRadius;
35205
- private groundingObject;
35206
- private groundingCallback;
35207
- private dollyDirection;
35208
- private cameraEulers;
35209
- private rotationEulers;
35210
- private cameraPivotOffset;
35211
- private cameraForwardVector;
35212
- private cameraRightVector;
35213
- private desiredForwardVector;
35214
- private desiredRightVector;
35215
- private lastRotationQuaternion;
35216
- private scaledCamDirection;
35217
- private scaledMaxDirection;
35218
- private parentNodePosition;
35219
- private maximumCameraPos;
35220
- private tempWorldPosition;
35221
- private cameraRaycastShape;
35222
- private defaultRaycastGroup;
35223
- private defaultRaycastMask;
35224
- private cameraRaycastMask;
35225
- private avatarSkins;
35226
- private cameraNode;
35227
- private cameraPivot;
35228
- private navigationAgent;
35229
- private characterController;
35230
- private verticalVelocity;
35231
- private smoothMotionSpeed;
35232
- private movementSpeed;
35233
- private isRunPressed;
35234
- private isJumpPressed;
35235
- private isCharacterSliding;
35236
- private isCharacterFalling;
35237
- private isCharacterGrounded;
35238
- private isCharacterFallTriggered;
35239
- private isCharacterJumpFrame;
35240
- private isCharacterJumping;
35241
- private isCharacterLanding;
35242
- private isCharacterRising;
35243
- private isCharacterNavigating;
35244
- private navigationAngularSpeed;
35245
- private updateStateParams;
35246
- private animationStateParams;
35247
- private sphereCollisionShape;
35248
- private hasGroundedContact;
35249
- private showDebugColliders;
35250
- private colliderVisibility;
35251
- private colliderRenderGroup;
35252
- private groundCheckDistance;
35253
- private deltaTime;
35254
- private minJumpTimer;
35255
- private delayJumpTimer;
35256
- private playerControl;
35257
- private canPlayerJump;
35258
- private animator;
35259
- private lastJumpVelocity;
35260
- private inputMovementVector;
35261
- private playerLookRotation;
35262
- private playerRotationVector;
35263
- private playerMovementVelocity;
35264
- private playerRotationQuaternion;
35265
- private playerMoveDirection;
35266
- private forwardDirection;
35267
- private downDirection;
35268
- private climbContact;
35269
- private climbContactNode;
35270
- private climbContactAngle;
35271
- private climbContactPoint;
35272
- private climbContactNormal;
35273
- private climbContactDistance;
35274
- private climbSensorLine;
35275
- private offsetClimbRaycastPosition;
35276
- private startClimbRaycastPosition;
35277
- private endClimbRaycastPosition;
35278
- private heightContact;
35279
- private heightContactNode;
35280
- private heightContactAngle;
35281
- private heightContactPoint;
35282
- private heightContactNormal;
35283
- private heightContactDistance;
35284
- private heightSensorLine;
35285
- private offsetHeightRaycastPosition;
35286
- private startHeightRaycastPosition;
35287
- private endHeightRaycastPosition;
35288
- protected m_velocityOffset: BABYLON.Vector3;
35289
- protected m_actualVelocity: BABYLON.Vector3;
35290
- protected m_linearVelocity: BABYLON.Vector3;
35291
- protected m_lastPosition: BABYLON.Vector3;
35292
- protected m_positionCenter: BABYLON.Vector3;
35293
- protected m_scaledVelocity: number;
35294
- protected playerDrawVelocity: number;
35295
- constructor(transform: BABYLON.TransformNode, scene: BABYLON.Scene, properties?: any, alias?: string);
35296
- protected awake(): void;
35297
- protected start(): void;
35298
- protected after(): void;
35299
- protected update(): void;
35300
- protected destroy(): void;
35301
- /** Register handler that is triggered before the controller has been updated */
35302
- onPreUpdateObservable: BABYLON.Observable<BABYLON.TransformNode>;
35303
- /** Register handler that is triggered before the controller movement has been applied */
35304
- onBeforeMoveObservable: BABYLON.Observable<BABYLON.TransformNode>;
35305
- /** Register handler that is triggered after the controller has been updated */
35306
- onPostUpdateObservable: BABYLON.Observable<BABYLON.TransformNode>;
35307
- /** Register handler that is triggered after player input has been updated */
35308
- onPlayerInputObservable: BABYLON.Observable<BABYLON.TransformNode>;
35309
- /** Register handler that is triggered when player position should be updated */
35310
- onPlayerPositionObservable: BABYLON.Observable<BABYLON.TransformNode>;
35311
- /** Register handler that is triggered after performing action has been updated */
35312
- onUpdateActionObservable: BABYLON.Observable<BABYLON.TransformNode>;
35313
- /** Observer on the Animator's `onAnimatorMoveObservable` while this controller takes root motion (D19, D20); null otherwise. */
35314
- private animatorMoveObserver;
35315
- /** The Animator's exported `applyRootMotion`, restored when this controller stops taking root motion. */
35316
- private exportedApplyRootMotion;
35317
- /** The last Animator tick's horizontal root-motion velocity (world, metres per second), moved by the character controller when `rootMotion` is on. */
35318
- private readonly rootMotionVelocity;
35319
- /**
35320
- * Registers the `onAnimatorMoveObservable` taker while root motion drives the player (`rootMotion` locomotion or a
35321
- * root-motion action) and removes it otherwise. The Animator may sit on a child model node, so the taker moves this
35322
- * player node rather than letting the built-in path move the model (D19, D20, D29).
35323
- */
35324
- private syncAnimatorMoveTaker;
35325
- /**
35326
- * The `onAnimatorMove` taker: a root-motion action moves and turns the player node; otherwise the horizontal root
35327
- * velocity is kept for the character controller's next move.
35328
- * @param animator The Animator that ticked.
35329
- */
35330
- private onAnimatorMove;
35331
- private isPerformingAction;
35332
- private isRootMotionAction;
35333
- private isActionInterruptable;
35334
- private afterActionHandler;
35335
- private performActionTimer;
35336
- private performActionNumber;
35337
- private playerRotationSpeed;
35338
- private rotatePlayerTowards;
35339
- private matchStartTime;
35340
- private matchTargetTime;
35341
- private matchTargetOffset;
35342
- private matchTargetHeight;
35343
- private lockTargetHeight;
35344
- private lastStartHeight;
35345
- private lastTargetHeight;
35346
- private lastTargetNormal;
35347
- private lastTargetRotation;
35348
- private lastDeltaPosition;
35349
- private lastDeltaRotation;
35350
- /** The eased player height of the height match (world metres). */
35351
- private smoothedPlayerHeight;
35352
- /** The SmoothDamp velocity of the height match (`x` holds it). */
35353
- private readonly playerHeightVelocity;
35354
- /** Full path hash of the base-layer state the running action entered; valid while `actionStateEntered`. */
35355
- private actionStateHash;
35356
- /** True once the running action's state was entered, so its exit ends the action. */
35357
- private actionStateEntered;
35358
- getIsPerformingAction(): boolean;
35359
- getIsRootMotionAction(): boolean;
35360
- getIsActionInterruptable(): boolean;
35361
- playActionAnimation(action: number, interruptableAction?: boolean, enableRootMotion?: boolean, afterActionComplete?: () => void): void;
35362
- resetActionAnimationState(): void;
35363
- /** Advances the action timer that drives the height match (the root motion itself is applied by the move taker). */
35364
- private updateAnimationActionState;
35365
- /**
35366
- * Applies a root-motion action's world root delta to the player node: the height match replaces the vertical delta
35367
- * between the match start and target times, and the player either turns toward the climb surface or by the root
35368
- * rotation delta. Called from the `onAnimatorMove` taker.
35369
- * @param animator The Animator that ticked.
35370
- */
35371
- private applyActionRootMotion;
35372
- /**
35373
- * The height match: from `matchStartTime` the vertical delta eases the player toward the target height
35374
- * (`lastTargetHeight + matchTargetOffset`, Unity SmoothDamp over the match window); once `matchTargetTime` passes it
35375
- * snaps to the target height once.
35376
- * @param deltaTime The frame delta in seconds.
35377
- */
35378
- private applyHeightMatch;
35379
- /**
35380
- * Turns the player toward the climb surface (facing into its normal) at `playerRotationSpeed`, while touching it.
35381
- * @param deltaTime The frame delta in seconds.
35382
- */
35383
- private rotateTowardsClimbSurface;
35384
- /** Set the player world position */
35385
- setWorldPosition(x: number, y: number, z: number): void;
35386
- /** TODO */
35387
- setPlayerControl(mode: PROJECT.PlayerInputControl): void;
35388
- /** TODO */
35389
- togglePlayerControl(): void;
35390
- private showAvatarSkins;
35391
- /** TODO */
35392
- attachPlayerCamera(player: TOOLKIT.PlayerNumber): void;
35393
- private ikLeftFootTarget;
35394
- private ikLeftPoleTarget;
35395
- private ikRightFootTarget;
35396
- private ikRightPoleTarget;
35397
- private abstractSkinMesh;
35398
- private rootBoneTransform;
35399
- private leftFootTransform;
35400
- private leftFootPoleOffset;
35401
- private leftFootMaxAngle;
35402
- private rightFootTransform;
35403
- private rightFootPoleOffset;
35404
- private rightFootMaxAngle;
35405
- private ikLeftController;
35406
- private ikRightController;
35407
- onAnimatorIK: () => void;
35408
- getPlayerMesh(): BABYLON.AbstractMesh;
35409
- getRootHipBone(): BABYLON.Bone;
35410
- getLeftFootBone(): BABYLON.Bone;
35411
- getRightFootBone(): BABYLON.Bone;
35412
- getLeftFootTarget(): BABYLON.Mesh;
35413
- getRightFootTarget(): BABYLON.Mesh;
35414
- getLeftFootPoleTarget(): BABYLON.Mesh;
35415
- getRightFootPoleTarget(): BABYLON.Mesh;
35416
- getRootBoneTransform(): BABYLON.TransformNode;
35417
- getLeftFootTransform(): BABYLON.TransformNode;
35418
- getRightFootTransform(): BABYLON.TransformNode;
35419
- getLeftFootController(): BABYLON.BoneIKController;
35420
- getRightFootController(): BABYLON.BoneIKController;
35421
- isGroundedFootIKActive(): boolean;
35422
- setupBoneControllers(): void;
35423
- /**
35424
- * Finds the player's `TOOLKIT.Animator` (on this node or a child model), ends a running action when its action state
35425
- * exits, runs `onAnimatorIK` or the foot IK controllers in the Animator's IK pass, and takes root motion when
35426
- * `rootMotion` is on.
35427
- */
35428
- private attachAnimationController;
35429
- /**
35430
- * Records the base-layer state a running action enters, so that state's exit can end the action.
35431
- * @param change The entered state.
35432
- */
35433
- private onAnimatorStateEnter;
35434
- /**
35435
- * Ends a running action when its action state exits.
35436
- * @param change The exited state.
35437
- */
35438
- private onAnimatorStateExit;
35439
- /** The Animator's IK pass: the script's `onAnimatorIK` when set, else the foot IK controllers. */
35440
- private onAnimatorIKPass;
35441
- private updateAnimatorTargetMeshes;
35442
- /** TODO */
35443
- enableCharacterController(state: boolean): void;
35444
- /** TODO */
35445
- resetPlayerRotation(): void;
35446
- /** TODO */
35447
- resetPlayerJumpingState(): void;
35448
- private awakePlayerController;
35449
- private startPlayerController;
35450
- private updatePlayerPosition;
35451
- private updatePlayerController;
35452
- private afterPlayerController;
35453
- private updateCharacterController;
35454
- private updateCameraController;
35455
- getBoomArmMaxDistance(): number;
35456
- setBoomArmMaxDistance(distance: number): void;
35457
- setSmoothBoomArmLength(length: number, speed: number, updateMaxDistance?: boolean): void;
35458
- private smoothBoomArmLength;
35459
- private smoothBoomArmSpeed;
35460
- private updateSmoothBoomArmLength;
35461
- private castPhysicsClimbingVolumeRay;
35462
- private castPhysicsHeightCheckVolumeRay;
35463
- private getCheckedVerticalVelocity;
35464
- private destroyPlayerController;
35465
- private validateAnimationStateParams;
35466
- /** Fills a missing params object with the defaults, and merges keys added since a params object was exported (motionSpeed). */
35467
- static ApplyAnimationStateParamDefaults(params: PROJECT.AnimationStateParams): PROJECT.AnimationStateParams;
35468
- }
35469
- /**
35470
- * Babylon Interface Definition
35471
- * @interface AnimationStateParams
35472
- */
35473
- interface AnimationStateParams {
35474
- moveDirection: string;
35475
- inputMagnitude: string;
35476
- horizontalInput: string;
35477
- verticalInput: string;
35478
- mouseXInput: string;
35479
- mouseYInput: string;
35480
- heightInput: string;
35481
- speedInput: string;
35482
- /** Speed multiplier parameter of the Starter Assets controller (Unity sets MotionSpeed every frame). */
35483
- motionSpeed?: string;
35484
- jumpFrame: string;
35485
- jumpState: string;
35486
- actionState: string;
35487
- fallingState: string;
35488
- slidingState: string;
35489
- groundedState: string;
35490
- }
35491
- /**
35492
- * Babylon Enum Definition
35493
- * @interface PlayerInputControl
35494
- */
35495
- enum PlayerInputControl {
35496
- FirstPersonStrafing = 0,
35497
- ThirdPersonStrafing = 1
35498
- }
35499
- /**
35500
- * Babylon Enum Definition
35501
- * @interface PlayerMoveDirection
35502
- */
35503
- enum PlayerMoveDirection {
35504
- Stationary = 0,
35505
- Forward = 1,
35506
- ForwardLeft = 2,
35507
- ForwardRight = 3,
35508
- Backward = 4,
35509
- BackwardLeft = 5,
35510
- BackwardRight = 6,
35511
- StrafingLeft = 7,
35512
- StrafingRight = 8
35513
- }
35514
- /**
35515
- * Babylon Enum Definition
35516
- * @interface ActionAnimationType
35517
- */
35518
- enum ActionAnimationType {
35519
- Neutral = 0,
35520
- StepUp = 1,
35521
- JumpUp = 2,
35522
- ClimbUp = 3,
35523
- VaultOver = 4
35524
- }
35525
- }
35526
- declare namespace PROJECT {
35527
- /**
35528
- * Babylon toolkit third person player controller class (LEGACY)
35529
- * @class ThirdPersonPlayerController - All rights reserved (c) 2020 Mackey Kinard
35530
- * @deprecated This class is considered legacy and may be removed in future versions.
35531
- */
35532
- class ThirdPersonPlayerController extends TOOLKIT.ScriptComponent {
35533
- static MIN_VERTICAL_VELOCITY: number;
35534
- static MIN_GROUND_DISTANCE: number;
35535
- static MIN_MOVE_EPSILON: number;
35536
- static MIN_TIMER_OFFSET: number;
35537
- static MIN_SLOPE_LIMIT: number;
35538
- static PLAYER_HEIGHT: string;
35539
- enableInput: boolean;
35540
- attachCamera: boolean;
35541
- mouseWheel: boolean;
35542
- requireSprintButton: boolean;
35543
- gravitationalForce: number;
35544
- minFallVelocity: number;
35545
- verticalStepSpeed: number;
35546
- minStepUpHeight: number;
35547
- rigidBodyMass: number;
35548
- airbornTimeout: number;
35549
- maxAngle: number;
35550
- speedFactor: number;
35551
- rootMotion: boolean;
35552
- moveSpeed: number;
35553
- walkSpeed: number;
35554
- jumpSpeed: number;
35555
- jumpDelay: number;
35556
- lowTurnSpeed: number;
35557
- highTurnSpeed: number;
35558
- smoothDampTime: number;
35559
- smoothInputVectors: boolean;
35560
- smoothAcceleration: boolean;
35561
- accelerationSpeed: number;
35562
- decelerationSpeed: number;
35563
- climbVolumeTag: string;
35564
- vaultVolumeTag: string;
35565
- maxHeightRanges: any;
35566
- useClimbSystem: boolean;
35567
- distanceFactor: number;
35568
- inputMagnitude: number;
35569
- /** Unity StarterAssetsInputs.analogMovement: true drives the MotionSpeed parameter with the input magnitude (gamepad sticks), false keeps it at 1 (keyboard). */
35570
- analogMovement: boolean;
35571
- landingEpsilon: number;
35572
- minimumDistance: number;
35573
- movementAllowed: boolean;
35574
- playerInputX: number;
35575
- playerInputZ: number;
35576
- playerMouseX: number;
35577
- playerMouseY: number;
35578
- runKeyRequired: boolean;
35579
- buttonRun: number;
35580
- keyboardRun: number;
35581
- buttonJump: number;
35582
- keyboardJump: number;
35583
- buttonCamera: number;
35584
- keyboardCamera: number;
35585
- postNetworkAttributes: boolean;
35586
- playerNumber: TOOLKIT.PlayerNumber;
35587
- airbornVelocity: BABYLON.Vector3;
35588
- movementVelocity: BABYLON.Vector3;
35589
- isAnimationEnabled(): boolean;
35590
- isRunButtonPressed(): boolean;
35591
- isJumpButtonPressed(): boolean;
35592
- getPlayerJumped(): boolean;
35593
- getPlayerJumping(): boolean;
35594
- getPlayerFalling(): boolean;
35595
- getPlayerSliding(): boolean;
35596
- getPlayerGrounded(): boolean;
35597
- getFallTriggered(): boolean;
35598
- getMovementSpeed(): number;
35599
- getAnimator(): TOOLKIT.Animator;
35600
- getVerticalVelocity(): number;
35601
- getCharacterController(): TOOLKIT.CharacterController;
35602
- getPlayerLookRotation(): BABYLON.Vector3;
35603
- getPlayerMoveDirection(): PROJECT.PlayerMoveDirection;
35604
- getInputMovementVector(): BABYLON.Vector3;
35605
- getInputMagnitudeValue(): number;
35606
- rayClimbOffset: number;
35607
- rayClimbLength: number;
35608
- getClimbContact(): boolean;
35609
- getClimbContactNode(): BABYLON.TransformNode;
35610
- getClimbContactPoint(): BABYLON.Vector3;
35611
- getClimbContactAngle(): number;
35612
- getClimbContactNormal(): BABYLON.Vector3;
35613
- getClimbContactDistance(): number;
35614
- canClimbObstaclePredicate: (action: number) => boolean;
35615
- rayHeightOffset: number;
35616
- rayHeightLength: number;
35617
- getHeightContact(): boolean;
35618
- getHeightContactNode(): BABYLON.TransformNode;
35619
- getHeightContactPoint(): BABYLON.Vector3;
35620
- getHeightContactAngle(): number;
35621
- getHeightContactNormal(): BABYLON.Vector3;
35622
- getHeightContactDistance(): number;
35623
- private freeCamera;
35624
- private cameraForwardVector;
35625
- private cameraRightVector;
35626
- private desiredForwardVector;
35627
- private desiredRightVector;
35628
- private lastRotationQuaternion;
35629
- private avatarSkins;
35630
- private avatarRadius;
35631
- private navigationAgent;
35632
- private characterController;
35633
- private verticalVelocity;
35634
- private smoothMotionSpeed;
35635
- private movementSpeed;
35636
- private isRunPressed;
35637
- private isJumpPressed;
35638
- private isCharacterSliding;
35639
- private isCharacterFalling;
35640
- private isCharacterGrounded;
35641
- private isCharacterFallTriggered;
35642
- private isCharacterJumpFrame;
35643
- private isCharacterJumping;
35644
- private isCharacterRising;
35645
- private isCharacterLanding;
35646
- private isCharacterNavigating;
35647
- private navigationAngularSpeed;
35648
- private updateStateParams;
35649
- private animationStateParams;
35650
- private sphereCollisionShape;
35651
- private hasGroundedContact;
35652
- private showDebugColliders;
35653
- private colliderVisibility;
35654
- private colliderRenderGroup;
35655
- private groundCheckDistance;
35656
- private deltaTime;
35657
- private delayJumpTimer;
35658
- private canPlayerJump;
35659
- private animator;
35660
- private lastJumpVelocity;
35661
- private inputMovementVector;
35662
- private playerLookRotation;
35663
- private playerMovementVelocity;
35664
- private playerRotationQuaternion;
35665
- private playerMoveDirection;
35666
- private forwardDirection;
35667
- private downDirection;
35668
- private climbContact;
35669
- private climbContactNode;
35670
- private climbContactAngle;
35671
- private climbContactPoint;
35672
- private climbContactNormal;
35673
- private climbContactDistance;
35674
- private climbSensorLine;
35675
- private offsetClimbRaycastPosition;
35676
- private startClimbRaycastPosition;
35677
- private endClimbRaycastPosition;
35678
- private heightContact;
35679
- private heightContactNode;
35680
- private heightContactAngle;
35681
- private heightContactPoint;
35682
- private heightContactNormal;
35683
- private heightContactDistance;
35684
- private heightSensorLine;
35685
- private offsetHeightRaycastPosition;
35686
- private startHeightRaycastPosition;
35687
- private endHeightRaycastPosition;
35688
- protected m_velocityOffset: BABYLON.Vector3;
35689
- protected m_actualVelocity: BABYLON.Vector3;
35690
- protected m_linearVelocity: BABYLON.Vector3;
35691
- protected m_lastPosition: BABYLON.Vector3;
35692
- protected m_positionCenter: BABYLON.Vector3;
35693
- protected m_scaledVelocity: number;
35694
- protected playerDrawVelocity: number;
35695
- constructor(transform: BABYLON.TransformNode, scene: BABYLON.Scene, properties?: any, alias?: string);
35696
- protected awake(): void;
35697
- protected start(): void;
35698
- protected after(): void;
35699
- protected update(): void;
35700
- protected destroy(): void;
35701
- /** Character controller position
35702
- * @deprecated Moved to default camera controller
35703
- * @see PROJECT.DefaultCameraSystem
35704
- */
35705
- boomPosition: BABYLON.Vector3;
35706
- /** Register handler that is triggered before the controller has been updated */
35707
- onPreUpdateObservable: BABYLON.Observable<BABYLON.TransformNode>;
35708
- /** Register handler that is triggered before the controller movement has been applied */
35709
- onBeforeMoveObservable: BABYLON.Observable<BABYLON.TransformNode>;
35710
- /** Register handler that is triggered after the controller has been updated */
35711
- onPostUpdateObservable: BABYLON.Observable<BABYLON.TransformNode>;
35712
- /** Register handler that is triggered after player input has been updated */
35713
- onPlayerInputObservable: BABYLON.Observable<BABYLON.TransformNode>;
35714
- /** Register handler that is triggered when player position should be updated */
35715
- onPlayerPositionObservable: BABYLON.Observable<BABYLON.TransformNode>;
35716
- /** Register handler that is triggered after performing action has been updated */
35717
- onUpdateActionObservable: BABYLON.Observable<BABYLON.TransformNode>;
35718
- /** Register handler that is triggered after animation state has been updated */
35719
- onAnimationStateObservable: BABYLON.Observable<BABYLON.TransformNode>;
35720
- /** Observer on the Animator's `onAnimatorMoveObservable` while this controller takes root motion (D19, D20); null otherwise. */
35721
- private animatorMoveObserver;
35722
- /** The Animator's exported `applyRootMotion`, restored when this controller stops taking root motion. */
35723
- private exportedApplyRootMotion;
35724
- /** The last Animator tick's horizontal root-motion velocity (world, metres per second), moved by the character controller when `rootMotion` is on. */
35725
- private readonly rootMotionVelocity;
35726
- /**
35727
- * Registers the `onAnimatorMoveObservable` taker while root motion drives the player (`rootMotion` locomotion or a
35728
- * root-motion action) and removes it otherwise. The Animator may sit on a child model node, so the taker moves this
35729
- * player node rather than letting the built-in path move the model (D19, D20, D29).
35730
- */
35731
- private syncAnimatorMoveTaker;
35732
- /**
35733
- * The `onAnimatorMove` taker: a root-motion action moves and turns the player node; otherwise the horizontal root
35734
- * velocity is kept for the character controller's next move.
35735
- * @param animator The Animator that ticked.
35736
- */
35737
- private onAnimatorMove;
35738
- private isPerformingAction;
35739
- private isRootMotionAction;
35740
- private isActionInterruptable;
35741
- private afterActionHandler;
35742
- private performActionTimer;
35743
- private performActionNumber;
35744
- private playerRotationSpeed;
35745
- private rotatePlayerTowards;
35746
- private matchStartTime;
35747
- private matchTargetTime;
35748
- private matchTargetOffset;
35749
- private matchTargetHeight;
35750
- private lockTargetHeight;
35751
- private lastStartHeight;
35752
- private lastTargetHeight;
35753
- private lastTargetNormal;
35754
- private lastTargetRotation;
35755
- private lastDeltaPosition;
35756
- private lastDeltaRotation;
35757
- /** The eased player height of the height match (world metres). */
35758
- private smoothedPlayerHeight;
35759
- /** The SmoothDamp velocity of the height match (`x` holds it). */
35760
- private readonly playerHeightVelocity;
35761
- /** Full path hash of the base-layer state the running action entered; valid while `actionStateEntered`. */
35762
- private actionStateHash;
35763
- /** True once the running action's state was entered, so its exit ends the action. */
35764
- private actionStateEntered;
35765
- getIsPerformingAction(): boolean;
35766
- getIsRootMotionAction(): boolean;
35767
- getIsActionInterruptable(): boolean;
35768
- playActionAnimation(action: number, interruptableAction?: boolean, enableRootMotion?: boolean, afterActionComplete?: () => void): void;
35769
- resetActionAnimationState(): void;
35770
- /** Advances the action timer that drives the height match (the root motion itself is applied by the move taker). */
35771
- private updateAnimationActionState;
35772
- /**
35773
- * Applies a root-motion action's world root delta to the player node: the height match replaces the vertical delta
35774
- * between the match start and target times, and the player either turns toward the climb surface or by the root
35775
- * rotation delta. Called from the `onAnimatorMove` taker.
35776
- * @param animator The Animator that ticked.
35777
- */
35778
- private applyActionRootMotion;
35779
- /**
35780
- * The height match: from `matchStartTime` the vertical delta eases the player toward the target height
35781
- * (`lastTargetHeight + matchTargetOffset`, Unity SmoothDamp over the match window); once `matchTargetTime` passes it
35782
- * snaps to the target height once.
35783
- * @param deltaTime The frame delta in seconds.
35784
- */
35785
- private applyHeightMatch;
35786
- /**
35787
- * Turns the player toward the climb surface (facing into its normal) at `playerRotationSpeed`, while touching it.
35788
- * @param deltaTime The frame delta in seconds.
35789
- */
35790
- private rotateTowardsClimbSurface;
35791
- /** Set the player world position */
35792
- setWorldPosition(x: number, y: number, z: number): void;
35793
- private ikLeftFootTarget;
35794
- private ikLeftPoleTarget;
35795
- private ikRightFootTarget;
35796
- private ikRightPoleTarget;
35797
- private abstractSkinMesh;
35798
- private rootBoneTransform;
35799
- private leftFootTransform;
35800
- private leftFootPoleOffset;
35801
- private leftFootMaxAngle;
35802
- private rightFootTransform;
35803
- private rightFootPoleOffset;
35804
- private rightFootMaxAngle;
35805
- private ikLeftController;
35806
- private ikRightController;
35807
- onAnimatorIK: () => void;
35808
- getPlayerMesh(): BABYLON.AbstractMesh;
35809
- getRootHipBone(): BABYLON.Bone;
35810
- getLeftFootBone(): BABYLON.Bone;
35811
- getRightFootBone(): BABYLON.Bone;
35812
- getLeftFootTarget(): BABYLON.Mesh;
35813
- getRightFootTarget(): BABYLON.Mesh;
35814
- getLeftFootPoleTarget(): BABYLON.Mesh;
35815
- getRightFootPoleTarget(): BABYLON.Mesh;
35816
- getRootBoneTransform(): BABYLON.TransformNode;
35817
- getLeftFootTransform(): BABYLON.TransformNode;
35818
- getRightFootTransform(): BABYLON.TransformNode;
35819
- getLeftFootController(): BABYLON.BoneIKController;
35820
- getRightFootController(): BABYLON.BoneIKController;
35821
- isGroundedFootIKActive(): boolean;
35822
- setupBoneControllers(): void;
35823
- /**
35824
- * Finds the player's `TOOLKIT.Animator` (on this node or a child model), ends a running action when its action state
35825
- * exits, runs `onAnimatorIK` or the foot IK controllers in the Animator's IK pass, and takes root motion when
35826
- * `rootMotion` is on.
35827
- */
35828
- private attachAnimationController;
35829
- /**
35830
- * Records the base-layer state a running action enters, so that state's exit can end the action.
35831
- * @param change The entered state.
35832
- */
35833
- private onAnimatorStateEnter;
35834
- /**
35835
- * Ends a running action when its action state exits.
35836
- * @param change The exited state.
35837
- */
35838
- private onAnimatorStateExit;
35839
- /** The Animator's IK pass: the script's `onAnimatorIK` when set, else the foot IK controllers. */
35840
- private onAnimatorIKPass;
35841
- private updateAnimatorTargetMeshes;
35842
- /** TODO */
35843
- enableCharacterController(state: boolean): void;
35844
- /** TODO */
35845
- resetPlayerJumpingState(): void;
35846
- private awakePlayerController;
35847
- private startPlayerController;
35848
- private updatePlayerPosition;
35849
- private updatePlayerController;
35850
- private afterPlayerController;
35851
- private updateCharacterController;
35852
- private castPhysicsClimbingVolumeRay;
35853
- private castPhysicsHeightCheckVolumeRay;
35854
- private getCheckedVerticalVelocity;
35855
- private destroyPlayerController;
35856
- private validateAnimationStateParams;
35857
- /** Fills a missing params object with the defaults, and merges keys added since a params object was exported (motionSpeed). */
35858
- static ApplyAnimationStateParamDefaults(params: PROJECT.AnimationStateParams): PROJECT.AnimationStateParams;
35859
- }
35860
- /**
35861
- * Babylon Enum Definition
35862
- * @interface ThirdPersonControl
35863
- */
35864
- enum ThirdPersonControl {
35865
- ThirdPersonTurning = 0,
35866
- ThirdPersonForward = 1
35867
- }
35868
- }
35869
35890
  declare namespace PROJECT {
35870
35891
  /**
35871
35892
  * Babylon Script Component
@@ -58425,10 +58446,20 @@ declare namespace TOOLKIT {
58425
58446
  static AllUniforms(): string[];
58426
58447
  private static AllUniformsBase;
58427
58448
  private static registered;
58428
- /** The scene's `hdrp.fog` block (parity scenes only), or null. */
58449
+ /** The scene's fog block: `hdrp.fog` on a parity scene, `urp.fog` on a URP physical sky scene, otherwise null. */
58429
58450
  static FogBlock(scene: BABYLON.Scene): any;
58430
- /** The sky the aerial perspective comes from: the live PhysicallyBasedSky when it runs, else the `hdrp.sky` block. */
58451
+ /** The sky the aerial perspective comes from: the live PhysicallyBasedSky when it runs, else the export's physical sky block. */
58431
58452
  static SkyOf(scene: BABYLON.Scene): any;
58453
+ /**
58454
+ * Binds `fogChain` for a URP physical sky, whose pass runs after everything where Unity's runs before transparents. x = the chain
58455
+ * holds display values (decode, composite in linear, encode), y = a water surface exists, z = its height in metres, so a ray that
58456
+ * meets the water first takes no fog, w = the fog is on, which makes Unity's opaque pass give sky pixels aerial perspective up to
58457
+ * the fog's maximum distance (measured: the Morning preset's zenith 0.023 without it, 0.046 with it). A parity scene binds zero.
58458
+ * @param effect The fog effect.
58459
+ * @param scene The scene.
58460
+ * @param fog The scene's fog block, or null.
58461
+ */
58462
+ private static BindChain;
58432
58463
  /** The fog inputs of this frame (computed once per render id). */
58433
58464
  static Frame(scene: BABYLON.Scene, fog: any): IHdrpFogFrame;
58434
58465
  /** The view depth at and beyond which a pixel is sky: the nearest face of an infinite-distance sky mesh (none -> 1e30). */
@@ -58473,6 +58504,21 @@ declare namespace TOOLKIT {
58473
58504
  static AmbientGlsl(): string;
58474
58505
  /** WGSL twin of `AmbientGlsl`. */
58475
58506
  static AmbientWgsl(): string;
58507
+ /**
58508
+ * The PhysicallyBasedSky aerial perspective at distance `tFrag` along `dir` (AtmosphericScattering.hlsl
58509
+ * `EvaluateAtmosphericScattering`, sky part): the in-scatter from the sky's froxel LUT (`apLut`, sampled at screen `uv`) and
58510
+ * the opacity from the optical depth, with the sky's artistic horizon / zenith tint. Shared by this pass and the volumetric
58511
+ * clouds (at their mean cloud distance). Needs the atmosphere uniforms (HdrpPbSkyShaders.GlslUniforms + GlslCommon) and
58512
+ * a `sampler2DArray apLut` declared first.
58513
+ * @returns GLSL source.
58514
+ */
58515
+ static AerialPerspectiveGlsl(): string;
58516
+ /**
58517
+ * WGSL twin of AerialPerspectiveGlsl (`fogAerialPerspective` returns a `FogAerial`). Needs the atmosphere uniforms and
58518
+ * `apLut` / `apLutSampler` declared first.
58519
+ * @returns WGSL source.
58520
+ */
58521
+ static AerialPerspectiveWgsl(): string;
58476
58522
  static GlslHelpers(prefix: string): string;
58477
58523
  static WgslHelpers(prefix: string): string;
58478
58524
  private static Glsl;
@@ -58814,6 +58860,21 @@ declare namespace TOOLKIT {
58814
58860
  requested: boolean;
58815
58861
  captured: boolean;
58816
58862
  }, nowSeconds: number, frame: number, precomputationHash: string, lightHash: string, updateMode: number, updatePeriod: number): boolean;
58863
+ /** ProbeRenderOutcome: nothing changes. */
58864
+ static readonly ProbeRenderKept: number;
58865
+ /** ProbeRenderOutcome: the render is the requested capture, ready for the prefilter. */
58866
+ static readonly ProbeCaptureAccepted: number;
58867
+ /** ProbeRenderOutcome: the render did not draw the sky, so the capture is taken again on the next frame. */
58868
+ static readonly ProbeCaptureRetry: number;
58869
+ /**
58870
+ * What one finished probe render means for the live environment. A requested capture stands only when the sky was drawn;
58871
+ * a render that did not draw it, while a capture waits for its prefilter, has replaced that capture, so it is taken again.
58872
+ * @param capturing - True while a capture is requested.
58873
+ * @param pendingFilter - True while an accepted capture waits for its prefilter.
58874
+ * @param drewSky - True when the sky material was ready for this render.
58875
+ * @returns ProbeRenderKept, ProbeCaptureAccepted or ProbeCaptureRetry.
58876
+ */
58877
+ static ProbeRenderOutcome(capturing: boolean, pendingFilter: boolean, drewSky: boolean): number;
58817
58878
  /** D34: the ambient SH - Dynamic (1) → the live read-back once it exists, else the exported static SH; Static (0) → the exported SH. */
58818
58879
  static SelectAmbientSh(skyAmbientMode: number, readback: BABYLON.SphericalHarmonics, exported: BABYLON.SphericalHarmonics): BABYLON.SphericalHarmonics;
58819
58880
  /** The polynomial scale that leaves diffuse = SH x indirect.diffuse after the environment level (pe x indirect.reflection) multiplies it. */
@@ -58899,6 +58960,8 @@ declare namespace TOOLKIT {
58899
58960
  private filtering;
58900
58961
  private pendingFilter;
58901
58962
  private capturing;
58963
+ /** True when the probe's current render draws the sky (its material is ready), so the render can stand as a capture. */
58964
+ private probeDrawsSky;
58902
58965
  private shReading;
58903
58966
  /** The live capture's ambient, pre-scaled harmonics in physical units (Dynamic ambient), null until the first read-back. */
58904
58967
  private readbackHarmonics;
@@ -58915,6 +58978,10 @@ declare namespace TOOLKIT {
58915
58978
  private apRequested;
58916
58979
  private apCamera;
58917
58980
  private readonly startTime;
58981
+ /** Multiplies the exported sun intensity to the strength the sky scatters (`sky.sunintensityscale`, 1 on HDRP). */
58982
+ private readonly sunIntensityScale;
58983
+ /** The sky's stars (`params.spaceemissionurl`), or null. */
58984
+ private readonly spaceCube;
58918
58985
  private constructor();
58919
58986
  /** "live" or "baked: <reason>" (Inspector read-out). */
58920
58987
  get mode(): string;
@@ -58934,7 +59001,25 @@ declare namespace TOOLKIT {
58934
59001
  private writeCloudUniforms;
58935
59002
  /** The cloud ambient: the sky's ambient SH at (0, -1, 0), physical (CloudLayerCommon `SampleSH9(_AmbientProbeBuffer, down)`). */
58936
59003
  private cloudAmbient;
59004
+ /**
59005
+ * The sky's ambient probe in one direction, physical and before the indirect-diffuse scale - the ambient the cloud layer and
59006
+ * the volumetric clouds (TOOLKIT.VolumetricClouds) light with.
59007
+ * @param direction The world direction.
59008
+ * @returns The ambient radiance, black when the sky has no ambient yet.
59009
+ */
59010
+ ambientAt(direction: BABYLON.Vector3): BABYLON.Color3;
58937
59011
  private cloudLayers;
59012
+ /**
59013
+ * Loads the sky's exported space emission cube (`params.spaceemissionurl`).
59014
+ * @returns The cube, or null when the export has none.
59015
+ */
59016
+ private loadSpaceEmission;
59017
+ /**
59018
+ * The `pbSpace` uniform: emission multiplier, cosine and sine of the Y rotation, and the X sign that takes a right-handed scene
59019
+ * direction back to Unity's left-handed cube.
59020
+ * @returns The uniform value.
59021
+ */
59022
+ private spaceEmissionUniform;
58938
59023
  private loadCloudMap;
58939
59024
  private bindEffect;
58940
59025
  /**
@@ -58945,6 +59030,12 @@ declare namespace TOOLKIT {
58945
59030
  * @param capturing True before the probe renders its faces, false after.
58946
59031
  */
58947
59032
  setProbeCapture(capturing: boolean): void;
59033
+ /**
59034
+ * True when the sky draws straight to display values: on a non-parity scene with no image-processing pass, materials encode
59035
+ * for display themselves, and the sky's raw radiance would otherwise sit among them as linear values.
59036
+ * @returns True for a scene whose image processing runs inside materials.
59037
+ */
59038
+ private encodesForDisplay;
58948
59039
  private applyMaterialUniforms;
58949
59040
  /** D37: the colour of every interacting light on surfaces x HDRP's atmospheric attenuation at the camera. */
58950
59041
  private attenuateSuns;
@@ -63340,6 +63431,36 @@ declare namespace TOOLKIT {
63340
63431
  private static WarnLightmappedMaterial;
63341
63432
  /** Clears the riders of a mesh this network attached, lifts the ambient and Baked-light exclusions, removes the dispose observer, and (dynamic) compacts the registry by moving the last entry in. A mesh another network attached, or a raw clone sharing a rider, is left alone. */
63342
63433
  detach(mesh: BABYLON.AbstractMesh): void;
63434
+ /**
63435
+ * The dispose observer's detach. It runs before the loader's DisposeEntity, so the rider is normally intact and
63436
+ * detach() does the work. When the mesh's metadata is already gone (another observer cleared it first), the
63437
+ * registry entry is found by identity instead - never through metadata - so a disposed mesh never stays in the
63438
+ * registry for sampleDynamic to read.
63439
+ * @param mesh The mesh being disposed.
63440
+ */
63441
+ private detachDisposed;
63442
+ /**
63443
+ * Lets go of a mesh this network attached, reading nothing from its metadata (it may already be gone): lifts the
63444
+ * ambient and Baked-light exclusions, removes its dynamic registry entry (or its static count), clears the owner
63445
+ * and removes the dispose observer. The rider itself is detach()'s to clear.
63446
+ * @param mesh The mesh to release.
63447
+ * @param registryIndex The mesh's dynamic registry index, or -1 for a static mesh.
63448
+ */
63449
+ private releaseMesh;
63450
+ /**
63451
+ * Removes one dynamic registry entry by its index, never by reading the removed mesh's metadata: the last entry
63452
+ * moves into the freed index, the last slot is nulled and the count drops by one. The moved mesh's
63453
+ * lightProbeSlot follows it only while its metadata.toolkit exists - a moved mesh that lost its metadata is
63454
+ * dropped by the next late().
63455
+ * @param registryIndex The entry to remove, in [0, getDynamicCount()).
63456
+ */
63457
+ private removeDynamicEntry;
63458
+ /**
63459
+ * Drops every registry entry whose mesh was disposed, or lost its metadata, without the dispose observer
63460
+ * removing it, so sampleDynamic never reads a dead mesh. Walks from the end, so the move-last-in of
63461
+ * removeDynamicEntry only ever moves an entry that was already checked. One check per entry, no allocation.
63462
+ */
63463
+ private dropDisposedEntries;
63343
63464
  /** Re-interpolates one dynamic mesh now (ignores MoveThreshold). Returns the cell used. */
63344
63465
  sampleMeshNow(mesh: BABYLON.AbstractMesh): number;
63345
63466
  /** One registry entry's re-interpolation (Control flow › Frame step 4). */
@@ -63394,6 +63515,210 @@ declare namespace TOOLKIT {
63394
63515
  private onDataLoaded;
63395
63516
  }
63396
63517
  }
63518
+ declare namespace TOOLKIT {
63519
+ /** One node kept around the camera while it is under water, as FollowPlayerSystem does in Unity. */
63520
+ interface IMeshWaterFollower {
63521
+ /** Node id. */
63522
+ node: string;
63523
+ /** World offset from the camera, in metres. */
63524
+ offset: number[];
63525
+ /** Local scale set once at start, or null to leave the node's own. */
63526
+ scale: number[] | null;
63527
+ }
63528
+ /** Underwater state of a water surface drawn by an ordinary mesh. */
63529
+ interface IMeshWaterUnderwater {
63530
+ /** Height the camera is compared with, in metres. It can differ from the drawn surface: Unity URP Water sits 0.1 m below it. */
63531
+ sealevel: number;
63532
+ /** Raw RGB keys of the fog gradient (`Gradient.Evaluate`), sampled evenly from surface to `fogdepth`. Empty leaves the fog alone. */
63533
+ fogcolors: number[][];
63534
+ /** Added to each fog colour channel that is zero or more, then clamped to 1. A negative channel adds nothing. */
63535
+ fogcolormultiplier: number[];
63536
+ /** Metres of depth over which the gradient runs. */
63537
+ fogdepth: number;
63538
+ /** Fog density in Babylon's terms: Unity's value with the same export factor as `metadata.fogdensity`. */
63539
+ fogdensity: number;
63540
+ /** Linear fog start in metres. */
63541
+ fogstart: number;
63542
+ /** Linear fog end in metres. */
63543
+ fogend: number;
63544
+ /** The sun's raw colour (`Light.color`), which multiplies the fog; white when the effect has no light. */
63545
+ suncolor: number[];
63546
+ /** Node ids of `TOOLKIT.PostProcessor` volumes enabled only under water. */
63547
+ volumenodes: string[];
63548
+ /** Node ids enabled only under water. */
63549
+ shownodes: string[];
63550
+ /** Node ids rotated Euler(180, 0, 0) while under water. */
63551
+ flipnodes: string[];
63552
+ /** Nodes kept around the camera while under water. */
63553
+ follownodes: TOOLKIT.IMeshWaterFollower[];
63554
+ }
63555
+ /** Exported properties of `TOOLKIT.MeshWaterSurface`. */
63556
+ interface IMeshWaterSurfaceProperties {
63557
+ /** World height of the still surface in metres. */
63558
+ sealevel: number;
63559
+ /** Vertical wave amplitude in metres (the material's `_WaveSteepness`), zero for a flat surface. */
63560
+ waveamplitude: number;
63561
+ /** Wave phase speed in radians per second (the material's `_WaveSpeed / 20`). */
63562
+ wavespeed: number;
63563
+ /** The underwater state, or null when the scene has none: the surface then only answers height queries. */
63564
+ underwater: TOOLKIT.IMeshWaterUnderwater | null;
63565
+ }
63566
+ /**
63567
+ * Water drawn by an ordinary mesh with a transpiled graph. It answers height queries in the shape of
63568
+ * `HdrpWaterSurface`, and turns the underwater look on and off as one state switch: each frame it compares the active camera with
63569
+ * sea level, and on a crossing it writes the scene's fog values, enables the listed volumes and nodes, plays their particles, and
63570
+ * turns the listed nodes over. `scene.fogMode` is never written, so no material recompiles, and a scene with fog off has no underwater fog, as in Unity.
63571
+ * @class MeshWaterSurface - All rights reserved (c) 2024 Mackey Kinard
63572
+ */
63573
+ class MeshWaterSurface extends TOOLKIT.ScriptComponent {
63574
+ /** The class name of the volumes this component switches. */
63575
+ private static readonly POST_PROCESSOR_CLASS;
63576
+ /** The class name of the particle systems this component plays. */
63577
+ private static readonly PARTICLES_CLASS;
63578
+ /** `ParticleSystemStopBehavior.StopEmittingAndClear`, because Unity deactivates the object in the same step. */
63579
+ private static readonly STOP_AND_CLEAR;
63580
+ /** CanvasTools doubles Unity's linear fog end on scene intake, so the underwater end takes the same factor. */
63581
+ private static readonly LINEAR_FOG_END_SCALE;
63582
+ /** The scene's water surface, by `scene.uniqueId`. */
63583
+ private static Registry;
63584
+ /** The exported properties. */
63585
+ private waterProperties;
63586
+ /** True between `enterUnderwater` and `leaveUnderwater`. */
63587
+ private isUnderwater;
63588
+ /** One fog colour, reused each frame. */
63589
+ private readonly fogColorChannels;
63590
+ /** The scene's fog colour above water, saved at the first switch. */
63591
+ private readonly surfaceFogColor;
63592
+ /** The scene's fog density above water. */
63593
+ private surfaceFogDensity;
63594
+ /** The scene's linear fog start above water. */
63595
+ private surfaceFogStart;
63596
+ /** The scene's linear fog end above water. */
63597
+ private surfaceFogEnd;
63598
+ /** Nodes enabled only under water. */
63599
+ private shownNodes;
63600
+ /** Particle systems on the shown nodes, played only under water. */
63601
+ private shownParticles;
63602
+ /** Volume nodes enabled only under water. */
63603
+ private volumeNodes;
63604
+ /** Nodes turned over while under water. */
63605
+ private flippedNodes;
63606
+ /** Nodes kept around the camera while under water. */
63607
+ private followers;
63608
+ /** One follower position, reused each frame. */
63609
+ private readonly followPosition;
63610
+ /**
63611
+ * Created by the scene loader from the exported component.
63612
+ * @param transform - The water root.
63613
+ * @param scene - The scene.
63614
+ * @param properties - The exported `IMeshWaterSurfaceProperties`.
63615
+ * @param alias - The class name the component registers under.
63616
+ */
63617
+ constructor(transform: BABYLON.TransformNode, scene: BABYLON.Scene, properties?: any, alias?: string);
63618
+ /**
63619
+ * The scene's water surface. One per scene is the supported case; a second replaces the first with one warning.
63620
+ * @param scene - The scene to look in.
63621
+ * @returns The surface, or null when the scene has none.
63622
+ */
63623
+ static Get(scene: BABYLON.Scene): TOOLKIT.MeshWaterSurface;
63624
+ /**
63625
+ * Reads the exported properties and registers the surface.
63626
+ * Runs before the first frame, so game code can query heights from its own `start`.
63627
+ */
63628
+ protected awake(): void;
63629
+ /**
63630
+ * Builds the components on the nodes shown only under water, which stay asleep while their node is disabled. Their particle
63631
+ * systems then join the reveal-time warm-up, so the first dip compiles nothing.
63632
+ */
63633
+ protected ready(): void;
63634
+ /** Finds the listed nodes once. A camera that starts under water enters the state at once, as Unity's `Start` does. */
63635
+ protected start(): void;
63636
+ /** Runs the state switch for the active camera. Allocates nothing on a frame without a crossing. */
63637
+ protected update(): void;
63638
+ /** Drops the surface from the registry and puts the scene back as it was above water. */
63639
+ protected destroy(): void;
63640
+ /** @returns World height of the still surface in metres. */
63641
+ getSeaLevel(): number;
63642
+ /** @returns World height of the surface now: `sealevel + sin(clockSeconds * wavespeed) * waveamplitude`. */
63643
+ getSurfaceHeight(): number;
63644
+ /**
63645
+ * @param camera - The camera to measure.
63646
+ * @returns Metres of the camera above the surface, negative under water.
63647
+ */
63648
+ getCameraHeight(camera: BABYLON.Camera): number;
63649
+ /**
63650
+ * True at or below the height the Unity underwater component compares with. That height ignores the wave, so a camera
63651
+ * resting at the surface does not flicker between the two states.
63652
+ * @param camera - The camera to test.
63653
+ * @returns True when the underwater state applies to this camera.
63654
+ */
63655
+ isCameraUnderwater(camera: BABYLON.Camera): boolean;
63656
+ /**
63657
+ * Mirrors `HdrpWaterSurface.ProjectPointOnWaterSurface`. The surface is one flat height, so the search ends at once.
63658
+ * @param searchParameters - `targetPositionWS` may be a `Vector3` or a number array.
63659
+ * @returns The surface point under the target, or null without a target.
63660
+ */
63661
+ ProjectPointOnWaterSurface(searchParameters: TOOLKIT.IHdrpWaterSearchParameters): TOOLKIT.IHdrpWaterSearchResult;
63662
+ /**
63663
+ * Mirrors `HdrpWaterSurface.FindWaterSurfaceHeight`.
63664
+ * @param searchParameters - As `ProjectPointOnWaterSurface`.
63665
+ * @returns The surface point under the target, or null without a target.
63666
+ */
63667
+ FindWaterSurfaceHeight(searchParameters: TOOLKIT.IHdrpWaterSearchParameters): TOOLKIT.IHdrpWaterSearchResult;
63668
+ /**
63669
+ * Resolves node ids, skipping one the export no longer holds.
63670
+ * @param nodeIds - Exported node ids.
63671
+ * @returns The nodes found.
63672
+ */
63673
+ private findNodes;
63674
+ /**
63675
+ * Finds the particle systems to start and stop: Unity's underwater component does this from script, so they are authored stopped.
63676
+ * @param nodes - The shown nodes.
63677
+ * @returns The systems found.
63678
+ */
63679
+ private findParticles;
63680
+ /**
63681
+ * Works out a node's two rotations once. Unity turns the plane over because it draws front faces only. The node stays
63682
+ * live: a static water mesh loads with a frozen world matrix, which would ignore the turn.
63683
+ * @param node - The node to turn over.
63684
+ * @returns The node and its rotations.
63685
+ */
63686
+ private prepareFlip;
63687
+ /**
63688
+ * Resolves the follow list and sets each node's fixed scale.
63689
+ * @param follownodes - The exported list, absent on an older export.
63690
+ * @returns The followers found.
63691
+ */
63692
+ private prepareFollowers;
63693
+ /** Saves the surface fog, writes the underwater fog, and turns on everything that shows only below the surface. */
63694
+ private enterUnderwater;
63695
+ /** Restores the surface fog and turns off everything `enterUnderwater` turned on. */
63696
+ private leaveUnderwater;
63697
+ /**
63698
+ * Saves the scene's fog and writes the underwater distances and density. The density takes the scene intake's scale for its mode.
63699
+ * @param underwater - The underwater block.
63700
+ */
63701
+ private writeUnderwaterFog;
63702
+ /** Puts the scene's fog back exactly as it was. */
63703
+ private restoreSurfaceFog;
63704
+ /**
63705
+ * Switches the listed volumes. The node goes first because `IsVolumeEnabled` also tests it.
63706
+ * @param enabled - The new state.
63707
+ */
63708
+ private setVolumesEnabled;
63709
+ /**
63710
+ * Writes the fog colour of the current depth, as the Unity underwater component does each frame, in the same raw
63711
+ * colour values as `metadata.fogcolor`.
63712
+ * @param depthMeters - Metres below the surface, zero or more.
63713
+ */
63714
+ private updateFog;
63715
+ /**
63716
+ * Keeps the horizon box and the particles around the camera, as `FollowPlayerSystem.LateUpdate` does.
63717
+ * @param camera - The active camera.
63718
+ */
63719
+ private updateFollowers;
63720
+ }
63721
+ }
63397
63722
  /** Babylon Toolkit Namespace */
63398
63723
  declare namespace TOOLKIT {
63399
63724
  /**
@@ -68154,6 +68479,11 @@ declare namespace TOOLKIT {
68154
68479
  * @returns True for a Cinemachine volume.
68155
68480
  */
68156
68481
  private isCinemachineVolume;
68482
+ /**
68483
+ * True for a volume the exporter marked `role: "switched"`, which a component turns on later.
68484
+ * @returns True for a switched volume.
68485
+ */
68486
+ private isSwitchedVolume;
68157
68487
  /** Whether this volume contributes: `SetVolumeEnabled` and its node's own enabled state. */
68158
68488
  IsVolumeEnabled(): boolean;
68159
68489
  /** True while the per-frame local-volume observer is registered (only scenes with local volumes register one). */
@@ -69766,6 +70096,8 @@ declare namespace TOOLKIT {
69766
70096
  static readonly VOLUME_TYPES: string[];
69767
70097
  /** cinemachine-port D25: the `role` the exporter writes on a Cinemachine camera's volume. */
69768
70098
  static readonly CINEMACHINE_VOLUME_ROLE: string;
70099
+ /** The `role` of a volume `TOOLKIT.MeshWaterSurface` switches on below the surface. */
70100
+ static readonly SWITCHED_VOLUME_ROLE: string;
69769
70101
  /** PPv2 `GradingMode` enum (`ColorGrading.gradingMode`): 0 LowDefinitionRange, 1 HighDefinitionRange (default), 2 External. */
69770
70102
  static readonly GRADING_MODES: string[];
69771
70103
  /** Unity `RenderingPath` names as exported in `renderingpath`; PPv2 renders SSR only on `DeferredShading`. */
@@ -78843,6 +79175,23 @@ declare namespace TOOLKIT {
78843
79175
  * @returns The body, or null when there is no collider to build it from.
78844
79176
  */
78845
79177
  static CreateComplexCompoundBody(scene: BABYLON.Scene, entity: BABYLON.TransformNode, childItems: TOOLKIT.PhyscisContainerData[], rootMeshShape: BABYLON.PhysicsShape, motionType: BABYLON.PhysicsMotionType, physics: any, mass: number, centerOfMass: BABYLON.Vector3, layermask: number, filtermask: number): BABYLON.PhysicsBody;
79178
+ /**
79179
+ * Marks what the loader may dispose once a complex compound child has given its collider to the root's body: a node
79180
+ * that exists only to carry the collider goes whole, while a node that also renders stays and only loses its
79181
+ * `.Collider` mesh. A LOD level with a BoxCollider is such a node: disposing it would remove the visible mesh,
79182
+ * and with it every lower level, which stay blocked by a disposed LOD master.
79183
+ * @param entity The compound child node.
79184
+ */
79185
+ private static MarkCompoundChildForDisposal;
79186
+ /**
79187
+ * Whether a node is a mesh Unity renders, shadow-only renderers included. Having vertices is not enough: with the
79188
+ * exporter's "Default Collision Proxy" on, a collider whose renderer is absent or disabled gets a generated box.
79189
+ * The exporter writes `metadata.toolkit.renderer` only for a present, enabled renderer whenever physics is exported,
79190
+ * and it writes one on a `.Collider` mesh too, so that name is ruled out first.
79191
+ * @param node A node.
79192
+ * @returns True when the node draws in Unity.
79193
+ */
79194
+ private static RendersItself;
78846
79195
  protected static CreateCompoundPhysicsShapeAndBody(scene: BABYLON.Scene, root: BABYLON.TransformNode, entity: BABYLON.TransformNode, element: any, impostortype: number, staticfriction: number, dynamicfriction: number, restitution: number, fcombine: number, rcombine: number, sitems: TOOLKIT.PhyscisContainerData[], item: TOOLKIT.PhyscisContainerData, center: any, complex: boolean, trigger: boolean, persist: boolean, layer: number, filter: number): void;
78847
79196
  protected static CreateHeightFieldTerrainShapeFromMesh(terrainMesh: BABYLON.Mesh, scaleX: number, scaleZ: number): any;
78848
79197
  static GetPhysicsHeapSize(): number;
@@ -80344,7 +80693,8 @@ declare namespace TOOLKIT {
80344
80693
  getOwnedParticleSystems(): BABYLON.IParticleSystem[];
80345
80694
  /**
80346
80695
  * True when nothing of the system is drawn and it is drawn as quads, so a warm draw can show it (mesh / graph renderers draw through
80347
- * meshes): idle (never started), or playing but held by culling with no live particle.
80696
+ * meshes): idle (never started), or playing but held by culling with no live particle. A system whose object was inactive at
80697
+ * export (`enabled: false`) counts too: script activates it later, and without this draw its first show builds a GPU pipeline.
80348
80698
  */
80349
80699
  canBeginWarmupDraw(): boolean;
80350
80700
  /** Starts the warm draw: one invisible particle, the clock, RNG and emission bookkeeping untouched (SceneShaderWarmup reveal-time pass). */
@@ -83723,6 +84073,10 @@ declare namespace TOOLKIT {
83723
84073
  */
83724
84074
  class TerrainBuilder extends TOOLKIT.ScriptComponent {
83725
84075
  private static _registry;
84076
+ /** worldToUnityUV's inverse world matrix: height queries run every frame and must not allocate one per call. */
84077
+ private static readonly ScratchInverse;
84078
+ /** worldToUnityUV's terrain-local position. */
84079
+ private static readonly ScratchLocal;
83726
84080
  readonly onBuiltObservable: BABYLON.Observable<TOOLKIT.TerrainBuilder>;
83727
84081
  /** Loading progress of this terrain, stage by stage (see ITerrainLoadProgress). */
83728
84082
  readonly onLoadProgressObservable: BABYLON.Observable<TOOLKIT.ITerrainLoadProgress>;
@@ -83880,6 +84234,37 @@ declare namespace TOOLKIT {
83880
84234
  protected destroy(): void;
83881
84235
  private disposeParts;
83882
84236
  private buildAsync;
84237
+ /**
84238
+ * Finds this tile's four neighbours (D17). Reads each one's heights from its contract, because its heightfield may not be built yet.
84239
+ * @returns The neighbours, or null when the tile stands alone.
84240
+ */
84241
+ private resolveEdgeNeighbors;
84242
+ /**
84243
+ * One axis neighbour of this tile.
84244
+ * @param tiles The scene's registered tiles.
84245
+ * @param neighborId The exported node id, or null.
84246
+ * @param useIds True when the export carries neighbour ids, so adjacency is not tested.
84247
+ * @param offsetX -1 or 1 along Unity x, else 0.
84248
+ * @param offsetZ -1 or 1 along Unity z, else 0.
84249
+ * @returns The neighbour's heights, or null when there is no matching tile.
84250
+ */
84251
+ private edgeNeighborFor;
84252
+ /**
84253
+ * D17: tiles continue each other's normals only with equal resolution and equal x and z size.
84254
+ * @param other Another registered tile.
84255
+ * @returns True when a shared edge lines up sample for sample.
84256
+ */
84257
+ private canShareEdgeWith;
84258
+ /**
84259
+ * DR-6.2 rectangle adjacency, for an export without neighbour ids: both tiles allow auto connect, share a grouping id, and
84260
+ * the other tile's origin sits one tile size away in this tile's Unity space. Measured in that space, it holds under any
84261
+ * parent transform, where comparing world axes would swap neighbours below a mirrored root.
84262
+ * @param other Another registered tile.
84263
+ * @param offsetX -1 or 1 along Unity x, else 0.
84264
+ * @param offsetZ -1 or 1 along Unity z, else 0.
84265
+ * @returns True when the other tile is this tile's neighbour on that side.
84266
+ */
84267
+ private isAdjacentTile;
83883
84268
  /** Shows or hides the built trees and details as drawTreesAndFoliage says (on a change, and once the parts are built). */
83884
84269
  private applyTreesAndFoliageVisibility;
83885
84270
  /**
@@ -84036,6 +84421,13 @@ declare namespace TOOLKIT {
84036
84421
  private static NowMs;
84037
84422
  /** [u, v] of a world position in Unity terrain space (unclamped), or null before the contract is known. */
84038
84423
  private worldToUnityUV;
84424
+ /**
84425
+ * True when a world position lies on this tile's rectangle, widened by a tolerance.
84426
+ * @param worldPosition The world position.
84427
+ * @param tolerance Slack in metres on every side.
84428
+ * @returns False outside the widened rectangle, or before the contract is known.
84429
+ */
84430
+ private containsWorldPosition;
84039
84431
  /** Height relative to the terrain (Unity semantics), clamped to the terrain rect. */
84040
84432
  SampleHeight(worldPosition: BABYLON.Vector3): number;
84041
84433
  /** Local height at normalised (u, v). */
@@ -84050,7 +84442,13 @@ declare namespace TOOLKIT {
84050
84442
  private static Unregister;
84051
84443
  /** Every registered (valid-contract) terrain of the scene. */
84052
84444
  static GetTerrains(scene: BABYLON.Scene): TOOLKIT.TerrainBuilder[];
84053
- /** The terrain whose rect contains the world position (the last registered wins overlaps), or null. */
84445
+ /**
84446
+ * The terrain whose rect contains the world position (the last registered wins overlaps), or null. A point that misses
84447
+ * every rect by Float32 rounding on a shared tile edge gets a second scan with TERRAIN_EDGE_TOLERANCE_METERS of slack.
84448
+ * @param scene The scene.
84449
+ * @param worldPosition The world position.
84450
+ * @returns The terrain under the position, or null when none covers it.
84451
+ */
84054
84452
  static GetTerrainAt(scene: BABYLON.Scene, worldPosition: BABYLON.Vector3): TOOLKIT.TerrainBuilder;
84055
84453
  /** World Y of the terrain surface under a world position, or null when no terrain covers it. */
84056
84454
  static GetWorldHeightAt(scene: BABYLON.Scene, worldPosition: BABYLON.Vector3): number;
@@ -84174,6 +84572,20 @@ declare namespace TOOLKIT {
84174
84572
  wavelength: number;
84175
84573
  } | null;
84176
84574
  }
84575
+ /** The heights of one neighbouring tile, enough to continue a central difference across a shared edge. */
84576
+ interface ITerrainEdgeNeighbor {
84577
+ /** The neighbour's 16-bit heights, z outer, index = z * resolution + x. */
84578
+ heights: Uint16Array;
84579
+ /** The neighbour's height scale in metres (`size[1]`), which may differ from this tile's. */
84580
+ heightScale: number;
84581
+ }
84582
+ /** The four axis neighbours of a tile in Unity terrain space: left -x, right +x, top +z, bottom -z. */
84583
+ interface ITerrainEdgeNeighbors {
84584
+ left: ITerrainEdgeNeighbor | null;
84585
+ right: ITerrainEdgeNeighbor | null;
84586
+ top: ITerrainEdgeNeighbor | null;
84587
+ bottom: ITerrainEdgeNeighbor | null;
84588
+ }
84177
84589
  interface ITerrainContract {
84178
84590
  contract: number;
84179
84591
  name: string;
@@ -84396,14 +84808,6 @@ declare namespace TOOLKIT {
84396
84808
  }[];
84397
84809
  /** The layer's main-pass host with room for at least count instances (created or grown on demand). */
84398
84810
  private ensureMain;
84399
- /**
84400
- * Babylon's thinInstanceSetBuffer("matrix") keeps the old previous-world buffer (created on the first draw once the scene
84401
- * needs previous world matrices, e.g. HDRP motion blur velocity), and every draw then writes the grown count into it - on
84402
- * WebGPU that invalidates the whole frame. Rebuilt at the new size the way Babylon's own _thinInstanceUpdateBufferSize does:
84403
- * merely disposing it leaves its four previousWorld vertex buffers on the geometry, and the next pipeline then counts them
84404
- * as four separate buffers (past WebGPU's 8).
84405
- */
84406
- private static ResizePreviousMatrices;
84407
84811
  /** The main host's tint buffer: Babylon's "color" for mesh layers, "tkGrassTint" for texture grass (TerrainGrassPlugin). */
84408
84812
  private static TintBuffer;
84409
84813
  /** XZ distance from the camera (Unity-local metres) to the chunk rect. */
@@ -84576,6 +84980,14 @@ declare namespace TOOLKIT {
84576
84980
  * Keyed on the material's type and shader name, never on a graph, scene or material name.
84577
84981
  */
84578
84982
  static IsGraphMaterial(material: BABYLON.Material): boolean;
84983
+ /**
84984
+ * True when a Shader Graph class alone decides how its mesh moves, so the toolkit adds no sway. In Unity a terrain tree or
84985
+ * mesh detail on a Shader Graph gets no engine wind: only what the graph computes moves it, and the transpiled class
84986
+ * already does that. A SpeedTree material is the exception, because its wind comes from data its host may not carry.
84987
+ * @param material The source material of a tree or detail host.
84988
+ * @returns True when MODE_TREE and MODE_SWAY must be left out.
84989
+ */
84990
+ static GraphOwnsMotion(material: BABYLON.Material): boolean;
84579
84991
  getClassName(): string;
84580
84992
  isCompatible(shaderLanguage: BABYLON.ShaderLanguage): boolean;
84581
84993
  /** Installs (or extends, OR-ing the modes) the plugin on a material. Idempotent per material (metadata.tkFoliage). */
@@ -84889,6 +85301,8 @@ declare namespace TOOLKIT {
84889
85301
  private _errors;
84890
85302
  private _minH;
84891
85303
  private _maxH;
85304
+ /** The tile's axis neighbours, null when it stands alone, so border normals stay one-sided. */
85305
+ private edgeNeighbors;
84892
85306
  constructor(contract: TOOLKIT.ITerrainContract, heights: Uint16Array);
84893
85307
  get cellSizeX(): number;
84894
85308
  get cellSizeZ(): number;
@@ -84898,6 +85312,12 @@ declare namespace TOOLKIT {
84898
85312
  sampleHeight(x: number, z: number): number;
84899
85313
  /** Terrain-local normal (handedness applied to x). */
84900
85314
  normalAt(u: number, v: number, out: number[]): void;
85315
+ /**
85316
+ * Sets the tiles whose heights continue this tile's normals across its shared edges. Call it before any normal is read:
85317
+ * the normal textures are built once from normalAt.
85318
+ * @param neighbors The axis neighbours, or null when the tile stands alone.
85319
+ */
85320
+ setEdgeNeighbors(neighbors: TOOLKIT.ITerrainEdgeNeighbors): void;
84901
85321
  /** Fills the holes grid from TerrainImages pixels (R channel, > 127 = solid). Image row 0 = terrain z 0. */
84902
85322
  setHoles(pixels: Uint8ClampedArray, width: number): void;
84903
85323
  private cellX;
@@ -84953,8 +85373,19 @@ declare namespace TOOLKIT {
84953
85373
  static DecodeHeight(value: number, sizeY: number): number;
84954
85374
  /** Bilinear local height at normalised (u, v), both clamped to 0..1. */
84955
85375
  static SampleHeightBilinear(h: Uint16Array, R: number, sizeY: number, u: number, v: number): number;
84956
- /** Central difference at the nearest sample (one-sided on border samples), normalised [x, y, z] into out. */
84957
- static SampleNormal(h: Uint16Array, R: number, size: number[], u: number, v: number, out: number[]): void;
85376
+ /**
85377
+ * Central difference at the nearest sample, normalised [x, y, z] into out. A border sample continues across its shared
85378
+ * edge into a neighbouring tile, each height decoded with its own tile's scale, so both tiles compute the same normal
85379
+ * on the edge. A border sample without a neighbour stays one-sided.
85380
+ * @param h The tile's heights, z outer.
85381
+ * @param R The tile's samples per side.
85382
+ * @param size The tile's size [x, y, z] in metres.
85383
+ * @param u Unity-space normalised x, clamped to 0..1.
85384
+ * @param v Unity-space normalised z, clamped to 0..1.
85385
+ * @param out Receives the unit normal.
85386
+ * @param neighbors The tile's axis neighbours, or null when it stands alone.
85387
+ */
85388
+ static SampleNormal(h: Uint16Array, R: number, size: number[], u: number, v: number, out: number[], neighbors?: TOOLKIT.ITerrainEdgeNeighbors): void;
84958
85389
  /** handedness 0 → -x */
84959
85390
  static UnityToLocalX(x: number, handedness: number): number;
84960
85391
  /** handedness 0 → -yaw */
@@ -85309,7 +85740,8 @@ declare namespace TOOLKIT {
85309
85740
  }
85310
85741
  /**
85311
85742
  * Terrain trees (unity-terrain-system-parity D15-D18, D29, D41, Design Reference §4.4, §14). Every prototype LOD renderer
85312
- * becomes one thin-instance host parented to the terrain node. Each update selects a Unity LODGroup level per instance
85743
+ * becomes one thin-instance host parented to the terrain node. Hosts start small and grow to what is really drawn (D18), and
85744
+ * every tile's hosts draw one scene-owned copy of each prototype's geometry (D19). Each update selects a Unity LODGroup level per instance
85313
85745
  * (relative height, maxfulllod, 0.5 s dithered crossfade), culls by distance and frustum, and rewrites the host buffers.
85314
85746
  * Instances outside the frustum but inside the terrain's shadow reach still go to the casting hosts, so trees behind
85315
85747
  * the camera cast into view (D44). Instances are visited through a 64 m grid (D45). Tree colliders are one static
@@ -85327,6 +85759,12 @@ declare namespace TOOLKIT {
85327
85759
  private static readonly NO_PROBE_RECORD;
85328
85760
  /** cos(0.5 deg): a smaller dot between light directions counts as the light turning. */
85329
85761
  private static readonly LIGHT_TURN_DOT;
85762
+ /** The clone state a shared host must keep to draw as the renderer mesh does: winding, render group, layer, sort order, vertex colours, bones. */
85763
+ private static readonly HOST_DRAW_STATE;
85764
+ /** Per scene (uniqueId): one hidden mesh per "<templateid>|<lod>|<source uniqueId>", whose GPU buffers every tile's hosts share (D19). */
85765
+ private static PreparedHosts;
85766
+ /** The probe buffer a host holds now: growth replaces it, and the host's dispose must free the current one. */
85767
+ private static ProbeBuffers;
85330
85768
  /** Per-scene clones of prototype materials, keyed "<templateid>|<material uniqueId>" (D41), with a reference count. */
85331
85769
  private static _materials;
85332
85770
  private _owner;
@@ -85340,6 +85778,8 @@ declare namespace TOOLKIT {
85340
85778
  private _colliderShapes;
85341
85779
  private _distance;
85342
85780
  private _built;
85781
+ /** True once a host of this tile fell back to its own geometry, so the warning prints once per tile. */
85782
+ private _warnedUniqueHost;
85343
85783
  private _n;
85344
85784
  private _proto;
85345
85785
  private _local;
@@ -85410,14 +85850,24 @@ declare namespace TOOLKIT {
85410
85850
  * @returns A new array of caster meshes.
85411
85851
  */
85412
85852
  getCasterMeshes(): BABYLON.AbstractMesh[];
85413
- /** Host count and instances drawn per host (diagnostics). */
85853
+ /**
85854
+ * Host count, instances drawn per host, and instances the hosts and caster slots have room for (diagnostics).
85855
+ * @returns The numbers; capacity counts every host and slot.
85856
+ */
85414
85857
  getStats(): {
85415
85858
  hosts: number;
85416
85859
  instances: number;
85417
85860
  drawn: number;
85418
85861
  visibleHosts: number;
85419
85862
  colliders: boolean;
85863
+ capacity: number;
85420
85864
  };
85865
+ /**
85866
+ * How many prepared prototype geometries a scene holds (tests and diagnostics).
85867
+ * @param scene The scene.
85868
+ * @returns One per (template, LOD, source) in use, 0 when the scene has no trees.
85869
+ */
85870
+ static PreparedHostCount(scene: BABYLON.Scene): number;
85421
85871
  /**
85422
85872
  * Builds the tree instancer from the terrain contract: one camera host per LOD renderer of each prototype (plus the
85423
85873
  * caster slots of each casting host, terrain-performance D8), registers the shadow casters with the owner, decodes the
@@ -85428,9 +85878,9 @@ declare namespace TOOLKIT {
85428
85878
  /**
85429
85879
  * Creates the hosts of one prototype (§4.4 step 1): one thin-instance host per renderer mesh of each LOD level, with the
85430
85880
  * host's shadow-casting flag, its light-probe use and, for a casting host, its caster slots (terrain-performance D8).
85431
- * @param p The exported tree prototype.
85432
- * @param tpl The prototype's template node in the scene.
85433
- * @param cap The prototype's instance count (each host's capacity).
85881
+ * @param prototype The exported tree prototype.
85882
+ * @param template The prototype's template node in the scene.
85883
+ * @param instanceCount The prototype's instance count: the ceiling each host and slot can grow to (D18).
85434
85884
  * @returns The prototype's runtime data, or null when no LOD produced a host.
85435
85885
  */
85436
85886
  private buildPrototype;
@@ -85441,6 +85891,19 @@ declare namespace TOOLKIT {
85441
85891
  * TerrainProbePlugin) over `probes` (every record starts at "no probe") - and the probe plugin on its material(s).
85442
85892
  */
85443
85893
  static AttachProbeBuffer(host: BABYLON.Mesh, probes: Float32Array): BABYLON.Buffer;
85894
+ /**
85895
+ * One instanced buffer over a host's probe records, bound as the three vec4 views of TerrainProbePlugin.
85896
+ * @param host The host mesh.
85897
+ * @param probes The packed records, TerrainProbePlugin.STRIDE each.
85898
+ * @returns The new buffer.
85899
+ */
85900
+ private static CreateProbeBuffer;
85901
+ /**
85902
+ * Gives a grown host a probe buffer of its new size. The plugin stays attached, and the views' attribute names do not
85903
+ * change, so no shader recompiles.
85904
+ * @param host The host whose probes array was replaced.
85905
+ */
85906
+ private static ResizeProbeBuffer;
85444
85907
  /**
85445
85908
  * X10 fix loop 2: samples the scene's light-probe network once per instance (spatially ordered by the D45 grid so each
85446
85909
  * tetrahedral walk starts in the previous instance's cell), at the instance's world position (ProbeSampleHeight 0).
@@ -85497,12 +85960,49 @@ declare namespace TOOLKIT {
85497
85960
  * @throws Error when the source has no index buffer, no vertex buffers, or a vertex buffer without a GPU wrapper.
85498
85961
  */
85499
85962
  static CreateSharedHost(scene: BABYLON.Scene, source: BABYLON.Mesh, name: string): BABYLON.Mesh;
85963
+ /**
85964
+ * The mesh a renderer's geometry is drawn from: a copy baked into prototype space, in one interleaved buffer.
85965
+ * @param source The renderer's mesh.
85966
+ * @param templateWorldInverse The inverse world matrix of the prototype's template.
85967
+ * @param name The new mesh's name.
85968
+ * @returns The mesh, or null when the source cannot be cloned.
85969
+ */
85970
+ private static BakeHostGeometry;
85971
+ /**
85972
+ * The scene's one hidden copy of a prototype renderer's geometry (D19): it owns the GPU buffers every tile's hosts draw, so
85973
+ * a tile's dispose never frees another tile's geometry. Lives until the scene is disposed.
85974
+ * @param prototype The exported tree prototype.
85975
+ * @param lod The LOD level.
85976
+ * @param source The renderer's mesh.
85977
+ * @param templateWorldInverse The inverse world matrix of the prototype's template.
85978
+ * @returns The prepared mesh, or null when the source cannot be cloned.
85979
+ */
85980
+ private prepareHostGeometry;
85981
+ /**
85982
+ * Today's path for an engine without shared GPU buffers: the tile keeps its own geometry copy, so its trees never vanish.
85983
+ * @param source The renderer's mesh.
85984
+ * @param templateWorldInverse The inverse world matrix of the prototype's template.
85985
+ * @param name The host's name.
85986
+ * @param reason Why sharing failed, for the warning.
85987
+ * @returns The host, or null when the source cannot be cloned.
85988
+ */
85989
+ private createUniqueHost;
85990
+ /**
85991
+ * One camera host of this tile: the scene's prepared geometry (D19) with this tile's own instance buffers.
85992
+ * @param prototype The exported tree prototype.
85993
+ * @param lod The LOD level.
85994
+ * @param source The renderer's mesh.
85995
+ * @param templateWorldInverse The inverse world matrix of the prototype's template.
85996
+ * @param matrices The host's first instance matrices.
85997
+ * @param fades The host's first LOD fades.
85998
+ * @returns The host, or null when the source cannot be cloned.
85999
+ */
85500
86000
  private createHost;
85501
86001
  /**
85502
86002
  * Builds the CASTER_SLOTS caster-only meshes of a casting host (terrain-performance D8). When GPU sharing fails the host keeps
85503
86003
  * no slots and casts itself, as before.
85504
86004
  * @param host The casting host.
85505
- * @param capacity Instances each slot can hold (the prototype's instance count).
86005
+ * @param capacity Instances each slot can hold at first; it grows to the host's capacityCeiling (D18).
85506
86006
  */
85507
86007
  private createCasterSlots;
85508
86008
  /**
@@ -85524,6 +86024,7 @@ declare namespace TOOLKIT {
85524
86024
  /**
85525
86025
  * D41: one clone per (prototype, source material), named "<material>.<prototype>", with the foliage plugin attached.
85526
86026
  * T8: a SpeedTree 8 material on a host with wind vertex data gets its own clone without the MODE_TREE bend.
86027
+ * A Shader Graph tree gets no bend either, because only its graph moves it in Unity (TerrainFoliagePlugin.GraphOwnsMotion).
85527
86028
  * @param p The exported tree prototype.
85528
86029
  * @param lod The LOD level of the host.
85529
86030
  * @param source The renderer's material (a MultiMaterial is cloned per sub-material).
@@ -85668,12 +86169,19 @@ declare namespace TOOLKIT {
85668
86169
  private static KthSmallest;
85669
86170
  /**
85670
86171
  * Appends instance `instanceIndex` to a host or slot: its matrix, the fade, its probe SH when the target binds probes (a "no probe" record while the scene's network is switched off), and the
85671
- * instance's sphere in the target's terrain-local box. A full target ignores the instance.
86172
+ * instance's sphere in the target's terrain-local box. A full target grows (D18); one at its ceiling ignores the instance.
85672
86173
  * @param target The camera host or caster slot.
85673
86174
  * @param instanceIndex The instance index.
85674
86175
  * @param fade The LOD fade value (1 steady; signed crossfade weight otherwise).
85675
86176
  */
85676
86177
  private appendInstance;
86178
+ /**
86179
+ * Gives a full host or slot larger arrays, keeping the instances written so far (D18). The GPU buffers follow in uploadTarget.
86180
+ * @param target The camera host or caster slot.
86181
+ * @param ceiling The most instances the target can ever hold.
86182
+ * @returns False when the target is already at its ceiling.
86183
+ */
86184
+ private static GrowTarget;
85677
86185
  /**
85678
86186
  * True when any host of a prototype's LOD level casts shadows (billboard LODs and castshadows:false renderers do not).
85679
86187
  * @param hosts The instancer's hosts.
@@ -85700,6 +86208,21 @@ declare namespace TOOLKIT {
85700
86208
  * @param shadowOnly True when the instance is outside the view (state 2).
85701
86209
  */
85702
86210
  private writeCaster;
86211
+ /**
86212
+ * Binds a grown host's or slot's new arrays. Each set uploads its whole array, so the frame needs no partial update.
86213
+ * @param target The camera host or caster slot.
86214
+ */
86215
+ private static RebindGrownTarget;
86216
+ /**
86217
+ * Babylon's thinInstanceSetBuffer("matrix") keeps the old previous-world buffer (created on the first draw once the scene
86218
+ * needs previous world matrices, e.g. HDRP motion blur velocity), and every draw then writes the grown count into it - on
86219
+ * WebGPU that invalidates the whole frame. Rebuilt at the new size the way Babylon's own _thinInstanceUpdateBufferSize does:
86220
+ * merely disposing it leaves its four previousWorld vertex buffers on the geometry, and the next pipeline then counts them
86221
+ * as four separate buffers (past WebGPU's 8).
86222
+ * @param mesh The grown thin-instance mesh.
86223
+ * @param matrices Its new instance matrices.
86224
+ */
86225
+ static ResizePreviousMatrices(mesh: BABYLON.Mesh, matrices: Float32Array): void;
85703
86226
  /**
85704
86227
  * Uploads a host's or slot's instances written this update: count, matrices, fades, the probe buffer when bound, the bounding
85705
86228
  * box, and visibility (an empty target is hidden; a slot must be visible to cast). An empty slot is also disabled, and a
@@ -93296,6 +93819,515 @@ declare namespace TOOLKIT {
93296
93819
  private static crosses;
93297
93820
  }
93298
93821
  }
93822
+ declare namespace TOOLKIT {
93823
+ /** The exported curves of `urp.clouds`: 64 samples each over the layer height (CloudExportMath.CloudCurveSamples). */
93824
+ interface ICloudCurves {
93825
+ density?: number[];
93826
+ erosion?: number[];
93827
+ ambientocclusion?: number[];
93828
+ }
93829
+ /** One noise sidecar: its url, relative to the scene folder, and its volume edge in texels. */
93830
+ interface ICloudNoiseFile {
93831
+ url: string;
93832
+ size: number;
93833
+ }
93834
+ /**
93835
+ * The exported `urp.clouds` block (DR-4.6): the VolumetricClouds Volume fields under their lowercased names, the renderer
93836
+ * feature's resolution scale, the curves and the noise sidecars. Every value may be missing from an older export.
93837
+ */
93838
+ interface IUrpCloudsBlock {
93839
+ state?: boolean;
93840
+ localclouds?: boolean;
93841
+ resolutionscale?: number;
93842
+ densitymultiplier?: number;
93843
+ shapefactor?: number;
93844
+ shapescale?: number;
93845
+ shapeoffset?: number[];
93846
+ coveragevariation?: number;
93847
+ coveragepatternsize?: number;
93848
+ coveragegapamount?: number;
93849
+ coveragepatternoffset?: number[];
93850
+ erosionfactor?: number;
93851
+ erosionscale?: number;
93852
+ microerosion?: boolean;
93853
+ microerosionfactor?: number;
93854
+ microerosionscale?: number;
93855
+ bottomaltitude?: number;
93856
+ altituderange?: number;
93857
+ earthcurvature?: number;
93858
+ globalspeed?: number;
93859
+ globalorientation?: number;
93860
+ shapespeedmultiplier?: number;
93861
+ erosionspeedmultiplier?: number;
93862
+ altitudedistortion?: number;
93863
+ verticalshapewindspeed?: number;
93864
+ verticalerosionwindspeed?: number;
93865
+ cloudmapspeedmultiplier?: number;
93866
+ ambientlightprobedimmer?: number;
93867
+ sunlightdimmer?: number;
93868
+ erosionocclusion?: number;
93869
+ scatteringtint?: number[];
93870
+ powdereffectintensity?: number;
93871
+ multiscattering?: number;
93872
+ temporalaccumulationfactor?: number;
93873
+ perceptualblending?: number;
93874
+ numprimarysteps?: number;
93875
+ longraysamplemultiplier?: number;
93876
+ numlightsteps?: number;
93877
+ fadeinmode?: number;
93878
+ fadeinstart?: number;
93879
+ fadeindistance?: number;
93880
+ curves?: TOOLKIT.ICloudCurves;
93881
+ noise?: {
93882
+ worley?: TOOLKIT.ICloudNoiseFile;
93883
+ erosion?: TOOLKIT.ICloudNoiseFile;
93884
+ };
93885
+ }
93886
+ /** The two `urp.sky` fields the clouds read: the planet and the sun's intensity scale. */
93887
+ interface ICloudSkyFields {
93888
+ planet?: {
93889
+ radius?: number;
93890
+ renderingspace?: number;
93891
+ center?: number[];
93892
+ };
93893
+ sunintensityscale?: number;
93894
+ }
93895
+ /** One tier's march settings (DR-6.4). */
93896
+ interface ICloudTierSettings {
93897
+ /** Cloud target size as a fraction of the render size. */
93898
+ resolutionScale: number;
93899
+ /** Primary march steps. */
93900
+ primarySteps: number;
93901
+ /** How much longer rays may multiply their step count. */
93902
+ longRayMultiplier: number;
93903
+ /** Light march steps toward the sun. */
93904
+ lightSteps: number;
93905
+ }
93906
+ /**
93907
+ * unity-gaia-terrain-port T19 / T20: the pure maths of the volumetric clouds - shell intersection, step size, tier settings and
93908
+ * the curve texture - free of Babylon so the tests run it without a scene.
93909
+ */
93910
+ class VolumetricCloudsMath {
93911
+ /** The lowest tier: clouds are never switched off, only coarser. */
93912
+ static readonly LowestTier: number;
93913
+ /**
93914
+ * Where a ray enters and leaves the cloud shell (the local-clouds case of `IntersectCloudVolume`).
93915
+ * @param rayOrigin - Ray origin in planet space (relative to the planet centre), metres.
93916
+ * @param rayDirection - Normalised ray direction.
93917
+ * @param innerRadius - Radius of the layer bottom, metres from the planet centre.
93918
+ * @param outerRadius - Radius of the layer top, metres from the planet centre.
93919
+ * @param planetRadius - Planet radius for the earth-shadow test below the layer. Defaults to `innerRadius` (no test lost for a ray going up).
93920
+ * @returns `[entry, exit]` in metres along the ray, or null when the ray misses the shell or the planet hides it.
93921
+ */
93922
+ static ShellInterval(rayOrigin: number[], rayDirection: number[], innerRadius: number, outerRadius: number, planetRadius?: number): number[];
93923
+ /**
93924
+ * The primary step length before the long-ray refinement (`TraceVolumetricRay`).
93925
+ * @param shellLength - Metres of the ray inside the shell.
93926
+ * @param steps - Primary step count.
93927
+ * @param maximumStep - The largest step, metres (layer thickness / 8).
93928
+ * @returns The step length in metres.
93929
+ */
93930
+ static StepSize(shellLength: number, steps: number, maximumStep: number): number;
93931
+ /**
93932
+ * The largest primary step (`_MaxStepSize`, layer thickness / 8), lengthened when a tier marches fewer steps than authored so
93933
+ * the march still reaches as far as Unity's, up to CLOUD_MAX_STEP_STRETCH times.
93934
+ * @param altitudeRange - Layer thickness, metres.
93935
+ * @param authoredSteps - The Volume's primary steps (missing gives no stretch).
93936
+ * @param tierSteps - The tier's primary steps.
93937
+ * @returns The largest step, metres.
93938
+ */
93939
+ static MaximumStep(altitudeRange: number, authoredSteps: number, tierSteps: number): number;
93940
+ /**
93941
+ * The march settings of one tier (DR-6.4): every value is the authored one capped by the tier's CLOUD_TIER_CAPS row. Tier 0 caps
93942
+ * at the browser ceiling; tiers 1 and 2 lower the resolution, long-ray refinement and light steps but keep 64 primary steps.
93943
+ * @param tier - 0, 1 or 2 (clamped).
93944
+ * @param authored - The `urp.clouds` block.
93945
+ * @returns The settings.
93946
+ */
93947
+ static TierSettings(tier: number, authored: TOOLKIT.IUrpCloudsBlock): TOOLKIT.ICloudTierSettings;
93948
+ /**
93949
+ * The tier clouds start at: 1 on a phone-width viewport or a GPU whose textures stop below 8192, otherwise 0.
93950
+ * @param maximumTextureSize - `engine.getCaps().maxTextureSize`.
93951
+ * @param viewportCssWidth - The canvas width in CSS pixels.
93952
+ * @returns The starting tier.
93953
+ */
93954
+ static StartTier(maximumTextureSize: number, viewportCssWidth: number): number;
93955
+ /**
93956
+ * True when the camera moved far enough in one frame to be a cut, so the temporal history no longer matches.
93957
+ * @param previousPosition - Last frame's camera position, or null on the first frame.
93958
+ * @param currentPosition - This frame's camera position.
93959
+ * @returns True for a cut (or the first frame).
93960
+ */
93961
+ static IsCameraCut(previousPosition: number[], currentPosition: number[]): boolean;
93962
+ /**
93963
+ * The 64 x 1 curve texture (`PrepareCustomLutData`): density in red (zero at both ends), erosion in green, one minus ambient
93964
+ * occlusion in blue, each clamped to 0..1. Missing curves give white, as the cloud feature does without a density curve.
93965
+ * @param density - 64 density samples over the layer height.
93966
+ * @param erosion - 64 erosion samples.
93967
+ * @param ambientOcclusion - 64 ambient occlusion samples.
93968
+ * @returns RGBA floats, 64 texels.
93969
+ */
93970
+ static PackCurves(density: number[], erosion: number[], ambientOcclusion: number[]): Float32Array;
93971
+ /**
93972
+ * Both hits of a sphere centred on the planet (`IntersectSphere`), or a negative pair when the ray misses.
93973
+ * @param sphereRadius - Sphere radius, metres.
93974
+ * @param cosChi - Cosine between the ray and the up vector at the origin.
93975
+ * @param radialDistance - Distance of the origin from the planet centre, metres.
93976
+ * @returns `[near, far]` distances along the ray.
93977
+ */
93978
+ private static IntersectSphere;
93979
+ }
93980
+ /**
93981
+ * unity-gaia-terrain-port T20 / T21 (DR-6.4, amended): decides the cloud tier from what a tier saves, not from the whole frame.
93982
+ * Frame times are averaged over windows of CLOUD_TIER_WINDOW_FRAMES frames. A second steady window over CLOUD_TIER_BUDGET_MS steps
93983
+ * down one tier on trial; if the next window is not at least CLOUD_TIER_MINIMUM_SAVING faster, the clouds were not what made the frame
93984
+ * slow, so the previous tier comes back and the tier stays there for the scene. A step that saves time stays, and a later slow
93985
+ * window may try the next tier. The tier never goes above the starting tier, and clouds are never switched off.
93986
+ */
93987
+ class VolumetricCloudsTier {
93988
+ /** The tier now drawn. */
93989
+ tier: number;
93990
+ /** True once a trial step saved nothing: the tier no longer changes. */
93991
+ isSettled: boolean;
93992
+ private windowMilliseconds;
93993
+ private windowFrames;
93994
+ /** The mean frame time of the window before the step on trial, or 0 when no step is on trial. */
93995
+ private meanBeforeStep;
93996
+ /** The previous window's mean frame time, or 0 before the first window. */
93997
+ private previousMean;
93998
+ /**
93999
+ * Starts tracking at a tier.
94000
+ * @param startTier - The starting tier (VolumetricCloudsMath.StartTier).
94001
+ */
94002
+ constructor(startTier: number);
94003
+ /**
94004
+ * Adds one frame.
94005
+ * @param frameMilliseconds - The frame's duration (engine.getDeltaTime()).
94006
+ * @returns True when this frame closed a window that changed the tier (a trial step down, or the restore of one).
94007
+ */
94008
+ addFrame(frameMilliseconds: number): boolean;
94009
+ }
94010
+ /**
94011
+ * unity-gaia-terrain-port T19 / T20 (D16): the URP volumetric clouds (`urp.clouds`) drawn in the browser. One fragment pass marches
94012
+ * the clouds into a half-float target at the authored resolution scale, limited by the camera depth copy, and a full-screen mesh
94013
+ * composites them as the first transparent of the main rendering group, so water draws over the clouds and terrain hides them.
94014
+ * A temporal pass reprojects last frame's clouds and blends them in (`temporalaccumulationfactor`), and the march settings step
94015
+ * down a tier when frames run slow (DR-6.4).
94016
+ * One instance per scene, on `scene._tkVolumetricClouds`. Cloud shadows on the ground and the clouds' own ambient probe are not
94017
+ * carried (the export reports it).
94018
+ */
94019
+ class VolumetricClouds {
94020
+ /** The composite mesh's name. */
94021
+ static readonly MeshName: string;
94022
+ /**
94023
+ * Creates the scene's clouds when the export carries a `urp.clouds` block and the engine can render half-float targets.
94024
+ * @param scene - The scene being loaded.
94025
+ * @param metadata - The scene metadata.
94026
+ * @param root - The scene's root url, which the noise urls are relative to.
94027
+ * @returns The clouds, or null when there are none to draw.
94028
+ */
94029
+ static TryCreate(scene: BABYLON.Scene, metadata: unknown, root: string): TOOLKIT.VolumetricClouds;
94030
+ /**
94031
+ * The scene's clouds.
94032
+ * @param scene - The scene.
94033
+ * @returns The live clouds, or null.
94034
+ */
94035
+ static Get(scene: BABYLON.Scene): TOOLKIT.VolumetricClouds;
94036
+ /** The scene the clouds draw in. */
94037
+ readonly scene: BABYLON.Scene;
94038
+ /** The exported `urp.clouds` block. */
94039
+ readonly block: TOOLKIT.IUrpCloudsBlock;
94040
+ /** True once disposed. */
94041
+ disposed: boolean;
94042
+ /** The tier now drawn (DR-6.4). */
94043
+ tier: number;
94044
+ private readonly sky;
94045
+ private readonly root;
94046
+ private readonly isLocal;
94047
+ /** True when the live sky draws aerial perspective, so the march hazes the clouds at their distance (`CLOUD_AERIAL`). */
94048
+ private hasAerial;
94049
+ /** Bound to `apLut` until the sky's aerial perspective exists (a 1 x 1 x 1 black layer). */
94050
+ private placeholderAerial;
94051
+ private readonly planetRadius;
94052
+ private readonly planetCenter;
94053
+ private readonly scatteringTint;
94054
+ private settings;
94055
+ private worleyTexture;
94056
+ private erosionTexture;
94057
+ private curveTexture;
94058
+ private placeholderDepth;
94059
+ private marchTarget;
94060
+ private renderer;
94061
+ private marchPass;
94062
+ private temporalPass;
94063
+ /** Ping-pong history at cloud resolution: the temporal pass reads one and writes the other. */
94064
+ private readonly historyTargets;
94065
+ private historyIndex;
94066
+ private hasHistory;
94067
+ private compositeMesh;
94068
+ private compositeMaterial;
94069
+ private isReady;
94070
+ private isPending;
94071
+ private preExposure;
94072
+ private preExposureBinding;
94073
+ private frameSeed;
94074
+ private readonly windOffset;
94075
+ private verticalShapeOffset;
94076
+ private verticalErosionOffset;
94077
+ private sceneDepth;
94078
+ private beforeRenderObserver;
94079
+ private afterRenderObserver;
94080
+ private tierTracker;
94081
+ private targetWidth;
94082
+ private targetHeight;
94083
+ private lastCamera;
94084
+ private sunLight;
94085
+ private ambientSource;
94086
+ private ambientCaptureCount;
94087
+ private readonly previousEye;
94088
+ private readonly currentEye;
94089
+ private hasPreviousEye;
94090
+ private beforeTargetsObserver;
94091
+ private afterTargetsObserver;
94092
+ private disposeObserver;
94093
+ private readonly mirror;
94094
+ private readonly inverseViewProjection;
94095
+ /** Last frame's view-projection (Babylon space), for the temporal reprojection. */
94096
+ private readonly previousViewProjection;
94097
+ /** Last frame's view-projection taking Unity-space points, bound to the temporal pass. */
94098
+ private readonly previousViewProjectionUnity;
94099
+ private readonly sunDirection;
94100
+ private readonly cameraForward;
94101
+ /** The camera's local forward axis: +Z, or -Z in a right-handed scene. */
94102
+ private readonly localForward;
94103
+ private readonly ambientTop;
94104
+ private readonly ambientBottom;
94105
+ /**
94106
+ * Builds the passes and starts loading the noise. The scene's loading is held until both noise volumes are uploaded and every
94107
+ * shader compiled, so the first frame has clouds and no compile follows the reveal.
94108
+ * @param scene - The scene.
94109
+ * @param block - The `urp.clouds` block.
94110
+ * @param sky - The `urp.sky` block (planet), or null.
94111
+ * @param root - The scene's root url.
94112
+ */
94113
+ private constructor();
94114
+ /** Releases every target, texture, mesh and observer, and the scene's loading if it is still held. */
94115
+ dispose(): void;
94116
+ /** Creates the curve texture, the march target and pass, and the composite mesh. */
94117
+ private createPasses;
94118
+ /**
94119
+ * One half-float RGBA target at cloud resolution, sampled bilinearly and clamped.
94120
+ * @param name - Target name.
94121
+ * @param textureType - Half float, or float where half-float targets cannot render.
94122
+ * @returns The target.
94123
+ */
94124
+ private createCloudTarget;
94125
+ /**
94126
+ * The 64 x 1 half-float curve texture (density, erosion, ambient occlusion), sampled with a repeating bilinear sampler as
94127
+ * Unity's `s_linear_repeat_sampler` does.
94128
+ * @returns The texture.
94129
+ */
94130
+ private createCurveTexture;
94131
+ /**
94132
+ * The composite: a clip-space quad drawn as the first transparent of the default rendering group, blending
94133
+ * `scene x transmittance + scattering`. It is hidden while render targets (probes, reflections) draw.
94134
+ * @param language - The shader language of the engine.
94135
+ */
94136
+ private createCompositeMesh;
94137
+ /**
94138
+ * Loads both noise sidecars into wrapping single-channel 3D textures.
94139
+ * @returns True when both loaded. On a failure one warning prints and the clouds do not draw (the sky still does).
94140
+ */
94141
+ private loadNoise;
94142
+ /**
94143
+ * One noise volume: `size³` bytes, x fastest, then y, then slice, as CloudExportMath.FlipbookToVolume wrote them.
94144
+ * @param name - Texture name.
94145
+ * @param buffer - The sidecar bytes.
94146
+ * @param size - Volume edge in texels.
94147
+ * @returns The texture, or null (with one warning) when the file has the wrong length.
94148
+ */
94149
+ private createNoiseTexture;
94150
+ /** Polls until the noise is uploaded and every shader compiled, then starts drawing and releases the scene's loading. */
94151
+ private waitUntilReady;
94152
+ /** Lets the scene finish loading (once). */
94153
+ private releasePending;
94154
+ /**
94155
+ * Advances the wind, sizes the targets, marches the clouds and blends in the reprojected history. The composite then reads
94156
+ * the new history (or the march itself when the accumulation factor is off, as Unity's `denoiseClouds`).
94157
+ */
94158
+ private render;
94159
+ /**
94160
+ * True when the colour buffer holds display-encoded values: a non-parity scene whose image processing runs in the materials
94161
+ * (the sky encodes for display and the fog pass decodes the same way, HdrpPhysicallyBasedSky.encodesForDisplay).
94162
+ * @returns True to encode the composite.
94163
+ */
94164
+ private isDisplayEncoded;
94165
+ /**
94166
+ * Resets the temporal history on the first frame, a camera switch or a cut (a move above CLOUD_CAMERA_CUT_METERS in one frame).
94167
+ * @param camera - The active camera.
94168
+ */
94169
+ private trackCamera;
94170
+ /**
94171
+ * DR-6.4: one frame into the tier window; a slow window steps the clouds down one tier, resizes the targets once and reports it.
94172
+ */
94173
+ private updateTier;
94174
+ /** Reports once each authored value the starting tier lowers (tier 0 holds the browser ceiling). */
94175
+ private reportLoweredSettings;
94176
+ /**
94177
+ * Accumulates the wind offsets like VolumetricCloudsURP: kilometres per hour along the global orientation, wrapped.
94178
+ * @param deltaSeconds - Seconds since the last frame.
94179
+ */
94180
+ private advanceWind;
94181
+ /** Resizes the cloud targets (once) when the render size or the tier's resolution scale changed; the history restarts. */
94182
+ private resizeTargets;
94183
+ /**
94184
+ * Sets the cloud target size: the render size times the tier's resolution scale, at least 1 pixel.
94185
+ * @returns True when the size changed.
94186
+ */
94187
+ private updateTargetSize;
94188
+ /**
94189
+ * Binds the march uniforms. Each vec4 packs (VolumetricCloudsURP.UpdateMaterialProperties):
94190
+ * cloudEye = camera position · cloudForward = (camera forward, x mirror sign) · cloudCamera = (far plane, depth copy bound, frame seed,
94191
+ * pre-exposure) · cloudPlanet = (planet centre, radius) · cloudLayer = (bottom radius, top radius, largest step, primary steps)
94192
+ * · cloudSteps = (long ray multiplier, light steps, fade start, fade distance) · cloudShape = (shape scale, shape factor,
94193
+ * erosion scale, erosion factor) · cloudDetail = (erosion occlusion, micro erosion scale, micro erosion factor, density)
94194
+ * · cloudShapeOffset = (offset x, offset z, offset y, altitude distortion) · cloudWind = (wind direction, wind offset)
94195
+ * · cloudWindSpeed = (shape speed, erosion speed, vertical shape offset, vertical erosion offset) · cloudCoverage = (variation,
94196
+ * inverse pattern size, gap amount) · cloudScattering = (multi scattering, powder) · cloudTint · cloudSunDirection (toward the
94197
+ * sun) · cloudSunColor · cloudAmbientTop / Bottom. Positions and directions are mirrored into Unity's space.
94198
+ * @param effect - The march effect.
94199
+ */
94200
+ private bindMarch;
94201
+ /**
94202
+ * The sun and ambient terms: the first interacting directional light's colour (already attenuated by the sky) times its
94203
+ * intensity, the sky's sun scale and the sun dimmer, and the sky's ambient probe evaluated up and down times the probe dimmer.
94204
+ * @param effect - The march effect.
94205
+ * @param mirrorX - -1 in a right-handed scene, else 1.
94206
+ */
94207
+ private bindLighting;
94208
+ /**
94209
+ * Binds the live sky's aerial perspective (its froxel LUT, camera and atmosphere uniforms) for the haze at cloud distance.
94210
+ * Until the sky has built the LUT (its first frames) the placeholder is bound and the haze is skipped.
94211
+ * @param effect - The march effect.
94212
+ */
94213
+ private bindAerial;
94214
+ /**
94215
+ * The sun: the first interacting directional light, looked up again only when the cached one is gone or switched off. Its
94216
+ * world direction (parent rotation applied) is written to `sunDirection` without allocating.
94217
+ * @returns The sun, or null when the scene has no enabled directional light.
94218
+ */
94219
+ private resolveSun;
94220
+ /**
94221
+ * Re-evaluates the ambient up and down only when its source changed (the live sky captured again, or a new environment), so
94222
+ * the per-frame bind does not allocate: the live sky's ambient probe, else the environment's polynomial, else the scene's
94223
+ * ambient colour.
94224
+ */
94225
+ private refreshAmbient;
94226
+ /**
94227
+ * Binds the temporal pass: this frame's march, last frame's history and view-projection (into Unity's space), and
94228
+ * `cloudCamera` = (far plane, depth copy bound, history valid, accumulation factor).
94229
+ * @param effect - The temporal effect.
94230
+ */
94231
+ private bindTemporal;
94232
+ /**
94233
+ * Unity hands the shader `white - tint x 0.75` through Material.SetColor, which linearises it.
94234
+ * @param tint - The authored scattering tint (sRGB components).
94235
+ * @returns The linear extinction tint.
94236
+ */
94237
+ private static LinearScatteringTint;
94238
+ /**
94239
+ * The canvas width in CSS pixels (the render width when there is no canvas).
94240
+ * @param scene - The scene.
94241
+ * @returns The width.
94242
+ */
94243
+ private static CanvasCssWidth;
94244
+ }
94245
+ }
94246
+ declare namespace TOOLKIT {
94247
+ /**
94248
+ * unity-gaia-terrain-port T19 (D16): the GLSL and WGSL sources of the volumetric clouds - a line-for-line fragment port of the
94249
+ * cloud march (`TraceVolumetricRay`, `EvaluateCloudProperties`, the two-octave light march `EvaluateSunTransmittance`) and of the
94250
+ * combine pass. Every shader is registered in `ShaderStore` (GLSL) and `ShaderStoreWGSL` (WGSL) as twins.
94251
+ * No `;` inside `//` comments of a shader string, no sampler function parameters, WGSL samplers at module scope.
94252
+ * Defines: `CLOUD_LOCAL` (the camera flies through the layer, Unity's `_LOCAL_VOLUMETRIC_CLOUDS`), `CLOUD_MICRO_EROSION`, and
94253
+ * `CLOUD_AERIAL`: the sky's aerial perspective at the mean cloud distance, as Unity's clouds combine pass with
94254
+ * `PHYSICALLY_BASED_SKY` (VolumetricClouds.shader, `EvaluateAtmosphericScattering` at cloud depth). It reuses the fog pass's
94255
+ * shared function (HdrpFogPass.AerialPerspectiveGlsl / Wgsl), so clouds take the in-scatter and extinction terrain takes at
94256
+ * the same distance.
94257
+ */
94258
+ class VolumetricCloudsShaders {
94259
+ /** The march pass: scattering in rgb, transmittance in alpha, one fragment per cloud-target pixel. */
94260
+ static readonly MarchName: string;
94261
+ /** The full-screen composite drawn as the first transparent. */
94262
+ static readonly CompositeName: string;
94263
+ /** The temporal pass: reprojects last frame's clouds and blends them in (pass 3, Temporal Denoising). */
94264
+ static readonly TemporalName: string;
94265
+ /** Every vec4 / mat4 uniform of the temporal pass. */
94266
+ static readonly TemporalUniforms: string[];
94267
+ /** The samplers of the temporal pass. */
94268
+ static readonly TemporalSamplers: string[];
94269
+ /** Every vec4 / mat4 uniform of the march pass, in declaration order. */
94270
+ static readonly MarchUniforms: string[];
94271
+ /** The samplers of the march pass. */
94272
+ static readonly MarchSamplers: string[];
94273
+ /** The extra sampler of the march when `CLOUD_AERIAL` is on: the live sky's aerial perspective froxels. */
94274
+ static readonly AerialSampler: string;
94275
+ /** The extra uniform of the march when `CLOUD_AERIAL` is on: (camera - planet centre, 1 when the LUT is bound). */
94276
+ static readonly AerialCameraUniform: string;
94277
+ private static registered;
94278
+ /** Registers every cloud shader once (GLSL in ShadersStore, WGSL in ShadersStoreWGSL). */
94279
+ static Register(): void;
94280
+ /**
94281
+ * Every source, GLSL then WGSL (tests scan them for `;` inside `//` comments).
94282
+ * @returns The shader strings.
94283
+ */
94284
+ static AllSources(): string[];
94285
+ /** The march pass uniforms. The packing of each vec4 is documented on `VolumetricClouds.bindMarch`. */
94286
+ private static GlslMarchUniforms;
94287
+ /** Constants of VolumetricCloudsUtilities.hlsl. */
94288
+ private static GlslConstants;
94289
+ /** Ray and shell geometry: sphere intersections in planet space (`cloudPlanet.xyz` is the planet centre, `.w` its radius). */
94290
+ private static GlslGeometry;
94291
+ /** Cloud density: coverage pattern, shape and erosion noise, the curve texture (`EvaluateCloudProperties`). */
94292
+ private static GlslDensity;
94293
+ /** Lighting: phase function, powder effect and the light march toward the sun (`EvaluateSunTransmittance`, `EvaluateCloud`). */
94294
+ private static GlslLighting;
94295
+ /** The aerial perspective declarations and functions of the march (only under `CLOUD_AERIAL`). */
94296
+ private static GlslAerial;
94297
+ /** The march pass (`frag` of pass 0 and `TraceVolumetricRay`). */
94298
+ private static GlslMarch;
94299
+ /** A clip-space quad: positions are already in clip space, the uv follows them. */
94300
+ private static GlslCompositeVertex;
94301
+ /**
94302
+ * Pass 1 (Combine): blending gives scene x transmittance + scattering (premultiplied, alpha = 1 - transmittance). When the
94303
+ * colour buffer holds display-encoded values (`cloudDisplayEncoded` = 1: a non-parity scene whose image processing runs in
94304
+ * the materials, as the sky and fog pass assume), the wanted `encode(L x T + S)` is not linear in the encoded scene `d`,
94305
+ * so the blend uses the straight line through its two ends: `encode(S)` at d = 0 and `encode(T + S)` at d = 1, that is
94306
+ * `encode(S) + d x (encode(T + S) - encode(S))` (the slope from the scattering's luminance). It is exact where the cloud
94307
+ * is clear or opaque and within a few hundredths over a bright sky, where a plain `T^(1/gamma)` overshoots cloud edges.
94308
+ */
94309
+ private static GlslCompositeFragment;
94310
+ /**
94311
+ * Pass 3 (Temporal Denoising): the history is reprojected with last frame's view-projection at the distance where the ray
94312
+ * enters the cloud layer (or the scene depth, when nearer), clamped to the current colour's 5-tap box and blended in by
94313
+ * the accumulation factor, faded by the reprojection velocity. Transmittance stays the current frame's, as in Unity.
94314
+ * `cloudCamera` = (far plane, depth copy bound, history valid, accumulation factor), `cloudTexel` = (1 / width, 1 / height).
94315
+ */
94316
+ private static GlslTemporal;
94317
+ /** The march pass uniforms (WGSL twin of GlslMarchUniforms). */
94318
+ private static WgslMarchUniforms;
94319
+ private static WgslConstants;
94320
+ private static WgslGeometry;
94321
+ private static WgslDensity;
94322
+ private static WgslLighting;
94323
+ /** WGSL twin of GlslAerial. */
94324
+ private static WgslAerial;
94325
+ private static WgslMarch;
94326
+ private static WgslCompositeVertex;
94327
+ private static WgslCompositeFragment;
94328
+ private static WgslTemporal;
94329
+ }
94330
+ }
93299
94331
  /** Babylon Toolkit Namespace */
93300
94332
  declare namespace TOOLKIT {
93301
94333
  /**