簡(jiǎn)介
目標(biāo):
- 通過鼠標(biāo)拖拽改變 Entity 模型的位置;
- 選中 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);