@yali-engine/animation 0.0.0-stage → 0.4.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/animation.d.ts +100 -0
- package/dist/animation.js +183 -0
- package/dist/animation.js.map +1 -0
- package/dist/components.d.ts +33 -0
- package/dist/components.js +19 -0
- package/dist/components.js.map +1 -0
- package/dist/gltf.d.ts +68 -0
- package/dist/gltf.js +134 -0
- package/dist/gltf.js.map +1 -0
- package/dist/graph.d.ts +94 -0
- package/dist/graph.js +155 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/morph.d.ts +49 -0
- package/dist/morph.js +136 -0
- package/dist/morph.js.map +1 -0
- package/dist/plugin.d.ts +16 -0
- package/dist/plugin.js +111 -0
- package/dist/plugin.js.map +1 -0
- package/dist/ragdoll.d.ts +72 -0
- package/dist/ragdoll.js +192 -0
- package/dist/ragdoll.js.map +1 -0
- package/package.json +28 -3
- package/README.md +0 -3
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { type Entity, type World } from '@yali-engine/core';
|
|
2
|
+
import type { BuiltGraph } from './graph.ts';
|
|
3
|
+
import { Morphs } from './morph.ts';
|
|
4
|
+
/** One animated property of one joint (`Animation.addClip`). */
|
|
5
|
+
export interface ClipTrack {
|
|
6
|
+
readonly joint: number;
|
|
7
|
+
readonly path: 'translation' | 'rotation' | 'scale';
|
|
8
|
+
/** LINEAR (rotations by normalized lerp) or STEP. */
|
|
9
|
+
readonly interpolation: 'LINEAR' | 'STEP';
|
|
10
|
+
/** Key times in seconds, increasing. */
|
|
11
|
+
readonly times: Float32Array;
|
|
12
|
+
/** 3 floats per key, or 4 (x, y, z, w) for a rotation. */
|
|
13
|
+
readonly values: Float32Array;
|
|
14
|
+
}
|
|
15
|
+
/** A joint's rest transform: translation, rotation (x, y, z, w), scale (per axis). */
|
|
16
|
+
export interface JointRest {
|
|
17
|
+
readonly t: readonly number[];
|
|
18
|
+
readonly r: readonly number[];
|
|
19
|
+
readonly s: readonly number[];
|
|
20
|
+
}
|
|
21
|
+
/** This frame's palette (the renderer's `PaletteView`): views into the core's memory. */
|
|
22
|
+
export interface PaletteFrame {
|
|
23
|
+
readonly f32: Float32Array<ArrayBufferLike>;
|
|
24
|
+
/** First float. */
|
|
25
|
+
readonly at: number;
|
|
26
|
+
/** Rows (joints), 12 floats each. */
|
|
27
|
+
readonly rows: number;
|
|
28
|
+
}
|
|
29
|
+
/** What `Animation.stats` reports. */
|
|
30
|
+
export interface AnimationStats {
|
|
31
|
+
readonly skeletons: number;
|
|
32
|
+
readonly clips: number;
|
|
33
|
+
readonly skins: number;
|
|
34
|
+
readonly graphs: number;
|
|
35
|
+
/** Palette rows (joints) skinned last frame. */
|
|
36
|
+
readonly paletteRows: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* An app's animation assets (the `animation` resource, ADR-0083): skeletons, clips and skins
|
|
40
|
+
* live in the core (its `anim` variant); this adds them and reads the frame's palette. Which
|
|
41
|
+
* entity plays what is ECS data (`anim.Animator`, `anim.Skin`, `anim.Socket`).
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* const anim = app.resource<Animation>('animation');
|
|
45
|
+
* const skeleton = anim.addSkeleton([-1, 0], [{ t: [0, 0, 0], r: [0, 0, 0, 1], s: [1, 1, 1] }, { t: [0, 1, 0], r: [0, 0, 0, 1], s: [1, 1, 1] }]);
|
|
46
|
+
* const clip = anim.addClip(skeleton, [{ joint: 1, path: 'rotation', interpolation: 'LINEAR', times, values }]);
|
|
47
|
+
*/
|
|
48
|
+
export declare class Animation {
|
|
49
|
+
#private;
|
|
50
|
+
readonly world: World;
|
|
51
|
+
/** Morph targets bound to animators (blended on the CPU when their weights change). */
|
|
52
|
+
readonly morphs: Morphs;
|
|
53
|
+
constructor(world: World);
|
|
54
|
+
/**
|
|
55
|
+
* Adds a skeleton: `parents[i]` is -1 for a root, else an earlier joint (parents first);
|
|
56
|
+
* `rest` is each joint's local rest transform. Returns its id (for `anim.Animator.skeleton`).
|
|
57
|
+
*/
|
|
58
|
+
addSkeleton(parents: readonly number[], rest: readonly JointRest[]): number;
|
|
59
|
+
/** Adds a clip over `skeleton`'s joints. Returns its id (for `anim.Animator.clip`). */
|
|
60
|
+
addClip(skeleton: number, tracks: readonly ClipTrack[]): number;
|
|
61
|
+
/**
|
|
62
|
+
* Adds a skin over `skeleton`: the joint each slot follows and each slot's inverse bind
|
|
63
|
+
* matrix (16 floats, column-major). Returns its id (for `anim.Skin.skin`) and how far its rest
|
|
64
|
+
* palette is from the identity (`restError`: about 0 for a consistent file).
|
|
65
|
+
*/
|
|
66
|
+
addSkin(skeleton: number, joints: readonly number[], inverseBind: Float32Array): {
|
|
67
|
+
id: number;
|
|
68
|
+
restError: number;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Adds a graph (ADR-0089) built with `graph()` for `skeleton`; returns its id (for
|
|
72
|
+
* `anim.Graph.graph`). Every clip it plays must animate that skeleton.
|
|
73
|
+
*/
|
|
74
|
+
addGraph(skeleton: number, g: BuiltGraph): number;
|
|
75
|
+
/** Adds a per-joint weight mask (0–1 per skeleton joint) for masked blends; returns its id. */
|
|
76
|
+
addMask(skeleton: number, weights: Float32Array): number;
|
|
77
|
+
/**
|
|
78
|
+
* Joint `joint`'s model matrix of animator `entity` (16 floats, column-major, in the animator's
|
|
79
|
+
* root frame) as of the last update, or null before its first.
|
|
80
|
+
*/
|
|
81
|
+
jointModel(entity: Entity, joint: number): Float32Array | null;
|
|
82
|
+
/** A clip's length in seconds (negative for an unknown id). */
|
|
83
|
+
clipDuration(clip: number): number;
|
|
84
|
+
/** One frame (the plugin's Update system calls it): animators advance by `dt`, palettes and sockets follow. */
|
|
85
|
+
update(dt: number): void;
|
|
86
|
+
/** This frame's palette, as views into the core's memory (valid until the next `update`). Allocation-free. */
|
|
87
|
+
palette(): PaletteFrame;
|
|
88
|
+
/**
|
|
89
|
+
* Sets parameter `name` of `entity`'s graph (its `anim.Graph`, built as `g`): a trigger fires
|
|
90
|
+
* with 1, and the graph clears it when a transition takes it.
|
|
91
|
+
*/
|
|
92
|
+
setParam(entity: Entity, g: BuiltGraph, name: string, value: number): void;
|
|
93
|
+
/** `entity`'s graph state: its root state machine's state name ('' without one) and seconds in it. */
|
|
94
|
+
state(entity: Entity, g: BuiltGraph): {
|
|
95
|
+
state: string;
|
|
96
|
+
time: number;
|
|
97
|
+
};
|
|
98
|
+
/** Asset counts and the last frame's palette size. */
|
|
99
|
+
stats(): AnimationStats;
|
|
100
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { requireFeature, YaliError } from '@yali-engine/core';
|
|
2
|
+
import { registerAnimation } from "./components.js";
|
|
3
|
+
import { Morphs } from "./morph.js";
|
|
4
|
+
const PATHS = { translation: 0, rotation: 1, scale: 2 };
|
|
5
|
+
/**
|
|
6
|
+
* An app's animation assets (the `animation` resource, ADR-0083): skeletons, clips and skins
|
|
7
|
+
* live in the core (its `anim` variant); this adds them and reads the frame's palette. Which
|
|
8
|
+
* entity plays what is ECS data (`anim.Animator`, `anim.Skin`, `anim.Socket`).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const anim = app.resource<Animation>('animation');
|
|
12
|
+
* const skeleton = anim.addSkeleton([-1, 0], [{ t: [0, 0, 0], r: [0, 0, 0, 1], s: [1, 1, 1] }, { t: [0, 1, 0], r: [0, 0, 0, 1], s: [1, 1, 1] }]);
|
|
13
|
+
* const clip = anim.addClip(skeleton, [{ joint: 1, path: 'rotation', interpolation: 'LINEAR', times, values }]);
|
|
14
|
+
*/
|
|
15
|
+
export class Animation {
|
|
16
|
+
world;
|
|
17
|
+
/** Morph targets bound to animators (blended on the CPU when their weights change). */
|
|
18
|
+
morphs;
|
|
19
|
+
#x;
|
|
20
|
+
#skeletons = [];
|
|
21
|
+
#clips = 0;
|
|
22
|
+
#skins = 0;
|
|
23
|
+
#graphs = 0;
|
|
24
|
+
#frame = { f32: new Float32Array(0), at: 0, rows: 0 };
|
|
25
|
+
constructor(world) {
|
|
26
|
+
requireFeature(world.core, 'anim');
|
|
27
|
+
this.world = world;
|
|
28
|
+
this.#x = world.core.exports;
|
|
29
|
+
this.morphs = new Morphs(world);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Adds a skeleton: `parents[i]` is -1 for a root, else an earlier joint (parents first);
|
|
33
|
+
* `rest` is each joint's local rest transform. Returns its id (for `anim.Animator.skeleton`).
|
|
34
|
+
*/
|
|
35
|
+
addSkeleton(parents, rest) {
|
|
36
|
+
const n = parents.length;
|
|
37
|
+
if (rest.length !== n)
|
|
38
|
+
throw new YaliError('ANIM_INVALID', `${n} parents but ${rest.length} rest transforms.`, 'Give one rest transform per joint.');
|
|
39
|
+
const ptr = this.world.scratch(n * 4 + n * 40);
|
|
40
|
+
const heap = this.world.core.heap;
|
|
41
|
+
heap.i32.set(parents, ptr >>> 2);
|
|
42
|
+
const f = heap.f32;
|
|
43
|
+
const at = (ptr + n * 4) >>> 2;
|
|
44
|
+
for (let j = 0; j < n; j++) {
|
|
45
|
+
const r = rest[j];
|
|
46
|
+
f.set([r.t[0], r.t[1], r.t[2], r.r[0], r.r[1], r.r[2], r.r[3], r.s[0], r.s[1], r.s[2]], at + j * 10);
|
|
47
|
+
}
|
|
48
|
+
const id = this.world.check(this.#x.yali_anim_add_skeleton(this.world.handle, ptr, n, ptr + n * 4));
|
|
49
|
+
this.#skeletons[id] = n;
|
|
50
|
+
return id;
|
|
51
|
+
}
|
|
52
|
+
/** Adds a clip over `skeleton`'s joints. Returns its id (for `anim.Animator.clip`). */
|
|
53
|
+
addClip(skeleton, tracks) {
|
|
54
|
+
let words = 1;
|
|
55
|
+
for (const t of tracks) {
|
|
56
|
+
const width = t.path === 'rotation' ? 4 : 3;
|
|
57
|
+
if (t.values.length !== t.times.length * width) {
|
|
58
|
+
throw new YaliError('ANIM_INVALID', `A ${t.path} track of ${t.times.length} keys has ${t.values.length} values.`, `Give ${width} values per key.`);
|
|
59
|
+
}
|
|
60
|
+
words += 4 + t.times.length * (1 + width);
|
|
61
|
+
}
|
|
62
|
+
const ptr = this.world.scratch(words * 4);
|
|
63
|
+
const heap = this.world.core.heap;
|
|
64
|
+
const u = heap.u32;
|
|
65
|
+
const f = heap.f32;
|
|
66
|
+
let o = ptr >>> 2;
|
|
67
|
+
u[o++] = tracks.length;
|
|
68
|
+
for (const t of tracks) {
|
|
69
|
+
u[o++] = t.joint;
|
|
70
|
+
u[o++] = PATHS[t.path];
|
|
71
|
+
u[o++] = t.interpolation === 'STEP' ? 1 : 0;
|
|
72
|
+
u[o++] = t.times.length;
|
|
73
|
+
f.set(t.times, o);
|
|
74
|
+
o += t.times.length;
|
|
75
|
+
f.set(t.values, o);
|
|
76
|
+
o += t.values.length;
|
|
77
|
+
}
|
|
78
|
+
const id = this.world.check(this.#x.yali_anim_add_clip(this.world.handle, skeleton, ptr, words));
|
|
79
|
+
this.#clips++;
|
|
80
|
+
return id;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Adds a skin over `skeleton`: the joint each slot follows and each slot's inverse bind
|
|
84
|
+
* matrix (16 floats, column-major). Returns its id (for `anim.Skin.skin`) and how far its rest
|
|
85
|
+
* palette is from the identity (`restError`: about 0 for a consistent file).
|
|
86
|
+
*/
|
|
87
|
+
addSkin(skeleton, joints, inverseBind) {
|
|
88
|
+
const n = joints.length;
|
|
89
|
+
if (inverseBind.length !== n * 16)
|
|
90
|
+
throw new YaliError('ANIM_INVALID', `${n} joints but ${inverseBind.length / 16} inverse bind matrices.`, 'Give 16 floats per joint.');
|
|
91
|
+
const ptr = this.world.scratch(n * 4 + n * 64 + 4);
|
|
92
|
+
const heap = this.world.core.heap;
|
|
93
|
+
heap.u32.set(joints, ptr >>> 2);
|
|
94
|
+
heap.f32.set(inverseBind, (ptr + n * 4) >>> 2);
|
|
95
|
+
const errAt = ptr + n * 68;
|
|
96
|
+
const id = this.world.check(this.#x.yali_anim_add_skin(this.world.handle, skeleton, n, ptr, ptr + n * 4, errAt));
|
|
97
|
+
this.#skins++;
|
|
98
|
+
return { id, restError: this.world.core.heap.f32[errAt >>> 2] };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Adds a graph (ADR-0089) built with `graph()` for `skeleton`; returns its id (for
|
|
102
|
+
* `anim.Graph.graph`). Every clip it plays must animate that skeleton.
|
|
103
|
+
*/
|
|
104
|
+
addGraph(skeleton, g) {
|
|
105
|
+
const ptr = this.world.scratch(g.words.byteLength);
|
|
106
|
+
this.world.core.heap.u32.set(g.words, ptr >>> 2);
|
|
107
|
+
const id = this.world.check(this.#x.yali_anim_add_graph(this.world.handle, skeleton, ptr, g.words.length));
|
|
108
|
+
this.#graphs++;
|
|
109
|
+
return id;
|
|
110
|
+
}
|
|
111
|
+
/** Adds a per-joint weight mask (0–1 per skeleton joint) for masked blends; returns its id. */
|
|
112
|
+
addMask(skeleton, weights) {
|
|
113
|
+
const ptr = this.world.scratch(weights.byteLength);
|
|
114
|
+
this.world.core.heap.f32.set(weights, ptr >>> 2);
|
|
115
|
+
return this.world.check(this.#x.yali_anim_add_mask(this.world.handle, skeleton, ptr, weights.length));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Joint `joint`'s model matrix of animator `entity` (16 floats, column-major, in the animator's
|
|
119
|
+
* root frame) as of the last update, or null before its first.
|
|
120
|
+
*/
|
|
121
|
+
jointModel(entity, joint) {
|
|
122
|
+
const ptr = this.world.scratch(64);
|
|
123
|
+
const found = this.world.check(this.#x.yali_anim_joint_model(this.world.handle, entity, joint, ptr));
|
|
124
|
+
return found ? this.world.core.heap.f32.slice(ptr >>> 2, (ptr >>> 2) + 16) : null;
|
|
125
|
+
}
|
|
126
|
+
/** A clip's length in seconds (negative for an unknown id). */
|
|
127
|
+
clipDuration(clip) {
|
|
128
|
+
return this.#x.yali_anim_clip_duration(this.world.handle, clip);
|
|
129
|
+
}
|
|
130
|
+
/** One frame (the plugin's Update system calls it): animators advance by `dt`, palettes and sockets follow. */
|
|
131
|
+
update(dt) {
|
|
132
|
+
this.world.check(this.#x.yali_anim_update(this.world.handle, dt));
|
|
133
|
+
}
|
|
134
|
+
/** This frame's palette, as views into the core's memory (valid until the next `update`). Allocation-free. */
|
|
135
|
+
palette() {
|
|
136
|
+
const ptr = this.world.scratch(8);
|
|
137
|
+
this.world.check(this.#x.yali_anim_palette(this.world.handle, ptr));
|
|
138
|
+
const heap = this.world.core.heap;
|
|
139
|
+
const p = this.#frame;
|
|
140
|
+
p.f32 = heap.f32;
|
|
141
|
+
p.at = heap.u32[ptr >>> 2] >>> 2;
|
|
142
|
+
p.rows = heap.u32[(ptr >>> 2) + 1];
|
|
143
|
+
return p;
|
|
144
|
+
}
|
|
145
|
+
#graphQuery = null;
|
|
146
|
+
/**
|
|
147
|
+
* Sets parameter `name` of `entity`'s graph (its `anim.Graph`, built as `g`): a trigger fires
|
|
148
|
+
* with 1, and the graph clears it when a transition takes it.
|
|
149
|
+
*/
|
|
150
|
+
setParam(entity, g, name, value) {
|
|
151
|
+
const i = g.params.indexOf(name);
|
|
152
|
+
if (i < 0)
|
|
153
|
+
throw Object.assign(new YaliError('ANIM_GRAPH', `No parameter named ${JSON.stringify(name)}.`, `Parameters: ${g.params.join(', ')}.`), { path: 'name' });
|
|
154
|
+
this.#graphRow(entity, (params) => (params[i] = value));
|
|
155
|
+
}
|
|
156
|
+
/** `entity`'s graph state: its root state machine's state name ('' without one) and seconds in it. */
|
|
157
|
+
state(entity, g) {
|
|
158
|
+
let out = { state: '', time: 0 };
|
|
159
|
+
this.#graphRow(entity, (_, state, time) => (out = { state: state > 0 ? (g.states[state - 1] ?? '') : '', time }));
|
|
160
|
+
return out;
|
|
161
|
+
}
|
|
162
|
+
#graphRow(entity, fn) {
|
|
163
|
+
const { Graph } = registerAnimation(this.world);
|
|
164
|
+
this.#graphQuery ??= this.world.query({ with: [Graph], columns: [[Graph, 'params', 'write'], [Graph, 'state'], [Graph, 'stateTime']] });
|
|
165
|
+
const q = this.#graphQuery;
|
|
166
|
+
const chunks = q.run();
|
|
167
|
+
for (let c = 0; c < chunks; c++) {
|
|
168
|
+
const k = q.chunk(c);
|
|
169
|
+
for (let r = 0; r < k.length; r++) {
|
|
170
|
+
if (k.entity(r) !== entity)
|
|
171
|
+
continue;
|
|
172
|
+
fn(k.f32(0).subarray(r * 16, r * 16 + 16), k.u32(1)[r], k.f32(2)[r]);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
throw Object.assign(new YaliError('MISSING_COMPONENT', `Entity ${entity} has no anim.Graph.`, 'Insert anim.Graph { graph, params } beside its anim.Animator.'), { path: 'entity' });
|
|
177
|
+
}
|
|
178
|
+
/** Asset counts and the last frame's palette size. */
|
|
179
|
+
stats() {
|
|
180
|
+
return { skeletons: this.#skeletons.filter((n) => n !== undefined).length, clips: this.#clips, skins: this.#skins, graphs: this.#graphs, paletteRows: this.#frame.rows };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=animation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animation.js","sourceRoot":"","sources":["../src/animation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Component, World } from '@yali-engine/core';
|
|
2
|
+
/** `anim.Animator.flags`: the clip loops (else it holds its last frame). */
|
|
3
|
+
export declare const ANIM_LOOP = 1;
|
|
4
|
+
/** `anim.Animator.flags`: time does not advance. */
|
|
5
|
+
export declare const ANIM_PAUSED = 2;
|
|
6
|
+
/** The animation components, declared as the core declares them (one schema: the same ids). */
|
|
7
|
+
export interface AnimationComponents {
|
|
8
|
+
/** Plays a clip on a skeleton: `skeleton`, `clip` (ids from `Animation`), `time`, `speed`, `flags`. */
|
|
9
|
+
readonly Animator: Component;
|
|
10
|
+
/** On a skinned mesh's entity: `skin` (an `Animation.addSkin` id), `animator` (its entity), `palette` (out). */
|
|
11
|
+
readonly Skin: Component;
|
|
12
|
+
/** Its `Transform` follows a joint of `animator` (its parent's animator), in that entity's space. */
|
|
13
|
+
readonly Socket: Component;
|
|
14
|
+
/**
|
|
15
|
+
* Beside `anim.Animator`: a graph drives the pose instead of the animator's clip (ADR-0089).
|
|
16
|
+
* `graph` (an `Animation.addGraph` id), `params` (16 slots, named by the graph), `state` (out:
|
|
17
|
+
* the root state machine's state + 1), `stateTime` (out: seconds in it).
|
|
18
|
+
*/
|
|
19
|
+
readonly Graph: Component;
|
|
20
|
+
/**
|
|
21
|
+
* On a root-level entity tied to joint `joint` of `animator` at `offsetT` / `offsetR` in the
|
|
22
|
+
* joint's frame (model units): `mode` 0 puts its Transform at the joint (a kinematic ragdoll
|
|
23
|
+
* body follows the animation), 1 puts the joint at its Transform (a simulated body drives the
|
|
24
|
+
* pose; the joints below follow). ADR-0091.
|
|
25
|
+
*/
|
|
26
|
+
readonly Bone: Component;
|
|
27
|
+
}
|
|
28
|
+
/** `anim.Bone.mode`: the entity follows its joint. */
|
|
29
|
+
export declare const BONE_FOLLOW = 0;
|
|
30
|
+
/** `anim.Bone.mode`: the joint follows the entity. */
|
|
31
|
+
export declare const BONE_DRIVE = 1;
|
|
32
|
+
/** Registers `anim.Animator`, `anim.Skin` and `anim.Socket` on `world` (idempotent). */
|
|
33
|
+
export declare function registerAnimation(world: World): AnimationComponents;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** `anim.Animator.flags`: the clip loops (else it holds its last frame). */
|
|
2
|
+
export const ANIM_LOOP = 1;
|
|
3
|
+
/** `anim.Animator.flags`: time does not advance. */
|
|
4
|
+
export const ANIM_PAUSED = 2;
|
|
5
|
+
/** `anim.Bone.mode`: the entity follows its joint. */
|
|
6
|
+
export const BONE_FOLLOW = 0;
|
|
7
|
+
/** `anim.Bone.mode`: the joint follows the entity. */
|
|
8
|
+
export const BONE_DRIVE = 1;
|
|
9
|
+
/** Registers `anim.Animator`, `anim.Skin` and `anim.Socket` on `world` (idempotent). */
|
|
10
|
+
export function registerAnimation(world) {
|
|
11
|
+
return {
|
|
12
|
+
Animator: world.registerComponent({ name: 'anim.Animator', fields: { skeleton: 'u32', clip: 'u32', time: 'f32', speed: 'f32', flags: 'u8' } }),
|
|
13
|
+
Skin: world.registerComponent({ name: 'anim.Skin', fields: { skin: 'u32', animator: 'entity', palette: 'u32' } }),
|
|
14
|
+
Socket: world.registerComponent({ name: 'anim.Socket', fields: { animator: 'entity', joint: 'u32' } }),
|
|
15
|
+
Graph: world.registerComponent({ name: 'anim.Graph', fields: { graph: 'u32', params: { scalar: 'f32', lanes: 16 }, state: 'u32', stateTime: 'f32' } }),
|
|
16
|
+
Bone: world.registerComponent({ name: 'anim.Bone', fields: { animator: 'entity', joint: 'u32', mode: 'u8', offsetT: 'vec3<f32>', offsetR: 'quat' } }),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;AAC3B,oDAAoD;AACpD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAyB7B,sDAAsD;AACtD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAC7B,sDAAsD;AACtD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAE5B,wFAAwF;AACxF,MAAM,UAAU,iBAAiB,CAAC,KAAY;IAC5C,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QAC9I,IAAI,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;QACjH,MAAM,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;QACtG,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC;QACtJ,IAAI,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;KACtJ,CAAC;AACJ,CAAC"}
|
package/dist/gltf.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type Component, type Entity, type World } from '@yali-engine/core';
|
|
2
|
+
import type { GltfAsset } from '@yali-engine/gltf';
|
|
3
|
+
import type { Animation } from './animation.ts';
|
|
4
|
+
/** A glTF's animation assets in the core (`addGltfAnimation`). */
|
|
5
|
+
export interface GltfAnimationAssets {
|
|
6
|
+
/** The skeleton: every node of the default scene, depth first (`joints[node]` is its joint). */
|
|
7
|
+
readonly skeleton: number;
|
|
8
|
+
/** `joints[node]` = that node's joint, or -1 when it is not in the default scene. */
|
|
9
|
+
readonly joints: readonly number[];
|
|
10
|
+
/** One clip per glTF animation, in file order: its name, id and length (seconds). */
|
|
11
|
+
readonly clips: readonly {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly id: number;
|
|
14
|
+
readonly duration: number;
|
|
15
|
+
}[];
|
|
16
|
+
/** One skin id per glTF skin (0 when it could not be made). */
|
|
17
|
+
readonly skins: readonly number[];
|
|
18
|
+
/** Per skin, how far its rest palette is from the identity (about 0 for a consistent file). */
|
|
19
|
+
readonly restErrors: readonly number[];
|
|
20
|
+
/** Each joint's parent joint (-1 for a root). */
|
|
21
|
+
readonly parents: readonly number[];
|
|
22
|
+
/** Per skin, the joint of each of its slots. */
|
|
23
|
+
readonly skinJoints: readonly (readonly number[])[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Adds a loaded glTF's skeleton, clips and skins to `animation` (ADR-0088). The skeleton is the
|
|
27
|
+
* whole node tree of the default scene, so a clip may move any node: a skinned mesh's joints, or
|
|
28
|
+
* a rigid mesh's node (which `spawnAnimatedGltf` makes a socket). Morph-weight channels are
|
|
29
|
+
* played by `Animation.morphs`, which `spawnAnimatedGltf` binds.
|
|
30
|
+
*/
|
|
31
|
+
export declare function addGltfAnimation(animation: Animation, asset: GltfAsset, warnings?: string[]): GltfAnimationAssets;
|
|
32
|
+
/** `spawnAnimatedGltf`'s options. */
|
|
33
|
+
export interface SpawnAnimatedOptions {
|
|
34
|
+
readonly at?: {
|
|
35
|
+
t?: readonly number[];
|
|
36
|
+
r?: readonly number[];
|
|
37
|
+
s?: number;
|
|
38
|
+
};
|
|
39
|
+
/** The clip to play: an index into the file's animations or its name (default the first; -1 none). */
|
|
40
|
+
readonly clip?: number | string;
|
|
41
|
+
/** Default 1. */
|
|
42
|
+
readonly speed?: number;
|
|
43
|
+
/** Default true. */
|
|
44
|
+
readonly loop?: boolean;
|
|
45
|
+
readonly warnings?: string[];
|
|
46
|
+
}
|
|
47
|
+
/** What `spawnAnimatedGltf` made. */
|
|
48
|
+
export interface AnimatedGltf {
|
|
49
|
+
/** The root entity: it carries `anim.Animator`; every mesh entity is its child. */
|
|
50
|
+
readonly root: Entity;
|
|
51
|
+
readonly assets: GltfAnimationAssets;
|
|
52
|
+
/** The skinned meshes' entities (`anim.Skin`). */
|
|
53
|
+
readonly skinned: readonly Entity[];
|
|
54
|
+
/** The rigid meshes' entities (`anim.Socket` on their node's joint). */
|
|
55
|
+
readonly sockets: readonly Entity[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Spawns a loaded glTF as one animated model (ADR-0088): a root entity at `at` with an
|
|
59
|
+
* `anim.Animator` playing `clip` over the whole node tree; each skinned primitive as a child at
|
|
60
|
+
* the root's origin with `anim.Skin` (the glTF rule: a skinned mesh's own node transform is
|
|
61
|
+
* ignored); each rigid primitive as a child with `anim.Socket` on its node's joint, so animated
|
|
62
|
+
* nodes move their meshes. Pass `assets` to share one set of skeleton, clips and skins between
|
|
63
|
+
* instances of the same file.
|
|
64
|
+
*
|
|
65
|
+
* Mesh entities carry `Transform` and `GlobalTransform` but no `PreviousTransform`: animation runs
|
|
66
|
+
* at the render rate, so they are not interpolated between fixed steps.
|
|
67
|
+
*/
|
|
68
|
+
export declare function spawnAnimatedGltf(world: World, animation: Animation, asset: GltfAsset, Mesh: Component, options?: SpawnAnimatedOptions, assets?: GltfAnimationAssets): AnimatedGltf;
|
package/dist/gltf.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { registerTransforms } from '@yali-engine/core';
|
|
2
|
+
import { ANIM_LOOP, registerAnimation } from "./components.js";
|
|
3
|
+
/**
|
|
4
|
+
* Adds a loaded glTF's skeleton, clips and skins to `animation` (ADR-0088). The skeleton is the
|
|
5
|
+
* whole node tree of the default scene, so a clip may move any node: a skinned mesh's joints, or
|
|
6
|
+
* a rigid mesh's node (which `spawnAnimatedGltf` makes a socket). Morph-weight channels are
|
|
7
|
+
* played by `Animation.morphs`, which `spawnAnimatedGltf` binds.
|
|
8
|
+
*/
|
|
9
|
+
export function addGltfAnimation(animation, asset, warnings) {
|
|
10
|
+
const s = asset.scene;
|
|
11
|
+
const joints = new Array(s.nodes.length).fill(-1);
|
|
12
|
+
const parents = [];
|
|
13
|
+
const rest = [];
|
|
14
|
+
const visit = (node, parent) => {
|
|
15
|
+
if (joints[node] >= 0)
|
|
16
|
+
return; // a node reached twice (an invalid file): first wins
|
|
17
|
+
const j = parents.length;
|
|
18
|
+
joints[node] = j;
|
|
19
|
+
parents.push(parent);
|
|
20
|
+
const n = s.nodes[node];
|
|
21
|
+
rest.push({ t: [...n.t], r: [...n.r], s: [...n.s] });
|
|
22
|
+
for (const c of n.children)
|
|
23
|
+
visit(c, j);
|
|
24
|
+
};
|
|
25
|
+
for (const r of s.roots)
|
|
26
|
+
visit(r, -1);
|
|
27
|
+
const skeleton = animation.addSkeleton(parents, rest);
|
|
28
|
+
const clips = s.animations.map((a) => {
|
|
29
|
+
const tracks = [];
|
|
30
|
+
for (const c of a.channels) {
|
|
31
|
+
if (c.path === 'weights')
|
|
32
|
+
continue; // morph weights: `Morphs`, bound by spawnAnimatedGltf
|
|
33
|
+
const joint = joints[c.node] ?? -1;
|
|
34
|
+
if (joint < 0)
|
|
35
|
+
continue;
|
|
36
|
+
tracks.push({ joint, path: c.path, interpolation: c.interpolation, times: c.times, values: c.values });
|
|
37
|
+
}
|
|
38
|
+
const id = animation.addClip(skeleton, tracks);
|
|
39
|
+
return { name: a.name, id, duration: animation.clipDuration(id) };
|
|
40
|
+
});
|
|
41
|
+
const restErrors = [];
|
|
42
|
+
const skinJoints = [];
|
|
43
|
+
const skins = s.skins.map((k) => {
|
|
44
|
+
const slots = k.joints.map((n) => joints[n] ?? -1);
|
|
45
|
+
skinJoints.push(slots.filter((j) => j >= 0));
|
|
46
|
+
if (slots.some((j) => j < 0)) {
|
|
47
|
+
warnings?.push(`skin ${k.name}: a joint is not in the default scene; its meshes draw at their bind pose`);
|
|
48
|
+
restErrors.push(Number.NaN);
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
const r = animation.addSkin(skeleton, slots, k.inverseBindMatrices);
|
|
52
|
+
restErrors.push(r.restError);
|
|
53
|
+
return r.id;
|
|
54
|
+
});
|
|
55
|
+
return { skeleton, joints, clips, skins, restErrors, parents, skinJoints };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Spawns a loaded glTF as one animated model (ADR-0088): a root entity at `at` with an
|
|
59
|
+
* `anim.Animator` playing `clip` over the whole node tree; each skinned primitive as a child at
|
|
60
|
+
* the root's origin with `anim.Skin` (the glTF rule: a skinned mesh's own node transform is
|
|
61
|
+
* ignored); each rigid primitive as a child with `anim.Socket` on its node's joint, so animated
|
|
62
|
+
* nodes move their meshes. Pass `assets` to share one set of skeleton, clips and skins between
|
|
63
|
+
* instances of the same file.
|
|
64
|
+
*
|
|
65
|
+
* Mesh entities carry `Transform` and `GlobalTransform` but no `PreviousTransform`: animation runs
|
|
66
|
+
* at the render rate, so they are not interpolated between fixed steps.
|
|
67
|
+
*/
|
|
68
|
+
export function spawnAnimatedGltf(world, animation, asset, Mesh, options = {}, assets) {
|
|
69
|
+
const { Transform, GlobalTransform, bundle } = registerTransforms(world);
|
|
70
|
+
const { Animator, Skin, Socket } = registerAnimation(world);
|
|
71
|
+
const a = assets ?? addGltfAnimation(animation, asset, options.warnings);
|
|
72
|
+
const s = asset.scene;
|
|
73
|
+
const pick = options.clip ?? 0;
|
|
74
|
+
const index = typeof pick === 'string' ? a.clips.findIndex((c) => c.name === pick) : pick;
|
|
75
|
+
if (typeof pick === 'string' && index < 0)
|
|
76
|
+
options.warnings?.push(`no animation named ${pick}; none plays`);
|
|
77
|
+
const clip = index >= 0 && index < a.clips.length ? a.clips[index].id : 0;
|
|
78
|
+
const root = world.spawn([...bundle, Animator]);
|
|
79
|
+
world.insert(root, Transform, { t: options.at?.t ?? [0, 0, 0], r: options.at?.r ?? [0, 0, 0, 1], s: options.at?.s ?? 1 });
|
|
80
|
+
world.insert(root, Animator, { skeleton: a.skeleton, clip, time: 0, speed: options.speed ?? 1, flags: options.loop === false ? 0 : ANIM_LOOP });
|
|
81
|
+
const skinned = [];
|
|
82
|
+
const sockets = [];
|
|
83
|
+
const IDENTITY = { t: [0, 0, 0], r: [0, 0, 0, 1], s: 1 };
|
|
84
|
+
for (let node = 0; node < s.nodes.length; node++) {
|
|
85
|
+
const n = s.nodes[node];
|
|
86
|
+
const joint = a.joints[node];
|
|
87
|
+
if (n.mesh < 0 || joint < 0)
|
|
88
|
+
continue;
|
|
89
|
+
const ids = asset.meshes[n.mesh];
|
|
90
|
+
for (let p = 0; p < ids.length; p++) {
|
|
91
|
+
const m = asset.materialOf[n.mesh][p];
|
|
92
|
+
const material = m >= 0 && asset.materialIds.length > 0 ? asset.materialIds[m] : 0;
|
|
93
|
+
const color = material > 0 ? WHITE : m >= 0 ? rgba8(s.materials[m].baseColor) : DEFAULT_COLOR;
|
|
94
|
+
const skin = n.skin >= 0 && asset.skinned[n.mesh][p] ? a.skins[n.skin] : 0;
|
|
95
|
+
// Morph targets: one weight state per mesh, driven by the first instance spawned.
|
|
96
|
+
const morph = asset.morphs[n.mesh]?.[p];
|
|
97
|
+
if (morph && !animation.morphs.has(ids[p])) {
|
|
98
|
+
const tracks = new Map();
|
|
99
|
+
s.animations.forEach((an, ai) => {
|
|
100
|
+
const ch = an.channels.find((c) => c.node === node && c.path === 'weights');
|
|
101
|
+
if (ch && a.clips[ai])
|
|
102
|
+
tracks.set(a.clips[ai].id, { times: ch.times, values: ch.values, interpolation: ch.interpolation });
|
|
103
|
+
});
|
|
104
|
+
animation.morphs.add({ animator: root, mesh: ids[p], base: morph.base, targets: morph.targets, defaults: s.meshes[n.mesh].weights, tracks });
|
|
105
|
+
}
|
|
106
|
+
if (skin > 0) {
|
|
107
|
+
const e = world.spawn([Transform, GlobalTransform, Mesh, Skin]);
|
|
108
|
+
world.insert(e, Transform, IDENTITY);
|
|
109
|
+
world.setParent(e, root);
|
|
110
|
+
world.insert(e, Mesh, { mesh: ids[p], material, color });
|
|
111
|
+
world.insert(e, Skin, { skin, animator: root, palette: 0 });
|
|
112
|
+
skinned.push(e);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Placed by its socket from the first animation update on.
|
|
116
|
+
const e = world.spawn([Transform, GlobalTransform, Mesh, Socket]);
|
|
117
|
+
world.insert(e, Transform, IDENTITY);
|
|
118
|
+
world.setParent(e, root);
|
|
119
|
+
world.insert(e, Mesh, { mesh: ids[p], material, color });
|
|
120
|
+
world.insert(e, Socket, { animator: root, joint });
|
|
121
|
+
sockets.push(e);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { root, assets: a, skinned, sockets };
|
|
126
|
+
}
|
|
127
|
+
/** RGBA8 of a linear colour (as `@yali-engine/render`'s `rgba8`, which this package does not import). */
|
|
128
|
+
function rgba8(c) {
|
|
129
|
+
const b = (x) => Math.round(Math.min(1, Math.max(0, x)) * 255);
|
|
130
|
+
return (b(c[0]) | (b(c[1]) << 8) | (b(c[2]) << 16) | (b(c[3] ?? 1) << 24)) >>> 0;
|
|
131
|
+
}
|
|
132
|
+
const DEFAULT_COLOR = rgba8([0.8, 0.8, 0.8, 1]);
|
|
133
|
+
const WHITE = rgba8([1, 1, 1, 1]);
|
|
134
|
+
//# sourceMappingURL=gltf.js.map
|
package/dist/gltf.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gltf.js","sourceRoot":"","sources":["../src/gltf.ts"],"names":[],"mappings":"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"}
|