@hypersoniclabs/helix-cli 0.1.25-helix3.491 → 0.1.25-helix3.493
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/assets/city-materials/cs2-asphalt/asphalt_col.ktx2 +0 -0
- package/assets/city-materials/cs2-asphalt/overrides.json +6 -0
- package/dist/cs2/buildingsLook.d.ts +86 -0
- package/dist/cs2/buildingsLook.js +273 -0
- package/dist/cs2/buildingsLook.js.map +1 -0
- package/dist/cs2/convert/buildingsCommand.d.ts +6 -0
- package/dist/cs2/convert/buildingsCommand.js +80 -0
- package/dist/cs2/convert/buildingsCommand.js.map +1 -0
- package/dist/cs2/convert/buildingsRestyle.d.ts +128 -0
- package/dist/cs2/convert/buildingsRestyle.js +510 -0
- package/dist/cs2/convert/buildingsRestyle.js.map +1 -0
- package/dist/cs2/convert/terrainConform.d.ts +6 -0
- package/dist/cs2/convert/terrainConform.js +2 -1
- package/dist/cs2/convert/terrainConform.js.map +1 -1
- package/dist/cs2/restyle/command.js +16 -5
- package/dist/cs2/restyle/command.js.map +1 -1
- package/dist/cs2/restyle/format.d.ts +3 -0
- package/dist/cs2/restyle/format.js +18 -0
- package/dist/cs2/restyle/format.js.map +1 -1
- package/dist/cs2/restyle/library.d.ts +11 -0
- package/dist/cs2/restyle/library.js +51 -0
- package/dist/cs2/restyle/library.js.map +1 -0
- package/dist/cs2/restyle/restyle.d.ts +11 -2
- package/dist/cs2/restyle/restyle.js +50 -5
- package/dist/cs2/restyle/restyle.js.map +1 -1
- package/dist/cs2/restyle/ribbons.d.ts +21 -0
- package/dist/cs2/restyle/ribbons.js +156 -0
- package/dist/cs2/restyle/ribbons.js.map +1 -0
- package/dist/cs2/restyle/scenePatch.d.ts +11 -1
- package/dist/cs2/restyle/scenePatch.js +85 -1
- package/dist/cs2/restyle/scenePatch.js.map +1 -1
- package/dist/cs2/restyle/terrainCarve.d.ts +68 -0
- package/dist/cs2/restyle/terrainCarve.js +222 -0
- package/dist/cs2/restyle/terrainCarve.js.map +1 -0
- package/dist/cs2/restyle/terrainPack.d.ts +16 -0
- package/dist/cs2/restyle/terrainPack.js +78 -0
- package/dist/cs2/restyle/terrainPack.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- 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
|
Binary file
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { type FacadeLanes } from '../city/buildings/facade';
|
|
2
|
+
export type BuildingZone = 'residential' | 'commercial' | 'office' | 'industrial' | 'mixed' | 'rural' | 'civic';
|
|
3
|
+
export type BuildingDensity = 'low' | 'medium' | 'high';
|
|
4
|
+
export interface BuildingKind {
|
|
5
|
+
prefab: string;
|
|
6
|
+
zone: BuildingZone;
|
|
7
|
+
density: BuildingDensity | null;
|
|
8
|
+
region: 'EU' | 'NA' | null;
|
|
9
|
+
/** The `_L<n>` level suffix, or null (signature and service buildings have none). */
|
|
10
|
+
level: number | null;
|
|
11
|
+
}
|
|
12
|
+
/** `EU_ResidentialLow01_L5_2x2_<32 hex>` and `..._Win_<32 hex>` both reduce to the prefab's own name. */
|
|
13
|
+
export declare function prefabOfMaterialName(materialName: string): string;
|
|
14
|
+
export declare function classifyPrefab(name: string): BuildingKind;
|
|
15
|
+
/** sRGB multipliers (0..1). The albedo is grey, so a colour here is the colour the wall reads as, times the grey's value. */
|
|
16
|
+
export type Srgb = readonly [number, number, number];
|
|
17
|
+
export interface Scheme {
|
|
18
|
+
name: string;
|
|
19
|
+
/** Mask red, green, blue: the main wall, a second wall or roof, and the trim. */
|
|
20
|
+
colors: readonly [Srgb, Srgb, Srgb];
|
|
21
|
+
}
|
|
22
|
+
/** Share of its own chroma every palette colour keeps (1 = the first, saturated stand-in; 0 = its luminance grey). */
|
|
23
|
+
export declare const CHROMA_KEEP = 0.5;
|
|
24
|
+
/** The saturated primaries (red, orange, yellow, teal, green, blue) and the pinks and mints keep less: CS2 has almost none of them. */
|
|
25
|
+
export declare const ACCENT_CHROMA_KEEP = 0.35;
|
|
26
|
+
/**
|
|
27
|
+
* Blend an sRGB colour toward its own luminance grey. Done in linear light on `Y = 0.2126 R + 0.7152 G + 0.0722 B`, so the colour keeps
|
|
28
|
+
* its luminance exactly (the albedo it multiplies keeps its brightness) and only the chroma shrinks, by `keep`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function muteColor([r, g, b]: Srgb, keep: number): Srgb;
|
|
31
|
+
/** Every list holds a prime number (11) of schemes so a stride through it never repeats before the list is spent. */
|
|
32
|
+
export declare function schemesFor(kind: BuildingKind): readonly Scheme[];
|
|
33
|
+
/** FNV-1a over UTF-16 code units, then an avalanche. Stable across platforms: the restyle and its tests depend on it. */
|
|
34
|
+
export declare function hash32(text: string): number;
|
|
35
|
+
/**
|
|
36
|
+
* How many colourways a pool of prototypes gets, by how many buildings wear it (Granit: the three biggest pools are 1,498, 1,395 and
|
|
37
|
+
* 1,362 buildings; one colour for all of them is the grey city again). Each colourway is a distinct appearance (a material the
|
|
38
|
+
* renderer switches to) and a copy of the geometry (0.2 to 0.9 MB), so the ladder stops at 8 and a pool under 10 buildings stays one.
|
|
39
|
+
*/
|
|
40
|
+
export declare function variantCountFor(instances: number): number;
|
|
41
|
+
/** Which colourway building `entityId` wears: uniform over the prototype's variants, independent of every other building. */
|
|
42
|
+
export declare function variantIndex(entityId: number | string, variants: number): number;
|
|
43
|
+
/** Scheme of variant `k` of a prototype: a stride walk through the zone's list, so a prototype's variants never repeat. */
|
|
44
|
+
export declare function schemeOf(kind: BuildingKind, prototypeKey: string, k: number): Scheme;
|
|
45
|
+
/** A small deterministic value jitter (+-5 %) per prototype variant, so two variants with the same scheme still differ. */
|
|
46
|
+
export declare function jitterOf(prototypeKey: string, k: number): number;
|
|
47
|
+
/** Linear-light multipliers of a scheme's three colours, value-scaled by `jitter`. */
|
|
48
|
+
export declare function schemeLinear(scheme: Scheme, jitter?: number): [number, number, number][];
|
|
49
|
+
export interface TintResult {
|
|
50
|
+
/** RGBA, same size as the input; alpha untouched. */
|
|
51
|
+
data: Uint8Array;
|
|
52
|
+
/** Mean linear-light tinted / untinted over the opaque pixels, per channel: the colour a far mesh carries instead. */
|
|
53
|
+
ratio: [number, number, number];
|
|
54
|
+
/** Share of opaque pixels the mask colours. */
|
|
55
|
+
coverage: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* `albedo * (1 + sum_i w_i * (colour_i - 1))` in linear light, where `w` is the control mask's red/green/blue weight at the
|
|
59
|
+
* pixel (clamped so the three never sum past 1). Pixels outside the mask keep the captured albedo, which is how a window, a door or
|
|
60
|
+
* a painted-brick patch keeps its own colour. Both images are RGBA, the same size; `mask` may be RGB-only (alpha ignored).
|
|
61
|
+
*/
|
|
62
|
+
export declare function tintAlbedo(albedo: Uint8Array, mask: Uint8Array, linearColors: readonly [number, number, number][]): TintResult;
|
|
63
|
+
/** A vertex colour byte for a linear ratio. glTF `COLOR_0` is linear, so no transfer function. */
|
|
64
|
+
export declare const ratioToByte: (ratio: number) => number;
|
|
65
|
+
export interface FacadeLook {
|
|
66
|
+
/** Index into the engine's `FACADE_FAMILIES` (the CLI building generator's names are the base table). */
|
|
67
|
+
family: number;
|
|
68
|
+
familyName: string;
|
|
69
|
+
floorHeightM: number;
|
|
70
|
+
groundType: number;
|
|
71
|
+
bayWidthM: number;
|
|
72
|
+
windowRatio: number;
|
|
73
|
+
/** Tint palette index, 1..255 (0 is neutral). */
|
|
74
|
+
tint: number;
|
|
75
|
+
/** `_FACADE` lanes without the per-building seed (lane x low 10 bits) and height (lane w high byte): `facadeLanes` fills them. */
|
|
76
|
+
lanes: FacadeLanes;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The engine facade parameters for a prototype: a style family by zone and colourway, a floor height and bay width by
|
|
80
|
+
* zone, a glazed share by zone, and the tint palette entry that matches the colourway. `heightM` and `seed` are per
|
|
81
|
+
* building and go through `facadeLanes`. NOT yet consumed at the HLOD tiers: the shared-material pool replaces every
|
|
82
|
+
* cluster mesh's material (`hlod/resources.ts`), so a `HELIX_materials_city` primitive there is discarded.
|
|
83
|
+
*/
|
|
84
|
+
export declare function facadeLookFor(kind: BuildingKind, prototypeKey: string, k: number): FacadeLook;
|
|
85
|
+
/** `_FACADE` lanes of one building: its prototype's look plus its own height class and seed. */
|
|
86
|
+
export declare function facadeLanes(look: Pick<FacadeLook, 'family' | 'floorHeightM' | 'groundType' | 'bayWidthM' | 'windowRatio' | 'tint'>, heightM: number, seed: number): FacadeLanes;
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The look of a captured Cities: Skylines II building: which colours it wears and how a flat grey albedo takes them.
|
|
3
|
+
//
|
|
4
|
+
// WHY THIS EXISTS. CS2 draws a building from a NEUTRAL albedo (the captured `_BaseColorMap` has a median chroma of 0.7 of 255
|
|
5
|
+
// across the 315 Granit building maps) plus a `_ControlMask` whose red/green/blue regions the game fills, per instance, with a
|
|
6
|
+
// three-colour `ColorSet`. The exporter (`PacificaExportMod.cs`, `CaptureSurfaceMaterial`) keeps the base map only, the
|
|
7
|
+
// materials' `colors` and `vectors` are empty, and no placement record carries a colour (`placements.ts`
|
|
8
|
+
// PLACEMENT_RECORD_STRIDE = 4: prefab, entity, owner, depth). Rendered as captured every building is the same grey. This
|
|
9
|
+
// module is the missing half: a deterministic stand-in ColorSet per building, chosen from palettes that read like CS2's own
|
|
10
|
+
// (muted renders, brick, pastel plaster, glass and steel for offices, pale metal for industry), and the maths that applies it.
|
|
11
|
+
//
|
|
12
|
+
// TONED TO CS2. The first stand-in palette was far more saturated than the game: salmon, mint, teal and orange walls where the
|
|
13
|
+
// real Granit overview is mostly white, light grey, beige and tan with dull brick and a few subdued pastels (and grey-blue glass
|
|
14
|
+
// on offices). Every palette colour now goes through `muteColor`, a blend toward its own luminance grey (linear light, so a
|
|
15
|
+
// building keeps its brightness), with the saturated primaries pulled down harder. `CHROMA_KEEP` and `ACCENT_CHROMA_KEEP` are the two
|
|
16
|
+
// numbers; `buildingsLook.spec.ts` bounds the resulting mean saturation.
|
|
17
|
+
//
|
|
18
|
+
// Pure: no I/O, no three, no gltf-transform. `convert/buildingsRestyle.ts` does the files.
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.ratioToByte = exports.ACCENT_CHROMA_KEEP = exports.CHROMA_KEEP = void 0;
|
|
21
|
+
exports.prefabOfMaterialName = prefabOfMaterialName;
|
|
22
|
+
exports.classifyPrefab = classifyPrefab;
|
|
23
|
+
exports.muteColor = muteColor;
|
|
24
|
+
exports.schemesFor = schemesFor;
|
|
25
|
+
exports.hash32 = hash32;
|
|
26
|
+
exports.variantCountFor = variantCountFor;
|
|
27
|
+
exports.variantIndex = variantIndex;
|
|
28
|
+
exports.schemeOf = schemeOf;
|
|
29
|
+
exports.jitterOf = jitterOf;
|
|
30
|
+
exports.schemeLinear = schemeLinear;
|
|
31
|
+
exports.tintAlbedo = tintAlbedo;
|
|
32
|
+
exports.facadeLookFor = facadeLookFor;
|
|
33
|
+
exports.facadeLanes = facadeLanes;
|
|
34
|
+
const facade_1 = require("../city/buildings/facade");
|
|
35
|
+
/** `EU_ResidentialLow01_L5_2x2_<32 hex>` and `..._Win_<32 hex>` both reduce to the prefab's own name. */
|
|
36
|
+
function prefabOfMaterialName(materialName) {
|
|
37
|
+
return materialName.replace(/_[0-9a-f]{32}$/i, '').replace(/_(Win|Sub\d+)(_.*)?$/i, '');
|
|
38
|
+
}
|
|
39
|
+
function classifyPrefab(name) {
|
|
40
|
+
const prefab = prefabOfMaterialName(name);
|
|
41
|
+
const region = /^EU_/.test(prefab) ? 'EU' : /^NA_/.test(prefab) ? 'NA' : null;
|
|
42
|
+
const level = /_L(\d+)(?:_|$)/.exec(prefab)?.[1];
|
|
43
|
+
const density = /Low/.test(prefab) ? 'low' : /Medium/.test(prefab) ? 'medium' : /High/.test(prefab) ? 'high' : null;
|
|
44
|
+
let zone = 'civic';
|
|
45
|
+
if (/Extractor|Agricultur|Greenhouse|CattleShed|ChickenCoop|OilPump|OilDrilling|OreDrift|Forestry|Quarry|BucketWheel|Mine\d|Sawmill|Barn/i.test(prefab))
|
|
46
|
+
zone = 'rural';
|
|
47
|
+
else if (/Mixed/.test(prefab))
|
|
48
|
+
zone = 'mixed';
|
|
49
|
+
else if (/Residential/.test(prefab))
|
|
50
|
+
zone = 'residential';
|
|
51
|
+
else if (/Office/.test(prefab))
|
|
52
|
+
zone = 'office';
|
|
53
|
+
else if (/Industrial|Warehouse|Factory|Manufactur|Depot|CargoHarbor|CargoTrain|Powerplant|PowerPlant|Treatment|Recycling|Incinerat|Landfill|Pumping|Desalination/i.test(prefab))
|
|
54
|
+
zone = 'industrial';
|
|
55
|
+
else if (/Commercial|Shop|Supermarket|Mall|GasStation|Hotel|Restaurant|Cinema|Bank|Parking/i.test(prefab))
|
|
56
|
+
zone = 'commercial';
|
|
57
|
+
return { prefab, zone, density, region, level: level === undefined ? null : Number(level) };
|
|
58
|
+
}
|
|
59
|
+
const toLinear = (v) => (v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4);
|
|
60
|
+
const fromLinear = (v) => (v <= 0.0031308 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055);
|
|
61
|
+
/** Share of its own chroma every palette colour keeps (1 = the first, saturated stand-in; 0 = its luminance grey). */
|
|
62
|
+
exports.CHROMA_KEEP = 0.5;
|
|
63
|
+
/** The saturated primaries (red, orange, yellow, teal, green, blue) and the pinks and mints keep less: CS2 has almost none of them. */
|
|
64
|
+
exports.ACCENT_CHROMA_KEEP = 0.35;
|
|
65
|
+
/**
|
|
66
|
+
* Blend an sRGB colour toward its own luminance grey. Done in linear light on `Y = 0.2126 R + 0.7152 G + 0.0722 B`, so the colour keeps
|
|
67
|
+
* its luminance exactly (the albedo it multiplies keeps its brightness) and only the chroma shrinks, by `keep`.
|
|
68
|
+
*/
|
|
69
|
+
function muteColor([r, g, b], keep) {
|
|
70
|
+
const lin = [toLinear(r), toLinear(g), toLinear(b)];
|
|
71
|
+
const y = 0.2126 * lin[0] + 0.7152 * lin[1] + 0.0722 * lin[2];
|
|
72
|
+
const out = lin.map((v) => Math.min(1, Math.max(0, fromLinear(y + keep * (v - y)))));
|
|
73
|
+
return [out[0], out[1], out[2]];
|
|
74
|
+
}
|
|
75
|
+
const c = (r, g, b) => muteColor([r / 255, g / 255, b / 255], exports.CHROMA_KEEP);
|
|
76
|
+
const accent = (r, g, b) => muteColor([r / 255, g / 255, b / 255], exports.ACCENT_CHROMA_KEEP);
|
|
77
|
+
const scheme = (name, a, b, d) => ({ name, colors: [a, b, d] });
|
|
78
|
+
const CREAM = c(255, 240, 205), BUTTER = c(255, 232, 160), OCHRE = c(238, 196, 120), SAND = c(235, 215, 180), WHITE = c(250, 248, 242);
|
|
79
|
+
const BRICK = c(235, 130, 105), CLAY = c(220, 150, 120), TERRACOTTA = c(240, 150, 105), ROSE = accent(245, 190, 180), BROWN = c(170, 125, 100);
|
|
80
|
+
const SAGE = c(190, 220, 170), MINT = accent(180, 225, 200), SKY = c(170, 205, 245), POWDER = c(195, 215, 235), SLATE = c(140, 160, 185);
|
|
81
|
+
const STEEL = c(190, 200, 212), GREY = c(215, 215, 212), CHARCOAL = c(120, 124, 130), TEAL = accent(120, 190, 195), NAVY = c(95, 120, 165);
|
|
82
|
+
const RED = accent(235, 90, 80), GREEN = accent(110, 180, 120), YELLOW = accent(255, 215, 90), ORANGE = accent(250, 160, 80), BLUE = accent(100, 150, 230);
|
|
83
|
+
const RESIDENTIAL_EU = [
|
|
84
|
+
scheme('cream', CREAM, TERRACOTTA, BROWN), scheme('brick', BRICK, GREY, CHARCOAL), scheme('ochre', OCHRE, CLAY, WHITE),
|
|
85
|
+
scheme('white-plaster', WHITE, TERRACOTTA, SLATE), scheme('rose', ROSE, CREAM, BROWN), scheme('butter', BUTTER, BRICK, WHITE),
|
|
86
|
+
scheme('sage', SAGE, CREAM, BROWN), scheme('powder', POWDER, WHITE, CHARCOAL), scheme('sand', SAND, BRICK, WHITE),
|
|
87
|
+
scheme('terracotta', TERRACOTTA, CREAM, CHARCOAL), scheme('clay', CLAY, SAND, BROWN),
|
|
88
|
+
];
|
|
89
|
+
const RESIDENTIAL_NA = [
|
|
90
|
+
scheme('white-siding', WHITE, GREY, CHARCOAL), scheme('beige-siding', SAND, BROWN, WHITE), scheme('sage-siding', SAGE, WHITE, BROWN),
|
|
91
|
+
scheme('blue-siding', POWDER, WHITE, NAVY), scheme('brick', BRICK, CREAM, CHARCOAL), scheme('grey-siding', GREY, SLATE, WHITE),
|
|
92
|
+
scheme('butter-siding', BUTTER, WHITE, BROWN), scheme('clay-siding', CLAY, CREAM, CHARCOAL), scheme('mint-siding', MINT, WHITE, SLATE),
|
|
93
|
+
scheme('terracotta', TERRACOTTA, SAND, BROWN), scheme('taupe', c(205, 190, 175), WHITE, CHARCOAL),
|
|
94
|
+
];
|
|
95
|
+
const COMMERCIAL = [
|
|
96
|
+
scheme('white', WHITE, GREY, RED), scheme('light-grey', GREY, WHITE, BLUE), scheme('cream-red', CREAM, BRICK, RED),
|
|
97
|
+
scheme('sky', SKY, WHITE, NAVY), scheme('butter', BUTTER, WHITE, ORANGE), scheme('mint', MINT, WHITE, GREEN),
|
|
98
|
+
scheme('steel', STEEL, WHITE, YELLOW), scheme('sand', SAND, WHITE, TEAL), scheme('rose', ROSE, WHITE, CHARCOAL),
|
|
99
|
+
scheme('terracotta', TERRACOTTA, CREAM, BLUE), scheme('powder', POWDER, GREY, ORANGE),
|
|
100
|
+
];
|
|
101
|
+
const OFFICE = [
|
|
102
|
+
scheme('steel-blue', STEEL, SLATE, WHITE), scheme('glass-blue', c(150, 190, 235), STEEL, WHITE), scheme('glass-teal', TEAL, STEEL, WHITE),
|
|
103
|
+
scheme('graphite', c(150, 154, 160), STEEL, WHITE), scheme('white-curtain', WHITE, STEEL, SLATE), scheme('navy-glass', NAVY, STEEL, WHITE),
|
|
104
|
+
scheme('sand-stone', SAND, STEEL, CHARCOAL), scheme('glass-green', c(140, 200, 180), STEEL, WHITE), scheme('light-grey', GREY, SLATE, WHITE),
|
|
105
|
+
scheme('powder', POWDER, WHITE, NAVY), scheme('bronze', c(190, 165, 140), STEEL, CHARCOAL),
|
|
106
|
+
];
|
|
107
|
+
const INDUSTRIAL = [
|
|
108
|
+
scheme('pale-grey', GREY, STEEL, SLATE), scheme('blue-grey', c(175, 190, 205), GREY, NAVY), scheme('tan', c(220, 200, 165), GREY, BROWN),
|
|
109
|
+
scheme('olive', c(190, 195, 150), GREY, CHARCOAL), scheme('white-metal', WHITE, STEEL, BLUE), scheme('green-metal', c(160, 195, 165), GREY, GREEN),
|
|
110
|
+
scheme('red-door', GREY, STEEL, RED), scheme('sky-metal', SKY, GREY, SLATE), scheme('brick', c(205, 150, 130), GREY, CHARCOAL),
|
|
111
|
+
scheme('sand', SAND, STEEL, ORANGE), scheme('charcoal', c(150, 154, 158), STEEL, YELLOW),
|
|
112
|
+
];
|
|
113
|
+
const RURAL = [
|
|
114
|
+
scheme('barn-red', c(215, 105, 90), WHITE, CHARCOAL), scheme('white-barn', WHITE, c(190, 90, 80), CHARCOAL), scheme('weathered', c(185, 170, 150), GREY, BROWN),
|
|
115
|
+
scheme('sage-metal', c(175, 200, 170), GREY, CHARCOAL), scheme('tin', STEEL, GREY, SLATE), scheme('cream', CREAM, BRICK, BROWN),
|
|
116
|
+
scheme('ochre', OCHRE, GREY, BROWN), scheme('sky-metal', SKY, WHITE, SLATE), scheme('olive', c(190, 195, 150), GREY, BROWN),
|
|
117
|
+
scheme('silver', c(205, 210, 215), WHITE, CHARCOAL), scheme('green-barn', c(150, 190, 150), WHITE, CHARCOAL),
|
|
118
|
+
];
|
|
119
|
+
const CIVIC = [
|
|
120
|
+
scheme('limestone', c(240, 232, 215), SAND, SLATE), scheme('brick', BRICK, CREAM, CHARCOAL), scheme('white', WHITE, GREY, NAVY),
|
|
121
|
+
scheme('sandstone', c(235, 210, 170), CREAM, BROWN), scheme('grey-stone', GREY, STEEL, CHARCOAL), scheme('buff', c(235, 220, 185), BRICK, SLATE),
|
|
122
|
+
scheme('powder', POWDER, WHITE, SLATE), scheme('sage', SAGE, CREAM, CHARCOAL), scheme('rose-stone', ROSE, CREAM, BROWN),
|
|
123
|
+
scheme('terracotta', TERRACOTTA, SAND, CHARCOAL), scheme('pale-green', c(205, 225, 195), WHITE, SLATE),
|
|
124
|
+
];
|
|
125
|
+
/** Every list holds a prime number (11) of schemes so a stride through it never repeats before the list is spent. */
|
|
126
|
+
function schemesFor(kind) {
|
|
127
|
+
switch (kind.zone) {
|
|
128
|
+
case 'residential': return kind.region === 'NA' ? RESIDENTIAL_NA : RESIDENTIAL_EU;
|
|
129
|
+
case 'mixed': return kind.region === 'NA' ? RESIDENTIAL_NA : RESIDENTIAL_EU;
|
|
130
|
+
case 'commercial': return COMMERCIAL;
|
|
131
|
+
case 'office': return OFFICE;
|
|
132
|
+
case 'industrial': return INDUSTRIAL;
|
|
133
|
+
case 'rural': return RURAL;
|
|
134
|
+
default: return CIVIC;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// ------------------------------------------------------------------------------------------------------------ choosing
|
|
138
|
+
/** FNV-1a over UTF-16 code units, then an avalanche. Stable across platforms: the restyle and its tests depend on it. */
|
|
139
|
+
function hash32(text) {
|
|
140
|
+
let h = 0x811c9dc5;
|
|
141
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
142
|
+
h ^= text.charCodeAt(i);
|
|
143
|
+
h = Math.imul(h, 0x01000193);
|
|
144
|
+
}
|
|
145
|
+
h ^= h >>> 16;
|
|
146
|
+
h = Math.imul(h, 0x85ebca6b);
|
|
147
|
+
h ^= h >>> 13;
|
|
148
|
+
h = Math.imul(h, 0xc2b2ae35);
|
|
149
|
+
h ^= h >>> 16;
|
|
150
|
+
return h >>> 0;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* How many colourways a pool of prototypes gets, by how many buildings wear it (Granit: the three biggest pools are 1,498, 1,395 and
|
|
154
|
+
* 1,362 buildings; one colour for all of them is the grey city again). Each colourway is a distinct appearance (a material the
|
|
155
|
+
* renderer switches to) and a copy of the geometry (0.2 to 0.9 MB), so the ladder stops at 8 and a pool under 10 buildings stays one.
|
|
156
|
+
*/
|
|
157
|
+
function variantCountFor(instances) {
|
|
158
|
+
if (instances >= 1000)
|
|
159
|
+
return 8;
|
|
160
|
+
if (instances >= 300)
|
|
161
|
+
return 6;
|
|
162
|
+
if (instances >= 100)
|
|
163
|
+
return 4;
|
|
164
|
+
if (instances >= 40)
|
|
165
|
+
return 3;
|
|
166
|
+
if (instances >= 10)
|
|
167
|
+
return 2;
|
|
168
|
+
return 1;
|
|
169
|
+
}
|
|
170
|
+
/** Which colourway building `entityId` wears: uniform over the prototype's variants, independent of every other building. */
|
|
171
|
+
function variantIndex(entityId, variants) {
|
|
172
|
+
return variants <= 1 ? 0 : hash32(`building:${entityId}`) % variants;
|
|
173
|
+
}
|
|
174
|
+
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
|
|
175
|
+
/** Scheme of variant `k` of a prototype: a stride walk through the zone's list, so a prototype's variants never repeat. */
|
|
176
|
+
function schemeOf(kind, prototypeKey, k) {
|
|
177
|
+
const list = schemesFor(kind);
|
|
178
|
+
const h = hash32(`${kind.zone}:${prototypeKey}`);
|
|
179
|
+
let stride = 1 + ((h >>> 8) % (list.length - 1));
|
|
180
|
+
while (gcd(stride, list.length) !== 1)
|
|
181
|
+
stride += 1;
|
|
182
|
+
return list[(h + k * stride) % list.length];
|
|
183
|
+
}
|
|
184
|
+
/** A small deterministic value jitter (+-5 %) per prototype variant, so two variants with the same scheme still differ. */
|
|
185
|
+
function jitterOf(prototypeKey, k) {
|
|
186
|
+
return 0.95 + 0.1 * (hash32(`jitter:${prototypeKey}:${k}`) / 0xffffffff);
|
|
187
|
+
}
|
|
188
|
+
// -------------------------------------------------------------------------------------------------------- applying
|
|
189
|
+
const LINEAR_LUT = (() => { const lut = new Float32Array(256); for (let i = 0; i < 256; i += 1)
|
|
190
|
+
lut[i] = toLinear(i / 255); return lut; })();
|
|
191
|
+
/** Linear-light multipliers of a scheme's three colours, value-scaled by `jitter`. */
|
|
192
|
+
function schemeLinear(scheme, jitter = 1) {
|
|
193
|
+
return scheme.colors.map(([r, g, b]) => [Math.min(1, toLinear(r) * jitter), Math.min(1, toLinear(g) * jitter), Math.min(1, toLinear(b) * jitter)]);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* `albedo * (1 + sum_i w_i * (colour_i - 1))` in linear light, where `w` is the control mask's red/green/blue weight at the
|
|
197
|
+
* pixel (clamped so the three never sum past 1). Pixels outside the mask keep the captured albedo, which is how a window, a door or
|
|
198
|
+
* a painted-brick patch keeps its own colour. Both images are RGBA, the same size; `mask` may be RGB-only (alpha ignored).
|
|
199
|
+
*/
|
|
200
|
+
function tintAlbedo(albedo, mask, linearColors) {
|
|
201
|
+
if (albedo.length !== mask.length || albedo.length % 4)
|
|
202
|
+
throw new Error(`tintAlbedo: albedo (${albedo.length} B) and mask (${mask.length} B) must be the same RGBA size`);
|
|
203
|
+
const out = new Uint8Array(albedo.length);
|
|
204
|
+
const sumBefore = [0, 0, 0], sumAfter = [0, 0, 0];
|
|
205
|
+
let opaque = 0, covered = 0;
|
|
206
|
+
for (let i = 0; i < albedo.length; i += 4) {
|
|
207
|
+
let w0 = mask[i] / 255, w1 = mask[i + 1] / 255, w2 = mask[i + 2] / 255;
|
|
208
|
+
const total = w0 + w1 + w2;
|
|
209
|
+
if (total > 1) {
|
|
210
|
+
w0 /= total;
|
|
211
|
+
w1 /= total;
|
|
212
|
+
w2 /= total;
|
|
213
|
+
}
|
|
214
|
+
const lin = [LINEAR_LUT[albedo[i]], LINEAR_LUT[albedo[i + 1]], LINEAR_LUT[albedo[i + 2]]];
|
|
215
|
+
for (let ch = 0; ch < 3; ch += 1) {
|
|
216
|
+
const gain = 1 + w0 * (linearColors[0][ch] - 1) + w1 * (linearColors[1][ch] - 1) + w2 * (linearColors[2][ch] - 1);
|
|
217
|
+
const tinted = lin[ch] * gain;
|
|
218
|
+
out[i + ch] = Math.round(Math.min(1, Math.max(0, fromLinear(tinted))) * 255);
|
|
219
|
+
if (albedo[i + 3] >= 128) {
|
|
220
|
+
sumBefore[ch] += lin[ch];
|
|
221
|
+
sumAfter[ch] += tinted;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
out[i + 3] = albedo[i + 3];
|
|
225
|
+
if (albedo[i + 3] >= 128) {
|
|
226
|
+
opaque += 1;
|
|
227
|
+
if (w0 + w1 + w2 > 0.5)
|
|
228
|
+
covered += 1;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const ratio = sumBefore.map((before, ch) => (before > 1e-9 ? Math.min(1, sumAfter[ch] / before) : 1));
|
|
232
|
+
return { data: out, ratio, coverage: opaque ? covered / opaque : 0 };
|
|
233
|
+
}
|
|
234
|
+
/** A vertex colour byte for a linear ratio. glTF `COLOR_0` is linear, so no transfer function. */
|
|
235
|
+
const ratioToByte = (ratio) => Math.round(Math.min(1, Math.max(0, ratio)) * 255);
|
|
236
|
+
exports.ratioToByte = ratioToByte;
|
|
237
|
+
const FAMILY_BY_ZONE = {
|
|
238
|
+
residential: ['brick-red', 'brick-buff', 'white-render', 'stucco', 'terracotta', 'brick-brown', 'limestone'],
|
|
239
|
+
mixed: ['brick-buff', 'stucco', 'limestone', 'brick-red', 'white-render', 'party-brick'],
|
|
240
|
+
commercial: ['white-render', 'concrete-punched', 'ribbon-white', 'limestone', 'stucco', 'glass-grey'],
|
|
241
|
+
office: ['glass-blue', 'glass-grey', 'glass-green', 'ribbon-white', 'ribbon-concrete', 'concrete-punched'],
|
|
242
|
+
industrial: ['warehouse-metal', 'industrial-ribbon', 'warehouse-brick', 'ribbon-concrete'],
|
|
243
|
+
rural: ['warehouse-metal', 'warehouse-brick', 'white-render'],
|
|
244
|
+
civic: ['civic-limestone', 'limestone', 'brick-buff', 'white-render'],
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* The engine facade parameters for a prototype: a style family by zone and colourway, a floor height and bay width by
|
|
248
|
+
* zone, a glazed share by zone, and the tint palette entry that matches the colourway. `heightM` and `seed` are per
|
|
249
|
+
* building and go through `facadeLanes`. NOT yet consumed at the HLOD tiers: the shared-material pool replaces every
|
|
250
|
+
* cluster mesh's material (`hlod/resources.ts`), so a `HELIX_materials_city` primitive there is discarded.
|
|
251
|
+
*/
|
|
252
|
+
function facadeLookFor(kind, prototypeKey, k) {
|
|
253
|
+
const families = FAMILY_BY_ZONE[kind.zone];
|
|
254
|
+
const h = hash32(`facade:${prototypeKey}:${k}`);
|
|
255
|
+
const familyName = families[h % families.length];
|
|
256
|
+
const family = facade_1.FACADE_FAMILY_NAMES.indexOf(familyName);
|
|
257
|
+
const floorHeightM = kind.zone === 'industrial' || kind.zone === 'rural' ? 5.5 : kind.zone === 'office' ? 3.8 : kind.zone === 'commercial' ? 3.6 : 3.1;
|
|
258
|
+
const bayWidthM = kind.zone === 'office' ? 1.5 : kind.zone === 'industrial' || kind.zone === 'rural' ? 6 : kind.zone === 'commercial' ? 3.4 : 2.9;
|
|
259
|
+
const windowRatio = kind.zone === 'office' ? 0.8 : kind.zone === 'commercial' ? 0.55 : kind.zone === 'industrial' || kind.zone === 'rural' ? 0.12 : 0.42;
|
|
260
|
+
const groundType = kind.zone === 'commercial' || kind.zone === 'mixed' ? facade_1.GROUND_TYPE.STOREFRONT : kind.zone === 'office' ? facade_1.GROUND_TYPE.LOBBY
|
|
261
|
+
: kind.zone === 'residential' ? facade_1.GROUND_TYPE.RESIDENTIAL : facade_1.GROUND_TYPE.BLANK;
|
|
262
|
+
const tint = 1 + ((h >>> 9) % 255);
|
|
263
|
+
const look = { family, familyName, floorHeightM, groundType, bayWidthM, windowRatio, tint };
|
|
264
|
+
return { ...look, lanes: facadeLanes(look, 0, 0) };
|
|
265
|
+
}
|
|
266
|
+
/** `_FACADE` lanes of one building: its prototype's look plus its own height class and seed. */
|
|
267
|
+
function facadeLanes(look, heightM, seed) {
|
|
268
|
+
return (0, facade_1.packFacade)({
|
|
269
|
+
family: look.family, seed: seed & 1023, floorHeightM: look.floorHeightM, groundType: look.groundType, groundExtraM: look.groundType === facade_1.GROUND_TYPE.STOREFRONT ? 0.75 : 0,
|
|
270
|
+
bayWidthM: look.bayWidthM, windowRatio: look.windowRatio, tint: look.tint, heightM,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=buildingsLook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildingsLook.js","sourceRoot":"","sources":["../../src/cs2/buildingsLook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* `helix cs2 restyle-buildings`: gives the captured Granit buildings their colour back. See `buildingsRestyle.ts` for what
|
|
4
|
+
* it writes. The caller attaches it to the `cs2` group `src/index.ts` already registers (or to any `Command`).
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerCs2RestyleBuildings(parent: Command, fail: (message: string) => never): void;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.registerCs2RestyleBuildings = registerCs2RestyleBuildings;
|
|
37
|
+
/**
|
|
38
|
+
* `helix cs2 restyle-buildings`: gives the captured Granit buildings their colour back. See `buildingsRestyle.ts` for what
|
|
39
|
+
* it writes. The caller attaches it to the `cs2` group `src/index.ts` already registers (or to any `Command`).
|
|
40
|
+
*/
|
|
41
|
+
function registerCs2RestyleBuildings(parent, fail) {
|
|
42
|
+
parent
|
|
43
|
+
.command('restyle-buildings')
|
|
44
|
+
.description('Restyle the captured Granit buildings (KTX2 near models in colourways, per-building colour on the far tiers) into an overlay data folder')
|
|
45
|
+
.argument('<dataFolder>', 'the shared granit-data/public folder (read only)')
|
|
46
|
+
.requiredOption('--out <dir>', 'overlay folder to write: buildings/ plus restyle/ (point GRANIT_DATA at it)')
|
|
47
|
+
.option('--stage <stage>', 'prototypes, clusters or all (default all)', 'all')
|
|
48
|
+
.option('--shard <i/n>', 'prototypes stage only: this process takes every n-th prototype starting at i, e.g. 0/4')
|
|
49
|
+
.option('--limit <n>', 'prototypes stage only: stop after n prototypes (a trial)')
|
|
50
|
+
.option('--only <text...>', 'prototypes stage only: only prototypes whose source uri contains one of these')
|
|
51
|
+
.option('--json', 'machine-readable report')
|
|
52
|
+
.action(async (dataFolder, opts) => {
|
|
53
|
+
try {
|
|
54
|
+
if (!['prototypes', 'clusters', 'all'].includes(opts.stage))
|
|
55
|
+
fail(`✖ --stage must be prototypes, clusters or all, got '${opts.stage}'`);
|
|
56
|
+
let shard;
|
|
57
|
+
if (opts.shard) {
|
|
58
|
+
const match = /^(\d+)\/(\d+)$/.exec(opts.shard);
|
|
59
|
+
if (!match || Number(match[2]) < 1 || Number(match[1]) >= Number(match[2]))
|
|
60
|
+
fail(`✖ --shard must be i/n with 0 <= i < n, got '${opts.shard}'`);
|
|
61
|
+
shard = { index: Number(match[1]), count: Number(match[2]) };
|
|
62
|
+
}
|
|
63
|
+
const { restylePrototypes, restyleClusters } = await Promise.resolve().then(() => __importStar(require('./buildingsRestyle')));
|
|
64
|
+
const log = (message) => console.error(message);
|
|
65
|
+
const common = { data: dataFolder, out: opts.out, log };
|
|
66
|
+
let prototypes;
|
|
67
|
+
if (opts.stage === 'prototypes' || opts.stage === 'all') {
|
|
68
|
+
prototypes = (await restylePrototypes({ ...common, ...(shard ? { shard } : {}), ...(opts.limit ? { limit: Number(opts.limit) } : {}), ...(opts.only ? { only: opts.only } : {}) })).length;
|
|
69
|
+
}
|
|
70
|
+
let report;
|
|
71
|
+
if (opts.stage === 'clusters' || opts.stage === 'all')
|
|
72
|
+
report = await restyleClusters(common);
|
|
73
|
+
console.log(opts.json ? JSON.stringify({ prototypes, report }, null, 2) : `✔ ${opts.out}${prototypes === undefined ? '' : `\n prototypes restyled ${prototypes}`}${report ? '\n clusters stage written (see restyle/report.json)' : ''}`);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
fail(`✖ ${error instanceof Error ? error.message : String(error)}`);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=buildingsCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildingsCommand.js","sourceRoot":"","sources":["../../../src/cs2/convert/buildingsCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { NodeIO, type Material, type Texture } from '@gltf-transform/core';
|
|
2
|
+
import { type FacadeLook } from '../buildingsLook';
|
|
3
|
+
export declare const RESTYLE_SCHEMA = "helix.cs2-building-look/1";
|
|
4
|
+
export interface RestyleOptions {
|
|
5
|
+
/** The shared `granit-data/public` folder. Read only. */
|
|
6
|
+
data: string;
|
|
7
|
+
/** The overlay folder to write. */
|
|
8
|
+
out: string;
|
|
9
|
+
log?: (message: string) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface TextureFile {
|
|
12
|
+
/** `tex-<first 24 hex of sha256>.ktx2`: the name a GLB references and the file under `buildings/hlod/textures/`. */
|
|
13
|
+
name: string;
|
|
14
|
+
sha256: string;
|
|
15
|
+
bytes: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
}
|
|
19
|
+
export interface PrototypeVariant {
|
|
20
|
+
k: number;
|
|
21
|
+
/** Relative to `buildings/`, e.g. `hlod/prototypes/<sha>.glb`. */
|
|
22
|
+
uri: string;
|
|
23
|
+
sha256: string;
|
|
24
|
+
bytes: number;
|
|
25
|
+
scheme: string;
|
|
26
|
+
/** Linear-light mean tint of the body materials: the far meshes' vertex colour. */
|
|
27
|
+
ratio: [number, number, number];
|
|
28
|
+
coverage: number;
|
|
29
|
+
facade: FacadeLook;
|
|
30
|
+
/** The shared KTX2 files this GLB references, by content. */
|
|
31
|
+
textures: TextureFile[];
|
|
32
|
+
}
|
|
33
|
+
export interface PrototypeRecord {
|
|
34
|
+
/** The data folder's own prototype uri: the key every document resource is matched by. */
|
|
35
|
+
sourceUri: string;
|
|
36
|
+
prefab: string;
|
|
37
|
+
zone: string;
|
|
38
|
+
/** Buildings that wear this prototype, and every building that wears a prototype sharing its albedo (the colourway pool). */
|
|
39
|
+
instances: number;
|
|
40
|
+
groupInstances: number;
|
|
41
|
+
group: string;
|
|
42
|
+
variants: PrototypeVariant[];
|
|
43
|
+
/** Prototypes whose materials had no control mask: tinted nothing, only re-encoded. */
|
|
44
|
+
masked: boolean;
|
|
45
|
+
}
|
|
46
|
+
interface DocResource {
|
|
47
|
+
id: string;
|
|
48
|
+
kind: string;
|
|
49
|
+
source: {
|
|
50
|
+
kind: string;
|
|
51
|
+
assetId?: string;
|
|
52
|
+
uri: string;
|
|
53
|
+
};
|
|
54
|
+
integrity: {
|
|
55
|
+
sha256: string;
|
|
56
|
+
};
|
|
57
|
+
bytes: number;
|
|
58
|
+
mimeType?: string;
|
|
59
|
+
required?: boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare const textureFileName: (digest: string) => string;
|
|
62
|
+
interface MaterialBundle {
|
|
63
|
+
dir: string;
|
|
64
|
+
byAssetName: Map<string, {
|
|
65
|
+
textures: Record<string, string>;
|
|
66
|
+
}>;
|
|
67
|
+
files: Map<string, string>;
|
|
68
|
+
}
|
|
69
|
+
/** The albedo pool a prototype belongs to: prototypes whose body albedo and control mask are the same bytes (L1..L5 of one model) share colourways. */
|
|
70
|
+
export declare function prototypeGroup(io: NodeIO, bundle: MaterialBundle, file: string): Promise<string>;
|
|
71
|
+
/** `prototypes` stage: writes GLBs and shared KTX2 files for this shard's colourway pools and `<out>/restyle/prototypes.shard-<i>.json`. */
|
|
72
|
+
export declare function restylePrototypes(options: RestyleOptions & {
|
|
73
|
+
shard?: {
|
|
74
|
+
index: number;
|
|
75
|
+
count: number;
|
|
76
|
+
};
|
|
77
|
+
limit?: number;
|
|
78
|
+
only?: string[];
|
|
79
|
+
}): Promise<PrototypeRecord[]>;
|
|
80
|
+
/**
|
|
81
|
+
* The engine's material pool (`load/materialPool.ts`) keys on every enumerable state of a freshly parsed material, `name`
|
|
82
|
+
* included, so two prototypes whose materials draw identically but carry their own prefab-hash names never merge. A material
|
|
83
|
+
* is named for what it draws with: its factors and the shared texture files it samples. Equal appearance, equal name.
|
|
84
|
+
*/
|
|
85
|
+
export declare function nameMaterialsByContent(materials: Material[], files: Map<Texture, TextureFile>): void;
|
|
86
|
+
export interface ClustersReport {
|
|
87
|
+
parts: {
|
|
88
|
+
id: string;
|
|
89
|
+
file: string;
|
|
90
|
+
documentBytes: number;
|
|
91
|
+
nodes: number;
|
|
92
|
+
resources: number;
|
|
93
|
+
remappedNodes: number;
|
|
94
|
+
newResources: number;
|
|
95
|
+
}[];
|
|
96
|
+
clusters: {
|
|
97
|
+
mass: number;
|
|
98
|
+
refinement: number;
|
|
99
|
+
carriers: number;
|
|
100
|
+
};
|
|
101
|
+
massVertices: number;
|
|
102
|
+
refinementVertices: number;
|
|
103
|
+
estimatedBytesAdded: {
|
|
104
|
+
mass: number;
|
|
105
|
+
refinement: number;
|
|
106
|
+
};
|
|
107
|
+
documentCapBytes: number;
|
|
108
|
+
prototypes: {
|
|
109
|
+
count: number;
|
|
110
|
+
variants: number;
|
|
111
|
+
sourceBytes: number;
|
|
112
|
+
geometryBytes: number;
|
|
113
|
+
};
|
|
114
|
+
/** Distinct shared KTX2 files across every colourway, their bytes, and their transcoded GPU size (8 bpp with mips, once each). */
|
|
115
|
+
textures: {
|
|
116
|
+
files: number;
|
|
117
|
+
bytes: number;
|
|
118
|
+
gpuBytes: number;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** `clusters` stage: needs every `prototypes.shard-*.json` under `<out>/restyle`. Writes the cluster GLBs, carriers, documents and index. */
|
|
122
|
+
export declare function restyleClusters(options: RestyleOptions): Promise<ClustersReport>;
|
|
123
|
+
/** Adds `COLOR_0` (u8 normalised RGB, per vertex from its source building) to every primitive of one cluster GLB and writes it. */
|
|
124
|
+
export declare function recolourCluster(io: NodeIO, dir: string, outDir: string, resource: DocResource, colourOf: (sourceIndex: number) => [number, number, number]): Promise<{
|
|
125
|
+
vertices: number;
|
|
126
|
+
addedEstimate: number;
|
|
127
|
+
}>;
|
|
128
|
+
export {};
|