cesium沙盒例子(HeadingPitchRoll) 代码详细注释

cesium例子(HeadingPitchRoll)

cesium 自带的沙盒里面有很多的例子供大家学习,其中的例子HeadingPitchRoll 是一个可以使用键盘按键实时控制飞机飞行的例子,功能相当有用,如图所示;
在这里插入图片描述
这里贴上我对于示例代码的注释,如有错误还请指正,有疑问欢迎在评论区提出

带有代码如下:

	//初始化三维场景
const viewer = new Cesium.Viewer("cesiumContainer", {
  shouldAnimate: true,//开启动画
});

//鼠标聚焦到场景中
const canvas = viewer.canvas;
canvas.setAttribute("tabindex", "0"); // needed to put focus on the canvas
canvas.addEventListener("click", function () {
  canvas.focus();
});
canvas.focus();

const scene = viewer.scene;

//定义飞机的路径数据,使用一个positionProperty来存储飞机轨迹
const pathPosition = new Cesium.SampledPositionProperty();
//新增path 路径到场景中
const entityPath = viewer.entities.add({
  position: pathPosition,
  name: "path",
  path: {
    show: true,
    leadTime: 0,
    trailTime: 60,
    width: 10,
    resolution: 1,
    material: new Cesium.PolylineGlowMaterialProperty({
      glowPower: 0.3,
      taperPower: 0.3,
      color: Cesium.Color.PALEGOLDENROD,
    }),
  },
});
//获取场景的相机,便于后续设置相机视角
const camera = viewer.camera;
//获取场景的控制对象
const controller = scene.screenSpaceCameraController;
let r = 0;

//定义飞机的姿态
const hpRoll = new Cesium.HeadingPitchRoll();
//定义相机的姿态
const hpRange = new Cesium.HeadingPitchRange();
// 飞机的飞行速度
let speed = 10;
//每一次按键调整飞机姿态的度数
const deltaRadians = Cesium.Math.toRadians(3.0);

//飞机的初始位置
let position = Cesium.Cartesian3.fromDegrees(
  -123.0744619,
  44.0503706,
  5000.0
);
//关键对象,飞机的飞行依赖的速度对象,记录飞机当前飞行的速度和方向
let speedVector = new Cesium.Cartesian3();
//定义参考轴
const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator(
  "north",
  "west"
);

const headingSpan = document.getElementById("heading");
const pitchSpan = document.getElementById("pitch");
const rollSpan = document.getElementById("roll");
const speedSpan = document.getElementById("speed");
const fromBehind = document.getElementById("fromBehind");

try {
  //使用primitive的api添加飞机模型到场景中
  const planePrimitive = scene.primitives.add(
    await Cesium.Model.fromGltfAsync({
      url: "../../SampleData/models/CesiumAir/Cesium_Air.glb",
      modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
        position,
        hpRoll,
        Cesium.Ellipsoid.WGS84,
        fixedFrameTransform
      ),
      minimumPixelSize: 128,
    })
  );
  //添加一个回调函数,在飞机模型加载完成后执行
  planePrimitive.readyEvent.addEventListener(() => {
    // 播放飞机模型自动的动画
    planePrimitive.activeAnimations.addAll({
      multiplier: 0.5,
      loop: Cesium.ModelAnimationLoop.REPEAT,
    });

    // 通过飞机的包围盒,计算出相机需要锁定到飞机需要距离飞机多远
    r =
      2.0 *
      Math.max(
        planePrimitive.boundingSphere.radius,
        camera.frustum.near
      );
    //设置场景的缩放最小值,避免缩放太小看不到飞机
    controller.minimumZoomDistance = r * 0.5;
    //获取相机锁定所需要的三个参数,heading,pitch,range
    const center = planePrimitive.boundingSphere.center;
    const heading = Cesium.Math.toRadians(230.0);
    const pitch = Cesium.Math.toRadians(-20.0);
    hpRange.heading = heading;
    hpRange.pitch = pitch;
    hpRange.range = r * 50.0;
    //相机锁定飞机
    camera.lookAt(center, hpRange);
  });
// 这里比较简单,就是绑定按钮,改变对应的数值
  document.addEventListener("keydown", function (e) {
    switch (e.keyCode) {
      case 40:
        if (e.shiftKey) {
          // speed down
          speed = Math.max(--speed, 1);
        } else {
          // pitch down
          hpRoll.pitch -= deltaRadians;
          if (hpRoll.pitch < -Cesium.Math.TWO_PI) {
            hpRoll.pitch += Cesium.Math.TWO_PI;
          }
        }
        break;
      case 38:
        if (e.shiftKey) {
          // speed up
          speed = Math.min(++speed, 100);
        } else {
          // pitch up
          hpRoll.pitch += deltaRadians;
          if (hpRoll.pitch > Cesium.Math.TWO_PI) {
            hpRoll.pitch -= Cesium.Math.TWO_PI;
          }
        }
        break;
      case 39:
        if (e.shiftKey) {
          // roll right
          hpRoll.roll += deltaRadians;
          if (hpRoll.roll > Cesium.Math.TWO_PI) {
            hpRoll.roll -= Cesium.Math.TWO_PI;
          }
        } else {
          // turn right
          hpRoll.heading += deltaRadians;
          if (hpRoll.heading > Cesium.Math.TWO_PI) {
            hpRoll.heading -= Cesium.Math.TWO_PI;
          }
        }
        break;
      case 37:
        if (e.shiftKey) {
          // roll left until
          hpRoll.roll -= deltaRadians;
          if (hpRoll.roll < 0.0) {
            hpRoll.roll += Cesium.Math.TWO_PI;
          }
        } else {
          // turn left
          hpRoll.heading -= deltaRadians;
          if (hpRoll.heading < 0.0) {
            hpRoll.heading += Cesium.Math.TWO_PI;
          }
        }
        break;
      default:
    }
  });
//关键部分,场景每一次更新都会触发的代码,支持飞机飞行的关键代码
  viewer.scene.preUpdate.addEventListener(function (scene, time) {
    // 对关键的飞机飞行的速度对象就行实时更新,将速度矢量对象与速度值的标量进行相乘,得到一个拥有方向和速度值的矢量对象
    speedVector = Cesium.Cartesian3.multiplyByScalar(
      Cesium.Cartesian3.UNIT_X,//x轴方向,Cesium.Cartesian3.UNIT_X=new Cartesian3(1,0,0),使用这个方向值,代表飞机的速度方向一直都是飞机当前的X轴方向
      speed / 10,//
      speedVector
    );
    //使用飞机当前的位置矩阵乘以速度矢量,可以得到飞机以当前速度飞行后的位置矢量
    position = Cesium.Matrix4.multiplyByPoint(
      planePrimitive.modelMatrix,
      speedVector,
      position
    );
    //将新的位置点添加到路径中
    pathPosition.addSample(Cesium.JulianDate.now(), position);
    //将新的位置矢量与新的姿态信息加以转化得到新的位置矩阵,以此更新飞机的位置和姿态
    Cesium.Transforms.headingPitchRollToFixedFrame(
      position,
      hpRoll,
      Cesium.Ellipsoid.WGS84,
      fixedFrameTransform,
      planePrimitive.modelMatrix
    );
    //判断是否点击锁定飞机,如果点击了开启锁定
    if (fromBehind.checked) {
      // Zoom to model
      const center = planePrimitive.boundingSphere.center;
      hpRange.heading = hpRoll.heading;
      hpRange.pitch =  Cesium.Math.toRadians(-25);
      camera.lookAt(center, hpRange);
    }
  });
} catch (error) {
  console.log(`Error loading model: ${error}`);
}
// 同步修改界面显示的数值
viewer.scene.preRender.addEventListener(function (scene, time) {
  headingSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.heading).toFixed(
    1
  );
  pitchSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.pitch).toFixed(1);
  rollSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.roll).toFixed(1);
  speedSpan.innerHTML = speed.toFixed(1);
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sannianerban12138

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值