auto-git:
[change] src/geometry/spline-road-mesh.ts
This commit is contained in:
@@ -512,6 +512,7 @@ export function buildSplineRoadEdgeMeshData(options: {
|
|||||||
path: SplineRoadPathLike;
|
path: SplineRoadPathLike;
|
||||||
side: ScenePathRoadEdgeSide;
|
side: ScenePathRoadEdgeSide;
|
||||||
terrains?: readonly Terrain[];
|
terrains?: readonly Terrain[];
|
||||||
|
clipIntervals?: readonly SplineCorridorPathClipInterval[];
|
||||||
}): SplineRoadEdgeMeshData | null {
|
}): SplineRoadEdgeMeshData | null {
|
||||||
const { path, side } = options;
|
const { path, side } = options;
|
||||||
const edge = path.road.edges[side];
|
const edge = path.road.edges[side];
|
||||||
@@ -542,64 +543,80 @@ export function buildSplineRoadEdgeMeshData(options: {
|
|||||||
const uvs: number[] = [];
|
const uvs: number[] = [];
|
||||||
const indices: number[] = [];
|
const indices: number[] = [];
|
||||||
const profileLastIndex = Math.max(1, profile.length - 1);
|
const profileLastIndex = Math.max(1, profile.length - 1);
|
||||||
|
const stationRuns = buildVisibleRoadStationRuns(
|
||||||
|
stations,
|
||||||
|
options.clipIntervals ?? []
|
||||||
|
);
|
||||||
|
let stationCount = 0;
|
||||||
|
|
||||||
for (let stationIndex = 0; stationIndex < stations.length; stationIndex += 1) {
|
for (const run of stationRuns) {
|
||||||
const station = stations[stationIndex]!;
|
const runVertexOffset = positions.length / 3;
|
||||||
const tangent = resolveStationTangent(stations, stationIndex);
|
|
||||||
|
|
||||||
if (tangent === null) {
|
for (let stationIndex = 0; stationIndex < run.length; stationIndex += 1) {
|
||||||
return null;
|
const station = run[stationIndex]!;
|
||||||
}
|
const tangent = resolveStationTangent(run, stationIndex);
|
||||||
|
|
||||||
const leftDirection = {
|
if (tangent === null) {
|
||||||
x: -tangent.z,
|
return null;
|
||||||
y: 0,
|
}
|
||||||
z: tangent.x
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let profileIndex = 0; profileIndex < profile.length; profileIndex += 1) {
|
const leftDirection = {
|
||||||
const profilePoint = profile[profileIndex]!;
|
x: -tangent.z,
|
||||||
const edgePoint = addVec3(station.center, {
|
|
||||||
x: leftDirection.x * profilePoint.offset,
|
|
||||||
y: 0,
|
y: 0,
|
||||||
z: leftDirection.z * profilePoint.offset
|
z: tangent.x
|
||||||
});
|
};
|
||||||
const vertex = resolveRoadVertexPosition({
|
|
||||||
path,
|
|
||||||
terrains,
|
|
||||||
point: edgePoint,
|
|
||||||
fallbackY: station.center.y
|
|
||||||
});
|
|
||||||
|
|
||||||
positions.push(
|
for (let profileIndex = 0; profileIndex < profile.length; profileIndex += 1) {
|
||||||
vertex.x,
|
const profilePoint = profile[profileIndex]!;
|
||||||
vertex.y + profilePoint.heightOffset,
|
const edgePoint = addVec3(station.center, {
|
||||||
vertex.z
|
x: leftDirection.x * profilePoint.offset,
|
||||||
);
|
y: 0,
|
||||||
uvs.push(profileIndex / profileLastIndex, station.distance);
|
z: leftDirection.z * profilePoint.offset
|
||||||
|
});
|
||||||
|
const vertex = resolveRoadVertexPosition({
|
||||||
|
path,
|
||||||
|
terrains,
|
||||||
|
point: edgePoint,
|
||||||
|
fallbackY: station.center.y
|
||||||
|
});
|
||||||
|
|
||||||
|
positions.push(
|
||||||
|
vertex.x,
|
||||||
|
vertex.y + profilePoint.heightOffset,
|
||||||
|
vertex.z
|
||||||
|
);
|
||||||
|
uvs.push(profileIndex / profileLastIndex, station.distance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let stationIndex = 0; stationIndex < run.length - 1; stationIndex += 1) {
|
||||||
|
const currentRow = runVertexOffset + stationIndex * profile.length;
|
||||||
|
const nextRow = currentRow + profile.length;
|
||||||
|
|
||||||
|
for (let profileIndex = 0; profileIndex < profile.length - 1; profileIndex += 1) {
|
||||||
|
const current = currentRow + profileIndex;
|
||||||
|
const currentNext = current + 1;
|
||||||
|
const next = nextRow + profileIndex;
|
||||||
|
const nextNext = next + 1;
|
||||||
|
|
||||||
|
indices.push(current, currentNext, next, next, currentNext, nextNext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge.kind !== "softShoulder") {
|
||||||
|
addEdgeProfileCaps({
|
||||||
|
indices,
|
||||||
|
profileVertexCount: profile.length,
|
||||||
|
vertexOffset: runVertexOffset,
|
||||||
|
stationCount: run.length
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
stationCount += run.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let stationIndex = 0; stationIndex < stations.length - 1; stationIndex += 1) {
|
if (positions.length === 0) {
|
||||||
const currentRow = stationIndex * profile.length;
|
return null;
|
||||||
const nextRow = currentRow + profile.length;
|
|
||||||
|
|
||||||
for (let profileIndex = 0; profileIndex < profile.length - 1; profileIndex += 1) {
|
|
||||||
const current = currentRow + profileIndex;
|
|
||||||
const currentNext = current + 1;
|
|
||||||
const next = nextRow + profileIndex;
|
|
||||||
const nextNext = next + 1;
|
|
||||||
|
|
||||||
indices.push(current, currentNext, next, next, currentNext, nextNext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (edge.kind !== "softShoulder") {
|
|
||||||
addEdgeProfileCaps({
|
|
||||||
indices,
|
|
||||||
profileVertexCount: profile.length,
|
|
||||||
stationCount: stations.length
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -608,7 +625,7 @@ export function buildSplineRoadEdgeMeshData(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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -617,6 +634,7 @@ export function buildSplineRoadEdgeMeshGeometry(options: {
|
|||||||
path: SplineRoadPathLike;
|
path: SplineRoadPathLike;
|
||||||
side: ScenePathRoadEdgeSide;
|
side: ScenePathRoadEdgeSide;
|
||||||
terrains?: readonly Terrain[];
|
terrains?: readonly Terrain[];
|
||||||
|
clipIntervals?: readonly SplineCorridorPathClipInterval[];
|
||||||
}): BufferGeometry | null {
|
}): BufferGeometry | null {
|
||||||
const meshData = buildSplineRoadEdgeMeshData(options);
|
const meshData = buildSplineRoadEdgeMeshData(options);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user