Handle road mouth segments and add profile caps to junction edges
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
|||||||
} from "../document/terrains";
|
} from "../document/terrains";
|
||||||
import {
|
import {
|
||||||
buildSplineCorridorJunctionFootprint,
|
buildSplineCorridorJunctionFootprint,
|
||||||
|
isSplineCorridorJunctionFootprintRoadMouthEdge,
|
||||||
type SplineCorridorJunctionFootprint,
|
type SplineCorridorJunctionFootprint,
|
||||||
type SplineCorridorJunctionFootprintPoint,
|
type SplineCorridorJunctionFootprintPoint,
|
||||||
type SplineCorridorJunctionFootprintPathLike
|
type SplineCorridorJunctionFootprintPathLike
|
||||||
@@ -214,6 +215,44 @@ function getPerimeterDistances(
|
|||||||
return distances;
|
return distances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addJunctionEdgeProfileCap(options: {
|
||||||
|
indices: number[];
|
||||||
|
rowOffset: number;
|
||||||
|
profileVertexCount: number;
|
||||||
|
reverse: boolean;
|
||||||
|
}) {
|
||||||
|
if (options.profileVertexCount < 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let index = 1; index < options.profileVertexCount - 1; index += 1) {
|
||||||
|
if (options.reverse) {
|
||||||
|
options.indices.push(
|
||||||
|
options.rowOffset,
|
||||||
|
options.rowOffset + index + 1,
|
||||||
|
options.rowOffset + index
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
options.indices.push(
|
||||||
|
options.rowOffset,
|
||||||
|
options.rowOffset + index,
|
||||||
|
options.rowOffset + index + 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRoadMouthSegment(
|
||||||
|
points: readonly SplineCorridorJunctionFootprintPoint[],
|
||||||
|
index: number
|
||||||
|
): boolean {
|
||||||
|
return isSplineCorridorJunctionFootprintRoadMouthEdge(
|
||||||
|
points[index]!,
|
||||||
|
points[(index + 1) % points.length]!
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function buildSplineCorridorJunctionEdgeMeshData(options: {
|
export function buildSplineCorridorJunctionEdgeMeshData(options: {
|
||||||
junction: SplineCorridorJunction;
|
junction: SplineCorridorJunction;
|
||||||
paths: readonly SplineCorridorJunctionMeshPathLike[];
|
paths: readonly SplineCorridorJunctionMeshPathLike[];
|
||||||
@@ -290,6 +329,10 @@ export function buildSplineCorridorJunctionEdgeMeshData(options: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let pointIndex = 0; pointIndex < footprint.points.length; pointIndex += 1) {
|
for (let pointIndex = 0; pointIndex < footprint.points.length; pointIndex += 1) {
|
||||||
|
if (isRoadMouthSegment(footprint.points, pointIndex)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const currentRow = pointIndex * profile.length;
|
const currentRow = pointIndex * profile.length;
|
||||||
const nextRow = currentRow + profile.length;
|
const nextRow = currentRow + profile.length;
|
||||||
|
|
||||||
@@ -301,6 +344,28 @@ export function buildSplineCorridorJunctionEdgeMeshData(options: {
|
|||||||
|
|
||||||
indices.push(current, currentNext, next, next, currentNext, nextNext);
|
indices.push(current, currentNext, next, next, currentNext, nextNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const previousSegmentIndex =
|
||||||
|
(pointIndex - 1 + footprint.points.length) % footprint.points.length;
|
||||||
|
const nextSegmentIndex = (pointIndex + 1) % footprint.points.length;
|
||||||
|
|
||||||
|
if (isRoadMouthSegment(footprint.points, previousSegmentIndex)) {
|
||||||
|
addJunctionEdgeProfileCap({
|
||||||
|
indices,
|
||||||
|
rowOffset: currentRow,
|
||||||
|
profileVertexCount: profile.length,
|
||||||
|
reverse: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRoadMouthSegment(footprint.points, nextSegmentIndex)) {
|
||||||
|
addJunctionEdgeProfileCap({
|
||||||
|
indices,
|
||||||
|
rowOffset: nextRow,
|
||||||
|
profileVertexCount: profile.length,
|
||||||
|
reverse: false
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user