lecodes-sdk 0.19.2 → 0.20.2
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 +62 -0
- package/dist/host.d.ts +3 -0
- 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/gl/AudioSource.d.ts +60 -0
- package/dist/types/gl/AudioZone.d.ts +32 -0
- package/dist/types/gl/DecalSet.d.ts +103 -0
- package/dist/types/gl/Geometry.d.ts +5 -0
- package/dist/types/gl/Light.d.ts +7 -0
- package/dist/types/gl/Locomotion.d.ts +3 -1
- package/dist/types/gl/Material.d.ts +86 -2
- package/dist/types/gl/Mesh.d.ts +11 -0
- package/dist/types/gl/Scene.d.ts +23 -0
- package/dist/types/gl/SceneAudio.d.ts +11 -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/Animator.d.ts +51 -183
- package/dist/types/gl/animation/Feet.d.ts +85 -0
- package/dist/types/gl/animation/Warp.d.ts +53 -0
- package/dist/types/gl/animation/core.d.ts +61 -17
- package/dist/types/gl/state.d.ts +0 -1
- package/dist/types/inject.d.ts +17 -2
- package/dist/types/plugins/map.d.ts +174 -0
- package/dist/types/runtime/input.d.ts +11 -0
- package/dist/types/ui/UIImage.d.ts +15 -5
- package/dist/types.json +1 -1
- package/package.json +1 -1
- 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 +1481 -1345
- package/src/compile/__tests__/compile.test.ts +12 -0
- package/src/compile/compileProject.ts +35 -15
- package/src/compile/index.ts +3 -0
- package/src/core/Aspect.ts +34 -9
- package/src/g2/Scene2D.ts +7 -0
- package/src/gl/AudioSource.ts +113 -0
- package/src/gl/AudioZone.ts +75 -0
- package/src/gl/DecalSet.ts +233 -0
- package/src/gl/Geometry.ts +5 -0
- package/src/gl/Light.ts +16 -0
- package/src/gl/Lightmap.ts +3 -2
- package/src/gl/Locomotion.ts +7 -5
- package/src/gl/Material.ts +152 -4
- package/src/gl/Mesh.ts +20 -1
- package/src/gl/Particles.ts +3 -3
- package/src/gl/Scene.ts +42 -8
- package/src/gl/SceneAudio.ts +26 -0
- package/src/gl/Texture.ts +43 -3
- package/src/gl/Vehicle.ts +5 -5
- package/src/gl/animation/AnimationClip.ts +43 -20
- package/src/gl/animation/Animator.ts +138 -329
- package/src/gl/animation/Feet.ts +134 -0
- package/src/gl/animation/Loop.ts +3 -1
- package/src/gl/animation/Warp.ts +96 -0
- package/src/gl/animation/core.ts +741 -670
- package/src/gl/state.ts +6 -6
- package/src/host.d.ts +3 -0
- package/src/inject.ts +23 -2
- package/src/plugins/map.ts +396 -0
- package/src/runtime/input.ts +6 -1
- package/src/ui/UIImage.ts +21 -7
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Aspect } from "../core/Aspect";
|
|
2
2
|
import { Vec3, type Vec3Like } from "../math/vec";
|
|
3
|
-
import { Animator
|
|
3
|
+
import { Animator } from "./animation/Animator";
|
|
4
|
+
import type { FeetOptions } from "./animation/Feet";
|
|
5
|
+
import type { WarpOptions } from "./animation/Warp";
|
|
4
6
|
import type { Node } from "./Node";
|
|
5
7
|
/** How fast the character wants to go: the gait picks its clips and its speed. */
|
|
6
8
|
export type Gait = "walk" | "run" | "sprint";
|
|
@@ -7,8 +7,47 @@ export type MaterialColorOptions = {
|
|
|
7
7
|
color?: ColorInput;
|
|
8
8
|
map?: Texture | Canvas | null;
|
|
9
9
|
};
|
|
10
|
+
/** How a stencil test / write on a material compares and what it writes. `test` runs against the
|
|
11
|
+
* scene's stencil buffer (`Scene.stencil` must be on); the ops say what the buffer gets when the
|
|
12
|
+
* fragment passes / fails the stencil test / fails the depth test (`replace` writes `ref`). */
|
|
13
|
+
export type StencilTest = "always" | "never" | "less" | "lessEqual" | "greater" | "greaterEqual" | "equal" | "notEqual";
|
|
14
|
+
export type StencilOp = "keep" | "zero" | "replace" | "increment" | "decrement" | "invert";
|
|
15
|
+
export type MaterialStencil = {
|
|
16
|
+
/** Write the stencil buffer at all. Default `false`. */
|
|
17
|
+
write?: boolean;
|
|
18
|
+
/** The reference value, 0..255. Default 0. */
|
|
19
|
+
ref?: number;
|
|
20
|
+
/** Default `"always"`. */
|
|
21
|
+
test?: StencilTest;
|
|
22
|
+
onPass?: StencilOp;
|
|
23
|
+
onFail?: StencilOp;
|
|
24
|
+
onDepthFail?: StencilOp;
|
|
25
|
+
readMask?: number;
|
|
26
|
+
writeMask?: number;
|
|
27
|
+
};
|
|
28
|
+
/** Render state a material instance can override at run time (Filament keeps the defaults in the
|
|
29
|
+
* shader package; these are per-instance overrides on top). */
|
|
30
|
+
export type MaterialStateOptions = {
|
|
31
|
+
/** Test against the scene's depth buffer. `false` draws over everything already drawn — an
|
|
32
|
+
* editor gizmo, a marker that must never hide behind a wall. Pair it with a high
|
|
33
|
+
* `Mesh.renderPriority` so nothing drawn later covers it. Default `true`. */
|
|
34
|
+
depthTest?: boolean;
|
|
35
|
+
/** Write to the depth buffer. Leave it on for something drawn over the scene whose own parts must
|
|
36
|
+
* still occlude each other (a gizmo's cone in front of its shaft). Unset = the shader's default
|
|
37
|
+
* (on for opaque, off for a blended one). */
|
|
38
|
+
depthWrite?: boolean;
|
|
39
|
+
/** Draw both faces (no back-face culling): a plane seen from behind, a ribbon, cloth, a flat
|
|
40
|
+
* marker. Default `false` = the shader's culling (back faces dropped). */
|
|
41
|
+
doubleSided?: boolean;
|
|
42
|
+
/** A stencil test / write for this material — see `MaterialStencil`. The selection-outline
|
|
43
|
+
* recipe: the object writes `{ write: true, ref: 1, onPass: "replace" }`, and a slightly larger
|
|
44
|
+
* copy of it draws with `{ test: "notEqual", ref: 1 }` + `depthTest: false` in `renderPriority` 7. */
|
|
45
|
+
stencil?: MaterialStencil;
|
|
46
|
+
};
|
|
47
|
+
/** @deprecated the name before doubleSided / stencil joined it — the same type */
|
|
48
|
+
export type MaterialDepthOptions = MaterialStateOptions;
|
|
10
49
|
/** `Material.unlit` options. */
|
|
11
|
-
export type UnlitMaterialOptions = MaterialColorOptions & {
|
|
50
|
+
export type UnlitMaterialOptions = MaterialColorOptions & MaterialStateOptions & {
|
|
12
51
|
/** Alpha-blend this material instead of drawing it opaque. Opaque is the default: a blended draw
|
|
13
52
|
* writes no depth, is sorted back-to-front and casts no shadow, which is rarely what a flat
|
|
14
53
|
* colour wants. Turn it on for anything that must show what is behind it — a glass pane, a
|
|
@@ -16,6 +55,26 @@ export type UnlitMaterialOptions = MaterialColorOptions & {
|
|
|
16
55
|
* (`"#ffffff80"`) mean anything; the opaque material has no alpha channel at all. */
|
|
17
56
|
transparent?: boolean;
|
|
18
57
|
};
|
|
58
|
+
/** `Material.decal` options — the projected-decal material a `DecalSet` draws with. */
|
|
59
|
+
export type DecalMaterialOptions = {
|
|
60
|
+
/** The atlas (a `DecalSet`'s `sheet` cuts it into cells). */
|
|
61
|
+
map?: Texture;
|
|
62
|
+
/** A tangent-space normal atlas (same cell grid; +X = the image's right, +Y = its top; LINEAR —
|
|
63
|
+
* `Texture.fromPixels(…, { srgb: false })`). Turns the decal into a RELIEF decal: instead of
|
|
64
|
+
* painting a colour it bends the surface's lighting, so a footprint or a dent shows on any
|
|
65
|
+
* surface without a colour of its own. With `map` too, the colour multiplies in (a crater
|
|
66
|
+
* darkens by the map's alpha). The sun term applies in shadow as well (no shadow read). */
|
|
67
|
+
normalMap?: Texture;
|
|
68
|
+
/** Relief strength — the normal map's xy scale. Default 1. */
|
|
69
|
+
bump?: number;
|
|
70
|
+
/** Soft fraction (0..1) of the box's half depth at both ends. Default 0.3. */
|
|
71
|
+
edge?: number;
|
|
72
|
+
/** Cosine of the surface angle past which the decal fades (0.3 ≈ 72°); 0 = project onto
|
|
73
|
+
* anything. Default 0.3. */
|
|
74
|
+
angleFade?: number;
|
|
75
|
+
/** HDR boost of the image (0 = none). */
|
|
76
|
+
emissive?: number;
|
|
77
|
+
};
|
|
19
78
|
/** `Material.particles` options — the default point-sprite material for particle systems. */
|
|
20
79
|
export type ParticlesMaterialOptions = {
|
|
21
80
|
/** Sprite texture — a single image or a flipbook sheet of frames. Unset = soft round dot. */
|
|
@@ -54,12 +113,14 @@ export type ParticlesMaterialOptions = {
|
|
|
54
113
|
stretch?: number;
|
|
55
114
|
};
|
|
56
115
|
/** `Material.lit` options — PBR scalars on top of the color/map pair. */
|
|
57
|
-
export type LitMaterialOptions = MaterialColorOptions & {
|
|
116
|
+
export type LitMaterialOptions = MaterialColorOptions & MaterialStateOptions & {
|
|
58
117
|
/** Perceptual roughness, 0 (mirror) … 1 (matte). Unset = the shader's default. */
|
|
59
118
|
roughness?: number;
|
|
60
119
|
/** Metallic factor, 0 (dielectric) … 1 (metal). Unset = the shader's default. */
|
|
61
120
|
metallic?: number;
|
|
62
121
|
};
|
|
122
|
+
/** `Material.lightmapShading` tiers — see the setter. */
|
|
123
|
+
export type LightmapShading = "full" | "baked" | "baked-lite";
|
|
63
124
|
export declare class Material {
|
|
64
125
|
readonly shader: FetchResponse | "unknown";
|
|
65
126
|
readonly uniforms: Record<string, UniformValue>;
|
|
@@ -68,6 +129,15 @@ export declare class Material {
|
|
|
68
129
|
/** Set a uniform (chainable). */
|
|
69
130
|
set(key: string, value: UniformValue): this;
|
|
70
131
|
set color(c: ColorInput);
|
|
132
|
+
/** Depth test against the scene (write-only; see `MaterialDepthOptions`). A host that predates
|
|
133
|
+
* the call leaves the material as the shader has it. */
|
|
134
|
+
set depthTest(on: boolean);
|
|
135
|
+
/** Depth write (write-only; see `MaterialStateOptions`). */
|
|
136
|
+
set depthWrite(on: boolean);
|
|
137
|
+
/** Both faces drawn (write-only; see `MaterialStateOptions`). */
|
|
138
|
+
set doubleSided(on: boolean);
|
|
139
|
+
/** The stencil test / write (write-only; `null` = back to none). See `MaterialStencil`. */
|
|
140
|
+
set stencil(s: MaterialStencil | null);
|
|
71
141
|
set map(value: Texture | Canvas | null);
|
|
72
142
|
/** PBR lit material. */
|
|
73
143
|
static lit(options?: LitMaterialOptions): Material;
|
|
@@ -77,6 +147,10 @@ export declare class Material {
|
|
|
77
147
|
* driven by the particle curves. Uniforms all default to 0 on a fresh instance, so every look
|
|
78
148
|
* knob is primed here; JS writes after construction override them. */
|
|
79
149
|
static particles(options?: ParticlesMaterialOptions): Material;
|
|
150
|
+
/** Projected-decal material (`DecalSet`): samples the atlas where the decal's box meets the opaque
|
|
151
|
+
* scene behind it. Blended, no depth write, no shadows — the engine keeps the scene depth bound
|
|
152
|
+
* while a set with live decals is on screen. */
|
|
153
|
+
static decal(options?: DecalMaterialOptions): Material;
|
|
80
154
|
/** Material that samples a VideoPlayer's texture. */
|
|
81
155
|
static video(map?: Texture): Material;
|
|
82
156
|
/** The lightmap material (docs/lightmap-plan.md): PBR base colour × a baked shadow/AO atlas on UV1.
|
|
@@ -92,6 +166,16 @@ export declare class Material {
|
|
|
92
166
|
* unset layer is white and an unbaked terrain is fully lit. */
|
|
93
167
|
static terrain(): Material;
|
|
94
168
|
private static _lmTemplate;
|
|
169
|
+
static _lightmapShading: LightmapShading;
|
|
170
|
+
/** Which shader lightmapped models take — a graphics-quality tier, engine-wide. `"full"` is filament's
|
|
171
|
+
* lit path over the baked atlas (IBL specular, real-time point lights such as a muzzle flash, sun
|
|
172
|
+
* shadows on dynamic objects). `"baked"` keeps the baked light and an approximated ambient but drops
|
|
173
|
+
* the lit path: ~40 % cheaper per pixel on a fill-bound GPU. `"baked-lite"` is that minus the normal,
|
|
174
|
+
* metallic/roughness and occlusion map reads (the factors stand in, the atlas keeps the baked AO;
|
|
175
|
+
* emissive still glows): +20 % more at 1080p on the same GPU. Read when a lightmapped model LOADS, so set
|
|
176
|
+
* it before the level (a settings menu applies it on the next level load), like `Texture.maxSize`. */
|
|
177
|
+
static get lightmapShading(): LightmapShading;
|
|
178
|
+
static set lightmapShading(mode: LightmapShading);
|
|
95
179
|
/** Shadow-catcher material (transparent except where shadows fall). */
|
|
96
180
|
static shadow(color?: ColorInput): Material;
|
|
97
181
|
/** Load a custom compiled shader (.mat URL) as a material. */
|
package/dist/types/gl/Mesh.d.ts
CHANGED
|
@@ -11,15 +11,26 @@ export type MeshOptions = {
|
|
|
11
11
|
name?: string;
|
|
12
12
|
castShadows?: boolean;
|
|
13
13
|
receiveShadows?: boolean;
|
|
14
|
+
/** Coarse draw order, 0 (first) … 7 (last); default 4. See `Mesh.renderPriority`. */
|
|
15
|
+
renderPriority?: number;
|
|
14
16
|
};
|
|
15
17
|
export declare class Mesh extends Node {
|
|
16
18
|
private _geometry?;
|
|
17
19
|
constructor(geometry?: Geometry, material?: Material);
|
|
18
20
|
get geometry(): Geometry | undefined;
|
|
21
|
+
/** Replace the geometry in place — the node, its transform and its material stay, the vertex and
|
|
22
|
+
* index buffers are rebuilt. What an editor overlay or a debug drawer redraws with. */
|
|
23
|
+
setGeometry(geometry: Geometry): this;
|
|
19
24
|
/** A Mesh always carries a material (slot 0) — see Node.setMaterial for the slot API. */
|
|
20
25
|
get material(): Material;
|
|
21
26
|
set material(m: Material);
|
|
22
27
|
set culling(v: boolean);
|
|
28
|
+
/** Coarse draw order within the frame: 0 draws first, 7 last, 4 is the default (Filament's
|
|
29
|
+
* renderable priority; within one priority opaque draws sort front-to-back, blended back-to-front).
|
|
30
|
+
* Something drawn over the scene with `Material.depthTest = false` goes in 7, so nothing drawn
|
|
31
|
+
* after it can cover it. Write-only; a host that predates the call ignores it. */
|
|
32
|
+
set renderPriority(v: number);
|
|
33
|
+
private static _warnedPriority;
|
|
23
34
|
set castShadows(v: boolean);
|
|
24
35
|
set receiveShadows(v: boolean);
|
|
25
36
|
static box(options?: MeshOptions & {
|
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 "./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
|
|
@@ -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,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
|
}
|
|
@@ -1,219 +1,87 @@
|
|
|
1
1
|
import { Aspect } from "../../core/Aspect";
|
|
2
|
-
import { Vec3 } from "../../math/vec";
|
|
3
2
|
import type { Node } from "../Node";
|
|
4
3
|
import type { AnimationClip } from "./AnimationClip";
|
|
5
|
-
import { type ActiveClip, type
|
|
4
|
+
import { type ActiveClip, type ClipInfo, type ClipEventHandler, type LayerOptions, type LoopDef, type LoopOptions, type PlayOptions, type StopOptions } from "./core";
|
|
5
|
+
import { Feet } from "./Feet";
|
|
6
|
+
import { Warp } from "./Warp";
|
|
6
7
|
import type { Loop } from "./Loop";
|
|
7
8
|
import type { Layer } from "./Layer";
|
|
8
9
|
import type { Playback } from "./Playback";
|
|
9
10
|
/** Level of detail for a GLB instance (docs/lod-plan.md): `'auto'` = the engine's pick by screen size and
|
|
10
11
|
* visibility, or a fixed level 0 (full) … 3 (coarsest mesh, animation every 4th frame without fingers). */
|
|
11
12
|
export type LodMode = "auto" | 0 | 1 | 2 | 3;
|
|
12
|
-
/** What `Animator.warp` turns on. Speeds are m/s, angles degrees, distances metres. */
|
|
13
|
-
export type WarpOptions = {
|
|
14
|
-
/** Fit the stride to the speed the body actually travels at. `[min, max]` clamps the scale
|
|
15
|
-
* (default 0.85…1.2). It is a CORRECTION: a pack whose takes already read right at the speeds it
|
|
16
|
-
* is played at wants none of this, and a wide range only lets the legs be stretched into shapes
|
|
17
|
-
* nobody recorded. Open it for a pack that must cover speeds it was never recorded at. */
|
|
18
|
-
stride?: boolean | [number, number];
|
|
19
|
-
/** Turn the lower body toward where the body really travels; a number caps the turn in degrees
|
|
20
|
-
* (default 20). The spine counter-turns, so the chest keeps facing where it faced — the whole twist
|
|
21
|
-
* lives in one joint, which is why a few degrees read as a lean and a lot reads as a broken back.
|
|
22
|
-
* Only applied while the gait LOOP shows: a start, a turn or a stop walks a path of its own. */
|
|
23
|
-
orientation?: boolean | number;
|
|
24
|
-
/** Below this speed — the game's or the clip's — both warps are off (default 0.2). */
|
|
25
|
-
minSpeed?: number;
|
|
26
|
-
/** How far the pelvis may drop to keep a stretched leg from locking straight (default 0.25). */
|
|
27
|
-
pelvis?: number;
|
|
28
|
-
/** The stride scale's own spring, seconds (default 0.15). The body's speed is continuous but the
|
|
29
|
-
* shown clip's recorded one steps at every switch, so the scale is smoothed rather than followed. */
|
|
30
|
-
strideTime?: number;
|
|
31
|
-
};
|
|
32
|
-
/** What `Animator.feet` sets: which bones the feet are, and what the engine does with them. Distances
|
|
33
|
-
* are metres, times seconds. Every key is optional and only the keys given change — set the bones
|
|
34
|
-
* once, switch the lock on somewhere else. */
|
|
35
|
-
export type FeetOptions = {
|
|
36
|
-
/** The contact bones per side — `'LeftFoot'`, or with a toe / ball `['LeftFoot', 'LeftToeBase']`.
|
|
37
|
-
* Default: classified from the bone names (Mixamo / Unity / Blender / UE). Set them for a rig the
|
|
38
|
-
* classifier misses; it re-bakes every clip's contacts and phase. */
|
|
39
|
-
left?: string | string[];
|
|
40
|
-
right?: string | string[];
|
|
41
|
-
/** FOOT LOCK: a foot the shown clip calls planted (its baked contacts, else a runtime detector) is
|
|
42
|
-
* pinned where it landed — heel to ball, rolling as the clip rolls — and the leg re-solved to keep it
|
|
43
|
-
* there while the body moves on. What hides the last of a transition's slide: the pose the new clip
|
|
44
|
-
* starts from is not the one the old clip ended in, and the difference used to be dragged out of
|
|
45
|
-
* the standing foot over the blend. Off by default; a `Locomotion` turns it on. */
|
|
46
|
-
lock?: boolean;
|
|
47
|
-
/** GROUND IK: each foot is put on the ground the engine probes under it (stairs, a slope, a kerb),
|
|
48
|
-
* aligned to its normal, and the pelvis lowered so the lower leg can reach — the feet stop hanging
|
|
49
|
-
* in the air on a step down and sinking into a step up. Needs a physics world to probe; without
|
|
50
|
-
* one the ground is the node's own plane. Off by default. */
|
|
51
|
-
ik?: boolean;
|
|
52
|
-
/** How far the pelvis may drop for the ground (default 0.35). */
|
|
53
|
-
pelvis?: number;
|
|
54
|
-
/** The anchor's leash: a locked foot never absorbs more residual than this — beyond it the anchor
|
|
55
|
-
* follows the animation instead of fighting it (default 0.10). */
|
|
56
|
-
unlockDistance?: number;
|
|
57
|
-
/** The lock's ease in / out, seconds (default 0.08 / 0.12). */
|
|
58
|
-
lockIn?: number;
|
|
59
|
-
lockOut?: number;
|
|
60
|
-
/** 0..1: how much the foot tilts onto the ground normal (default 1). */
|
|
61
|
-
align?: number;
|
|
62
|
-
/** The probe ray's reach above and below the ankle (default 0.6) — a step taller than this is a
|
|
63
|
-
* hole to the probe. */
|
|
64
|
-
probe?: number;
|
|
65
|
-
/** The lock plants only once the animated ankle moves slower than this, m/s (default 0.2: a foot
|
|
66
|
-
* the take itself holds still). Raise it to pin a foot a transition is still dragging — a run
|
|
67
|
-
* entered from standing lands its first foot while the offset from the idle still decays. */
|
|
68
|
-
plantSpeed?: number;
|
|
69
|
-
};
|
|
70
|
-
/** One foot after this frame's evaluation (`Animator.foot`): whether the lock holds it, the lock's
|
|
71
|
-
* weight (eased 0…1), where it was pinned and where the leg was asked to put the ankle — all world. */
|
|
72
|
-
export type FootState = {
|
|
73
|
-
locked: boolean;
|
|
74
|
-
weight: number;
|
|
75
|
-
anchor: Vec3;
|
|
76
|
-
target: Vec3;
|
|
77
|
-
};
|
|
78
13
|
export declare class Animator extends Aspect<"anim", Node> {
|
|
79
14
|
static readonly aspect = "anim";
|
|
80
15
|
private _c;
|
|
81
16
|
private _rootMotion;
|
|
82
17
|
private _rootRotation;
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
get lod(): "auto" | "full";
|
|
88
|
-
set lod(v: "auto" | "full");
|
|
18
|
+
/** The feet: the contact bones, the foot lock, ground IK, footstep events. See `Feet`. */
|
|
19
|
+
feet: Feet;
|
|
20
|
+
/** The warp: stride and orientation fitted to the body's real motion, the step warp dials. See `Warp`. */
|
|
21
|
+
warp: Warp;
|
|
89
22
|
onAttach(): void;
|
|
90
23
|
onDetach(): void;
|
|
91
|
-
/** The clip list, in order: the GLB's embedded clips
|
|
92
|
-
*
|
|
24
|
+
/** The clip list, in order: the GLB's embedded clips, then the clips you added (an added clip with an
|
|
25
|
+
* embedded clip's name takes its place). */
|
|
93
26
|
get clips(): readonly AnimationClip[];
|
|
94
|
-
/** One clip by name
|
|
27
|
+
/** One clip by name or index — the resource: its name, duration, tracks, events. `undefined` if none. */
|
|
95
28
|
clip(ref: string | number): AnimationClip | undefined;
|
|
96
|
-
/** Add a clip under a name (default: its own
|
|
97
|
-
* Overrides an embedded clip of the same name. Chainable. */
|
|
29
|
+
/** Add a clip under a name (default: its own) — from another file, procedural, or sliced. Chainable. */
|
|
98
30
|
addClip(name: string | AnimationClip, clip?: AnimationClip): this;
|
|
99
|
-
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
|
|
103
|
-
|
|
31
|
+
/** What the engine measured about a clip on THIS skeleton (unlike `clip()`, which is the file's data):
|
|
32
|
+
* speed, travel, turn, the foot contacts, the gait phase, its cycle, and comparisons with other clips.
|
|
33
|
+
* Binds the clip on first ask. `undefined` if there is no such clip. */
|
|
34
|
+
clipInfo(clip: string | number): ClipInfo | undefined;
|
|
35
|
+
/** Play a one-shot: by name, index, or the first clip. It takes the layer over from whatever it showed,
|
|
36
|
+
* transitioned over `fade`. `await` the Playback: it resolves at the hand-over (`true`, or `false` if cut
|
|
37
|
+
* short), and what you start right then is what the clip hands over to (nothing = back to the loop). */
|
|
104
38
|
play(clip?: string | number, options?: PlayOptions): Playback;
|
|
105
|
-
/** Set the
|
|
106
|
-
*
|
|
107
|
-
* layer over from whatever plays — a one-shot included (it is cut short) — transitioned over
|
|
108
|
-
* `fade`. `stop()` removes it. */
|
|
39
|
+
/** Set the LOOP — what shows when no one-shot plays: a clip, or a blend space (`{ Idle: 0, Run: 6 }`, drive
|
|
40
|
+
* the returned object's `value`). Takes the layer over, a one-shot included. `stop()` removes it. */
|
|
109
41
|
playLoop(def: LoopDef, options?: LoopOptions): Loop | undefined;
|
|
110
|
-
/** Fade everything out, on every layer
|
|
42
|
+
/** Fade everything out, on every layer → the rest pose. */
|
|
111
43
|
stop(options?: StopOptions): this;
|
|
112
|
-
/** The
|
|
44
|
+
/** The current loop (the object the last `playLoop()` returned), if any. */
|
|
113
45
|
get loop(): Loop | undefined;
|
|
114
|
-
/** A one-shot
|
|
46
|
+
/** A one-shot hasn't handed over yet. */
|
|
115
47
|
get busy(): boolean;
|
|
116
|
-
/** What every layer shows this frame with
|
|
117
|
-
* blend shares (a debug overlay's list). */
|
|
48
|
+
/** What every layer shows this frame, with weights: a one-shot, or a loop's members with their shares. */
|
|
118
49
|
get active(): ActiveClip[];
|
|
119
|
-
/** Where the base layer is in the GAIT CYCLE: 0 at a left-foot-down, 0.5 at a right-foot-down
|
|
120
|
-
*
|
|
121
|
-
* This is the number `play(clip, { phase: 'match' })` matches against. */
|
|
50
|
+
/** Where the base layer is in the GAIT CYCLE: 0 at a left-foot-down, 0.5 at a right-foot-down; -1 when
|
|
51
|
+
* what plays has no cycle. What `play(clip, { phase: 'match' })` matches against. */
|
|
122
52
|
get phase(): number;
|
|
123
|
-
/**
|
|
124
|
-
get _id(): number;
|
|
125
|
-
/** Bind a clip to the base layer without playing it and return its native slot (-1 = no such clip);
|
|
126
|
-
* creates the native animator on first use. What a Locomotion registers its set with. */
|
|
127
|
-
_slot(clip: string | number): number;
|
|
128
|
-
/** What the engine measured on a clip once it was bound to this skeleton: foot contacts, the gait
|
|
129
|
-
* phase φ(t), and the root's travel / yaw / speed — a controller reads these instead of shipping
|
|
130
|
-
* measured tables. Binds the clip on first ask. `undefined` if there is no such clip. */
|
|
131
|
-
curves(clip: string | number): ClipCurves | undefined;
|
|
132
|
-
/** The skeleton's calibrated KNEE HINGE AXIS for a side (thigh-local, unit) with its confidence
|
|
133
|
-
* report — measured once over every bound clip's knee rotation track; the ground truth
|
|
134
|
-
* `curves(clip).kneePoleAt` predicts bend planes from. Undefined = no leg chain, or no knee
|
|
135
|
-
* motion bound to calibrate from. */
|
|
136
|
-
kneeAxis(side: "left" | "right"): KneeAxisReport | undefined;
|
|
137
|
-
/** STEP WARP v2 knobs (the warp rewrite): `stride` scales each foot's travel-direction offset
|
|
138
|
-
* from its hip (the step shortens / lengthens), `lift` = metres ADDED to its height
|
|
139
|
-
* (swing-gated; 0 = neutral, negative = a shuffle; half of what it adds raises the pelvis —
|
|
140
|
-
* the body steps higher with the foot), `pitch` (degrees, + = toes up) rotates each foot about
|
|
141
|
-
* its lateral axis, `slope` (degrees, + = ascending) the invisible staircase — feet on the
|
|
142
|
-
* incline + auto pitch; raise the character by tan(slope) × the stride-scaled clip travel to
|
|
143
|
-
* hold each planted foot on its tread. Solved in the calibrated knee hinge plane.
|
|
144
|
-
* Omit / null = off. A tuning bench's dial — locomotion will drive this itself later. */
|
|
145
|
-
setStepWarp(options?: {
|
|
146
|
-
stride?: number;
|
|
147
|
-
lift?: number;
|
|
148
|
-
pitch?: number;
|
|
149
|
-
slope?: number;
|
|
150
|
-
} | null): void;
|
|
151
|
-
/** Scrub: set `clip`'s playhead directly, seconds — for inspectors and debug boards (pair with
|
|
152
|
-
* `speed = 0`). The clip should be the one showing; nothing is faded or re-picked. */
|
|
153
|
-
seek(clip: string | number, time: number): void;
|
|
154
|
-
/** `clip`'s current playhead, seconds (-1 = not bound). */
|
|
53
|
+
/** A clip's playhead, seconds (-1 = not bound). */
|
|
155
54
|
time(clip: string | number): number;
|
|
156
|
-
/**
|
|
157
|
-
*
|
|
55
|
+
/** Scrub a clip's playhead, seconds — inspectors and debug boards (pair with `speed = 0`). Nothing is
|
|
56
|
+
* faded or re-picked. */
|
|
57
|
+
seek(clip: string | number, time: number): void;
|
|
58
|
+
/** Re-aim a playing turn clip's warp (`play({ turn })`) to `deg` for the rest of the clip; `undefined` = off. */
|
|
158
59
|
setTurn(clip: string | number, deg: number | undefined): void;
|
|
159
|
-
/** THE FEET (docs/animation-v2-plan.md §2.9): which bones they are, and what the engine does with
|
|
160
|
-
* them after the clips are composited — the foot LOCK (a planted foot stays where it landed while the
|
|
161
|
-
* body moves on) and GROUND IK (each foot on the ground probed under it, the pelvis lowered). Only
|
|
162
|
-
* the keys given change, so the bones and the behaviour can be set from different places:
|
|
163
|
-
*
|
|
164
|
-
* model.anim.feet = { left: 'LeftFoot', right: 'RightFoot' } // a rig the classifier misses
|
|
165
|
-
* model.anim.feet = { lock: true } // (a Locomotion does this itself)
|
|
166
|
-
* model.anim.feet = { lock: true, ik: true, pelvis: 0.3 } // stairs and slopes
|
|
167
|
-
*
|
|
168
|
-
* The engine probes the ground itself (against what a character can stand on) and reads the
|
|
169
|
-
* CharacterController's ground state; nothing is fed per frame. See `FeetOptions`. */
|
|
170
|
-
set feet(f: FeetOptions);
|
|
171
|
-
private readonly _feetOpts;
|
|
172
|
-
/** One foot's state after this frame's evaluation — where the lock holds it and with what weight
|
|
173
|
-
* (a debug beam under the foot). `undefined` on a host without the feet stage, or before anything
|
|
174
|
-
* played. */
|
|
175
|
-
foot(side: "left" | "right"): FootState | undefined;
|
|
176
|
-
/** WARPING (docs/animation-v2-plan.md §2.7) — the pose is fitted to what the body actually does,
|
|
177
|
-
* after the clips are composited and before the feet:
|
|
178
|
-
*
|
|
179
|
-
* `stride` — each leg's hip→foot vector is scaled ALONG the travel direction by the ratio of the
|
|
180
|
-
* game speed to the shown clip's own (clamped, default 0.6…1.5), the foot height kept, and the
|
|
181
|
-
* pelvis lowered when that would overextend a leg. A walk played at 1.9 m/s stops skating; a
|
|
182
|
-
* speed between two gaits becomes continuous instead of "two clips and a crossfade".
|
|
183
|
-
* `orientation` — the lower body turns from the clip's travel direction toward the one the body
|
|
184
|
-
* really travels in (capped, default 60°) and the spine counter-turns, so the chest keeps its
|
|
185
|
-
* facing. Arcs and strafing stop needing a clip per angle.
|
|
186
|
-
*
|
|
187
|
-
* Both need to know the body's motion, which a `Locomotion` feeds every frame; without one, set
|
|
188
|
-
* `_creator.animatorSetMotion` yourself or leave warping off. Off by default.
|
|
189
|
-
*
|
|
190
|
-
* model.anim.warp = true // both, with the defaults
|
|
191
|
-
* model.anim.warp = { stride: [0.7, 1.4], orientation: 45 }
|
|
192
|
-
*/
|
|
193
|
-
set warp(w: WarpOptions | boolean);
|
|
194
|
-
/** A foot planted (world position) — audio, dust, decals. Fires for what the BASE layer shows,
|
|
195
|
-
* from the clip's own contacts; a clip with no contacts fires nothing. */
|
|
196
|
-
onStep(cb: StepHandler): this;
|
|
197
|
-
offStep(cb: StepHandler): this;
|
|
198
|
-
/** A new layer on top (masked override / additive). The returned object is its handle. */
|
|
199
|
-
addLayer(options?: LayerOptions): Layer;
|
|
200
|
-
on(event: string, cb: ClipEventHandler): this;
|
|
201
|
-
off(event: string, cb: ClipEventHandler): this;
|
|
202
60
|
/** Global playback rate: 0.3 = slow-mo, 0 = pause. */
|
|
203
61
|
get speed(): number;
|
|
204
62
|
set speed(v: number);
|
|
205
|
-
/**
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
63
|
+
/** Clip events (`clip.addEvent(0.4, 'hit')` → `anim.on('hit', …)`). */
|
|
64
|
+
on(event: string, cb: ClipEventHandler): this;
|
|
65
|
+
off(event: string, cb: ClipEventHandler): this;
|
|
66
|
+
/** A new layer on top (masked override / additive); the returned object is its handle. */
|
|
67
|
+
addLayer(options?: LayerOptions): Layer;
|
|
68
|
+
/** The root bone's horizontal travel comes OFF the pose and moves the node — or its CharacterController
|
|
69
|
+
* (on this node or an ancestor) as a velocity, so it collides. For clips whose hips actually travel. A
|
|
70
|
+
* character under a `Locomotion` gets this from its displacement mode instead. */
|
|
209
71
|
get rootMotion(): boolean;
|
|
210
72
|
set rootMotion(on: boolean);
|
|
211
|
-
/** With `rootMotion
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
* crossfade into the next clip keeps that heading instead of swinging back. Off by default: a
|
|
215
|
-
* walk cycle's hip sway is a turn too, and most rigs want it in the pose; turn it on for a rig
|
|
216
|
-
* whose root bone carries the heading (`lecodes assets retarget --root-rotation yaw`). */
|
|
73
|
+
/** With `rootMotion`: the root bone's TURN is root motion too — it comes off the pose and turns the node,
|
|
74
|
+
* so a turn clip leaves the character facing where it took it. Off by default (a walk's hip sway is a
|
|
75
|
+
* turn too); on for a rig whose root carries the heading (`lecodes assets retarget --root-rotation yaw`). */
|
|
217
76
|
get rootRotation(): boolean;
|
|
218
77
|
set rootRotation(on: boolean);
|
|
78
|
+
/** `'auto'` (default): a character small on screen or out of view is evaluated every 2nd / 4th frame
|
|
79
|
+
* without its finger, toe and twist joints; `'full'`: every frame, every joint (a hero seen through a
|
|
80
|
+
* scope). Independent of `Model.lod`, the mesh level. */
|
|
81
|
+
get lod(): "auto" | "full";
|
|
82
|
+
set lod(v: "auto" | "full");
|
|
83
|
+
/** The native animator's id — 0 until something is played or bound. */
|
|
84
|
+
get _id(): number;
|
|
85
|
+
/** Bind a clip to the base layer without playing it; its native slot (-1 = no such clip). */
|
|
86
|
+
_slot(clip: string | number): number;
|
|
219
87
|
}
|