# 添加 3D Tiles,并调整位置
## 3D Tiles 是什么
3DTiles数据集是cesium小组AnalyticlGraphics与2016年3月定义的一种数据集,3DTiles数据集以分块、分级渲染,将大数据量三维数据以分块,分层的形式组织起来,可以大量减轻浏览器和GPU的负担是一个优秀的,并且格式公开的数据格式。
3D Tiles将用于流式传输3D内容,包括建筑物,树木,点云和矢量数据。
参考 [官网 3dtiles 介绍](https://cesium.com/blog/2015/08/10/introducing-3d-tiles/)
## 3D Tiles
3D Tiles将用于流式传输3D内容,包括建筑物,树木,点云和矢量数据。
contextCapture 可以将无人机成果转换成Cesium支持的倾斜摄影成果,当前例子就是使用的这种成果。
数据的加载比较简单
```
var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: url, //数据路径
maximumScreenSpaceError: 2, //最大的屏幕空间误差
maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数
modelMatrix: m //形状矩阵
}));
```
但是问题在于生成的数据不一定是落在地面上,有可能是浮在空中的,例如:
![3dtiles-in-sky](https://box.kancloud.cn/f2d41854a9e9ac919621a91cc008c137_491x497.png)
这并不是我们想要的,我们希望拍摄的成果能贴到地面上,和地图能很好的融合在一起,类似这样
![3dtiles-on-ground](https://box.kancloud.cn/206833667eb04ffbe9d3e450a7c7e027_545x440.png)
由于单个瓦片的位置信息是写到了数据中的(.b3dm和对应的json文件中),如果能整体调整加载后的tileset,就会是最好的选择,这里就要提到本文的主角:
## modelMatrix
通过查看API文档,我们发现Cesium3DTile里面有一个属性,可以更改位置(当然通过查看源码也可以查这个)
```
transform : Matrix4 Scene/Cesium3DTile.js 88
The local transform of this tile
```
说明通过矩阵运算是可以调整整个数据的显示位置的
###1. 自己获取偏移量
参考《WebGl编程指南》的第三章第四章
![](https://box.kancloud.cn/655c914cb81271400b94a58c40a686b8_279x127.png)
Tx,Ty,Tz就是我们需要设置的 x,y,z方向上的平移距离
由于Cesium的矩阵是列主序的,所以这里写成
```
//创建平移矩阵方法一
// m = Cesium.Matrix4.fromArray([
// 1.0, 0.0, 0.0, 0.0,
// 0.0, 1.0, 0.0, 0.0,
// 0.0, 0.0, 1.0, 0.0,
// x, y, z, 1.0
// ]);
//创建平移矩阵方法二
var translation=Cesium.Cartesian3.fromArray([x, y, z]);
m= Cesium.Matrix4.fromTranslation(translation);
//生效
tileset._modelMatrix = m;
```
这里我们只需要不断的修改 x,y,z,就可以调整物体的位置了
获取 x,y,z 之后,在加载3D Tiles 时将modelMatrix 设置成目标 x,y,z值,就完成了
![](https://box.kancloud.cn/696e01c6811887cc73886831bcbb21d7_1280x905.jpg)
###2. 计算偏移量
官方示例 [3D Tiles Adjust Height](http://localhost:8080/Apps/Sandcastle/index.html?src=3D%20Tiles%20Adjust%20Height.html&label=3D%20Tiles)
一步到位
```
//方法二,直接调用函数,调整高度,height表示物体离地面的高度
function changeHeight(height) {
height = Number(height);
if (isNaN(height)) {
return;
}
var cartographic = Cesium.Cartographic.fromCartesian(tileset.boundingSphere.center);
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude,height);
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
}
```
参考代码:[lesson02](https://gitee.com/HQCode/Cesium-test/tree/master)
>旋转参考
```
Cesium.knockout.getObservable(viewModel, 'rotatex').subscribe(function(rotatex) {
var mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(rotatex));
tileset.modelMatrix = Cesium.Matrix4.fromRotationTranslation(mx);
});
```
**Cesium学习交流群:593764057(满),476893082**
- cesium编程入门(一)cesium简介
- cesium编程入门(二)环境搭建
- cesium编程入门(三)开始使用cesium开发
- cesium编程入门(四)界面介绍及小控件隐藏
- cesium编程入门(五)绘制形状
- cesium编程入门(六)添加 3D Tiles,并调整位置,贴地
- cesium编程入门(七)3D Tiles,模型旋转
- cesium编程入门(八)设置材质
- cesium编程入门(九)实体 Entity
- cesium编程入门(十)优秀资源
- cesium编程入门(十一)常见问题
- cesium编程中级开篇
- cesium编程中级(一)添加示例到Sandcastle
- cesium编程中级(二)源码编译
- cesium编程中级(三)尝试添加PBS本地服务
- cesium编程中级(四)使用渐变纹理