Fix cruise vehicle model orientation

This commit is contained in:
2026-07-27 15:07:48 +08:00
parent 633f1ee364
commit 4fc9397cec

View File

@@ -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 x0 = cx - sx / 2;
const x1 = cx + sx / 2; const x1 = cx + sx / 2;
const y0 = cy - sy / 2; const y0 = up - height / 2;
const y1 = cy + sy / 2; const y1 = up + height / 2;
const z0 = cz - sz / 2; const z0 = lateral - width / 2;
const z1 = cz + sz / 2; const z1 = lateral + width / 2;
const positions = [ const positions = [
x0, y0, z0, x1, y0, z0, x1, y1, z0, x0, y1, z0, x0, y0, z0, x1, y0, z0, x1, y1, z0, x0, y1, z0,
x0, y0, z1, x1, y0, z1, x1, y1, z1, x0, y1, z1, 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] }; 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 positions = [];
const indices = []; const indices = [];
const y0 = cy - width / 2; const z0 = lateral - width / 2;
const y1 = cy + width / 2; const z1 = lateral + width / 2;
for (const y of [y0, y1]) { for (const z of [z0, z1]) {
positions.push(cx, y, cz); positions.push(cx, up, z);
for (let i = 0; i < segments; i += 1) { for (let i = 0; i < segments; i += 1) {
const angle = 2 * Math.PI * i / segments; 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; const center0 = 0;
@@ -640,8 +640,8 @@ function cylinderY(cx, cy, cz, radius, width, segments) {
return { return {
positions, positions,
indices, indices,
min: [cx - radius, y0, cz - radius], min: [cx - radius, up - radius, z0],
max: [cx + radius, y1, cz + radius], max: [cx + radius, up + radius, z1],
}; };
} }
@@ -809,13 +809,14 @@ function cesiumPreviewHtml(glbName, metadataName, routeName, vehicleModelName, a
clampToGround: false clampToGround: false
} }
}); });
const vehicleOrientation = correctedVehicleOrientation(positions, -90.0);
const vehicle = viewer.entities.add({ const vehicle = viewer.entities.add({
name: "Cruise vehicle", name: "Cruise vehicle",
availability: new Cesium.TimeIntervalCollection([ availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({ start, stop }) new Cesium.TimeInterval({ start, stop })
]), ]),
position: positions, position: positions,
orientation: new Cesium.VelocityOrientationProperty(positions), orientation: vehicleOrientation,
model: { model: {
uri: "${escapeJs(vehicleModelName)}", uri: "${escapeJs(vehicleModelName)}",
scale: 1.0, scale: 1.0,
@@ -852,6 +853,19 @@ function cesiumPreviewHtml(glbName, metadataName, routeName, vehicleModelName, a
return { segment, vehicle }; 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) { function createChaseFollow(viewer, positions) {
const scratchPosition = new Cesium.Cartesian3(); const scratchPosition = new Cesium.Cartesian3();
const scratchPrevious = new Cesium.Cartesian3(); const scratchPrevious = new Cesium.Cartesian3();