Ceisum无人机巡检视频投放
公司投标内容有个视频投放的功能动画,原本想实现这么一个效果:

案例效果来自别人的展示作品,Leader一眼就相中了这个效果,可惜别人的终究是别人的,又不会白白给你,终究是要自己动手尝试。
动画方面的展示效果我已经非常熟练了,无非就是两种写法1. 实体绑定时间轴,监听路径以及姿态;2. CZML加载模型和点位集合。
为了方便,我一般都用第二种。动画方面没有问题,那么就差一个视椎体视频了,只要把这个做出来,把它跟CZML的时间轴绑定起来就完事了。
Step 0:
思路:构建一个视椎体,然后计算远截面四点坐标,利用这四个点来画一个矩形,贴入视频材质,完成视频在视椎体内播放。
使用CZML播放动画,将视椎体的朝向更正为垂直向下,再将位置绑定给动画中的实体,让它们一起运动。

经过不懈努力拿到一个视椎体方法,可以计算出四点点位,视频作为材质镶嵌到视椎体头部,偶然间尝试到的perPositionHeight: true解决了多边形不贴合问题,视频播放也解决了,一切都在向着美好的方向,最后发现视椎体我控制不了它旋转到垂直向下的方向,这需要足够的矩阵计算能力,还有就是动态更新位置也是个技术大关,一时半会儿搞不定,Game Over!
花费了不少时间去追求最高品质效果,受阻后开始琢磨阉割版。
虽然接下来实现的可能是个简陋功能,但能让Leader有个可以交差的东西,后续有时间再重新研究。
想法:去除视椎体,添加一个适合贴视频的材质,让它跟随无人机一起运动,可以简单实现视频追着无人机飞。
Step 1:
思路: 动态点还是依靠CZML实现,在dataSource.then方法内部作用域中获取路径实体,添加rectangle矩形,所需四个点通过Cesium.CallbackProperty回调函数实时计算。
部分代码:
dataSource.then(function (dataSource) {var entity = dataSource.entities.getById("path");entity.viewFrom = new Cesium.Cartesian3(0.0, 0, 15000.0);that.viewer.trackedEntity = entity;const videoElement = document.getElementById('ceguiji'); //视频早已绑定到标签that.viewer.entities.add({rectangle: {coordinates: new Cesium.CallbackProperty(function (time, result){var sourpos = entity.position.getValue(time);var cartographic1 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(sourpos);var lon1 = Cesium.Math.toDegrees(cartographic1.longitude);var lat1 = Cesium.Math.toDegrees(cartographic1.latitude);var height1 = cartographic1.height;return Cesium.Rectangle.fromDegrees(lon1-0.0001,lat1 - 0.0002, lon1+0.0001, lat1+0.0002)},false),material: videoElement},})}

很容易就出来一个跟随路径飞行的视频,但跟路径夹角基础在45度,视频长宽被拉伸得不成型,还不能变方向,这就是固定点的局限性,直接pass。
Step 2:
思路:将材质换成视频墙,plane比wall更合适,只需要一个动点,长宽皆可由属性定义,这样一个长宽合适的视频就跟随路径移动了,但有个两个问题,一个是大难题怎样实时更新姿态,另一个视频立起来了,我还要让它倒下去,跟地面平行。
部分代码:
var bluePlane = that.viewer.entities.add({name : "Blue plane",position : Cesium.Cartesian3.fromDegrees(118.835100, 35.183068, 190),plane : {plane : new Cesium.Plane(Cesium.Cartesian3.UNIT_Y, 0.0),dimensions : new Cesium.Cartesian2(-150.0, 100.0),material : videoElement,stRotation: Cesium.Math.toRadians(90)},});

经过一系列尝试,我发现解决将它放平的难度可能比解决实时更新姿态的难度更高,AI也说了,这两个材质设计之初就没考虑过空间问题,所以还是换吧。
Step 3:
思路:box材质让我看到了希望,它是一个立体盒子,我可以通过设置长宽、高为0,来实现一个平面视频墙。
var bluePlane = that.viewer.entities.add({name : "Blue plane",position : Cesium.Cartesian3.fromDegrees(118.835100, 35.183068, 190),box: {dimensions : new Cesium.Cartesian3(60.0, 30.0, 0.0),material: videoElement},});

轻松得到一个平行地面的视频材质,所以只剩下最后一个问题,如何让材质跟随路径调整姿态。
Step 4:
思路:我尝试将box加入czml中,这样它可以通过czml的自带属性来实时更新姿态,我就不用考虑变换矩阵
{id: "box",name: "uva-box-fly",availability: "2022-08-04T10:00:00Z/2022-08-04T15:00:00Z",box: {dimensions: {cartesian: [60.0, 30.0]},material: Cesium.Color.RED.withAlpha(0.5),},orientation: {velocityReference: "#position"},model: {gltf: "/models/Cesium_Air.glb",scale: 2},position: {epoch: "2022-08-04T10:00:00Z",cartographicDegrees: [],},},
但我发现视频是横着放的,这个暂且不管,得到下面这个效果。

因为它用的是飞机路径的position,和飞机路线重合,所以就叠一起了,我复制了一份路径存储数组,在push的时候高度降低50,这样就可以分离飞机和视频。
但再看效果,发现连飞机都复刻下来了,简直离谱!

Step 5:
接上一步,既然都是要在dataSource.then中实现,那么加入实体追踪的方式似乎也难不了多少,尝试了一下思路,很轻易就实现了同样的效果,关键点在于设置实体方向orientation: Cesium.Quaternion.IDENTITY,这个值可以根据position初始化姿态,也就可以做到跟随路径同步调整方向,但实现效果上我看到了一个斜放的刀片一样的东西,视频方向永远倾斜,这跟视椎体初始化角度问题一样,是个大毛病。

看到只差最后一步,我只能去搜寻旋转实体的方法,让它在原有姿态基础上旋转到合适角度。原本尝试了Cesium.Transforms.headingPitchRollQuaternion(Cesium.Cartesian3.fromDegrees(lon,lat,height), new Cesium.HeadingPitchRoll(45, 0, 0))这个常用办法,但报错了,搜了一下AI发现这个用于局部坐标系,而我获取到的点已经是Cartesian3,方法不可用,于是尝试更难的四元数矩阵转换,还好没给我出现太多阻碍,连着解决了几个小问题,实现了比较好的一版。
部分代码:
var bluePlane = that.viewer.entities.add({name : "Blue plane",position : Cesium.Cartesian3.fromDegrees(118.835100, 35.183068, 190),orientation: Cesium.Quaternion.IDENTITY,box: {dimensions : new Cesium.Cartesian3(60.0, 30.0, 0.0),material: videoElement},});that.viewer.clock.onTick.addEventListener(function(clock) {var currentTime = that.viewer.clock.currentTime;var currentOrientation = entity.orientation.getValue(currentTime);if (Cesium.defined(currentOrientation) && currentOrientation instanceof Cesium.Quaternion) {var newOrientation = Cesium.Quaternion.clone(currentOrientation);// 应用旋转var rotationQuaternion = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, Cesium.Math.toRadians(-90));var finalOrientation = Cesium.Quaternion.multiply(newOrientation, rotationQuaternion, new Cesium.Quaternion());// 更新实体的 orientationbluePlane.orientation = new Cesium.ConstantProperty(finalOrientation);} else {console.error('Orientation is not a valid Cesium.Quaternion');}})var property = new Cesium.SampledPositionProperty();//存储坐标for (var ind = 0; ind < timesArr.length; ind++) {var time = Cesium.JulianDate.addSeconds(that.viewer.clock.currentTime,timesArr[ind],new Cesium.JulianDate());var position = entity.position.getValue(time);if (position) {var cartographic =Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);var lat = Cesium.Math.toDegrees(cartographic.latitude);var lng = Cesium.Math.toDegrees(cartographic.longitude);var hei = cartographic.height / 1.9;property.addSample(time,Cesium.Cartesian3.fromDegrees(lng, lat, hei));}}bluePlane.position = property;

效果我很满意,实现了我最初的思路,视频和无人机保持相对静止状态,同时飞行和调整朝向,视频可以播放,于是迫不及待地写入了项目。

阉割版视频投屏正式完成了,Leader可以拿去交差了。
两个月后。。。
Leader找到我,问我视频投放这块有什么突破性研究没有,可不可以把之前看到的那个高品质效果做出来,我给了他一个OK的手势。
我在来到这个公司之前,是做军工项目的,对于Cesium用的最多的就是军标绘制,兵力单元的展示等静态方面的效果,交互用的不多,视椎体更是不了解。
在那次受挫之后,我看了很多计算机图形学的文章,搜罗了网上几乎所有对相机视椎体的介绍文章,还从地理专业的高中同学以及考研的大学室友那里取了经,自信已经可以试着把那个功能做出来了。
之前还遗留了个问题,就是关于视椎体为什么会歪的答案,我请教了Cesium中文网的作者,他告诉我视椎体初始姿态会受到地理位置的影响,需要手动矫正。后来我结识了很多Cesium爱好者,互相分享技术,探讨问题,终于在某个Demo中拿到了矫正过的视椎体,虽然方法被做过加密,里面全是单个字母那种变量,让人看的头晕,但我还是将矫正方法给剥离了出来,加入了我的视椎体中,但很神奇的一点,人家可以完美运行的方法,到了我这就不断报错,我逐行检查,发现了几个NaN,原来是计算过程中出现了不符合数学逻辑的东西,由于没找到罪魁祸首,我暂且在中间强行赋值,跳过了几步,让视椎体正常构建而不报错,最后成功矫正了朝向,但也留了个问题,想要在视椎体构建完成之后再次改动朝向,需要重新矫正视椎体,我用的暴力矫正方法可没那么灵活。
不要想太多,先把功能给实现再说,细节方面可以慢慢来。
我重新构建了视椎体,贴上视频,计算出远截面四顶点相对位置,构建平移矩阵移动位置,构建旋转矩阵调整朝向,很好,都成功了,接着加载CZML动画,将视椎体的中心点给绑了上去,视椎体其他部位都是根据中心点来自动调整的。
就在我满含期待之下,纳尼?视椎体不见了?
就在CZML启动之后,视椎体瞬移消失了,我根本不知道它跑哪儿去了,我询问了一些Cesium爱好者,他们说可能是没有考虑缩放等属性,导致视椎体变得很小或者处于隐身状态。
对此我毫无办法,我的能力目前只到这里,超出平移和旋转的知识还是两眼一抹黑,我心想难到就止步于此了吗?
不!我可不是一个人,我的背后还有一支完备的支援大军,我有一个Cesium探讨扣扣群,里面的个个都是人才,说话又好听,于是就将我的问题抛给了群友,期待能从他们那里得到答案。
答案并没有如期拿到,因为群里的老大哥不屑地告诉我,视频投影?群文件里早就上传的有,你干嘛再自己做一个?
于是我找到了那个源码,如获至宝,居然是封装完好的,可以直接拿来用,于是我就改变思路,在这个封装方法的基础上继续完成我的无人机视频投放。封装的方法只到改变初始姿态这点,后面的都要我自己加上,但这对我而言完全不是问题,很快我就看到了效果。


感谢群友的贡献,功能真的很完美,效果跟Leader相中的那个案例作品差不多。
视频投影源码是别人的成果,我就不私自放了。
相关文章:
Ceisum无人机巡检视频投放
公司投标内容有个视频投放的功能动画,原本想实现这么一个效果: 案例效果来自别人的展示作品,Leader一眼就相中了这个效果,可惜别人的终究是别人的,又不会白白给你,终究是要自己动手尝试。 动画方面的展示…...
分享几款开源好用的图片在线编辑,适合做快速应用嵌入
图片生成器是指一种工具或软件,用于自动生成图片或图像内容,通常依据用户设定的参数或模板进行操作。这种工具能够帮助用户快速创建视觉效果丰富的图像,而无需具备专业的设计技能。 在数字化时代,图片编辑已经成为日常工作和生活的…...
闪存学习_1:Flash-Aware Computing from Jihong Kim
闪存学习_1:Flash-Aware Computing from Jihong Kim 前言一、Storage Media:NAND Flash Memory1、概念2、编程和擦除操作3、读操作4、异地更新操作(Out-Place Update)5、数据可靠性6、闪存控制器(SSD主控)7…...
如何将本地项目上传至Gitee仓库(详细教程)
前提条件 1、本地电脑安装Git客户端 2、本地已有项目 3、Gitee注册好了账户 如果没有安装Gitee 可以区菜鸟查看一下安装教程 Git教程https://www.runoob.com/git/git-tutorial.html 操作示例 前提条件已经准备好的情况下登录gitee 码云 https://gitee.com 点解右侧加号 新…...
redis详细教程(3.hash和set类型)
hash Redis中的Hash是一种数据结构,用于存储键值对集合。在Redis中,Hash非常适合表示对象,其中对象的每个字段都对应一个键值对。以下是关于Redis中Hash的详细讲解: 特点: 1. 键值对集合:Hash是一个包含…...
性能测试详解
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 一、 性能测试术语解释 1. 响应时间 响应时间即从应用系统发出请求开始,到客户端接收到最后一个字节数据为止所消耗的时间。响应时间按软件的特点…...
修改ruoyi的logo和标题
1、修改网页标签上的图标和标题 静态修改 标签页上的 图标 直接替换public/favicon.ico文件为你自己的图标文件 如果你的图标文件名不是favicon.ico,你还需要在public/index.html中相应地修改这一行,将/favicon.ico替换为你的图标文件路径。 静态修改…...
vue系列==vue3新语法
vue系列vue3新语法 1、setup组合式API入口函数 2、利用ref函数定义响应式数据 3、利用reactive函数定义响应式数据 1、setup组合式API入口函数 1、Vue3为组合式API提供了一个setup函数,所有组合式API函数都是在此函数中调用的,它是组合式API的使用入口…...
001-Kotlin界面开发之Jetpack Compose Desktop学习路径
Compose Desktop学习之路 学习过程 理解Kotlin的基本语法 Compose Desktop采用Kotlin构建,因此对Kotlin的基本语法有很好的理解是必不可少的。你可以从官方的Kotlin文档开始。 用一句话概括,Kotlin是一种现代的、静态类型的编程语言,它结合…...
qt QStackedLayout详解
QStackedLayout类提供了一种布局方式,使得在同一时间内只有一个子部件(或称为页面)是可见的。这些子部件被维护在一个堆栈中,用户可以通过切换来显示不同的子部件,适合用在需要动态显示不同界面的场景,如向…...
python实现钉钉群机器人消息通知(消息卡片)
直接上代码 python """ 飞书群机器人发送通知 """ import time import urllib3 import datetimeurllib3.disable_warnings()class DingTalkRobotAlert():def __init__(self):self.webhook webhook_urlself.headers {Content-Type: applicatio…...
防火墙技术应用
目录 防火墙安全功能指标防火墙性能指标防火墙部署防火墙应用案例-Linux防火墙防火墙应用案例-华为包过滤防火墙ACL(基本)防火墙应用案例-工控防火墙部署 防火墙安全功能指标 我们防火墙也会提供各种各样的互联接口,它这种接口有以太网、快速以太网、千兆以太网&am…...
docker engine stopped
1)环境:win 10 2)docker安装时已经已经安装了虚拟机 3)启用网络适配器 4)启用docker服务(依赖服务LanmanServer) 5)全都弄好了,docker还是打不开,没办法了&a…...
Redis- 内核的分配内存限制的警告“WARNING Memory overcommit must be enabled!”
文章目录 问题描述报错原因影响解决方案注意事项 问题描述 [rootredisxxx]# redis-sentinel ./sentinel.conf 19638:X 01 Nov 2024 16:57:27.180 # WARNING Memory overcommit must be enabled! Without it, background save or replication may fail under low memory condi…...
腾讯云在线扩容数据盘
文章目录 一、查询云硬盘使用的分区形式二、根据不同的云硬盘类型进行在线扩容分区2.1 安装 gdisk 工具。2.2 安装 growpart 工具使用 growpart 工具扩容分区 三、根据不同的云硬盘类型进行在线扩容文件系统3.1 扩容 EXT 文件系统3.2 扩容 XFS 文件系统 一、查询云硬盘使用的分…...
Time Travel Queries|在 RisingWave 中访问历史数据
对于许多组织来说,能够访问历史数据十分关键。以金融交易公司为例: 特定时间点的数据快照与合规审查、审计流程息息相关。企业的关键业务系统也依赖历史数据来恢复故障并重建系统。分析过去事件及其对当前状况的影响,还有助于准确预测并制定…...
Unity之UnityWebRequest
复习UnityWebRequest 介绍下载文件和上传文件下载进度和异常验证文件DownloadHandlerScript 介绍 unity中使用UnityWebRequest来代替所有HTTP请求提供了三种API,UnityWebRequest.Get,UnityWebRequest.Post,UnityWebRequest.Put分别处理GET,POST,PUT请求…...
使用 pkg 打包 Puppeteer 应用:跨平台自动化的轻量级选择
使用 pkg 打包 Puppeteer 应用 pkg 是一个非常强大的工具,它允许你将 Node.js 项目打包成独立的可执行文件,这意味着你可以在没有安装 Node.js 环境的设备上运行该应用。这对于希望分发不暴露源代码的应用程序、创建跨平台的快速演示版本或简化部署流程…...
【Flask】三、Flask 常见项目架构
目录 前言 简单项目结构 中型项目结构 复杂项目结构 前言 Flask是一个轻量级的Web应用框架,它被广泛用于快速开发简单的网站和复杂的大型应用。随着项目规模的增长,合理的项目架构变得尤为重要。这里探讨Flask项目中的三种常见架构&…...
AI机西使用体验:你不知道的强大功能揭秘!
AI机西有人用过吗?用户体验和功能详解 最近我听说了很多关于AI机西的讨论,很多人都在问:这款工具好用吗?有没有人用过?今天我就从我的使用体验出发,给大家分享一下AI机西的功能和我的感受。 1. 绘画功能&a…...
系统辨识避坑指南:为什么你的最小二乘估计总是不准?从理论到MATLAB仿真的5个常见误区
系统辨识避坑指南:为什么你的最小二乘估计总是不准?从理论到MATLAB仿真的5个常见误区 在系统辨识的实际应用中,许多学习者和初级研发人员都会遇到一个共同的困惑:明明按照教科书上的步骤进行操作,为什么得到的结果却总…...
5分钟学会:用SlopeCraft制作惊艳的Minecraft立体地图画终极指南
5分钟学会:用SlopeCraft制作惊艳的Minecraft立体地图画终极指南 【免费下载链接】SlopeCraft Map Pixel Art Generator for Minecraft 项目地址: https://gitcode.com/gh_mirrors/sl/SlopeCraft 你是否曾想将心爱的照片或艺术作品变成Minecraft世界中的立体艺…...
买服装模板机选中捷、川田、杰克还是慧拿?紧凑型流水线升级,空间与适配才是核心决策
在服装智能制造全面普及的今天,线上模板机已经成为服装企业改造紧凑流水线、实现降本增效的核心装备。当前市场上,中捷、川田、杰克、慧拿四大品牌稳居全球服装自动化设备第一梯队,技术实力、产品品质、品牌口碑均处于行业头部水平。面对 “选…...
VSCode里Code Runner跑Python总报9009?别慌,检查一下你的setting.json文件
VSCode中Code Runner执行Python报错9009的终极排查指南 当你第一次在VSCode中用Code Runner插件运行Python脚本,满心期待看到输出结果时,终端却弹出"Process exited with code 9009"的红色错误提示——这种挫败感我深有体会。这个看似神秘的错…...
手把手教你搞定Windows下的NAMD和VMD安装(附最新版下载与注册避坑指南)
Windows平台NAMD与VMD安装全攻略:从零开始玩转分子动力学模拟 当第一次接触分子动力学模拟时,软件安装往往是新手面临的第一个挑战。NAMD和VMD作为该领域最常用的工具组合,它们的安装过程看似简单,实则暗藏诸多细节。本文将带你从…...
3分钟解锁Translumo:Windows平台屏幕实时翻译的终极解决方案
3分钟解锁Translumo:Windows平台屏幕实时翻译的终极解决方案 【免费下载链接】Translumo Advanced real-time screen translator for games, hardcoded subtitles in videos, static text and etc. 项目地址: https://gitcode.com/gh_mirrors/tr/Translumo 还…...
暗黑3终极宏工具D3KeyHelper:5分钟配置你的自动战斗系统
暗黑3终极宏工具D3KeyHelper:5分钟配置你的自动战斗系统 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper D3KeyHelper是一款专为暗黑破坏神…...
告别命令行!用这个免费软件5分钟搞定Abaqus三维Voronoi泡沫模型
五分钟可视化构建Abaqus三维Voronoi泡沫模型:零代码解决方案全指南 在材料科学与工程仿真领域,三维Voronoi泡沫结构的建模一直是学术研究和工业应用的热点。这种仿生多孔结构因其优异的力学性能和轻量化特性,被广泛应用于缓冲材料、骨科植入物…...
B站视频下载终极指南:3分钟掌握无水印高清下载技巧
B站视频下载终极指南:3分钟掌握无水印高清下载技巧 【免费下载链接】BiliDownload B站视频下载工具 项目地址: https://gitcode.com/gh_mirrors/bil/BiliDownload 你是否曾经想要保存B站上的精彩视频,却发现下载过程复杂繁琐?或者需要…...
CANopen设备配置不求人:手把手教你用EDS/DCF文件玩转对象字典
CANopen设备配置实战:从EDS/DCF解析到对象字典高效配置 在工业自动化领域,CANopen协议因其开放性和灵活性成为设备互联的主流选择。而对象字典(Object Dictionary)作为CANopen设备的核心配置数据库,其管理效率直接影响项目开发周期。本文将带…...
