lecodes-sdk 0.19.1 → 0.20.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 +31 -0
- package/dist/host.d.ts +3 -0
- package/dist/inject.js +260 -361
- package/dist/types/gl/Locomotion.d.ts +3 -1
- 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 +46 -7
- package/dist/types/inject.d.ts +7 -2
- package/dist/types/plugins/map.d.ts +174 -0
- package/dist/types.json +1 -1
- package/package.json +1 -1
- package/prompts/dist/2d-game.md +197 -408
- package/prompts/dist/3d-app.md +166 -491
- package/prompts/dist/ar-app.md +163 -373
- package/prompts/dist/design.md +87 -83
- package/prompts/dist/ui-app.md +136 -325
- package/src/bridges.d.ts +13 -6
- package/src/compile/__tests__/compile.test.ts +12 -0
- package/src/compile/compileProject.ts +5 -0
- package/src/core/Aspect.ts +1 -1
- package/src/gl/CameraPlace.ts +52 -52
- package/src/gl/Locomotion.ts +7 -5
- package/src/gl/Particles.ts +3 -3
- package/src/gl/Ragdoll.ts +270 -270
- package/src/gl/Scene.ts +1 -1
- package/src/gl/Trigger.ts +45 -45
- package/src/gl/animation/Animator.ts +137 -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 +736 -670
- package/src/gl/scenarios.ts +291 -291
- package/src/gl/state.ts +6 -6
- package/src/host.d.ts +3 -0
- package/src/inject.ts +11 -2
- package/src/plugins/map.ts +396 -0
- package/src/scene/gizmos.ts +148 -148
|
@@ -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";
|
|
@@ -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
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Vec3 } from "../../math/vec";
|
|
2
|
+
import type { KneeAxisReport, StepHandler } from "./core";
|
|
3
|
+
/** The feet settings (`anim.feet.set()` / the properties of `anim.feet`). Distances are metres, times
|
|
4
|
+
* seconds. Every key is optional and only the keys given change. */
|
|
5
|
+
export type FeetOptions = {
|
|
6
|
+
/** The contact bones per side — `'LeftFoot'`, or with a toe / ball `['LeftFoot', 'LeftToeBase']`.
|
|
7
|
+
* Default: classified from the bone names (Mixamo / Unity / Blender / UE). Setting them re-bakes
|
|
8
|
+
* every clip's contacts and phase. */
|
|
9
|
+
left?: string | string[];
|
|
10
|
+
right?: string | string[];
|
|
11
|
+
/** FOOT LOCK: a foot the shown clip calls planted is pinned where it landed — heel to ball, rolling
|
|
12
|
+
* as the clip rolls — and the leg re-solved to keep it there while the body moves on. Off by default. */
|
|
13
|
+
lock?: boolean;
|
|
14
|
+
/** GROUND IK: each foot is put on the ground the engine probes under it (stairs, a slope, a kerb),
|
|
15
|
+
* aligned to its normal, the pelvis lowered so the leg can reach. Needs a physics world to probe;
|
|
16
|
+
* without one the ground is the node's own plane. Off by default. */
|
|
17
|
+
ik?: boolean;
|
|
18
|
+
/** How far the pelvis may drop for the ground (default 0.35). */
|
|
19
|
+
pelvis?: number;
|
|
20
|
+
/** A locked foot never absorbs more residual than this — beyond it the anchor follows the animation
|
|
21
|
+
* instead of fighting it (default 0.10). */
|
|
22
|
+
unlockDistance?: number;
|
|
23
|
+
/** The lock's ease in / out, seconds (default 0.08 / 0.12). */
|
|
24
|
+
lockIn?: number;
|
|
25
|
+
lockOut?: number;
|
|
26
|
+
/** 0..1: how much the foot tilts onto the ground normal (default 1). */
|
|
27
|
+
align?: number;
|
|
28
|
+
/** The probe ray's reach above and below the ankle (default 0.6). */
|
|
29
|
+
probe?: number;
|
|
30
|
+
/** The lock plants only once the animated ankle moves slower than this, m/s (default 0.2). Raise it
|
|
31
|
+
* to pin a foot a transition is still dragging. */
|
|
32
|
+
plantSpeed?: number;
|
|
33
|
+
};
|
|
34
|
+
/** One foot after this frame's evaluation (`anim.feet.state(side)`): whether the lock holds it, the
|
|
35
|
+
* lock's weight (eased 0…1), where it was pinned and where the leg was asked to put the ankle — all world. */
|
|
36
|
+
export type FootState = {
|
|
37
|
+
locked: boolean;
|
|
38
|
+
weight: number;
|
|
39
|
+
anchor: Vec3;
|
|
40
|
+
target: Vec3;
|
|
41
|
+
};
|
|
42
|
+
export declare class Feet {
|
|
43
|
+
private readonly _c;
|
|
44
|
+
private readonly _o;
|
|
45
|
+
/** Change several settings at once; only the keys given change. Chainable. */
|
|
46
|
+
set(options: FeetOptions): this;
|
|
47
|
+
/** The current settings (what was set; unset keys are the engine's defaults). */
|
|
48
|
+
get options(): Readonly<FeetOptions>;
|
|
49
|
+
get lock(): boolean;
|
|
50
|
+
set lock(v: boolean);
|
|
51
|
+
get ik(): boolean;
|
|
52
|
+
set ik(v: boolean);
|
|
53
|
+
get pelvis(): number;
|
|
54
|
+
set pelvis(v: number);
|
|
55
|
+
get unlockDistance(): number;
|
|
56
|
+
set unlockDistance(v: number);
|
|
57
|
+
get lockIn(): number;
|
|
58
|
+
set lockIn(v: number);
|
|
59
|
+
get lockOut(): number;
|
|
60
|
+
set lockOut(v: number);
|
|
61
|
+
get align(): number;
|
|
62
|
+
set align(v: number);
|
|
63
|
+
get probe(): number;
|
|
64
|
+
set probe(v: number);
|
|
65
|
+
get plantSpeed(): number;
|
|
66
|
+
set plantSpeed(v: number);
|
|
67
|
+
/** The contact bones (`undefined` = classified from the names). */
|
|
68
|
+
get left(): string | string[] | undefined;
|
|
69
|
+
set left(v: string | string[] | undefined);
|
|
70
|
+
get right(): string | string[] | undefined;
|
|
71
|
+
set right(v: string | string[] | undefined);
|
|
72
|
+
/** One foot's state after this frame's evaluation — where the lock holds it and with what weight
|
|
73
|
+
* (a debug beam under the foot). `undefined` on a host without the feet stage, or before anything played. */
|
|
74
|
+
state(side: "left" | "right"): FootState | undefined;
|
|
75
|
+
/** The skeleton's calibrated KNEE HINGE AXIS for a side (thigh-local, unit) with its confidence report —
|
|
76
|
+
* measured once over every bound clip's knee rotation track. `undefined` = no leg chain, or no knee
|
|
77
|
+
* motion bound to calibrate from. */
|
|
78
|
+
kneeAxis(side: "left" | "right"): KneeAxisReport | undefined;
|
|
79
|
+
/** A foot planted (world position) — audio, dust, decals. Fires for what the BASE layer shows, from
|
|
80
|
+
* the clip's own contacts; a clip with no contacts fires nothing. */
|
|
81
|
+
onStep(cb: StepHandler): this;
|
|
82
|
+
offStep(cb: StepHandler): this;
|
|
83
|
+
private pushBones;
|
|
84
|
+
private push;
|
|
85
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** What `anim.warp` turns on. Speeds are m/s, angles degrees, distances metres. */
|
|
2
|
+
export type WarpOptions = {
|
|
3
|
+
/** Fit the stride to the speed the body actually travels at. `[min, max]` clamps the scale (default
|
|
4
|
+
* 0.85…1.2). A CORRECTION: a pack whose takes already read right at the speeds it is played at wants
|
|
5
|
+
* none of this; open the range for a pack that must cover speeds it was never recorded at. */
|
|
6
|
+
stride?: boolean | [number, number];
|
|
7
|
+
/** Turn the lower body toward where the body really travels; a number caps the turn in degrees
|
|
8
|
+
* (default 20). The whole twist lives in one joint: a few degrees read as a lean, a lot as a broken
|
|
9
|
+
* back. Only applied while the gait LOOP shows — a start, a turn or a stop walks a path of its own. */
|
|
10
|
+
orientation?: boolean | number;
|
|
11
|
+
/** Below this speed — the game's or the clip's — both warps are off (default 0.2). */
|
|
12
|
+
minSpeed?: number;
|
|
13
|
+
/** How far the pelvis may drop to keep a stretched leg from locking straight (default 0.25). */
|
|
14
|
+
pelvis?: number;
|
|
15
|
+
/** The stride scale's own spring, seconds (default 0.15): the shown clip's recorded speed steps at every
|
|
16
|
+
* switch, so the scale is smoothed rather than followed. */
|
|
17
|
+
strideTime?: number;
|
|
18
|
+
};
|
|
19
|
+
/** STEP WARP dials (`anim.warp.step`): `stride` scales each foot's travel-direction offset from its hip,
|
|
20
|
+
* `lift` = metres ADDED to its height (swing-gated; negative = a shuffle; half of it raises the pelvis),
|
|
21
|
+
* `pitch` (degrees, + = toes up) rotates each foot about its lateral axis, `slope` (degrees, + = ascending)
|
|
22
|
+
* the invisible staircase — feet on the incline, auto pitch, the character raised to hold each planted
|
|
23
|
+
* foot on its tread. A tuning bench's dial; locomotion will drive this itself later. */
|
|
24
|
+
export type StepWarpOptions = {
|
|
25
|
+
stride?: number;
|
|
26
|
+
lift?: number;
|
|
27
|
+
pitch?: number;
|
|
28
|
+
slope?: number;
|
|
29
|
+
};
|
|
30
|
+
export declare class Warp {
|
|
31
|
+
private readonly _c;
|
|
32
|
+
private _o;
|
|
33
|
+
private _step;
|
|
34
|
+
/** Replace the settings: `true` = both warps with the defaults, `false` / `{}` = off, or the options.
|
|
35
|
+
* (Replaces, does not merge — what is not asked for is off.) Chainable. */
|
|
36
|
+
set(w: WarpOptions | boolean): this;
|
|
37
|
+
/** The current settings. */
|
|
38
|
+
get options(): Readonly<WarpOptions>;
|
|
39
|
+
get stride(): boolean | [number, number];
|
|
40
|
+
set stride(v: boolean | [number, number]);
|
|
41
|
+
get orientation(): boolean | number;
|
|
42
|
+
set orientation(v: boolean | number);
|
|
43
|
+
get minSpeed(): number;
|
|
44
|
+
set minSpeed(v: number);
|
|
45
|
+
get pelvis(): number;
|
|
46
|
+
set pelvis(v: number);
|
|
47
|
+
get strideTime(): number;
|
|
48
|
+
set strideTime(v: number);
|
|
49
|
+
/** The step warp dials; `null` = off. */
|
|
50
|
+
get step(): StepWarpOptions | null;
|
|
51
|
+
set step(v: StepWarpOptions | null | undefined);
|
|
52
|
+
private push;
|
|
53
|
+
}
|
|
@@ -48,8 +48,17 @@ export type LoopOptions = {
|
|
|
48
48
|
* over from a start / turn clip wants). The members share one clock, so this is every member's phase. */
|
|
49
49
|
phase?: number | "match";
|
|
50
50
|
};
|
|
51
|
-
/**
|
|
52
|
-
|
|
51
|
+
/** A blend member with its CYCLE given explicitly: `at` = its position, `offset` = its gait phase at t = 0
|
|
52
|
+
* (0 = a left-foot-down, 0.5 = a right-foot-down, 0–1), `cycles` = how many gait cycles the clip holds
|
|
53
|
+
* (a two-stride loop: 2). Both are measured offline from the clip's foot marks. Members given as a
|
|
54
|
+
* bare position run in normalized time and have no cycle (nothing phase-matches to them). */
|
|
55
|
+
export type BlendMember = {
|
|
56
|
+
at: BlendPosition;
|
|
57
|
+
offset?: number;
|
|
58
|
+
cycles?: number;
|
|
59
|
+
};
|
|
60
|
+
/** What a layer loops: one clip (name / index), or a blend space `{ name: position | { at, offset, cycles } }`. */
|
|
61
|
+
export type LoopDef = string | number | Record<string, BlendPosition | BlendMember>;
|
|
53
62
|
/** One clip the layer shows this frame — `layer.active` / `anim.active` (a debug overlay's list). */
|
|
54
63
|
export type ActiveClip = {
|
|
55
64
|
name: string;
|
|
@@ -73,9 +82,28 @@ export type LayerOptions = {
|
|
|
73
82
|
export type ClipEventHandler = (clip: string, layer: Layer) => void;
|
|
74
83
|
/** A foot planted: which one, and where in the world it landed. */
|
|
75
84
|
export type StepHandler = (side: "left" | "right", position: Vec3) => void;
|
|
76
|
-
/**
|
|
85
|
+
/** A loop's GAIT CYCLE as two numbers — what a blend member's `{ offset, cycles }` wants: φ(t) = offset +
|
|
86
|
+
* cycles · t / duration, 0 = a left-foot-down. `residual` = the worst foot-down's distance from that line
|
|
87
|
+
* (cycles; a clean loop sits under 0.03), `steps` = the foot-downs it was fitted through. */
|
|
88
|
+
export type ClipCycle = {
|
|
89
|
+
offset: number;
|
|
90
|
+
cycles: number;
|
|
91
|
+
residual: number;
|
|
92
|
+
steps: number;
|
|
93
|
+
};
|
|
94
|
+
/** A loop's cycle found by POSE against a reference loop (`clipInfo(clip).alignTo(ref)`): the `{ offset,
|
|
95
|
+
* cycles }` under which it shows the reference's pose at the reference's phase. `score` = the fit at that
|
|
96
|
+
* alignment (metres, the joint distance + velocity measure), `margin` = how much worse the runner-up
|
|
97
|
+
* alignment ≥ 0.2 cycle away is — near 0 means ambiguous (a mirror pair, an in-place idle). */
|
|
98
|
+
export type ClipAlign = {
|
|
99
|
+
offset: number;
|
|
100
|
+
cycles: number;
|
|
101
|
+
score: number;
|
|
102
|
+
margin: number;
|
|
103
|
+
};
|
|
104
|
+
/** What the engine measured on a clip once it was bound to this skeleton (`anim.clipInfo('Walk')`).
|
|
77
105
|
* The root curves are of the clip's ROOT bone — its travel is what root motion would move. */
|
|
78
|
-
export type
|
|
106
|
+
export type ClipInfo = {
|
|
79
107
|
/** total horizontal root travel, metres */
|
|
80
108
|
travel: number;
|
|
81
109
|
/** mean root speed over the clip, m/s */
|
|
@@ -84,6 +112,17 @@ export type ClipCurves = {
|
|
|
84
112
|
turn: number;
|
|
85
113
|
/** the root barely moves — an in-place clip */
|
|
86
114
|
inPlace: boolean;
|
|
115
|
+
/** The gait cycle fitted through the foot contacts (a foot already down at t = 0 is not a step) —
|
|
116
|
+
* the numbers a blend member takes as `{ offset, cycles }`. Undefined: no steps. */
|
|
117
|
+
cycle(): ClipCycle | undefined;
|
|
118
|
+
/** This loop's cycle found by POSE against `reference` (its cycle given, else `reference`'s `cycle()`,
|
|
119
|
+
* else offset 0 / one cycle — the answer is then relative to the reference's own time). Reads no marks:
|
|
120
|
+
* a markless loop (swimming, breathing, an upper-body sway) gets a cycle, and a marked one gets a
|
|
121
|
+
* second opinion — a mirrored anchor shows as a 0.5 disagreement with `cycle()`. Undefined: nothing to compare. */
|
|
122
|
+
alignTo(reference: string | number, cycle?: {
|
|
123
|
+
offset: number;
|
|
124
|
+
cycles: number;
|
|
125
|
+
}): ClipAlign | undefined;
|
|
87
126
|
/** the clip has a gait cycle (feet planting in turn) — `phaseAt` is meaningful */
|
|
88
127
|
hasPhase: boolean;
|
|
89
128
|
/** When each foot TOUCHES the ground, seconds — the phase anchor. `still` is the window inside it
|
|
@@ -185,7 +224,7 @@ export type ClipCurves = {
|
|
|
185
224
|
* relative to the root, no turn). Starts, stops and turns are not. */
|
|
186
225
|
cyclic: boolean;
|
|
187
226
|
};
|
|
188
|
-
/** The calibrated knee hinge-axis report (`anim.kneeAxis('left')`): the axis in the thigh's local
|
|
227
|
+
/** The calibrated knee hinge-axis report (`anim.feet.kneeAxis('left')`): the axis in the thigh's local
|
|
189
228
|
* frame, and the calibration's own confidence — the angular spread of its measurements (radians;
|
|
190
229
|
* a real knee comes in at a few degrees) over `samples` consecutive-frame deltas of the pack.
|
|
191
230
|
* `plant` = the calibrated PLANT HEIGHTS (model space): where the ankle / toe actually sit under
|
|
@@ -309,7 +348,7 @@ export declare class Core {
|
|
|
309
348
|
/** A bound clip's current playhead, seconds (-1 = not bound). */
|
|
310
349
|
timeOf(ref: string | number): number;
|
|
311
350
|
/** What the engine measured on the clip once it was bound to this skeleton — binds it if needed. */
|
|
312
|
-
|
|
351
|
+
clipInfo(ref: string | number): ClipInfo | undefined;
|
|
313
352
|
/** The skeleton's calibrated knee hinge axis for a side, with its confidence report — measured once
|
|
314
353
|
* over every bound clip's knee rotation track. Undefined = no leg chain / no knee motion bound. */
|
|
315
354
|
kneeAxis(side: "left" | "right"): KneeAxisReport | undefined;
|
|
@@ -321,7 +360,7 @@ export declare class Core {
|
|
|
321
360
|
* own lateral axis — a slope's foot rotation; `slope` (degrees, + = ascending) is the INVISIBLE
|
|
322
361
|
* STAIRCASE: foot heights follow the incline (leading foot higher) and the feet auto-pitch by
|
|
323
362
|
* the same angle — pair it with raising the character by tan(slope) × the stride-scaled clip
|
|
324
|
-
* travel (`
|
|
363
|
+
* travel (`clipInfo(clip).travelAt`), which holds every planted foot's world height constant on
|
|
325
364
|
* its own tread. Solved in the calibrated knee hinge plane with a SOFT reach (a leg at its limit
|
|
326
365
|
* keeps a residual knee bend instead of popping against the clamp), and whenever a leg would
|
|
327
366
|
* overreach — a descent, a long stride — the pelvis lowers by exactly the excess (weighted by
|
package/dist/types/inject.d.ts
CHANGED
|
@@ -60,6 +60,7 @@ export { easeIn, easeOut, easeInOut } from "./animate/easings";
|
|
|
60
60
|
export { QRScanner } from "./plugins/qr";
|
|
61
61
|
export { CameraView, type CameraFacing } from "./plugins/camera";
|
|
62
62
|
export { Geolocation, type GeoPosition, type GeoOptions, type GeoWatch } from "./plugins/geolocation";
|
|
63
|
+
export { MapView, type MapOptions, type MapStyle, type MapStyleName, type MapCamera, type MapTap, type LngLat, type CameraMove, type FitOptions, type MapPaddingValues, type MarkerItem, type MarkerTap, type MarkerLayer, type MarkerLayerOptions, type LineLayer, type LineLayerOptions, type UserLocationOptions, } from "./plugins/map";
|
|
63
64
|
export { Push, type PushPayload, type PushStatus, type PushRegisterOptions, type PushEvent } from "./plugins/push";
|
|
64
65
|
export { OAuth, type OAuthCredential, type OAuthProviderName } from "./plugins/oauth";
|
|
65
66
|
export { Service } from "./plugins/service";
|
|
@@ -94,11 +95,15 @@ export { Gearbox } from "./gl/Gearbox";
|
|
|
94
95
|
export { AnimationClip } from "./gl/animation/AnimationClip";
|
|
95
96
|
export type { ClipDef, ClipTrackDef, ClipKey } from "./gl/animation/AnimationClip";
|
|
96
97
|
export { Animator } from "./gl/animation/Animator";
|
|
97
|
-
export type {
|
|
98
|
+
export type { LodMode } from "./gl/animation/Animator";
|
|
99
|
+
export { Feet } from "./gl/animation/Feet";
|
|
100
|
+
export type { FeetOptions, FootState } from "./gl/animation/Feet";
|
|
101
|
+
export { Warp } from "./gl/animation/Warp";
|
|
102
|
+
export type { WarpOptions, StepWarpOptions } from "./gl/animation/Warp";
|
|
98
103
|
export { Playback } from "./gl/animation/Playback";
|
|
99
104
|
export { Loop } from "./gl/animation/Loop";
|
|
100
105
|
export { Layer } from "./gl/animation/Layer";
|
|
101
|
-
export type { PlayOptions, StopOptions, LayerOptions, LoopOptions, LoopDef, BlendPosition, ActiveClip } from "./gl/animation/core";
|
|
106
|
+
export type { PlayOptions, StopOptions, LayerOptions, LoopOptions, LoopDef, BlendPosition, BlendMember, ActiveClip, ClipInfo, ClipCycle, ClipAlign, KneeAxisReport, StepHandler, ClipEventHandler } from "./gl/animation/core";
|
|
102
107
|
export { IK } from "./gl/IK";
|
|
103
108
|
export type { IKTwoBone, IKLookAt } from "./gl/IK";
|
|
104
109
|
export { Light } from "./gl/Light";
|