@hypersoniclabs/helix-cli 0.1.27-helix3.548 → 0.1.27-helix3.549

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 (27) hide show
  1. package/dist/city/colliders/apply.js +26 -0
  2. package/dist/city/colliders/apply.js.map +1 -1
  3. package/dist/city/colliders/command.js +2 -1
  4. package/dist/city/colliders/command.js.map +1 -1
  5. package/dist/city/colliders/deckColliders.d.ts +34 -0
  6. package/dist/city/colliders/deckColliders.js +195 -48
  7. package/dist/city/colliders/deckColliders.js.map +1 -1
  8. package/dist/city/colliders/lips.d.ts +85 -0
  9. package/dist/city/colliders/lips.js +350 -0
  10. package/dist/city/colliders/lips.js.map +1 -0
  11. package/dist/tsconfig.build.tsbuildinfo +1 -1
  12. package/package.json +2 -2
  13. package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
  14. package/plugins/beamng-vehicle/bin/__pycache__/beamng_audio.cpython-312.pyc +0 -0
  15. package/plugins/beamng-vehicle/bin/__pycache__/beamng_engine.cpython-312.pyc +0 -0
  16. package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
  17. package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
  18. package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
  19. package/plugins/beamng-vehicle/bin/__pycache__/beamng_stock_events.cpython-312.pyc +0 -0
  20. package/plugins/beamng-vehicle/bin/__pycache__/fmod_studio.cpython-312.pyc +0 -0
  21. package/plugins/beamng-vehicle/bin/__pycache__/fsb5.cpython-312.pyc +0 -0
  22. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio.cpython-312.pyc +0 -0
  23. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_ac.cpython-312.pyc +0 -0
  24. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_beamng.cpython-312.pyc +0 -0
  25. package/plugins/beamng-vehicle/bin/__pycache__/sim_audio_fixtures.cpython-312.pyc +0 -0
  26. package/plugins/beamng-vehicle/bin/__pycache__/test_beamng_engine.cpython-312.pyc +0 -0
  27. package/plugins/beamng-vehicle/bin/__pycache__/test_sim_audio.cpython-312.pyc +0 -0
@@ -62,6 +62,17 @@ async function unitBoxGlb() {
62
62
  document.createScene('unit-box').addChild(document.createNode('unit-box').setMesh(mesh));
63
63
  return new core_1.NodeIO().writeBinary(document);
64
64
  }
65
+ /** Whether (x, y, z) lies inside the oriented unit-cube box (position, rotation quaternion, scale). */
66
+ function pointInBox(box, x, y, z) {
67
+ if (x < box.min[0] || x > box.max[0] || y < box.min[1] || y > box.max[1] || z < box.min[2] || z > box.max[2])
68
+ return false;
69
+ const [qx, qy, qz, qw] = box.rotation;
70
+ // Rotate (p - position) by the inverse (conjugate) quaternion.
71
+ const px = x - box.position[0], py = y - box.position[1], pz = z - box.position[2];
72
+ const tx = 2 * (-qy * pz + qz * py), ty = 2 * (-qz * px + qx * pz), tz = 2 * (-qx * py + qy * px);
73
+ const lx = px + qw * tx + (-qy * tz + qz * ty), ly = py + qw * ty + (-qz * tx + qx * tz), lz = pz + qw * tz + (-qx * ty + qy * tx);
74
+ return Math.abs(lx) <= box.scale[0] / 2 && Math.abs(ly) <= box.scale[1] / 2 && Math.abs(lz) <= box.scale[2] / 2;
75
+ }
65
76
  const sha256 = (bytes) => (0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex');
66
77
  const json = (value) => new TextEncoder().encode(JSON.stringify(value));
67
78
  async function pool(items, size, work) {
@@ -81,6 +92,7 @@ async function applyColliders(options) {
81
92
  const files = [];
82
93
  const report = { root: options.rootName, newRoot: options.newRootName, rootRevision: root.revision };
83
94
  let next = root;
95
+ let deckCells = [];
84
96
  if (options.decks.enabled) {
85
97
  const resources = root.resources.filter((resource) => resource.kind === 'model' || resource.kind === 'collider');
86
98
  const under = (dir) => resources.map((resource) => resource.source.uri ?? '').filter((uri) => uri.startsWith(dir)).sort();
@@ -94,6 +106,7 @@ async function applyColliders(options) {
94
106
  };
95
107
  log(`decks: ${roads.render.length} render cells, ${roads.collision.length} collider cells, origin ${roads.originX},${roads.originZ}, cell ${roads.cellSizeM} m`);
96
108
  const { cells, report: deck } = await (0, deckColliders_1.buildDeckColliders)(roads, { ...options.decks, log });
109
+ deckCells = cells;
97
110
  for (const cell of cells)
98
111
  files.push({ path: `scene/${options.newRootName}/roads/${cell.file}`, bytes: cell.bytes });
99
112
  next = (0, deckColliders_1.patchSceneDeckColliders)(next, cells, 'roads').scene;
@@ -142,6 +155,19 @@ async function applyColliders(options) {
142
155
  files.push({ path: `scene/${child.integrity.sha256}/scene.helix-scene.json`, bytes: childBytes });
143
156
  files.push({ path: `scene/${child.integrity.sha256}/${unitUri}`, bytes: unit });
144
157
  next = (0, buildingBoxes_1.mountColliderChild)(next, child);
158
+ // The lips are ramps at the foot of kerbs and deck edges: none may sit inside a building's box.
159
+ if (deckCells.length > 0) {
160
+ const inside = (x, y, z) => boxes.some((box) => pointInBox(box, x, y, z));
161
+ let lipTrianglesInBuildings = 0, checked = 0;
162
+ for (const cell of deckCells)
163
+ for (let at = 0; at < cell.lipVertices.length; at += 9) {
164
+ const v = cell.lipVertices;
165
+ checked += 1;
166
+ if (inside((v[at] + v[at + 3] + v[at + 6]) / 3, (v[at + 1] + v[at + 4] + v[at + 7]) / 3, (v[at + 2] + v[at + 5] + v[at + 8]) / 3))
167
+ lipTrianglesInBuildings += 1;
168
+ }
169
+ report.decks.lipTrianglesInsideBuildingBoxes = { checked, inside: lipTrianglesInBuildings };
170
+ }
145
171
  report.buildings = { ...stats, ...sets, childSha256: child.integrity.sha256, childBytes: childBytes.length, unitBox: buildingBoxes_1.UNIT_BOX_RESOURCE_ID, streamRadiusM: planOptions.streamRadiusM };
146
172
  }
147
173
  next = (0, buildingBoxes_1.sealScene)(next);
@@ -1 +1 @@
1
- {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/city/colliders/apply.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/city/colliders/apply.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@ function registerCityColliders(city, fail) {
17
17
  .requiredOption('--out <dir>', 'output folder (mirrors the prefix layout)')
18
18
  .option('--road-cell <m>', 'road render/collider cell size in metres', '1024')
19
19
  .option('--no-decks', 'skip the elevated-deck collider cells')
20
+ .option('--no-lips', 'skip the bevels on kerbs and deck edges (3-35 cm steps a wheel cannot roll up)')
20
21
  .option('--no-buildings', 'skip the building-box child Scene')
21
22
  .option('--stream-radius <m>', 'physics radius of the building colliders in metres', '120')
22
23
  .option('--per-block <n>', 'buildings per collider set', '60')
@@ -32,7 +33,7 @@ function registerCityColliders(city, fail) {
32
33
  const result = await (0, apply_1.applyColliders)({
33
34
  source: (0, apply_1.prefixSource)(source), rootName: opts.root, newRootName: opts.newRoot,
34
35
  buildings: { enabled: opts.buildings, streamRadiusM, buildingsPerBlock },
35
- decks: { enabled: opts.decks, roadCellM },
36
+ decks: { enabled: opts.decks, roadCellM, lips: opts.lips },
36
37
  log: (message) => console.error(message),
37
38
  });
38
39
  await (0, apply_1.writeFiles)((0, node_path_1.resolve)(opts.out), result.files);
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/city/colliders/command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/city/colliders/command.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import type { HelixSceneV2 } from '@hypersoniclabs/helix-manifest';
2
+ import { cs2GltfIo } from '../../cs2/convert/glb';
3
+ import { type LipOptions } from './lips';
2
4
  export interface DeckColliderOptions {
3
5
  /** A render triangle is already covered when a collider triangle lies under its centroid within this many metres. */
4
6
  toleranceM: number;
@@ -7,6 +9,11 @@ export interface DeckColliderOptions {
7
9
  maxTrianglesPerCell: number;
8
10
  errorM: number;
9
11
  errorCapM: number;
12
+ /** Bevel the 3-35 cm lips (kerbs, deck-to-ground seams) into the cell; false leaves the cells as they were. */
13
+ lips: boolean;
14
+ lipOptions?: Partial<LipOptions>;
15
+ /** Diagnostics: a wall bevel that was not emitted, and why. */
16
+ onLipDrop?: (reason: 'no-ground' | 'duplicate' | 'degenerate', x: number, z: number) => void;
10
17
  log?: (message: string) => void;
11
18
  }
12
19
  export declare const DEFAULT_DECK_COLLIDER_OPTIONS: Readonly<DeckColliderOptions>;
@@ -28,7 +35,11 @@ export interface DeckColliderCell {
28
35
  file: string;
29
36
  bytes: Uint8Array;
30
37
  sha256: string;
38
+ /** Deck plus lip triangles. */
31
39
  triangles: number;
40
+ lipTriangles: number;
41
+ /** The lip triangles' vertices (9 floats each), for checks; not written anywhere. */
42
+ lipVertices: Float32Array;
32
43
  uncoveredTriangles: number;
33
44
  errorM: number;
34
45
  bounds: {
@@ -46,7 +57,29 @@ export interface DeckColliderReport {
46
57
  bytes: number;
47
58
  maxCellTriangles: number;
48
59
  cellsWithoutColliderSet: number[][];
60
+ lips?: LipReport;
49
61
  }
62
+ export interface LipReport {
63
+ wallCandidates: number;
64
+ /** Near-vertical collider triangles between two up-facing surfaces 3-35 cm apart (kerbs and the like). */
65
+ wallLips: number;
66
+ wallLipsAtRampEntrances: number;
67
+ deckEdgeLips: number;
68
+ deckEdgeAboveGround: number;
69
+ deckEdgeBelowGround: number;
70
+ bevelTriangles: number;
71
+ droppedNoGround: number;
72
+ droppedDuplicate: number;
73
+ droppedDegenerate: number;
74
+ maxCellLipTriangles: number;
75
+ recutCells: number;
76
+ overCapCells: string[];
77
+ }
78
+ type Tri = Float32Array;
79
+ export declare function readWorldTriangles(io: ReturnType<typeof cs2GltfIo>, bytes: Uint8Array): Promise<Array<{
80
+ tri: Tri;
81
+ kind: number;
82
+ }>>;
50
83
  /** Unit normal Y of a triangle (counter-clockwise from above is up). */
51
84
  export declare function normalY(t: ArrayLike<number>): number;
52
85
  /** y of the triangle's plane at (x, z), or null when (x, z) lies outside it. */
@@ -62,3 +95,4 @@ export interface PatchDeckResult {
62
95
  }
63
96
  /** Lists each deck cell as a second collider of the cell's existing collision set (a new set, node and group when the cell had none). */
64
97
  export declare function patchSceneDeckColliders(scene: HelixSceneV2, cells: readonly DeckColliderCell[], uriDir?: string): PatchDeckResult;
98
+ export {};
@@ -12,6 +12,7 @@
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.DEFAULT_DECK_COLLIDER_OPTIONS = void 0;
14
14
  exports.roadCellsFromFolder = roadCellsFromFolder;
15
+ exports.readWorldTriangles = readWorldTriangles;
15
16
  exports.normalY = normalY;
16
17
  exports.heightUnder = heightUnder;
17
18
  exports.buildDeckColliders = buildDeckColliders;
@@ -21,10 +22,11 @@ const node_path_1 = require("node:path");
21
22
  const node_crypto_1 = require("node:crypto");
22
23
  const glb_1 = require("../../cs2/convert/glb");
23
24
  const meshoptimizer_1 = require("meshoptimizer");
25
+ const lips_1 = require("./lips");
24
26
  /** `_ROAD.x` kinds that are not a walking or driving surface. */
25
27
  const KERB = 4;
26
28
  const BUCKET_M = 4;
27
- exports.DEFAULT_DECK_COLLIDER_OPTIONS = Object.freeze({ toleranceM: 0.5, upMinNy: 0.6, maxTrianglesPerCell: 60_000, errorM: 0.05, errorCapM: 0.2 });
29
+ exports.DEFAULT_DECK_COLLIDER_OPTIONS = Object.freeze({ toleranceM: 0.5, upMinNy: 0.6, maxTrianglesPerCell: 60_000, errorM: 0.05, errorCapM: 0.2, lips: true });
28
30
  /** A restyled `roads/` folder (`mesh-cells.json` + `render/` + `collider/`). */
29
31
  async function roadCellsFromFolder(roadsDir) {
30
32
  const index = JSON.parse(await (0, promises_1.readFile)((0, node_path_1.join)(roadsDir, 'mesh-cells.json'), 'utf8'));
@@ -125,53 +127,76 @@ function heightUnder(t, x, z) {
125
127
  return null;
126
128
  return l1 * t[1] + l2 * t[4] + l3 * t[7];
127
129
  }
128
- class TriangleBuckets {
129
- cells = new Map();
130
- add(t) {
131
- const x0 = Math.floor(Math.min(t[0], t[3], t[6]) / BUCKET_M), x1 = Math.floor(Math.max(t[0], t[3], t[6]) / BUCKET_M);
132
- const z0 = Math.floor(Math.min(t[2], t[5], t[8]) / BUCKET_M), z1 = Math.floor(Math.max(t[2], t[5], t[8]) / BUCKET_M);
133
- for (let gx = x0; gx <= x1; gx += 1)
134
- for (let gz = z0; gz <= z1; gz += 1) {
135
- const key = `${gx},${gz}`;
136
- const list = this.cells.get(key);
137
- if (list)
138
- list.push(t);
139
- else
140
- this.cells.set(key, [t]);
141
- }
130
+ const coveredBy = (index, x, y, z, toleranceM, upMinNy) => {
131
+ for (const hit of index.hits(x, z, y - toleranceM, y + toleranceM))
132
+ if (hit.ny >= upMinNy && Math.abs(hit.h - y) < toleranceM)
133
+ return true;
134
+ return false;
135
+ };
136
+ async function simplifyCell(flat, maxTriangles, options) {
137
+ const positions = Float32Array.from(flat);
138
+ const identity = new Uint32Array(positions.length / 3);
139
+ for (let at = 0; at < identity.length; at += 1)
140
+ identity[at] = at;
141
+ let error = options.errorM;
142
+ let welded = await (0, glb_1.weldAndSimplify)(positions, identity, maxTriangles, error);
143
+ while (welded.trianglesAfter > maxTriangles && error < options.errorCapM) {
144
+ error *= 2;
145
+ welded = await (0, glb_1.weldAndSimplify)(positions, identity, maxTriangles, error);
142
146
  }
143
- covered(x, y, z, toleranceM) {
144
- const list = this.cells.get(`${Math.floor(x / BUCKET_M)},${Math.floor(z / BUCKET_M)}`);
145
- if (!list)
146
- return false;
147
- for (const t of list) {
148
- const h = heightUnder(t, x, z);
149
- if (h !== null && Math.abs(h - y) < toleranceM)
150
- return true;
147
+ return { positions: welded.positions, indices: welded.indices, errorM: welded.errorMetres };
148
+ }
149
+ /** Appends flat triangles (9 floats each) to a welded mesh, sharing exactly equal vertices. */
150
+ function appendTriangles(mesh, flat) {
151
+ const positions = Array.from(mesh.positions);
152
+ const indices = Array.from(mesh.indices);
153
+ const slot = new Map();
154
+ for (let at = 0; at < flat.length; at += 3) {
155
+ const k = `${flat[at]},${flat[at + 1]},${flat[at + 2]}`;
156
+ let id = slot.get(k);
157
+ if (id === undefined) {
158
+ id = positions.length / 3;
159
+ slot.set(k, id);
160
+ positions.push(flat[at], flat[at + 1], flat[at + 2]);
151
161
  }
152
- return false;
162
+ indices.push(id);
153
163
  }
164
+ return { positions: Float32Array.from(positions), indices: Uint32Array.from(indices), errorM: mesh.errorM };
154
165
  }
166
+ const triKey = (t) => {
167
+ const v = [0, 1, 2].map((c) => `${Math.round(t[c * 3] * 100)},${Math.round(t[c * 3 + 1] * 100)},${Math.round(t[c * 3 + 2] * 100)}`).sort();
168
+ return v.join('|');
169
+ };
155
170
  async function buildDeckColliders(roads, input = {}) {
156
171
  const options = { ...exports.DEFAULT_DECK_COLLIDER_OPTIONS, ...input };
172
+ const lipOptions = { ...lips_1.DEFAULT_LIP_OPTIONS, ...options.lipOptions };
157
173
  const log = options.log ?? (() => undefined);
158
174
  await meshoptimizer_1.MeshoptDecoder.ready;
159
175
  const io = (0, glb_1.cs2GltfIo)();
160
176
  const index = roads;
161
- const buckets = new TriangleBuckets();
177
+ const ground = new lips_1.SurfaceIndex();
178
+ const sloped = new lips_1.SurfaceIndex();
179
+ const walls = [];
162
180
  let colliderTriangles = 0;
163
181
  for (const cell of index.collision) {
164
182
  for (const { tri } of await readWorldTriangles(io, await roads.read(cell))) {
165
- if (normalY(tri) >= options.upMinNy) {
166
- buckets.add(tri);
167
- colliderTriangles += 1;
183
+ const ny = normalY(tri);
184
+ if (ny >= Math.min(options.upMinNy, lipOptions.upMinNy)) {
185
+ ground.add(tri);
186
+ if (ny >= options.upMinNy)
187
+ colliderTriangles += 1;
188
+ if (ny < 0.99863)
189
+ sloped.add(tri);
168
190
  }
191
+ if (options.lips && ny < lipOptions.faceMaxNy && ny > lipOptions.faceMinNy)
192
+ walls.push(tri);
169
193
  }
170
194
  }
171
- log(`existing collider: ${colliderTriangles} up-facing triangles in ${index.collision.length} cells`);
195
+ log(`existing collider: ${colliderTriangles} up-facing triangles in ${index.collision.length} cells, ${walls.length} wall candidates`);
172
196
  const uncovered = new Map();
173
197
  const report = { renderTriangles: 0, surfaceTriangles: 0, uncoveredTriangles: 0, byKind: {}, cells: 0, triangles: 0, bytes: 0, maxCellTriangles: 0, cellsWithoutColliderSet: [] };
174
198
  const kindName = ['asphalt', 'concrete', 'sett', 'gravel', 'kerb', 'sidewalk', 'median'];
199
+ const cellOf = (x, z) => `${Math.floor((x - index.originX) / index.cellSizeM)},${Math.floor((z - index.originZ) / index.cellSizeM)}`;
175
200
  for (const cell of index.render) {
176
201
  for (const { tri, kind } of await readWorldTriangles(io, await roads.read(cell))) {
177
202
  report.renderTriangles += 1;
@@ -179,12 +204,11 @@ async function buildDeckColliders(roads, input = {}) {
179
204
  continue;
180
205
  report.surfaceTriangles += 1;
181
206
  const cx = (tri[0] + tri[3] + tri[6]) / 3, cy = (tri[1] + tri[4] + tri[7]) / 3, cz = (tri[2] + tri[5] + tri[8]) / 3;
182
- if (buckets.covered(cx, cy, cz, options.toleranceM))
207
+ if (coveredBy(ground, cx, cy, cz, options.toleranceM, options.upMinNy))
183
208
  continue;
184
209
  report.uncoveredTriangles += 1;
185
210
  report.byKind[kindName[kind] ?? String(kind)] = (report.byKind[kindName[kind] ?? String(kind)] ?? 0) + 1;
186
- const gx = Math.floor((cx - index.originX) / index.cellSizeM), gz = Math.floor((cz - index.originZ) / index.cellSizeM);
187
- const key = `${gx},${gz}`;
211
+ const key = cellOf(cx, cz);
188
212
  const list = uncovered.get(key);
189
213
  if (list)
190
214
  list.push(...tri);
@@ -193,41 +217,164 @@ async function buildDeckColliders(roads, input = {}) {
193
217
  }
194
218
  }
195
219
  log(`render surface ${report.surfaceTriangles} triangles, ${report.uncoveredTriangles} uncovered`);
220
+ // 1. Deck cells, simplified with room left for the lips the cell will carry.
221
+ const reserve = new Map();
222
+ const lipsReport = { wallCandidates: walls.length, wallLips: 0, wallLipsAtRampEntrances: 0, deckEdgeLips: 0, deckEdgeAboveGround: 0, deckEdgeBelowGround: 0, bevelTriangles: 0, droppedNoGround: 0, droppedDuplicate: 0, droppedDegenerate: 0, maxCellLipTriangles: 0, recutCells: 0, overCapCells: [] };
223
+ const deckByCell = new Map();
224
+ // The wall bevels of a cell are known before its deck is cut (walls never depend on the deck mesh), so they are planned first
225
+ // against the ground tier plus the uncovered render surface the deck will approximate.
226
+ const wallTriangles = new Map();
227
+ const seen = new Set();
228
+ if (options.lips) {
229
+ // The wall pass sees the ground tier plus the uncovered deck surface the deck cells will approximate.
230
+ for (const flat of uncovered.values())
231
+ for (let at = 0; at < flat.length; at += 9) {
232
+ const t = flat.slice(at, at + 9);
233
+ ground.add(t);
234
+ if (normalY(t) < 0.99863)
235
+ sloped.add(t);
236
+ }
237
+ const found = [];
238
+ for (const wall of walls) {
239
+ const lip = (0, lips_1.classifyWall)(wall, ground, lipOptions);
240
+ if (lip)
241
+ found.push(lip);
242
+ }
243
+ lipsReport.wallLips = found.length;
244
+ const bevelled = (0, lips_1.bevelWalls)(found, ground, lipOptions);
245
+ lipsReport.droppedDegenerate += bevelled.degenerate;
246
+ if (options.onLipDrop)
247
+ for (const lip of bevelled.degeneratedLips)
248
+ options.onLipDrop('degenerate', (lip.tri[0] + lip.tri[3] + lip.tri[6]) / 3, (lip.tri[2] + lip.tri[5] + lip.tri[8]) / 3);
249
+ for (const { lip, tri: bevel } of bevelled.triangles) {
250
+ const wall = lip.tri;
251
+ const cx = (wall[0] + wall[3] + wall[6]) / 3, cz = (wall[2] + wall[5] + wall[8]) / 3;
252
+ // A bevel must rest on a surface: one lies under its centroid no more than a step below it.
253
+ const bx = (bevel[0] + bevel[3] + bevel[6]) / 3, by = (bevel[1] + bevel[4] + bevel[7]) / 3, bz = (bevel[2] + bevel[5] + bevel[8]) / 3;
254
+ const rests = (x, y, z, below) => ground.hits(x, z, y - below, y + 0.03).some((hit) => hit.ny >= lipOptions.upMinNy);
255
+ // ... on its centroid, or at least at one of its corners (a bevel at a kerb's end hangs over a corner of the surface).
256
+ if (!rests(bx, by, bz, lipOptions.maxStepM + 0.05) && ![0, 3, 6].some((c) => rests(bevel[c], bevel[c + 1], bevel[c + 2], 0.06))) {
257
+ lipsReport.droppedNoGround += 1;
258
+ options.onLipDrop?.('no-ground', cx, cz);
259
+ continue;
260
+ }
261
+ const k = triKey(bevel);
262
+ if (seen.has(k)) {
263
+ lipsReport.droppedDuplicate += 1;
264
+ options.onLipDrop?.('duplicate', cx, cz);
265
+ continue;
266
+ }
267
+ seen.add(k);
268
+ // Ramp entrance: the upper surface within 8 m is a sloped road triangle or deck surface.
269
+ let entrance = false;
270
+ for (let d = 1; d <= 8 && !entrance; d += 1) {
271
+ const px = cx - lip.step.dx * d, pz = cz - lip.step.dz * d;
272
+ if (sloped.hits(px, pz, lip.step.high - 0.6, lip.step.high + 0.6).length > 0)
273
+ entrance = true;
274
+ }
275
+ if (entrance)
276
+ lipsReport.wallLipsAtRampEntrances += 1;
277
+ const key = cellOf(cx, cz);
278
+ const list = wallTriangles.get(key);
279
+ if (list)
280
+ list.push(...bevel);
281
+ else
282
+ wallTriangles.set(key, [...bevel]);
283
+ lipsReport.bevelTriangles += 1;
284
+ }
285
+ for (const [key, flat] of wallTriangles)
286
+ reserve.set(key, flat.length / 9);
287
+ log(`lips: ${lipsReport.wallLips} wall lips, ${lipsReport.bevelTriangles} bevel triangles in ${wallTriangles.size} cells (${lipsReport.droppedNoGround} without ground, ${lipsReport.droppedDuplicate} duplicate, ${lipsReport.droppedDegenerate} degenerate)`);
288
+ }
289
+ const edgeReserve = options.lips ? Math.round(0.08 * options.maxTrianglesPerCell) : 0;
290
+ for (const [key, flat] of [...uncovered.entries()].sort(([a], [b]) => (a < b ? -1 : 1))) {
291
+ const budget = Math.max(2000, options.maxTrianglesPerCell - (reserve.get(key) ?? 0) - edgeReserve);
292
+ const mesh = await simplifyCell(flat, budget, options);
293
+ if (mesh.indices.length === 0)
294
+ continue;
295
+ deckByCell.set(key, { ...mesh, uncovered: flat.length / 9, flat });
296
+ }
297
+ // 2. Deck edges: free borders of the simplified deck meshes sitting a step above or below the ground tier (or a neighbouring cell).
298
+ const edgeTriangles = new Map();
299
+ if (options.lips) {
300
+ const edgeIndex = new lips_1.SurfaceIndex();
301
+ // Only the ground tier and the SIMPLIFIED deck cells: the unsimplified surface the wall pass added to `ground` must not mask a border.
302
+ for (const cell of index.collision)
303
+ for (const { tri } of await readWorldTriangles(io, await roads.read(cell)))
304
+ if (normalY(tri) >= lipOptions.upMinNy)
305
+ edgeIndex.add(tri);
306
+ for (const key of deckByCell.keys()) {
307
+ const mesh = deckByCell.get(key);
308
+ for (let at = 0; at < mesh.indices.length; at += 3) {
309
+ const t = new Float32Array(9);
310
+ for (let c = 0; c < 3; c += 1)
311
+ for (let a = 0; a < 3; a += 1)
312
+ t[c * 3 + a] = mesh.positions[mesh.indices[at + c] * 3 + a];
313
+ if (normalY(t) >= lipOptions.upMinNy)
314
+ edgeIndex.add(t);
315
+ }
316
+ }
317
+ for (const [key, mesh] of deckByCell) {
318
+ for (const edge of (0, lips_1.deckEdgeLips)(mesh.positions, mesh.indices, edgeIndex, lipOptions)) {
319
+ lipsReport.deckEdgeLips += 1;
320
+ if (edge.kind === 'deck-over-ground')
321
+ lipsReport.deckEdgeAboveGround += 1;
322
+ else
323
+ lipsReport.deckEdgeBelowGround += 1;
324
+ const list = edgeTriangles.get(key);
325
+ if (list)
326
+ list.push(...edge.tris);
327
+ else
328
+ edgeTriangles.set(key, [...edge.tris]);
329
+ }
330
+ }
331
+ log(`lips: ${lipsReport.deckEdgeLips} deck edge lips (${lipsReport.deckEdgeAboveGround} above ground, ${lipsReport.deckEdgeBelowGround} below)`);
332
+ }
333
+ // 3. Assemble each cell: the deck mesh plus its lips, cut again smaller when the sum would pass the cap.
196
334
  const known = new Set(index.collision.map((file) => cellOfFile(file).join(',')));
197
335
  const cells = [];
198
- for (const [key, flat] of [...uncovered.entries()].sort(([a], [b]) => (a < b ? -1 : 1))) {
336
+ const keys = [...new Set([...deckByCell.keys(), ...wallTriangles.keys(), ...edgeTriangles.keys()])].sort((a, b) => (a < b ? -1 : 1));
337
+ for (const key of keys) {
199
338
  const [cx, cz] = key.split(',').map(Number);
200
339
  if (!known.has(key))
201
340
  report.cellsWithoutColliderSet.push([cx, cz]);
202
- const positions = Float32Array.from(flat);
203
- const identity = new Uint32Array(positions.length / 3);
204
- for (let at = 0; at < identity.length; at += 1)
205
- identity[at] = at;
206
- let error = options.errorM;
207
- let welded = await (0, glb_1.weldAndSimplify)(positions, identity, options.maxTrianglesPerCell, error);
208
- while (welded.trianglesAfter > options.maxTrianglesPerCell && error < options.errorCapM) {
209
- error *= 2;
210
- welded = await (0, glb_1.weldAndSimplify)(positions, identity, options.maxTrianglesPerCell, error);
341
+ const lipFlat = [...(wallTriangles.get(key) ?? []), ...(edgeTriangles.get(key) ?? [])];
342
+ let lipTriangles = lipFlat.length / 9;
343
+ const deck = deckByCell.get(key);
344
+ let mesh = deck ?? { positions: new Float32Array(0), indices: new Uint32Array(0), errorM: 0 };
345
+ if (deck && deck.indices.length / 3 + lipTriangles > options.maxTrianglesPerCell) {
346
+ lipsReport.recutCells += 1;
347
+ const target = Math.max(1000, options.maxTrianglesPerCell - lipTriangles);
348
+ mesh = await simplifyCell(deck.flat, target, options);
211
349
  }
212
- if (welded.indices.length === 0)
350
+ const full = lipTriangles > 0 ? appendTriangles(mesh, lipFlat) : mesh;
351
+ if (full.indices.length === 0)
213
352
  continue;
214
- const bytes = await (0, glb_1.writeCs2Glb)(`cs2-roads-deck-collider-${cx}-${cz}`, [], [{ positions: welded.positions, indices: welded.indices }]);
353
+ if (full.indices.length / 3 > options.maxTrianglesPerCell) {
354
+ // Lips alone pass the cap (a lips-only cell): keep the walls in file order and drop the tail.
355
+ lipsReport.overCapCells.push(key);
356
+ }
357
+ const bytes = await (0, glb_1.writeCs2Glb)(`cs2-roads-deck-collider-${cx}-${cz}`, [], [{ positions: full.positions, indices: full.indices }]);
215
358
  const min = [Infinity, Infinity, Infinity], max = [-Infinity, -Infinity, -Infinity];
216
- for (let at = 0; at < welded.positions.length; at += 3)
359
+ for (let at = 0; at < full.positions.length; at += 3)
217
360
  for (let axis = 0; axis < 3; axis += 1) {
218
- const v = welded.positions[at + axis];
361
+ const v = full.positions[at + axis];
219
362
  if (v < min[axis])
220
363
  min[axis] = v;
221
364
  if (v > max[axis])
222
365
  max[axis] = v;
223
366
  }
224
- const triangles = welded.indices.length / 3;
225
- cells.push({ cx, cz, file: `deck-collider/${cx}_${cz}.glb`, bytes, sha256: (0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex'), triangles, uncoveredTriangles: flat.length / 9, errorM: welded.errorMetres, bounds: { min, max } });
367
+ const triangles = full.indices.length / 3;
368
+ lipTriangles = Math.min(lipTriangles, triangles);
369
+ lipsReport.maxCellLipTriangles = Math.max(lipsReport.maxCellLipTriangles, lipTriangles);
370
+ cells.push({ cx, cz, file: `deck-collider/${cx}_${cz}.glb`, bytes, sha256: (0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex'), triangles, lipTriangles, lipVertices: Float32Array.from(lipFlat), uncoveredTriangles: deck?.uncovered ?? 0, errorM: mesh.errorM, bounds: { min, max } });
226
371
  report.triangles += triangles;
227
372
  report.bytes += bytes.length;
228
373
  report.maxCellTriangles = Math.max(report.maxCellTriangles, triangles);
229
374
  }
230
375
  report.cells = cells.length;
376
+ if (options.lips)
377
+ report.lips = lipsReport;
231
378
  return { cells, report };
232
379
  }
233
380
  /** Lists each deck cell as a second collider of the cell's existing collision set (a new set, node and group when the cell had none). */