cesium 模型知识点.txt

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值