上一篇文章结尾说到能通过entities类来创建小车模型并实现键盘控制,这篇就来演示一下。关于上一篇文章 Cesium开发实践(一)控制小车并视角跟随 大家也可以看看。
上一篇创建模型的方法:
let carPrimitive = scene.primitives.add(Cesium.Model.fromGltf({
id:'mycar',
url:"你的URL地址",
modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84,fixedFrameTransforms),
}))
entities创建模型
let mycar = viewer.entities.add({
id:'car',
// 位置
position: new Cesium.CallbackProperty(getPositin, false),
// 姿态
orientation: new Cesium.CallbackProperty(getOrientation, false),
model: {
uri: "你的URL地址",
}
});
可以看到两种方法添加的参数不一样,这个orientation是姿态,包含了Heading,Pitch,Roll。
我选用的方法是通过计算下个点位的经纬度坐标来刷新模型的位置,相信有很多小伙伴会遇到跟我一样的问题,直接修改position,值会改变但是模型的位置并不会变化,然后我去查看了Cesium的API文档,这里想要修改position或者orientation都需要使用回调函数。方法很简单,只需要返回你需要的坐标或者方位就好了。
let radian = Cesium.Math.toRadians(2.0);
let speed = 0.4;
let speedVector = new Cesium.Cartesian3();
let scene = viewer.scene;
let position = Cesium.Cartesian3.fromDegrees(posi[0],posi[1],posi[2])
let hpRoll = new Cesium.HeadingPitchRoll();
var orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpRoll
)
// 添加模型
let mycar = viewer.entities.add({
id:'car',
position: new Cesium.CallbackProperty(getPositin, false),
// 根据所提供的速度计算点
orientation: new Cesium.CallbackProperty(getOrientation, false),
model: {
uri:'/static/model/GLTFformat/taxi.glb',
}
});
viewer.trackedEntity = mycar;
let flag = {
moveUp:false,
moveDown:false,
moveLeft:false,
moveRight:false
};
// 根据键盘按键返回标志
function setFlagStatus(key,value) {
switch (key.keyCode){
case 37:
// 左
flag.moveLeft = value;
break;
case 38:
// 上
flag.moveUp = value;
break;
case 39:
// 右
flag.moveRight = value;
break;
case 40:
flag.moveDown = value;
// 下
break;
}
}
document.addEventListener('keydown',(e)=>{
setFlagStatus(e, true);
});
document.addEventListener('keyup',(e)=>{
setFlagStatus(e, false);
});
var count = 0;
viewer.clock.onTick.addEventListener((clock)=>{
if(flag.moveUp){
if(flag.moveLeft){
hpRoll.heading -= radian;
count += 2;
}
if(flag.moveRight){
hpRoll.heading += radian;
count -= 2;
}
moveCar(1);
}else if(flag.moveDown){
if(flag.moveLeft){
hpRoll.heading -= radian;
count += 2;
}
if(flag.moveRight){
hpRoll.heading += radian;
count -= 2;
}
moveCar(-1);
}else {
if(flag.moveLeft){
hpRoll.heading -= radian;
count += 2;
moveCar(0)
}
if(flag.moveRight){
hpRoll.heading += radian;
count -= 2;
moveCar(0)
}
}
});
// 移动小车
function moveCar(isUP) {
// 计算速度矩阵
if(isUP>0){
speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X,speed,speedVector);
}else if(isUP<0){
speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X,-speed,speedVector);
}else{
speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X,0,speedVector);
}
// 根据速度计算出下一个位置的坐标
let fixedFrameTransforms = Cesium.Transforms.localFrameToFixedFrameGenerator('east', 'north');
let modelMatrix= Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84,fixedFrameTransforms);
position = Cesium.Matrix4.multiplyByPoint(modelMatrix ,speedVector, position);
}
function getPositin(){
return position
}
function getOrientation(){
return Cesium.Transforms.headingPitchRollQuaternion(position,hpRoll)
}