cesium实现全景图加载

实现cesium对全景图的加载,简单可以分为两步

1. 根据全景图类型,创建对应几何

php 复制代码
    const degreesToRadians = (value: number) => Cesium.Math.toRadians(value)
    
    // radius和fov为入参,radius默认100
    let effectiveRadius = radius ?? 100
    if (fov && fov > 0) {
        effectiveRadius = Math.max(
            effectiveRadius,
            1.0 / Math.tan(degreesToRadians(fov) / 2.0)
        )
    }

    const sphereGeometry = new Cesium.SphereGeometry({
        radius: effectiveRadius,
        vertexFormat: Cesium.VertexFormat.POSITION_AND_NORMAL_AND_ST,
        slicePartitions: slicePartitions ?? DEFAULT_SLICE_PARTITIONS,
        stackPartitions: stackPartitions ?? DEFAULT_STACK_PARTITIONS,
    })

    const geometryInstance = new Cesium.GeometryInstance({
        geometry: sphereGeometry,
        id: id ?? 'panorama-sphere',
    })

2. 将全景图作为纹理贴在几何上

php 复制代码
    // source为全景图图片
    const material = Cesium.Material.fromType('Image', {
        image: source,
    })

    const appearance = new Cesium.EllipsoidSurfaceAppearance({
        material: material,
        flat: true,
        renderState: {
            cull: {
                enabled: false,
            },
        }
    })
    // position根据你拍摄位置经纬高度转为Cartesian3类型
    // hpr是你的偏航/翻滚/俯仰角参数,类型为HeadingPitchRoll
    let modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, hpr)
    
    const primitive = new Cesium.Primitive({
        geometryInstances: geometryInstance,
        appearance,
        modelMatrix,
        asynchronous: false,
    })

    viewer.scene.primitives.add(primitive)

3. 注意点

a. 大多数 equirectangular 全景图在纹理坐标上,0° 水平方向通常对应的是东向,因此,在计算偏航角时需要减去90°

scss 复制代码
    const position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
    const hpr = new Cesium.HeadingPitchRoll(
        degreesToRadians(heading - 90), // 大多数 equirectangular 全景图在纹理坐标上,0° 水平方向通常对应的是东向
        degreesToRadians(pitch),
        degreesToRadians(roll)
    )

b. 从球体内部向外看, 图像是相反的,需要调整

arduino 复制代码
    const scaleMat = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(-1.0, 1.0, 1.0), new Cesium.Matrix4())
    modelMatrix = Cesium.Matrix4.multiply(modelMatrix, scaleMat, new Cesium.Matrix4())
相关推荐
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄1 天前
JavaScript 隐式全局变量解析
javascript
沙蒿同学1 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端
paopaokaka_luck1 天前
智慧社区综合服务小程序(人脸识别、AI问答、Echarts图形化分析)
前端·javascript·spring boot·spring·数据分析·echarts
Hilaku1 天前
为什么死磕 1px 的团队,用户体验反而更差?
前端·javascript·程序员
陈拉斯1 天前
给公司年会写了个大屏抽奖系统:动画在前端跑,凭什么说结果没被改?
javascript
yzy851 天前
Vue中下载或打开文件的JavaScript方法
前端·javascript·vue
用户298698530141 天前
在 React 中用 JavaScript 将 Word 转换为文本
前端·javascript·react.js
李少兄1 天前
深入解析 JavaScript 中的 `document` 对象
javascript