@hypersoniclabs/helix-cli 0.1.25-helix3.508 → 0.1.25-helix3.511

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 (49) hide show
  1. package/README.md +1 -1
  2. package/dist/itemLod/artifact.d.ts +67 -10
  3. package/dist/itemLod/artifact.js +170 -46
  4. package/dist/itemLod/artifact.js.map +1 -1
  5. package/dist/itemLod/atlas.d.ts +223 -0
  6. package/dist/itemLod/atlas.js +636 -0
  7. package/dist/itemLod/atlas.js.map +1 -0
  8. package/dist/itemLod/basis.d.ts +21 -0
  9. package/dist/itemLod/basis.js +115 -0
  10. package/dist/itemLod/basis.js.map +1 -0
  11. package/dist/itemLod/command.d.ts +1 -0
  12. package/dist/itemLod/command.js +18 -7
  13. package/dist/itemLod/command.js.map +1 -1
  14. package/dist/itemLod/flat.d.ts +12 -0
  15. package/dist/itemLod/flat.js +124 -0
  16. package/dist/itemLod/flat.js.map +1 -0
  17. package/dist/itemLod/index.d.ts +5 -3
  18. package/dist/itemLod/index.js +3 -2
  19. package/dist/itemLod/index.js.map +1 -1
  20. package/dist/itemLod/levelGlb.d.ts +40 -1
  21. package/dist/itemLod/levelGlb.js +154 -24
  22. package/dist/itemLod/levelGlb.js.map +1 -1
  23. package/dist/itemLod/mips.d.ts +37 -0
  24. package/dist/itemLod/mips.js +131 -0
  25. package/dist/itemLod/mips.js.map +1 -0
  26. package/dist/itemLod/simplify.d.ts +67 -4
  27. package/dist/itemLod/simplify.js +417 -110
  28. package/dist/itemLod/simplify.js.map +1 -1
  29. package/dist/itemLod/textures.d.ts +58 -5
  30. package/dist/itemLod/textures.js +98 -11
  31. package/dist/itemLod/textures.js.map +1 -1
  32. package/dist/tsconfig.build.tsbuildinfo +1 -1
  33. package/docs/item-lod.md +133 -32
  34. package/package.json +2 -2
  35. package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
  36. package/plugins/beamng-vehicle/bin/__pycache__/beamng_audio.cpython-312.pyc +0 -0
  37. package/plugins/beamng-vehicle/bin/__pycache__/beamng_engine.cpython-312.pyc +0 -0
  38. package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
  39. package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
  40. package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
  41. package/plugins/beamng-vehicle/bin/__pycache__/beamng_stock_events.cpython-312.pyc +0 -0
  42. package/plugins/beamng-vehicle/bin/__pycache__/fmod_studio.cpython-312.pyc +0 -0
  43. package/plugins/beamng-vehicle/bin/__pycache__/fsb5.cpython-312.pyc +0 -0
  44. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio.cpython-312.pyc +0 -0
  45. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_ac.cpython-312.pyc +0 -0
  46. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_beamng.cpython-312.pyc +0 -0
  47. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_fixtures.cpython-312.pyc +0 -0
  48. package/plugins/beamng-vehicle/bin/__pycache__/test_beamng_engine.cpython-312.pyc +0 -0
  49. package/plugins/beamng-vehicle/bin/__pycache__/test_sim_audio.cpython-312.pyc +0 -0
@@ -0,0 +1,223 @@
1
+ import type { ItemModel, ModelGroup, ModelImage, ModelMaterial, ModelTextureRef } from './model';
2
+ import { type MipChain, type UvRegion } from './mips';
3
+ /**
4
+ * The material atlas of item-lod/1. A level draws every material of the item with at most one primitive per render state
5
+ * (opaque or alpha-blended, lit or unlit), because the runtime pays one draw call per primitive per placement band.
6
+ *
7
+ * Every source material becomes a "recipe": the texels and factors that decide its surface. Materials with the same recipe
8
+ * share one rectangle of the atlas. A rectangle holds the part of each source texture the material's UVs actually use (its
9
+ * footprint), already multiplied by the material's factors (base colour factor, metallic and roughness factors, normal
10
+ * scale, emissive factor and strength), so one set of atlas textures and one material per primitive reproduces them all.
11
+ * Vertex UVs are remapped affinely into their rectangle. Materials that repeat a texture a few times bake the repeats into
12
+ * the rectangle; materials that repeat it too finely for the atlas to resolve fall back to the texture's mean colour, which
13
+ * is what a mipmapped texture shows at that distance anyway. A material with no texture is a 4 x 4 swatch.
14
+ */
15
+ /** Gutter around a textured rectangle, in atlas pixels at the colour resolution (the mip chain reaches it at level 2). */
16
+ export declare const GUTTER_LOD1 = 4, GUTTER_LOD2 = 2;
17
+ /** A rectangle is at least this many pixels on a side (one compression block). */
18
+ export declare const MIN_RECT = 4;
19
+ /** Tiled footprints larger than this many repeats (in total, or along one axis) fold to the mean colour. */
20
+ export declare const MAX_TILE_CELLS = 36, MAX_TILE_AXIS = 12;
21
+ export declare class AtlasOverflowError extends Error {
22
+ constructor(detail: string);
23
+ }
24
+ export interface PackItem {
25
+ id: number;
26
+ w: number;
27
+ h: number;
28
+ }
29
+ export interface PackedItem {
30
+ id: number;
31
+ x: number;
32
+ y: number;
33
+ }
34
+ /**
35
+ * Shelf packing, tallest first. Deterministic: ties break on width then id. Returns null when the items do not fit.
36
+ */
37
+ export declare function packRects(items: readonly PackItem[], width: number, height: number): PackedItem[] | null;
38
+ export interface RectRequest {
39
+ id: number;
40
+ /** Footprint in source texels (0 for a swatch). */
41
+ fullW: number;
42
+ fullH: number;
43
+ swatch: boolean;
44
+ /** Surface area (square metres) the recipe covers at this level. */
45
+ area: number;
46
+ }
47
+ export interface AtlasRect {
48
+ id: number;
49
+ x: number;
50
+ y: number;
51
+ w: number;
52
+ h: number;
53
+ gutter: number;
54
+ }
55
+ export interface AtlasLayout {
56
+ width: number;
57
+ height: number;
58
+ rects: AtlasRect[];
59
+ gutter: number;
60
+ edge: number;
61
+ }
62
+ /**
63
+ * Chooses rectangle sizes and positions for an atlas of at most `edge` x `edge` pixels. Texel density is uniform across
64
+ * recipes (so the surface area a recipe covers decides its share) and capped at each recipe's own source resolution; the
65
+ * highest density that packs wins, in the smallest power-of-two box that holds the result.
66
+ */
67
+ export declare function layoutAtlas(requests: readonly RectRequest[], edge: number): AtlasLayout;
68
+ export type AtlasSlot = 'baseColor' | 'metallicRoughness' | 'normal' | 'emissive';
69
+ type Transform = NonNullable<ModelTextureRef['transform']>;
70
+ /** What a material samples and how: the UV set, transform and wrap shared by all of its textures. */
71
+ export interface UvMapping {
72
+ texCoord: number;
73
+ transform?: Transform;
74
+ wrapS: number;
75
+ wrapT: number;
76
+ }
77
+ export type AlphaClass = 'OPAQUE' | 'MASK' | 'BLEND';
78
+ export type FootprintClass = 'plain' | 'tiled' | 'mean' | 'swatch';
79
+ /** A material reduced to the properties that decide its texels. */
80
+ export interface ResolvedMaterial {
81
+ index: number;
82
+ mapping: UvMapping | null;
83
+ alpha: AlphaClass;
84
+ cutoff: number;
85
+ base: {
86
+ image: ModelImage | null;
87
+ factor: [number, number, number, number];
88
+ };
89
+ mr: {
90
+ image: ModelImage | null;
91
+ roughness: number;
92
+ metallic: number;
93
+ };
94
+ occlusion: {
95
+ image: ModelImage;
96
+ strength: number;
97
+ } | null;
98
+ normal: {
99
+ image: ModelImage;
100
+ scale: number;
101
+ } | null;
102
+ emissive: {
103
+ image: ModelImage | null;
104
+ factor: [number, number, number];
105
+ strength: number;
106
+ } | null;
107
+ notes: string[];
108
+ }
109
+ export declare function resolveMaterial(material: ModelMaterial): ResolvedMaterial;
110
+ /** Everything that decides a material's texels except where on the texture it reads (which is the footprint) and how its UVs are transformed. */
111
+ export declare function bakeKey(material: ResolvedMaterial): string;
112
+ /** A material's UVs in the space of its texture: the UV set and KHR_texture_transform applied. Null when the group has no such set. */
113
+ export declare function effectiveUv(group: ModelGroup, mapping: UvMapping | null): Float32Array | null;
114
+ export interface Footprint {
115
+ u0: number;
116
+ u1: number;
117
+ v0: number;
118
+ v1: number;
119
+ repeatsU: number;
120
+ repeatsV: number;
121
+ klass: FootprintClass;
122
+ }
123
+ /** The part of the texture a set of UVs reads, and whether it is a plain crop, a small tiling, or a tiling too fine to keep. */
124
+ export declare function footprintOf(bounds: {
125
+ u0: number;
126
+ u1: number;
127
+ v0: number;
128
+ v1: number;
129
+ } | null, mapping: UvMapping | null): Footprint;
130
+ export interface Recipe {
131
+ id: number;
132
+ key: string;
133
+ /** Resolved material every other member of the recipe agrees with. */
134
+ material: ResolvedMaterial;
135
+ klass: FootprintClass;
136
+ footprint: UvRegion;
137
+ /** Footprint in source texels of the sharpest image; the rectangle is never sized beyond it. */
138
+ fullW: number;
139
+ fullH: number;
140
+ area: number;
141
+ /** Source material indices in this recipe. */
142
+ members: number[];
143
+ /** Roughness and metalness this recipe averages to, for levels that drop the metallic-roughness map. */
144
+ meanMr: {
145
+ roughness: number;
146
+ metallic: number;
147
+ };
148
+ /** Source images that feed each atlas texture, and their byte total (the never-larger limit). */
149
+ sourceImages: Record<AtlasSlot, ModelImage[]>;
150
+ }
151
+ export interface BucketPlan {
152
+ alphaMode: AlphaClass;
153
+ doubleSided: boolean;
154
+ unlit: boolean;
155
+ group: ModelGroup;
156
+ /** Source material indices drawn by this primitive. */
157
+ materials: number[];
158
+ /** Recipes (atlas mode) in this bucket, with the surface area each covers. */
159
+ recipes: Array<{
160
+ recipe: number;
161
+ area: number;
162
+ }>;
163
+ }
164
+ export interface AtlasPlan {
165
+ layout: AtlasLayout;
166
+ recipes: Recipe[];
167
+ needs: {
168
+ normal: boolean;
169
+ metallicRoughness: boolean;
170
+ occlusion: boolean;
171
+ emissive: boolean;
172
+ };
173
+ /** The strength the baked emissive texels are divided by (the largest among emitting recipes). */
174
+ emissiveStrength: number;
175
+ /** Roughness and metalness shared by every recipe when no map is needed. */
176
+ constantMr: {
177
+ roughness: number;
178
+ metallic: number;
179
+ };
180
+ folded: number;
181
+ }
182
+ export interface LevelPlan {
183
+ kind: 'direct' | 'atlas';
184
+ buckets: BucketPlan[];
185
+ atlas: AtlasPlan | null;
186
+ /** Direct mode: the source material each bucket is written from. */
187
+ direct?: Array<{
188
+ material: number;
189
+ }>;
190
+ notes: string[];
191
+ }
192
+ export interface PlanContext {
193
+ /** Mip chain of a source image (decoded once per compile). */
194
+ chain(image: ModelImage): Promise<MipChain>;
195
+ /** Pixel size of a source image. */
196
+ size(image: ModelImage): Promise<{
197
+ width: number;
198
+ height: number;
199
+ }>;
200
+ }
201
+ /**
202
+ * Plans how a level's groups are drawn: one primitive per render state, with the material atlas that lets them share one
203
+ * material set. `edge` is the atlas edge cap (512 at LOD1, 256 at LOD2).
204
+ */
205
+ export declare function planLevel(model: ItemModel, allGroups: readonly ModelGroup[], edge: number, context: PlanContext): Promise<LevelPlan>;
206
+ export interface BakeContext {
207
+ chain(image: ModelImage): Promise<MipChain>;
208
+ }
209
+ /**
210
+ * Renders one atlas texture. `shrink` (1 or 0.5) scales the whole layout, for data maps kept at half the colour resolution.
211
+ */
212
+ export declare function bakeAtlasSlot(plan: AtlasPlan, slot: AtlasSlot, shrink: number, context: BakeContext): Promise<{
213
+ data: Uint8Array;
214
+ width: number;
215
+ height: number;
216
+ }>;
217
+ /**
218
+ * Per-pixel weights for judging an encoded atlas texture: a pixel counts for the surface its rectangle is drawn on, shared by
219
+ * the rectangle's pixels, so a small palette strip that paints most of a vehicle is judged as the large area it is. Unused
220
+ * pixels weigh nothing. Same geometry as `bakeAtlasSlot`.
221
+ */
222
+ export declare function atlasPixelWeights(plan: AtlasPlan, shrink: number): Float32Array;
223
+ export {};