@hypersoniclabs/helix-cli 0.1.25-helix3.480 → 0.1.25-helix3.481

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 (71) hide show
  1. package/dist/city/buildings/build.d.ts +130 -0
  2. package/dist/city/buildings/build.js +304 -0
  3. package/dist/city/buildings/build.js.map +1 -0
  4. package/dist/city/buildings/check.d.ts +64 -0
  5. package/dist/city/buildings/check.js +342 -0
  6. package/dist/city/buildings/check.js.map +1 -0
  7. package/dist/city/buildings/colliders.d.ts +30 -0
  8. package/dist/city/buildings/colliders.js +95 -0
  9. package/dist/city/buildings/colliders.js.map +1 -0
  10. package/dist/city/buildings/command.d.ts +4 -0
  11. package/dist/city/buildings/command.js +96 -0
  12. package/dist/city/buildings/command.js.map +1 -0
  13. package/dist/city/buildings/emit.d.ts +9 -0
  14. package/dist/city/buildings/emit.js +54 -0
  15. package/dist/city/buildings/emit.js.map +1 -0
  16. package/dist/city/buildings/facade.d.ts +60 -0
  17. package/dist/city/buildings/facade.js +214 -0
  18. package/dist/city/buildings/facade.js.map +1 -0
  19. package/dist/city/buildings/gallery.d.ts +3 -0
  20. package/dist/city/buildings/gallery.js +104 -0
  21. package/dist/city/buildings/gallery.js.map +1 -0
  22. package/dist/city/buildings/glb.d.ts +22 -0
  23. package/dist/city/buildings/glb.js +110 -0
  24. package/dist/city/buildings/glb.js.map +1 -0
  25. package/dist/city/buildings/ground.d.ts +11 -0
  26. package/dist/city/buildings/ground.js +87 -0
  27. package/dist/city/buildings/ground.js.map +1 -0
  28. package/dist/city/buildings/index.d.ts +7 -0
  29. package/dist/city/buildings/index.js +35 -0
  30. package/dist/city/buildings/index.js.map +1 -0
  31. package/dist/city/buildings/mesh.d.ts +35 -0
  32. package/dist/city/buildings/mesh.js +122 -0
  33. package/dist/city/buildings/mesh.js.map +1 -0
  34. package/dist/city/buildings/model.d.ts +64 -0
  35. package/dist/city/buildings/model.js +4 -0
  36. package/dist/city/buildings/model.js.map +1 -0
  37. package/dist/city/buildings/plan.d.ts +30 -0
  38. package/dist/city/buildings/plan.js +288 -0
  39. package/dist/city/buildings/plan.js.map +1 -0
  40. package/dist/city/buildings/poly.d.ts +56 -0
  41. package/dist/city/buildings/poly.js +240 -0
  42. package/dist/city/buildings/poly.js.map +1 -0
  43. package/dist/city/buildings/roofs.d.ts +47 -0
  44. package/dist/city/buildings/roofs.js +359 -0
  45. package/dist/city/buildings/roofs.js.map +1 -0
  46. package/dist/city/buildings/skeleton.d.ts +32 -0
  47. package/dist/city/buildings/skeleton.js +557 -0
  48. package/dist/city/buildings/skeleton.js.map +1 -0
  49. package/dist/city/buildings/street.d.ts +17 -0
  50. package/dist/city/buildings/street.js +132 -0
  51. package/dist/city/buildings/street.js.map +1 -0
  52. package/dist/index.js +2 -0
  53. package/dist/index.js.map +1 -1
  54. package/dist/tsconfig.build.tsbuildinfo +1 -1
  55. package/docs/city-buildings.md +130 -0
  56. package/package.json +3 -2
  57. package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
  58. package/plugins/beamng-vehicle/bin/__pycache__/beamng_audio.cpython-312.pyc +0 -0
  59. package/plugins/beamng-vehicle/bin/__pycache__/beamng_engine.cpython-312.pyc +0 -0
  60. package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
  61. package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
  62. package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
  63. package/plugins/beamng-vehicle/bin/__pycache__/beamng_stock_events.cpython-312.pyc +0 -0
  64. package/plugins/beamng-vehicle/bin/__pycache__/fmod_studio.cpython-312.pyc +0 -0
  65. package/plugins/beamng-vehicle/bin/__pycache__/fsb5.cpython-312.pyc +0 -0
  66. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio.cpython-312.pyc +0 -0
  67. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_ac.cpython-312.pyc +0 -0
  68. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_beamng.cpython-312.pyc +0 -0
  69. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_fixtures.cpython-312.pyc +0 -0
  70. package/plugins/beamng-vehicle/bin/__pycache__/test_beamng_engine.cpython-312.pyc +0 -0
  71. package/plugins/beamng-vehicle/bin/__pycache__/test_sim_audio.cpython-312.pyc +0 -0
@@ -0,0 +1,130 @@
1
+ import { type CitySource, type Vec2 } from '../source';
2
+ import { type GroundFilter } from './ground';
3
+ import type { BuildingsStats } from './model';
4
+ /** Bump when a change to the generator changes any output byte (the digest gate in digest.spec.ts pins it). */
5
+ export declare const BUILDINGS_GENERATOR_VERSION = 1;
6
+ export declare const BUILDINGS_MANIFEST_SCHEMA: "helix.city-buildings/1";
7
+ export declare const BUILDINGS_MANIFEST_FILE = "buildings.json";
8
+ export declare const CELL_INDEX_SCHEMA: "helix.city-buildings-index/1";
9
+ export interface BuildBuildingsOptions {
10
+ out: string;
11
+ cellM?: number;
12
+ farCellM?: number;
13
+ groundFilter?: GroundFilter;
14
+ /** Plan only the first N buildings (by id): for smoke runs. */
15
+ limit?: number;
16
+ /** Nothing is written; everything else runs (timing and sizes). */
17
+ dryRun?: boolean;
18
+ }
19
+ export interface FileRef {
20
+ file: string;
21
+ sha256: string;
22
+ bytes: number;
23
+ }
24
+ export interface CellEntry {
25
+ key: string;
26
+ ix: number;
27
+ iz: number;
28
+ /** Scene metres of the cell origin the GLB and collider coordinates are relative to. */
29
+ origin: [number, number, number];
30
+ bounds: {
31
+ min: [number, number, number];
32
+ max: [number, number, number];
33
+ };
34
+ buildings: number;
35
+ meshBuildings: number;
36
+ near: (FileRef & {
37
+ triangles: number;
38
+ vertices: number;
39
+ }) | null;
40
+ box: FileRef & {
41
+ triangles: number;
42
+ vertices: number;
43
+ };
44
+ colliders: FileRef & {
45
+ boxes: number;
46
+ hulls: number;
47
+ };
48
+ index: FileRef;
49
+ }
50
+ export interface FarEntry extends FileRef {
51
+ key: string;
52
+ ix: number;
53
+ iz: number;
54
+ /** Cluster-local coordinates: positions are relative to this origin (the centre of the cluster, y = 0). */
55
+ origin: [number, number, number];
56
+ bounds: {
57
+ min: [number, number, number];
58
+ max: [number, number, number];
59
+ };
60
+ /** Fine cell keys in source order: `_HELIX_HLOD_SOURCE` value i is `cells[i]`. */
61
+ cells: string[];
62
+ triangles: number;
63
+ buildings: number;
64
+ quantizationErrorM: number;
65
+ }
66
+ export interface MeshBuildingEntry {
67
+ id: string;
68
+ cell: string;
69
+ kind: string;
70
+ ref: string;
71
+ baseY: number;
72
+ heightM: number;
73
+ }
74
+ export interface BuildingsManifest {
75
+ schema: typeof BUILDINGS_MANIFEST_SCHEMA;
76
+ generator: {
77
+ name: 'helix-city-buildings';
78
+ version: number;
79
+ };
80
+ source: {
81
+ id: string;
82
+ manifestSha256: string;
83
+ };
84
+ options: {
85
+ cellM: number;
86
+ farCellM: number;
87
+ groundFilter: string;
88
+ groundKind: string;
89
+ };
90
+ boundsXZ: [Vec2, Vec2];
91
+ cells: CellEntry[];
92
+ far: FarEntry[];
93
+ meshBuildings: MeshBuildingEntry[];
94
+ totals: {
95
+ buildings: number;
96
+ parts: number;
97
+ meshBuildings: number;
98
+ cells: number;
99
+ nearTriangles: number;
100
+ boxTriangles: number;
101
+ farTriangles: number;
102
+ nearBytes: number;
103
+ boxBytes: number;
104
+ colliderBytes: number;
105
+ indexBytes: number;
106
+ farBytes: number;
107
+ colliders: number;
108
+ nearBox: number;
109
+ nearPoly: number;
110
+ };
111
+ stats: BuildingsStats;
112
+ }
113
+ export interface BuildTimings {
114
+ readMs: number;
115
+ planMs: number;
116
+ emitMs: number;
117
+ encodeMs: number;
118
+ writeMs: number;
119
+ totalMs: number;
120
+ }
121
+ export interface BuildResult {
122
+ manifest: BuildingsManifest;
123
+ manifestSha256: string;
124
+ timings: BuildTimings;
125
+ out: string;
126
+ }
127
+ export declare function newStats(): BuildingsStats;
128
+ /** Builds from a folder on disk (overrides applied, hashes verified). */
129
+ export declare function buildBuildings(sourceDir: string, options: BuildBuildingsOptions): Promise<BuildResult>;
130
+ export declare function buildBuildingsFromSource(source: CitySource, manifestSha256: string, options: BuildBuildingsOptions): Promise<BuildResult>;
@@ -0,0 +1,304 @@
1
+ "use strict";
2
+ // `helix city buildings build`: a helix.city-source/1 folder -> content-addressed building cells and a whole-map far layer.
3
+ //
4
+ // <out>/buildings.json manifest (helix.city-buildings/1): cells, far clusters, mesh buildings, numbers
5
+ // <out>/chunks/building/<sha256>.glb NEAR level of a 256 m cell (LOD0): chosen representation, roofs, parapets
6
+ // <out>/chunks/building-box/<sha256>.glb BOX level of a cell (LOD1): one oriented box per part, <= 12 triangles
7
+ // <out>/chunks/building-collider/<sha256>.bin one oriented box per part (colliders.ts)
8
+ // <out>/chunks/building-index/<sha256>.json building id -> triangle ranges, levels, use (the design's buildings/<cell> sidecar)
9
+ // <out>/chunks/building-far/<sha256>.glb the generator-written HLOD v2 "complete" layer: box masses per 1,024 m cluster
10
+ //
11
+ // A chunk's bytes are a pure function of the generator version, the cell and the source features it owns (plus the
12
+ // roads and shop POIs near them), so an edit touches only the cells it reaches and neighbours keep their names.
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.CELL_INDEX_SCHEMA = exports.BUILDINGS_MANIFEST_FILE = exports.BUILDINGS_MANIFEST_SCHEMA = exports.BUILDINGS_GENERATOR_VERSION = void 0;
15
+ exports.newStats = newStats;
16
+ exports.buildBuildings = buildBuildings;
17
+ exports.buildBuildingsFromSource = buildBuildingsFromSource;
18
+ const promises_1 = require("node:fs/promises");
19
+ const node_path_1 = require("node:path");
20
+ const source_1 = require("../source");
21
+ const colliders_1 = require("./colliders");
22
+ const emit_1 = require("./emit");
23
+ const ground_1 = require("./ground");
24
+ const glb_1 = require("./glb");
25
+ const mesh_1 = require("./mesh");
26
+ const plan_1 = require("./plan");
27
+ const street_1 = require("./street");
28
+ /** Bump when a change to the generator changes any output byte (the digest gate in digest.spec.ts pins it). */
29
+ exports.BUILDINGS_GENERATOR_VERSION = 1;
30
+ exports.BUILDINGS_MANIFEST_SCHEMA = 'helix.city-buildings/1';
31
+ exports.BUILDINGS_MANIFEST_FILE = 'buildings.json';
32
+ exports.CELL_INDEX_SCHEMA = 'helix.city-buildings-index/1';
33
+ const key2 = (ix, iz) => `${ix},${iz}`;
34
+ function toMeshData(mb) {
35
+ return {
36
+ positions: Float32Array.from(mb.positions),
37
+ normals: Float32Array.from(mb.normals),
38
+ uvs: Float32Array.from(mb.uvs),
39
+ facade: Uint16Array.from(mb.facade),
40
+ colors: Uint8Array.from(mb.colors),
41
+ indices: Uint32Array.from(mb.indices),
42
+ };
43
+ }
44
+ function boundsOf(mb, origin) {
45
+ const min = [Infinity, Infinity, Infinity];
46
+ const max = [-Infinity, -Infinity, -Infinity];
47
+ for (let i = 0; i < mb.vertexCount; i += 1) {
48
+ const p = [mb.positions[i * 3] + origin[0], mb.positions[i * 3 + 1], mb.positions[i * 3 + 2] + origin[1]];
49
+ for (let a = 0; a < 3; a += 1) {
50
+ if (p[a] < min[a])
51
+ min[a] = p[a];
52
+ if (p[a] > max[a])
53
+ max[a] = p[a];
54
+ }
55
+ }
56
+ return { min: min.map(source_1.roundMm), max: max.map(source_1.roundMm) };
57
+ }
58
+ async function store(out, dir, ext, bytes, dryRun) {
59
+ const sha256 = (0, source_1.sha256Hex)(bytes);
60
+ const file = `chunks/${dir}/${sha256}.${ext}`;
61
+ if (!dryRun) {
62
+ const path = (0, node_path_1.join)(out, file);
63
+ await (0, promises_1.mkdir)((0, node_path_1.dirname)(path), { recursive: true });
64
+ const exists = await (0, promises_1.stat)(path).then((s) => s.size === bytes.byteLength, () => false);
65
+ if (!exists)
66
+ await (0, promises_1.writeFile)(path, bytes);
67
+ }
68
+ return { file, sha256, bytes: bytes.byteLength };
69
+ }
70
+ function newStats() {
71
+ return { buildings: 0, parts: 0, meshBuildings: 0, refused: {}, notes: {}, nearBox: 0, nearPoly: 0, roofs: {} };
72
+ }
73
+ /** Builds from a folder on disk (overrides applied, hashes verified). */
74
+ async function buildBuildings(sourceDir, options) {
75
+ const t0 = performance.now();
76
+ const dir = (0, node_path_1.resolve)(sourceDir);
77
+ const loaded = await (0, source_1.readCitySource)(dir);
78
+ const { source } = (0, source_1.applyOverrides)(loaded);
79
+ const manifestSha256 = await (0, source_1.readCitySourceIdentity)(dir);
80
+ const readMs = performance.now() - t0;
81
+ const result = await buildBuildingsFromSource(source, manifestSha256, options);
82
+ result.timings.readMs = readMs;
83
+ result.timings.totalMs = performance.now() - t0;
84
+ return result;
85
+ }
86
+ async function buildBuildingsFromSource(source, manifestSha256, options) {
87
+ const t0 = performance.now();
88
+ const cellM = options.cellM ?? source_1.CITY_SOURCE_GRID_M;
89
+ const farCellM = options.farCellM ?? cellM * 4;
90
+ if (!(cellM > 0) || farCellM % cellM !== 0)
91
+ throw new Error(`--far-cell (${farCellM}) must be a multiple of --cell (${cellM})`);
92
+ const out = (0, node_path_1.resolve)(options.out);
93
+ const dryRun = options.dryRun === true;
94
+ const stats = newStats();
95
+ const timings = { readMs: 0, planMs: 0, emitMs: 0, encodeMs: 0, writeMs: 0, totalMs: 0 };
96
+ // ---- plan every building
97
+ const tPlan = performance.now();
98
+ const ground = (0, ground_1.createGroundModel)(source.terrain, options.groundFilter ?? 'auto');
99
+ const ctx = { ground, defaults: source.manifest.defaults, landUse: new plan_1.LandUseIndex(source.areas), cellM, stats };
100
+ const streets = new street_1.StreetIndex(source.roads, source.pois);
101
+ const rows = [...(source.buildings ?? [])].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
102
+ const plans = [];
103
+ for (const row of options.limit !== undefined ? rows.slice(0, options.limit) : rows) {
104
+ const plan = (0, plan_1.planBuilding)(row, ctx);
105
+ if (!plan)
106
+ continue;
107
+ plans.push(plan);
108
+ stats.buildings += 1;
109
+ stats.parts += plan.parts.length;
110
+ if (plan.mesh)
111
+ stats.meshBuildings += 1;
112
+ for (const part of plan.parts) {
113
+ const key = part.roof.kind;
114
+ stats.roofs[key] = (stats.roofs[key] ?? 0) + 1;
115
+ if (!plan.mesh) {
116
+ if (part.rep === 'box')
117
+ stats.nearBox += 1;
118
+ else
119
+ stats.nearPoly += 1;
120
+ }
121
+ }
122
+ }
123
+ timings.planMs = performance.now() - tPlan;
124
+ // ---- group by cell
125
+ const byCell = new Map();
126
+ for (const plan of plans) {
127
+ const key = key2(plan.cell[0], plan.cell[1]);
128
+ const list = byCell.get(key);
129
+ if (list)
130
+ list.push(plan);
131
+ else
132
+ byCell.set(key, [plan]);
133
+ }
134
+ const cellKeys = [...byCell.keys()].sort((a, b) => {
135
+ const [ax, az] = a.split(',').map(Number);
136
+ const [bx, bz] = b.split(',').map(Number);
137
+ return az - bz || ax - bx;
138
+ });
139
+ const cells = [];
140
+ const boxData = new Map();
141
+ const meshBuildings = [];
142
+ const totals = {
143
+ buildings: stats.buildings, parts: stats.parts, meshBuildings: stats.meshBuildings, cells: 0, nearTriangles: 0, boxTriangles: 0, farTriangles: 0,
144
+ nearBytes: 0, boxBytes: 0, colliderBytes: 0, indexBytes: 0, farBytes: 0, colliders: 0, nearBox: stats.nearBox, nearPoly: stats.nearPoly,
145
+ };
146
+ for (const key of cellKeys) {
147
+ const group = byCell.get(key);
148
+ const [ix, iz] = group[0].cell;
149
+ const origin = [ix * cellM, iz * cellM];
150
+ const tEmit = performance.now();
151
+ const near = new mesh_1.MeshBuilder(origin);
152
+ const box = new mesh_1.MeshBuilder(origin);
153
+ const nearRanges = [];
154
+ const boxRanges = [];
155
+ for (const plan of group) {
156
+ const n0 = near.triangleCount;
157
+ if (!plan.mesh)
158
+ (0, emit_1.emitBuilding)(near, plan, 'near', streets);
159
+ nearRanges.push(n0, near.triangleCount - n0);
160
+ const b0 = box.triangleCount;
161
+ (0, emit_1.emitBuilding)(box, plan, 'box', streets);
162
+ boxRanges.push(b0, box.triangleCount - b0);
163
+ if (plan.mesh)
164
+ meshBuildings.push({ id: plan.id, cell: key, kind: plan.mesh.kind, ref: plan.mesh.ref, baseY: (0, source_1.roundMm)(plan.baseY), heightM: (0, source_1.roundMm)(plan.heightM) });
165
+ }
166
+ timings.emitMs += performance.now() - tEmit;
167
+ const tEnc = performance.now();
168
+ const extras = { cell: [ix, iz], origin: [origin[0], 0, origin[1]], generator: exports.BUILDINGS_GENERATOR_VERSION };
169
+ const nearGlb = near.triangleCount > 0 ? await (0, glb_1.encodeBuildingGlb)(toMeshData(near), `buildings ${key} near`, { ...extras, level: 'near' }) : null;
170
+ const boxMesh = toMeshData(box);
171
+ const boxGlb = await (0, glb_1.encodeBuildingGlb)(boxMesh, `buildings ${key} box`, { ...extras, level: 'box' });
172
+ const colliders = (0, colliders_1.encodeColliders)(group, origin);
173
+ const index = {
174
+ schema: exports.CELL_INDEX_SCHEMA,
175
+ cell: [ix, iz],
176
+ ids: group.map((p) => p.id),
177
+ near: nearRanges,
178
+ box: boxRanges,
179
+ levels: group.map((p) => p.levels),
180
+ heightM: group.map((p) => (0, source_1.roundMm)(p.heightM)),
181
+ use: group.map((p) => p.use),
182
+ repr: group.map((p) => (p.mesh ? 'm' : p.parts.every((q) => q.rep === 'box') ? 'b' : 'p')).join(''),
183
+ family: group.map((p) => p.facade.familyName),
184
+ };
185
+ timings.encodeMs += performance.now() - tEnc;
186
+ const tWrite = performance.now();
187
+ const nearRef = nearGlb ? await store(out, 'building', 'glb', nearGlb.bytes, dryRun) : null;
188
+ const boxRef = await store(out, 'building-box', 'glb', boxGlb.bytes, dryRun);
189
+ const colliderRef = await store(out, 'building-collider', 'bin', colliders.bytes, dryRun);
190
+ const indexRef = await store(out, 'building-index', 'json', Buffer.from(`${JSON.stringify(index)}\n`, 'utf8'), dryRun);
191
+ timings.writeMs += performance.now() - tWrite;
192
+ const bounds = boundsOf(box, origin);
193
+ cells.push({
194
+ key, ix, iz, origin: [origin[0], 0, origin[1]], bounds, buildings: group.length, meshBuildings: group.filter((p) => p.mesh).length,
195
+ near: nearRef && nearGlb ? { ...nearRef, triangles: nearGlb.triangles, vertices: nearGlb.vertices } : null,
196
+ box: { ...boxRef, triangles: boxGlb.triangles, vertices: boxGlb.vertices },
197
+ colliders: { ...colliderRef, ...colliders.counts },
198
+ index: indexRef,
199
+ });
200
+ totals.cells += 1;
201
+ totals.nearTriangles += nearGlb?.triangles ?? 0;
202
+ totals.boxTriangles += boxGlb.triangles;
203
+ totals.nearBytes += nearRef?.bytes ?? 0;
204
+ totals.boxBytes += boxRef.bytes;
205
+ totals.colliderBytes += colliderRef.bytes;
206
+ totals.indexBytes += indexRef.bytes;
207
+ totals.colliders += colliders.counts.boxes + colliders.counts.hulls;
208
+ boxData.set(key, { mesh: boxMesh, origin, ix, iz, buildings: group.length });
209
+ }
210
+ // ---- the far layer: boxes of every cell, merged per coarse cluster, source = fine cell
211
+ const far = [];
212
+ const perFar = Math.round(farCellM / cellM);
213
+ const clusters = new Map();
214
+ for (const key of cellKeys) {
215
+ const d = boxData.get(key);
216
+ const fx = Math.floor(d.ix / perFar);
217
+ const fz = Math.floor(d.iz / perFar);
218
+ const ck = key2(fx, fz);
219
+ const list = clusters.get(ck);
220
+ if (list)
221
+ list.push(key);
222
+ else
223
+ clusters.set(ck, [key]);
224
+ }
225
+ const clusterKeys = [...clusters.keys()].sort((a, b) => {
226
+ const [ax, az] = a.split(',').map(Number);
227
+ const [bx, bz] = b.split(',').map(Number);
228
+ return az - bz || ax - bx;
229
+ });
230
+ for (const ck of clusterKeys) {
231
+ const members = clusters.get(ck); // already in (iz, ix) order
232
+ const [fx, fz] = ck.split(',').map(Number);
233
+ const origin = [(fx + 0.5) * farCellM, 0, (fz + 0.5) * farCellM];
234
+ const parts = members.map((k) => boxData.get(k));
235
+ const total = parts.reduce((s, d) => s + d.mesh.positions.length / 3, 0);
236
+ const merged = {
237
+ positions: new Float32Array(total * 3), normals: new Float32Array(total * 3), uvs: new Float32Array(total * 2),
238
+ facade: new Uint16Array(total * 4), colors: new Uint8Array(total * 4),
239
+ indices: new Uint32Array(parts.reduce((s, d) => s + d.mesh.indices.length, 0)), sources: new Uint16Array(total),
240
+ };
241
+ let v = 0;
242
+ let t = 0;
243
+ parts.forEach((d, source) => {
244
+ const n = d.mesh.positions.length / 3;
245
+ for (let i = 0; i < n; i += 1) {
246
+ merged.positions[(v + i) * 3] = d.mesh.positions[i * 3] + d.origin[0] - origin[0];
247
+ merged.positions[(v + i) * 3 + 1] = d.mesh.positions[i * 3 + 1] - origin[1];
248
+ merged.positions[(v + i) * 3 + 2] = d.mesh.positions[i * 3 + 2] + d.origin[1] - origin[2];
249
+ merged.sources[v + i] = source;
250
+ }
251
+ merged.normals.set(d.mesh.normals, v * 3);
252
+ merged.uvs.set(d.mesh.uvs, v * 2);
253
+ merged.facade.set(d.mesh.facade, v * 4);
254
+ merged.colors.set(d.mesh.colors, v * 4);
255
+ for (let i = 0; i < d.mesh.indices.length; i += 1)
256
+ merged.indices[t + i] = d.mesh.indices[i] + v;
257
+ v += n;
258
+ t += d.mesh.indices.length;
259
+ });
260
+ const tEnc = performance.now();
261
+ const glb = await (0, glb_1.encodeBuildingGlb)(merged, `buildings far ${ck}`, { cluster: [fx, fz], origin, generator: exports.BUILDINGS_GENERATOR_VERSION, level: 'far' });
262
+ timings.encodeMs += performance.now() - tEnc;
263
+ const tWrite = performance.now();
264
+ const ref = await store(out, 'building-far', 'glb', glb.bytes, dryRun);
265
+ timings.writeMs += performance.now() - tWrite;
266
+ const min = [Infinity, Infinity, Infinity];
267
+ const max = [-Infinity, -Infinity, -Infinity];
268
+ for (let i = 0; i < total; i += 1) {
269
+ for (let a = 0; a < 3; a += 1) {
270
+ const value = merged.positions[i * 3 + a] + origin[a];
271
+ if (value < min[a])
272
+ min[a] = value;
273
+ if (value > max[a])
274
+ max[a] = value;
275
+ }
276
+ }
277
+ far.push({
278
+ ...ref, key: ck, ix: fx, iz: fz, origin, bounds: { min: min.map(source_1.roundMm), max: max.map(source_1.roundMm) },
279
+ cells: members, triangles: glb.triangles, buildings: parts.reduce((s, d) => s + d.buildings, 0), quantizationErrorM: Number(glb.quantizationErrorM.toFixed(4)),
280
+ });
281
+ totals.farTriangles += glb.triangles;
282
+ totals.farBytes += ref.bytes;
283
+ }
284
+ const manifest = {
285
+ schema: exports.BUILDINGS_MANIFEST_SCHEMA,
286
+ generator: { name: 'helix-city-buildings', version: exports.BUILDINGS_GENERATOR_VERSION },
287
+ source: { id: source.manifest.id, manifestSha256 },
288
+ options: { cellM, farCellM, groundFilter: ground.filter, groundKind: ground.kind },
289
+ boundsXZ: source.manifest.frame.boundsXZ,
290
+ cells,
291
+ far,
292
+ meshBuildings,
293
+ totals,
294
+ stats,
295
+ };
296
+ const manifestBytes = Buffer.from((0, source_1.prettyCanonicalJson)(manifest), 'utf8');
297
+ if (!dryRun) {
298
+ await (0, promises_1.mkdir)(out, { recursive: true });
299
+ await (0, promises_1.writeFile)((0, node_path_1.join)(out, exports.BUILDINGS_MANIFEST_FILE), manifestBytes);
300
+ }
301
+ timings.totalMs = performance.now() - t0;
302
+ return { manifest, manifestSha256: (0, source_1.sha256Hex)(manifestBytes), timings, out };
303
+ }
304
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/city/buildings/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { CELL_INDEX_SCHEMA } from './build';
2
+ export interface DecodedMesh {
3
+ /** Cell-local (or cluster-local for the far layer) metres, node transform applied. */
4
+ positions: Float32Array;
5
+ normals: Float32Array;
6
+ indices: Uint32Array;
7
+ facade?: Uint16Array;
8
+ colors?: Uint8Array;
9
+ sources?: Uint16Array;
10
+ extensionsUsed: string[];
11
+ hasCityMaterialExtension: boolean;
12
+ }
13
+ export declare function decodeBuildingGlb(bytes: Uint8Array): Promise<DecodedMesh>;
14
+ export interface CellIndex {
15
+ schema: typeof CELL_INDEX_SCHEMA;
16
+ cell: [number, number];
17
+ ids: string[];
18
+ near: number[];
19
+ box: number[];
20
+ levels: number[];
21
+ heightM: number[];
22
+ use: string[];
23
+ repr: string;
24
+ family: string[];
25
+ }
26
+ export interface TriangleRange {
27
+ start: number;
28
+ count: number;
29
+ }
30
+ /** Closed-surface and winding facts of one building's triangles. */
31
+ export declare function surfaceFacts(mesh: DecodedMesh, range: TriangleRange): {
32
+ boundaryAboveBase: number;
33
+ boundaryTotal: number;
34
+ inverted: number;
35
+ degenerate: number;
36
+ minY: number;
37
+ };
38
+ export interface CheckReport {
39
+ buildings: number;
40
+ /** Source buildings that produced a mass at all. */
41
+ planned: number;
42
+ /** Planned buildings whose footprint is >= 85% covered by upward-facing generated triangles, box level. */
43
+ presentBox: number;
44
+ /** The same, near level (mesh buildings excluded). */
45
+ presentNear: number;
46
+ nearChecked: number;
47
+ presentPct: number;
48
+ missing: string[];
49
+ hollow: string[];
50
+ invertedBuildings: string[];
51
+ degenerateTriangles: number;
52
+ far: {
53
+ clusters: number;
54
+ cellsCovered: number;
55
+ cellsTotal: number;
56
+ triangles: number;
57
+ ok: boolean;
58
+ problems: string[];
59
+ };
60
+ manifestOk: boolean;
61
+ problems: string[];
62
+ }
63
+ export declare function checkBuildings(sourceDir: string, outDir: string): Promise<CheckReport>;
64
+ export declare function formatCheck(report: CheckReport): string;