@dylanebert/shallot-gltf 0.1.0-next.1 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +13 -41
  2. package/package.json +5 -5
  3. package/src/gltf.ts +3 -8
package/README.md CHANGED
@@ -1,53 +1,25 @@
1
1
  # shallot-gltf
2
2
 
3
- Experimental static glTF 2.0 loading and placement for Shallot. Not specification-complete or optimized.
3
+ experimental static glTF loading for [shallot](https://github.com/dylanebert/shallot).
4
4
 
5
- ```sh
6
- bun add @dylanebert/shallot-gltf @dylanebert/shallot
5
+ ```bash
6
+ bun add @dylanebert/shallot-gltf
7
7
  ```
8
8
 
9
9
  ```ts
10
- import { MeshPlugin, type Plugin, runApp } from "@dylanebert/shallot";
11
- import { loadGltfScene, spawnGltfScene } from "@dylanebert/shallot-gltf";
12
-
13
- const Model: Plugin = {
14
- name: "Model",
15
- dependencies: [MeshPlugin],
16
- async initialize(world, onProgress) {
17
- const model = await loadGltfScene(world, new URL("/model.glb", location.href), onProgress);
18
- spawnGltfScene(world, model, { translation: [0, 0, 0] });
19
- console.log(model.unsupported);
20
- },
21
- };
22
- await runApp({ plugins: [Model] });
10
+ // in your plugin's async initialize
11
+ const model = await loadGltfScene(world, url, onProgress);
12
+ spawnGltfScene(world, model, { translation: [0, 0, 0] });
23
13
  ```
24
14
 
25
- The game owns loading and placement; this package needs no plugin state. Call `loadGltfScene` from the game's async `initialize`, before image warm-up. Its handle belongs to that world. `spawnGltfScene` creates one entity per primitive instance, composing placement onto its node world transform. A composition with shear refuses with the node named, before spawning any entities. There is no core parent relation or model-root entity. Repeated placements share the load's meshes and materials, rather than registering copies. `model.primitives` exposes each `mesh`, `material` and model-space `matrix` for games that supply placements through `registerProducerTable` instead.
26
-
27
- `loadGltf` and `parse` remain deviceless entry points. [examples/gltf-model](examples/gltf-model) loads the textured Khronos Cesium Milk Truck through the package name. Run it with `bunx vite examples/gltf-model`; check its presentation with `bunx playwright test -c examples/gltf-model --workers=1`.
15
+ See [`examples/gltf-model`](examples/gltf-model).
28
16
 
29
- ## Compatibility
17
+ Meshes, base colour textures and `StandardMaterial` factors. Missing required extensions refuse by name; anything else ignored is listed in `model.unsupported`. No animation, skinning, lights, cameras, or Draco, meshopt and KTX2 compression.
30
18
 
31
- | shallot-gltf | Shallot |
19
+ | shallot-gltf | shallot |
32
20
  | --- | --- |
33
- | 0.1.0-next.1 | 0.10.0-next.5 and later 0.10 releases |
34
-
35
- ## Supported subset
36
-
37
- - `.gltf` and `.glb` v2, with external, data-URI or BIN buffers. `parse` accepts already-resolved buffers. External image URIs become absolute; embedded images expose their bytes. `loadGltfScene` registers these images in Shallot's shared sRGB image array; Shallot decodes them at warm.
38
- - Triangle primitives: positions, normals, first UV set and unsigned indices, including interleaved accessors and accessor offsets. Missing normals deindex the triangles and compute flat normals as glTF requires (three.js's smooth fallback is deliberately not copied).
39
- - Default scene hierarchy, matrix or TRS nodes, shared mesh primitives and column-major world matrices per primitive instance. Matrices retain shear; geometry remains mesh-local. No core parent relation is needed.
40
- - Linear base color RGBA, base color image reference, metallic, roughness and emissive factors, OPAQUE/MASK/BLEND, cutoff (default 0.5), and `KHR_materials_unlit`. These target Shallot's existing `StandardMaterial` fields rather than extending core.
41
-
42
- Unknown required extensions refuse with their names, including compression extensions. Unknown optional extensions and ignored features are named in `unsupported`. Non-triangle primitives and sparse-accessor primitives are skipped and reported. Vertex colors, tangents and extra UV sets are ignored and named. Base color textures requesting a UV set other than zero are omitted and reported. Base-color textures register their own wrap modes and texel filters, including glTF's default REPEAT wrapping. Unspecified filters follow GLTFLoader: linear magnification and linear-mipmap-linear minification. Shallot selects the nearest mip, so `unsupported` includes `sampler.minFilter.mipSelection` for linear mip blending or disabled mipmapping, including the unspecified minification default. Double-sided materials are reported, not mapped. Metallic-roughness, normal, occlusion and emissive maps are each named when ignored; their factors still decode.
43
-
44
- ## Scope cuts
45
-
46
- - Skinning, VAT, morph targets and animation clips are outside the static mesh pipeline; static geometry remains, without deformation or playback.
47
- - Lights and cameras are outside that pipeline.
48
- - Draco, meshopt and KTX2/Basis decoders are excluded: Bevy's core glTF loader ships none of them; each needs a vendored WASM decoder without a consumer here. Required compressed features refuse; optional extensions are reported and fallback data is used when available.
49
- - The archived worker pool, albedo buckets, palette union and scene routes depended on Shallot's removed renderer and are not recovered.
50
-
51
- The accessor, packing and node-local transform code is adapted from Shallot's archived `src/transitional/gltf/` at `f1023acd28a0fe31f64bc61345d4605887495201`; Accessor and GLB container tests are recovered from `a4e87190^:src/extras/gltf/`. Loading registers images before warm-up; runtime streaming is outside the supported subset.
21
+ | 0.1.0-next.1 | 0.10.0-next.5 and later 0.10 |
22
+ | 0.1.0-next.2 | 0.10.0-next.6 and later 0.10 |
23
+ | 0.1.0 | ^0.10.0 |
52
24
 
53
- See [CONTRIBUTING.md](CONTRIBUTING.md) for verification and [fixture provenance](tests/fixtures/README.md) for licenses.
25
+ changing it: [`CONTRIBUTING.md`](CONTRIBUTING.md). mit.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dylanebert/shallot-gltf",
3
- "version": "0.1.0-next.1",
3
+ "version": "0.1.0",
4
4
  "description": "Experimental static glTF loading and placement for Shallot.",
5
5
  "license": "MIT",
6
6
  "author": "Dylan Ebert <dylan.ebert@gmail.com>",
@@ -32,16 +32,16 @@
32
32
  "test": "bun test"
33
33
  },
34
34
  "peerDependencies": {
35
- "@dylanebert/shallot": "^0.10.0-next.5"
35
+ "@dylanebert/shallot": "^0.10.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@biomejs/biome": "^2.5.13",
39
- "@dylanebert/shallot": "0.10.0-next.5",
39
+ "@dylanebert/shallot": "0.10.0",
40
40
  "@playwright/test": "^1.64.1",
41
41
  "@types/bun": "^1.4.3",
42
42
  "@types/three": "0.180.0",
43
- "bun-webgpu": "github:dylanebert/bun-webgpu#7b75d0440d2f22e2c9a1cb383d15529652c53d98",
44
43
  "three": "0.180.0",
45
- "vite": "^8.3.4"
44
+ "vite": "^8.3.4",
45
+ "webgpu": "^0.6.2"
46
46
  }
47
47
  }
package/src/gltf.ts CHANGED
@@ -389,17 +389,10 @@ export function parse(gltf: GltfJson, buffers: ArrayBuffer[]): GltfScene {
389
389
  : wrap === 33648
390
390
  ? ImageAddressMode.MirrorRepeat
391
391
  : ImageAddressMode.Repeat;
392
- const textures = (gltf.textures ?? []).map((texture, index) => {
392
+ const textures = (gltf.textures ?? []).map((texture) => {
393
393
  const sampler =
394
394
  texture.sampler === undefined ? undefined : gltf.samplers?.[texture.sampler];
395
- // Shallot selects the nearest mip; glTF's unspecified min filter follows GLTFLoader.
396
395
  const min = sampler?.minFilter ?? 9987;
397
- if (
398
- materials.some((material) => material.texture === index) &&
399
- min !== 9984 &&
400
- min !== 9985
401
- )
402
- ignored.add("sampler.minFilter.mipSelection");
403
396
  return {
404
397
  image: texture.source,
405
398
  sampler: {
@@ -411,6 +404,8 @@ export function parse(gltf: GltfJson, buffers: ArrayBuffer[]): GltfScene {
411
404
  min === 9728 || min === 9984 || min === 9986
412
405
  ? ImageFilterMode.Nearest
413
406
  : ImageFilterMode.Linear,
407
+ mipmapFilter:
408
+ min === 9986 || min === 9987 ? ImageFilterMode.Linear : ImageFilterMode.Nearest,
414
409
  },
415
410
  };
416
411
  });