Feature: Track connection boundaries in junction footprints
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user