失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Cesium 视角跟随-第一人称视角漫游

Cesium 视角跟随-第一人称视角漫游

时间:2022-11-09 20:58:09

相关推荐

Cesium 视角跟随-第一人称视角漫游

Cesium 视角跟随-第一人称视角漫游

实现思路核心代码完整代码在线示例

4月19日更新—搞了一个Cesium镜像,欢迎使用:沙盒示例 和 API

作为三维项目,以第一人称视角漫游是比较常见的需求,而 Cesium 默认是不带此功能,因此需要自己实现。

在网上几乎没有发现完整的实现示例,大多都是部分代码或者提供思路,经研究,终于实现功能,这里记录一下。

本文包括实现思路、核心代码以及在线示例三部分。

实现思路

在最开始的时候,作者以为官方会有类似于viewer.trackedEntity = entity;的方法来实现第一人称视角,结果找半天并没有发现。

后来,想的是通过viewer.camera.setViewviewer.camera.lookAtTransform之类的方式实现,结果尝试很多次并没有成功。

viewer.camera.lookAtTransform也可以实现固定视角,但是没找到如何改变仰角,效果不太好,因此放弃。

最后改变思路,尝试实时监听飞行状态,通过viewer.camera.lookAt动态修改视角,实现第一人称视角飞行。

在调整模型角度的时候,因网上的碎片代码,并没有完美设置模型的方向与姿态,稍微花了点时间调整。

完成第一视角跟随之后,还需要取消跟随,按照常规来说,有绑定就应该有解绑。

通过onTickEvent = viewer.clock.onTick.addEventListener绑定,作者认为是viewer.clock.onTick.removeEventListener,结果发现直接调用一次方法也可以,这样更省事:onTickEvent()

至此,第一视角跟随功能已可以完全实现!

核心代码

这里贴上核心代码,具体解释详见注释信息。

// 获取当前模型方向和位置// entityB2 为模型对象const orientation = entityB2.orientation;const position = entityB2.position;// 实时调整位置function adjust() {if (viewer.clock.shouldAnimate === true) {// 获取偏向角let ori = orientation.getValue(viewer.clock.currentTime); // 获取位置let center = position.getValue(viewer.clock.currentTime);// 1、由四元数计算三维旋转矩阵var mtx3 = Cesium.Matrix3.fromQuaternion(ori);// 2、计算四维转换矩阵:var mtx4 = Cesium.Matrix4.fromRotationTranslation(mtx3, center);// 3、计算角度:var hpr = Cesium.Transforms.fixedFrameToHeadingPitchRoll(mtx4);// 获取角度(弧度)const headingTemp = hpr.heading;const pitchTemp = hpr.pitch;// 调整角度为第一人称,注意调整的角度const heading = Cesium.Math.toRadians(Cesium.Math.toDegrees(headingTemp) + 90);const pitch = Cesium.Math.toRadians(Cesium.Math.toDegrees(pitchTemp) - 12);// 视角高度,根据模型大小调整const range = 140.0;// 动态改变模型视角viewer.camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, range));}}onTickEvent = viewer.clock.onTick.addEventListener(adjust);setTimeout(function (){alert('您现在可以拖动了!');// 关闭视角跟随onTickEvent && onTickEvent();},10000);

完整代码

<!DOCTYPE html><html lang="en"><head><!-- Use correct character set. --><meta charset="utf-8"/><!-- Tell IE to use the latest, best version. --><meta http-equiv="X-UA-Compatible" content="IE=edge"/><!-- Make the application on mobile take up the full browser screen and disable user scaling. --><metaname="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/><title>Cesium model first person</title><script src="./Cesium.js"></script><script src="./cesium_init.js"></script><script src="http://www.openlayers.vip/examples/resources/jquery-3.5.1.min.js"></script><style>@import url(./Widgets/widgets.css);html,body,#cesiumContainer {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden;}</style><script>var _hmt = _hmt || [];(function() {var hm = document.createElement("script");hm.src = "/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";var s = document.getElementsByTagName("script")[0];s.parentNode.insertBefore(hm, s);})();</script></head><body><button id="reloadFunc" onClick="reloadFunc()">切换第三人称</button><button id="reloadFunc2" onClick="reloadFunc2()">切换自由模式</button><div id="cesiumContainer"></div><script>// 创建三维球const viewer = init();viewer.scene.debugShowFramesPerSecond = true;// 通过 czml 方式加载,定义数据const czml_team = [{id: "document",name: "flying_follow_team",version: "1.0",clock: {interval: "-03-08T10:00:00Z/-03-08T15:00:00Z",currentTime: "-03-08T10:00:00Z",multiplier: 10,},},{id: "flying_follow_team",name: "path with GPS flight data",description:"测试第一人称视角。",availability: "-03-08T10:00:00Z/-03-08T15:00:00Z",path: {material: {polylineGlow: {color: {rgba: [0, 0, 255, 200],},glowPower: 0.1,taperPower: 0.1,},},width: 20,leadTime: 0,trailTime: 1000,resolution: 0.5,show: true},model: {// 模型参数"gltf": "http://openlayers.vip/cesium/Apps/SampleData/models/CesiumAir/Cesium_Air.glb","minimumPixelSize": 1000,"maximumScale": 20},orientation: {// 自动计算方向"velocityReference": "#position"},position: {// 插值算法"interpolationAlgorithm": "LAGRANGE","interpolationDegree": 5,epoch: "-03-08T10:00:00Z",// 坐标组cartographicDegrees: [0, 118.93830177292894, 25.488280583435404, 0, 300, 119.14034602637892, 25.32388938213355, 2000, 800, 119.43064375816327, 25.230148210056235, 5000, 1500, 120.93105921868252, 24.769194048014963, 12000, 2500, 121.5592902752412, 24.65896429885, 12000, 3500, 121.56445881860067, 25.16649023047563, 5000, 4500, 119.94263373897657, 25.49632056739945, 12000, 5500, 119.30910179629008, 25.559938450361965, 5000, 6500, 118.96295053426707, 25.571485127594467, 0]},},];// 定义变量,模型和视角跟随事件let entityB2, onTickEvent;// 加载数据viewer.dataSources.add(Cesium.CzmlDataSource.load(czml_team)).then(function (ds) {// 获取模型对象entityB2 = ds.entities.getById("flying_follow_team");viewer.trackedEntity = entityB2;// 获取当前模型方向和位置const orientation = entityB2.orientation;const position = entityB2.position;// 实时调整位置function adjust() {if (viewer.clock.shouldAnimate === true) {let ori = orientation.getValue(viewer.clock.currentTime); // 获取偏向角let center = position.getValue(viewer.clock.currentTime); // 获取位置// 1、由四元数计算三维旋转矩阵var mtx3 = Cesium.Matrix3.fromQuaternion(ori);// 2、计算四维转换矩阵:var mtx4 = Cesium.Matrix4.fromRotationTranslation(mtx3, center);// 3、计算角度:var hpr = Cesium.Transforms.fixedFrameToHeadingPitchRoll(mtx4);// 获取角度(弧度)const headingTemp = hpr.heading;const pitchTemp = hpr.pitch;// 调整角度为第一人称const heading = Cesium.Math.toRadians(Cesium.Math.toDegrees(headingTemp) + 90);const pitch = Cesium.Math.toRadians(Cesium.Math.toDegrees(pitchTemp) - 12);// 视角高度,根据模型大小调整const range = 140.0;// 动态改变模型视角viewer.camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, range));}}onTickEvent = viewer.clock.onTick.addEventListener(adjust);});function reloadFunc () {alert('您现在可以拖动改变角度!');// 关闭视角跟随onTickEvent && onTickEvent();viewer.trackedEntity = entityB2;};function reloadFunc2 () {alert('您现在需要自己跟随飞机!');// 关闭视角跟随onTickEvent && onTickEvent();viewer.trackedEntity = undefined;};</script></body></html>

在线示例

示例中展示了,三维地图第一人称飞行

在线示例中,使用的官方模型,有需要 B2 轰炸机模型的可以 点击下载。

Cesium 沙盒测试

三维地图第一人称飞行

参考博客:

Cesium中的相机—setView&lookAtTransform

cesium飞行第一视角

Cesium 设置entity的姿态及获取entity的hpr(仰俯角、偏转角、翻滚角)

如何在Cesium中停用onTick方法

如果觉得《Cesium 视角跟随-第一人称视角漫游》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。