@yali-engine/gltf 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/gltf.d.ts ADDED
@@ -0,0 +1,166 @@
1
+ import { type AssetLoader, type Component, type DecodePool, type Entity, type World, type YaliPlugin } from '@yali-engine/core';
2
+ import type { DecodedTexture } from '@yali-engine/ktx2';
3
+ import { type MaterialStore, type MeshStore, type TextureStore } from '@yali-engine/render';
4
+ import { type LodOptions } from './lods.ts';
5
+ import { type GltfClusterPages, type GltfClusters, type GltfLod, type GltfMorphTarget, type GltfScene } from './parse.ts';
6
+ import { type GltfTextureOptions, type MaterialTextures } from './textures.ts';
7
+ /** A primitive as the decode worker hands it over: interleaved, ready for the pool. */
8
+ export interface DecodedPrimitive {
9
+ readonly vertices: Float32Array;
10
+ readonly indices: Uint32Array;
11
+ readonly material: number;
12
+ /** Levels of detail the file carried (`MSFT_lod`), finest first. */
13
+ readonly lods: readonly GltfLod[];
14
+ /** A skinned primitive's skin stream (`packSkin`, ADR-0088), or null. */
15
+ readonly skin: Uint16Array | null;
16
+ /** Morph targets (ADR-0088): position and normal deltas per target. Empty without any. */
17
+ readonly targets: readonly GltfMorphTarget[];
18
+ /** Clusters the file carried (`YALI_clusters`, ADR-0121), or null. */
19
+ readonly clusters: GltfClusters | null;
20
+ /** Streaming cluster pages (`YALI_cluster_pages`, ADR-0134) and their pages file's absolute URL, or null. */
21
+ readonly pages: (GltfClusterPages & {
22
+ readonly url: string;
23
+ }) | null;
24
+ }
25
+ /** What the `gltf` decoder returns: the scene without its attribute arrays, plus the primitives interleaved. */
26
+ export interface DecodedGltf {
27
+ readonly scene: Omit<GltfScene, 'meshes'> & {
28
+ readonly meshes: readonly {
29
+ name: string;
30
+ primitives: number;
31
+ weights: readonly number[];
32
+ }[];
33
+ };
34
+ readonly primitives: readonly (readonly DecodedPrimitive[])[];
35
+ /**
36
+ * Positions and indices of the primitives that need generated LODs, packed for the
37
+ * `gltf-lods` decoder (made on the worker, so the main thread forwards it without a
38
+ * copy), or null when none do or the caller did not ask (`lodSource`).
39
+ */
40
+ readonly lodSource: Uint8Array | null;
41
+ /** The materials' textures, decoded on the worker (`textures` option), each once. */
42
+ readonly textures: readonly DecodedTexture[];
43
+ /** Per material, its textures as indices into `textures` (empty without the `textures` option). */
44
+ readonly materialTextures: readonly MaterialTextures[];
45
+ }
46
+ /** What `decodeGltf` takes besides the bytes. */
47
+ export interface DecodeGltfOptions {
48
+ readonly baseUrl?: string;
49
+ /** Pack the primitives without LODs and with at least `minTriangles` triangles for `decodeGltfLods`. */
50
+ readonly lodSource?: {
51
+ readonly minTriangles: number;
52
+ };
53
+ /** Decode the materials' textures for a texture store of this size class and family (ADR-0066). */
54
+ readonly textures?: GltfTextureOptions;
55
+ }
56
+ /** A loaded glTF: the scene's structure and, per mesh, the geometry-pool id of each primitive. */
57
+ export interface GltfAsset {
58
+ readonly scene: DecodedGltf['scene'];
59
+ /** `meshes[m][p]` = the `render.Mesh` id of primitive p of mesh m. */
60
+ readonly meshes: readonly (readonly number[])[];
61
+ /** `materialOf[m][p]` = the material index of that primitive (-1 = default). */
62
+ readonly materialOf: readonly (readonly number[])[];
63
+ /** `skinned[m][p]`: that primitive is skinned (in the skinned pool; `@yali-engine/animation` drives it). */
64
+ readonly skinned: readonly (readonly boolean[])[];
65
+ /**
66
+ * `morphs[m][p]`: that primitive's morph targets and its vertices as loaded (interleaved, the
67
+ * base the targets add to), or null; `@yali-engine/animation` blends them.
68
+ */
69
+ readonly morphs: readonly (readonly ({
70
+ readonly base: Float32Array;
71
+ readonly targets: readonly GltfMorphTarget[];
72
+ } | null)[])[];
73
+ /** `materialIds[i]` = the `MaterialStore` id of glTF material i (empty without a material store). */
74
+ readonly materialIds: readonly number[];
75
+ /**
76
+ * Settles when generated LODs (for primitives the file gave none) have been added to the
77
+ * geometry pool, with how many primitives got some; 0 at once when nothing needed them.
78
+ */
79
+ readonly lodsReady: Promise<number>;
80
+ }
81
+ /**
82
+ * The `gltf` decoder, for `serveDecoders` (ADR-0047): parses, then interleaves each
83
+ * primitive for the geometry pool, so the main thread only stores references.
84
+ *
85
+ * @example
86
+ * // decode.worker.ts
87
+ * import { serveDecoders } from '@yali-engine/core/decode-worker';
88
+ * import { decodeGltf, decodeGltfLods } from '@yali-engine/gltf';
89
+ * serveDecoders({ gltf: decodeGltf, 'gltf-lods': decodeGltfLods });
90
+ */
91
+ export declare function decodeGltf(bytes: Uint8Array, options?: unknown): Promise<DecodedGltf>;
92
+ /** What the `gltf-lods` decoder returns: per packed primitive, its mesh and primitive index and its levels. */
93
+ export interface DecodedLods {
94
+ readonly primitives: readonly {
95
+ readonly mesh: number;
96
+ readonly primitive: number;
97
+ readonly lods: readonly GltfLod[];
98
+ }[];
99
+ }
100
+ /**
101
+ * The `gltf-lods` decoder (M2 increment 2b): simplifies the primitives `decodeGltf` packed
102
+ * (`lodSource`) with meshoptimizer's simplifier (`buildLods`), on a decode worker, after
103
+ * LOD 0 is already drawing.
104
+ */
105
+ export declare function decodeGltfLods(bytes: Uint8Array, options?: unknown): Promise<DecodedLods>;
106
+ /** `gltfLoader` options. */
107
+ export interface GltfLoaderOptions {
108
+ readonly meshes: () => MeshStore;
109
+ readonly materials?: () => MaterialStore;
110
+ /** The render plugin's texture store: with it (and `materials`), the materials' textures load too (ADR-0066). */
111
+ readonly textures?: () => TextureStore;
112
+ /** Decode (and generate LODs) on these workers; without one, decode inline and generate none. */
113
+ readonly pool?: DecodePool;
114
+ readonly baseUrl?: string;
115
+ /**
116
+ * Vertices a streamed mesh reserves for its cluster pages past its roots (ADR-0134; default 1,048,576:
117
+ * 32 MB of the vertex pool). Fewer pages than that fit reserve only what they need.
118
+ */
119
+ readonly streamVertices?: number;
120
+ /**
121
+ * Generate LODs on the decode pool for primitives the file gave none (decision 6 of
122
+ * M2.md), after LOD 0 is drawing; `false` turns it off. Needs the worker to serve
123
+ * `gltf-lods` (`decodeGltfLods`). Default: on with a pool, 256 triangles and up.
124
+ */
125
+ readonly lods?: (LodOptions & {
126
+ readonly minTriangles?: number;
127
+ }) | false;
128
+ }
129
+ /**
130
+ * The glTF asset loader (`.glb`, `.gltf`): decodes on the decode pool when given one
131
+ * (else on the calling thread), then adds the primitives to the render plugin's geometry
132
+ * pool inside the upload budget. Levels of detail from the file (`MSFT_lod`) go in with
133
+ * them; primitives without any get generated ones later (`lods`).
134
+ */
135
+ export declare function gltfLoader(options: GltfLoaderOptions): AssetLoader<GltfAsset | null, DecodedGltf>;
136
+ /**
137
+ * Spawns a loaded glTF's default scene as entities (ADR-0047): one entity per node with
138
+ * `Transform` (and the interpolation and global components) and `ChildOf` its parent;
139
+ * one per primitive with `render.Mesh`: its geometry id, and its material (the
140
+ * `MaterialStore` id when the loader had a material store, else the base colour as the
141
+ * instance colour).
142
+ * Everything hangs under one new root entity placed at `at`. Returns that root.
143
+ *
144
+ * A node's non-uniform scale becomes the uniform mean of its three axes (Yali's transforms
145
+ * are uniform-scale, ADR-0033), and is reported once in `warnings`.
146
+ */
147
+ export declare function spawnGltf(world: World, asset: GltfAsset, Mesh: Component, options?: {
148
+ at?: {
149
+ t?: readonly number[];
150
+ r?: readonly number[];
151
+ s?: number;
152
+ };
153
+ warnings?: string[];
154
+ }): Entity;
155
+ /**
156
+ * glTF as a plugin: registers `gltfLoader` with the asset server, decoding on `pool` when
157
+ * one is given. Depends on `@yali-engine/render` (the geometry pool) and `@yali-engine/assets`.
158
+ *
159
+ * @example
160
+ * plugins: [renderPlugin({ canvas }), assetsPlugin({ loaders: [] }), transformsPlugin(), gltfPlugin({ pool })]
161
+ * // then: const h = assets.load<GltfAsset | null>('temple.glb'); ... spawnGltf(world, h.get()!, render.Mesh!)
162
+ */
163
+ export declare function gltfPlugin(options?: {
164
+ pool?: DecodePool;
165
+ baseUrl?: string;
166
+ }): YaliPlugin;
package/dist/gltf.js ADDED
@@ -0,0 +1,296 @@
1
+ import { registerTransforms } from '@yali-engine/core';
2
+ import { MESH_VERTEX_FLOATS, packSkin, rgba8, SKIN_STREAM_BYTES } from '@yali-engine/render';
3
+ import { buildLods } from "./lods.js";
4
+ import { parseGltf } from "./parse.js";
5
+ import { decodeGltfTextures } from "./textures.js";
6
+ /**
7
+ * The `gltf` decoder, for `serveDecoders` (ADR-0047): parses, then interleaves each
8
+ * primitive for the geometry pool, so the main thread only stores references.
9
+ *
10
+ * @example
11
+ * // decode.worker.ts
12
+ * import { serveDecoders } from '@yali-engine/core/decode-worker';
13
+ * import { decodeGltf, decodeGltfLods } from '@yali-engine/gltf';
14
+ * serveDecoders({ gltf: decodeGltf, 'gltf-lods': decodeGltfLods });
15
+ */
16
+ export async function decodeGltf(bytes, options) {
17
+ const o = (options ?? {});
18
+ const scene = await parseGltf(bytes, o);
19
+ const primitives = scene.meshes.map((m) => m.primitives.map((p) => {
20
+ const n = p.positions.length / 3;
21
+ const v = new Float32Array(n * MESH_VERTEX_FLOATS);
22
+ for (let i = 0; i < n; i++) {
23
+ const o = i * MESH_VERTEX_FLOATS;
24
+ v[o] = p.positions[i * 3];
25
+ v[o + 1] = p.positions[i * 3 + 1];
26
+ v[o + 2] = p.positions[i * 3 + 2];
27
+ v[o + 3] = p.normals[i * 3];
28
+ v[o + 4] = p.normals[i * 3 + 1];
29
+ v[o + 5] = p.normals[i * 3 + 2];
30
+ if (p.uvs) {
31
+ v[o + 6] = p.uvs[i * 2];
32
+ v[o + 7] = p.uvs[i * 2 + 1];
33
+ }
34
+ }
35
+ return { vertices: v, indices: p.indices, material: p.material, lods: p.lods, skin: p.skin ? packSkin(p.skin.joints, p.skin.weights, n) : null, targets: p.targets, clusters: p.clusters, pages: p.pages ? { ...p.pages, url: new URL(p.pages.uri, o.baseUrl ?? 'file:///').href } : null };
36
+ }));
37
+ const lodSource = o.lodSource ? packLodSource(scene, o.lodSource.minTriangles) : null;
38
+ const warnings = [...scene.warnings];
39
+ const tex = o.textures && scene.images.length > 0 ? await decodeGltfTextures(scene, o.textures, warnings) : { textures: [], materials: [] };
40
+ return {
41
+ // Image bytes stay on the worker: the textures carry what the main thread needs.
42
+ scene: { ...scene, warnings, images: scene.images.map((im) => ({ mimeType: im.mimeType, bytes: null, url: im.url })), meshes: scene.meshes.map((m) => ({ name: m.name, primitives: m.primitives.length, weights: m.weights })) },
43
+ primitives,
44
+ lodSource,
45
+ textures: tex.textures,
46
+ materialTextures: tex.materials,
47
+ };
48
+ }
49
+ /**
50
+ * Packs `[count, then per primitive: mesh, primitive, vertex count, index count,
51
+ * positions (3 floats each), normals (3 floats each), indices]` (u32 / f32 words) for the
52
+ * primitives that need generated LODs.
53
+ */
54
+ function packLodSource(scene, minTriangles) {
55
+ const picks = scene.meshes.flatMap((m, mi) => m.primitives.map((p, pi) => ({ p, mi, pi }))).filter(({ p }) => p.lods.length === 0 && p.indices.length / 3 >= minTriangles);
56
+ if (picks.length === 0)
57
+ return null;
58
+ const words = 1 + picks.reduce((n, { p }) => n + 4 + p.positions.length * 2 + p.indices.length, 0);
59
+ const u32 = new Uint32Array(words);
60
+ const f32 = new Float32Array(u32.buffer);
61
+ u32[0] = picks.length;
62
+ let o = 1;
63
+ for (const { p, mi, pi } of picks) {
64
+ u32.set([mi, pi, p.positions.length / 3, p.indices.length], o);
65
+ o += 4;
66
+ f32.set(p.positions, o);
67
+ o += p.positions.length;
68
+ f32.set(p.normals, o);
69
+ o += p.positions.length;
70
+ u32.set(p.indices, o);
71
+ o += p.indices.length;
72
+ }
73
+ return new Uint8Array(u32.buffer);
74
+ }
75
+ /**
76
+ * The `gltf-lods` decoder (M2 increment 2b): simplifies the primitives `decodeGltf` packed
77
+ * (`lodSource`) with meshoptimizer's simplifier (`buildLods`), on a decode worker, after
78
+ * LOD 0 is already drawing.
79
+ */
80
+ export async function decodeGltfLods(bytes, options) {
81
+ const u32 = new Uint32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4);
82
+ const f32 = new Float32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4);
83
+ const out = [];
84
+ let o = 1;
85
+ for (let k = 0; k < u32[0]; k++) {
86
+ const [mesh, primitive, vertices, indices] = [u32[o], u32[o + 1], u32[o + 2], u32[o + 3]];
87
+ o += 4;
88
+ const positions = f32.subarray(o, o + vertices * 3);
89
+ o += vertices * 3;
90
+ const normals = f32.subarray(o, o + vertices * 3);
91
+ o += vertices * 3;
92
+ const index = u32.slice(o, o + indices);
93
+ o += indices;
94
+ out.push({ mesh, primitive, lods: await buildLods(positions, 3, index, { ...(options ?? {}), normals: { data: normals, stride: 3 } }) });
95
+ }
96
+ return { primitives: out };
97
+ }
98
+ /**
99
+ * The glTF asset loader (`.glb`, `.gltf`): decodes on the decode pool when given one
100
+ * (else on the calling thread), then adds the primitives to the render plugin's geometry
101
+ * pool inside the upload budget. Levels of detail from the file (`MSFT_lod`) go in with
102
+ * them; primitives without any get generated ones later (`lods`).
103
+ */
104
+ export function gltfLoader(options) {
105
+ // A streamed primitive (ADR-0134) reserves page slots after its root vertices: as many as it has pages, within the budget.
106
+ const streamed = (p, own) => {
107
+ const pages = p.pages.length / 5 - p.roots;
108
+ const slots = p.slotVertices > 0 ? Math.min(pages, Math.floor((options.streamVertices ?? 1 << 20) / p.slotVertices)) : 0;
109
+ return { pages: { words: p.words, pages: p.pages, roots: p.roots, localIds: p.localIds, triangleBytes: p.triangleBytes, corners: p.corners, slotVertices: p.slotVertices, rootData: p.rootData, url: p.url, base: p.base }, vertexCapacity: own + slots * p.slotVertices };
110
+ };
111
+ const lodOptions = options.pool && options.lods !== false ? (options.lods ?? {}) : null;
112
+ // The textures each loaded model added, to free their layers when it is evicted.
113
+ const owned = new Map();
114
+ return {
115
+ type: 'mesh',
116
+ extensions: ['.glb', '.gltf'],
117
+ decode: (bytes, ctx) => {
118
+ const store = options.textures?.();
119
+ const args = {
120
+ baseUrl: new URL(ctx.path, options.baseUrl ?? 'file:///').href,
121
+ ...(lodOptions ? { lodSource: { minTriangles: lodOptions.minTriangles ?? 256 } } : {}),
122
+ ...(store && options.materials ? { textures: { maxSize: store.size, family: store.family } } : {}),
123
+ };
124
+ return options.pool ? options.pool.decode('gltf', bytes, { signal: ctx.signal, args }) : decodeGltf(bytes, args);
125
+ },
126
+ upload: (d) => {
127
+ const store = options.meshes();
128
+ const materials = options.materials?.();
129
+ // A primitive draws as its material blends and sides (ADR-0081).
130
+ const stateOf = (material) => {
131
+ const m = d.scene.materials[material];
132
+ // A transmissive material is blended: the light through it is the blend's (ADR-0093).
133
+ return m ? { alpha: m.alphaMode === 'MASK' ? 'mask' : m.alphaMode === 'BLEND' || m.transmission > 0 ? 'blend' : 'opaque', doubleSided: m.doubleSided } : undefined;
134
+ };
135
+ const meshes = d.primitives.map((ps) => ps.map((p) => store.add({ vertices: p.vertices, indices: p.indices, lods: p.lods, state: stateOf(p.material), ...(p.skin ? { skin: p.skin } : {}), ...(p.clusters ? { clusters: p.clusters } : {}), ...(p.pages ? streamed(p.pages, p.vertices.length / MESH_VERTEX_FLOATS) : {}) })));
136
+ let lodsReady = Promise.resolve(0);
137
+ if (d.lodSource && options.pool && lodOptions) {
138
+ lodsReady = options.pool.decode('gltf-lods', d.lodSource, { args: lodOptions }).then((r) => {
139
+ let n = 0;
140
+ for (const p of r.primitives) {
141
+ const id = meshes[p.mesh]?.[p.primitive];
142
+ if (id === undefined || p.lods.length === 0)
143
+ continue;
144
+ store.addLods(id, p.lods);
145
+ n++;
146
+ }
147
+ return n;
148
+ });
149
+ }
150
+ const textureStore = options.textures?.();
151
+ const refs = textureStore ? d.textures.map((t) => textureStore.add(t)) : [];
152
+ const map = (i) => (i !== undefined && i >= 0 ? refs[i] : undefined);
153
+ const materialIds = materials
154
+ ? d.scene.materials.map((m, i) => {
155
+ const t = d.materialTextures[i];
156
+ return materials.add({
157
+ baseColor: m.baseColor,
158
+ metalness: m.metallic,
159
+ roughness: m.roughness,
160
+ emissive: m.emissive,
161
+ normalScale: m.normalScale,
162
+ // Without an occlusion texture the ORM's red channel is not occlusion.
163
+ occlusionStrength: t?.occlusion ? m.occlusionStrength : 0,
164
+ alphaCutoff: m.alphaCutoff,
165
+ baseColorMap: map(t?.baseColor),
166
+ normalMap: map(t?.normal),
167
+ ormMap: map(t?.orm),
168
+ emissiveMap: map(t?.emissive),
169
+ clearcoat: m.clearcoat,
170
+ clearcoatRoughness: m.clearcoatRoughness,
171
+ clearcoatMap: map(t?.clearcoat),
172
+ clearcoatRoughnessMap: map(t?.clearcoatRoughness),
173
+ transmission: m.transmission,
174
+ transmissionMap: map(t?.transmission),
175
+ sheenColor: m.sheenColor,
176
+ sheenRoughness: m.sheenRoughness,
177
+ sheenColorMap: map(t?.sheenColor),
178
+ ior: m.ior,
179
+ thickness: m.thickness,
180
+ thicknessMap: map(t?.thickness),
181
+ dispersion: m.dispersion,
182
+ attenuationColor: m.attenuationColor,
183
+ attenuationDistance: m.attenuationDistance,
184
+ });
185
+ })
186
+ : [];
187
+ if (textureStore)
188
+ owned.set(meshes, { store: textureStore, refs });
189
+ return {
190
+ scene: d.scene,
191
+ meshes,
192
+ materialOf: d.primitives.map((ps) => ps.map((p) => p.material)),
193
+ skinned: d.primitives.map((ps) => ps.map((p) => p.skin !== null)),
194
+ // A copy: the pool's block is this array, and blending rewrites it.
195
+ morphs: d.primitives.map((ps) => ps.map((p) => (p.targets.length > 0 ? { base: p.vertices.slice(), targets: p.targets } : null))),
196
+ materialIds,
197
+ lodsReady,
198
+ };
199
+ },
200
+ byteSize: (a) => (a ? a.scene.stats.vertices * MESH_VERTEX_FLOATS * 4 + a.scene.stats.triangles * 12 + skinBytes(a) + (owned.get(a.meshes)?.refs.reduce((n, r) => n + r.bytes, 0) ?? 0) : 0),
201
+ fallback: () => null,
202
+ dispose: (a) => {
203
+ const o = a && owned.get(a.meshes);
204
+ if (!o)
205
+ return;
206
+ for (const r of o.refs)
207
+ o.store.remove(r);
208
+ owned.delete(a.meshes);
209
+ },
210
+ };
211
+ }
212
+ /** Bytes of a loaded glTF's skin streams (the skinned primitives' vertices × 16). */
213
+ function skinBytes(a) {
214
+ let n = 0;
215
+ for (const s of a.scene.skins)
216
+ n += s.inverseBindMatrices.byteLength;
217
+ return a.skinned.some((ps) => ps.some(Boolean)) ? n + a.scene.stats.vertices * SKIN_STREAM_BYTES : n;
218
+ }
219
+ const DEFAULT_COLOR = rgba8(0.8, 0.8, 0.8);
220
+ const WHITE = rgba8(1, 1, 1);
221
+ /**
222
+ * Spawns a loaded glTF's default scene as entities (ADR-0047): one entity per node with
223
+ * `Transform` (and the interpolation and global components) and `ChildOf` its parent;
224
+ * one per primitive with `render.Mesh`: its geometry id, and its material (the
225
+ * `MaterialStore` id when the loader had a material store, else the base colour as the
226
+ * instance colour).
227
+ * Everything hangs under one new root entity placed at `at`. Returns that root.
228
+ *
229
+ * A node's non-uniform scale becomes the uniform mean of its three axes (Yali's transforms
230
+ * are uniform-scale, ADR-0033), and is reported once in `warnings`.
231
+ */
232
+ export function spawnGltf(world, asset, Mesh, options = {}) {
233
+ const { Transform, bundle } = registerTransforms(world);
234
+ const s = asset.scene;
235
+ const root = world.spawn(bundle);
236
+ world.insert(root, Transform, { t: options.at?.t ?? [0, 0, 0], r: options.at?.r ?? [0, 0, 0, 1], s: options.at?.s ?? 1 });
237
+ let warned = false;
238
+ const visit = (index, parent) => {
239
+ const n = s.nodes[index];
240
+ const e = world.spawn(bundle);
241
+ let scale = n.s[0];
242
+ if (n.s[0] !== n.s[1] || n.s[1] !== n.s[2]) {
243
+ scale = (n.s[0] + n.s[1] + n.s[2]) / 3;
244
+ if (!warned) {
245
+ options.warnings?.push(`node ${n.name}: non-uniform scale ${n.s.join(',')} drawn as ${scale.toFixed(3)} (uniform-scale transforms, ADR-0033)`);
246
+ warned = true;
247
+ }
248
+ }
249
+ world.insert(e, Transform, { t: n.t, r: n.r, s: scale });
250
+ world.setParent(e, parent);
251
+ if (n.mesh >= 0) {
252
+ const ids = asset.meshes[n.mesh];
253
+ for (let p = 0; p < ids.length; p++) {
254
+ const m = asset.materialOf[n.mesh][p];
255
+ const material = m >= 0 && asset.materialIds.length > 0 ? asset.materialIds[m] : 0;
256
+ const color = material > 0 ? WHITE : m >= 0 ? rgba8(...s.materials[m].baseColor) : DEFAULT_COLOR;
257
+ // One entity per primitive, at the node's transform.
258
+ const pe = ids.length === 1 ? e : world.spawn(bundle);
259
+ if (pe !== e) {
260
+ world.insert(pe, Transform, { t: [0, 0, 0], r: [0, 0, 0, 1], s: 1 });
261
+ world.setParent(pe, e);
262
+ }
263
+ world.insert(pe, Mesh, { mesh: ids[p], material, color });
264
+ }
265
+ }
266
+ for (const c of n.children)
267
+ visit(c, e);
268
+ };
269
+ for (const r of s.roots)
270
+ visit(r, root);
271
+ return root;
272
+ }
273
+ /**
274
+ * glTF as a plugin: registers `gltfLoader` with the asset server, decoding on `pool` when
275
+ * one is given. Depends on `@yali-engine/render` (the geometry pool) and `@yali-engine/assets`.
276
+ *
277
+ * @example
278
+ * plugins: [renderPlugin({ canvas }), assetsPlugin({ loaders: [] }), transformsPlugin(), gltfPlugin({ pool })]
279
+ * // then: const h = assets.load<GltfAsset | null>('temple.glb'); ... spawnGltf(world, h.get()!, render.Mesh!)
280
+ */
281
+ export function gltfPlugin(options = {}) {
282
+ return {
283
+ name: '@yali-engine/gltf',
284
+ version: '0.4.0',
285
+ dependencies: [
286
+ { name: '@yali-engine/render', range: '^0.4.0' },
287
+ { name: '@yali-engine/assets', range: '^0.4.0' },
288
+ ],
289
+ build(b) {
290
+ const render = b.app.resource('render');
291
+ const assets = b.app.resource('assets');
292
+ assets.register(gltfLoader({ meshes: () => render.meshes, materials: () => render.materials, textures: () => render.textures, pool: options.pool, baseUrl: options.baseUrl }));
293
+ },
294
+ };
295
+ }
296
+ //# sourceMappingURL=gltf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gltf.js","sourceRoot":"","sources":["../src/gltf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@yali-engine/gltf`: glTF 2.0 for Yali (M2 increment 1, ADR-0047). Parse in a decode worker,
3
+ * upload into the render plugin's geometry pool, spawn the node hierarchy as entities.
4
+ *
5
+ * @example
6
+ * const h = app.resource<AssetServer>('assets').load<GltfAsset | null>('temple.glb');
7
+ * await h.ready;
8
+ * spawnGltf(app.world, h.get()!, app.resource<RenderContext>('render').Mesh!, { at: { t: [0, 0, 0] } });
9
+ */
10
+ export { type DecodedGltf, type DecodedLods, type DecodedPrimitive, type DecodeGltfOptions, decodeGltf, decodeGltfLods, type GltfAsset, gltfLoader, type GltfLoaderOptions, gltfPlugin, spawnGltf, } from './gltf.ts';
11
+ export { buildLods, type LodOptions } from './lods.ts';
12
+ export { type GltfAnimation, type GltfChannel, type GltfClusters, type GltfImage, type GltfLod, type GltfMaterial, type GltfMesh, type GltfMorphTarget, type GltfNode, type GltfPrimitive, type GltfScene, type GltfSkin, type GltfTextureRef, type ParseOptions, parseGltf } from './parse.ts';
13
+ export { decodeGltfTextures, type GltfTextureOptions, type MaterialTextures, sizedVariant } from './textures.ts';
14
+ export { type GlbInput, type MeshoptEncode, writeGlb } from './write.ts';
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `@yali-engine/gltf`: glTF 2.0 for Yali (M2 increment 1, ADR-0047). Parse in a decode worker,
3
+ * upload into the render plugin's geometry pool, spawn the node hierarchy as entities.
4
+ *
5
+ * @example
6
+ * const h = app.resource<AssetServer>('assets').load<GltfAsset | null>('temple.glb');
7
+ * await h.ready;
8
+ * spawnGltf(app.world, h.get()!, app.resource<RenderContext>('render').Mesh!, { at: { t: [0, 0, 0] } });
9
+ */
10
+ export { decodeGltf, decodeGltfLods, gltfLoader, gltfPlugin, spawnGltf, } from "./gltf.js";
11
+ export { buildLods } from "./lods.js";
12
+ export { parseGltf } from "./parse.js";
13
+ export { decodeGltfTextures, sizedVariant } from "./textures.js";
14
+ export { writeGlb } from "./write.js";
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAKL,UAAU,EACV,cAAc,EAEd,UAAU,EAEV,UAAU,EACV,SAAS,GACV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,SAAS,EAAmB,MAAM,WAAW,CAAC;AACvD,OAAO,EAA2P,SAAS,EAAE,MAAM,YAAY,CAAC;AAChS,OAAO,EAAE,kBAAkB,EAAkD,YAAY,EAAE,MAAM,eAAe,CAAC;AACjH,OAAO,EAAqC,QAAQ,EAAE,MAAM,YAAY,CAAC"}
package/dist/lods.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ import type { MeshLod } from '@yali-engine/render';
2
+ /** How `buildLods` makes levels of detail. */
3
+ export interface LodOptions {
4
+ /** Most coarser levels (default 4; `MeshStore` keeps at most 7 besides LOD 0). */
5
+ readonly maxLevels?: number;
6
+ /** A primitive under this many triangles gets no LODs (default 256). */
7
+ readonly minTriangles?: number;
8
+ /** Each level aims at this fraction of the previous one's triangles (default 0.5). */
9
+ readonly ratio?: number;
10
+ /** The largest error a level may have, as a fraction of the mesh's extent (default 0.1). */
11
+ readonly maxError?: number;
12
+ /**
13
+ * Vertex normals (xyz at the start of every `stride` floats). With them the simplifier
14
+ * also keeps shading (`simplifyWithAttributes`), so a curved shiny surface does not show
15
+ * its coarse levels as faceted reflections (ADR-0066).
16
+ */
17
+ readonly normals?: {
18
+ readonly data: Float32Array;
19
+ readonly stride: number;
20
+ readonly weight?: number;
21
+ };
22
+ }
23
+ /**
24
+ * Simplifies a triangle mesh into coarser levels of detail with meshoptimizer's simplifier
25
+ * (M2 increment 2b; loaded on first use, so it reaches only the bundles that call this:
26
+ * build tools and the decode worker). Each level is simplified from the full mesh and
27
+ * carries its error in mesh units, never smaller than the previous level's, which is what
28
+ * the renderer's projected-error test reads. Stops when a level would not drop at least
29
+ * a fifth of the triangles within `maxError`.
30
+ *
31
+ * `positions` holds xyz at the start of every `stride` floats (3 packed, 8 interleaved).
32
+ *
33
+ * @example
34
+ * const lods = await buildLods(primitive.positions, 3, primitive.indices);
35
+ * meshes.add({ positions, normals, indices, lods });
36
+ */
37
+ export declare function buildLods(positions: Float32Array, stride: number, indices: Uint32Array, options?: LodOptions): Promise<MeshLod[]>;
package/dist/lods.js ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Simplifies a triangle mesh into coarser levels of detail with meshoptimizer's simplifier
3
+ * (M2 increment 2b; loaded on first use, so it reaches only the bundles that call this:
4
+ * build tools and the decode worker). Each level is simplified from the full mesh and
5
+ * carries its error in mesh units, never smaller than the previous level's, which is what
6
+ * the renderer's projected-error test reads. Stops when a level would not drop at least
7
+ * a fifth of the triangles within `maxError`.
8
+ *
9
+ * `positions` holds xyz at the start of every `stride` floats (3 packed, 8 interleaved).
10
+ *
11
+ * @example
12
+ * const lods = await buildLods(primitive.positions, 3, primitive.indices);
13
+ * meshes.add({ positions, normals, indices, lods });
14
+ */
15
+ export async function buildLods(positions, stride, indices, options = {}) {
16
+ const minTriangles = options.minTriangles ?? 256;
17
+ if (indices.length / 3 < minTriangles)
18
+ return [];
19
+ const { MeshoptSimplifier: S } = await import('meshoptimizer/simplifier');
20
+ await S.ready;
21
+ const maxLevels = options.maxLevels ?? 4;
22
+ const ratio = options.ratio ?? 0.5;
23
+ const maxError = options.maxError ?? 0.1;
24
+ const scale = S.getScale(positions, stride);
25
+ const out = [];
26
+ let previous = indices.length;
27
+ let error = 0;
28
+ for (let level = 0; level < maxLevels; level++) {
29
+ const target = Math.floor((previous * ratio) / 3) * 3;
30
+ if (target < 3 * 32)
31
+ break;
32
+ const n = options.normals;
33
+ const [lod, e] = n
34
+ ? S.simplifyWithAttributes(indices, positions, stride, n.data, n.stride, [n.weight ?? 0.5, n.weight ?? 0.5, n.weight ?? 0.5], null, target, maxError)
35
+ : S.simplify(indices, positions, stride, target, maxError);
36
+ if (lod.length === 0 || lod.length > previous * 0.8)
37
+ break;
38
+ error = Math.max(error, e * scale);
39
+ out.push({ indices: lod, error });
40
+ previous = lod.length;
41
+ }
42
+ return out;
43
+ }
44
+ //# sourceMappingURL=lods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lods.js","sourceRoot":"","sources":["../src/lods.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,SAAuB,EAAE,MAAc,EAAE,OAAoB,EAAE,UAAsB,EAAE;IACrH,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC;IACjD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,YAAY;QAAE,OAAO,EAAE,CAAC;IACjD,MAAM,EAAE,iBAAiB,EAAE,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;IAC1E,MAAM,CAAC,CAAC,KAAK,CAAC;IACd,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC;IACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,IAAI,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACtD,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;YAAE,MAAM;QAC3B,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC1B,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;YAChB,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC;YACrJ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC7D,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,QAAQ,GAAG,GAAG;YAAE,MAAM;QAC3D,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;QACnC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAClC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}