|
1 | 1 | import assert from 'assert'; |
2 | 2 | import Point from "@mapbox/point-geometry"; |
3 | | -import {ElevationPolygons, ElevationPortalGraph, type ElevationPortalEdge, type ElevationPortalType, type LeveledPolygon} from "./elevation_graph"; |
| 3 | +import {ElevationPortalGraph, type ElevationPortalEdge, type ElevationPortalType} from "./elevation_graph"; |
4 | 4 | import {vec2, vec3} from "gl-matrix"; |
5 | 5 | import {tileToMeter} from '../../src/geo/mercator_coordinate'; |
6 | 6 | import EXTENT from '../../src/style-spec/data/extent'; |
@@ -167,7 +167,6 @@ export class ElevatedStructures { |
167 | 167 | shadowCasterSegments: SegmentVector | undefined; |
168 | 168 |
|
169 | 169 | unevaluatedPortals = new ElevationPortalGraph(); |
170 | | - portalPolygons = new ElevationPolygons(); |
171 | 170 |
|
172 | 171 | // Tracks the rail/tunnel mesh same-feature vertex sections |
173 | 172 | // (within ElevatedStructure::vertexPositions). |
@@ -276,60 +275,62 @@ export class ElevatedStructures { |
276 | 275 | } |
277 | 276 | } |
278 | 277 |
|
279 | | - addPortalCandidates(id: number, polygon: Point[][], isTunnel: boolean, elevation: ElevationFeature, zLevel: number) { |
280 | | - if (polygon.length === 0) return; |
281 | | - |
282 | | - const leveledPoly: LeveledPolygon = {geometry: polygon, zLevel}; |
283 | | - this.portalPolygons.add(id, leveledPoly); |
| 278 | + addPortalCandidates(id: number, polygons: Point[][][], isTunnel: boolean, elevation: ElevationFeature, zLevel: number) { |
| 279 | + if (polygons.length === 0) return; |
284 | 280 |
|
285 | 281 | const pointsEqual = (a: Point, b: Point) => a.x === b.x && a.y === b.y; |
286 | 282 |
|
287 | | - // Each edge of the exterior ring is a potential portal |
288 | | - const exterior = polygon[0]; |
289 | | - assert(exterior.length > 1 && pointsEqual(exterior[0], exterior[exterior.length - 1])); |
290 | | - |
291 | 283 | this.vertexHashLookup.clear(); |
292 | 284 |
|
293 | | - let prevEdgeHash = ElevatedStructures.computeEdgeHash(exterior[exterior.length - 2], exterior[exterior.length - 1]); |
| 285 | + for (const polygon of polygons) { |
| 286 | + if (polygon.length === 0) { |
| 287 | + continue; |
| 288 | + } |
| 289 | + // Each edge of the exterior ring is a potential portal |
| 290 | + const exterior = polygon[0]; |
| 291 | + assert(exterior.length > 1 && pointsEqual(exterior[0], exterior[exterior.length - 1])); |
| 292 | + |
| 293 | + let prevEdgeHash = ElevatedStructures.computeEdgeHash(exterior[exterior.length - 2], exterior[exterior.length - 1]); |
294 | 294 |
|
295 | | - for (let i = 0; i < exterior.length - 1; i++) { |
296 | | - const a = exterior[i + 0]; |
297 | | - const b = exterior[i + 1]; |
| 295 | + for (let i = 0; i < exterior.length - 1; i++) { |
| 296 | + const a = exterior[i + 0]; |
| 297 | + const b = exterior[i + 1]; |
298 | 298 |
|
299 | | - const vavb = vec2.fromValues(b.x - a.x, b.y - a.y); |
300 | | - const length = vec2.length(vavb); |
| 299 | + const vavb = vec2.fromValues(b.x - a.x, b.y - a.y); |
| 300 | + const length = vec2.length(vavb); |
301 | 301 |
|
302 | | - if (length === 0) continue; |
| 302 | + if (length === 0) continue; |
303 | 303 |
|
304 | | - let type: ElevationPortalType = 'unevaluated'; |
| 304 | + let type: ElevationPortalType = 'unevaluated'; |
305 | 305 |
|
306 | | - // "Entrance" portals are entry & exit points for the polygons |
307 | | - // from ground level |
308 | | - const ha = elevation.pointElevation(a); |
309 | | - const hb = elevation.pointElevation(b); |
310 | | - const onGround = Math.abs(ha) < 0.01 && Math.abs(hb) < 0.01; |
| 306 | + // "Entrance" portals are entry & exit points for the polygons |
| 307 | + // from ground level |
| 308 | + const ha = elevation.pointElevation(a); |
| 309 | + const hb = elevation.pointElevation(b); |
| 310 | + const onGround = Math.abs(ha) < 0.01 && Math.abs(hb) < 0.01; |
311 | 311 |
|
312 | | - if (onGround) { |
313 | | - type = 'entrance'; |
314 | | - } else { |
315 | | - // Portals on tile borders describes connectivity between tiles |
316 | | - if (this.isOnBorder(a.x, b.x) || this.isOnBorder(a.y, b.y)) { |
317 | | - type = 'border'; |
| 312 | + if (onGround) { |
| 313 | + type = 'entrance'; |
| 314 | + } else { |
| 315 | + // Portals on tile borders describes connectivity between tiles |
| 316 | + if (this.isOnBorder(a.x, b.x) || this.isOnBorder(a.y, b.y)) { |
| 317 | + type = 'border'; |
| 318 | + } |
318 | 319 | } |
319 | | - } |
320 | 320 |
|
321 | | - const edgeHash = ElevatedStructures.computeEdgeHash(a, b); |
322 | | - this.unevaluatedPortals.portals.push({ |
323 | | - connection: {a: id, b: undefined}, va: a, vb: b, vab: vavb, length, hash: edgeHash, isTunnel, type |
324 | | - }); |
| 321 | + const edgeHash = ElevatedStructures.computeEdgeHash(a, b); |
| 322 | + this.unevaluatedPortals.portals.push({ |
| 323 | + connection: {a: id, b: undefined}, va: a, vb: b, vab: vavb, length, hash: edgeHash, isTunnel, type |
| 324 | + }); |
325 | 325 |
|
326 | | - // Construct a lookup table where vertex position maps to hashes of edges it's connected to |
327 | | - const posHash = ElevatedStructures.computePosHash(a); |
| 326 | + // Construct a lookup table where vertex position maps to hashes of edges it's connected to |
| 327 | + const posHash = ElevatedStructures.computePosHash(a); |
328 | 328 |
|
329 | | - assert(!this.vertexHashLookup.has(posHash)); |
330 | | - this.vertexHashLookup.set(posHash, {prev: prevEdgeHash, next: edgeHash}); |
| 329 | + assert(!this.vertexHashLookup.has(posHash)); |
| 330 | + this.vertexHashLookup.set(posHash, {prev: prevEdgeHash, next: edgeHash}); |
331 | 331 |
|
332 | | - prevEdgeHash = edgeHash; |
| 332 | + prevEdgeHash = edgeHash; |
| 333 | + } |
333 | 334 | } |
334 | 335 | } |
335 | 336 |
|
|
0 commit comments