@hypersoniclabs/helix-cli 0.1.25-helix3.507 → 0.1.25-helix3.509

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 (40) hide show
  1. package/README.md +1 -1
  2. package/dist/itemLod/artifact.d.ts +58 -10
  3. package/dist/itemLod/artifact.js +137 -46
  4. package/dist/itemLod/artifact.js.map +1 -1
  5. package/dist/itemLod/basis.d.ts +17 -0
  6. package/dist/itemLod/basis.js +105 -0
  7. package/dist/itemLod/basis.js.map +1 -0
  8. package/dist/itemLod/command.d.ts +1 -0
  9. package/dist/itemLod/command.js +18 -7
  10. package/dist/itemLod/command.js.map +1 -1
  11. package/dist/itemLod/index.d.ts +5 -3
  12. package/dist/itemLod/index.js +3 -2
  13. package/dist/itemLod/index.js.map +1 -1
  14. package/dist/itemLod/levelGlb.d.ts +21 -1
  15. package/dist/itemLod/levelGlb.js +32 -14
  16. package/dist/itemLod/levelGlb.js.map +1 -1
  17. package/dist/itemLod/simplify.d.ts +36 -4
  18. package/dist/itemLod/simplify.js +97 -18
  19. package/dist/itemLod/simplify.js.map +1 -1
  20. package/dist/itemLod/textures.d.ts +41 -5
  21. package/dist/itemLod/textures.js +67 -11
  22. package/dist/itemLod/textures.js.map +1 -1
  23. package/dist/tsconfig.build.tsbuildinfo +1 -1
  24. package/docs/item-lod.md +63 -28
  25. package/package.json +1 -1
  26. package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
  27. package/plugins/beamng-vehicle/bin/__pycache__/beamng_audio.cpython-312.pyc +0 -0
  28. package/plugins/beamng-vehicle/bin/__pycache__/beamng_engine.cpython-312.pyc +0 -0
  29. package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
  30. package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
  31. package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
  32. package/plugins/beamng-vehicle/bin/__pycache__/beamng_stock_events.cpython-312.pyc +0 -0
  33. package/plugins/beamng-vehicle/bin/__pycache__/fmod_studio.cpython-312.pyc +0 -0
  34. package/plugins/beamng-vehicle/bin/__pycache__/fsb5.cpython-312.pyc +0 -0
  35. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio.cpython-312.pyc +0 -0
  36. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_ac.cpython-312.pyc +0 -0
  37. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_beamng.cpython-312.pyc +0 -0
  38. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_fixtures.cpython-312.pyc +0 -0
  39. package/plugins/beamng-vehicle/bin/__pycache__/test_beamng_engine.cpython-312.pyc +0 -0
  40. package/plugins/beamng-vehicle/bin/__pycache__/test_sim_audio.cpython-312.pyc +0 -0
package/README.md CHANGED
@@ -76,7 +76,7 @@ The token is stored in `~/.helix/credentials.json` (mode `600`). It's sent as
76
76
  | `helix item set-version <item-id> --package-version <v> --reason <text> [--expected-current-version-id <uuid>] [--as-admin] [--json]` | Move an item to a sealed Package Version of its own package (pin resolved from the public Package API; `POST /api/v1/universal-items/<id>/versions`). The flow for a **listed** item: `continuum publish-package` seals vN → `item set-version`; the visual check is advisory and never gates the move. A refusal (a technical failure or content safety) prints the server's plain reason first, then the remedy. An unknown version lists the sealed ones. A **vehicle** moves its car with the pin: the version's sealed root (role `vehicle-definition`) is verified against the manifest and sent as `vehiclePackage`, the same rider `vehicle publish --item` sends; a version without one is refused with a pointer to that resume. A version the item **already had** is a rollback: `PUT /api/v1/universal-items/<id>/versions/current { revision, reason }` (the server restores that revision's retained `vehiclePackage`; a pin-only revision has none and is refused). `--as-admin` (platform admins, for an item another account created) posts the same body to `POST /api/v1/admin/universal-items/<id>/versions`: same gates (visual QA included, no override), `--reason` recorded with you as the actor. |
77
77
  | `helix item thumbnail refresh <item-id> [--force] [--dry-run] [--json]` | Re-render a published item's canonical thumbnail from its **active Package Version** with the standard server renderer (`POST /api/v1/universal-items/<id>/thumbnail/regenerate`, owner or admin). Prints the status (`generated` / `current` / `dry-run`), old -> new thumbnail URL, renderer version and the source lane + Package Version. `--dry-run` writes nothing; `--force` re-renders even when the stored thumbnail is current. Moving an item to a new Package Version now refreshes the thumbnail automatically unless you uploaded one. An older backend answers 404 and the CLI says it does not support thumbnail refresh yet. Not the world `helix thumbnail set <slug>` command. |
78
78
  | `helix item thumbnail set <item-id> <image> [--json]` | Upload your own thumbnail (png/jpg/webp, up to 10 MiB, checked locally) for a published item (`PUT /api/v1/universal-items/<id>/thumbnail`, moderated). A creator upload stays in place across version moves until you run `thumbnail refresh --force`. 403 = you are not the item's owner. |
79
- | `helix item lods <packageId>[@version] \| --item <id> \| --glb <file> [--out <dir>] [--variant <id>] [--api-url <url>] [--json]` | Compile the `helix.item-lod/1` Runtime Artifact for a published prop, Device or vehicle Package Version: LOD1 (at most 25% of the triangles, textures at most 512 px) and LOD2 (at most 300 triangles, textures at most 256 px), each its own GLB with its own downsampled UASTC KTX2 textures and a measured `maxErrorM`, plus an 8-view 512 px octahedral impostor atlas. Content-addressed and deterministic; a source of 300 triangles or fewer waives the LOD1 cap; skinned input (avatars, add-ons) is refused. Local preview; the backend worker is the catalogue's source of truth. See [docs/item-lod.md](docs/item-lod.md). |
79
+ | `helix item lods <packageId>[@version] \| --item <id> \| --glb <file> [--out <dir>] [--variant <id>] [--profile prop\|vehicle] [--api-url <url>] [--json]` | Compile the `helix.item-lod/1` Runtime Artifact for a published prop, Device or vehicle Package Version: up to two levels, LOD1 (props at most 25% of the triangles, vehicles max(5000, 10%), textures at most 512 px) and LOD2 (at most 300 triangles, textures at most 256 px), each its own GLB with its own textures (never larger than the source's) and a measured `maxErrorM`, plus an 8-view 512 px octahedral impostor atlas. A level that does not cut half the triangles, or cannot be made strictly smaller in bytes, is omitted. Content-addressed and deterministic; skinned input (avatars, add-ons) is refused. Local preview; the backend worker is the catalogue's source of truth. See [docs/item-lod.md](docs/item-lod.md). |
80
80
  | `helix device create <dir> --id <slug> --title <t> --model <mesh.glb> --template standing-desk\|clock\|television` | Scaffold a GLB-backed `helix.device/1` definition, including the interactive TV/media-player template. There is intentionally no website Device editor. |
81
81
  | `helix device validate [dir] [--json]` | Validate the definition, GLB bytes and named-node bindings, typed state/controls, capabilities, and Home+World compatibility, including [declarative character hand reach](docs/device-hand-reach.md). |
82
82
  | `helix device test [dir] [--mode single\|multiplayer\|both] [--json]` | Exercise every interaction, persistence remount, and deterministic one-/two-client authority convergence. |
@@ -1,4 +1,8 @@
1
1
  import { type ImpostorFraming } from './impostor';
2
+ import { type LevelTextureSpec, type WrittenLevel, type WrittenTexture } from './levelGlb';
3
+ import { type ItemModel } from './model';
4
+ import { type ItemLodProfile, type SimplifiedLevel } from './simplify';
5
+ import { TextureCache } from './textures';
2
6
  /** The `helix.item-lod/1` Runtime Artifact: a small first-load file per level plus an octahedral impostor. */
3
7
  export declare const ITEM_LOD_SCHEMA = "helix.item-lod/1";
4
8
  export declare const ITEM_LOD_COMPILER = "item-lod/1";
@@ -8,6 +12,11 @@ export declare const ITEM_LOD_CAPS: {
8
12
  readonly lod1TextureEdge: number;
9
13
  readonly lod2Triangles: number;
10
14
  readonly lod2TextureEdge: number;
15
+ /** Vehicle LOD1 starting budget: max(this, vehicleLod1TriangleRatio of the source); it widens to the prop budget only to hold the error bound. */
16
+ readonly vehicleLod1MinTriangles: 5000;
17
+ readonly vehicleLod1TriangleRatio: 0.1;
18
+ /** A level is emitted only if it cuts at least this fraction of the triangles of the level above it. */
19
+ readonly minReduction: 0.5;
11
20
  };
12
21
  export interface ItemLodSource {
13
22
  /** Null only for a local `--glb` compile, which has no Package behind it. */
@@ -19,6 +28,8 @@ export interface ItemLodSource {
19
28
  modelCid: string;
20
29
  }
21
30
  export interface ItemLodLevel {
31
+ /** Which tier this is. `levels` lists only the tiers that were emitted, nearest first, so read this, not the index. */
32
+ lod: 1 | 2;
22
33
  object: string;
23
34
  triangles: number;
24
35
  maxErrorM: number;
@@ -28,7 +39,7 @@ export interface ItemLodLevel {
28
39
  textureMaxEdge: number;
29
40
  /** The triangle cap this level was held to. */
30
41
  cap: number;
31
- /** Present when the cap does not apply because the source is already tiny. */
42
+ /** Retained for artifacts written by the first compiler; a level that cannot reduce is now omitted instead. */
32
43
  waived?: string;
33
44
  }
34
45
  export interface ItemLodImpostor {
@@ -45,21 +56,28 @@ export interface ItemLodImpostor {
45
56
  export interface ItemLodArtifact {
46
57
  schema: typeof ITEM_LOD_SCHEMA;
47
58
  source: ItemLodSource;
59
+ /** Which LOD1 triangle budget applied: props keep at most 25 percent, vehicles max(5000, 10 percent). */
60
+ profile?: ItemLodProfile;
48
61
  bounds: {
49
62
  min: [number, number, number];
50
63
  max: [number, number, number];
51
64
  };
52
- /** [source, LOD1, LOD2] */
53
- triangles: [number, number, number];
54
- levels: [ItemLodLevel, ItemLodLevel];
65
+ /** [source, then one count per entry of `levels`], so `levels[i].triangles === triangles[i + 1]`. */
66
+ triangles: number[];
67
+ /**
68
+ * Zero, one or two levels, nearest first. A tier that does not cut at least half the triangles of the level above it, or
69
+ * cannot be made strictly smaller in bytes, is omitted: with `levels` empty the runtime goes from the full model straight
70
+ * to the impostor. Each omission is explained in `warnings`.
71
+ */
72
+ levels: ItemLodLevel[];
55
73
  impostor: ItemLodImpostor;
56
- /** Approximate GPU-resident bytes: vertex and index buffers plus transcoded textures with mips. */
74
+ /** Approximate GPU-resident bytes: vertex and index buffers plus transcoded textures with mips. A tier key is present only if that level is. */
57
75
  estimatedBytes: {
58
- lod1: number;
59
- lod2: number;
76
+ lod1?: number;
77
+ lod2?: number;
60
78
  impostor: number;
61
79
  };
62
- /** Anything the compiler could not carry across (material extensions, morph targets, animation). */
80
+ /** Anything the compiler could not carry across (material extensions, morph targets, animation), then one note per omitted level. */
63
81
  warnings: string[];
64
82
  }
65
83
  export interface ItemLodObject {
@@ -74,12 +92,25 @@ export interface ItemLodReportLevel {
74
92
  capMet: boolean;
75
93
  waived: string | null;
76
94
  maxErrorM: number;
95
+ /** `maxErrorM` over every source vertex, sub-visible parts included. */
96
+ strictErrorM: number;
77
97
  bytes: number;
78
98
  textures: number;
79
99
  textureMaxEdge: number;
80
100
  residentBytes: number;
81
101
  droppedMaterials: number;
82
102
  notes: string[];
103
+ /** Which texture spec produced the level (0 is the full set; higher rungs trade texture detail for bytes). */
104
+ textureRung: number;
105
+ /** Per texture: how it was made and what it cost. */
106
+ textureDetail: WrittenTexture[];
107
+ }
108
+ export interface ItemLodOmission {
109
+ lod: 1 | 2;
110
+ reason: string;
111
+ /** What the omitted tier would have been, so the decision can be audited. */
112
+ triangles: number;
113
+ bytes: number | null;
83
114
  }
84
115
  export interface ItemLodReport {
85
116
  sourceTriangles: number;
@@ -87,8 +118,11 @@ export interface ItemLodReport {
87
118
  materials: number;
88
119
  images: number;
89
120
  extensionsUsed: string[];
90
- lod1: ItemLodReportLevel;
91
- lod2: ItemLodReportLevel;
121
+ profile: ItemLodProfile;
122
+ /** Null when that tier was omitted; see `omitted`. */
123
+ lod1: ItemLodReportLevel | null;
124
+ lod2: ItemLodReportLevel | null;
125
+ omitted: ItemLodOmission[];
92
126
  impostor: {
93
127
  bytes: number;
94
128
  coverage: number;
@@ -129,10 +163,24 @@ export declare function validateItemLodArtifact(value: unknown): {
129
163
  };
130
164
  export interface CompileItemLodOptions {
131
165
  source: ItemLodSource;
166
+ /**
167
+ * `vehicle` aims LOD1 at max(5000, 10 percent of the source) triangles, widening up to a quarter only if the measured error
168
+ * would pass 10 percent of the longest extent; default `prop` (at most 25 percent).
169
+ */
170
+ profile?: ItemLodProfile;
132
171
  /** Atlas capture; defaults to the headless placements capture host. Injected by tests. */
133
172
  captureAtlas?: (captureGlb: Uint8Array, framing: ImpostorFraming) => Promise<Uint8Array>;
134
173
  onProgress?: (message: string) => void;
135
174
  }
175
+ /**
176
+ * Writes `simplified` with the first texture spec on the ladder whose file is strictly smaller than `aboveBytes`.
177
+ * Returns what the last attempt measured when none is.
178
+ */
179
+ export declare function writeSmallerLevel(model: ItemModel, simplified: SimplifiedLevel, cache: TextureCache, ladder: readonly LevelTextureSpec[], aboveBytes: number): Promise<{
180
+ written: WrittenLevel;
181
+ rung: number;
182
+ smaller: boolean;
183
+ }>;
136
184
  /** Compile a static GLB into an item-lod/1 artifact and its objects. Deterministic: the same bytes give the same CIDs. */
137
185
  export declare function compileItemLods(glb: Uint8Array, options: CompileItemLodOptions): Promise<ItemLodBuild>;
138
186
  export declare const itemLodObjectPath: (object: ItemLodObject) => string;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.itemLodObjectPath = exports.ITEM_LOD_CAPS = exports.ITEM_LOD_COMPILER = exports.ITEM_LOD_SCHEMA = void 0;
4
4
  exports.checkItemLodCaps = checkItemLodCaps;
5
5
  exports.validateItemLodArtifact = validateItemLodArtifact;
6
+ exports.writeSmallerLevel = writeSmallerLevel;
6
7
  exports.compileItemLods = compileItemLods;
7
8
  exports.writeItemLodOutput = writeItemLodOutput;
8
9
  const promises_1 = require("node:fs/promises");
@@ -22,28 +23,48 @@ exports.ITEM_LOD_CAPS = {
22
23
  lod1TextureEdge: levelGlb_1.LOD1_TEXTURES.maxEdge,
23
24
  lod2Triangles: simplify_1.ITEM_LOD2.maxTriangles,
24
25
  lod2TextureEdge: levelGlb_1.LOD2_TEXTURES.maxEdge,
26
+ /** Vehicle LOD1 starting budget: max(this, vehicleLod1TriangleRatio of the source); it widens to the prop budget only to hold the error bound. */
27
+ vehicleLod1MinTriangles: simplify_1.VEHICLE_LOD1_MIN_TRIANGLES,
28
+ vehicleLod1TriangleRatio: simplify_1.VEHICLE_LOD1_RATIO,
29
+ /** A level is emitted only if it cuts at least this fraction of the triangles of the level above it. */
30
+ minReduction: simplify_1.ITEM_LOD_MIN_REDUCTION,
25
31
  };
26
32
  const CID = /^cid:sha256:[a-f0-9]{64}$/;
27
33
  /** Checks the design's caps against an artifact. Waived levels pass but are listed. */
28
34
  function checkItemLodCaps(artifact) {
29
35
  const failures = [], waivers = [];
30
- const [source, t1, t2] = artifact.triangles;
31
- const [lod1, lod2] = artifact.levels;
32
- const lod1Cap = Math.floor(source * exports.ITEM_LOD_CAPS.lod1TriangleRatio);
33
- if (t1 > lod1Cap) {
34
- if (lod1.waived)
35
- waivers.push(`LOD1: ${lod1.waived}`);
36
- else
37
- failures.push(`LOD1 has ${t1} triangles, over 25 percent of the source (${lod1Cap})`);
36
+ const source = artifact.triangles[0];
37
+ const vehicle = artifact.profile === 'vehicle';
38
+ // A vehicle starts at max(5000, 10 percent) and may widen to the prop budget (a quarter) when the error bound needs it.
39
+ const lod1Cap = vehicle ? Math.max(exports.ITEM_LOD_CAPS.vehicleLod1MinTriangles, Math.floor(source * exports.ITEM_LOD_CAPS.lod1TriangleRatio)) : Math.floor(source * exports.ITEM_LOD_CAPS.lod1TriangleRatio);
40
+ let above = source, aboveBytes = Infinity;
41
+ for (const level of artifact.levels) {
42
+ const name = `LOD${level.lod}`;
43
+ if (level.lod === 1) {
44
+ if (level.triangles > lod1Cap) {
45
+ if (level.waived)
46
+ waivers.push(`${name}: ${level.waived}`);
47
+ else
48
+ failures.push(`${name} has ${level.triangles} triangles, over its cap of ${lod1Cap} (${vehicle ? 'max(5000, 25 percent' : '25 percent'} of the source)`);
49
+ }
50
+ if (level.cap > lod1Cap && !level.waived)
51
+ failures.push(`${name} was given a budget of ${level.cap} triangles, over ${lod1Cap}`);
52
+ if (level.textureMaxEdge > exports.ITEM_LOD_CAPS.lod1TextureEdge)
53
+ failures.push(`${name} textures reach ${level.textureMaxEdge}px, over ${exports.ITEM_LOD_CAPS.lod1TextureEdge}`);
54
+ }
55
+ else {
56
+ if (level.triangles > exports.ITEM_LOD_CAPS.lod2Triangles)
57
+ failures.push(`${name} has ${level.triangles} triangles, over ${exports.ITEM_LOD_CAPS.lod2Triangles}`);
58
+ if (level.textureMaxEdge > exports.ITEM_LOD_CAPS.lod2TextureEdge)
59
+ failures.push(`${name} textures reach ${level.textureMaxEdge}px, over ${exports.ITEM_LOD_CAPS.lod2TextureEdge}`);
60
+ }
61
+ if (level.triangles > above * (1 - exports.ITEM_LOD_CAPS.minReduction) + 1e-9 && !level.waived)
62
+ failures.push(`${name} (${level.triangles}) cuts under ${exports.ITEM_LOD_CAPS.minReduction * 100} percent of the triangles above it (${above})`);
63
+ if (level.bytes >= aboveBytes)
64
+ failures.push(`${name} is ${level.bytes} bytes, not smaller than the level above it (${aboveBytes})`);
65
+ above = level.triangles;
66
+ aboveBytes = level.bytes;
38
67
  }
39
- if (t2 > exports.ITEM_LOD_CAPS.lod2Triangles)
40
- failures.push(`LOD2 has ${t2} triangles, over ${exports.ITEM_LOD_CAPS.lod2Triangles}`);
41
- if (t2 > t1)
42
- failures.push(`LOD2 (${t2}) has more triangles than LOD1 (${t1})`);
43
- if (lod1.textureMaxEdge > exports.ITEM_LOD_CAPS.lod1TextureEdge)
44
- failures.push(`LOD1 textures reach ${lod1.textureMaxEdge}px, over ${exports.ITEM_LOD_CAPS.lod1TextureEdge}`);
45
- if (lod2.textureMaxEdge > exports.ITEM_LOD_CAPS.lod2TextureEdge)
46
- failures.push(`LOD2 textures reach ${lod2.textureMaxEdge}px, over ${exports.ITEM_LOD_CAPS.lod2TextureEdge}`);
47
68
  if (artifact.impostor.size !== impostor_1.IMPOSTOR_SIZE || artifact.impostor.views !== impostor_1.IMPOSTOR_VIEWS)
48
69
  failures.push('impostor is not 8 views at 512 px');
49
70
  return { ok: failures.length === 0, failures, waivers };
@@ -59,6 +80,8 @@ function validateItemLodArtifact(value) {
59
80
  return { valid: false, errors: ['artifact must be an object'] };
60
81
  if (a.schema !== exports.ITEM_LOD_SCHEMA)
61
82
  errors.push(`schema must be ${exports.ITEM_LOD_SCHEMA}`);
83
+ if (a.profile !== undefined && a.profile !== 'prop' && a.profile !== 'vehicle')
84
+ errors.push('profile must be "prop" or "vehicle"');
62
85
  const s = a.source;
63
86
  if (!s || typeof s !== 'object')
64
87
  errors.push('source is required');
@@ -77,13 +100,24 @@ function validateItemLodArtifact(value) {
77
100
  }
78
101
  if (!a.bounds || !isVec3(a.bounds.min) || !isVec3(a.bounds.max) || a.bounds.min.some((v, i) => v > a.bounds.max[i]))
79
102
  errors.push('bounds must be finite min/max vectors');
80
- if (!Array.isArray(a.triangles) || a.triangles.length !== 3 || !a.triangles.every(isCount) || a.triangles[0] < 1)
81
- errors.push('triangles must be [source, lod1, lod2] counts');
82
- if (!Array.isArray(a.levels) || a.levels.length !== 2)
83
- errors.push('levels must hold exactly LOD1 and LOD2');
84
- else
103
+ const levelCount = Array.isArray(a.levels) ? a.levels.length : -1;
104
+ if (levelCount < 0 || levelCount > 2)
105
+ errors.push('levels must hold zero, one or two entries (LOD1, LOD2)');
106
+ if (!Array.isArray(a.triangles) || !a.triangles.every(isCount) || a.triangles[0] < 1 || (levelCount >= 0 && a.triangles.length !== levelCount + 1))
107
+ errors.push('triangles must be [source, then one count per level]');
108
+ if (levelCount >= 0 && levelCount <= 2) {
109
+ const seen = new Set();
85
110
  a.levels.forEach((level, index) => {
86
111
  const name = `levels[${index}]`;
112
+ // Artifacts from the first compiler had no `lod` and always held both tiers; their position says which tier each is.
113
+ const lod = level.lod ?? (levelCount === 2 ? index + 1 : undefined);
114
+ if (lod !== 1 && lod !== 2)
115
+ errors.push(`${name}.lod must be 1 or 2`);
116
+ else {
117
+ if (seen.has(lod) || (index > 0 && lod <= (a.levels[index - 1].lod ?? index)))
118
+ errors.push(`${name}.lod repeats or is out of order`);
119
+ seen.add(lod);
120
+ }
87
121
  if (!isCid(level.object))
88
122
  errors.push(`${name}.object must be a CID`);
89
123
  if (!isCount(level.triangles) || level.triangles !== a.triangles?.[index + 1])
@@ -94,6 +128,7 @@ function validateItemLodArtifact(value) {
94
128
  if (!isCount(level[key]))
95
129
  errors.push(`${name}.${key} must be a count`);
96
130
  });
131
+ }
97
132
  const i = a.impostor;
98
133
  if (!i || typeof i !== 'object')
99
134
  errors.push('impostor is required');
@@ -108,31 +143,77 @@ function validateItemLodArtifact(value) {
108
143
  errors.push('impostor.bytes must be a count');
109
144
  }
110
145
  const e = a.estimatedBytes;
111
- if (!e || !isCount(e.lod1) || !isCount(e.lod2) || !isCount(e.impostor))
112
- errors.push('estimatedBytes needs lod1, lod2 and impostor counts');
146
+ if (!e || !isCount(e.impostor))
147
+ errors.push('estimatedBytes needs an impostor count');
148
+ else if (a.levels) {
149
+ // Every emitted tier has an estimate and no omitted tier has one.
150
+ for (const tier of [1, 2]) {
151
+ const present = a.levels.some((level, index) => (level.lod ?? (a.levels.length === 2 ? index + 1 : 0)) === tier);
152
+ const key = tier === 1 ? 'lod1' : 'lod2';
153
+ if (present !== (e[key] !== undefined) || (e[key] !== undefined && !isCount(e[key])))
154
+ errors.push(`estimatedBytes.${key} must be a count exactly when LOD${tier} is present`);
155
+ }
156
+ }
113
157
  if (!Array.isArray(a.warnings) || a.warnings.some(w => typeof w !== 'string'))
114
158
  errors.push('warnings must be a string list');
115
159
  return errors.length ? { valid: false, errors } : { valid: true, artifact: a };
116
160
  }
117
- const reportLevel = (level, written) => ({
118
- triangles: level.triangles, cap: level.cap, capMet: level.capMet, waived: level.waived, maxErrorM: level.maxErrorM,
161
+ const reportLevel = (level, written, rung) => ({
162
+ triangles: level.triangles, cap: level.cap, capMet: level.capMet, waived: level.waived, maxErrorM: level.maxErrorM, strictErrorM: level.strictErrorM,
119
163
  bytes: written.bytes.length, textures: written.textureCount, textureMaxEdge: written.textureMaxEdge, residentBytes: written.residentBytes,
120
- droppedMaterials: level.droppedMaterials.length, notes: level.notes,
164
+ droppedMaterials: level.droppedMaterials.length, notes: level.notes, textureRung: rung, textureDetail: written.textures,
121
165
  });
166
+ const percent = (fraction) => `${Math.round(fraction * 1000) / 10} percent`;
167
+ /**
168
+ * Writes `simplified` with the first texture spec on the ladder whose file is strictly smaller than `aboveBytes`.
169
+ * Returns what the last attempt measured when none is.
170
+ */
171
+ async function writeSmallerLevel(model, simplified, cache, ladder, aboveBytes) {
172
+ let best = null;
173
+ for (let rung = 0; rung < ladder.length; rung++) {
174
+ const written = await (0, levelGlb_1.writeLevelGlb)(model, simplified.groups, cache, { mode: 'level', textures: ladder[rung] });
175
+ if (written.bytes.length < aboveBytes)
176
+ return { written, rung, smaller: true };
177
+ if (!best || written.bytes.length < best.written.bytes.length)
178
+ best = { written, rung };
179
+ }
180
+ return { ...best, smaller: false };
181
+ }
122
182
  /** Compile a static GLB into an item-lod/1 artifact and its objects. Deterministic: the same bytes give the same CIDs. */
123
183
  async function compileItemLods(glb, options) {
124
184
  const started = Date.now();
125
185
  const progress = options.onProgress ?? (() => undefined);
186
+ const profile = options.profile ?? 'prop';
126
187
  progress('reading model');
127
188
  const model = await (0, model_1.readItemModel)(glb);
128
- progress(`${model.triangles} triangles, ${model.groups.length} materials, ${model.images.length} images`);
129
- const [lod1, lod2] = await (0, simplify_1.simplifyLevels)(model);
130
- progress(`LOD1 ${lod1.triangles} triangles, LOD2 ${lod2.triangles} triangles`);
189
+ progress(`${model.triangles} triangles, ${model.groups.length} materials, ${model.images.length} images (${profile})`);
131
190
  const cache = new textures_1.TextureCache();
132
- const written1 = await (0, levelGlb_1.writeLevelGlb)(model, lod1.groups, cache, { mode: 'level', textures: levelGlb_1.LOD1_TEXTURES });
133
- progress(`LOD1 written (${written1.bytes.length} bytes)`);
134
- const written2 = await (0, levelGlb_1.writeLevelGlb)(model, lod2.groups, cache, { mode: 'level', textures: levelGlb_1.LOD2_TEXTURES });
135
- progress(`LOD2 written (${written2.bytes.length} bytes)`);
191
+ // Each tier is emitted only if it cuts at least half the triangles of the level above it (the source for the first tier
192
+ // emitted) and its file is strictly smaller in bytes than that level's file; otherwise it is omitted and the next tier
193
+ // is measured against the last one emitted.
194
+ const emitted = [], omitted = [];
195
+ let aboveTriangles = model.triangles, aboveBytes = glb.length;
196
+ for (const lod of [1, 2]) {
197
+ const simplified = lod === 1 ? await (0, simplify_1.simplifyLod1)(model, profile) : await (0, simplify_1.simplifyLod2)(model, aboveTriangles);
198
+ const cut = 1 - simplified.triangles / aboveTriangles;
199
+ if (simplified.triangles > aboveTriangles * (1 - exports.ITEM_LOD_CAPS.minReduction)) {
200
+ const reason = `LOD${lod} omitted: it would cut only ${percent(cut)} of the triangles of the level above it (${aboveTriangles} to ${simplified.triangles}); at least ${percent(exports.ITEM_LOD_CAPS.minReduction)} is required`;
201
+ omitted.push({ lod, reason, triangles: simplified.triangles, bytes: null });
202
+ progress(reason);
203
+ continue;
204
+ }
205
+ const attempt = await writeSmallerLevel(model, simplified, cache, lod === 1 ? levelGlb_1.LOD1_TEXTURE_LADDER : levelGlb_1.LOD2_TEXTURE_LADDER, aboveBytes);
206
+ if (!attempt.smaller) {
207
+ const reason = `LOD${lod} omitted: its smallest file is ${attempt.written.bytes.length} bytes, not smaller than the level above it (${aboveBytes} bytes)`;
208
+ omitted.push({ lod, reason, triangles: simplified.triangles, bytes: attempt.written.bytes.length });
209
+ progress(reason);
210
+ continue;
211
+ }
212
+ emitted.push({ lod, simplified, written: attempt.written, rung: attempt.rung });
213
+ progress(`LOD${lod} ${simplified.triangles} triangles, ${attempt.written.bytes.length} bytes (texture rung ${attempt.rung})`);
214
+ aboveTriangles = simplified.triangles;
215
+ aboveBytes = attempt.written.bytes.length;
216
+ }
136
217
  const framing = (0, impostor_1.impostorFraming)(model.bounds);
137
218
  const captureGlb = await (0, levelGlb_1.writeLevelGlb)(model, model.groups, cache, { mode: 'capture', textures: levelGlb_1.LOD1_TEXTURES });
138
219
  progress('capturing impostor (64 views)');
@@ -140,24 +221,30 @@ async function compileItemLods(glb, options) {
140
221
  const impostorBytes = await (0, impostor_1.encodeImpostorAtlas)(atlas);
141
222
  progress(`impostor encoded (${impostorBytes.length} bytes)`);
142
223
  const objects = [
143
- { cid: (0, helix_manifest_1.cidFromBytes)(written1.bytes), bytes: written1.bytes, mediaType: 'model/gltf-binary', role: 'lod1' },
144
- { cid: (0, helix_manifest_1.cidFromBytes)(written2.bytes), bytes: written2.bytes, mediaType: 'model/gltf-binary', role: 'lod2' },
224
+ ...emitted.map((level) => ({ cid: (0, helix_manifest_1.cidFromBytes)(level.written.bytes), bytes: level.written.bytes, mediaType: 'model/gltf-binary', role: level.lod === 1 ? 'lod1' : 'lod2' })),
145
225
  { cid: (0, helix_manifest_1.cidFromBytes)(impostorBytes), bytes: impostorBytes, mediaType: 'image/ktx2', role: 'impostor' },
146
226
  ];
147
- const level = (simplified, written, object) => ({
148
- object: object.cid, triangles: simplified.triangles, maxErrorM: Math.round(simplified.maxErrorM * 1e5) / 1e5, bytes: written.bytes.length,
149
- textureMaxEdge: written.textureMaxEdge, cap: simplified.cap, ...(simplified.waived ? { waived: simplified.waived } : {}),
150
- });
227
+ const levels = emitted.map((level, index) => ({
228
+ lod: level.lod, object: objects[index].cid, triangles: level.simplified.triangles, maxErrorM: Math.round(level.simplified.maxErrorM * 1e5) / 1e5,
229
+ bytes: level.written.bytes.length, textureMaxEdge: level.written.textureMaxEdge, cap: level.simplified.cap,
230
+ ...(level.simplified.waived ? { waived: level.simplified.waived } : {}),
231
+ }));
232
+ const estimatedBytes = { impostor: (0, textures_1.residentTextureBytes)(impostor_1.IMPOSTOR_SIZE, impostor_1.IMPOSTOR_SIZE) };
233
+ for (const level of emitted)
234
+ estimatedBytes[level.lod === 1 ? 'lod1' : 'lod2'] = level.written.residentBytes;
235
+ const budgetNotes = emitted.filter(level => level.lod === 1 && level.simplified.budgetNote).map(level => level.simplified.budgetNote);
236
+ const warnings = [...model.warnings, ...budgetNotes, ...omitted.map(entry => entry.reason)];
151
237
  const artifact = {
152
238
  schema: exports.ITEM_LOD_SCHEMA,
153
239
  source: options.source,
240
+ profile,
154
241
  bounds: { min: model.bounds.min, max: model.bounds.max },
155
- triangles: [model.triangles, lod1.triangles, lod2.triangles],
156
- levels: [level(lod1, written1, objects[0]), level(lod2, written2, objects[1])],
157
- impostor: { object: objects[2].cid, kind: 'octahedral', views: impostor_1.IMPOSTOR_VIEWS, size: impostor_1.IMPOSTOR_SIZE, format: 'ktx2-uastc',
242
+ triangles: [model.triangles, ...emitted.map(level => level.simplified.triangles)],
243
+ levels,
244
+ impostor: { object: objects[objects.length - 1].cid, kind: 'octahedral', views: impostor_1.IMPOSTOR_VIEWS, size: impostor_1.IMPOSTOR_SIZE, format: 'ktx2-uastc',
158
245
  center: framing.center, radius: Math.round(framing.radius * 1e6) / 1e6, bytes: impostorBytes.length },
159
- estimatedBytes: { lod1: written1.residentBytes, lod2: written2.residentBytes, impostor: (0, textures_1.residentTextureBytes)(impostor_1.IMPOSTOR_SIZE, impostor_1.IMPOSTOR_SIZE) },
160
- warnings: model.warnings,
246
+ estimatedBytes,
247
+ warnings,
161
248
  };
162
249
  const validation = validateItemLodArtifact(artifact);
163
250
  if (!validation.valid)
@@ -165,12 +252,16 @@ async function compileItemLods(glb, options) {
165
252
  const artifactBytes = (0, helix_manifest_1.canonicalJsonBytes)(artifact);
166
253
  const caps = checkItemLodCaps(artifact);
167
254
  const previews = [{ name: 'impostor.png', bytes: await (0, impostor_1.impostorPreviewPng)(atlas) }];
255
+ const reported = (lod) => {
256
+ const level = emitted.find(candidate => candidate.lod === lod);
257
+ return level ? reportLevel(level.simplified, level.written, level.rung) : null;
258
+ };
168
259
  return {
169
260
  artifact, artifactBytes, artifactCid: (0, helix_manifest_1.cidFromBytes)(artifactBytes), objects, previews,
170
261
  report: {
171
262
  sourceTriangles: model.triangles, sourceBytes: glb.length, materials: model.materials.length, images: model.images.length,
172
- extensionsUsed: model.extensionsUsed, lod1: reportLevel(lod1, written1), lod2: reportLevel(lod2, written2),
173
- impostor: { bytes: impostorBytes.length, coverage: Math.round((0, impostor_1.impostorCoverage)(atlas) * 1e4) / 1e4 }, caps, warnings: model.warnings,
263
+ extensionsUsed: model.extensionsUsed, profile, lod1: reported(1), lod2: reported(2), omitted,
264
+ impostor: { bytes: impostorBytes.length, coverage: Math.round((0, impostor_1.impostorCoverage)(atlas) * 1e4) / 1e4 }, caps, warnings,
174
265
  millis: { total: Date.now() - started },
175
266
  },
176
267
  };
@@ -1 +1 @@
1
- {"version":3,"file":"artifact.js","sourceRoot":"","sources":["../../src/itemLod/artifact.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"artifact.js","sourceRoot":"","sources":["../../src/itemLod/artifact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Basis encoders for item-lod/1 textures. The sceneHlod encoder is UASTC-only; a level texture picks per texture between
3
+ * ETC1S (smallest, lossy), RDO-tuned UASTC and plain UASTC, so this module reaches the same installed WASM encoder and
4
+ * exposes all three.
5
+ */
6
+ export type BasisMode = 'etc1s' | 'uastc-rdo' | 'uastc';
7
+ /** Tuned in the item-lod round 2 measurements: ETC1S quality 128, RDO UASTC scalar 2 (about a third smaller than plain UASTC). */
8
+ export declare const BASIS_SETTINGS: {
9
+ readonly etc1sQuality: 128;
10
+ readonly etc1sCompression: 2;
11
+ readonly rdoScalar: 2;
12
+ readonly uastcFlags: 2;
13
+ };
14
+ /** Encodes RGBA8 pixels as a mipmapped KTX2. Deterministic for a given input and mode. */
15
+ export declare function encodeBasis(data: Uint8Array, width: number, height: number, color: boolean, mode: BasisMode): Promise<Uint8Array>;
16
+ /** Peak signal-to-noise ratio (dB) between the encoder input and what the file decodes to (base mip). */
17
+ export declare function basisPsnr(reference: Uint8Array, ktx2: Uint8Array): Promise<number>;
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BASIS_SETTINGS = void 0;
4
+ exports.encodeBasis = encodeBasis;
5
+ exports.basisPsnr = basisPsnr;
6
+ const promises_1 = require("node:fs/promises");
7
+ const node_path_1 = require("node:path");
8
+ const node_url_1 = require("node:url");
9
+ const esm_1 = require("../character/esm");
10
+ const textureCodec_1 = require("../sceneHlod/textureCodec");
11
+ let modulePromise;
12
+ function getEncoderModule() {
13
+ return modulePromise ??= (async () => {
14
+ // Resolve through Node's package search paths; the package exports map hides this installed implementation file.
15
+ for (const directory of require.resolve.paths('ktx2-encoder') ?? []) {
16
+ const file = (0, node_path_1.join)(directory, 'ktx2-encoder/dist/node/NodeBasisEncoder.js');
17
+ try {
18
+ await (0, promises_1.access)(file);
19
+ }
20
+ catch (error) {
21
+ if (['ENOENT', 'ENOTDIR'].includes(error.code ?? ''))
22
+ continue;
23
+ throw error;
24
+ }
25
+ return (await (0, esm_1.importEsm)((0, node_url_1.pathToFileURL)(file).href)).nodeEncoder.init();
26
+ }
27
+ throw new Error('Cannot locate the installed ktx2-encoder Basis implementation');
28
+ })();
29
+ }
30
+ /** Tuned in the item-lod round 2 measurements: ETC1S quality 128, RDO UASTC scalar 2 (about a third smaller than plain UASTC). */
31
+ exports.BASIS_SETTINGS = { etc1sQuality: 128, etc1sCompression: 2, rdoScalar: 2, uastcFlags: 2 };
32
+ /** Upper bound for the encoded file: every mip at UASTC's 16 bytes per 4x4 block, doubled, plus container slack. */
33
+ function outputCapacity(width, height) {
34
+ let bytes = 0, w = width, h = height;
35
+ for (;;) {
36
+ bytes += Math.ceil(w / 4) * Math.ceil(h / 4) * 16;
37
+ if (w === 1 && h === 1)
38
+ break;
39
+ w = Math.max(1, Math.floor(w / 2));
40
+ h = Math.max(1, Math.floor(h / 2));
41
+ }
42
+ return bytes * 2 + 65536;
43
+ }
44
+ /** Encodes RGBA8 pixels as a mipmapped KTX2. Deterministic for a given input and mode. */
45
+ async function encodeBasis(data, width, height, color, mode) {
46
+ if (![width, height].every(n => Number.isInteger(n) && n >= 1 && n <= 4096))
47
+ throw new Error('item-lod: texture rectangle out of range');
48
+ if (data.length !== width * height * 4)
49
+ throw new Error('item-lod: RGBA image has the wrong length');
50
+ const capacity = outputCapacity(width, height);
51
+ const module = await getEncoderModule(), encoder = new module.BasisEncoder();
52
+ try {
53
+ encoder.setDebug(false);
54
+ encoder.setCreateKTX2File(true);
55
+ encoder.setKTX2SRGBTransferFunc(color);
56
+ encoder.setMipGen(true);
57
+ encoder.setPerceptual(color);
58
+ if (mode === 'etc1s') {
59
+ encoder.setUASTC(false);
60
+ encoder.setQualityLevel(exports.BASIS_SETTINGS.etc1sQuality);
61
+ encoder.setCompressionLevel(exports.BASIS_SETTINGS.etc1sCompression);
62
+ }
63
+ else {
64
+ encoder.setUASTC(true);
65
+ encoder.setKTX2UASTCSupercompression(true);
66
+ encoder.setPackUASTCFlags(exports.BASIS_SETTINGS.uastcFlags);
67
+ if (mode === 'uastc-rdo') {
68
+ encoder.setRDOUASTC(true);
69
+ encoder.setRDOUASTCQualityScalar(exports.BASIS_SETTINGS.rdoScalar);
70
+ }
71
+ }
72
+ encoder.setSliceSourceImage(0, data, width, height, 0);
73
+ const output = new Uint8Array(capacity), length = encoder.encode(output);
74
+ if (!length || length > capacity)
75
+ throw new Error('item-lod: Basis encoding failed');
76
+ return output.slice(0, length);
77
+ }
78
+ finally {
79
+ encoder.delete();
80
+ }
81
+ }
82
+ /** Peak signal-to-noise ratio (dB) between the encoder input and what the file decodes to (base mip). */
83
+ async function basisPsnr(reference, ktx2) {
84
+ const decoded = await (0, textureCodec_1.decodeHlodImage)(ktx2, 'image/ktx2');
85
+ if (decoded.data.length !== reference.length)
86
+ throw new Error('item-lod: decoded texture has a different size');
87
+ // Alpha counts only when the image actually uses it (a cutout), so an opaque map is judged on colour alone.
88
+ let hasAlpha = false;
89
+ for (let i = 3; i < reference.length; i += 4)
90
+ if (reference[i] !== 255) {
91
+ hasAlpha = true;
92
+ break;
93
+ }
94
+ const channels = hasAlpha ? 4 : 3;
95
+ let squared = 0, samples = 0;
96
+ for (let i = 0; i < reference.length; i += 4)
97
+ for (let c = 0; c < channels; c++) {
98
+ const d = reference[i + c] - decoded.data[i + c];
99
+ squared += d * d;
100
+ samples++;
101
+ }
102
+ const mse = squared / Math.max(1, samples);
103
+ return mse === 0 ? 99 : 10 * Math.log10(255 * 255 / mse);
104
+ }
105
+ //# sourceMappingURL=basis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basis.js","sourceRoot":"","sources":["../../src/itemLod/basis.ts"],"names":[],"mappings":"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"}