Feature: Track connection boundaries in junction footprints

This commit is contained in:
2026-05-13 17:04:45 +02:00
parent 48d487e0e9
commit 8a99a68068

View File

@@ -30,6 +30,7 @@ export interface SplineCorridorJunctionFootprintPoint {
z: number; z: number;
fallbackY: number; fallbackY: number;
heightOffset: number; heightOffset: number;
connectionBoundaryKey: string | null;
} }
export interface SplineCorridorJunctionFootprint { export interface SplineCorridorJunctionFootprint {
@@ -107,15 +108,24 @@ function createFootprintPoint(options: {
leftAxis: { x: number; z: number }; leftAxis: { x: number; z: number };
offset: number; offset: number;
heightOffset: number; heightOffset: number;
connectionBoundaryKey: string;
}): SplineCorridorJunctionFootprintPoint { }): SplineCorridorJunctionFootprintPoint {
return { return {
x: options.position.x + options.leftAxis.x * options.offset, x: options.position.x + options.leftAxis.x * options.offset,
z: options.position.z + options.leftAxis.z * options.offset, z: options.position.z + options.leftAxis.z * options.offset,
fallbackY: options.position.y + options.heightOffset, fallbackY: options.position.y + options.heightOffset,
heightOffset: options.heightOffset heightOffset: options.heightOffset,
connectionBoundaryKey: options.connectionBoundaryKey
}; };
} }
function createConnectionBoundaryKey(options: {
pathId: string;
distance: number;
}): string {
return `${options.pathId}:${Math.round(options.distance * 100000)}`;
}
function addConnectionBoundaryPoints(options: { function addConnectionBoundaryPoints(options: {
points: SplineCorridorJunctionFootprintPoint[]; points: SplineCorridorJunctionFootprintPoint[];
path: SplineCorridorJunctionFootprintPathLike; path: SplineCorridorJunctionFootprintPathLike;
@@ -184,19 +194,25 @@ function addConnectionBoundaryPoints(options: {
x: -tangent.z, x: -tangent.z,
z: tangent.x z: tangent.x
}; };
const connectionBoundaryKey = createConnectionBoundaryKey({
pathId: options.path.id,
distance
});
options.points.push( options.points.push(
createFootprintPoint({ createFootprintPoint({
position, position,
leftAxis: localLeftAxis, leftAxis: localLeftAxis,
offset: halfWidth, offset: halfWidth,
heightOffset heightOffset,
connectionBoundaryKey
}), }),
createFootprintPoint({ createFootprintPoint({
position, position,
leftAxis: localLeftAxis, leftAxis: localLeftAxis,
offset: -halfWidth, offset: -halfWidth,
heightOffset heightOffset,
connectionBoundaryKey
}) })
); );
} }
@@ -236,6 +252,10 @@ function dedupePoints(
existing.fallbackY = (existing.fallbackY + point.fallbackY) * 0.5; existing.fallbackY = (existing.fallbackY + point.fallbackY) * 0.5;
existing.heightOffset = (existing.heightOffset + point.heightOffset) * 0.5; existing.heightOffset = (existing.heightOffset + point.heightOffset) * 0.5;
existing.connectionBoundaryKey =
existing.connectionBoundaryKey === point.connectionBoundaryKey
? existing.connectionBoundaryKey
: null;
} }
return deduped; return deduped;
@@ -346,7 +366,8 @@ function buildCircularFootprint(options: {
x: options.junction.center.x + Math.cos(angle) * options.junction.radius, x: options.junction.center.x + Math.cos(angle) * options.junction.radius,
z: options.junction.center.z + Math.sin(angle) * options.junction.radius, z: options.junction.center.z + Math.sin(angle) * options.junction.radius,
fallbackY: options.fallbackY, fallbackY: options.fallbackY,
heightOffset: options.heightOffset heightOffset: options.heightOffset,
connectionBoundaryKey: null
}); });
} }
@@ -361,7 +382,8 @@ function buildCircularFootprint(options: {
x: options.junction.center.x, x: options.junction.center.x,
z: options.junction.center.z, z: options.junction.center.z,
fallbackY: options.fallbackY, fallbackY: options.fallbackY,
heightOffset: options.heightOffset heightOffset: options.heightOffset,
connectionBoundaryKey: null
}, },
points, points,
forwardAxis: options.forwardAxis, forwardAxis: options.forwardAxis,
@@ -432,7 +454,8 @@ export function buildSplineCorridorJunctionFootprint(options: {
x: junction.center.x, x: junction.center.x,
z: junction.center.z, z: junction.center.z,
fallbackY, fallbackY,
heightOffset heightOffset,
connectionBoundaryKey: null
}; };
if (hull.length < 3 || !isPointInsidePolygonXZ(centerPoint.x, centerPoint.z, hull)) { if (hull.length < 3 || !isPointInsidePolygonXZ(centerPoint.x, centerPoint.z, hull)) {
@@ -456,6 +479,16 @@ export function buildSplineCorridorJunctionFootprint(options: {
}; };
} }
export function isSplineCorridorJunctionFootprintRoadMouthEdge(
start: SplineCorridorJunctionFootprintPoint,
end: SplineCorridorJunctionFootprintPoint
): boolean {
return (
start.connectionBoundaryKey !== null &&
start.connectionBoundaryKey === end.connectionBoundaryKey
);
}
function getDistanceToSegmentXZ(options: { function getDistanceToSegmentXZ(options: {
x: number; x: number;
z: number; z: number;