feat: add native preview traffic simulation

This commit is contained in:
2026-08-18 16:57:27 +08:00
parent 0bc949bc24
commit 5403936ae4
21 changed files with 777 additions and 45 deletions

View File

@@ -16,6 +16,7 @@ const {
} = require("./lib/scene-layers");
const { digest: glbDigest } = require("./glb-digest");
const { buildVehicleRoute: buildPreviewVehicleRoute } = require("./lib/vehicle-route");
const { buildNativeTrafficSimulation } = require("./lib/native-preview-traffic-simulation");
const { writePreviewVehicleLibrary } = require("./lib/vehicle-library");
const { readTrafficSignals } = require("./lib/traffic-signals");
const {
@@ -338,11 +339,9 @@ function exportCesium(area, roadProvider) {
fs.rmSync(area.outputs.packageStagingDir, { recursive: true, force: true });
fs.mkdirSync(path.dirname(area.outputs.glb), { recursive: true });
fs.mkdirSync(path.dirname(area.outputs.metadata), { recursive: true });
if (roadProvider === "osm2streets") {
fs.mkdirSync(path.dirname(area.outputs.trafficSignalsDynamicGlb), { recursive: true });
fs.mkdirSync(path.dirname(area.outputs.trafficSignalsCountdown0Glb), { recursive: true });
fs.mkdirSync(path.dirname(area.outputs.trafficSignalsCountdown1Glb), { recursive: true });
}
fs.mkdirSync(path.dirname(area.outputs.trafficSignalsDynamicGlb), { recursive: true });
fs.mkdirSync(path.dirname(area.outputs.trafficSignalsCountdown0Glb), { recursive: true });
fs.mkdirSync(path.dirname(area.outputs.trafficSignalsCountdown1Glb), { recursive: true });
console.log("Stage: cesium");
const started = Date.now();
@@ -363,19 +362,15 @@ function exportCesium(area, roadProvider) {
"--metadata",
area.outputs.metadata,
];
if (roadProvider === "osm2streets") {
exporterArgs.splice(-2, 0,
"--dynamic-glb", area.outputs.trafficSignalsDynamicGlb,
"--countdown-0-glb", area.outputs.trafficSignalsCountdown0Glb,
"--countdown-1-glb", area.outputs.trafficSignalsCountdown1Glb,
);
}
exporterArgs.splice(-2, 0,
"--dynamic-glb", area.outputs.trafficSignalsDynamicGlb,
"--countdown-0-glb", area.outputs.trafficSignalsCountdown0Glb,
"--countdown-1-glb", area.outputs.trafficSignalsCountdown1Glb,
);
runCommand(blenderExecutable(area), exporterArgs, "cesium");
if (roadProvider === "osm2streets") {
ensureFile(area.outputs.trafficSignalsDynamicGlb, "Dynamic traffic signal GLB");
ensureFile(area.outputs.trafficSignalsCountdown0Glb, "Traffic countdown group 0 GLB");
ensureFile(area.outputs.trafficSignalsCountdown1Glb, "Traffic countdown group 1 GLB");
}
ensureFile(area.outputs.trafficSignalsDynamicGlb, "Dynamic traffic signal GLB");
ensureFile(area.outputs.trafficSignalsCountdown0Glb, "Traffic countdown group 0 GLB");
ensureFile(area.outputs.trafficSignalsCountdown1Glb, "Traffic countdown group 1 GLB");
const semanticAssets = semanticAssetRecords(area);
const finished = Date.now();
const digest = glbDigest(area.outputs.glb);
@@ -392,9 +387,9 @@ function exportCesium(area, roadProvider) {
outputs: {
glb: fileRecord(area.outputs.glb),
metadata: fileRecord(area.outputs.metadata),
...(roadProvider === "osm2streets" ? {
trafficSignalsDynamicGlb: fileRecord(area.outputs.trafficSignalsDynamicGlb),
} : {}),
trafficSignalsDynamicGlb: fileRecord(area.outputs.trafficSignalsDynamicGlb),
trafficSignalsCountdown0Glb: fileRecord(area.outputs.trafficSignalsCountdown0Glb),
trafficSignalsCountdown1Glb: fileRecord(area.outputs.trafficSignalsCountdown1Glb),
semanticAssets,
},
summary: {
@@ -558,6 +553,7 @@ function writeCesiumPreview(area, roadProvider) {
ensureFile(area.outputs.packageManifest, "Published asset package manifest");
ensureFile(area.outputs.packageTrafficSignals, "Published traffic signal anchors");
let vehicleRoute = null;
let routeArtifact = null;
const previewInputs = {
config: fileRecord(configPath),
osm: fileRecord(area.input),
@@ -579,6 +575,11 @@ function writeCesiumPreview(area, roadProvider) {
});
} else {
Object.assign(previewInputs, nativeRoadRecords(area));
const simulation = buildNativeTrafficSimulation(area);
fs.mkdirSync(path.dirname(area.outputs.trafficSimulation), { recursive: true });
fs.writeFileSync(area.outputs.trafficSimulation, `${JSON.stringify(simulation, null, 2)}\n`);
previewInputs.trafficSimulation = fileRecord(area.outputs.trafficSimulation);
routeArtifact = area.outputs.trafficSimulation;
}
const htmlPath = area.outputs.cesiumPreview;
const started = Date.now();
@@ -594,7 +595,9 @@ function writeCesiumPreview(area, roadProvider) {
writeCesiumPreviewSupportFiles(path.dirname(htmlPath));
const glbName = "package/manifest.json";
const metadataName = "package/manifest.json";
const routeName = vehicleRoute ? previewRelativePath(area.outputs.areaDir, area.outputs.vehicleRoute) : null;
const routeName = vehicleRoute || routeArtifact
? previewRelativePath(area.outputs.areaDir, vehicleRoute ? area.outputs.vehicleRoute : routeArtifact)
: null;
const vehicleModelName = previewRelativePath(area.outputs.areaDir, area.outputs.vehicleModel);
const descriptor = { routeName, vehicleModelName: previewRelativePath(area.outputs.areaDir, area.outputs.vehicleModel), vehicleModelNames: vehicleModelNames.map((name) => `_preview/${name}`), trafficSignalsName: "package/runtime/traffic-signals.json", assets: [] };
fs.mkdirSync(area.outputs.previewDir, { recursive: true });
@@ -617,10 +620,11 @@ function writeCesiumPreview(area, roadProvider) {
outputs: {
cesiumPreview: fileRecord(area.outputs.cesiumPreview),
vehicleRoute: optionalFileRecord(area.outputs.vehicleRoute),
...(routeArtifact ? { trafficSimulation: fileRecord(routeArtifact) } : {}),
vehicleModel: fileRecord(area.outputs.vehicleModel),
trafficSignals: fileRecord(area.outputs.packageTrafficSignals),
},
summary: previewSummary(area),
summary: previewSummary(area, vehicleRoute ? area.outputs.vehicleRoute : routeArtifact),
warnings: [],
});
}