Implement support for clipping road mesh geometry using visible station runs
This commit is contained in:
@@ -415,6 +415,7 @@ function addEdgeProfileCaps(options: {
|
|||||||
export function buildSplineRoadMeshData(options: {
|
export function buildSplineRoadMeshData(options: {
|
||||||
path: SplineRoadPathLike;
|
path: SplineRoadPathLike;
|
||||||
terrains?: readonly Terrain[];
|
terrains?: readonly Terrain[];
|
||||||
|
clipIntervals?: readonly SplineCorridorPathClipInterval[];
|
||||||
}): SplineRoadMeshData | null {
|
}): SplineRoadMeshData | null {
|
||||||
const { path } = options;
|
const { path } = options;
|
||||||
const terrains = options.terrains ?? [];
|
const terrains = options.terrains ?? [];
|
||||||
@@ -428,44 +429,59 @@ export function buildSplineRoadMeshData(options: {
|
|||||||
const uvs: number[] = [];
|
const uvs: number[] = [];
|
||||||
const indices: number[] = [];
|
const indices: number[] = [];
|
||||||
const halfWidth = path.road.width * 0.5;
|
const halfWidth = path.road.width * 0.5;
|
||||||
|
const stationRuns = buildVisibleRoadStationRuns(
|
||||||
|
stations,
|
||||||
|
options.clipIntervals ?? []
|
||||||
|
);
|
||||||
|
let stationCount = 0;
|
||||||
|
|
||||||
for (let index = 0; index < stations.length; index += 1) {
|
for (const run of stationRuns) {
|
||||||
const station = stations[index]!;
|
const runVertexOffset = positions.length / 3;
|
||||||
const tangent = resolveStationTangent(stations, index);
|
|
||||||
|
|
||||||
if (tangent === null) {
|
for (let index = 0; index < run.length; index += 1) {
|
||||||
return null;
|
const station = run[index]!;
|
||||||
|
const tangent = resolveStationTangent(run, index);
|
||||||
|
|
||||||
|
if (tangent === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const perpendicular = {
|
||||||
|
x: -tangent.z * halfWidth,
|
||||||
|
y: 0,
|
||||||
|
z: tangent.x * halfWidth
|
||||||
|
};
|
||||||
|
const left = resolveRoadVertexPosition({
|
||||||
|
path,
|
||||||
|
terrains,
|
||||||
|
point: addVec3(station.center, perpendicular),
|
||||||
|
fallbackY: station.center.y
|
||||||
|
});
|
||||||
|
const right = resolveRoadVertexPosition({
|
||||||
|
path,
|
||||||
|
terrains,
|
||||||
|
point: subtractVec3(station.center, perpendicular),
|
||||||
|
fallbackY: station.center.y
|
||||||
|
});
|
||||||
|
|
||||||
|
positions.push(left.x, left.y, left.z, right.x, right.y, right.z);
|
||||||
|
uvs.push(0, station.distance, 1, station.distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
const perpendicular = {
|
for (let index = 0; index < run.length - 1; index += 1) {
|
||||||
x: -tangent.z * halfWidth,
|
const left = runVertexOffset + index * 2;
|
||||||
y: 0,
|
const right = left + 1;
|
||||||
z: tangent.x * halfWidth
|
const nextLeft = left + 2;
|
||||||
};
|
const nextRight = left + 3;
|
||||||
const left = resolveRoadVertexPosition({
|
|
||||||
path,
|
|
||||||
terrains,
|
|
||||||
point: addVec3(station.center, perpendicular),
|
|
||||||
fallbackY: station.center.y
|
|
||||||
});
|
|
||||||
const right = resolveRoadVertexPosition({
|
|
||||||
path,
|
|
||||||
terrains,
|
|
||||||
point: subtractVec3(station.center, perpendicular),
|
|
||||||
fallbackY: station.center.y
|
|
||||||
});
|
|
||||||
|
|
||||||
positions.push(left.x, left.y, left.z, right.x, right.y, right.z);
|
indices.push(left, right, nextLeft, nextLeft, right, nextRight);
|
||||||
uvs.push(0, station.distance, 1, station.distance);
|
}
|
||||||
|
|
||||||
|
stationCount += run.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let index = 0; index < stations.length - 1; index += 1) {
|
if (positions.length === 0) {
|
||||||
const left = index * 2;
|
return null;
|
||||||
const right = left + 1;
|
|
||||||
const nextLeft = left + 2;
|
|
||||||
const nextRight = left + 3;
|
|
||||||
|
|
||||||
indices.push(left, right, nextLeft, nextLeft, right, nextRight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -473,7 +489,7 @@ export function buildSplineRoadMeshData(options: {
|
|||||||
positions: new Float32Array(positions),
|
positions: new Float32Array(positions),
|
||||||
uvs: new Float32Array(uvs),
|
uvs: new Float32Array(uvs),
|
||||||
indices: new Uint32Array(indices),
|
indices: new Uint32Array(indices),
|
||||||
stationCount: stations.length,
|
stationCount,
|
||||||
totalLength: stations[stations.length - 1]?.distance ?? 0
|
totalLength: stations[stations.length - 1]?.distance ?? 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -481,6 +497,7 @@ export function buildSplineRoadMeshData(options: {
|
|||||||
export function buildSplineRoadMeshGeometry(options: {
|
export function buildSplineRoadMeshGeometry(options: {
|
||||||
path: SplineRoadPathLike;
|
path: SplineRoadPathLike;
|
||||||
terrains?: readonly Terrain[];
|
terrains?: readonly Terrain[];
|
||||||
|
clipIntervals?: readonly SplineCorridorPathClipInterval[];
|
||||||
}): BufferGeometry | null {
|
}): BufferGeometry | null {
|
||||||
const meshData = buildSplineRoadMeshData(options);
|
const meshData = buildSplineRoadMeshData(options);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user