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())
相关推荐
mayaairi32 分钟前
Vue2 事件绑定完全指南:从入门到原理
前端·javascript·vue.js
ℋᙚᵐⁱᒻᵉ鲸落6 小时前
移动端滑动手势冲突:overflow: auto导致外层横向滑动失效
前端·javascript·css·vue.js·html
默_笙8 小时前
🎃 前端学了 Next.js,后端该学啥?NestJS 就是 Node 版的蜜雪冰城
前端·javascript
এ慕ོ冬℘゜9 小时前
navigator 导航对象 BOM制作方法
javascript
kyriewen11 小时前
面试官让我用 AI 重构一个 8 年陈的 React 组件——他说他不看代码,只看我会不会拆
前端·javascript·面试
Jacky199912 小时前
Electron + Vue 3 桌面打字游戏实战:从 VSCode 扩展到独立应用的架构改造
javascript
ToTacview13 小时前
WebGL 没有几何着色器,那 Cesium 的粗线是怎么画出来的?
cesium
柚yuzumi14 小时前
别再猜 this:先看它属于谁,再看它指向谁
前端·javascript
汉堡大王952714 小时前
面试必考:手写代码 new 做了什么?从原理到实现全解析
前端·javascript·面试
BillKu14 小时前
TypeScript中,字符串字面量联合类型(Union Type)、enum的用法说明
前端·javascript·typescript