From 4fc9397cecd726081180fe1cb3758064e2ba8fac Mon Sep 17 00:00:00 2001 From: que01 Date: Mon, 27 Jul 2026 15:07:48 +0800 Subject: [PATCH] Fix cruise vehicle model orientation --- scripts/build-area.js | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/scripts/build-area.js b/scripts/build-area.js index 8c9701d..b6e6066 100755 --- a/scripts/build-area.js +++ b/scripts/build-area.js @@ -595,13 +595,13 @@ function material(name, color, roughness, metallic) { }; } -function cuboid(cx, cy, cz, sx, sy, sz) { +function cuboid(cx, lateral, up, sx, width, height) { const x0 = cx - sx / 2; const x1 = cx + sx / 2; - const y0 = cy - sy / 2; - const y1 = cy + sy / 2; - const z0 = cz - sz / 2; - const z1 = cz + sz / 2; + const y0 = up - height / 2; + const y1 = up + height / 2; + const z0 = lateral - width / 2; + const z1 = lateral + width / 2; const positions = [ x0, y0, z0, x1, y0, z0, x1, y1, z0, x0, y1, z0, x0, y0, z1, x1, y0, z1, x1, y1, z1, x0, y1, z1, @@ -614,16 +614,16 @@ function cuboid(cx, cy, cz, sx, sy, sz) { return { positions, indices, min: [x0, y0, z0], max: [x1, y1, z1] }; } -function cylinderY(cx, cy, cz, radius, width, segments) { +function cylinderY(cx, lateral, up, radius, width, segments) { const positions = []; const indices = []; - const y0 = cy - width / 2; - const y1 = cy + width / 2; - for (const y of [y0, y1]) { - positions.push(cx, y, cz); + const z0 = lateral - width / 2; + const z1 = lateral + width / 2; + for (const z of [z0, z1]) { + positions.push(cx, up, z); for (let i = 0; i < segments; i += 1) { const angle = 2 * Math.PI * i / segments; - positions.push(cx + Math.cos(angle) * radius, y, cz + Math.sin(angle) * radius); + positions.push(cx + Math.cos(angle) * radius, up + Math.sin(angle) * radius, z); } } const center0 = 0; @@ -640,8 +640,8 @@ function cylinderY(cx, cy, cz, radius, width, segments) { return { positions, indices, - min: [cx - radius, y0, cz - radius], - max: [cx + radius, y1, cz + radius], + min: [cx - radius, up - radius, z0], + max: [cx + radius, up + radius, z1], }; } @@ -809,13 +809,14 @@ function cesiumPreviewHtml(glbName, metadataName, routeName, vehicleModelName, a clampToGround: false } }); + const vehicleOrientation = correctedVehicleOrientation(positions, -90.0); const vehicle = viewer.entities.add({ name: "Cruise vehicle", availability: new Cesium.TimeIntervalCollection([ new Cesium.TimeInterval({ start, stop }) ]), position: positions, - orientation: new Cesium.VelocityOrientationProperty(positions), + orientation: vehicleOrientation, model: { uri: "${escapeJs(vehicleModelName)}", scale: 1.0, @@ -852,6 +853,19 @@ function cesiumPreviewHtml(glbName, metadataName, routeName, vehicleModelName, a return { segment, vehicle }; } + function correctedVehicleOrientation(positions, yawDegrees) { + const velocityOrientation = new Cesium.VelocityOrientationProperty(positions); + const correction = Cesium.Quaternion.fromAxisAngle( + Cesium.Cartesian3.UNIT_Z, + Cesium.Math.toRadians(yawDegrees) + ); + return new Cesium.CallbackProperty((time, result) => { + const base = velocityOrientation.getValue(time); + if (!base) return result; + return Cesium.Quaternion.multiply(base, correction, result || new Cesium.Quaternion()); + }, false); + } + function createChaseFollow(viewer, positions) { const scratchPosition = new Cesium.Cartesian3(); const scratchPrevious = new Cesium.Cartesian3();