说在前面:加载和旋转缩放没什么好说的,但是平移还是用些细节要注意的。我也是跳了几天才偶然发现问题。
1.primitives方式加载:
handler.setInputAction(function (evt) {
let cartesian = viewer.scene.pickPosition(evt.position);
if (Cesium.defined(cartesian)) {
let headingPitchRoll = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(0), Cesium.Math.toRadians(0), Cesium.Math.toRadians(0));
let modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(cartesian, headingPitchRoll, Cesium.Ellipsoid.WGS84, Cesium.Transforms.eastNorthUpToFixedFrame, new Cesium.Matrix4());
let model = viewer.scene.primitives.add(Cesium.Model.fromGltf({
url : '../src/data/GLTF/oneBuilding.gltf',
modelMatrix : modelMatrix,
minimumPixelSize : 128,
scale : 1,
cull:false,
}));
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
2.旋转和缩放(说明一点,我设定的鼠标在3Dtiles上移动点击才可以。向直接在地表点击的话可能需要修改 判断是否是渠道模型 的那句代码)
// 旋转的关键代码
handler.setInputAction(function (evt) {
let pickedObject = viewer.scene.pick(evt.position); //判断是否拾取到模型
if ( pickedObject ){
let m = pickedObject.primitive.modelMatrix;// 带旋转模型的矩阵
let rotationM = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(rtaleX)); // rtaleX表示水平方向旋转的度数
let newMatrix4 = Cesium.Matrix4.multiplyByMatrix3(m, rotationM, new Cesium.Matrix4());// 计算矩阵4的变换矩阵(在原变换中,累加变换)
pickedObject.primitive.modelMatrix = newMatrix4
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// 调整高度的关键代码
handler.setInputAction(function (evt) {
let pickedObject = viewer.scene.pick(evt.position); //判断是否拾取到模型
if ( pickedObject ){
let oldMatrix = pickedObject.primitive.modelMatrix;// 模型的矩阵
let oldCenter = new Cesium.Cartesian3(oldMatrix[12],oldMatrix[13],oldMatrix[14]);// 模型高度调整前中心点笛卡尔坐标
let oldCartographic = Cesium.Cartographic.fromCartesian(oldCenter);// 高度调整前的弧度坐标
let newHeight = oldCartographic.height+height;
let newCartographic = new Cesium.Cartographic( oldCartographic.longitude, oldCartographic.latitude, newHeight ); // 高度调整后的弧度坐标
let newCartesian = viewer.scene.globe.ellipsoid.cartographicToCartesian(newCartographic);
let headingPitchRoll = new Cesium.HeadingPitchRoll(0,0,0);
let m = Cesium.Transforms.headingPitchRollToFixedFrame(newCartesian, headingPitchRoll, Cesium.Ellipsoid.WGS84, Cesium.Transforms.eastNorthUpToFixedFrame, new Cesium.Matrix4());
pickedObject.primitive.modelMatrix = m;// 平移变换
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
3平移:这是我写这篇博客的关键。管网demo里升降平移是对3Dtiles,对gltf不一定有效的,我也是愣了几天偶然改正确的,主要就是获取鼠标移动时坐标。
// 移动模型
function moveGltfModel ( ) {
let _this = this;
let viewer = _this.viewer;
let handler = new Cesium.ScreenSpaceEventHandler( viewer.canvas);
let pickedObject = null;
let leftDownFlag = false;
let rtaleX = parseFloat( $("#rangeRtaleX").val() );
handler.setInputAction(function (movement) {
pickedObject = viewer.scene.pick(movement.position);
if(Cesium.defined(pickedObject)){
if (pickedObject.primitive.isCesium3DTileset == undefined ){
leftDownFlag = true;
document.body.style.cursor = 'pointer';
viewer.scene.screenSpaceCameraController.enableRotate = false;//锁定相机
pickedObject.primitive.color = new Cesium.Color(0, 1, 0, 1); //选中模型后高亮
pickedObject.primitive.silhouetteSize = 3.0;//选中模型后高亮
}
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
handler.setInputAction(function () {
pickedObject.primitive.color = new Cesium.Color(1, 1, 1, 1);
pickedObject.primitive.silhouetteSize = 0;
leftDownFlag = false;
pickedObject = null;
viewer.scene.screenSpaceCameraController.enableRotate = true;//解除锁定相机
handler.destroy();//销毁左键监听事件
document.body.style.cursor = 'default';
}, Cesium.ScreenSpaceEventType.LEFT_UP);
handler.setInputAction((movement) => {
if ( leftDownFlag && pickedObject.primitive.modelMatrix ) {
// ************g关键代码:cartesian的值************
let ray = viewer.camera.getPickRay(movement.endPosition);
let cartesian = viewer.scene.globe.pick(ray, viewer.scene);
let headingPitchRoll = new Cesium.HeadingPitchRoll( Cesium.Math.toRadians(0),0,0);
let m = Cesium.Transforms.headingPitchRollToFixedFrame(cartesian, headingPitchRoll, Cesium.Ellipsoid.WGS84, Cesium.Transforms.eastNorthUpToFixedFrame, new Cesium.Matrix4());
pickedObject.primitive.modelMatrix = m;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
说明一下:我之前用了好几种获取鼠标坐标导致的结果是移动时会到处跑。但下面这样获取就不会。
// 这样获取就不会到处跑
let ray = viewer.camera.getPickRay(movement.endPosition);
let cartesian = viewer.scene.globe.pick(ray, viewer.scene);
//列几种我之前的获取方式会出问题的额
// let headingPitchRoll = new Cesium.HeadingPitchRoll(0,0,0);
// let cartesian = viewer.scene.pickPosition(movement.endPosition);
// let headingPitchRoll = new Cesium.HeadingPitchRoll(0,0,0);
// let position = viewer.scene.globe.pick(viewer.camera.getPickRay(movement.endPosition), viewer.scene);// 获取鼠标移动后的点
// let cartesian = new Cesium.Cartesian3( position.x, position.y, position.z )
扩展一下:entity加载的话,直接修改entity的position就可以了
handler.setInputAction(function (movement) {
if (leftDownFlag === true && pointDraged != null) {
let ray = viewer.camera.getPickRay(movement.endPosition);
let cartesian = viewer.scene.globe.pick(ray, viewer.scene);
console.log(cartesian);
pointDraged.id.position = new Cesium.CallbackProperty(function () {
return cartesian;
}, false);//防止闪烁,在移动的过程
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);