说结果
调整位置和高度没问题,旋转有的可以有的不可以。
网上有很多方法,针对不同软件生成的3dtiles服务,有的可以有的不可以,与其说别人给的方法不对,不如说自己该去补补数学、图形学知识了。
说方案
方法一
/**
* 调高度官方方法
* @param {*} tileset
* @param {Object} [params] 对象有如下属性:
* @param {Object} [params.height] 偏移高度(单位:米)
*/
export function adjust3DTile(
tileset,
params = { height: 0 }
) {
const cartographic = Cesium.Cartographic.fromCartesian(
tileset.boundingSphere.center
);
const surface = Cesium.Cartesian3.fromRadians(
cartographic.longitude,
cartographic.latitude,
0.0
);
const offset = Cesium.Cartesian3.fromRadians(
cartographic.longitude,
cartographic.latitude
params.height
);
const tranlation = Cesium.Cartesian3.subtract(
offset,
surface,
new Cesium.Cartesian3()
);
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(tranlation);
}
方法二
/**
* 平移、贴地、旋转模型,白膜有效,倾斜摄影无效(目前只验证过cesiumlab处理的3dtiles数据,其他工具处理的数据有待验证。)
* @param {*} tileset
* @param {Object} [params] 对象有如下属性:
* @param {Object} [params.tx] 模型中心X轴坐标(经度,单位:十进制度)
* @param {Object} [params.ty] 模型中心Y轴坐标(纬度,单位:十进制度)
* @param {Object} [params.tz] 模型中心Z轴坐标(高程,单位:米)
* @param {Object} [params.rx] X轴(纬度)方向旋转角度(单位:度)
* @param {Object} [params.ry] Y轴(纬度)方向旋转角度(单位:度)
* @param {Object} [params.rz] Z轴(高程)方向旋转角度(单位:度)
*/
export function update3dtilesMaxtrix(tileset, params) {
//旋转
let mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
let my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
let mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
let rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
let rotationY = Cesium.Matrix4.fromRotationTranslation(my);
let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
//平移
let position = Cesium.Cartesian3.fromDegrees(params.tx, params.ty, params.tz);
let m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
//旋转、平移矩阵相乘
Cesium.Matrix4.multiply(m, rotationX, m);
Cesium.Matrix4.multiply(m, rotationY, m);
Cesium.Matrix4.multiply(m, rotationZ, m);
//赋值给tileset
tileset._root.transform = m;
}
// 缩放
var scale = Cesium.Matrix4.fromUniformScale(0.6)
Cesium.Matrix4.multiply(m, scale, m)
//https://hqcode.gitee.io/cesium-test/lesson03/
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Use correct character set. -->
<meta charset="utf-8">
<!-- Tell IE to use the latest, best version. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>Hello World!</title>
<script src="../Build/Cesium/Cesium.js"></script>
<style>
@import url(../Build/CesiumUnminified/Widgets/widgets.css);
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.canvas {
position: absolute;
left: 10px;
top: 10px;
display:none;
}
#canvas-a {
top: 10px;
}
#canvas-b {
top: 120px;
}
</style>
</head>
<body>
<button onClick ="rotatex()">rotatex</button>
<button onClick ="rotatey()">rotatey</button>
<button onClick ="rotatez()">rotatez</button>
<div id="cesiumContainer" class="fullSize">
<div id="cesiumxin" style="position:fixed;left:0;z-index:99"><a href="http://cesium.xin" style="color:aliceblue;text-decoration:none">cesium中文网 http://cesium.xin </a></div>
</div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar"></div>
<script>
var viewer = new Cesium.Viewer('cesiumContainer',
{
imageryProvider: new Cesium.SingleTileImageryProvider({
url: '../img/worldimage.jpg'
}),
homeButton: false,
//sceneModePicker: false,
baseLayerPicker: false,
navigationHelpButton: false,
animation: false,
timeline: false,
fullscreenButton: false,
vrButton: false
});
var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url : 'Tileset/tileset.json',
modelMatrix:Cesium.Matrix4.IDENTITY
}));
tileset.readyPromise.then(function() {
var boundingSphere = tileset.boundingSphere;
viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.0, -0.5, boundingSphere.radius * 2));
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
}).otherwise(function(error) {
throw(error);
});
var m = tileset.modelMatrix;
var anglex = 1;
function rotatex(){
anglex += 1;
let m1 = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(anglex));
tileset.modelMatrix = Cesium.Matrix4.multiplyByMatrix3(m,m1,new Cesium.Matrix4());
}
var angley = 1;
function rotatey(){
angley += 1;
let m1 = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(angley));
tileset.modelMatrix = Cesium.Matrix4.multiplyByMatrix3(m,m1,new Cesium.Matrix4());
}
var anglez = 1;
function rotatez(){
anglez += 1;
let m1 = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(anglez));
tileset.modelMatrix = Cesium.Matrix4.multiplyByMatrix3(m,m1,new Cesium.Matrix4());
}
</script>
</body>
</html>
参考文章
https://github.com/CesiumGS/cesium/issues/7633
https://community.cesium.com/t/is-there-is-a-way-to-rotate-the-the-3d-tile-model/5774/4
https://www.cnblogs.com/pumpkin-123/p/11930271.html
https://www.cnblogs.com/huqi-code/p/8288239.html
http://cesium.xin/wordpress/archives/106.html
ES6 函数参数初始化
function test4({x,y}={x:100,y:200}) {
console.log(x,y);
}
test4({}); // undefined undefined
test4(); // 100 200