cesium 模型知识点.txt
https://blog.csdn.net/weixin_42193179/article/details/88050185
分类专栏: cesium
版权
1.
模型(tileset)是由瓦片(tile)组成的。
瓦片(tile)是由构件(feature)构成的。
即,从大到小从宏观到微观:模型(tileset) -> 瓦片(tile)-> 构件(feature)。
比方说,一栋楼(模型)是由多个楼层(瓦片)组成的,每一层是由多个房间(构件)组成的。
模型(瓦片的集合/tileset) > 瓦片(构件的集合/tiles) > 构件(貌似是模型中的最小构件单位/feature)。
2.
加载模型及相关操作。cesiumLab vs marsgis
cesiumLab代码:
方式一、
var longitude = 116.3920432054884;
var latitude = 39.908812421212374;
var height = 42.570401483462206;
var heading = 0;
var tileset = new Cesium.Cesium3DTileset({
url: 'http://localhost:9002/api/folder/8dcd7469fa524370833672fa4ea560ec/tileset.json'
});
viewer.scene.primitives.add(tileset);
tileset.readyPromise.then(function (argument) {
var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
var mat = Cesium.Transforms.eastNorthUpToFixedFrame(position);
var rotationX = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(heading)));
Cesium.Matrix4.multiply(mat, rotationX, mat);
tileset._root.transform = mat;
viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height + 1000)});
});
方式二、
location: {
longitude: 116.39123,
latitude: 39.90691,
height: 0
},
heading: 0,
scale: 1,
range: 500,
add3dtiles: function() {
this.tileset = new Cesium.Cesium3DTileset({
url: this.url
});
var self = this;
this.viewer.scene.primitives.add(this.tileset);
var infowindow = this.$refs.infowindow;
this.tileset.readyPromise.then(function(tileset) {
//获得模型的包围盒大小
self.range = tileset.boundingSphere.radius;
//如果tileset自带世界矩阵矩阵,那么计算放置的经纬度和heading
var mat = Cesium.Matrix4.fromArray(tileset._root.transform);
//原来的矩阵的逆
self.orginMatrixInverse = Cesium.Matrix4.inverse(mat, new Cesium.Matrix4());
var pos = Cesium.Matrix4.getTranslation(mat, new Cesium.Cartesian3());
var wpos = Cesium.Cartographic.fromCartesian(pos);
if (wpos) {
self.location.longitude = Cesium.Math.toDegrees(wpos.longitude);
self.location.latitude = Cesium.Math.toDegrees(wpos.latitude);
self.location.height = wpos.height;
//取旋转矩阵
var rotmat = Cesium.Matrix4.getRotation(mat, new Cesium.Matrix3());
//默认的旋转矩阵
var defrotmat = Cesium.Matrix4.getRotation(Cesium.Transforms.eastNorthUpToFixedFrame(pos), new Cesium.Matrix3());
//计算rotmat 的x轴,在defrotmat 上 旋转
var xaxis = Cesium.Matrix3.getColumn(defrotmat, 0, new Cesium.Cartesian3());
var yaxis = Cesium.Matrix3.getColumn(defrotmat, 1, new Cesium.Cartesian3());
var zaxis = Cesium.Matrix3.getColumn(defrotmat, 2, new Cesium.Cartesian3());
var dir = Cesium.Matrix3.getColumn(rotmat, 0, new Cesium.Cartesian3());
dir = Cesium.Cartesian3.cross(dir, zaxis, dir);
dir = Cesium.Cartesian3.cross(zaxis, dir, dir);
dir = Cesium.Cartesian3.normalize(dir, dir);
var heading = Cesium.Cartesian3.angleBetween(xaxis, dir);
var ay = Cesium.Cartesian3.angleBetween(yaxis, dir);
if (ay > Math.PI * 0.5) {
heading = 2 * Math.PI - heading;
}
this.heading = Cesium.Math.toDegrees(heading);
self.initEditor();
}
//如果tileset不带世界矩阵,那么更新
else {
//self.initEditor();
// self.inputPos();
}
self.locate();
}).otherwise(function(err) {
infowindow.info("3dtiles加载失败:" + err);
});
},
locate: function() {
if (this.tileset.boundingSphere) {
this.viewer.camera.flyToBoundingSphere(this.tileset.boundingSphere);
} else {
this.viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(this.location.longitude, this.location.latitude, this.location.height + 1000)
});
}
},
resetStyle: function() {
if (this.tileset) {
this.tileset.style = undefined;
}
},
locateNode: function(nodeid, nodesphere) {
if (nodesphere[3] <= 0)
return;
//飞行过去
console.log(nodesphere);
var center = new Cesium.Cartesian3(nodesphere[0], nodesphere[1], nodesphere[2]);
if (this.orginMatrixInverse && this.tileset._root.transform) {
var mat = Cesium.Matrix4.multiply(this.tileset._root.transform, this.orginMatrixInverse, new Cesium.Matrix4());
center = Cesium.Matrix4.multiplyByPoint(mat, center, new Cesium.Cartesian3());
}
var sphere = new Cesium.BoundingSphere(center, nodesphere[3]);
this.viewer.camera.flyToBoundingSphere(sphere, {
duration: 0.5
});
//设置tileset的样式
if (this.tileset) {
this.tileset.style = new Cesium.Cesium3DTileStyle({
color: {
conditions: [
["${id} ==='" + nodeid + "'", "rgb(255, 255, 255)"],
["true", "rgba(255, 200, 200,0.2)"]
]
}
});
}
}
marsgis代码:
showModel: function (t) {
null != this.tileset && (viewer.scene.primitives.remove(this.tileset), this.tileset = null), this.tileset = new Cesium.Cesium3DTileset({
url: t,
maximumScreenSpaceError: 1
}), this.viewer.scene.primitives.add(this.tileset);
var i = this;
this.tileset.readyPromise.then(function (e) {
console.log("e:", e);
console.log("e._root:", e._root);
console.log("e._root.transform:", e._root.transform);
// e._root.transform: c {0: -0.890646599990569, 1: -0.454696199594014, 2: 0, 3: 0, 4: 0.28540106310396, 5: -0.559035872114604, 6: 0.778476156904111, 7: 0, 8: -0.353970150018852, 9: 0.693347142320371, 10: 0.627674177525097, 11: 0, 12: -2254681.9484696, 13: 4416409.93097713, 14: 3998093.165514, 15: 1}
e._root && e._root.transform && (i.orginMatrixInverse = Cesium.Matrix4.inverse(e._root.transform, new Cesium.Matrix4)), i.location = mars3d.util.tileset.getCenter(e, !0), (i.location.z < -1e3 || 1e4 < i.location.z) && (i.location.z = 0), i.toView(), i.editor.update({
position: Cesium.Cartesian3.fromDegrees(i.location.x, i.location.y, i.location.z),
heading: Cesium.Math.toRadians(i.location.heading),
range: .9 * e.boundingSphere.radius,
scale: 1
}), i.tileset._root.transform = i.editor.modelMatrix(), i.locate(), showSceneTree(t)
}).otherwise(function (e) {
throw e
}), $("#viewReset").hide()
},
locate: function () {
this.tileset.boundingSphere ? this.viewer.camera.flyToBoundingSphere(this.tileset.boundingSphere) : this.viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(this.location.x, this.location.y, this.location.z + 1e3)})
}
function resetStyle() {
workModel.tileset.style = void 0
}
function locateNode(e, t) {
/*此函数用于,定位模型的最后一级节点。
* e, 节点id。t, 节点包容球[x,y,z,radius],
* 其中x,y,z,代表包容球的球心坐标,单位:米。
* radius,包容球的半径。*/
console.log("e:", e);
// e: 8aa8055c543c4c4a8272bf04d8d671a5
console.log("t:", t);
// t: (4) [-2254678.64016919, 4416402.06381591, 3998110.43911067, 0.13197181397185, remove: ƒ, insert: ƒ]
if (!(t[3] <= 0)) {
var i = workModel.tileset, o = workModel.orginMatrixInverse, r = new Cesium.Cartesian3(t[0], t[1], t[2]);
if (o && i._root.transform) {
var a = Cesium.Matrix4.multiply(i._root.transform, o, new Cesium.Matrix4);
r = Cesium.Matrix4.multiplyByPoint(a, r, new Cesium.Cartesian3)
}
var n = new Cesium.BoundingSphere(r, t[3]);
viewer.camera.flyToBoundingSphere(n, {duration: .5}), i.style = new Cesium.Cesium3DTileStyle({color: {conditions: [["${id} ==='" + e + "'", "rgb(255, 255, 255)"], ["true", "rgba(255, 200, 200,0.2)"]]}})
}
}
3.移除模型
// 移除视图中的模型。
// viewer.scene.primitives.removeAll();
// viewer.scene.primitives.remove(this.tileset);
4.
bim分层时的样式设置方法:
var style = new Cesium.Cesium3DTileStyle();
// 用自定义函数重写颜色表达式。
style.color = {
// 评估颜色。此处feature, result,会自动传参,无需自己操心。
evaluateColor : function(feature, result) {
// 此函数貌似是多进程执行,效率极高。
// 上下两种方式均可。
// return Cesium.Color.TRANSPARENT;
return Cesium.Color.clone(Cesium.Color.WHITE, result);
}
};
示例函数如下:
showOneFloor: function(floorName) {
/*此函数用于,设置模型样式,只展示当前层(floorName)。*/
if (this.tileset) {
var self = this;
// 以下要获取当前层的样式,并把当前模型设置成该样式。
$.ajax({
// 类似这样:"./data/3dtiles/bimYIYUAN/floorsNodesStyle/16F.json"
url: this.url.slice(0,this.url.lastIndexOf('/')+1) + "floorsNodes/" + floorName + ".json",
dataType: 'json',
data: { x: new Date() },
success: function(floor) {
// floor,当前层的信息,包括层名及其子节点id。
var style = new Cesium.Cesium3DTileStyle();
// 用自定义函数重写颜色表达式。
style.color = {
// 评估颜色。此处feature, result,会自动传参,无需自己操心。
evaluateColor : function(feature, result) {
var featureId = feature.getProperty("id");
if(!(featureId in floor.childrenNodesIds)){
// 上下两种方式均可。
// 非当前层的feature的样式。
// return Cesium.Color.TRANSPARENT;
return Cesium.Color.clone(Cesium.Color.TRANSPARENT, result);
}
else {
// 当前层的feature的样式。
// return Cesium.Color.WHITE;
return Cesium.Color.clone(Cesium.Color.WHITE, result);
}
}
};
// 设置当前模型的样式。
self.tileset.style = style;
}
});
}
},
5.
展示全部模型:
showCompleteModel: function() {
/*此函数用于,重置模型到原始样式,即展示整个模型。*/
if (this.tileset) {
this.tileset.style = undefined;
this.layerWork.centerAt(1);
}
}
原文链接:https://blog.csdn.net/weixin_42193179/article/details/88050185