@hypersoniclabs/helix-cli 0.1.25-helix3.480 → 0.1.25-helix3.482
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/README.md +1 -0
- package/dist/city/buildings/build.d.ts +130 -0
- package/dist/city/buildings/build.js +304 -0
- package/dist/city/buildings/build.js.map +1 -0
- package/dist/city/buildings/check.d.ts +64 -0
- package/dist/city/buildings/check.js +342 -0
- package/dist/city/buildings/check.js.map +1 -0
- package/dist/city/buildings/colliders.d.ts +30 -0
- package/dist/city/buildings/colliders.js +95 -0
- package/dist/city/buildings/colliders.js.map +1 -0
- package/dist/city/buildings/command.d.ts +4 -0
- package/dist/city/buildings/command.js +96 -0
- package/dist/city/buildings/command.js.map +1 -0
- package/dist/city/buildings/emit.d.ts +9 -0
- package/dist/city/buildings/emit.js +54 -0
- package/dist/city/buildings/emit.js.map +1 -0
- package/dist/city/buildings/facade.d.ts +60 -0
- package/dist/city/buildings/facade.js +214 -0
- package/dist/city/buildings/facade.js.map +1 -0
- package/dist/city/buildings/gallery.d.ts +3 -0
- package/dist/city/buildings/gallery.js +104 -0
- package/dist/city/buildings/gallery.js.map +1 -0
- package/dist/city/buildings/glb.d.ts +22 -0
- package/dist/city/buildings/glb.js +110 -0
- package/dist/city/buildings/glb.js.map +1 -0
- package/dist/city/buildings/ground.d.ts +11 -0
- package/dist/city/buildings/ground.js +87 -0
- package/dist/city/buildings/ground.js.map +1 -0
- package/dist/city/buildings/index.d.ts +7 -0
- package/dist/city/buildings/index.js +35 -0
- package/dist/city/buildings/index.js.map +1 -0
- package/dist/city/buildings/mesh.d.ts +35 -0
- package/dist/city/buildings/mesh.js +122 -0
- package/dist/city/buildings/mesh.js.map +1 -0
- package/dist/city/buildings/model.d.ts +64 -0
- package/dist/city/buildings/model.js +4 -0
- package/dist/city/buildings/model.js.map +1 -0
- package/dist/city/buildings/plan.d.ts +30 -0
- package/dist/city/buildings/plan.js +288 -0
- package/dist/city/buildings/plan.js.map +1 -0
- package/dist/city/buildings/poly.d.ts +56 -0
- package/dist/city/buildings/poly.js +240 -0
- package/dist/city/buildings/poly.js.map +1 -0
- package/dist/city/buildings/roofs.d.ts +47 -0
- package/dist/city/buildings/roofs.js +359 -0
- package/dist/city/buildings/roofs.js.map +1 -0
- package/dist/city/buildings/skeleton.d.ts +32 -0
- package/dist/city/buildings/skeleton.js +557 -0
- package/dist/city/buildings/skeleton.js.map +1 -0
- package/dist/city/buildings/street.d.ts +17 -0
- package/dist/city/buildings/street.js +132 -0
- package/dist/city/buildings/street.js.map +1 -0
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/sceneSplit/chunk.d.ts +55 -0
- package/dist/sceneSplit/chunk.js +202 -0
- package/dist/sceneSplit/chunk.js.map +1 -0
- package/dist/sceneSplit/clip.d.ts +37 -0
- package/dist/sceneSplit/clip.js +154 -0
- package/dist/sceneSplit/clip.js.map +1 -0
- package/dist/sceneSplit/commands.d.ts +3 -0
- package/dist/sceneSplit/commands.js +115 -0
- package/dist/sceneSplit/commands.js.map +1 -0
- package/dist/sceneSplit/fragments.d.ts +15 -0
- package/dist/sceneSplit/fragments.js +155 -0
- package/dist/sceneSplit/fragments.js.map +1 -0
- package/dist/sceneSplit/geometryQueries.d.ts +9 -0
- package/dist/sceneSplit/geometryQueries.js +63 -0
- package/dist/sceneSplit/geometryQueries.js.map +1 -0
- package/dist/sceneSplit/gltfIo.d.ts +13 -0
- package/dist/sceneSplit/gltfIo.js +24 -0
- package/dist/sceneSplit/gltfIo.js.map +1 -0
- package/dist/sceneSplit/ktx2.d.ts +9 -0
- package/dist/sceneSplit/ktx2.js +80 -0
- package/dist/sceneSplit/ktx2.js.map +1 -0
- package/dist/sceneSplit/math.d.ts +48 -0
- package/dist/sceneSplit/math.js +221 -0
- package/dist/sceneSplit/math.js.map +1 -0
- package/dist/sceneSplit/plan.d.ts +37 -0
- package/dist/sceneSplit/plan.js +152 -0
- package/dist/sceneSplit/plan.js.map +1 -0
- package/dist/sceneSplit/source.d.ts +30 -0
- package/dist/sceneSplit/source.js +180 -0
- package/dist/sceneSplit/source.js.map +1 -0
- package/dist/sceneSplit/split.d.ts +29 -0
- package/dist/sceneSplit/split.js +969 -0
- package/dist/sceneSplit/split.js.map +1 -0
- package/dist/sceneSplit/testutil/fixtures.d.ts +17 -0
- package/dist/sceneSplit/testutil/fixtures.js +223 -0
- package/dist/sceneSplit/testutil/fixtures.js.map +1 -0
- package/dist/sceneSplit/types.d.ts +175 -0
- package/dist/sceneSplit/types.js +3 -0
- package/dist/sceneSplit/types.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/docs/city-buildings.md +130 -0
- package/docs/scene-split.md +97 -0
- package/package.json +4 -2
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_audio.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_engine.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_stock_events.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/fmod_studio.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/fsb5.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/sim_audio.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_ac.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_beamng.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_fixtures.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/test_beamng_engine.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/test_sim_audio.cpython-312.pyc +0 -0
package/README.md
CHANGED
|
@@ -106,6 +106,7 @@ The token is stored in `~/.helix/credentials.json` (mode `600`). It's sent as
|
|
|
106
106
|
| `helix world scene-source inventory\|compile <helsinki\|bistro> <archive>` | Verify and safely inventory a known CC BY source archive, then compile deterministic local proxy/detail GLBs and an existing-schema Scene v2 package. |
|
|
107
107
|
| `helix world scene-source publish <world-id> <package-dir> [--publish]` | Validate the Scene v2 package, refuse it if it breaks the open-world performance rules (docs/scene-perf.md; no override), and print its multipart build receipt. Execution remains dry-run-only until backend private-pin entitlement lands; `--publish` currently fails closed, and access control never changes CC BY rights. |
|
|
108
108
|
| `helix scene validate <dir\|file> [--perf] [--tier desktop\|mobile\|desktop,mobile] [--out <report.json>]` | Check a Scene v2 package against the shared validator and, with `--perf`, the 14 open-world performance rules (textures, geometry, cells, draws, budget, first-playable bytes). Exit 0 pass, 1 refused, 2 cannot be judged. See `docs/scene-perf.md`. |
|
|
109
|
+
| `helix scene split <input> -o <dir> [--cell-size m] [--core-radius m] [--spawn x,y,z] [--textures ktx2\|keep]` | Split a monolithic environment (one big shell GLB, or a Scene v2 document with an eager shell) into a small eager spawn core plus distance-streamed cells on a fixed, content-addressed grid. Writes a validated Scene v2 package with per-cell bounds, priority and an honest memory budget, plus a report of eager bytes before and after. Deterministic and byte-identical on a rerun; never publishes. See [`docs/scene-split.md`](docs/scene-split.md). |
|
|
109
110
|
| `helix continuum publish-source-map\|publish-scratch\|publish-package\|publish-glb\|make-item\|publish-owned-item` | Resume exact-CID object adoption/ingestion, Package lease/seal, optional explicitly authorized Listing, and WorldRelease publication through one creator-owned pipeline. |
|
|
110
111
|
| `helix continuum receipt <job-id>` | Read the sanitized durable receipt for a completed Continuum publication. |
|
|
111
112
|
| `helix unreal init\|validate\|doctor\|package [project]` | Create and gate a shared-runtime or native-game publish manifest, check optional editor MCP, and assemble a local upload-shaped package. |
|
|
@@ -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;
|