Cesium — Entity 拖拽、屬性修改

簡(jiǎn)介

目標(biāo)

  1. 通過鼠標(biāo)拖拽改變 Entity 模型的位置;
  2. 選中 Entity ,獲取其姿態(tài)、比例等屬性信息,實(shí)現(xiàn)對(duì)其屬性修改。

思路

  • 鼠標(biāo)左鍵按下選中模型,鼠標(biāo)移動(dòng)改變所選模型的位置,鼠標(biāo)左鍵抬起結(jié)束拖拽,實(shí)現(xiàn)目標(biāo)1。
  • 鼠標(biāo)左鍵點(diǎn)擊選中模型,獲取該對(duì)象相應(yīng)屬性信息,進(jìn)而做到對(duì)其修改,實(shí)現(xiàn)目標(biāo)2。

1. 選中Entity

Cesium 中使用 scene.pick 或 scene.drillPick 方法選中 Entity 對(duì)象;當(dāng)多個(gè) Entity 互相覆蓋時(shí),前者選中的是最上層的 Entity,后者選中的是鼠標(biāo)下所有的 Entity。

let picked = viewer.scene.pick(windowPosition);
let pickedArray = viewer.scene.dillPick(windowPosition);

2. 拖拽Entity

這里主要實(shí)現(xiàn)GLTF三維模型的拖拽,其它類型Entity的拖拽可作參考。
(1)首先定義三個(gè)函數(shù),分別對(duì)應(yīng)左鍵按下、鼠標(biāo)移動(dòng)、左鍵抬起。

let leftDownFlag = false; // 鼠標(biāo)左鍵是否按下
let pickedEntity = null; //被選中的Entity

// 拖拽模型-左鍵按下
function leftDownAction(e) {
  leftDownFlag = true;
  let picked = viewer.scene.pick(e.position);
  if (picked) {
    document.body.style.cursor = 'move';
    pickedEntity = Cesium.defaultValue(picked.id, picked.primitive.id);
    if (pickedEntity instanceof Cesium.Entity && pickedEntity.model) {
      //鎖定相機(jī)
      viewer.scene.screenSpaceCameraController.enableRotate = false;
    }
  }
}

// 拖拽模型-鼠標(biāo)移動(dòng)
function mouseMoveAction(e) {
  if (leftDownFlag && pickedEntity) {
    // let ray = viewer.camera.getPickRay(e.endPosition);
    // let cartesian = viewer.scene.globe.pick(ray, viewer.scene);
    let cartesian = viewer.scene.camera.pickEllipsoid(
      e.endPosition,
      viewer.scene.globe.ellipsoid
    );
    pickedEntity.position = cartesian;
  }
}

// 拖拽模型-左鍵抬起
function leftUpAction(e) {
  document.body.style.cursor = 'default';
  leftDownFlag = false;
  pickedEntity = null;
  // 解除相機(jī)鎖定
  viewer.scene.screenSpaceCameraController.enableRotate = true;
}

注意兩點(diǎn):

  • 左鍵按下后鎖定相機(jī),防止拖拽時(shí)相機(jī)視角改變,左鍵抬起后解除鎖定。
  • 鼠標(biāo)按下和抬起事件中,獲取屏幕坐標(biāo)的屬性是 position, 而鼠標(biāo)移動(dòng)時(shí)獲取屏幕坐標(biāo)的屬性是 endPosition。

(2) 給 Viewer 添加相應(yīng)鼠標(biāo)事件

viewer.screenSpaceEventHandler.setInputAction((e) => {
  leftDownAction(e);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

viewer.screenSpaceEventHandler.setInputAction((e) => {
  mouseMoveAction(e);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

viewer.screenSpaceEventHandler.setInputAction((e) => {
  leftUpAction(e);
}, Cesium.ScreenSpaceEventType.LEFT_UP);

3. 修改屬性

選中 Entity 后,即可獲取相應(yīng)的屬性信息。下面的 pickModel 函數(shù)傳入windowPosition,返回一個(gè) Entity 對(duì)象。

function pickModel(windowPosition) {
  let picked = viewer.scene.pick(windowPosition);
  if (Cesium.defined(picked)) {
    let entity = Cesium.defaultValue(picked.id, picked.primitive.id);
    if (entity instanceof Cesium.Entity) {
      if (entity.model) {
        console.log('model');
        return entity;
      }
    }
  }
}

獲取到 Entity 對(duì)象后,可對(duì)其屬性進(jìn)行修改:

viewer.screenSpaceEventHandler.setInputAction((e) => {
  let entity = pickModel(e.position);
  // 獲取模型的比例
  let scale = entity.model.scale.getValue();
  // 設(shè)置模型的比例
  entity.model.scale.setValue(2.0);
  
  // 獲取模型(當(dāng)前)的位置
    let position = entity.position.getValue(Cesium.JulianDate.fromDate(new Date()));
  // 設(shè)置模型的位置
  let position2 = Cesium.Cartesian3.fromDegrees(114.08, 23.55, 1000);
  entity.position.setValue(position2);
  
  // 設(shè)置模型的方位
    let heading = Cesium.Math.toRadians(90);
    let pitch = Cesium.Math.toRadians(0);
    let roll = Cesium.Math.toRadians(0);
    let orientation = Cesium.Transforms.headingPitchRollQuaternion(
        position,
        new Cesium.HeadingPitchRoll(heading, pitch, roll)
    );
    entity.orientation = orientation;
  
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容