簡介
目標(biāo):
- 通過鼠標(biāo)拖拽改變 Entity 模型的位置;
- 選中 Entity 芦倒,獲取其姿態(tài)艺挪、比例等屬性信息,實現(xiàn)對其屬性修改兵扬。
思路:
- 鼠標(biāo)左鍵按下選中模型麻裳,鼠標(biāo)移動改變所選模型的位置,鼠標(biāo)左鍵抬起結(jié)束拖拽器钟,實現(xiàn)目標(biāo)1津坑。
- 鼠標(biāo)左鍵點擊選中模型,獲取該對象相應(yīng)屬性信息傲霸,進(jìn)而做到對其修改疆瑰,實現(xiàn)目標(biāo)2。
1. 選中Entity
Cesium 中使用 scene.pick 或 scene.drillPick 方法選中 Entity 對象昙啄;當(dāng)多個 Entity 互相覆蓋時穆役,前者選中的是最上層的 Entity,后者選中的是鼠標(biāo)下所有的 Entity跟衅。
let picked = viewer.scene.pick(windowPosition);
let pickedArray = viewer.scene.dillPick(windowPosition);
2. 拖拽Entity
這里主要實現(xiàn)GLTF三維模型的拖拽,其它類型Entity的拖拽可作參考播歼。
(1)首先定義三個函數(shù)伶跷,分別對應(yīng)左鍵按下掰读、鼠標(biāo)移動、左鍵抬起叭莫。
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)移動
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;
}
注意兩點:
- 左鍵按下后鎖定相機(jī)蹈集,防止拖拽時相機(jī)視角改變,左鍵抬起后解除鎖定雇初。
- 鼠標(biāo)按下和抬起事件中拢肆,獲取屏幕坐標(biāo)的屬性是 position, 而鼠標(biāo)移動時獲取屏幕坐標(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刊橘,返回一個 Entity 對象鄙才。
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 對象后,可對其屬性進(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);