赞
踩
用投射做了两个功能,一个是模拟无人机巡检,展示当前无人机的实时视频流,并且展示当前无人机的拍摄轨迹及范围。
第二个是直接将无人机的视频投射到拍摄范围面上。
代码都差不多,只是第二个用了实时视频做材质,并且实时计算了视频材质的朝向,不然会出现视频方向和移动方向有差异的情况。
思路:移动使用property来进行设置,让坐标和时间进行关联,视频锥体采用自定义geometry的形式,这部分代码可以参考我的另一篇文章Cesium无人机实时视频投射及关键点拍照展示_easyCesium的博客-CSDN博客
部分代码:
调用代码:
其中做了个视角跟随的效果,即会让视角锁定在飞机正上方
ScanRoam核心代码
1、构建property
- createProperty(positions, times) {
- times = times || 120; // 不设置事件和速度 则默认120s播放完成
- var distance = 0;// 总距离
- var speed;
- for (var i = 0; i < positions.length - 1; i++) {
- var oneP = positions[i];
- var secP = positions[i + 1];
- var dis = Cesium.Cartesian3.distance(oneP, secP);
- distance += dis;
- }
- speed = distance / times; // (米/秒)
- this.allDistance = distance;
-
- this.startTime = this.viewer.clock.currentTime;
- this.endTime = Cesium.JulianDate.addSeconds(this.startTime, times, new Cesium.JulianDate());
- var property = new Cesium.SampledPositionProperty(); // 模型的property
- var oldTimes = 0;
- for (var i = 1; i < positions.length; i++) {
- var nowP = positions[i];
- var lastP = positions[i - 1];
- if (i == 1) { // 下标从1开始 此处加上第一个点
- property.addSample(this.startTime, positions[0]);
- }
- oldTimes += Cesium.Cartesian3.distance(nowP, lastP) / speed;
- var nowTime = Cesium.JulianDate.addSeconds(this.startTime, oldTimes, new Cesium.JulianDate());
- property.addSample(nowTime, nowP);
- }
-
- return {
- property
- }
- }
2、实时回调:
- start() {
- this.viewer.clock.currentTime = this.startTime;
- this.viewer.clock.shouldAnimate = true;
- this.viewer.clock.multiplier = 1;
- let last_dis = Number.MAX_VALUE;
- // 绑定时间回调
- this.viewer.clock.onTick.addEventListener(function () {
- let isthan = Cesium.JulianDate.greaterThanOrEquals(this.viewer.clock.currentTime.clone(), this.endTime.clone());
- let nowP = this.property.getValue(this.viewer.clock.currentTime.clone());
- let nextP = this.positions[this.step + 1];
- if (nextP && nowP) {
- let dis = Cesium.Cartesian3.distance(nowP.clone(), nextP.clone());
- if (dis > last_dis) {
- this.step++;
- last_dis = Number.MAX_VALUE;
- } else {
- last_dis = dis;
- }
- } else {
- this.step = this.positions.length - 1;
- }
- if (isthan) { // 结束
- if (this.endFun) this.endFun();
- return;
- }
- let orientation = this.entity.orientation.getValue(this.viewer.clock.currentTime.clone());
- let hpr = this.orientation2Hpr(nowP.clone(), orientation)
- // 设置模型姿态
- if (this.flyingFun) this.flyingFun(nowP, hpr, this.step);
-
- }, this)
-
- }
ConePrimitive核心代码:
- getGeometry(dis, fov, aspect) {
- let positions = new Float64Array(5 * 3);
- fov = Cesium.Math.toRadians(fov / 2);
- const tanfov = Math.tan(fov);
- const halfw = tanfov * dis;
- const halfh = halfw / aspect;
-
- // 点0 坐标
- positions[0] = 0.0;
- positions[1] = 0.0;
- positions[2] = 0.0;
-
- // 点1 坐标
- positions[3] = 1.0 * halfw;
- positions[4] = 1.0 * dis;
- positions[5] = 1.0 * halfh;
-
- // 点2 坐标
- positions[6] = -1.0 * halfw;
- positions[7] = 1.0 * dis;
- positions[8] = 1.0 * halfh;
-
- // 点3 坐标
- positions[9] = -1.0 * halfw;
- positions[10] = 1.0 * dis;
- positions[11] = -1.0 * halfh;
-
- // 点4 坐标
- positions[12] = 1.0 * halfw;
- positions[13] = 1.0 * dis;
- positions[14] = -1.0 * halfh;
-
-
- // 创建顶点属性中的坐标
- const attributes = new Cesium.GeometryAttributes({
- position: new Cesium.GeometryAttribute({
- componentDatatype: Cesium.ComponentDatatype.DOUBLE,
- componentsPerAttribute: 3,
- values: positions
- })
- });
-
- // 点的索引
- const indices = new Uint16Array(18);
-
- indices[0] = 0;
- indices[1] = 4;
-
- indices[2] = 0;
- indices[3] = 1;
-
- indices[4] = 0;
- indices[5] = 2;
-
- indices[6] = 0;
- indices[7] = 3;
-
- indices[8] = 1;
- indices[9] = 4;
-
- indices[10] = 4;
- indices[11] = 1;
-
- indices[12] = 1;
- indices[13] = 2;
-
- indices[14] = 2;
- indices[15] = 3;
-
- indices[16] = 3;
- indices[17] = 4;
-
-
- let geometry = new Cesium.Geometry({
- attributes: attributes,
- indices: indices,
- primitiveType: Cesium.PrimitiveType.LINES,
- boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
- });
-
- return geometry;
- }
-
-
- update(context, frameState, commandList) {
- var geometry = this.getGeometry(this.distance, this.fov, this.aspect);
- if (!geometry) {
- return;
- }
- if (this._primitive) {
- this._primitive.destroy();
- this._primitive = undefined;
- }
-
-
- let headingPitchRoll = new Cesium.HeadingPitchRoll(
- Cesium.Math.toRadians((this.heading || 0)),
- Cesium.Math.toRadians(0),
- Cesium.Math.toRadians(this.pitch || 0)
- );
- var hprmtx = Cesium.Transforms.headingPitchRollToFixedFrame(this.position.clone(), headingPitchRoll);
-
- this._primitive = new Cesium.Primitive({
- geometryInstances: new Cesium.GeometryInstance({
- geometry: geometry,
- attributes: {
- color: Cesium.ColorGeometryInstanceAttribute.fromColor(this.outlineColor)
- }
- }),
- appearance: new Cesium.PerInstanceColorAppearance({
- translucent: false,
- flat: true
- }),
- modelMatrix: hprmtx,
- asynchronous: false,
- show: this.coneVisible
- });
-
-
- this.updateRectangle(hprmtx);
- this._primitive.update(context, frameState, commandList);
-
-
- }
功能体验:在线体验
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。