02-Cesium加载gltf模型

1.js中class类中的#代表类内部私有方法

在 JavaScript 中,类方法名以 # 开头表示这些方法是私有方法。这是 ECMAScript 的一个新特性,称为“私有字段”(Private Fields)。私有字段只能在类的内部访问,不能在类的外部访问,从而增强了封装性和安全性。

class MyClass {
    #privateMethod() {
        // 私有方法的实现
    }

    publicMethod() {
        // 可以在类的内部调用私有方法
        this.#privateMethod();
    }
}

2.Cesium加载gltf

  • constructor:类的构造函数,初始化模型的各种属性。
  • createFeature:创建并添加模型实体到 Cesium 视图中。
  • remove:删除模型实体。
  • setHeadingPitchRoll:设置模型的旋转角度。
  • locate:定位到模型的位置。
  • setClippingPlane:根据两个点设置模型的裁剪平面。

通过这些方法,你可以方便地加载、管理、旋转和裁剪 GLTF 模型。希望这对你理解代码有所帮助!如果有其他具体的问题或需求,请随时提出。

class LoaderGltf {
    /**
     * 加载gltf模型
     * @param {Object} options 
     * @param {Number} options.lon 经度 
     * @param {Number} options.lat 纬度 
     * @param {Number} [options.height=0] 高度 
     * @param {String} options.url 模型地址 
     * @param {Number} [options.scale = 1] 缩放倍数
     * @param {Object} [options.rotation = {heading:0,pitch:0,roll:0}] 旋转  Heading:绕y轴转;Pitch:绕x轴转;Roll:绕z轴转
     */
    constructor(options = {}, map) {
        this.url = options.url;
        this.lon = options.lon;
        this.lat = options.lat;
        this.height = options.height || 0;
        this.scale = options.scale || 1;
        this.headingPitchRoll = options.headingPitchRoll || { heading: 0, pitch: 0, roll: 0 };
        this.map = map;
        this.clippingPlanePoint = [];
        this.id = options.id || Cesium.createGuid();
        this.createFeature();
    }
    /**
     * 加载模型
     */
    createFeature() {
        let headingPitchRoll = this.headingPitchRoll;
        let position = Cesium.Cartesian3.fromDegrees(this.lon, this.lat, this.height);

        let entity = new Cesium.Entity({
            id: this.id,
            position: position,
            orientation: Cesium.Transforms.headingPitchRollQuaternion(
                position,
                new Cesium.HeadingPitchRoll(
                    Cesium.Math.toRadians(headingPitchRoll.heading),
                    Cesium.Math.toRadians(headingPitchRoll.pitch),
                    Cesium.Math.toRadians(headingPitchRoll.roll)
                )
            ),
            model: {
                uri: this.url,
                scale: this.scale,
                maximumScale: this.scale
            }
        });
        this.map.viewer.entities.add(entity);
        this.feature = entity;
    }
    /**
     * 删除元素
     */
    remove() {
        this.map.viewer.entities.removeById(this.id);
    }
    /**
     * 设置旋转角度
     * @param {*} headingPitchRoll 
     */
    setHeadingPitchRoll(headingPitchRoll) {
        if (headingPitchRoll) {
            this.headingPitchRoll = headingPitchRoll;
            let position = Cesium.Cartesian3.fromDegrees(this.lon, this.lat, this.height);
            let hpr = Cesium.Transforms.headingPitchRollQuaternion(
                position,
                new Cesium.HeadingPitchRoll(
                    Cesium.Math.toRadians(this.headingPitchRoll.heading),
                    Cesium.Math.toRadians(this.headingPitchRoll.pitch),
                    Cesium.Math.toRadians(this.headingPitchRoll.roll)
                )
            );
            this.feature.orientation.setValue(hpr)
            this.setClippingPlane(this.clippingPlanePoints);
        }
    }
    /**
     * 定位到模型位置
     */
    locate() {
        this.map.viewer.zoomTo(this.feature);
    }
    /**
     * 两个点裁剪模型
     * @param {Array<[lon,lat]>} points 
     */
    setClippingPlane(points = []) {
        this.clippingPlanePoints = points;
        if(points.length>1){
            let position = Cesium.Cartesian3.fromDegrees(this.lon, this.lat, this.height);
            let hpr = new Cesium.HeadingPitchRoll(
                Cesium.Math.toRadians(this.headingPitchRoll.heading),
                Cesium.Math.toRadians(this.headingPitchRoll.pitch),
                Cesium.Math.toRadians(this.headingPitchRoll.roll)
            );
            let inverseTransform = Cesium.Transforms.headingPitchRollToFixedFrame(position, hpr);
            inverseTransform = Cesium.Matrix4.inverseTransformation(inverseTransform,new Cesium.Matrix4());

            const p1C3 = this.#getOriginCoordinateSystemPoint(points[0], inverseTransform)
            const p2C3 = this.#getOriginCoordinateSystemPoint(points[1], inverseTransform)

            // 定义一个垂直向下的向量up
            const up = new Cesium.Cartesian3(0, 0, -10)
            //  right 实际上就是由p1指向p2的向量
            const right = Cesium.Cartesian3.subtract(p2C3, p1C3, new Cesium.Cartesian3())

            // 计算normal, right叉乘up,得到平面法向量,这个法向量指向right的右侧
            let normal = Cesium.Cartesian3.cross(right, up, new Cesium.Cartesian3())
            normal = Cesium.Cartesian3.normalize(normal, normal)

            // 由于已经获得了法向量和过平面的一点,因此可以直接构造Plane,并进一步构造ClippingPlane
            const planeTmp = Cesium.Plane.fromPointNormal(p1C3, normal)
            let clippingPlanes = Cesium.ClippingPlane.fromPlane(planeTmp)
            this.feature.model.clippingPlanes = new Cesium.ClippingPlaneCollection({
                planes:[clippingPlanes]
            });
        }else{
            this.feature.model.clippingPlanes = undefined;
        }
    }

    #getOriginCoordinateSystemPoint(point, inverseTransform) {
        const val = Cesium.Cartesian3.fromDegrees(point[0], point[1])
        return Cesium.Matrix4.multiplyByPoint(
            inverseTransform, val, new Cesium.Cartesian3(0, 0, 0))
    }
}

export default LoaderGltf;

Cesium是一个用于构建地球浏览应用的JavaScript库。它能够加载和渲染各种类型的3D模型,包括gltf模型。 要在Cesium加载gltf模型,首先需要引入Cesium库文件。可以使用<script>标签将cesium.js导入到HTML文件中。 接下来,在JavaScript代码中使用Cesium的Viewer对象创建一个视图器,用于显示地球场景。可以通过指定一个HTML元素的id来指定视图器的容器。例如,可以使用以下代码创建一个视图器: var viewer = new Cesium.Viewer('cesiumContainer'); 这里的'cesiumContainer'是要显示场景的HTML元素的id。 然后,可以使用Cesium的Entity对象创建一个实体,该实体可以包含gltf模型的位置、方向和缩放信息。可以使用以下代码创建一个实体: var modelEntity = viewer.entities.add({ name: 'gltfModel', position: Cesium.Cartesian3.fromDegrees(longitude, latitude, height), orientation: Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, Cesium.Math.toRadians(rotation)), model: { uri: 'path/to/model.gltf' } }); 这里的longitude、latitude和height是模型在地球上的位置,rotation是模型的初始方向角度。 最后,调用Cesium的Viewer对象的render函数来渲染场景。可以将此函数放在循环中,以便持续渲染场景。 viewer.render(); 通过以上步骤,就可以在Cesium中成功加载并显示一个gltf模型了。您可以根据需要调整模型的位置、方向、缩放等属性,以实现更多的效果和交互。另外,Cesium还提供了许多其他功能和API,可以用于对模型进行更高级的操作和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值