lecodes-sdk 0.20.0 → 1.0.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/dist/global.d.ts +48 -5
- package/dist/inject.js +361 -260
- package/dist/types/audio/Bus.d.ts +45 -0
- package/dist/types/audio/Sound.d.ts +28 -0
- package/dist/types/audio/Voice.d.ts +27 -0
- package/dist/types/audio/audio.d.ts +83 -0
- package/dist/types/audio/support.d.ts +1 -0
- package/dist/types/canvas/Canvas.d.ts +2 -0
- package/dist/types/gl/DecalSet.d.ts +148 -0
- package/dist/types/gl/Geometry.d.ts +17 -0
- package/dist/types/gl/Light.d.ts +7 -0
- package/dist/types/gl/Lightmap.d.ts +9 -0
- package/dist/types/gl/Material.d.ts +90 -2
- package/dist/types/gl/Mesh.d.ts +18 -1
- package/dist/types/gl/Model.d.ts +34 -0
- package/dist/types/gl/Particles.d.ts +13 -0
- package/dist/types/gl/Scene.d.ts +23 -0
- package/dist/types/gl/Texture.d.ts +29 -1
- package/dist/types/gl/animation/AnimationClip.d.ts +25 -12
- package/dist/types/gl/animation/DynamicBone.d.ts +173 -0
- package/dist/types/gl/{IK.d.ts → animation/IK.d.ts} +4 -4
- package/dist/types/gl/{Locomotion.d.ts → animation/Locomotion.d.ts} +6 -6
- package/dist/types/gl/animation/core.d.ts +15 -10
- package/dist/types/gl/audio/AudioSource.d.ts +60 -0
- package/dist/types/gl/audio/AudioZone.d.ts +32 -0
- package/dist/types/gl/audio/SceneAudio.d.ts +11 -0
- package/dist/types/gl/{NavAgent.d.ts → nav/NavAgent.d.ts} +4 -4
- package/dist/types/gl/{NavMesh.d.ts → nav/NavMesh.d.ts} +4 -4
- package/dist/types/gl/{CharacterController.d.ts → physics/CharacterController.d.ts} +5 -5
- package/dist/types/gl/{Physics.d.ts → physics/Physics.d.ts} +6 -5
- package/dist/types/gl/{Ragdoll.d.ts → physics/Ragdoll.d.ts} +4 -4
- package/dist/types/gl/{Shape.d.ts → physics/Shape.d.ts} +3 -3
- package/dist/types/gl/{Trigger.d.ts → physics/Trigger.d.ts} +2 -2
- package/dist/types/gl/state.d.ts +0 -1
- package/dist/types/gl/{Terrain.d.ts → terrain/Terrain.d.ts} +6 -6
- package/dist/types/gl/{terrainMesh.d.ts → terrain/terrainMesh.d.ts} +1 -1
- package/dist/types/gl/vehicle/Vehicle.d.ts +300 -0
- package/dist/types/gl/vehicle/Wheel.d.ts +147 -0
- package/dist/types/inject.d.ts +33 -21
- package/dist/types/runtime/files.d.ts +24 -1
- package/dist/types/runtime/input.d.ts +11 -0
- package/dist/types/scene/defineScene.d.ts +10 -3
- package/dist/types/ui/UIImage.d.ts +15 -5
- package/dist/types.json +1 -1
- package/package.json +1 -1
- package/prompts/README.md +142 -142
- package/prompts/dist/2d-game.md +408 -197
- package/prompts/dist/3d-app.md +491 -166
- package/prompts/dist/ar-app.md +373 -163
- package/prompts/dist/design.md +83 -87
- package/prompts/dist/ui-app.md +325 -136
- package/src/audio/Bus.ts +102 -0
- package/src/audio/Sound.ts +96 -0
- package/src/audio/Voice.ts +102 -0
- package/src/audio/audio.ts +161 -0
- package/src/audio/support.ts +6 -0
- package/src/bridges.d.ts +279 -32
- package/src/canvas/Canvas.ts +21 -0
- package/src/compile/__tests__/compile.test.ts +11 -0
- package/src/compile/compileProject.ts +30 -15
- package/src/compile/header.ts +6 -3
- package/src/compile/index.ts +4 -0
- package/src/compile/sceneEditor.ts +42 -1
- package/src/core/Aspect.ts +33 -8
- package/src/g2/Scene2D.ts +7 -0
- package/src/gl/CameraPlace.ts +52 -52
- package/src/gl/DecalSet.ts +360 -0
- package/src/gl/Geometry.ts +348 -279
- package/src/gl/Light.ts +16 -0
- package/src/gl/Lightmap.ts +35 -7
- package/src/gl/Material.ts +173 -4
- package/src/gl/Mesh.ts +120 -83
- package/src/gl/Model.ts +33 -1
- package/src/gl/Node.ts +1 -1
- package/src/gl/Particles.ts +21 -3
- package/src/gl/Scene.ts +41 -7
- package/src/gl/Texture.ts +43 -3
- package/src/gl/animation/AnimationClip.ts +43 -20
- package/src/gl/animation/Animator.ts +4 -3
- package/src/gl/animation/DynamicBone.ts +459 -0
- package/src/gl/{IK.ts → animation/IK.ts} +4 -4
- package/src/gl/{Locomotion.ts → animation/Locomotion.ts} +7 -7
- package/src/gl/animation/core.ts +20 -15
- package/src/gl/audio/AudioSource.ts +113 -0
- package/src/gl/audio/AudioZone.ts +75 -0
- package/src/gl/audio/SceneAudio.ts +26 -0
- package/src/gl/{NavAgent.ts → nav/NavAgent.ts} +5 -5
- package/src/gl/{NavMesh.ts → nav/NavMesh.ts} +8 -8
- package/src/gl/{CharacterController.ts → physics/CharacterController.ts} +5 -5
- package/src/gl/{Physics.ts → physics/Physics.ts} +12 -5
- package/src/gl/{Ragdoll.ts → physics/Ragdoll.ts} +272 -270
- package/src/gl/{Shape.ts → physics/Shape.ts} +3 -3
- package/src/gl/{Trigger.ts → physics/Trigger.ts} +2 -2
- package/src/gl/{physicsEvents.ts → physics/physicsEvents.ts} +1 -1
- package/src/gl/scenarios.ts +291 -291
- package/src/gl/state.ts +1 -1
- package/src/gl/{Terrain.ts → terrain/Terrain.ts} +10 -10
- package/src/gl/{terrainMesh.ts → terrain/terrainMesh.ts} +1 -1
- package/src/gl/vehicle/Vehicle.ts +666 -0
- package/src/gl/vehicle/Wheel.ts +290 -0
- package/src/inject.ts +226 -212
- package/src/runtime/files.ts +32 -2
- package/src/runtime/input.ts +6 -1
- package/src/scene/defineScene.ts +26 -10
- package/src/scene/gizmos.ts +148 -148
- package/src/scene/level.ts +2 -2
- package/src/ui/UIImage.ts +21 -7
- package/dist/types/gl/Gearbox.d.ts +0 -86
- package/dist/types/gl/Vehicle.d.ts +0 -191
- package/dist/types/gl/Wheel.d.ts +0 -95
- package/src/gl/Gearbox.ts +0 -212
- package/src/gl/Vehicle.ts +0 -473
- package/src/gl/Wheel.ts +0 -240
- /package/dist/types/gl/{physicsEvents.d.ts → physics/physicsEvents.d.ts} +0 -0
package/dist/types/gl/Model.d.ts
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
import { type FetchResponse } from "../runtime/fetch";
|
|
2
2
|
import { Node } from "./Node";
|
|
3
3
|
import { Animator, type LodMode } from "./animation/Animator";
|
|
4
|
+
/** One polygon under a screen point — what `Model.pickTriangle` returns. `bones` are the vertex's raw
|
|
5
|
+
* JOINTS_0 / WEIGHTS_0 pairs (weight > 0; empty = unweighted), `bind` its position in mesh space,
|
|
6
|
+
* `world` its skinned position this frame. */
|
|
7
|
+
export interface TrianglePick {
|
|
8
|
+
/** the Model's root entity, and the mesh node's own entity (0 when the host has no entity for it) */
|
|
9
|
+
entity: number;
|
|
10
|
+
node: number;
|
|
11
|
+
nodeName: string;
|
|
12
|
+
mesh: string;
|
|
13
|
+
primitive: number;
|
|
14
|
+
material: string;
|
|
15
|
+
/** triangle index within the primitive (index-buffer order), and whether the ray came from behind */
|
|
16
|
+
triangle: number;
|
|
17
|
+
backface: boolean;
|
|
18
|
+
distance: number;
|
|
19
|
+
point: [number, number, number];
|
|
20
|
+
bary: [number, number, number];
|
|
21
|
+
skin: string;
|
|
22
|
+
vertices: {
|
|
23
|
+
index: number;
|
|
24
|
+
bind: [number, number, number];
|
|
25
|
+
world: [number, number, number];
|
|
26
|
+
bones: {
|
|
27
|
+
name: string;
|
|
28
|
+
weight: number;
|
|
29
|
+
}[];
|
|
30
|
+
}[];
|
|
31
|
+
}
|
|
4
32
|
export declare class Model extends Node {
|
|
5
33
|
/** The model's Animator — always present, its clip table = the GLB's embedded clips. Configure
|
|
6
34
|
* more (external clips, blend spaces, layers) with `model.aspect(Animator, {...})`. */
|
|
@@ -31,6 +59,12 @@ export declare class Model extends Node {
|
|
|
31
59
|
get lod(): LodMode;
|
|
32
60
|
set lod(v: LodMode);
|
|
33
61
|
private static _cullDefault;
|
|
62
|
+
/** DEBUG: the closest polygon of this model under a screen point (logical px — `Input.mouse.position`,
|
|
63
|
+
* a touch event's clientX/Y), tested against the CPU-skinned CURRENT pose, both faces. Names the
|
|
64
|
+
* triangle, its three vertices (bind + skinned positions) and their raw bone weights, so a stretched
|
|
65
|
+
* or misbound polygon can be traced to its binding. One full CPU skin of the model per call: click-rate
|
|
66
|
+
* only. null = miss, or a host without the pick (desktop today). */
|
|
67
|
+
pickTriangle(screenX: number, screenY: number): TrianglePick | null;
|
|
34
68
|
/** Duplicate this model — a deep copy of the GLB (meshes, skeleton, animation clips), attached to
|
|
35
69
|
* the same parent and scene and sharing this model's current transform. The clone has its own
|
|
36
70
|
* independent animation state (reach it via clone.anim). Mirrors this model's culling flag. */
|
|
@@ -116,6 +116,12 @@ type Noise = {
|
|
|
116
116
|
strength?: number;
|
|
117
117
|
frequency?: number;
|
|
118
118
|
speed?: number;
|
|
119
|
+
/** How much of the displacement a particle earns with AGE (default 0 = all of it from birth).
|
|
120
|
+
* The field is sampled by position, so at 0 every particle born at the same spot is pushed the
|
|
121
|
+
* same way and a plume's root wanders off its emitter by up to `strength` metres; at 1 a particle
|
|
122
|
+
* is born exactly where the emitter put it and drifts into the field over its life — what you
|
|
123
|
+
* want whenever the source is visible (an exhaust pipe, a contact patch, a muzzle). */
|
|
124
|
+
ramp?: number;
|
|
119
125
|
};
|
|
120
126
|
/** Ground plane for bouncing particles (all render modes). `height` is in the simulation space:
|
|
121
127
|
* world y with `space: 'world'`, emitter-local y otherwise. */
|
|
@@ -169,6 +175,11 @@ export type ParticlesOptions = ParticlesMaterialOptions & {
|
|
|
169
175
|
* without this the engine picks who covers whom per frame (smoke popping over a fireball).
|
|
170
176
|
* Default 0; a fireball wants 2, its smoke 1, a smoke trail -1. */
|
|
171
177
|
order?: number;
|
|
178
|
+
/** Coarse draw order among ALL blended draws, 0 (first) … 7 (last) — see `Mesh.renderPriority`.
|
|
179
|
+
* Default 5: meshes sit at 4 and decals at 3, so smoke covers a car's glass and its skid marks
|
|
180
|
+
* whatever the camera does (the engine's depth sort compares object centres, and an emitter's
|
|
181
|
+
* centre says nothing about where its cloud is). `order` breaks ties inside one priority. */
|
|
182
|
+
renderPriority?: number;
|
|
172
183
|
shape?: Shape;
|
|
173
184
|
/** Extra velocity over life (radial burst that decays, axis drift) — see `VelocityOverLife`. */
|
|
174
185
|
velocityOverLife?: VelocityOverLife;
|
|
@@ -212,6 +223,8 @@ export declare class Particles extends Node {
|
|
|
212
223
|
set inheritVelocity(val: number);
|
|
213
224
|
set rateOverDistance(val: number);
|
|
214
225
|
set order(val: number);
|
|
226
|
+
/** Coarse draw order, 0 … 7 — see `Mesh.renderPriority`. Write-only. */
|
|
227
|
+
set renderPriority(v: number);
|
|
215
228
|
set velocityOverLife(v: VelocityOverLife);
|
|
216
229
|
set shape(shape: Shape);
|
|
217
230
|
/** (mesh mode) Replace the particle mesh; live particles keep flying as the new shape. */
|
package/dist/types/gl/Scene.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Presentable, type PresentOptions } from "../ui/presentable";
|
|
|
4
4
|
import type { ClickEvent, TouchStartEvent } from "../runtime/touch";
|
|
5
5
|
import type { FetchResponse } from "../runtime/fetch";
|
|
6
6
|
import { Camera } from "./Camera";
|
|
7
|
+
import { SceneAudio } from "./audio/SceneAudio";
|
|
7
8
|
import { type ControlsHandle, type ControlsOptions } from "./controls";
|
|
8
9
|
import { Material } from "./Material";
|
|
9
10
|
import { Node } from "./Node";
|
|
@@ -95,6 +96,9 @@ export type SceneOptions = {
|
|
|
95
96
|
* takes over). Unset keeps the host default (desktop 4×, mobile/web off). The biggest single
|
|
96
97
|
* fill-rate cost after resolution — turn it down on big screens before anything else. */
|
|
97
98
|
antialias?: boolean | 2 | 4;
|
|
99
|
+
/** Keep a stencil buffer for this scene (off by default: it costs memory and a clear per frame).
|
|
100
|
+
* Needed before any material's `stencil` test or write does anything. */
|
|
101
|
+
stencil?: boolean;
|
|
98
102
|
/** Render the 3D at this fraction of the viewport (0.25–1) and upscale; the UI stays at native
|
|
99
103
|
* resolution. A fixed, predictable cut of per-pixel GPU work — `0.75` is ~45 % cheaper and
|
|
100
104
|
* barely visible in motion, `0.5` quarters it. Headless renders ignore it. */
|
|
@@ -118,6 +122,10 @@ export type SceneOptions = {
|
|
|
118
122
|
* scene file — `env` is applied before the nodes build) and leaves already-loaded ones alone.
|
|
119
123
|
* On the desktop host `CREATOR_TEXTURE_ANISOTROPY` overrides it, for tuning without a rebuild. */
|
|
120
124
|
anisotropy?: number;
|
|
125
|
+
/** Engine-wide cap on texture size, 0 / unset = none (see `Texture.maxSize`): a KTX2 above it
|
|
126
|
+
* loses its top mip levels on load, a glTF image is downsampled. Applied before this scene's
|
|
127
|
+
* assets load; like `anisotropy` it does not touch textures already loaded. */
|
|
128
|
+
maxTextureSize?: number;
|
|
121
129
|
/** The look on an HDR display (a screen with headroom above SDR white — Apple XDR panels, the
|
|
122
130
|
* macOS host today); ignored on SDR. `strength` 0..1 is how much of the picture reaches for the
|
|
123
131
|
* display's headroom (0 only what SDR clipped, 1 nearly everything; default 0.35). `paperWhite`
|
|
@@ -132,6 +140,8 @@ export type SceneOptions = {
|
|
|
132
140
|
};
|
|
133
141
|
export declare class Scene implements Presentable {
|
|
134
142
|
readonly camera: Camera;
|
|
143
|
+
/** The listener + global 3D audio knobs (docs/audio-plan.md). */
|
|
144
|
+
readonly audio: SceneAudio;
|
|
135
145
|
readonly _touchStartListeners: Array<(ev: TouchStartEvent<Node | null>) => void>;
|
|
136
146
|
private _material?;
|
|
137
147
|
private static _active;
|
|
@@ -153,6 +163,19 @@ export declare class Scene implements Presentable {
|
|
|
153
163
|
setFog(options: FogOptions | false): void;
|
|
154
164
|
setMaterialGlobalParameter(i: number, x: number, y: number, z: number, w: number): void;
|
|
155
165
|
setAntialias(enabled: boolean, scale?: number): void;
|
|
166
|
+
/** Depth-reading effects on / off (a graphics-settings menu): soft particles and projected decals
|
|
167
|
+
* read the scene depth, which costs a depth pre-pass of every opaque draw (~12 % of a fill-bound
|
|
168
|
+
* frame). Off = hard-edged particles, no decals, no pre-pass. Engine-wide, live. */
|
|
169
|
+
setDepthEffects(enabled: boolean): void;
|
|
170
|
+
/** LOD distance (a graphics-settings menu): the engine's LOD thresholds × `bias`. 2 = every level
|
|
171
|
+
* switches at half the distance (a model must look twice as big on screen to keep its detail),
|
|
172
|
+
* 0.5 = full detail twice as far, 1 = the defaults. Engine-wide, live. Only GLBs that carry
|
|
173
|
+
* `_LOD<n>` meshes (`lecodes assets doctor --lod`) have levels to switch. */
|
|
174
|
+
setLodBias(bias: number): void;
|
|
175
|
+
/** Runtime form of `bloom` / `bloomIntensity` (a graphics-settings menu). */
|
|
176
|
+
setBloom(enabled: boolean, intensity?: number): void;
|
|
177
|
+
/** The scene's stencil buffer on / off (see `SceneOptions.stencil`). */
|
|
178
|
+
setStencil(enabled: boolean): void;
|
|
156
179
|
add(...nodes: Node[]): this;
|
|
157
180
|
remove(...nodes: Node[]): this;
|
|
158
181
|
/** Attach (and configure) a system, or reconfigure it if already present. Returns the scene typed
|
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
import { type FetchResponse, type File } from "../runtime/fetch";
|
|
2
|
+
/** `Texture.load` options. */
|
|
3
|
+
export type TextureLoadOptions = {
|
|
4
|
+
/** `true` (default): colour, stored sRGB. `false`: data (normal map, mask, heightmap) — kept linear. */
|
|
5
|
+
srgb?: boolean;
|
|
6
|
+
/** Ignore `Texture.maxSize` for this texture (a lightmap page, a lookup table). */
|
|
7
|
+
fullSize?: boolean;
|
|
8
|
+
};
|
|
2
9
|
export declare class Texture {
|
|
10
|
+
static _maxSize: number;
|
|
11
|
+
/** Engine-wide cap on texture size (a "texture quality" setting), 0 = none. A KTX2 wider or
|
|
12
|
+
* taller than this loses its top mip levels on load (nothing resampled, less memory and
|
|
13
|
+
* bandwidth), a glTF PNG/JPEG is downsampled. Reaches textures loaded AFTER it is set — a loaded
|
|
14
|
+
* level keeps its textures — so set it up front (`SceneOptions.maxTextureSize`, or before the
|
|
15
|
+
* level loads) and apply a menu change on the next level load. Lightmap pages are exempt
|
|
16
|
+
* (`TextureLoadOptions.fullSize`). A host may pin it (desktop `CREATOR_TEXTURE_MAX_SIZE`). */
|
|
17
|
+
static _anisotropy: number;
|
|
18
|
+
/** Engine-wide anisotropic filtering, 1 (off) … 16 (default 2; `SceneOptions.anisotropy` sets it up
|
|
19
|
+
* front). A sampler is baked when its texture is bound, so like `maxSize` this reaches textures
|
|
20
|
+
* loaded AFTER it — set it before the level loads. Measured on a lightmapped interior at 720p:
|
|
21
|
+
* 4× costs ~20 % of the frame over 1× on an integrated GPU. A host may pin it. */
|
|
22
|
+
static get anisotropy(): number;
|
|
23
|
+
static set anisotropy(level: number);
|
|
24
|
+
static get maxSize(): number;
|
|
25
|
+
static set maxSize(size: number);
|
|
3
26
|
readonly width: number;
|
|
4
27
|
readonly height: number;
|
|
5
28
|
/** Horizontal wrap mode (U). */
|
|
@@ -23,5 +46,10 @@ export declare class Texture {
|
|
|
23
46
|
}): Texture;
|
|
24
47
|
/** Re-upload a rectangle of a `fromPixels` texture (same channel count). */
|
|
25
48
|
update(x: number, y: number, width: number, height: number, data: Uint8Array): void;
|
|
26
|
-
|
|
49
|
+
/** Decode an image (PNG / JPG, or a KTX2 the core transcodes) into a texture. `srgb` (default
|
|
50
|
+
* true) says the bytes are COLOUR, stored sRGB so the GPU linearises them on sample; pass
|
|
51
|
+
* `false` for DATA — a normal map, a mask, a heightmap — which must come back as stored (a
|
|
52
|
+
* flat normal read through sRGB bends by ~35°). A KTX2 decides by its own header. Image
|
|
53
|
+
* textures get a mip chain (trilinear) on hosts that build one. */
|
|
54
|
+
static load(source: string | FetchResponse | File, options?: TextureLoadOptions): Promise<Texture>;
|
|
27
55
|
}
|
|
@@ -22,6 +22,19 @@ export type ClipInfo = {
|
|
|
22
22
|
duration: number;
|
|
23
23
|
trackCount: number;
|
|
24
24
|
};
|
|
25
|
+
/** What `AnimationClip.from(clip, …)` derives from a clip. */
|
|
26
|
+
export type DeriveOptions = {
|
|
27
|
+
/** The clip MIRRORED — left ↔ right, the motion on the other side of the body (a stop that brakes on the
|
|
28
|
+
* left foot brakes on the right). Derived on the rig of the clip's own file (joints pair by name, the
|
|
29
|
+
* sagittal plane comes from the rest pose), so the result is the same on every model: its contacts,
|
|
30
|
+
* phase, root motion and heading are the mirrored ones, its name is `<name>_M`. Only clips from a GLB
|
|
31
|
+
* carry a rig; a curve-built clip cannot be mirrored. */
|
|
32
|
+
mirror?: boolean;
|
|
33
|
+
/** Start of the window, seconds of the source (default 0). */
|
|
34
|
+
from?: number;
|
|
35
|
+
/** End of the window, seconds of the source (default the clip's end). */
|
|
36
|
+
to?: number;
|
|
37
|
+
};
|
|
25
38
|
export declare class AnimationClip {
|
|
26
39
|
/** Source name (the clip's name inside its file; `"clip"` for procedural clips). Informational —
|
|
27
40
|
* an Animator addresses clips by the key YOU give it. */
|
|
@@ -33,8 +46,8 @@ export declare class AnimationClip {
|
|
|
33
46
|
private constructor();
|
|
34
47
|
/** Mark a moment of the clip (SECONDS from its start) with an event name: `kick.addEvent(0.4, 'hit')`
|
|
35
48
|
* → `anim.on('hit', (clip, layer) => …)` fires when the playhead crosses it, loops included.
|
|
36
|
-
* Events are part of the clip: every model playing it gets them; `
|
|
37
|
-
* the
|
|
49
|
+
* Events are part of the clip: every model playing it gets them; `AnimationClip.from(clip, { from, to })`
|
|
50
|
+
* keeps the ones inside the window, re-timed. Chainable. */
|
|
38
51
|
addEvent(time: number, name: string): this;
|
|
39
52
|
private _pushEvents;
|
|
40
53
|
/** Load ONE clip from a GLB: the file's only/first clip, or the one named / at the given index. */
|
|
@@ -43,18 +56,18 @@ export declare class AnimationClip {
|
|
|
43
56
|
static loadAll(source: string | FetchResponse): Promise<Record<string, AnimationClip>>;
|
|
44
57
|
/** Build a clip from curves in code — no DCC needed. Keys are `[time, value]`; a track binds to the
|
|
45
58
|
* node of that name when the clip is used by an Animator (bones, or any child node). */
|
|
46
|
-
static
|
|
47
|
-
/** A
|
|
48
|
-
* (`
|
|
49
|
-
* action,
|
|
59
|
+
static fromCurves(def: ClipDef): AnimationClip;
|
|
60
|
+
/** A NEW clip derived from `clip`: its mirror (`{ mirror: true }` — the other side of the body), a window
|
|
61
|
+
* of it (`{ from, to }` seconds of the source, re-timed to 0; array-slice semantics), or both. Cut a
|
|
62
|
+
* too-long take down to the action, carve several sub-clips out of one packed timeline, get the
|
|
63
|
+
* left-footed stop from the right-footed one:
|
|
50
64
|
*
|
|
51
|
-
* clips: { Kick:
|
|
65
|
+
* clips: { Kick: AnimationClip.from(kick, { from: 0.2, to: 1.1 }), StopM: AnimationClip.from(stop, { mirror: true }) }
|
|
52
66
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
|
|
57
|
-
slice(start: number, end?: number): AnimationClip;
|
|
67
|
+
* A window drops the keys outside it and interpolates exact boundary values in, so the clip starts and
|
|
68
|
+
* ends precisely on the source's pose at the cut points. Everything downstream (blend spaces, events'
|
|
69
|
+
* times, root motion, foot contacts, phase sync) sees a normal clip. */
|
|
70
|
+
static from(clip: AnimationClip, options: DeriveOptions): AnimationClip;
|
|
58
71
|
private static _label;
|
|
59
72
|
private static _loadSet;
|
|
60
73
|
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { Aspect } from "../../core/Aspect";
|
|
2
|
+
import type { FieldMeta } from "../../core/fields";
|
|
3
|
+
import { Vec3, type Vec3Like } from "../../math/vec";
|
|
4
|
+
import { Node } from "../Node";
|
|
5
|
+
/** One value for the chain, or `[root, tip]` interpolated down it by depth. */
|
|
6
|
+
export type DynamicBoneCurve = number | readonly [root: number, tip: number];
|
|
7
|
+
/** `'none'`, `'probe'` (a ray from the chain root down against the physics world, every frame), a
|
|
8
|
+
* height (a horizontal plane at that world y) or a world point (a plane through it, `floorNormal` up). */
|
|
9
|
+
export type DynamicBoneFloor = "none" | "probe" | number | Vec3Like;
|
|
10
|
+
/** `'auto'` = every DynamicBoneCollider under the model; `'humanoid'` = those plus capsules generated
|
|
11
|
+
* on the standard humanoid bones (hips, spine, head, limbs — the Ragdoll's layout); `'none'`; or the
|
|
12
|
+
* nodes carrying the colliders to use. */
|
|
13
|
+
export type DynamicBoneColliders = "auto" | "humanoid" | "none" | Node[];
|
|
14
|
+
/** The cloth's OUTSIDE, which makes every collider one-sided: `'none'` = a collider pushes a bone to its
|
|
15
|
+
* nearest surface (tails, ropes); `'auto'` = away from the root bone's own axis (a cloak's strips round a
|
|
16
|
+
* spine face out from it); a vector = a fixed direction in the root bone's frame (a cape on the back:
|
|
17
|
+
* `[0, 0, -1]`). With a side the body is under the cloth by definition: an arm that swung through the
|
|
18
|
+
* cape pushes it away, and a bone that ended up inside a capsule leaves it on the outside — never
|
|
19
|
+
* through it to be held against the chest from the wrong side. */
|
|
20
|
+
export type DynamicBoneSide = "none" | "auto" | Vec3Like;
|
|
21
|
+
/** A capsule (or a sphere) riding a bone — what dynamic bones stay out of. Attach to a body bone:
|
|
22
|
+
* `hips.aspect(DynamicBoneCollider, { radius: 0.12, to: 'Spine' })`. The capsule runs from
|
|
23
|
+
* `offset` (the bone's origin by default) to the `to` bone's origin, or to `end` (both in the bone's
|
|
24
|
+
* local space); neither = a sphere at `offset`. Picked up by every DynamicBone on the same model
|
|
25
|
+
* with `colliders: 'auto'` / `'humanoid'`, or listed explicitly. */
|
|
26
|
+
export declare class DynamicBoneCollider extends Aspect<"dynamicBoneCollider", Node> {
|
|
27
|
+
static readonly aspect = "dynamicBoneCollider";
|
|
28
|
+
/** Radius in metres, in the world: the bone's scale does not touch it (`offset` / `end` are in the bone's own units). */
|
|
29
|
+
radius: number;
|
|
30
|
+
/** Start of the capsule in the bone's local space (default: the bone's origin). */
|
|
31
|
+
offset: Vec3Like;
|
|
32
|
+
/** End of the capsule in the bone's local space (a sphere when neither `end` nor `to` is set). */
|
|
33
|
+
end?: Vec3Like;
|
|
34
|
+
/** The bone the capsule reaches (its origin), instead of `end`. */
|
|
35
|
+
to?: string;
|
|
36
|
+
static fields: FieldMeta<DynamicBoneCollider>;
|
|
37
|
+
private _id;
|
|
38
|
+
private _segment;
|
|
39
|
+
onAttach(): void;
|
|
40
|
+
onReconfigure(): void;
|
|
41
|
+
onDetach(): void;
|
|
42
|
+
}
|
|
43
|
+
export declare class DynamicBone extends Aspect<"dynamicBone", Node> {
|
|
44
|
+
static readonly aspect = "dynamicBone";
|
|
45
|
+
/** Only these bones (by name) join the chain — the root always does, a bone left out takes its
|
|
46
|
+
* subtree with it. Default: the root's whole subtree. */
|
|
47
|
+
bones?: string[];
|
|
48
|
+
/** Depth limit under the root (0 = no limit). */
|
|
49
|
+
depth: number;
|
|
50
|
+
/** Particle radius for the collisions, metres. */
|
|
51
|
+
radius: DynamicBoneCurve;
|
|
52
|
+
/** 0..1 — how fast a bone returns to the animated shape (per 1/60 s). 0 = a rope, 1 = rigid. */
|
|
53
|
+
stiffness: DynamicBoneCurve;
|
|
54
|
+
/** 0..1 — velocity lost per 1/60 s. 0.02 swings like a rope, 0.1 settles like a tail, 0.3 is honey. */
|
|
55
|
+
damping: DynamicBoneCurve;
|
|
56
|
+
/** m/s² downward. A hanging rest pose feels none of it (the bone length cancels it); a pose that
|
|
57
|
+
* sticks out droops by as much as `stiffness` lets it. */
|
|
58
|
+
gravity: DynamicBoneCurve;
|
|
59
|
+
/** Max deviation from the animated direction, degrees per bone (0 = free). */
|
|
60
|
+
angleLimit: DynamicBoneCurve;
|
|
61
|
+
/** Relative mass per bone. A bone-length constraint moves its two ends in inverse proportion to
|
|
62
|
+
* their masses (the root is kinematic): `[3, 1]` makes a tail's base carry its tip, `1` shares
|
|
63
|
+
* evenly like a rope. */
|
|
64
|
+
mass: DynamicBoneCurve;
|
|
65
|
+
/** Bones (by name) that ride the animation exactly while their subtrees still simulate: a sheet's
|
|
66
|
+
* several roots under one anchor (a cloak's seven strips under the spine), so ONE chain owns them all
|
|
67
|
+
* and `link` ties neighbouring strips. */
|
|
68
|
+
pinned?: string[];
|
|
69
|
+
/** Metres a PINNED bone may be pushed off its animated place by a collider — a soft pin. Its particle
|
|
70
|
+
* collides and takes the edge pushes like a free bone (the strip below hangs from where it IS) and is
|
|
71
|
+
* drawn back to the animation when the collider leaves; the bone's local translation follows. A hard
|
|
72
|
+
* pin (0) at a capsule's edge made the first free bone below it jitter: the edge push on a segment
|
|
73
|
+
* with an immovable end is a lever, and a touch near the root threw the child out. 2–3 cm for a
|
|
74
|
+
* cloak's roots under a shoulder capsule. */
|
|
75
|
+
pinGive: number;
|
|
76
|
+
/** 0..1 of the character's travel the chain takes rigidly (0 = the full whip on a dash, 1 = it
|
|
77
|
+
* moves with the body and only the pose's own motion swings it). */
|
|
78
|
+
follow: number;
|
|
79
|
+
/** World wind, m/s². */
|
|
80
|
+
wind: Vec3Like;
|
|
81
|
+
/** The BODY'S TURN, ≥ 0. Above 0 the chain lives in the parent bone's ROTATING frame: `damping` acts
|
|
82
|
+
* against the body's rigid motion (its travel plus its spin), so a heavily damped cloak RIDES a turn —
|
|
83
|
+
* sweeps round with the back — instead of standing in the world while the character spins under it and
|
|
84
|
+
* being dragged round after. The turn's inertia comes back as the frame's forces, scaled by this value:
|
|
85
|
+
* a centrifugal push `ω² · r` along each bone's animated direction from the axis (the hem, farthest
|
|
86
|
+
* from the spine, flies out and, on the chain's length, up). The frame's own physics is built in: the
|
|
87
|
+
* whip back when the turn starts and forward when it stops, Coriolis. 1 = the physical push; more = a
|
|
88
|
+
* bigger fling. With low damping the frame reproduces a free particle (nothing is counted twice);
|
|
89
|
+
* an animation's spine sway is ~1 % of a 900°/s turn. A rotation over 90° in one frame (a respawn
|
|
90
|
+
* facing) counts as a snap, not a spin. 0 = the plain translational frame, no turn forces. */
|
|
91
|
+
spin: number;
|
|
92
|
+
/** With `spin`: the cloth's INERTIA against the body's turn, seconds — the cloth's own rotation follows the
|
|
93
|
+
* body's with this time constant. It falls behind when a turn starts (by about ω·τ: 45° at 900°/s and 0.05),
|
|
94
|
+
* rides once caught up, and keeps turning past the back when the body stops (the same angle, eased out over
|
|
95
|
+
* τ). Smooth by construction. 0 = glued to the turn; large = the cloth stays in the world while the body spins. */
|
|
96
|
+
spinInertia: number;
|
|
97
|
+
/** 0..1 strength of the ties between neighbouring columns at the same depth (a cloak). */
|
|
98
|
+
link: number;
|
|
99
|
+
/** 0..1 blend from the animation (0) to the simulation (1). At 0 nothing is simulated and the
|
|
100
|
+
* chain re-arms on the animated pose when it comes back. */
|
|
101
|
+
weight: number;
|
|
102
|
+
/** Substep rate, Hz (≤ 4 substeps per frame). */
|
|
103
|
+
rate: number;
|
|
104
|
+
/** A root jump longer than this in one frame (metres) resets the chain instead of whipping it. */
|
|
105
|
+
teleport: number;
|
|
106
|
+
/** What the particles stay above: `'none'`, `'probe'`, a height, or a world point. */
|
|
107
|
+
floor: DynamicBoneFloor;
|
|
108
|
+
/** The floor plane's normal when `floor` is a point. */
|
|
109
|
+
floorNormal: Vec3Like;
|
|
110
|
+
/** Friction against the floor, a Coulomb coefficient: a resting bone's slide loses up to
|
|
111
|
+
* `floorFriction · gravity · dt` of speed per substep (0 = ice, 1 = a rubber sole). While a bone
|
|
112
|
+
* rests on the floor or a collider, `stiffness` and `angleLimit` let go of it: the surface's
|
|
113
|
+
* reaction outranks the spring, or a hem folded on the floor would run away along it. */
|
|
114
|
+
floorFriction: number;
|
|
115
|
+
/** Constraint passes per substep (1..8, default 4). Each pass shares every bone length between its
|
|
116
|
+
* ends, so a pull needs passes to travel down a long chain: a long rope may want 8, a short tail is
|
|
117
|
+
* fine with 2. */
|
|
118
|
+
iterations: number;
|
|
119
|
+
/** What the chain collides with (see DynamicBoneColliders). */
|
|
120
|
+
colliders: DynamicBoneColliders;
|
|
121
|
+
/** The cloth's outside — makes the colliders one-sided (see DynamicBoneSide). */
|
|
122
|
+
side: DynamicBoneSide;
|
|
123
|
+
/** How firmly `guide()` targets are HELD through the constraint passes, 0..1. At 0 a guide is applied once
|
|
124
|
+
* before the passes and the length / link passes may drag the bone back toward its un-guided neighbours
|
|
125
|
+
* within the same frame; at 0.5 it is re-pulled after every pass with half its weight (converges with the
|
|
126
|
+
* passes), at 1 with its full weight (a target the bone length cannot reach then jitters). */
|
|
127
|
+
guideHold: number;
|
|
128
|
+
/** The chain's EDGES collide with the capsules too — every bone segment and every link, not only the bones'
|
|
129
|
+
* particles: a capsule thinner than a bone's length (a forearm) no longer passes through the cloth between
|
|
130
|
+
* two bones. Off = particles only. */
|
|
131
|
+
edges: boolean;
|
|
132
|
+
static fields: FieldMeta<DynamicBone>;
|
|
133
|
+
private _id;
|
|
134
|
+
private _chain;
|
|
135
|
+
private _depths;
|
|
136
|
+
private _blob;
|
|
137
|
+
private _sent;
|
|
138
|
+
private _floorKey;
|
|
139
|
+
private _colliderKey;
|
|
140
|
+
private _collidersDirty;
|
|
141
|
+
private _collidersRef;
|
|
142
|
+
private _own;
|
|
143
|
+
private _colliderSet;
|
|
144
|
+
/** The bones of the chain, the root first. */
|
|
145
|
+
get chain(): readonly Node[];
|
|
146
|
+
onAttach(): void;
|
|
147
|
+
onReconfigure(): void;
|
|
148
|
+
/** Every field is live: what changed since the last frame is pushed here, before the engine's stage. */
|
|
149
|
+
update(): void;
|
|
150
|
+
onDetach(): void;
|
|
151
|
+
/** Snap the chain onto the animated pose next frame (a teleport, a camera cut). */
|
|
152
|
+
reset(): void;
|
|
153
|
+
/** GUIDES: world points the bones' particles are drawn to each substep before the constraints —
|
|
154
|
+
* weight 1 = there before them, the rest of the chain hangs, collides and links as before (a cape's
|
|
155
|
+
* strips riding the arms). Replaces the previous set; an empty list clears. A late-phase script
|
|
156
|
+
* (after the animator, before the engine's chain stage) refreshes it every frame. */
|
|
157
|
+
guide(rows: readonly {
|
|
158
|
+
bone: Node;
|
|
159
|
+
at: Vec3Like;
|
|
160
|
+
weight: number;
|
|
161
|
+
}[]): void;
|
|
162
|
+
/** The particles' world positions (the bones, then the leaves' virtual tips) — for a debug draw. */
|
|
163
|
+
get particles(): Vec3[];
|
|
164
|
+
private _collect;
|
|
165
|
+
private _fill;
|
|
166
|
+
/** Neighbour links: the bones at the same depth, in tree order, tied pairwise. */
|
|
167
|
+
private _links;
|
|
168
|
+
private _sync;
|
|
169
|
+
private _pushFloor;
|
|
170
|
+
private _pushColliders;
|
|
171
|
+
/** Capsules on the standard humanoid bones, sized like the Ragdoll's parts. */
|
|
172
|
+
private _makeHumanoid;
|
|
173
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Aspect } from "
|
|
2
|
-
import { type Vec3Like } from "
|
|
3
|
-
import { Quat } from "
|
|
4
|
-
import type { Node } from "
|
|
1
|
+
import { Aspect } from "../../core/Aspect";
|
|
2
|
+
import { type Vec3Like } from "../../math/vec";
|
|
3
|
+
import { Quat } from "../../math/quat";
|
|
4
|
+
import type { Node } from "../Node";
|
|
5
5
|
type Target = Node | Vec3Like;
|
|
6
6
|
/** Two-bone analytic IK (limbs). Attach to the END bone: `foot.aspect(IK.TwoBone, { target })`
|
|
7
7
|
* solves upper (grandparent) + mid (parent) so the end reaches `target`; `pole` steers the bend
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Aspect } from "
|
|
2
|
-
import { Vec3, type Vec3Like } from "
|
|
3
|
-
import { Animator } from "./
|
|
4
|
-
import type { FeetOptions } from "./
|
|
5
|
-
import type { WarpOptions } from "./
|
|
6
|
-
import type { Node } from "
|
|
1
|
+
import { Aspect } from "../../core/Aspect";
|
|
2
|
+
import { Vec3, type Vec3Like } from "../../math/vec";
|
|
3
|
+
import { Animator } from "./Animator";
|
|
4
|
+
import type { FeetOptions } from "./Feet";
|
|
5
|
+
import type { WarpOptions } from "./Warp";
|
|
6
|
+
import type { Node } from "../Node";
|
|
7
7
|
/** How fast the character wants to go: the gait picks its clips and its speed. */
|
|
8
8
|
export type Gait = "walk" | "run" | "sprint";
|
|
9
9
|
/** What the engine shows: the idle, a start, the gait loop, a turn while moving, a stop, or a turn on the spot. */
|
|
@@ -6,18 +6,17 @@ import { Vec3 } from "../../math/vec";
|
|
|
6
6
|
import type { Node } from "../Node";
|
|
7
7
|
/** A position on a blend axis (1D) or plane (2D). */
|
|
8
8
|
export type BlendPosition = number | readonly [number, number];
|
|
9
|
-
/** The transition time (seconds) a play / playLoop without `fade` uses. */
|
|
10
|
-
export declare const DEFAULT_FADE = 0.2;
|
|
11
9
|
export type PlayOptions = {
|
|
12
|
-
/** Transition seconds — how long the difference to the pose the layer SHOWED
|
|
13
|
-
*
|
|
10
|
+
/** Transition seconds — how long the difference to the pose the layer SHOWED (its loop, a one-shot,
|
|
11
|
+
* or rest) takes to decay. Default `0` = cut: a fade is always asked for, never implied. Also the
|
|
12
|
+
* transition back to the loop at the end unless `fadeOut` overrides it. */
|
|
14
13
|
fade?: number;
|
|
15
14
|
/** Transition seconds for the way in only (overrides `fade`). */
|
|
16
15
|
fadeIn?: number;
|
|
17
|
-
/** One-shots: the transition BACK at the end (overrides `fade`
|
|
18
|
-
* clip ends — while it still plays — so the hand-over lands on the
|
|
19
|
-
* layer with no loop
|
|
20
|
-
*
|
|
16
|
+
/** One-shots: the transition BACK to the loop at the end (overrides `fade`; `0` = cut at the end).
|
|
17
|
+
* It starts this long before the clip ends — while it still plays — so the hand-over lands on the
|
|
18
|
+
* last pose, not after it. On a layer with no loop the clip HOLDS its last frame (a rock that broke
|
|
19
|
+
* stays broken) — `anim.stop({ fade })` is the way back to rest. */
|
|
21
20
|
fadeOut?: number;
|
|
22
21
|
/** Playback rate for this clip (default 1). */
|
|
23
22
|
speed?: number;
|
|
@@ -39,8 +38,8 @@ export type StopOptions = {
|
|
|
39
38
|
fade?: number;
|
|
40
39
|
};
|
|
41
40
|
export type LoopOptions = {
|
|
42
|
-
/** Transition seconds from whatever the layer shows — its previous loop,
|
|
43
|
-
*
|
|
41
|
+
/** Transition seconds from whatever the layer shows — its previous loop, a one-shot still playing,
|
|
42
|
+
* or rest. Default `0` = cut: a loop wanting a transition asks for one (`{ fade: 0.2 }`). */
|
|
44
43
|
fade?: number;
|
|
45
44
|
/** Playback rate of the loop's clips (default 1). */
|
|
46
45
|
speed?: number;
|
|
@@ -165,6 +164,12 @@ export type ClipInfo = {
|
|
|
165
164
|
turnAt(time: number): number;
|
|
166
165
|
/** the root's own speed at `time`, m/s — how fast the clip is moving the body right there */
|
|
167
166
|
speedAt(time: number): number;
|
|
167
|
+
/** the PELVIS' yaw relative to the clip's heading at `time` (rad, + = left, wrapped to ±π): the stance twist
|
|
168
|
+
* the heading leaves out — an idle stands ~43° off the course it starts along, a stop's tail turns into that
|
|
169
|
+
* stance while the heading holds. A controller that switches clips mid-pose can keep the PELVIS continuous
|
|
170
|
+
* (turn the node by the difference between the two clips' values) where keeping the course would swing
|
|
171
|
+
* the body. Without a baked heading: the pelvis' yaw at frame 0 throughout. */
|
|
172
|
+
pelvisYawAt(time: number): number;
|
|
168
173
|
/** the unit travel direction at `time` ([x, z], model space, held through stills) — integrate
|
|
169
174
|
* direction × d(travel) to reconstruct the root's 2D path (a treadmill display, a turn's arc) */
|
|
170
175
|
directionAt(time: number): [number, number];
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Aspect } from "../../core/Aspect";
|
|
2
|
+
import type { FieldMeta } from "../../core/fields";
|
|
3
|
+
import { type PlaySoundOptions, type Rolloff } from "../../audio/audio";
|
|
4
|
+
import type { Sound } from "../../audio/Sound";
|
|
5
|
+
import type { Voice } from "../../audio/Voice";
|
|
6
|
+
import type { Node } from "../Node";
|
|
7
|
+
export type AudioCone = {
|
|
8
|
+
/** Degrees of full volume around the node's −Z. */
|
|
9
|
+
inner: number;
|
|
10
|
+
/** Degrees where the volume has fallen to `outerGain`. */
|
|
11
|
+
outer: number;
|
|
12
|
+
/** Volume behind the source, 0 … 1. */
|
|
13
|
+
outerGain?: number;
|
|
14
|
+
};
|
|
15
|
+
export declare class AudioSource extends Aspect<"audio", Node> {
|
|
16
|
+
static readonly aspect = "audio";
|
|
17
|
+
static fields: FieldMeta<AudioSource>;
|
|
18
|
+
private _minDistance;
|
|
19
|
+
private _maxDistance;
|
|
20
|
+
private _rolloff;
|
|
21
|
+
private _cone;
|
|
22
|
+
private _doppler;
|
|
23
|
+
private _spread;
|
|
24
|
+
private _occlusion;
|
|
25
|
+
private _bus;
|
|
26
|
+
/** Metres of full volume around the node. Default 1. */
|
|
27
|
+
get minDistance(): number;
|
|
28
|
+
set minDistance(v: number);
|
|
29
|
+
/** Metres beyond which the source no longer gets quieter. Default 50. */
|
|
30
|
+
get maxDistance(): number;
|
|
31
|
+
set maxDistance(v: number);
|
|
32
|
+
/** `inverse` (default), `linear`, `exponential`, `none`. */
|
|
33
|
+
get rolloff(): Rolloff;
|
|
34
|
+
set rolloff(v: Rolloff);
|
|
35
|
+
/** Directional source along the node's −Z; null = omnidirectional (default). */
|
|
36
|
+
get cone(): AudioCone | null;
|
|
37
|
+
set cone(v: AudioCone | null);
|
|
38
|
+
/** Doppler amount 0 … 1 (0 = off, the default) — needs the node to actually move. */
|
|
39
|
+
get doppler(): number;
|
|
40
|
+
set doppler(v: number);
|
|
41
|
+
/** 0 = pin-point panning (default) … 1 = the same on every speaker (a big, close source). */
|
|
42
|
+
get spread(): number;
|
|
43
|
+
set spread(v: number);
|
|
44
|
+
/** The engine raycasts listener → source (against solid bodies) and muffles the voices when
|
|
45
|
+
* something is in the way. Default false. */
|
|
46
|
+
get occlusion(): boolean;
|
|
47
|
+
set occlusion(v: boolean);
|
|
48
|
+
/** Default bus for voices on this source. Default `sfx`. */
|
|
49
|
+
get bus(): string;
|
|
50
|
+
set bus(v: string);
|
|
51
|
+
/** Live voices on this source. */
|
|
52
|
+
get voices(): number;
|
|
53
|
+
onAttach(): void;
|
|
54
|
+
onDetach(): void;
|
|
55
|
+
/** Play a clip from this node. */
|
|
56
|
+
play(sound: Sound, options?: PlaySoundOptions): Voice;
|
|
57
|
+
/** Stop every voice on this source (fade in seconds). */
|
|
58
|
+
stopAll(fade?: number): void;
|
|
59
|
+
private _push;
|
|
60
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Aspect } from "../../core/Aspect";
|
|
2
|
+
import { type ReverbParams, type ReverbPreset } from "../../audio/Bus";
|
|
3
|
+
import { type Vec3Like } from "../../math/vec";
|
|
4
|
+
import type { Node } from "../Node";
|
|
5
|
+
export declare class AudioZone extends Aspect<"audioZone", Node> {
|
|
6
|
+
static readonly aspect = "audioZone";
|
|
7
|
+
private _box;
|
|
8
|
+
private _sphere;
|
|
9
|
+
private _reverb;
|
|
10
|
+
private _blend;
|
|
11
|
+
private _bus;
|
|
12
|
+
/** The engine's zone id — what `audio.stats.listenerZone` reports while the listener is inside. */
|
|
13
|
+
get id(): number;
|
|
14
|
+
/** Half-extents [hx, hy, hz]; falls back to the node's Shape box, then a 1 m cube. */
|
|
15
|
+
get box(): Vec3Like | null;
|
|
16
|
+
set box(v: Vec3Like | null);
|
|
17
|
+
/** Radius; falls back to the node's Shape sphere. */
|
|
18
|
+
get sphere(): number | null;
|
|
19
|
+
set sphere(v: number | null);
|
|
20
|
+
/** A preset name or explicit params (see Bus.reverb). */
|
|
21
|
+
get reverb(): ReverbPreset | ReverbParams;
|
|
22
|
+
set reverb(v: ReverbPreset | ReverbParams);
|
|
23
|
+
/** Crossfade depth in metres inside the border (0 = a hard edge). Default 1. */
|
|
24
|
+
get blend(): number;
|
|
25
|
+
set blend(v: number);
|
|
26
|
+
/** The bus the zone's reverb rides on. Default `sfx`. */
|
|
27
|
+
get bus(): string;
|
|
28
|
+
set bus(v: string);
|
|
29
|
+
onAttach(): void;
|
|
30
|
+
onDetach(): void;
|
|
31
|
+
private _push;
|
|
32
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Node } from "../Node";
|
|
2
|
+
export declare class SceneAudio {
|
|
3
|
+
private _listener;
|
|
4
|
+
private _doppler;
|
|
5
|
+
/** The node the engine listens from; null (default) = the active camera. */
|
|
6
|
+
get listener(): Node | null;
|
|
7
|
+
set listener(node: Node | null);
|
|
8
|
+
/** Multiplies every source's doppler amount (0 = off everywhere). Default 1. */
|
|
9
|
+
get dopplerFactor(): number;
|
|
10
|
+
set dopplerFactor(v: number);
|
|
11
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Aspect } from "
|
|
2
|
-
import type { FieldMeta } from "
|
|
3
|
-
import { Vec3, type Vec3Like } from "
|
|
1
|
+
import { Aspect } from "../../core/Aspect";
|
|
2
|
+
import type { FieldMeta } from "../../core/fields";
|
|
3
|
+
import { Vec3, type Vec3Like } from "../../math/vec";
|
|
4
4
|
import { NavCrowd } from "./NavMesh";
|
|
5
|
-
import type { Node } from "
|
|
5
|
+
import type { Node } from "../Node";
|
|
6
6
|
export type NavAgentState = "idle" | "moving" | "arrived" | "blocked" | "offmesh";
|
|
7
7
|
export type NavAgentAvoidance = "off" | "low" | "medium" | "high";
|
|
8
8
|
export type NavAgentDrive = "position" | "controller";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { System } from "
|
|
2
|
-
import { Vec3, type Vec3Like } from "
|
|
3
|
-
import type { Node } from "
|
|
4
|
-
import type { Scene } from "
|
|
1
|
+
import { System } from "../../core/Aspect";
|
|
2
|
+
import { Vec3, type Vec3Like } from "../../math/vec";
|
|
3
|
+
import type { Node } from "../Node";
|
|
4
|
+
import type { Scene } from "../Scene";
|
|
5
5
|
export declare const NAV_AGENT: {
|
|
6
6
|
readonly RADIUS: 0;
|
|
7
7
|
readonly HEIGHT: 1;
|