incanto 0.74.0 → 0.76.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/bin/incanto-multiplay.mjs +52 -4
- package/dist/2d.d.ts +83 -7
- package/dist/2d.js +4 -3
- package/dist/3d.d.ts +861 -167
- package/dist/3d.js +6 -6
- package/dist/{agent8-CHTT4unP.js → agent8-B-bh3n0X.js} +1 -1
- package/dist/{audio-player-BOrk4eQx.d.ts → audio-player-BRo2uvG6.d.ts} +23 -2
- package/dist/{behavior-J1cmVah0.d.ts → behavior-B_245qRy.d.ts} +15 -1
- package/dist/{create-game-ssvGvP7W.js → create-game-BMIPKrQW.js} +84 -8
- package/dist/{create-game-BAiA-FjP.js → create-game-Dai5vfVu.js} +80 -11
- package/dist/debug.d.ts +1 -1
- package/dist/{editor-switch-CFU9mCec.d.ts → editor-switch-Bzt0GzVp.d.ts} +13 -3
- package/dist/editor.js +1600 -1529
- package/dist/env.d.ts +1 -1
- package/dist/{environment-presets-BkqlWewf.js → environment-presets-e_9YCnGu.js} +2361 -104
- package/dist/{gameplay-Bxe1sMVT.js → gameplay-Bfff_beb.js} +10919 -6798
- package/dist/gameplay.d.ts +573 -31
- package/dist/gameplay.js +3 -2
- package/dist/index.d.ts +150 -6
- package/dist/index.js +6 -6
- package/dist/{loader-BAeWMYfF.d.ts → loader-CbkVdXL8.d.ts} +2 -2
- package/dist/net.d.ts +2 -2
- package/dist/net.js +2 -2
- package/dist/{physics-2d-C-SfvjzH.js → physics-2d-Tuf5LAyq.js} +250 -31
- package/dist/{physics-3d-rOzeg890.js → physics-3d-C5MOujfQ.js} +673 -51
- package/dist/{picking-BMV34Pjl.js → picking-DIwE48sU.js} +10 -7
- package/dist/{save-slots-CEUGeLuB.js → pose-ByFB_J3O.js} +217 -11
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/{register-DRQyZKGU.js → register-7E3P1gz6.js} +191 -430
- package/dist/{register-CjociOtt.js → register-B768Qedj.js} +596 -2
- package/dist/{replay-B6BbgGM_.js → replay-DrqQ6dZj.js} +133 -18
- package/dist/{replay-wZK5Ok5c.d.ts → replay-W5nCw_cU.d.ts} +21 -2
- package/dist/{rng-Bb-IutXB.d.ts → rng-BsXZg3D6.d.ts} +7 -0
- package/dist/{split-screen-BxZ5rBe7.js → split-screen-B-dIcQsQ.js} +10 -5
- package/dist/{split-screen-D6sx8z3Z.d.ts → split-screen-CiLJf2-C.d.ts} +3 -3
- package/dist/{sprite-animation-Bz3DHD_4.js → sprite-animation-SQa5gIu2.js} +8 -6
- package/dist/{src-CqtvYtSN.js → src-D823V07k.js} +1 -1
- package/dist/{test-CEl0y2Sw.js → test-CVbxnXlv.js} +487 -82
- package/dist/test.d.ts +90 -12
- package/dist/test.js +2 -2
- package/dist/vite.js +34 -5
- package/editor/assets/{agent8-BlzturGi.js → agent8-DA-I5qhv.js} +1 -1
- package/editor/assets/{debug-BMUi8usj.js → debug-99tEPoGm.js} +1 -1
- package/editor/assets/index-Db74LZY-.js +11579 -0
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +1639 -280
- package/skills/incanto-3d-character.md +383 -20
- package/skills/incanto-audio.md +24 -2
- package/skills/incanto-building-2d-games.md +21 -2
- package/skills/incanto-building-3d-games.md +38 -3
- package/skills/incanto-editor.md +29 -8
- package/skills/incanto-environment.md +257 -14
- package/skills/incanto-game-feel.md +60 -1
- package/skills/incanto-gameplay-behaviors.md +668 -20
- package/skills/incanto-hud.md +116 -0
- package/skills/incanto-multiplayer.md +141 -2
- package/skills/incanto-node-reference.md +398 -16
- package/skills/incanto-performance.md +32 -0
- package/skills/incanto-physics-and-input.md +241 -13
- package/skills/incanto-playtesting.md +2 -2
- package/skills/incanto-save-slots.md +61 -2
- package/skills/incanto-scene-json-authoring.md +13 -0
- package/skills/incanto-verifying-your-game.md +86 -3
- package/templates-app/beacon-isle-3d/PROJECT/Status.md +12 -0
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/beacon-isle-3d/src/game.scene.json +157 -3
- package/templates-app/molehill-2d/PROJECT/Status.md +7 -0
- package/templates-app/molehill-2d/package.json +1 -1
- package/templates-app/molehill-2d/src/game.scene.json +129 -2
- package/templates-app/platformer-2d/PROJECT/Status.md +7 -0
- package/templates-app/platformer-2d/docs/project-2d-rules.md +3 -2
- package/templates-app/platformer-2d/package.json +1 -1
- package/templates-app/platformer-2d/src/behaviors.ts +40 -26
- package/templates-app/platformer-2d/src/game.scene.json +144 -2
- package/templates-app/platformer-2d/verify.ts +18 -1
- package/templates-app/star-survivor/PROJECT/Status.md +7 -0
- package/templates-app/star-survivor/package.json +1 -1
- package/templates-app/star-survivor/src/behaviors.ts +9 -8
- package/templates-app/star-survivor/src/game.scene.json +142 -4
- package/templates-app/star-survivor/verify.ts +13 -0
- package/templates-app/tps-3d/PROJECT/Status.md +6 -0
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/tps-3d/src/game.scene.json +71 -10
- package/templates-app/village-quest-3d/PROJECT/Status.md +7 -0
- package/templates-app/village-quest-3d/package.json +1 -1
- package/templates-app/village-quest-3d/src/behaviors.ts +8 -16
- package/templates-app/village-quest-3d/src/grove.scene.json +121 -5
- package/templates-app/village-quest-3d/src/village.scene.json +126 -2
- package/templates-app/village-quest-3d/verify.ts +52 -2
- package/editor/assets/index-CrUCQoaB.js +0 -11046
package/dist/3d.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { c as showBootFailure, i as ParticleSim, o as ParticleView, r as SpatialPose, s as isWebGLAvailable } from "./audio-player-
|
|
2
|
-
import { D as QualityCaps, P as Scene$1, S as Scheduler, T as RendererStats, b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, w as GameStats, x as EngineOptions } from "./behavior-
|
|
1
|
+
import { c as showBootFailure, i as ParticleSim, o as ParticleView, r as SpatialPose, s as isWebGLAvailable } from "./audio-player-BRo2uvG6.js";
|
|
2
|
+
import { D as QualityCaps, P as Scene$1, S as Scheduler, T as RendererStats, b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, w as GameStats, x as EngineOptions } from "./behavior-B_245qRy.js";
|
|
3
3
|
import { t as DiagnosticSink } from "./diagnostics-Cu85N3tL.js";
|
|
4
|
-
import { a as SceneJson$1, s as JsonObject } from "./rng-
|
|
5
|
-
import { t as EditorSwitchOptions } from "./editor-switch-
|
|
4
|
+
import { a as SceneJson$1, s as JsonObject } from "./rng-BsXZg3D6.js";
|
|
5
|
+
import { t as EditorSwitchOptions } from "./editor-switch-Bzt0GzVp.js";
|
|
6
6
|
import { a as GridCell, c as diffText, d as frameText, i as FrameStatsOptions, l as frameSignature, n as FrameSignature, o as SIGNATURE_GRID, r as FrameStats, s as diffSignatures, t as FrameDiff, u as frameStats } from "./frame-report-DNxDAb1w.js";
|
|
7
|
-
import { t as LoadSceneOptions } from "./loader-
|
|
7
|
+
import { t as LoadSceneOptions } from "./loader-CbkVdXL8.js";
|
|
8
8
|
import { n as PathGrid } from "./pathfinding-_fGrCFmH.js";
|
|
9
|
-
import { AnimationClip, AnimationMixer, BufferGeometry, Color, DirectionalLight, Group, InstancedMesh, Mesh, MeshPhysicalMaterial, Object3D, PerspectiveCamera, Scene, ShaderMaterial, Texture, Vector3, WebGLRenderer } from "three";
|
|
9
|
+
import { AnimationClip, AnimationMixer, BufferGeometry, Color, DataTexture, DirectionalLight, Group, InstancedMesh, Mesh, MeshPhysicalMaterial, Object3D, PerspectiveCamera, Quaternion, Scene, ShaderMaterial, Texture, Vector3, WebGLRenderer } from "three";
|
|
10
10
|
import { VRM } from "@pixiv/three-vrm";
|
|
11
11
|
import { Sky } from "three/examples/jsm/objects/Sky.js";
|
|
12
12
|
import * as RapierNs from "@dimforge/rapier3d-compat";
|
|
@@ -451,6 +451,17 @@ declare class RigidBody3D extends PhysicsBody3D {
|
|
|
451
451
|
friction: number;
|
|
452
452
|
restitution: number;
|
|
453
453
|
/**
|
|
454
|
+
* How much a `Water3D` lifts this body: `0` (default) = it falls through
|
|
455
|
+
* water like air, `1` = water's own upthrust — the submerged part of the
|
|
456
|
+
* collider's volume, at 1000 kg/m³. So `mass` against the collider decides:
|
|
457
|
+
* a 1 m³ crate at 200 kg floats a fifth under, at 3000 kg it sinks, and a
|
|
458
|
+
* heavier hull sits deeper. Eight sample points across the collider give a
|
|
459
|
+
* tilted hull a righting moment, and the water's `drag` slows it. A body with
|
|
460
|
+
* a `CharacterController3D` under it is never lifted here — the swim spring
|
|
461
|
+
* owns that one.
|
|
462
|
+
*/
|
|
463
|
+
buoyancy: number;
|
|
464
|
+
/**
|
|
454
465
|
* Drag, per second: velocity decays by `e^(-linearDamping·t)`. `0` = none.
|
|
455
466
|
* A body flying through nothing keeps its speed forever otherwise.
|
|
456
467
|
*/
|
|
@@ -494,6 +505,16 @@ declare class CharacterBody3D extends PhysicsBody3D {
|
|
|
494
505
|
/** m/s, y-up (up = +y). */
|
|
495
506
|
velocity: number[];
|
|
496
507
|
/**
|
|
508
|
+
* The mass this body pushes dynamic bodies with, in kg. Rapier's character
|
|
509
|
+
* controller treats every dynamic body as an OBSTACLE — a character walks
|
|
510
|
+
* around things — so a beam on a `Patrol` slid up to the player and stopped
|
|
511
|
+
* dead against them, forever. A piston, a sweeping arm, a moving wall or a
|
|
512
|
+
* bruiser enemy is a thing that shoves: give it a mass and it pushes what it
|
|
513
|
+
* meets, and the harder the heavier. `0` (the default) keeps every scene as
|
|
514
|
+
* it was.
|
|
515
|
+
*/
|
|
516
|
+
pushes: number;
|
|
517
|
+
/**
|
|
497
518
|
* Hold the capsule against the surface while it moves, so walking down a
|
|
498
519
|
* slope does not become a series of small falls.
|
|
499
520
|
*
|
|
@@ -577,6 +598,94 @@ declare class CharacterBody3D extends PhysicsBody3D {
|
|
|
577
598
|
isOnFloor(): boolean;
|
|
578
599
|
}
|
|
579
600
|
//#endregion
|
|
601
|
+
//#region src/3d/nodes/vehicle-3d.d.ts
|
|
602
|
+
/** One wheel, as authored in `wheels`. */
|
|
603
|
+
interface WheelSpec {
|
|
604
|
+
/** Where the spring hangs from, in the CHASSIS's frame (m). */
|
|
605
|
+
position: [number, number, number];
|
|
606
|
+
/** Tyre radius (m). */
|
|
607
|
+
radius: number;
|
|
608
|
+
/** Spring length at rest (m) — the wheel hangs this far below its mount, less the load. */
|
|
609
|
+
rest: number;
|
|
610
|
+
/** Turns with the steer. */
|
|
611
|
+
steer: boolean;
|
|
612
|
+
/** Takes the engine force. */
|
|
613
|
+
drive: boolean;
|
|
614
|
+
}
|
|
615
|
+
/** What one wheel is doing this step. */
|
|
616
|
+
interface WheelState {
|
|
617
|
+
/** The spring found ground. */
|
|
618
|
+
contact: boolean;
|
|
619
|
+
/** Current spring length (m) — the wheel's centre is this far below its mount. */
|
|
620
|
+
suspension: number;
|
|
621
|
+
/** Total roll, radians. */
|
|
622
|
+
rotation: number;
|
|
623
|
+
/** Current steer, radians. */
|
|
624
|
+
steering: number;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* A car in one node — Rapier's raycast vehicle under a `RigidBody3D` chassis.
|
|
628
|
+
*
|
|
629
|
+
* ```json
|
|
630
|
+
* { "name": "Car", "type": "RigidBody3D",
|
|
631
|
+
* "props": { "mass": 800, "collider": { "shape": "box", "size": [1.8, 0.6, 4] } },
|
|
632
|
+
* "children": [
|
|
633
|
+
* { "name": "Drive", "type": "Vehicle3D", "props": { "wheels": [
|
|
634
|
+
* { "position": [-0.8, -0.1, 1.4], "steer": true },
|
|
635
|
+
* { "position": [ 0.8, -0.1, 1.4], "steer": true },
|
|
636
|
+
* { "position": [-0.8, -0.1, -1.4], "drive": true },
|
|
637
|
+
* { "position": [ 0.8, -0.1, -1.4], "drive": true } ] } },
|
|
638
|
+
* { "name": "Wheel0", "type": "Node3D", "props": { "position": [-0.8, -0.1, 1.4] },
|
|
639
|
+
* "children": [ { "name": "Hub", "type": "Node3D", "children": [ …the tyre mesh… ] } ] }
|
|
640
|
+
* ] }
|
|
641
|
+
* ```
|
|
642
|
+
*
|
|
643
|
+
* The wheels are springs that never touch anything (a ray each), so a car
|
|
644
|
+
* cannot catch a kerb on a wheel body or disagree with its axle; the throttle,
|
|
645
|
+
* steer and brake come from the `move` vector and the `brake` button (or from
|
|
646
|
+
* code, with `moveAction: ""`). Forward is +z, the +Z-forward rule. A child
|
|
647
|
+
* named `Wheel<i>` is posed every step — it hangs on its spring and turns to
|
|
648
|
+
* steer — and its child `Hub` spins as the wheel rolls.
|
|
649
|
+
*/
|
|
650
|
+
declare class Vehicle3D extends Node3D {
|
|
651
|
+
static override readonly typeName: string;
|
|
652
|
+
static override readonly props: PropSchema;
|
|
653
|
+
wheels: WheelSpec[];
|
|
654
|
+
suspensionStiffness: number;
|
|
655
|
+
suspensionCompression: number;
|
|
656
|
+
suspensionRelaxation: number;
|
|
657
|
+
maxTravel: number;
|
|
658
|
+
friction: number;
|
|
659
|
+
sideFriction: number;
|
|
660
|
+
maxSteerDeg: number;
|
|
661
|
+
engineForce: number;
|
|
662
|
+
brakeForce: number;
|
|
663
|
+
moveAction: string;
|
|
664
|
+
brakeAction: string;
|
|
665
|
+
enabled: boolean;
|
|
666
|
+
/** Live inputs, −1..1 (throttle, steer) and 0..1 (brake) — the actions write these, or your code does. */
|
|
667
|
+
throttle: number;
|
|
668
|
+
steer: number;
|
|
669
|
+
brake: number;
|
|
670
|
+
/** Forward speed, m/s (negative in reverse). */
|
|
671
|
+
speed: number;
|
|
672
|
+
/** @internal Written by the physics adapter each step. */
|
|
673
|
+
_states: WheelState[];
|
|
674
|
+
private reportedActions;
|
|
675
|
+
/** What wheel `i` is doing. */
|
|
676
|
+
wheel(i: number): WheelState;
|
|
677
|
+
/** The wheels with every default filled in. */
|
|
678
|
+
specs(): WheelSpec[];
|
|
679
|
+
get body(): RigidBody3D;
|
|
680
|
+
override onEnterTree(): void;
|
|
681
|
+
override onExitTree(): void;
|
|
682
|
+
override fixedUpdate(dt: number): void;
|
|
683
|
+
/** `Wheel<i>` hangs on its spring and turns to steer; its `Hub` spins. */
|
|
684
|
+
private poseWheels;
|
|
685
|
+
/** Full lock, radians. */
|
|
686
|
+
get maxSteer(): number;
|
|
687
|
+
}
|
|
688
|
+
//#endregion
|
|
580
689
|
//#region src/3d/physics/physics-3d.d.ts
|
|
581
690
|
type Rapier = typeof RapierNs;
|
|
582
691
|
interface Physics3DOptions {
|
|
@@ -616,6 +725,11 @@ declare class Physics3D {
|
|
|
616
725
|
private readonly warnedNoCollider;
|
|
617
726
|
private readonly entries;
|
|
618
727
|
private readonly byColliderHandle;
|
|
728
|
+
/** Every Water3D in the tree, rescanned when the structure changes. */
|
|
729
|
+
private readonly waters;
|
|
730
|
+
private watersStale;
|
|
731
|
+
/** Raycast vehicles, one per Vehicle3D in the tree, on their chassis entries. */
|
|
732
|
+
private readonly vehicles;
|
|
619
733
|
private readonly world;
|
|
620
734
|
private readonly events;
|
|
621
735
|
private readonly kcc;
|
|
@@ -639,6 +753,15 @@ declare class Physics3D {
|
|
|
639
753
|
* down to the places where that pair disagrees with a rotated parent.
|
|
640
754
|
*/
|
|
641
755
|
private poseFromTree;
|
|
756
|
+
/**
|
|
757
|
+
* @internal Called by Vehicle3D.fixedUpdate: push the throttle, steer and
|
|
758
|
+
* brake into Rapier's raycast vehicle on the chassis and let it apply the
|
|
759
|
+
* step's forces; read the wheels back. The controller is made on first
|
|
760
|
+
* use and remade if the chassis body was rebuilt.
|
|
761
|
+
*/
|
|
762
|
+
_driveVehicle(node: Vehicle3D, dt: number): void;
|
|
763
|
+
/** @internal The Vehicle3D left the tree: drop its controller. */
|
|
764
|
+
_freeVehicle(node: Vehicle3D): void;
|
|
642
765
|
/** @internal Called by CharacterBody3D.moveAndSlide (during tree fixedUpdate). */
|
|
643
766
|
/**
|
|
644
767
|
* May `candidate` carry `rider`? — see the 2D twin.
|
|
@@ -662,6 +785,28 @@ declare class Physics3D {
|
|
|
662
785
|
private lastRoot;
|
|
663
786
|
private readonly jointSet;
|
|
664
787
|
private readonly joints;
|
|
788
|
+
/** The two bodies each live joint ties, so a departed joint can be unlinked. */
|
|
789
|
+
private readonly jointBodies;
|
|
790
|
+
/** What a hinge's limits/motor were last pushed as, so a write re-applies. */
|
|
791
|
+
private readonly hingeState;
|
|
792
|
+
/** Joints refused at creation (bodies that disagree about the axis) — said once. */
|
|
793
|
+
private readonly refusedJoints;
|
|
794
|
+
/** A rope's or spring's numbers as last made, so a write REMAKES the joint. */
|
|
795
|
+
private readonly tetherState;
|
|
796
|
+
private tetherKey;
|
|
797
|
+
/**
|
|
798
|
+
* Who is jointed to whom, and whether that pair's contacts are on.
|
|
799
|
+
*
|
|
800
|
+
* A joint's own bodies are not the world to the character controller: a
|
|
801
|
+
* body jointed to a character with its contacts off is not an obstacle to
|
|
802
|
+
* its shape-cast (the joint said so, for the contact solver; the cast asks
|
|
803
|
+
* its own question), and a body jointed to it is never its GROUND — a
|
|
804
|
+
* chain hanging from a crane hook was the hook's "moving platform", and the
|
|
805
|
+
* carry dragged the hook along by however far the hook had just moved.
|
|
806
|
+
*/
|
|
807
|
+
private readonly jointed;
|
|
808
|
+
private linkJointed;
|
|
809
|
+
private unlinkJointed;
|
|
665
810
|
/** One fixed body per solid scatter field, carrying a collider per row. */
|
|
666
811
|
private readonly scatterBodies;
|
|
667
812
|
private readonly bodySet;
|
|
@@ -714,15 +859,41 @@ declare class Physics3D {
|
|
|
714
859
|
* meantime. syncBodies runs every step, so the body appears the moment the
|
|
715
860
|
* download lands.
|
|
716
861
|
*/
|
|
862
|
+
/**
|
|
863
|
+
* Lift every buoyant dynamic body by the water it is in — before the solver
|
|
864
|
+
* step, so the impulses are part of this step's motion.
|
|
865
|
+
*
|
|
866
|
+
* `Water3D.heightAt` had answered "so gameplay can float a raft, bob a
|
|
867
|
+
* buoy" since the water shipped, and nothing floated anything but the
|
|
868
|
+
* swimmer: a RigidBody3D dropped into a lake fell through it to the bed,
|
|
869
|
+
* whatever it weighed. This is Archimedes on eight sample points: each
|
|
870
|
+
* octant of the collider is an eighth of its volume, lifted by the water's
|
|
871
|
+
* density times however much of it is under the surface AT THAT POINT, at
|
|
872
|
+
* that point — so a tilted hull's low corners push harder and it rights
|
|
873
|
+
* itself, and a wave under one end rocks it. The water's `drag` then bleeds
|
|
874
|
+
* velocity and spin in proportion to how much is under, which is what stops
|
|
875
|
+
* a pushed crate and lets a bob die out.
|
|
876
|
+
*/
|
|
877
|
+
private applyBuoyancy;
|
|
878
|
+
/** The water whose footprint covers world (x, z), or null. */
|
|
879
|
+
private waterAt;
|
|
717
880
|
private ensureEntry;
|
|
718
881
|
/** Apply a world-space impulse to a dynamic body (character controllers). */
|
|
719
882
|
applyImpulse(node: PhysicsBody3D, impulse: [number, number, number]): void;
|
|
720
883
|
/** Mass the solver actually uses (collider-derived unless overridden). */
|
|
721
884
|
massOf(node: PhysicsBody3D): number;
|
|
885
|
+
/** The solver's rotation of a body, as a quaternion `[x, y, z, w]`. */
|
|
886
|
+
rotationOf(node: PhysicsBody3D): [number, number, number, number];
|
|
722
887
|
/** Current solver velocity (fresher than the node prop mid-step). */
|
|
723
888
|
velocityOf(node: PhysicsBody3D): [number, number, number];
|
|
724
889
|
/** Create newly-arrived joints; tear down departed ones. */
|
|
725
890
|
private syncJoints;
|
|
891
|
+
/**
|
|
892
|
+
* Push a hinge's `limits` and motor to the solver — on creation, and again
|
|
893
|
+
* whenever either changes. Limits and `angle` are this body relative to the
|
|
894
|
+
* target; Rapier measures the other way round, hence the flip.
|
|
895
|
+
*/
|
|
896
|
+
private applyHinge;
|
|
726
897
|
/** Who is currently inside each sensor/body, maintained from the event drain. */
|
|
727
898
|
private readonly overlaps;
|
|
728
899
|
private trackOverlap;
|
|
@@ -835,6 +1006,19 @@ interface CreateGame3DOptions {
|
|
|
835
1006
|
* to development, e.g. `debug: import.meta.env.VITE_INCANTO_DEBUG === '1'`.
|
|
836
1007
|
*/
|
|
837
1008
|
debug?: boolean;
|
|
1009
|
+
/**
|
|
1010
|
+
* Start the frame loop as soon as the game is built (default `true`).
|
|
1011
|
+
*
|
|
1012
|
+
* `false` hands back a game that has not run a single frame: no
|
|
1013
|
+
* `engine.start()`, and no warm-up tick either. Call `game.engine.start()`
|
|
1014
|
+
* when everything that must exist BEFORE the first frame does — a
|
|
1015
|
+
* `NetworkManager`, whose join takes a moment during which every behaviour
|
|
1016
|
+
* would otherwise run the game OFFLINE. The first race built from the
|
|
1017
|
+
* tarball gridded itself to slot 0 in those frames and sent that pose as
|
|
1018
|
+
* its first replicated state, on top of the other player's car. The shader
|
|
1019
|
+
* warm-up still runs; the canvas stays blank until you start.
|
|
1020
|
+
*/
|
|
1021
|
+
autoStart?: boolean;
|
|
838
1022
|
/** @internal Test seam — replaces `document` for the debug overlay. */
|
|
839
1023
|
_debugDoc?: {
|
|
840
1024
|
createElement(tag: string): HTMLElement;
|
|
@@ -1465,6 +1649,16 @@ declare class BoneLookAt3D extends Node3D {
|
|
|
1465
1649
|
private lookedUpFor;
|
|
1466
1650
|
/** 0..1 engage blend — eases in/out so tracking never snaps. */
|
|
1467
1651
|
private engage;
|
|
1652
|
+
/**
|
|
1653
|
+
* How far the head is COMMITTED to the target, 0..1.
|
|
1654
|
+
*
|
|
1655
|
+
* `attachedBone` was a test hook for "did it find the bone"; this is the one
|
|
1656
|
+
* for "is it watching" — the whole observable effect of the node, and it eased
|
|
1657
|
+
* in and out where nothing could read it. A harness asking whether an NPC
|
|
1658
|
+
* tracks the player, and lets go when the player walks behind it, has no other
|
|
1659
|
+
* question to ask.
|
|
1660
|
+
*/
|
|
1661
|
+
get engaged(): number;
|
|
1468
1662
|
/** Test hook. */
|
|
1469
1663
|
get attachedBone(): Object3D | null;
|
|
1470
1664
|
_onRender3D(_ctx: RenderContext3D): void;
|
|
@@ -1482,9 +1676,20 @@ declare class Camera3D extends Node3D {
|
|
|
1482
1676
|
/** A frustum whose planes are the wrong way round draws nothing at all. */
|
|
1483
1677
|
static validateJson(node: Node): void;
|
|
1484
1678
|
fov: number;
|
|
1679
|
+
minHorizontalFov: number;
|
|
1485
1680
|
near: number;
|
|
1486
1681
|
far: number;
|
|
1487
1682
|
current: boolean;
|
|
1683
|
+
/**
|
|
1684
|
+
* Make THIS the scene's camera and no other: the renderer takes the first
|
|
1685
|
+
* camera whose `current` is true in tree order, so setting your own without
|
|
1686
|
+
* clearing the gameplay camera's changed nothing visible. A handler a
|
|
1687
|
+
* connection can name — `triggerEnter → DoorCam.makeCurrent`.
|
|
1688
|
+
*/
|
|
1689
|
+
makeCurrent(blendSeconds?: number | undefined): void;
|
|
1690
|
+
blendSeconds: number;
|
|
1691
|
+
/** @internal `makeCurrent(seconds)` — read once by the renderer's sync. */
|
|
1692
|
+
_blendRequest: number | undefined;
|
|
1488
1693
|
lookAt: string;
|
|
1489
1694
|
/**
|
|
1490
1695
|
* Aim, every frame, whenever `lookAt` names something — see `aimAt`, which
|
|
@@ -1494,6 +1699,15 @@ declare class Camera3D extends Node3D {
|
|
|
1494
1699
|
private warnedLookAt;
|
|
1495
1700
|
override update(_dt: number): void;
|
|
1496
1701
|
protected override _createObject3D(): Object3D;
|
|
1702
|
+
/**
|
|
1703
|
+
* The vertical fov to actually render with at this aspect.
|
|
1704
|
+
*
|
|
1705
|
+
* Plain `fov` unless `minHorizontalFov` asks for more width than the screen
|
|
1706
|
+
* carries, in which case it is widened until it does. Public because a game
|
|
1707
|
+
* that wants to know what it is really showing — a harness, a debug overlay —
|
|
1708
|
+
* could not otherwise ask, and the answer is not the authored number.
|
|
1709
|
+
*/
|
|
1710
|
+
viewFov(aspect: number): number;
|
|
1497
1711
|
override _syncObject3D(): void;
|
|
1498
1712
|
}
|
|
1499
1713
|
//#endregion
|
|
@@ -1502,7 +1716,7 @@ declare class Camera3D extends Node3D {
|
|
|
1502
1716
|
* The states this controller enters, and therefore the only keys its
|
|
1503
1717
|
* `animations` map may carry.
|
|
1504
1718
|
*/
|
|
1505
|
-
declare const MOVEMENT_STATES: readonly ["idle", "walk", "run", "fastRun", "airborne"];
|
|
1719
|
+
declare const MOVEMENT_STATES: readonly ["idle", "walk", "run", "fastRun", "airborne", "swim", "climb", "crouch", "sneak", "dash"];
|
|
1506
1720
|
/** One of {@link MOVEMENT_STATES}. */
|
|
1507
1721
|
type MovementState = (typeof MOVEMENT_STATES)[number];
|
|
1508
1722
|
/**
|
|
@@ -1517,6 +1731,7 @@ declare class CharacterController3D extends Node3D {
|
|
|
1517
1731
|
static override readonly typeName: string;
|
|
1518
1732
|
static override readonly signals: readonly string[];
|
|
1519
1733
|
static override readonly props: PropSchema;
|
|
1734
|
+
enabled: boolean;
|
|
1520
1735
|
view: RigView;
|
|
1521
1736
|
camDistance: number;
|
|
1522
1737
|
eyeHeight: number;
|
|
@@ -1543,6 +1758,60 @@ declare class CharacterController3D extends Node3D {
|
|
|
1543
1758
|
fallGravity: number;
|
|
1544
1759
|
floatHeight: number;
|
|
1545
1760
|
/**
|
|
1761
|
+
* Swimming pace in water too deep to stand in (m/s; `sprint` still
|
|
1762
|
+
* multiplies). `0` turns swimming OFF and the body sinks to the bed, which
|
|
1763
|
+
* is what a drowning pit wants and what every scene got before this.
|
|
1764
|
+
*/
|
|
1765
|
+
swimSpeed: number;
|
|
1766
|
+
/**
|
|
1767
|
+
* How far the body's ORIGIN rides below the surface while swimming (m), or
|
|
1768
|
+
* `null` (the default) to take it from the body: deep enough that the head
|
|
1769
|
+
* rides 15 cm clear and the rest is in the water, which is what treading
|
|
1770
|
+
* water looks like.
|
|
1771
|
+
*
|
|
1772
|
+
* The origin is the middle of the capsule, so a fixed number is only ever
|
|
1773
|
+
* right for one character size. The 0.35 m this used to default to left the
|
|
1774
|
+
* head of a standard 1.68 m rig 0.46 m clear of the surface — a person
|
|
1775
|
+
* floating like a boat, chest and shoulders in the air.
|
|
1776
|
+
*/
|
|
1777
|
+
swimDepth: number | null;
|
|
1778
|
+
/** Held: swim down at `swimSpeed`. Missing from the input map is fine. */
|
|
1779
|
+
diveAction: string;
|
|
1780
|
+
/**
|
|
1781
|
+
* Ladder pace (m/s). A ladder is any `Area3D` in `ladderGroup`: push UP into
|
|
1782
|
+
* it and the body climbs, gravity off, held to the rungs; at the top it
|
|
1783
|
+
* pulls itself onto the ledge, down steps off at the bottom, `jump` lets go.
|
|
1784
|
+
* `0` = no ladders (every scene before this).
|
|
1785
|
+
*/
|
|
1786
|
+
climbSpeed: number;
|
|
1787
|
+
ladderGroup: string;
|
|
1788
|
+
/**
|
|
1789
|
+
* The pull-up, for any jump. A jump that falls a hand short of a ledge is
|
|
1790
|
+
* the most common near-miss in a platformer, and every one handles it the
|
|
1791
|
+
* same way: catch the edge, pull up. On the way down from a jump, a ledge
|
|
1792
|
+
* ahead no higher than this above the capsule's bottom is taken — the same
|
|
1793
|
+
* climb that takes a swimmer out of the water and a climber off a ladder.
|
|
1794
|
+
* `0` (the default) = a jump near a wall feels exactly as it did.
|
|
1795
|
+
*/
|
|
1796
|
+
mantleHeight: number;
|
|
1797
|
+
crouchHeight: number;
|
|
1798
|
+
crouchSpeedMultiplier: number;
|
|
1799
|
+
crouchAction: string;
|
|
1800
|
+
dashSpeed: number;
|
|
1801
|
+
dashSeconds: number;
|
|
1802
|
+
dashCooldown: number;
|
|
1803
|
+
dashAction: string;
|
|
1804
|
+
dashBackstep: boolean;
|
|
1805
|
+
private dashLeft;
|
|
1806
|
+
private dashCooldownLeft;
|
|
1807
|
+
private dashDir;
|
|
1808
|
+
/** Read-only: shorter right now — by the key, or by a ceiling. */
|
|
1809
|
+
crouching: boolean;
|
|
1810
|
+
/** The capsule height to stand back up to. */
|
|
1811
|
+
private standingHeight;
|
|
1812
|
+
/** The skin's authored y offset, restored on standing. */
|
|
1813
|
+
private skinRest;
|
|
1814
|
+
/**
|
|
1546
1815
|
* How high a step the PLAYER walks up without jumping (0 = off).
|
|
1547
1816
|
*
|
|
1548
1817
|
* The hover spring holds the capsule a fixed distance above whatever is
|
|
@@ -1561,13 +1830,29 @@ declare class CharacterController3D extends Node3D {
|
|
|
1561
1830
|
* 200 kg character does not move a seesaw a 70 kg crate tips.
|
|
1562
1831
|
*/
|
|
1563
1832
|
stepHeight: number;
|
|
1833
|
+
/**
|
|
1834
|
+
* The steepest ground this character STANDS on, in degrees (0-90).
|
|
1835
|
+
*
|
|
1836
|
+
* At or under it the ground is ground: the character holds its place with no
|
|
1837
|
+
* slide at all, however long you leave it there. Over it the ground stops
|
|
1838
|
+
* counting as ground — no hover spring, no `grounded`, no jump reset — and
|
|
1839
|
+
* the body slips off the face, which is what a slope limit means in every
|
|
1840
|
+
* engine that has one.
|
|
1841
|
+
*
|
|
1842
|
+
* 55° is a person. A mountain goat is 80; something on wheels is 25. `90`
|
|
1843
|
+
* turns the limit off — which is what this controller did before it had one,
|
|
1844
|
+
* and why it slid down a 7° hillside.
|
|
1845
|
+
*/
|
|
1846
|
+
slopeLimitDeg: number;
|
|
1564
1847
|
mouseLook: boolean;
|
|
1565
1848
|
zoomMin: number;
|
|
1566
1849
|
zoomMax: number;
|
|
1567
1850
|
pitchMin: number;
|
|
1568
1851
|
pitchMax: number;
|
|
1852
|
+
pitchStart: number;
|
|
1569
1853
|
/** Spring-arm: pull the orbit camera in front of walls/ground instead of clipping. */
|
|
1570
1854
|
cameraCollision: boolean;
|
|
1855
|
+
camera: "drive" | "none";
|
|
1571
1856
|
/**
|
|
1572
1857
|
* Ride whatever you are standing on.
|
|
1573
1858
|
*
|
|
@@ -1592,6 +1877,8 @@ declare class CharacterController3D extends Node3D {
|
|
|
1592
1877
|
* would fling the player on every step onto one.
|
|
1593
1878
|
*/
|
|
1594
1879
|
private groundCarry;
|
|
1880
|
+
private carriedRot;
|
|
1881
|
+
private carriedMe;
|
|
1595
1882
|
turnSpeed: number;
|
|
1596
1883
|
/** Camera smoothing rate (1-exp(-rate·dt)); side view uses 5. */
|
|
1597
1884
|
camLerp: number;
|
|
@@ -1606,6 +1893,19 @@ declare class CharacterController3D extends Node3D {
|
|
|
1606
1893
|
* character facing away from the camera until it first moves).
|
|
1607
1894
|
*/
|
|
1608
1895
|
skinYawOffset: number;
|
|
1896
|
+
lockOnAction: string;
|
|
1897
|
+
lockGroup: string;
|
|
1898
|
+
lockRange: number;
|
|
1899
|
+
/** What the character is locked onto, or null. */
|
|
1900
|
+
lockTarget: Node | null;
|
|
1901
|
+
/** Lock onto `node`: the camera yaw and the skin follow it from now on. */
|
|
1902
|
+
lock(node: Node): void;
|
|
1903
|
+
/** Let go. */
|
|
1904
|
+
unlock(): void;
|
|
1905
|
+
/** Lock the nearest live, visible member of `lockGroup` within `lockRange` — or let go if locked. */
|
|
1906
|
+
toggleLock(): void;
|
|
1907
|
+
/** Player → target on the ground plane, unit; null when not locked (and lets go when the lock is stale). */
|
|
1908
|
+
private lockDirection;
|
|
1609
1909
|
/**
|
|
1610
1910
|
* Movement-state → animation asset map, applied to the `skinPath` model
|
|
1611
1911
|
* directly — no CharacterAnimator behavior needed:
|
|
@@ -1628,9 +1928,33 @@ declare class CharacterController3D extends Node3D {
|
|
|
1628
1928
|
/** Camera yaw/pitch in radians (mouse look mutates these). */
|
|
1629
1929
|
yaw: number;
|
|
1630
1930
|
pitch: number;
|
|
1631
|
-
/** idle | walk | run | fastRun | airborne — drive animations from this. */
|
|
1931
|
+
/** idle | walk | run | fastRun | airborne | swim — drive animations from this. */
|
|
1632
1932
|
state: MovementState;
|
|
1633
1933
|
grounded: boolean;
|
|
1934
|
+
/** Slope of the ground under the character, degrees — 0 when there is none. */
|
|
1935
|
+
groundSlopeDeg: number;
|
|
1936
|
+
/** Its outward normal, or null. `[0, 1, 0]` is flat ground. */
|
|
1937
|
+
groundNormal: [number, number, number] | null;
|
|
1938
|
+
/** In water too deep to stand in — held at the surface by the swim spring. */
|
|
1939
|
+
swimming: boolean;
|
|
1940
|
+
/** The head is under the surface (diving, or a wave over it). */
|
|
1941
|
+
submerged: boolean;
|
|
1942
|
+
/** Pulling up onto a ledge out of the water (see the climb in fixedUpdate). */
|
|
1943
|
+
climbing: boolean;
|
|
1944
|
+
/** On a ladder — an `Area3D` in `ladderGroup` the body overlaps and pushed up into. */
|
|
1945
|
+
onLadder: boolean;
|
|
1946
|
+
private ladders;
|
|
1947
|
+
private ladderScanIn;
|
|
1948
|
+
private ladderLockout;
|
|
1949
|
+
/** Every Water3D in the tree, re-scanned every {@link WATER_SCAN_STEPS}. */
|
|
1950
|
+
private waters;
|
|
1951
|
+
private waterScanIn;
|
|
1952
|
+
/**
|
|
1953
|
+
* A hop out of the water is in progress: the spring may catch a ledge on
|
|
1954
|
+
* the way down (the mantle) — a jump from land never gets that, or the
|
|
1955
|
+
* spring would cushion every landing.
|
|
1956
|
+
*/
|
|
1957
|
+
private swimHop;
|
|
1634
1958
|
/** @internal Feel timers — see the jump block for what each one buys. */
|
|
1635
1959
|
private coyoteLeft;
|
|
1636
1960
|
private bufferLeft;
|
|
@@ -1640,6 +1964,12 @@ declare class CharacterController3D extends Node3D {
|
|
|
1640
1964
|
private jumping;
|
|
1641
1965
|
/** Seconds of air control still suppressed after a wall kick. */
|
|
1642
1966
|
private wallLockout;
|
|
1967
|
+
/** What the anti-slide has learned it must keep paying to hold a slope. */
|
|
1968
|
+
private slideHold;
|
|
1969
|
+
/** Where the body stood last step, for the anti-slide's position error. */
|
|
1970
|
+
private slideFrom;
|
|
1971
|
+
/** Seconds since the player last asked this character to move. */
|
|
1972
|
+
private stillFor;
|
|
1643
1973
|
/** The outward normal of the wall being pressed into this step, if any. */
|
|
1644
1974
|
private wallNormal;
|
|
1645
1975
|
private get body();
|
|
@@ -1648,6 +1978,25 @@ declare class CharacterController3D extends Node3D {
|
|
|
1648
1978
|
/** Actions already reported missing, so a per-frame read says it once. */
|
|
1649
1979
|
private readonly reportedActions;
|
|
1650
1980
|
/**
|
|
1981
|
+
* The water over a world point — `[wave surface, still level]` — or null
|
|
1982
|
+
* when no `Water3D`'s footprint covers it. The tree is re-scanned once a
|
|
1983
|
+
* second, so a lake streamed in later is found; the wave height is the CPU
|
|
1984
|
+
* twin of what is drawn, so a swimmer rides the swell the way a raft does.
|
|
1985
|
+
*/
|
|
1986
|
+
/** The ladder the body is overlapping, if any — an Area3D in `ladderGroup`. */
|
|
1987
|
+
private ladderUnder;
|
|
1988
|
+
/**
|
|
1989
|
+
* Swap the capsule's height and keep the feet where they are: the body
|
|
1990
|
+
* drops (or rises) by half the difference in the same step, the skin's
|
|
1991
|
+
* authored offset moves the other way so the model's feet stay on the
|
|
1992
|
+
* floor, and the adapter rebuilds the body at the new place next step.
|
|
1993
|
+
*/
|
|
1994
|
+
private setHeight;
|
|
1995
|
+
private sceneGravity;
|
|
1996
|
+
/** `swimDepth`, or what it is derived to be for this body (see the prop). */
|
|
1997
|
+
private effectiveSwimDepth;
|
|
1998
|
+
private surfaceAt;
|
|
1999
|
+
/**
|
|
1651
2000
|
* Read an input action this controller is allowed to be missing.
|
|
1652
2001
|
*
|
|
1653
2002
|
* Tolerated because a game may declare no sprint key and no jump; reported
|
|
@@ -1663,6 +2012,221 @@ declare class CharacterController3D extends Node3D {
|
|
|
1663
2012
|
private findCamera;
|
|
1664
2013
|
}
|
|
1665
2014
|
//#endregion
|
|
2015
|
+
//#region src/3d/nodes/mesh-instance-3d.d.ts
|
|
2016
|
+
type MeshKind = "box" | "sphere" | "capsule" | "plane" | "cylinder" | "gem";
|
|
2017
|
+
interface MeshMaterialProps {
|
|
2018
|
+
color?: string;
|
|
2019
|
+
metalness?: number;
|
|
2020
|
+
roughness?: number;
|
|
2021
|
+
emissive?: string;
|
|
2022
|
+
emissiveIntensity?: number;
|
|
2023
|
+
wireframe?: boolean;
|
|
2024
|
+
/** Flat per-face shading — gives faceted meshes (gem!) crisp glints that
|
|
2025
|
+
* sparkle as the mesh turns, instead of a smoothed surface. */
|
|
2026
|
+
flatShading?: boolean;
|
|
2027
|
+
/** 0..1 surface opacity; below 1 turns on transparency (glassy gems, etc.). */
|
|
2028
|
+
opacity?: number;
|
|
2029
|
+
/** Depth-test against the scene (default true). Set false so the mesh ALWAYS
|
|
2030
|
+
* draws on top of geometry behind it — the standard trick for flat ground
|
|
2031
|
+
* decals (AoE telegraphs, selection rings) that must never z-fight with or be
|
|
2032
|
+
* occluded by bumpy terrain. Pair with a high `renderOrder`. */
|
|
2033
|
+
depthTest?: boolean;
|
|
2034
|
+
/** Write to the depth buffer (default true). Set false for additive/overlay
|
|
2035
|
+
* decals so they don't occlude effects drawn after them. */
|
|
2036
|
+
depthWrite?: boolean;
|
|
2037
|
+
/** 0..1 lacquer layer over the base — THE car-paint look: a glossy clear
|
|
2038
|
+
* coat with its own reflection on top of a metallic base. */
|
|
2039
|
+
clearcoat?: number;
|
|
2040
|
+
/** 0..1 roughness of the clearcoat layer alone (default 0 = mirror lacquer). */
|
|
2041
|
+
clearcoatRoughness?: number;
|
|
2042
|
+
/** Reflection strength from the scene's image-based lighting (the PMREM'd
|
|
2043
|
+
* sky / HDRI). 1 = scene default; 2+ makes glass visibly mirror the sky. */
|
|
2044
|
+
envMapIntensity?: number;
|
|
2045
|
+
/** Color texture URL (sampled sRGB, tinted by `color`). */
|
|
2046
|
+
map?: string;
|
|
2047
|
+
/** Tangent-space normal map URL (sampled linear). */
|
|
2048
|
+
normalMap?: string;
|
|
2049
|
+
/** Texture tiling [u, v] across the mesh's UVs (both maps; default [1,1]).
|
|
2050
|
+
* Box/plane UVs span 0–1 per face — scale repeat by the face's world size
|
|
2051
|
+
* for worldspace-ish texel density (e.g. a 6×2.5 m wall at one tile per
|
|
2052
|
+
* meter wants `repeat: [6, 2.5]`). */
|
|
2053
|
+
repeat?: [number, number];
|
|
2054
|
+
}
|
|
2055
|
+
/**
|
|
2056
|
+
* A primitive mesh. Intent-level props only:
|
|
2057
|
+
* - `mesh`: box | sphere | capsule | plane | cylinder | gem
|
|
2058
|
+
* - `size [x,y,z]`: box extents; sphere/gem radius = x; capsule radius = x,
|
|
2059
|
+
* height = y; plane = x·z ground plane (laid flat); cylinder radius = x, height = y
|
|
2060
|
+
* - `material`: `{color, metalness, roughness, wireframe, flatShading, opacity,
|
|
2061
|
+
* clearcoat, clearcoatRoughness, envMapIntensity, depthTest, depthWrite,
|
|
2062
|
+
* emissive, emissiveIntensity, map, normalMap, repeat}` —
|
|
2063
|
+
* `map`/`normalMap` are texture URLs loaded lazily (headless-safe: geometry and
|
|
2064
|
+
* physics never wait on them), tiled by `repeat: [u, v]`. `gem` + `flatShading:
|
|
2065
|
+
* true` + a low `roughness` reads as a sparkling faceted jewel (spin it for the
|
|
2066
|
+
* sparkle). `depthTest: false` makes a flat `plane`/`cylinder` an always-on-top
|
|
2067
|
+
* ground decal (AoE telegraph, selection ring) — no z-fighting with terrain.
|
|
2068
|
+
*/
|
|
2069
|
+
declare class MeshInstance3D extends Node3D {
|
|
2070
|
+
static override readonly typeName: string;
|
|
2071
|
+
static override readonly props: PropSchema;
|
|
2072
|
+
mesh: string;
|
|
2073
|
+
size: number[];
|
|
2074
|
+
material: MeshMaterialProps;
|
|
2075
|
+
castShadow: boolean;
|
|
2076
|
+
receiveShadow: boolean;
|
|
2077
|
+
/** Loader hook: malformed materials fail at LOAD time, not at render. */
|
|
2078
|
+
static validateJson(node: Node): void;
|
|
2079
|
+
private geometryKey;
|
|
2080
|
+
private materialKey;
|
|
2081
|
+
/** True while this node is using a cache entry it must not dispose. */
|
|
2082
|
+
private sharedGeometry;
|
|
2083
|
+
private sharedMaterial;
|
|
2084
|
+
private textureKey;
|
|
2085
|
+
private loadedTextures;
|
|
2086
|
+
protected override _createObject3D(): Object3D;
|
|
2087
|
+
override _syncObject3D(alpha?: number, assets?: AssetStore3D | null): void;
|
|
2088
|
+
/** Lazy texture dressing — same headless guard as Tree3D bark: without a
|
|
2089
|
+
* DOM there is no Image decode, so geometry/colors apply and the maps are
|
|
2090
|
+
* skipped. Re-loads only when a texture-shaping key changes. */
|
|
2091
|
+
private syncTextures;
|
|
2092
|
+
/**
|
|
2093
|
+
* A private CLONE: `repeat` is per-node here (a 1x1 crate and a 8x8 floor
|
|
2094
|
+
* share one tile image), and that is the one field a shared master cannot
|
|
2095
|
+
* carry. The clone shares `texture.source`, so the fetch and the decode are
|
|
2096
|
+
* still done once per url for the whole scene.
|
|
2097
|
+
*/
|
|
2098
|
+
private loadTexture;
|
|
2099
|
+
/**
|
|
2100
|
+
* Give the GPU back everything this node OWNS.
|
|
2101
|
+
*
|
|
2102
|
+
* It used to dispose textures and nothing else, so every freed mesh leaked its
|
|
2103
|
+
* geometry and its material — a wave spawner that kills and respawns fifty
|
|
2104
|
+
* enemies a minute leaks fifty of each, forever, and nothing in the game says
|
|
2105
|
+
* so. Both are built here (`_createObject3D` news them, `_syncObject3D`
|
|
2106
|
+
* rebuilds the geometry on a shape change), so both are ours to release.
|
|
2107
|
+
*
|
|
2108
|
+
* The textures are NOT: since the shared texture cache they belong to the
|
|
2109
|
+
* asset store, except the per-node clones this node asked for, which are what
|
|
2110
|
+
* `loadedTextures` holds.
|
|
2111
|
+
*/
|
|
2112
|
+
override free(): void;
|
|
2113
|
+
}
|
|
2114
|
+
//#endregion
|
|
2115
|
+
//#region src/3d/nodes/instanced-mesh-3d.d.ts
|
|
2116
|
+
/**
|
|
2117
|
+
* Hundreds of copies of one mesh in ONE draw call — scattered rocks, fence
|
|
2118
|
+
* posts, pillars, crates, gravestones. Same `mesh`/`size`/`material` surface
|
|
2119
|
+
* as MeshInstance3D; `transforms` places the copies:
|
|
2120
|
+
*
|
|
2121
|
+
* { "name": "Rocks", "type": "InstancedMesh3D",
|
|
2122
|
+
* "props": { "mesh": "gem", "size": [0.7, 0.5, 0.7],
|
|
2123
|
+
* "material": { "color": "#8a8f98", "roughness": 0.9, "flatShading": true },
|
|
2124
|
+
* "transforms": [[12, 0.2, -8, 40, 1.3], [-6, 0.1, 14, 210, 0.8]] } }
|
|
2125
|
+
*
|
|
2126
|
+
* Each row is `[x, y, z, yawDeg?, scale?]` (yaw 0 and scale 1 when omitted) —
|
|
2127
|
+
* dense enough to generate hundreds inline. REPLACE the array to update
|
|
2128
|
+
* (mutations are not watched).
|
|
2129
|
+
*/
|
|
2130
|
+
declare class InstancedMesh3D extends Node3D {
|
|
2131
|
+
static override readonly typeName: string;
|
|
2132
|
+
static override readonly props: PropSchema;
|
|
2133
|
+
mesh: string;
|
|
2134
|
+
size: number[];
|
|
2135
|
+
material: MeshMaterialProps;
|
|
2136
|
+
castShadow: boolean;
|
|
2137
|
+
receiveShadow: boolean;
|
|
2138
|
+
/**
|
|
2139
|
+
* Make the scatter SOLID: `{}` gives every row a collider shaped like the
|
|
2140
|
+
* mesh itself — a faceted `gem` stone collides as that stone's own hull, not
|
|
2141
|
+
* as a ball tucked inside it — sized from `size` × the row's scale.
|
|
2142
|
+
*
|
|
2143
|
+
* A field of fifty boulders a player walks straight through is the tell that
|
|
2144
|
+
* a world is a picture. One fixed body carries all the colliders, so the cost
|
|
2145
|
+
* is a handful of shapes and no per-frame work — these never move.
|
|
2146
|
+
*
|
|
2147
|
+
* `{ shape: 'sphere' | 'box' }` (with `radius`/`size`) opts out into a
|
|
2148
|
+
* cheaper approximation when a rough blocker is genuinely all you want.
|
|
2149
|
+
*/
|
|
2150
|
+
collider: {
|
|
2151
|
+
shape?: string;
|
|
2152
|
+
radius?: number;
|
|
2153
|
+
size?: number[];
|
|
2154
|
+
} | null;
|
|
2155
|
+
private _transforms;
|
|
2156
|
+
private transformsDirty;
|
|
2157
|
+
get transforms(): number[][];
|
|
2158
|
+
set transforms(value: number[][]);
|
|
2159
|
+
private instanced;
|
|
2160
|
+
private builtKey;
|
|
2161
|
+
static validateJson(node: Node): void;
|
|
2162
|
+
/** Test hook: the live instance count. */
|
|
2163
|
+
get instanceCount(): number;
|
|
2164
|
+
override _syncObject3D(alpha?: number): void;
|
|
2165
|
+
override free(): void;
|
|
2166
|
+
}
|
|
2167
|
+
//#endregion
|
|
2168
|
+
//#region src/3d/nodes/flock-3d.d.ts
|
|
2169
|
+
/** One bird, in WORLD metres and m/s — what `boids()` answers. */
|
|
2170
|
+
interface Boid {
|
|
2171
|
+
x: number;
|
|
2172
|
+
y: number;
|
|
2173
|
+
z: number;
|
|
2174
|
+
vx: number;
|
|
2175
|
+
vy: number;
|
|
2176
|
+
vz: number;
|
|
2177
|
+
}
|
|
2178
|
+
/**
|
|
2179
|
+
* A flock — gulls over a harbor, fish under a boat, bats out of a cave — as
|
|
2180
|
+
* ONE instanced mesh that flies its own instances.
|
|
2181
|
+
*
|
|
2182
|
+
* ```json
|
|
2183
|
+
* { "name": "Gulls", "type": "Flock3D",
|
|
2184
|
+
* "props": { "position": [0, 14, 0], "count": 40, "radius": 30, "height": 6,
|
|
2185
|
+
* "mesh": "box", "size": [0.5, 0.08, 0.3], "follow": "/root/Boat" } }
|
|
2186
|
+
* ```
|
|
2187
|
+
*
|
|
2188
|
+
* Boids (Reynolds 1987): each instance steers away from neighbours closer
|
|
2189
|
+
* than `separation`, toward the average heading of those within `sight`
|
|
2190
|
+
* (`alignment`) and toward their centre (`cohesion`), turns back inside an
|
|
2191
|
+
* ellipsoid `radius` wide and `height` tall around this node — or around the
|
|
2192
|
+
* node at `follow`, offset by this node's position — and never turns faster
|
|
2193
|
+
* than `turn`. Every instance flies at `speed`, +z forward, so a mesh that is
|
|
2194
|
+
* longer along z reads as a body with a beak.
|
|
2195
|
+
*
|
|
2196
|
+
* No physics bodies, no behaviour per bird: forty birds cost one draw call
|
|
2197
|
+
* and forty-squared distance checks a frame. Seeded from `engine.rng`, so a
|
|
2198
|
+
* seeded run flies the same flight. `boids()` answers headless.
|
|
2199
|
+
*/
|
|
2200
|
+
declare class Flock3D extends InstancedMesh3D {
|
|
2201
|
+
static override readonly typeName: string;
|
|
2202
|
+
static override readonly props: PropSchema;
|
|
2203
|
+
count: number;
|
|
2204
|
+
radius: number;
|
|
2205
|
+
height: number;
|
|
2206
|
+
speed: number;
|
|
2207
|
+
turn: number;
|
|
2208
|
+
separation: number;
|
|
2209
|
+
sight: number;
|
|
2210
|
+
alignment: number;
|
|
2211
|
+
cohesion: number;
|
|
2212
|
+
follow: string;
|
|
2213
|
+
private px;
|
|
2214
|
+
private py;
|
|
2215
|
+
private pz;
|
|
2216
|
+
private vx;
|
|
2217
|
+
private vy;
|
|
2218
|
+
private vz;
|
|
2219
|
+
private rows;
|
|
2220
|
+
static override validateJson(node: Node): void;
|
|
2221
|
+
/** Every bird right now, in world metres and m/s. */
|
|
2222
|
+
boids(): Boid[];
|
|
2223
|
+
override update(dt: number): void;
|
|
2224
|
+
/** The roam centre in this node's local frame: the followed node's offset, or the origin. */
|
|
2225
|
+
private centre;
|
|
2226
|
+
/** Scatter `n` birds through the bound with random headings — engine-seeded. */
|
|
2227
|
+
private seed;
|
|
2228
|
+
}
|
|
2229
|
+
//#endregion
|
|
1666
2230
|
//#region src/3d/vegetation/flower-geometry.d.ts
|
|
1667
2231
|
/**
|
|
1668
2232
|
* Procedural flower PLANTS for Flowers3D — real plants like the reference
|
|
@@ -1999,161 +2563,8 @@ declare class Foliage3D extends Node3D implements SunConsumer3D {
|
|
|
1999
2563
|
override free(): void;
|
|
2000
2564
|
}
|
|
2001
2565
|
//#endregion
|
|
2002
|
-
//#region src/3d/nodes/mesh-instance-3d.d.ts
|
|
2003
|
-
type MeshKind = "box" | "sphere" | "capsule" | "plane" | "cylinder" | "gem";
|
|
2004
|
-
interface MeshMaterialProps {
|
|
2005
|
-
color?: string;
|
|
2006
|
-
metalness?: number;
|
|
2007
|
-
roughness?: number;
|
|
2008
|
-
emissive?: string;
|
|
2009
|
-
emissiveIntensity?: number;
|
|
2010
|
-
wireframe?: boolean;
|
|
2011
|
-
/** Flat per-face shading — gives faceted meshes (gem!) crisp glints that
|
|
2012
|
-
* sparkle as the mesh turns, instead of a smoothed surface. */
|
|
2013
|
-
flatShading?: boolean;
|
|
2014
|
-
/** 0..1 surface opacity; below 1 turns on transparency (glassy gems, etc.). */
|
|
2015
|
-
opacity?: number;
|
|
2016
|
-
/** Depth-test against the scene (default true). Set false so the mesh ALWAYS
|
|
2017
|
-
* draws on top of geometry behind it — the standard trick for flat ground
|
|
2018
|
-
* decals (AoE telegraphs, selection rings) that must never z-fight with or be
|
|
2019
|
-
* occluded by bumpy terrain. Pair with a high `renderOrder`. */
|
|
2020
|
-
depthTest?: boolean;
|
|
2021
|
-
/** Write to the depth buffer (default true). Set false for additive/overlay
|
|
2022
|
-
* decals so they don't occlude effects drawn after them. */
|
|
2023
|
-
depthWrite?: boolean;
|
|
2024
|
-
/** 0..1 lacquer layer over the base — THE car-paint look: a glossy clear
|
|
2025
|
-
* coat with its own reflection on top of a metallic base. */
|
|
2026
|
-
clearcoat?: number;
|
|
2027
|
-
/** 0..1 roughness of the clearcoat layer alone (default 0 = mirror lacquer). */
|
|
2028
|
-
clearcoatRoughness?: number;
|
|
2029
|
-
/** Reflection strength from the scene's image-based lighting (the PMREM'd
|
|
2030
|
-
* sky / HDRI). 1 = scene default; 2+ makes glass visibly mirror the sky. */
|
|
2031
|
-
envMapIntensity?: number;
|
|
2032
|
-
/** Color texture URL (sampled sRGB, tinted by `color`). */
|
|
2033
|
-
map?: string;
|
|
2034
|
-
/** Tangent-space normal map URL (sampled linear). */
|
|
2035
|
-
normalMap?: string;
|
|
2036
|
-
/** Texture tiling [u, v] across the mesh's UVs (both maps; default [1,1]).
|
|
2037
|
-
* Box/plane UVs span 0–1 per face — scale repeat by the face's world size
|
|
2038
|
-
* for worldspace-ish texel density (e.g. a 6×2.5 m wall at one tile per
|
|
2039
|
-
* meter wants `repeat: [6, 2.5]`). */
|
|
2040
|
-
repeat?: [number, number];
|
|
2041
|
-
}
|
|
2042
|
-
/**
|
|
2043
|
-
* A primitive mesh. Intent-level props only:
|
|
2044
|
-
* - `mesh`: box | sphere | capsule | plane | cylinder | gem
|
|
2045
|
-
* - `size [x,y,z]`: box extents; sphere/gem radius = x; capsule radius = x,
|
|
2046
|
-
* height = y; plane = x·z ground plane (laid flat); cylinder radius = x, height = y
|
|
2047
|
-
* - `material`: `{color, metalness, roughness, wireframe, flatShading, opacity,
|
|
2048
|
-
* clearcoat, clearcoatRoughness, envMapIntensity, depthTest, depthWrite,
|
|
2049
|
-
* emissive, emissiveIntensity, map, normalMap, repeat}` —
|
|
2050
|
-
* `map`/`normalMap` are texture URLs loaded lazily (headless-safe: geometry and
|
|
2051
|
-
* physics never wait on them), tiled by `repeat: [u, v]`. `gem` + `flatShading:
|
|
2052
|
-
* true` + a low `roughness` reads as a sparkling faceted jewel (spin it for the
|
|
2053
|
-
* sparkle). `depthTest: false` makes a flat `plane`/`cylinder` an always-on-top
|
|
2054
|
-
* ground decal (AoE telegraph, selection ring) — no z-fighting with terrain.
|
|
2055
|
-
*/
|
|
2056
|
-
declare class MeshInstance3D extends Node3D {
|
|
2057
|
-
static override readonly typeName: string;
|
|
2058
|
-
static override readonly props: PropSchema;
|
|
2059
|
-
mesh: string;
|
|
2060
|
-
size: number[];
|
|
2061
|
-
material: MeshMaterialProps;
|
|
2062
|
-
castShadow: boolean;
|
|
2063
|
-
receiveShadow: boolean;
|
|
2064
|
-
/** Loader hook: malformed materials fail at LOAD time, not at render. */
|
|
2065
|
-
static validateJson(node: Node): void;
|
|
2066
|
-
private geometryKey;
|
|
2067
|
-
private materialKey;
|
|
2068
|
-
/** True while this node is using a cache entry it must not dispose. */
|
|
2069
|
-
private sharedGeometry;
|
|
2070
|
-
private sharedMaterial;
|
|
2071
|
-
private textureKey;
|
|
2072
|
-
private loadedTextures;
|
|
2073
|
-
protected override _createObject3D(): Object3D;
|
|
2074
|
-
override _syncObject3D(alpha?: number, assets?: AssetStore3D | null): void;
|
|
2075
|
-
/** Lazy texture dressing — same headless guard as Tree3D bark: without a
|
|
2076
|
-
* DOM there is no Image decode, so geometry/colors apply and the maps are
|
|
2077
|
-
* skipped. Re-loads only when a texture-shaping key changes. */
|
|
2078
|
-
private syncTextures;
|
|
2079
|
-
/**
|
|
2080
|
-
* A private CLONE: `repeat` is per-node here (a 1x1 crate and a 8x8 floor
|
|
2081
|
-
* share one tile image), and that is the one field a shared master cannot
|
|
2082
|
-
* carry. The clone shares `texture.source`, so the fetch and the decode are
|
|
2083
|
-
* still done once per url for the whole scene.
|
|
2084
|
-
*/
|
|
2085
|
-
private loadTexture;
|
|
2086
|
-
/**
|
|
2087
|
-
* Give the GPU back everything this node OWNS.
|
|
2088
|
-
*
|
|
2089
|
-
* It used to dispose textures and nothing else, so every freed mesh leaked its
|
|
2090
|
-
* geometry and its material — a wave spawner that kills and respawns fifty
|
|
2091
|
-
* enemies a minute leaks fifty of each, forever, and nothing in the game says
|
|
2092
|
-
* so. Both are built here (`_createObject3D` news them, `_syncObject3D`
|
|
2093
|
-
* rebuilds the geometry on a shape change), so both are ours to release.
|
|
2094
|
-
*
|
|
2095
|
-
* The textures are NOT: since the shared texture cache they belong to the
|
|
2096
|
-
* asset store, except the per-node clones this node asked for, which are what
|
|
2097
|
-
* `loadedTextures` holds.
|
|
2098
|
-
*/
|
|
2099
|
-
override free(): void;
|
|
2100
|
-
}
|
|
2101
|
-
//#endregion
|
|
2102
|
-
//#region src/3d/nodes/instanced-mesh-3d.d.ts
|
|
2103
|
-
/**
|
|
2104
|
-
* Hundreds of copies of one mesh in ONE draw call — scattered rocks, fence
|
|
2105
|
-
* posts, pillars, crates, gravestones. Same `mesh`/`size`/`material` surface
|
|
2106
|
-
* as MeshInstance3D; `transforms` places the copies:
|
|
2107
|
-
*
|
|
2108
|
-
* { "name": "Rocks", "type": "InstancedMesh3D",
|
|
2109
|
-
* "props": { "mesh": "gem", "size": [0.7, 0.5, 0.7],
|
|
2110
|
-
* "material": { "color": "#8a8f98", "roughness": 0.9, "flatShading": true },
|
|
2111
|
-
* "transforms": [[12, 0.2, -8, 40, 1.3], [-6, 0.1, 14, 210, 0.8]] } }
|
|
2112
|
-
*
|
|
2113
|
-
* Each row is `[x, y, z, yawDeg?, scale?]` (yaw 0 and scale 1 when omitted) —
|
|
2114
|
-
* dense enough to generate hundreds inline. REPLACE the array to update
|
|
2115
|
-
* (mutations are not watched).
|
|
2116
|
-
*/
|
|
2117
|
-
declare class InstancedMesh3D extends Node3D {
|
|
2118
|
-
static override readonly typeName: string;
|
|
2119
|
-
static override readonly props: PropSchema;
|
|
2120
|
-
mesh: string;
|
|
2121
|
-
size: number[];
|
|
2122
|
-
material: MeshMaterialProps;
|
|
2123
|
-
castShadow: boolean;
|
|
2124
|
-
receiveShadow: boolean;
|
|
2125
|
-
/**
|
|
2126
|
-
* Make the scatter SOLID: `{}` gives every row a collider shaped like the
|
|
2127
|
-
* mesh itself — a faceted `gem` stone collides as that stone's own hull, not
|
|
2128
|
-
* as a ball tucked inside it — sized from `size` × the row's scale.
|
|
2129
|
-
*
|
|
2130
|
-
* A field of fifty boulders a player walks straight through is the tell that
|
|
2131
|
-
* a world is a picture. One fixed body carries all the colliders, so the cost
|
|
2132
|
-
* is a handful of shapes and no per-frame work — these never move.
|
|
2133
|
-
*
|
|
2134
|
-
* `{ shape: 'sphere' | 'box' }` (with `radius`/`size`) opts out into a
|
|
2135
|
-
* cheaper approximation when a rough blocker is genuinely all you want.
|
|
2136
|
-
*/
|
|
2137
|
-
collider: {
|
|
2138
|
-
shape?: string;
|
|
2139
|
-
radius?: number;
|
|
2140
|
-
size?: number[];
|
|
2141
|
-
} | null;
|
|
2142
|
-
private _transforms;
|
|
2143
|
-
private transformsDirty;
|
|
2144
|
-
get transforms(): number[][];
|
|
2145
|
-
set transforms(value: number[][]);
|
|
2146
|
-
private instanced;
|
|
2147
|
-
private builtKey;
|
|
2148
|
-
static validateJson(node: Node): void;
|
|
2149
|
-
/** Test hook: the live instance count. */
|
|
2150
|
-
get instanceCount(): number;
|
|
2151
|
-
override _syncObject3D(alpha?: number): void;
|
|
2152
|
-
override free(): void;
|
|
2153
|
-
}
|
|
2154
|
-
//#endregion
|
|
2155
2566
|
//#region src/3d/nodes/joint-3d.d.ts
|
|
2156
|
-
type JointType3D = "fixed" | "spherical" | "rope" | "spring";
|
|
2567
|
+
type JointType3D = "fixed" | "spherical" | "revolute" | "prismatic" | "rope" | "spring";
|
|
2157
2568
|
/**
|
|
2158
2569
|
* A physics joint linking its PARENT body to `target` (a node path to the
|
|
2159
2570
|
* other body). Godot-style placement: the joint lives as a child of body A.
|
|
@@ -2162,14 +2573,42 @@ type JointType3D = "fixed" | "spherical" | "rope" | "spring";
|
|
|
2162
2573
|
* "props": { "type": "spherical", "target": "%Anchor", "anchor": [0, -20] } }
|
|
2163
2574
|
*
|
|
2164
2575
|
* Types: `fixed` welds the bodies rigidly · `spherical` is a ball joint at the
|
|
2165
|
-
* anchors · `
|
|
2166
|
-
*
|
|
2167
|
-
*
|
|
2576
|
+
* anchors · `revolute` is a HINGE about `axis` (a door, a wheel, a lever) with
|
|
2577
|
+
* optional `limits` (degrees) and a `motorSpeed` (degrees a second) ·
|
|
2578
|
+
* `prismatic` is a SLIDE along `axis` (a portcullis, an elevator, a piston)
|
|
2579
|
+
* with `limits` in metres, a `motorSpeed` in metres a second and `travel`
|
|
2580
|
+
* read back · `rope`
|
|
2581
|
+
* caps the anchor distance at `length` (m; 0 = measured at creation) ·
|
|
2582
|
+
* `spring` pulls toward `length` with `stiffness`/`damping`. Anchors are LOCAL
|
|
2583
|
+
* meter offsets on each body; `angle` reads the hinge back.
|
|
2168
2584
|
*/
|
|
2169
2585
|
declare class Joint3D extends Node3D {
|
|
2170
2586
|
static override readonly typeName: string;
|
|
2171
2587
|
static override readonly props: PropSchema;
|
|
2172
2588
|
type: JointType3D;
|
|
2589
|
+
/** Hinge axis of a `revolute`, or the line of a `prismatic` (local to this body). */
|
|
2590
|
+
axis: number[];
|
|
2591
|
+
/**
|
|
2592
|
+
* `[min, max]` in degrees for a `revolute` swing; `[]` = no stops. Measured
|
|
2593
|
+
* as `angle` is: this body turned about `axis`, relative to the target.
|
|
2594
|
+
*/
|
|
2595
|
+
limits: number[];
|
|
2596
|
+
/** Degrees a second the motor drives the hinge at; `0` = no motor (free). */
|
|
2597
|
+
motorSpeed: number;
|
|
2598
|
+
/** The motor's gain — how quickly it reaches and holds `motorSpeed`. */
|
|
2599
|
+
motorStrength: number;
|
|
2600
|
+
/**
|
|
2601
|
+
* The hinge's current angle in degrees — this body's rotation about `axis`
|
|
2602
|
+
* relative to the target, written by physics every step. `0` when the joint
|
|
2603
|
+
* is not a `revolute` or is not simulated yet.
|
|
2604
|
+
*/
|
|
2605
|
+
angle: number;
|
|
2606
|
+
/**
|
|
2607
|
+
* A `prismatic` slide's current travel in metres — this body's anchor along
|
|
2608
|
+
* `axis` relative to the target's, written by physics every step. `0` where
|
|
2609
|
+
* the two anchors coincide, which is where the scene loaded it.
|
|
2610
|
+
*/
|
|
2611
|
+
travel: number;
|
|
2173
2612
|
target: string;
|
|
2174
2613
|
anchor: number[];
|
|
2175
2614
|
targetAnchor: number[];
|
|
@@ -2558,6 +2997,10 @@ declare class Particles3D extends Node3D {
|
|
|
2558
2997
|
maxParticles: number;
|
|
2559
2998
|
static validateJson(node: Node): void;
|
|
2560
2999
|
private sim;
|
|
3000
|
+
emitBox: number[];
|
|
3001
|
+
drift: number[];
|
|
3002
|
+
/** @internal Forget the sim so the next update rebuilds it from the props (a preset or kind that changed). */
|
|
3003
|
+
_rebuildSim(): void;
|
|
2561
3004
|
private bursted;
|
|
2562
3005
|
private finishedEmitted;
|
|
2563
3006
|
/** @internal */
|
|
@@ -2597,6 +3040,17 @@ declare class Particles3D extends Node3D {
|
|
|
2597
3040
|
* list changes (zero per-frame allocation); null when empty so the caller
|
|
2598
3041
|
* uses the colorStart→colorEnd ramp. */
|
|
2599
3042
|
private refreshPalette;
|
|
3043
|
+
/**
|
|
3044
|
+
* The stamp every particle is drawn with — a soft round dot.
|
|
3045
|
+
*
|
|
3046
|
+
* A subclass overrides it to look like the thing it IS: `Weather3D`'s rain is
|
|
3047
|
+
* a vertical STREAK, because 2,600 round dots read as a dirty lens and not as
|
|
3048
|
+
* a downpour (measured in a browser at intensity 1). The material is rebuilt
|
|
3049
|
+
* when this changes, so a node may return a different stamp over its life.
|
|
3050
|
+
*/
|
|
3051
|
+
protected sprite(): DataTexture;
|
|
3052
|
+
/** The stamp the current material was built with, so a change can rebuild it. */
|
|
3053
|
+
private builtSprite;
|
|
2600
3054
|
private syncParticles;
|
|
2601
3055
|
/**
|
|
2602
3056
|
* Hand the GPU back.
|
|
@@ -2609,6 +3063,65 @@ declare class Particles3D extends Node3D {
|
|
|
2609
3063
|
override free(): void;
|
|
2610
3064
|
}
|
|
2611
3065
|
//#endregion
|
|
3066
|
+
//#region src/3d/nodes/ragdoll-3d.d.ts
|
|
3067
|
+
/** A bone name → world position, metres — what `activate` takes headless. */
|
|
3068
|
+
type RagdollPose = Record<string, [number, number, number]>;
|
|
3069
|
+
/** A built limb: its name in {@link RIG} and the RigidBody3D that is it. */
|
|
3070
|
+
interface Limb {
|
|
3071
|
+
name: string;
|
|
3072
|
+
body: Node;
|
|
3073
|
+
}
|
|
3074
|
+
/**
|
|
3075
|
+
* A ragdoll for a skinned model — the death that falls.
|
|
3076
|
+
*
|
|
3077
|
+
* ```json
|
|
3078
|
+
* { "name": "Body", "type": "CharacterBody3D", "children": [
|
|
3079
|
+
* { "name": "Skin", "type": "ModelInstance3D", "props": { "model": "$base" } },
|
|
3080
|
+
* { "name": "Ragdoll", "type": "Ragdoll3D", "props": { "target": "../Skin", "lifetime": 8 } }
|
|
3081
|
+
* ] }
|
|
3082
|
+
* ```
|
|
3083
|
+
*
|
|
3084
|
+
* Idle it is nothing. `activate()` reads the skeleton at `target` (Mixamo
|
|
3085
|
+
* names, forgiving lookup), builds a capsule `RigidBody3D` per limb where the
|
|
3086
|
+
* bones are, joins each to its parent with a spherical `Joint3D`, gives them
|
|
3087
|
+
* the velocity of the body they fell out of, and from then on writes the
|
|
3088
|
+
* bones' world matrices from the limbs every frame — the model crumples,
|
|
3089
|
+
* slides, hangs off the ledge. Wire it from `Health.died`; turn the body's
|
|
3090
|
+
* collider and its controller off beside it. `reset()` puts the skeleton
|
|
3091
|
+
* back under the animation; `lifetime` does that on its own.
|
|
3092
|
+
*
|
|
3093
|
+
* Headless there is no skeleton: `activate(pose)` takes bone positions, so a
|
|
3094
|
+
* test can ask the same questions the game will.
|
|
3095
|
+
*/
|
|
3096
|
+
declare class Ragdoll3D extends Node3D {
|
|
3097
|
+
static override readonly typeName: string;
|
|
3098
|
+
static override readonly props: PropSchema;
|
|
3099
|
+
static override readonly signals: readonly string[];
|
|
3100
|
+
target: string;
|
|
3101
|
+
mass: number;
|
|
3102
|
+
damping: number;
|
|
3103
|
+
lifetime: number;
|
|
3104
|
+
collide: boolean;
|
|
3105
|
+
/** Read-only: built and driving the bones. */
|
|
3106
|
+
active: boolean;
|
|
3107
|
+
private driven;
|
|
3108
|
+
private limbNodes;
|
|
3109
|
+
private left;
|
|
3110
|
+
/** Every limb built right now, empty while idle. */
|
|
3111
|
+
limbs(): Limb[];
|
|
3112
|
+
/**
|
|
3113
|
+
* Build the ragdoll where the skeleton is (or where `pose` says the bones
|
|
3114
|
+
* are, headless). Returns false when there is nothing to build from.
|
|
3115
|
+
*/
|
|
3116
|
+
activate(pose?: RagdollPose | undefined): boolean;
|
|
3117
|
+
/** Free the limbs and hand the skeleton back to the animation. */
|
|
3118
|
+
reset(): void;
|
|
3119
|
+
override update(dt: number): void;
|
|
3120
|
+
override free(): void;
|
|
3121
|
+
/** The velocity of the body this ragdoll falls out of — the first body up the tree. */
|
|
3122
|
+
private hostVelocity;
|
|
3123
|
+
}
|
|
3124
|
+
//#endregion
|
|
2612
3125
|
//#region src/3d/terrain/heightmap.d.ts
|
|
2613
3126
|
/**
|
|
2614
3127
|
* A smooth radial depression carved into the terrain — a lake/pond bowl. x/z
|
|
@@ -3023,15 +3536,27 @@ declare class River3D extends Node3D implements SunConsumer3D {
|
|
|
3023
3536
|
private rockScanAt;
|
|
3024
3537
|
private world;
|
|
3025
3538
|
private readonly _bodies;
|
|
3539
|
+
private cubeTarget;
|
|
3540
|
+
private cubeCamera;
|
|
3541
|
+
private lastSkyAt;
|
|
3542
|
+
private rippleFft;
|
|
3543
|
+
private rippleSpectrum;
|
|
3544
|
+
private fftUnsupported;
|
|
3026
3545
|
/** Loader hook: a malformed river fails at LOAD, not as an invisible ribbon. */
|
|
3027
3546
|
static validateJson(node: Node): void;
|
|
3028
3547
|
protected override _createObject3D(): Object3D;
|
|
3029
3548
|
override onReady(): void;
|
|
3030
3549
|
override onExitTree(): void;
|
|
3550
|
+
/** Said once when the node has no course to be a river along. */
|
|
3551
|
+
private warnedNoPath;
|
|
3031
3552
|
override update(dt: number): void;
|
|
3032
3553
|
override _syncObject3D(): void;
|
|
3033
3554
|
/** Rocks are picked per FRAME (nearest to the eye), scanned on a timer. */
|
|
3034
3555
|
_onRender3D(ctx: RenderContext3D): void;
|
|
3556
|
+
/** The sky cube: the world beyond the banks, from above the channel's middle. */
|
|
3557
|
+
private syncSky;
|
|
3558
|
+
/** The ripple FFT, advected by the fragment in the ribbon's own frame. */
|
|
3559
|
+
private syncRipple;
|
|
3035
3560
|
/**
|
|
3036
3561
|
* @internal Water surface height over a world point, or null where this
|
|
3037
3562
|
* river does not run — the question scattered vegetation asks before it
|
|
@@ -3263,7 +3788,10 @@ declare class Terrain3D extends Node3D {
|
|
|
3263
3788
|
* `heightAt`, the drape and the mesh all pick it up on their next rebuild.
|
|
3264
3789
|
*/
|
|
3265
3790
|
_setExternalChannel(owner: Node, specs: ChannelSpec[] | null): void;
|
|
3266
|
-
/**
|
|
3791
|
+
/**
|
|
3792
|
+
* Authored trenches plus the ones other nodes cut — every course flattened to
|
|
3793
|
+
* `[x, z]`, whichever spelling it was written in (see `course`).
|
|
3794
|
+
*/
|
|
3267
3795
|
private allChannels;
|
|
3268
3796
|
/** @internal The pure heightfield (lazily built — physics pulls this). */
|
|
3269
3797
|
_heightmap(): Heightmap;
|
|
@@ -3407,6 +3935,19 @@ declare class Tree3D extends Node3D {
|
|
|
3407
3935
|
* it (keeps retrying until a terrain appears), false disables draping.
|
|
3408
3936
|
*/
|
|
3409
3937
|
drape: boolean | null;
|
|
3938
|
+
/**
|
|
3939
|
+
* Keep trunks out of standing and running water (default true) — a valley a
|
|
3940
|
+
* rill runs through has a grove on its banks, not trees in the current.
|
|
3941
|
+
*
|
|
3942
|
+
* `Foliage3D` and `Flowers3D` have had this since they were written, with the
|
|
3943
|
+
* same default and the same reason; the TREE — the tallest thing in a
|
|
3944
|
+
* landscape and the one that most obviously does not grow midstream — did
|
|
3945
|
+
* not. Measured on a river-valley game: two of twenty-two trunks stood in the
|
|
3946
|
+
* rill.
|
|
3947
|
+
*
|
|
3948
|
+
* `false` is the mangrove, the cypress swamp and the flooded forest.
|
|
3949
|
+
*/
|
|
3950
|
+
avoidWater: boolean;
|
|
3410
3951
|
/** Node path to the Terrain3D to drape onto ('' = auto-find the first one). */
|
|
3411
3952
|
terrain: string;
|
|
3412
3953
|
/** Resolved drape target + the grove's world position, set per rebuild. */
|
|
@@ -3465,6 +4006,18 @@ declare class Tree3D extends Node3D {
|
|
|
3465
4006
|
private buildBarkMaterial;
|
|
3466
4007
|
private loadBarkTexture;
|
|
3467
4008
|
/** Per-instance placement + jitter — ONE rng draw order for both paths. */
|
|
4009
|
+
/**
|
|
4010
|
+
* Where every trunk of this grove stands, in WORLD coordinates.
|
|
4011
|
+
*
|
|
4012
|
+
* `drape` is the prop that puts a grove on the ground it grows from, and
|
|
4013
|
+
* nothing could ask whether it had. `UiMinimap.markers()` and
|
|
4014
|
+
* `HudLayer.focusables()` are the same accessor for the same reason: a
|
|
4015
|
+
* feature whose effect no harness can read is a feature nobody checks.
|
|
4016
|
+
*
|
|
4017
|
+
* Recomputed from the seed rather than read back off the InstancedMesh, so it
|
|
4018
|
+
* answers headless too — where there is no mesh at all.
|
|
4019
|
+
*/
|
|
4020
|
+
trunks(): Array<[number, number, number]>;
|
|
3468
4021
|
private scatter;
|
|
3469
4022
|
private disposeMeshes;
|
|
3470
4023
|
override free(): void;
|
|
@@ -3613,6 +4166,14 @@ declare class Water3D extends Node3D implements RenderHook3D, SunConsumer3D {
|
|
|
3613
4166
|
* as a calm sea; 0.08 = the noisier ported-source look. */
|
|
3614
4167
|
waveHeight: number;
|
|
3615
4168
|
waveSpeed: number;
|
|
4169
|
+
/**
|
|
4170
|
+
* How hard this water holds a floating body back, per second at full
|
|
4171
|
+
* submersion — a pushed crate loses `drag` of its velocity each second (and
|
|
4172
|
+
* its spin likewise), scaled by how much of it is under. `0` is ice; `1.5`
|
|
4173
|
+
* lets a boat coast a few lengths; `6` is syrup. Only bodies with `buoyancy`
|
|
4174
|
+
* feel it (see `RigidBody3D.buoyancy`).
|
|
4175
|
+
*/
|
|
4176
|
+
drag: number;
|
|
3616
4177
|
/** 'fancy' shader water (default) | 'simple' cheap CPU sine material. */
|
|
3617
4178
|
quality: string;
|
|
3618
4179
|
/** Fancy ramp overrides: `{trough?, surface?, peak?}` hex strings. */
|
|
@@ -3628,6 +4189,16 @@ declare class Water3D extends Node3D implements RenderHook3D, SunConsumer3D {
|
|
|
3628
4189
|
*/
|
|
3629
4190
|
mirror: boolean;
|
|
3630
4191
|
/**
|
|
4192
|
+
* Screen-space reflections (fancy only, default on): the scene ABOVE the
|
|
4193
|
+
* waterline is rendered once at half resolution and every water pixel
|
|
4194
|
+
* marches its reflected ray through that image — so a rock, a pier, a
|
|
4195
|
+
* wader or a boat is mirrored on the water WITHOUT the planar `mirror`
|
|
4196
|
+
* pass. What the screen cannot see (behind the camera, off its edges)
|
|
4197
|
+
* falls back to the sky cube, which is why a mirror-calm lake still wants
|
|
4198
|
+
* `mirror: true`; with `mirror` on this is skipped as redundant.
|
|
4199
|
+
*/
|
|
4200
|
+
ssr: boolean;
|
|
4201
|
+
/**
|
|
3631
4202
|
* Milliseconds between planar-mirror re-renders. A reflection seen through a
|
|
3632
4203
|
* rippling surface does not need 60 Hz — 33 ms halves the pass's cost and
|
|
3633
4204
|
* nobody can tell. 0 re-renders every frame.
|
|
@@ -3688,6 +4259,30 @@ declare class Water3D extends Node3D implements RenderHook3D, SunConsumer3D {
|
|
|
3688
4259
|
/** Primary swell wavelength in meters (the two crossing trains derive). */
|
|
3689
4260
|
swellWavelength: number;
|
|
3690
4261
|
/**
|
|
4262
|
+
* The bottom under this water: a node path to a Terrain3D (fancy only). With
|
|
4263
|
+
* it the swell KNOWS the beach — waves slow and rise as the bottom comes up
|
|
4264
|
+
* (Green's law), their crests peak, and at 0.78× the depth they BREAK into
|
|
4265
|
+
* foam, with spray sprites bursting where the foam fronts pass. Sampled
|
|
4266
|
+
* once into a 256² depth grid over the terrain's footprint; beyond it the
|
|
4267
|
+
* water is assumed deep. Pair with `swell` (the waves that shoal) and
|
|
4268
|
+
* `shoreWaves` (the foam fronts the spray rides).
|
|
4269
|
+
*/
|
|
4270
|
+
bed: string;
|
|
4271
|
+
/**
|
|
4272
|
+
* Wind speed in m/s — THE realistic-sea dial (fancy only; 0 = off). Above 0
|
|
4273
|
+
* the surface stops being a noise field and becomes a JONSWAP spectrum:
|
|
4274
|
+
* thousands of waves at every wavelength and heading, each moving at the
|
|
4275
|
+
* speed deep water gives it, inverse-FFT'd on the GPU every frame into a
|
|
4276
|
+
* tiling patch with real crest shapes, choppy horizontal drag and whitecaps
|
|
4277
|
+
* born where the surface folds. The wind blows toward `swellDirectionDeg`.
|
|
4278
|
+
* 4 = a light breeze (ripples, 20 cm), 7 = a fresh breeze (1 m waves),
|
|
4279
|
+
* 12 = rough. The CPU twin (buoyancy, waders) sums the same spectrum.
|
|
4280
|
+
*/
|
|
4281
|
+
wind: number;
|
|
4282
|
+
/** Horizontal drag of the FFT sea toward its crests, 0..~1.5 — narrow
|
|
4283
|
+
* crests, broad troughs; past ~1.2 the surface folds and foams everywhere. */
|
|
4284
|
+
choppiness: number;
|
|
4285
|
+
/**
|
|
3691
4286
|
* GERSTNER pinch on the swell: 0 keeps the legacy height-only trains, 1 is
|
|
3692
4287
|
* maximum trochoid (crests narrow to a peak, troughs go broad). It also
|
|
3693
4288
|
* decides where whitecaps break — the surface's Jacobian collapses on a
|
|
@@ -3750,6 +4345,26 @@ declare class Water3D extends Node3D implements RenderHook3D, SunConsumer3D {
|
|
|
3750
4345
|
/** Per-frame scene pre-pass: depth (absorption/foam) + color grab (refraction). */
|
|
3751
4346
|
private scenePassTarget;
|
|
3752
4347
|
private mirrorTarget;
|
|
4348
|
+
/** Half-res render of the scene ABOVE the waterline — what SSR reflects. */
|
|
4349
|
+
private aboveTarget;
|
|
4350
|
+
private readonly ssrViewProj;
|
|
4351
|
+
/** The FFT sea (wind > 0): the GPU passes, and the CPU spectrum they share. */
|
|
4352
|
+
private seaFft;
|
|
4353
|
+
private seaFftUnsupported;
|
|
4354
|
+
private spectrum;
|
|
4355
|
+
private spectrumKey;
|
|
4356
|
+
private uploadedSpectrumKey;
|
|
4357
|
+
private rippleFft;
|
|
4358
|
+
private rippleSpectrum;
|
|
4359
|
+
private rippleKey;
|
|
4360
|
+
private uploadedRippleKey;
|
|
4361
|
+
/** The bed depth grid (see `bed`), its footprint, and the spray that rides it. */
|
|
4362
|
+
private bedTexture;
|
|
4363
|
+
private bedRect;
|
|
4364
|
+
private bedKey;
|
|
4365
|
+
private spray;
|
|
4366
|
+
/** Vertex spacing of the fancy grid — the mip the vertex shader reads at. */
|
|
4367
|
+
private fancySegments;
|
|
3753
4368
|
private readonly mirrorCamera;
|
|
3754
4369
|
private readonly mirrorMatrix;
|
|
3755
4370
|
private lastMirrorAt;
|
|
@@ -3864,6 +4479,11 @@ declare class Water3D extends Node3D implements RenderHook3D, SunConsumer3D {
|
|
|
3864
4479
|
private renderCutoutMasks;
|
|
3865
4480
|
private syncFancy;
|
|
3866
4481
|
/**
|
|
4482
|
+
* The bed depth grid and the spray that rides it. Built once per `bed`
|
|
4483
|
+
* (terrain heights are static); torn down when the path is cleared.
|
|
4484
|
+
*/
|
|
4485
|
+
private syncBed;
|
|
4486
|
+
/**
|
|
3867
4487
|
* @internal Environment-sky sun hand-off (see {@link SunConsumer3D}): the
|
|
3868
4488
|
* sky's sun drives the glint ONLY while the `sunDirection` prop sits at its
|
|
3869
4489
|
* schema default — an explicitly authored prop always wins. Runs right
|
|
@@ -3884,6 +4504,22 @@ declare class Water3D extends Node3D implements RenderHook3D, SunConsumer3D {
|
|
|
3884
4504
|
*/
|
|
3885
4505
|
heightAt(x: number, z: number): number;
|
|
3886
4506
|
/**
|
|
4507
|
+
* How far below THIS water's surface a world point is, in metres — `0` when
|
|
4508
|
+
* it is above the surface, and `0` when it is outside the pool's footprint.
|
|
4509
|
+
*
|
|
4510
|
+
* `heightAt` answers the surface height everywhere, including a hundred
|
|
4511
|
+
* metres inland, so the obvious spelling of "am I under water"
|
|
4512
|
+
* (`y < water.heightAt(x, z)`) says yes for a player standing in a cellar
|
|
4513
|
+
* well below sea level. The footprint-aware version lived inside
|
|
4514
|
+
* `CharacterController3D`'s swim spring and nothing else could reach it —
|
|
4515
|
+
* and every underwater game needs it for a breath meter, muffled audio, a
|
|
4516
|
+
* "you surfaced" banner, or an enemy that only strikes below.
|
|
4517
|
+
*
|
|
4518
|
+
* The WAVE is included: a point just under a trough is out, and the same
|
|
4519
|
+
* point under a crest is in, which is what a swimmer feels.
|
|
4520
|
+
*/
|
|
4521
|
+
depthAt(x: number, y: number, z: number): number;
|
|
4522
|
+
/**
|
|
3887
4523
|
* @internal Water surface height over a world point, or null outside this
|
|
3888
4524
|
* surface's footprint — what scattered vegetation asks before it plants a
|
|
3889
4525
|
* blade (see {@link WetSurface}). The STILL level, not the wave: grass does
|
|
@@ -3892,6 +4528,19 @@ declare class Water3D extends Node3D implements RenderHook3D, SunConsumer3D {
|
|
|
3892
4528
|
_waterYAt(x: number, z: number): number | null;
|
|
3893
4529
|
/** Base wave height at world (x, z) — the CPU twin of the active shader.
|
|
3894
4530
|
* Ripples are excluded on purpose: a splash must not re-trigger itself. */
|
|
4531
|
+
/**
|
|
4532
|
+
* The sea's spectrum, or null when there is no wind (or the tier collapsed
|
|
4533
|
+
* the surface to the simple shader, whose CPU waves are its own). Built on
|
|
4534
|
+
* the CPU once per (wind, heading, choppiness) and shared by the GPU upload
|
|
4535
|
+
* and the headless twin — one sea, two evaluators.
|
|
4536
|
+
*/
|
|
4537
|
+
private seaSpectrum;
|
|
4538
|
+
/**
|
|
4539
|
+
* The ripple layer's spectrum: the sea's own wind when it blows, else the
|
|
4540
|
+
* breeze that puts wind ripple on a pool — its ENERGY is irrelevant (the
|
|
4541
|
+
* layer is normalized to `detailStrength` by rms slope), only its shape.
|
|
4542
|
+
*/
|
|
4543
|
+
private rippleSpectrumFor;
|
|
3895
4544
|
private waveOffsetAt;
|
|
3896
4545
|
}
|
|
3897
4546
|
//#endregion
|
|
@@ -3948,6 +4597,29 @@ declare class WaterCutout3D extends Node3D {
|
|
|
3948
4597
|
/** How many cutouts one Water3D reads (the nearest ones win). */
|
|
3949
4598
|
declare const WATER_CUTOUT_MAX = 4;
|
|
3950
4599
|
//#endregion
|
|
4600
|
+
//#region src/3d/nodes/weather-3d.d.ts
|
|
4601
|
+
declare class Weather3D extends Particles3D {
|
|
4602
|
+
static override readonly typeName: string;
|
|
4603
|
+
static override readonly props: PropSchema;
|
|
4604
|
+
kind: string;
|
|
4605
|
+
intensity: number;
|
|
4606
|
+
radius: number;
|
|
4607
|
+
height: number;
|
|
4608
|
+
wind: number[];
|
|
4609
|
+
follow: string;
|
|
4610
|
+
/** Rain is a streak; snow keeps the soft flake the particle system draws. */
|
|
4611
|
+
protected override sprite(): DataTexture;
|
|
4612
|
+
private tunedFor;
|
|
4613
|
+
private camera;
|
|
4614
|
+
private cameraScanIn;
|
|
4615
|
+
override onEnterTree(): void;
|
|
4616
|
+
/** Set the inherited particle props from `kind` — once, and again if it changes. */
|
|
4617
|
+
private tune;
|
|
4618
|
+
private tuning;
|
|
4619
|
+
private followed;
|
|
4620
|
+
override update(dt: number): void;
|
|
4621
|
+
}
|
|
4622
|
+
//#endregion
|
|
3951
4623
|
//#region src/3d/register.d.ts
|
|
3952
4624
|
/**
|
|
3953
4625
|
* Register the 3D node taxonomy (and the core nodes). Call once in your game
|
|
@@ -4287,9 +4959,31 @@ interface SyncScratch {
|
|
|
4287
4959
|
parent: Object3D;
|
|
4288
4960
|
}>;
|
|
4289
4961
|
state: WalkState;
|
|
4962
|
+
blend: CameraBlend;
|
|
4963
|
+
}
|
|
4964
|
+
/**
|
|
4965
|
+
* The picture's flight from one camera to the next. `lastPos/Quat/Fov` is the
|
|
4966
|
+
* pose the picture was LAST drawn from — a blend already flying included, so a
|
|
4967
|
+
* second switch mid-blend starts from where the picture is, not from a camera
|
|
4968
|
+
* it never reached.
|
|
4969
|
+
*/
|
|
4970
|
+
interface CameraBlend {
|
|
4971
|
+
cam: PerspectiveCamera;
|
|
4972
|
+
active: boolean;
|
|
4973
|
+
t: number;
|
|
4974
|
+
seconds: number;
|
|
4975
|
+
fromPos: Vector3;
|
|
4976
|
+
fromQuat: Quaternion;
|
|
4977
|
+
fromFov: number;
|
|
4978
|
+
lastNode: Camera3D | null;
|
|
4979
|
+
lastPos: Vector3;
|
|
4980
|
+
lastQuat: Quaternion;
|
|
4981
|
+
lastFov: number;
|
|
4290
4982
|
}
|
|
4291
4983
|
interface SyncOptions {
|
|
4292
4984
|
assets?: AssetStore3D;
|
|
4985
|
+
/** Real seconds since the last frame — what a camera blend flies on. */
|
|
4986
|
+
dt?: number;
|
|
4293
4987
|
/** Sync `static: true` subtrees every frame anyway (the editor's edit mode). */
|
|
4294
4988
|
ignoreStatic?: boolean;
|
|
4295
4989
|
/**
|
|
@@ -4400,4 +5094,4 @@ declare function createNavDebugNode(nav: TerrainNav, opts?: {
|
|
|
4400
5094
|
name?: string;
|
|
4401
5095
|
}): InstancedMesh3D;
|
|
4402
5096
|
//#endregion
|
|
4403
|
-
export { Area3D, AssetStore3D, type BedSampler, Billboard3D, type BillboardGroupMode, BoneAttachment3D, BoneLookAt3D, Camera3D, CharacterBody3D, CharacterController3D, type CreateGame3DOptions, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, type DownhillTraceOptions, Environment3D, type Environment3DConfig, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, type FlowerVariety, Flowers3D, type FogEnvironment, Foliage3D, type FoliageKind, type FoliageStyle, type FrameDiff, type FrameSignature, type FrameStats, type FrameStatsOptions, type Game3D, type GridCell, type HeightSampler, type Heightmap, type HeightmapOptions, InstancedMesh3D, Joint3D, type JointType3D, LoftMesh3D, type LoftSection, MeshInstance3D, type MeshKind, type MeshMaterialProps, type ModelEntry, type ModelFacts, ModelInstance3D, type ModelVerdict, Node3D, OmniLight3D, Particles3D, Physics3D, type Physics3DOptions, PhysicsBody3D, QUARTER_PITCH, type RenderContext3D, type RenderHook3D, Renderer3D, type Renderer3DOptions, type Rig, type RigView, RigidBody3D, type Ripple, River3D, type RiverCarveOptions, type RiverCoverageGap, type RiverHit, type RiverRing, type RiverRingOptions, SIGNATURE_GRID, type SceneJson, type ShadowsEnvironment, type SkyEnvironment, SpotLight3D, StaticBody3D, type SunConsumer3D, type SyncOptions, type SyncResult, TERRAIN_THEMES, Terrain3D, type TerrainLayer, type TerrainNav, type TerrainNavOptions, type TerrainTheme, TextureCache3D, type TextureSpec, Trail3D, Tree3D, type TreeTier, type TreeType, VOXEL_PALETTE, type VoxelBlock, VoxelGrid3D, WATER_CUTOUT_MAX, WATER_MAX_RIPPLES, Water3D, WaterCutout3D, acquireOwnTexture, acquireTexture, applyQualityTier3D, buildHeightmap, buildRiverRings, buildTerrainNav, cameraRelative, createGame3D, createNavDebugNode, diffSignatures, diffText, enablePhysics3D, findRiverCoverageGaps, frameSignature, frameStats, frameText, horizonColorFromSky, isWebGLAvailable, keyboardIntensity, modelVerdict, movementState, parseEnvironment3D, projectToRiver, registerNodes3D, resolveFlowerDensity, rigPose, riverCarveChannels, riverStepFor, setEnvironment3D, showBootFailure, smoothCourse, splatWeights, sunDirectionFromElevationAzimuth, sunDirectionFromSky, syncTree, terrainThemeLayers, traceDownhillPath, verdictText };
|
|
5097
|
+
export { Area3D, AssetStore3D, type BedSampler, Billboard3D, type BillboardGroupMode, type Boid, BoneAttachment3D, BoneLookAt3D, Camera3D, CharacterBody3D, CharacterController3D, type CreateGame3DOptions, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, type DownhillTraceOptions, Environment3D, type Environment3DConfig, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, Flock3D, type FlowerVariety, Flowers3D, type FogEnvironment, Foliage3D, type FoliageKind, type FoliageStyle, type FrameDiff, type FrameSignature, type FrameStats, type FrameStatsOptions, type Game3D, type GridCell, type HeightSampler, type Heightmap, type HeightmapOptions, InstancedMesh3D, Joint3D, type JointType3D, type Limb, LoftMesh3D, type LoftSection, MeshInstance3D, type MeshKind, type MeshMaterialProps, type ModelEntry, type ModelFacts, ModelInstance3D, type ModelVerdict, Node3D, OmniLight3D, Particles3D, Physics3D, type Physics3DOptions, PhysicsBody3D, QUARTER_PITCH, Ragdoll3D, type RagdollPose, type RenderContext3D, type RenderHook3D, Renderer3D, type Renderer3DOptions, type Rig, type RigView, RigidBody3D, type Ripple, River3D, type RiverCarveOptions, type RiverCoverageGap, type RiverHit, type RiverRing, type RiverRingOptions, SIGNATURE_GRID, type SceneJson, type ShadowsEnvironment, type SkyEnvironment, SpotLight3D, StaticBody3D, type SunConsumer3D, type SyncOptions, type SyncResult, TERRAIN_THEMES, Terrain3D, type TerrainLayer, type TerrainNav, type TerrainNavOptions, type TerrainTheme, TextureCache3D, type TextureSpec, Trail3D, Tree3D, type TreeTier, type TreeType, VOXEL_PALETTE, Vehicle3D, type VoxelBlock, VoxelGrid3D, WATER_CUTOUT_MAX, WATER_MAX_RIPPLES, Water3D, WaterCutout3D, Weather3D, type WheelSpec, type WheelState, acquireOwnTexture, acquireTexture, applyQualityTier3D, buildHeightmap, buildRiverRings, buildTerrainNav, cameraRelative, createGame3D, createNavDebugNode, diffSignatures, diffText, enablePhysics3D, findRiverCoverageGaps, frameSignature, frameStats, frameText, horizonColorFromSky, isWebGLAvailable, keyboardIntensity, modelVerdict, movementState, parseEnvironment3D, projectToRiver, registerNodes3D, resolveFlowerDensity, rigPose, riverCarveChannels, riverStepFor, setEnvironment3D, showBootFailure, smoothCourse, splatWeights, sunDirectionFromElevationAzimuth, sunDirectionFromSky, syncTree, terrainThemeLayers, traceDownhillPath, verdictText };
|