deeptwins-engine-3d 0.0.47 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,7 @@ interface Position {
6
6
  lng: number;
7
7
  lat: number;
8
8
  alt: number;
9
+ timestamp?: number;
9
10
  }
10
11
  export default class ModelRoamRealTime {
11
12
  readonly _map: any;
@@ -16,16 +17,21 @@ export default class ModelRoamRealTime {
16
17
  private readonly _onPositionUpdate;
17
18
  modelLayer: any;
18
19
  polylineLayer: any;
19
- private positions;
20
- private positionsLineC3;
21
- private positionInterC3;
22
- private _eventPreUpdate;
20
+ private _lastFrameTime;
21
+ private _stepAccumulator;
22
+ private _frameCount;
23
+ private _fps;
24
+ private _time;
25
+ private receivedPositions;
26
+ private completedSegments;
27
+ private currentSegment;
28
+ private futureSegments;
29
+ private currentPointIndex;
30
+ private segmentCounter;
31
+ private _eventPostUpdate;
23
32
  private modelMatrix;
24
33
  private hpRoll;
25
- private _time;
26
34
  status: 'stop' | 'running' | 'destroy';
27
- private currentPathIndex;
28
- private maxPathIndex;
29
35
  private targetHeading;
30
36
  private currentHeading;
31
37
  private rotationSpeed;
@@ -35,9 +41,20 @@ export default class ModelRoamRealTime {
35
41
  /**
36
42
  * 实时添加点位
37
43
  * @param newPosition 新位置点
38
- * @throws 如果新位置与上一个位置完全相同
39
44
  */
40
45
  updatePosition(newPosition: Position): void;
46
+ /**
47
+ * 判断两个位置是否相同
48
+ */
49
+ private isSamePosition;
50
+ /**
51
+ * 创建新的路径段
52
+ */
53
+ private createNewSegment;
54
+ /**
55
+ * 开始漫游
56
+ */
57
+ private startRoaming;
41
58
  /**
42
59
  * 计算两点之间的路径点
43
60
  * 使用插值算法生成平滑的路径
@@ -49,7 +66,7 @@ export default class ModelRoamRealTime {
49
66
  private _getInterPosition;
50
67
  /**
51
68
  * 初始化模型
52
- * 加载模型
69
+ * 加载模型到第一个位置
53
70
  * @param initialPosition 初始位置
54
71
  */
55
72
  private initModel;
@@ -58,6 +75,31 @@ export default class ModelRoamRealTime {
58
75
  * 更新模型位置、朝向和路径线
59
76
  */
60
77
  private updateModel;
78
+ /**
79
+ * 完成当前路径段,切换到下一个路径段
80
+ */
81
+ private completeCurrentSegment;
82
+ /**
83
+ * 初始化轨迹线Entity
84
+ */
85
+ private initTrailLine;
86
+ /**
87
+ * 获取轨迹线位置点
88
+ * 返回:已完成路径段的起始点和结束点 + 当前路径段已飞行的插值点
89
+ */
90
+ private getTrailLinePositions;
91
+ /**
92
+ * 更新轨迹线 - 现在由CallbackProperty自动更新
93
+ */
94
+ private updateTrailLine;
95
+ /**
96
+ * 获取当前状态信息
97
+ */
98
+ getStatus(): any;
99
+ /**
100
+ * 获取详细的飞行信息
101
+ */
102
+ getFlightDetails(): any;
61
103
  /**
62
104
  * 计算模型朝向
63
105
  * @param start 起始点
@@ -20,6 +20,10 @@ import { colorString } from "../tool/utils";
20
20
  * 位置信息
21
21
  */
22
22
 
23
+ /**
24
+ * 路径段信息
25
+ */
26
+
23
27
  /**
24
28
  * 相机设置
25
29
  */
@@ -44,28 +48,37 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
44
48
  _defineProperty(this, "modelLayer", void 0);
45
49
  // 轨迹layer
46
50
  _defineProperty(this, "polylineLayer", void 0);
47
- // 所有位置信息点
48
- _defineProperty(this, "positions", []);
49
- // 所有轨迹位置信息点 Cartesian3
50
- _defineProperty(this, "positionsLineC3", []);
51
- // 插值后的位置信息点 Cartesian3
52
- _defineProperty(this, "positionInterC3", []);
51
+ // 上一帧时间
52
+ _defineProperty(this, "_lastFrameTime", performance.now());
53
+ // 累加器
54
+ _defineProperty(this, "_stepAccumulator", 0);
55
+ _defineProperty(this, "_frameCount", 0);
56
+ _defineProperty(this, "_fps", 'N/A');
57
+ // 重新设计的数据结构
58
+ // 上个点位的时间
59
+ _defineProperty(this, "_time", performance.now());
60
+ // 接收到的原始位置数据
61
+ _defineProperty(this, "receivedPositions", []);
62
+ // 已完成飞行的路径段
63
+ _defineProperty(this, "completedSegments", []);
64
+ // 当前正在飞行的路径段
65
+ _defineProperty(this, "currentSegment", null);
66
+ // 未来计划飞行的路径段队列
67
+ _defineProperty(this, "futureSegments", []);
68
+ // 当前在路径段中的索引位置
69
+ _defineProperty(this, "currentPointIndex", 0);
70
+ // 路径段计数器
71
+ _defineProperty(this, "segmentCounter", 0);
53
72
  // 帧率更新的事件
54
- _defineProperty(this, "_eventPreUpdate", void 0);
73
+ _defineProperty(this, "_eventPostUpdate", void 0);
55
74
  // 模型参数
56
75
  // 模型变换矩阵
57
76
  _defineProperty(this, "modelMatrix", new Cesium.Matrix4());
58
77
  // 模型姿态
59
78
  _defineProperty(this, "hpRoll", new Cesium.HeadingPitchRoll());
60
79
  // 漫游相关
61
- // 上个点位的时间
62
- _defineProperty(this, "_time", new Date().getTime());
63
80
  // 状态
64
81
  _defineProperty(this, "status", 'stop');
65
- // 当前漫游路径点索引
66
- _defineProperty(this, "currentPathIndex", 0);
67
- // 最大路径点索引
68
- _defineProperty(this, "maxPathIndex", 0);
69
82
  // 目标朝向角度
70
83
  _defineProperty(this, "targetHeading", 0);
71
84
  // 当前朝向角度
@@ -87,57 +100,47 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
87
100
  * 更新模型位置、朝向和路径线
88
101
  */
89
102
  _defineProperty(this, "updateModel", function () {
90
- if (_this.currentPathIndex >= _this.maxPathIndex) {
103
+ var currentTime = performance.now();
104
+ _this._frameCount++;
105
+ if (currentTime - _this._lastFrameTime > 1000) {
106
+ _this._fps = _this._frameCount;
107
+ _this._frameCount = 0;
108
+ _this._lastFrameTime = currentTime;
109
+ }
110
+ if (!_this.currentSegment || _this.status !== 'running') {
111
+ return;
112
+ }
113
+
114
+ // 检查当前路径段是否完成
115
+ if (_this.currentPointIndex >= _this.currentSegment.interpolatedPoints.length) {
116
+ _this.completeCurrentSegment();
91
117
  return;
92
118
  }
93
- if (_this.currentPathIndex > 0 && _this.currentPathIndex < _this.positionInterC3.length - 1 && !_this.positionInterC3[_this.currentPathIndex - 1].equals(_this.positionInterC3[_this.currentPathIndex])) {
94
- _this.getHeading(_this.positionInterC3[_this.currentPathIndex - 1], _this.positionInterC3[_this.currentPathIndex]);
119
+ var currentPos = _this.currentSegment.interpolatedPoints[_this.currentPointIndex];
120
+
121
+ // 计算朝向
122
+ if (_this.currentPointIndex > 0) {
123
+ var prevPos = _this.currentSegment.interpolatedPoints[_this.currentPointIndex - 1];
124
+ _this.getHeading(prevPos, currentPos);
95
125
  }
126
+
96
127
  // 更新朝向
97
128
  _this.updateHeading();
98
- var currentPos = _this.positionInterC3[_this.currentPathIndex];
99
- if (!_this.positionsLineC3.some(function (pos) {
100
- return pos.equals(currentPos);
101
- })) {
102
- _this.positionsLineC3.push(currentPos);
103
- if (_this.positions.length > 1) {
104
- // 更新轨迹
105
- _this.polylineLayer && _this._map.scene.primitives.remove(_this.polylineLayer);
106
- var trailGeometry = new Cesium.GeometryInstance({
107
- id: '_modelRoamRealTimePolyline',
108
- geometry: new Cesium.PolylineGeometry({
109
- positions: _this.positionsLineC3,
110
- width: _this.polylineOptions.width,
111
- vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT
112
- })
113
- });
114
- _this.polylineLayer = _this._map.scene.primitives.add(new Cesium.Primitive({
115
- geometryInstances: trailGeometry,
116
- appearance: _this.polylineLayer ? _this.polylineLayer.appearance : new Cesium.PolylineMaterialAppearance({
117
- material: new Cesium.Material({
118
- fabric: {
119
- type: 'Color',
120
- uniforms: {
121
- color: colorString(_this.polylineOptions.color)
122
- }
123
- }
124
- })
125
- }),
126
- asynchronous: false
127
- }));
128
- }
129
- }
130
- if (_this.modelLayer && _this.currentPathIndex < _this.positionInterC3.length) {
131
- // 更新模型位置
132
- var _position = _this.positionInterC3[_this.currentPathIndex];
133
- _this.modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(_position, _this.hpRoll, Cesium.Ellipsoid.WGS84, Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west'));
129
+
130
+ // 初始化轨迹线(如果还未创建)
131
+ _this.updateTrailLine();
132
+
133
+ // 更新模型位置
134
+ if (_this.modelLayer) {
135
+ // 只有位置真正发生变化时才更新矩阵
136
+ _this.modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(currentPos, _this.hpRoll, Cesium.Ellipsoid.WGS84, Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west'));
134
137
  _this.modelLayer.modelMatrix = _this.modelMatrix;
135
138
 
136
139
  // 调用位置更新回调
137
140
  if (_this._onPositionUpdate) {
138
- var cartographic = Cesium.Cartographic.fromCartesian(_position);
141
+ var cartographic = Cesium.Cartographic.fromCartesian(currentPos);
139
142
  _this._onPositionUpdate({
140
- lon: Cesium.Math.toDegrees(cartographic.longitude),
143
+ lng: Cesium.Math.toDegrees(cartographic.longitude),
141
144
  lat: Cesium.Math.toDegrees(cartographic.latitude),
142
145
  height: cartographic.height
143
146
  });
@@ -146,19 +149,31 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
146
149
  _this.updateCameraView();
147
150
  }
148
151
  }
149
- _this.currentPathIndex++;
152
+ _this.currentPointIndex++;
153
+ if (_this._fps === 'N/A') {
154
+ _this.currentPointIndex++;
155
+ } else {
156
+ // 每帧应飞的“点数”(允许小数)
157
+ var exactStep = _this._map.targetFrameRate / _this._fps;
158
+ // 累加步长
159
+ _this._stepAccumulator += exactStep;
160
+ // 取整:当前帧应飞的“完整点数”
161
+ var step = Math.max(1, Math.floor(_this._stepAccumulator));
162
+ // 剩余留给下帧
163
+ _this._stepAccumulator -= step;
164
+ _this.currentPointIndex = _this.currentPointIndex + step;
165
+ }
150
166
  });
151
- var _ref = options || {},
152
- model = _ref.model,
153
- polyline = _ref.polyline,
154
- onPositionUpdate = _ref.onPositionUpdate,
155
- flyTo = _ref.flyTo;
156
167
  if (!map) {
157
168
  throw new Error('undefined map');
158
169
  }
159
- if (!options.model && !((_options$model = options.model) !== null && _options$model !== void 0 && _options$model.url)) {
160
- throw new Error('undefined model');
170
+ if (!options || !options.model || !((_options$model = options.model) !== null && _options$model !== void 0 && _options$model.url)) {
171
+ throw new Error('undefined model or invalid options');
161
172
  }
173
+ var model = options.model,
174
+ polyline = options.polyline,
175
+ onPositionUpdate = options.onPositionUpdate,
176
+ flyTo = options.flyTo;
162
177
  this._map = map;
163
178
  this.modelOptions = model;
164
179
  this.polylineOptions = merge(constant.DEFAULT_POLYLINE_PRIMITIVE_OPTIONS(), cloneDeep(polyline || {}));
@@ -169,44 +184,98 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
169
184
  /**
170
185
  * 实时添加点位
171
186
  * @param newPosition 新位置点
172
- * @throws 如果新位置与上一个位置完全相同
173
187
  */
174
188
  _createClass(ModelRoamRealTime, [{
175
189
  key: "updatePosition",
176
190
  value: function updatePosition(newPosition) {
191
+ if (!newPosition) return;
177
192
  if (this.status === 'destroy') return;
178
- if (!this.positions.length) {
193
+
194
+ // 添加时间戳
195
+ if (!newPosition.timestamp) {
196
+ newPosition.timestamp = new Date().getTime();
197
+ }
198
+
199
+ // 如果是第一次接收数据,初始化模型
200
+ if (this.receivedPositions.length === 0) {
201
+ this.receivedPositions.push(newPosition);
179
202
  this.initModel(newPosition);
180
203
  return;
181
204
  }
182
205
 
183
- // 获取最后一个目标点的位置(而不是当前飞行位置)
184
- var lastTargetPos = this.positions[this.positions.length - 1];
185
- if (lastTargetPos) {
186
- if (newPosition.lng === lastTargetPos.lng && newPosition.lat === lastTargetPos.lat && Math.abs(newPosition.alt - lastTargetPos.alt) < 0.1) {
187
- return;
188
- }
206
+ // 检查是否与上一个位置相同
207
+ var lastPos = this.receivedPositions[this.receivedPositions.length - 1];
208
+ if (this.isSamePosition(newPosition, lastPos)) {
209
+ return;
189
210
  }
190
211
 
191
- // 将新位置添加到目标点数组
192
- this.positions.push(newPosition);
212
+ // 添加新位置到接收队列
213
+ this.receivedPositions.push(newPosition);
193
214
 
194
- // 从最后一个目标点计算到新点的路径
195
- var lastPos = Cesium.Cartesian3.fromDegrees(lastTargetPos.lng, lastTargetPos.lat, lastTargetPos.alt);
196
- var newPos = Cesium.Cartesian3.fromDegrees(newPosition.lng, newPosition.lat, newPosition.alt);
215
+ // 创建新的路径段
216
+ this.createNewSegment(lastPos, newPosition);
197
217
 
198
- // 飞行时间
199
- var newTime = new Date().getTime();
218
+ // 如果模型还未开始运行,启动运行
219
+ if (this.status === 'stop') {
220
+ this.startRoaming();
221
+ }
222
+ }
223
+
224
+ /**
225
+ * 判断两个位置是否相同
226
+ */
227
+ }, {
228
+ key: "isSamePosition",
229
+ value: function isSamePosition(pos1, pos2) {
230
+ return pos1.lng === pos2.lng && pos1.lat === pos2.lat && Math.abs(pos1.alt - pos2.alt) < 0.1;
231
+ }
232
+
233
+ /**
234
+ * 创建新的路径段
235
+ */
236
+ }, {
237
+ key: "createNewSegment",
238
+ value: function createNewSegment(startPos, endPos) {
239
+ var startC3 = Cesium.Cartesian3.fromDegrees(startPos.lng, startPos.lat, startPos.alt);
240
+ var endC3 = Cesium.Cartesian3.fromDegrees(endPos.lng, endPos.lat, endPos.alt);
241
+
242
+ // 计算飞行时间
243
+ var newTime = performance.now();
200
244
  var flightTime = (newTime - this._time) / 1000;
201
245
  this._time = newTime;
202
- var newPath = this._getInterPosition(lastPos, newPos, flightTime);
203
- if (this.status === 'running') {
204
- this.positionInterC3 = this.positionInterC3.concat(newPath);
205
- this.maxPathIndex = this.positionInterC3.length;
246
+
247
+ // 计算插值点
248
+ var interpolatedPoints = this._getInterPosition(startC3, endC3, flightTime);
249
+ var newSegment = {
250
+ startPos: startPos,
251
+ endPos: endPos,
252
+ interpolatedPoints: interpolatedPoints,
253
+ segmentIndex: this.segmentCounter++,
254
+ isCompleted: false
255
+ };
256
+
257
+ // 如果当前没有正在飞行的路径段,则设为当前段
258
+ if (!this.currentSegment) {
259
+ this.currentSegment = newSegment;
260
+ this.currentPointIndex = 0;
206
261
  } else {
207
- this.currentPathIndex = 0;
262
+ // 否则加入未来路径段队列
263
+ this.futureSegments.push(newSegment);
208
264
  }
209
265
  }
266
+
267
+ /**
268
+ * 开始漫游
269
+ */
270
+ }, {
271
+ key: "startRoaming",
272
+ value: function startRoaming() {
273
+ if (this.status === 'running') return;
274
+ this.status = 'running';
275
+ // 监听帧率更新
276
+ this._eventPostUpdate = this._map.on(constant.SCENE_EVENT_TYPE.POST_UPDATE, this.updateModel);
277
+ }
278
+
210
279
  /**
211
280
  * 计算两点之间的路径点
212
281
  * 使用插值算法生成平滑的路径
@@ -239,11 +308,8 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
239
308
  return arr;
240
309
  }
241
310
 
242
- // 设置无人机飞行参数
243
- var updateRate = 60; // 每秒更新次数
244
-
245
- // 计算总的插值点数
246
- var numberOfPoints = Math.max(10, Math.floor(flightTime * updateRate));
311
+ // 计算总的插值点数 用最大帧率*时间计算点位
312
+ var numberOfPoints = Math.max(10, Math.floor(flightTime * this._map.targetFrameRate));
247
313
 
248
314
  // 计算时间步长
249
315
  var timeStep = 1.0 / (numberOfPoints - 1);
@@ -278,9 +344,10 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
278
344
  }
279
345
  return arr;
280
346
  }
347
+
281
348
  /**
282
349
  * 初始化模型
283
- * 加载模型
350
+ * 加载模型到第一个位置
284
351
  * @param initialPosition 初始位置
285
352
  */
286
353
  }, {
@@ -292,20 +359,17 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
292
359
  return _regeneratorRuntime().wrap(function _callee$(_context) {
293
360
  while (1) switch (_context.prev = _context.next) {
294
361
  case 0:
295
- // 添加初始位置到目标点数组
296
- this.positions.push(initialPosition);
297
- pos = Cesium.Cartesian3.fromDegrees(initialPosition.lng, initialPosition.lat, initialPosition.alt);
298
- this.positionsLineC3 = [pos];
299
- // 创建模型矩阵
362
+ pos = Cesium.Cartesian3.fromDegrees(initialPosition.lng, initialPosition.lat, initialPosition.alt); // 创建模型矩阵
300
363
  this.modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(pos, this.hpRoll, Cesium.Ellipsoid.WGS84, Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west'));
301
- _context.next = 6;
364
+ _context.next = 4;
302
365
  return Cesium.Model.fromGltfAsync(_objectSpread({
303
366
  id: uuidv4(),
304
367
  modelMatrix: this.modelMatrix
305
368
  }, this.modelOptions));
306
- case 6:
369
+ case 4:
307
370
  model = _context.sent;
308
371
  this.modelLayer = this._map.scene.primitives.add(model);
372
+
309
373
  // 开启动画
310
374
  this.modelLayer.readyEvent.addEventListener(function () {
311
375
  if (_this2.flyTo) {
@@ -315,13 +379,8 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
315
379
  loop: Cesium.ModelAnimationLoop.REPEAT,
316
380
  multiplier: 2
317
381
  });
318
- if (_this2.status === 'stop') {
319
- _this2.status = 'running';
320
- // 监听帧率
321
- _this2._eventPreUpdate = _this2._map.on(constant.SCENE_EVENT_TYPE.PRE_UPDATE, _this2.updateModel);
322
- }
323
382
  });
324
- case 9:
383
+ case 7:
325
384
  case "end":
326
385
  return _context.stop();
327
386
  }
@@ -333,14 +392,190 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
333
392
  return initModel;
334
393
  }())
335
394
  }, {
336
- key: "getHeading",
395
+ key: "completeCurrentSegment",
337
396
  value:
397
+ /**
398
+ * 完成当前路径段,切换到下一个路径段
399
+ */
400
+ function completeCurrentSegment() {
401
+ if (!this.currentSegment) return;
402
+
403
+ // 标记当前段为已完成
404
+ this.currentSegment.isCompleted = true;
405
+ this.completedSegments.push(this.currentSegment);
406
+
407
+ // 从未来路径段队列中取出下一个路径段
408
+ if (this.futureSegments.length > 0) {
409
+ this.currentSegment = this.futureSegments.shift();
410
+ this.currentPointIndex = 0;
411
+ } else {
412
+ // 没有更多路径段,等待新数据
413
+ this.currentSegment = null;
414
+ this.currentPointIndex = 0;
415
+ }
416
+ }
417
+
418
+ /**
419
+ * 初始化轨迹线Entity
420
+ */
421
+ }, {
422
+ key: "initTrailLine",
423
+ value: function initTrailLine() {
424
+ var _this3 = this;
425
+ // 创建轨迹线Entity,使用callback动态更新位置
426
+ this.polylineLayer = this._map.entities.add({
427
+ id: uuidv4(),
428
+ polyline: {
429
+ positions: new Cesium.CallbackProperty(function () {
430
+ return _this3.getTrailLinePositions();
431
+ }, false),
432
+ width: this.polylineOptions.width || 2,
433
+ material: colorString(this.polylineOptions.color || Cesium.Color.YELLOW),
434
+ clampToGround: false
435
+ }
436
+ });
437
+ }
438
+
439
+ /**
440
+ * 获取轨迹线位置点
441
+ * 返回:已完成路径段的起始点和结束点 + 当前路径段已飞行的插值点
442
+ */
443
+ }, {
444
+ key: "getTrailLinePositions",
445
+ value: function getTrailLinePositions() {
446
+ var positions = [];
447
+
448
+ // 确保有基础数据
449
+ if (!Array.isArray(this.receivedPositions) || this.receivedPositions.length < 1) {
450
+ return positions;
451
+ }
452
+
453
+ // 添加已完成路径段的起始点和结束点
454
+ if (Array.isArray(this.completedSegments)) {
455
+ this.completedSegments.forEach(function (segment) {
456
+ if (segment.startPos && segment.endPos) {
457
+ // 添加起始点(如果这是第一个路径段或者与上一个路径段不重复)
458
+ if (positions.length === 0) {
459
+ positions.push(Cesium.Cartesian3.fromDegrees(segment.startPos.lng, segment.startPos.lat, segment.startPos.alt));
460
+ }
461
+ // 添加结束点
462
+ positions.push(Cesium.Cartesian3.fromDegrees(segment.endPos.lng, segment.endPos.lat, segment.endPos.alt));
463
+ }
464
+ });
465
+ }
466
+
467
+ // 如果当前有正在飞行的路径段,添加已飞行过的插值点
468
+ if (this.currentSegment && Array.isArray(this.currentSegment.interpolatedPoints) && this.currentPointIndex >= 0) {
469
+ // 如果还没有添加过任何点,先添加当前路径段的起始点
470
+ if (positions.length === 0 && this.currentSegment.startPos) {
471
+ positions.push(Cesium.Cartesian3.fromDegrees(this.currentSegment.startPos.lng, this.currentSegment.startPos.lat, this.currentSegment.startPos.alt));
472
+ }
473
+
474
+ // 添加当前路径段中已经飞行过的插值点
475
+ for (var i = 0; i <= this.currentPointIndex && i < this.currentSegment.interpolatedPoints.length; i++) {
476
+ positions.push(this.currentSegment.interpolatedPoints[i]);
477
+ }
478
+ }
479
+ return positions;
480
+ }
481
+
482
+ /**
483
+ * 更新轨迹线 - 现在由CallbackProperty自动更新
484
+ */
485
+ }, {
486
+ key: "updateTrailLine",
487
+ value: function updateTrailLine() {
488
+ // 由于使用了CallbackProperty和getTrailLinePositions方法
489
+ // 轨迹线会自动更新显示:所有原始位置点 + 当前段已飞行的插值点
490
+ if (!this.polylineLayer && this.receivedPositions.length >= 2) {
491
+ this.initTrailLine();
492
+ }
493
+ }
494
+
495
+ /**
496
+ * 获取当前状态信息
497
+ */
498
+ }, {
499
+ key: "getStatus",
500
+ value: function getStatus() {
501
+ var _this$currentSegment;
502
+ var currentProgress = this.currentSegment ? Math.round(this.currentPointIndex / this.currentSegment.interpolatedPoints.length * 100) : 0;
503
+ return {
504
+ status: this.status,
505
+ receivedPositionsCount: this.receivedPositions.length,
506
+ completedSegmentsCount: this.completedSegments.length,
507
+ currentSegmentIndex: ((_this$currentSegment = this.currentSegment) === null || _this$currentSegment === void 0 ? void 0 : _this$currentSegment.segmentIndex) || null,
508
+ currentSegmentProgress: "".concat(currentProgress, "%"),
509
+ futureSegmentsCount: this.futureSegments.length,
510
+ currentPointIndex: this.currentPointIndex,
511
+ totalTrailPoints: this.getTrailLinePositions().length,
512
+ isWaitingForData: !this.currentSegment && this.futureSegments.length === 0
513
+ };
514
+ }
515
+
516
+ /**
517
+ * 获取详细的飞行信息
518
+ */
519
+ }, {
520
+ key: "getFlightDetails",
521
+ value: function getFlightDetails() {
522
+ var _this4 = this;
523
+ return {
524
+ // 当前位置信息
525
+ currentPosition: this.currentSegment && this.currentPointIndex < this.currentSegment.interpolatedPoints.length ? function () {
526
+ var pos = _this4.currentSegment.interpolatedPoints[_this4.currentPointIndex];
527
+ var cartographic = Cesium.Cartographic.fromCartesian(pos);
528
+ return {
529
+ longitude: Cesium.Math.toDegrees(cartographic.longitude),
530
+ latitude: Cesium.Math.toDegrees(cartographic.latitude),
531
+ height: cartographic.height
532
+ };
533
+ }() : null,
534
+ // 当前路径段信息
535
+ currentSegment: this.currentSegment ? {
536
+ index: this.currentSegment.segmentIndex,
537
+ startPos: this.currentSegment.startPos,
538
+ endPos: this.currentSegment.endPos,
539
+ totalPoints: this.currentSegment.interpolatedPoints.length,
540
+ currentPoint: this.currentPointIndex,
541
+ progress: Math.round(this.currentPointIndex / this.currentSegment.interpolatedPoints.length * 100)
542
+ } : null,
543
+ // 队列信息
544
+ queue: {
545
+ completed: Array.isArray(this.completedSegments) ? this.completedSegments.map(function (seg) {
546
+ return {
547
+ index: seg.segmentIndex,
548
+ from: "(".concat(seg.startPos.lng, ", ").concat(seg.startPos.lat, ")"),
549
+ to: "(".concat(seg.endPos.lng, ", ").concat(seg.endPos.lat, ")")
550
+ };
551
+ }) : [],
552
+ future: Array.isArray(this.futureSegments) ? this.futureSegments.map(function (seg) {
553
+ return {
554
+ index: seg.segmentIndex,
555
+ from: "(".concat(seg.startPos.lng, ", ").concat(seg.startPos.lat, ")"),
556
+ to: "(".concat(seg.endPos.lng, ", ").concat(seg.endPos.lat, ")"),
557
+ points: seg.interpolatedPoints.length
558
+ };
559
+ }) : []
560
+ },
561
+ // 整体统计
562
+ statistics: {
563
+ totalDataReceived: this.receivedPositions.length,
564
+ totalSegmentsCreated: this.segmentCounter,
565
+ totalTrailPoints: this.getTrailLinePositions().length,
566
+ memoryStatus: "\u5DF2\u5B8C\u6210\u6BB5\u6570: ".concat(this.completedSegments.length, ", \u7B49\u5F85\u6BB5\u6570: ").concat(this.futureSegments.length)
567
+ }
568
+ };
569
+ }
570
+
338
571
  /**
339
572
  * 计算模型朝向
340
573
  * @param start 起始点
341
574
  * @param end 终点
342
575
  */
343
- function getHeading(start, end) {
576
+ }, {
577
+ key: "getHeading",
578
+ value: function getHeading(start, end) {
344
579
  var startCartographic = Cesium.Cartographic.fromCartesian(start);
345
580
  var endCartographic = Cesium.Cartographic.fromCartesian(end);
346
581
  var startLonLat = [Cesium.Math.toDegrees(startCartographic.longitude), Cesium.Math.toDegrees(startCartographic.latitude)];
@@ -355,6 +590,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
355
590
  var localDirection = Cesium.Matrix4.multiplyByPointAsVector(Cesium.Matrix4.inverse(transform, new Cesium.Matrix4()), direction, new Cesium.Cartesian3());
356
591
  this.targetHeading = Math.atan2(localDirection.x, localDirection.y);
357
592
  }
593
+
358
594
  /**
359
595
  * 更新模型朝向
360
596
  */
@@ -382,6 +618,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
382
618
  // 更新模型朝向
383
619
  this.hpRoll = new Cesium.HeadingPitchRoll(this.currentHeading, 0.0, 0.0);
384
620
  }
621
+
385
622
  /**
386
623
  * 更新相机视角
387
624
  * 根据当前模式更新相机位置和朝向
@@ -389,16 +626,17 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
389
626
  }, {
390
627
  key: "updateCameraView",
391
628
  value: function updateCameraView() {
392
- if (!this.modelLayer || !this.positionInterC3) {
629
+ if (!this.modelLayer || !this.currentSegment) {
393
630
  return;
394
631
  }
395
- var position = this.currentPathIndex >= this.positionInterC3.length ? this.positionInterC3[this.positionInterC3.length - 1] : this.positionInterC3[this.currentPathIndex];
632
+ var position = this.currentPointIndex >= this.currentSegment.interpolatedPoints.length ? this.currentSegment.interpolatedPoints[this.currentSegment.interpolatedPoints.length - 1] : this.currentSegment.interpolatedPoints[this.currentPointIndex];
396
633
  if (this.follow === 'first') {
397
634
  this.updateFirstPersonView(position);
398
635
  } else if (this.follow === 'third') {
399
636
  this.updateThirdPersonView(position);
400
637
  }
401
638
  }
639
+
402
640
  /**
403
641
  * 更新第一人称视角
404
642
  * @param position 模型当前位置
@@ -416,6 +654,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
416
654
  }
417
655
  });
418
656
  }
657
+
419
658
  /**
420
659
  * 更新第三人称视角
421
660
  * @param position 模型当前位置
@@ -425,6 +664,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
425
664
  value: function updateThirdPersonView(position) {
426
665
  this._map.camera.lookAt(position, new Cesium.HeadingPitchRange(this.hpRoll.heading, Cesium.Math.toRadians(this.thirdPersonSettings.pitch), this.thirdPersonSettings.distance));
427
666
  }
667
+
428
668
  /**
429
669
  * 设置第一人称视角
430
670
  */
@@ -436,6 +676,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
436
676
  this.follow = 'first';
437
677
  this.updateCameraView();
438
678
  }
679
+
439
680
  /**
440
681
  * 设置第一人称视角
441
682
  */
@@ -447,6 +688,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
447
688
  this.follow = 'third';
448
689
  this.updateCameraView();
449
690
  }
691
+
450
692
  /**
451
693
  * 取消视角跟随
452
694
  */
@@ -456,6 +698,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
456
698
  if (this.status === 'destroy') return;
457
699
  this.follow = null;
458
700
  }
701
+
459
702
  /**
460
703
  * 飞行定位到模型
461
704
  */
@@ -466,6 +709,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
466
709
  boundingSphere.radius = Math.max(boundingSphere.radius || 100);
467
710
  this._map.camera.flyToBoundingSphere(boundingSphere);
468
711
  }
712
+
469
713
  /**
470
714
  * 监听
471
715
  */
@@ -474,6 +718,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
474
718
  value: function on(type, event) {
475
719
  return this._map._event.listenToModelRoam(type, event, this);
476
720
  }
721
+
477
722
  /**
478
723
  * 销毁实例
479
724
  * 清理所有资源
@@ -483,20 +728,21 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
483
728
  value: function destroy() {
484
729
  if (this.status === 'destroy') return;
485
730
  this.status = 'destroy';
731
+ this._eventPostUpdate && this._eventPostUpdate.off();
486
732
  if (this.modelLayer) {
487
- this._eventPreUpdate.off();
488
733
  this._map.scene.primitives.remove(this.modelLayer);
489
734
  this.modelLayer = null;
490
735
  }
491
736
  if (this.polylineLayer) {
492
- this._map.scene.primitives.remove(this.polylineLayer);
737
+ this._map.entities.remove(this.polylineLayer);
493
738
  this.polylineLayer = null;
494
739
  }
495
- this.positions = [];
496
- this.positionsLineC3 = [];
497
- this.positionInterC3 = [];
498
- this.currentPathIndex = 0;
499
- this.maxPathIndex = 0;
740
+ this.receivedPositions = [];
741
+ this.completedSegments = [];
742
+ this.currentSegment = null;
743
+ this.futureSegments = [];
744
+ this.currentPointIndex = 0;
745
+ this.segmentCounter = 0;
500
746
  }
501
747
  }]);
502
748
  return ModelRoamRealTime;
@@ -39,7 +39,8 @@ var DeepTwins = /*#__PURE__*/function () {
39
39
  terrain: this._getTerrain.bind(this),
40
40
  moduleLayer: this._getModuleLayer.bind(this),
41
41
  trafficHistoryLayer: this._YunJing.TrafficHistoryLayer,
42
- trafficLayer: this._YunJing.TrafficLayer
42
+ trafficLayer: this._YunJing.TrafficLayer,
43
+ gridVTLayer: this._YunJing.GridVTLayer
43
44
  });
44
45
  }
45
46
  case 5:
package/dist/index.js CHANGED
@@ -45,7 +45,7 @@ window.Cesium = Cesium;
45
45
  var DeepTwinsEngine3D = /*#__PURE__*/_createClass(function DeepTwinsEngine3D() {
46
46
  _classCallCheck(this, DeepTwinsEngine3D);
47
47
  });
48
- _defineProperty(DeepTwinsEngine3D, "Version", '0.0.47');
48
+ _defineProperty(DeepTwinsEngine3D, "Version", '0.0.49');
49
49
  _defineProperty(DeepTwinsEngine3D, "Map", Map);
50
50
  _defineProperty(DeepTwinsEngine3D, "GroundSkyBox", GroundSkyBox);
51
51
  _defineProperty(DeepTwinsEngine3D, "RasterLayer", RasterLayer);
package/dist/map/Event.js CHANGED
@@ -252,7 +252,7 @@ var Event = /*#__PURE__*/function () {
252
252
  var pickedObject = _this5._getPickedObject(position);
253
253
  if (pickedObject) {
254
254
  var _modelRoam$modelLayer;
255
- var targetPolyline = pickedObject.id === '_modelRoamRealTimePolyline';
255
+ var targetPolyline = modelRoam.polylineLayer.id === pickedObject.id.id;
256
256
  var targetModel = (modelRoam === null || modelRoam === void 0 || (_modelRoam$modelLayer = modelRoam.modelLayer) === null || _modelRoam$modelLayer === void 0 ? void 0 : _modelRoam$modelLayer.id) === (pickedObject === null || pickedObject === void 0 ? void 0 : pickedObject.id);
257
257
  if (targetPolyline || targetModel) {
258
258
  var result = {
@@ -24,7 +24,7 @@ import { DEFAULT_CIRCLE_WAVE_MATERIAL_STYLE } from "../constant";
24
24
  import * as utils from "../tool/utils";
25
25
  import BaseMaterialProperty from "./BaseMaterialProperty";
26
26
  /* babel-plugin-inline-import './shader/CircleWaveShader.glsl' */
27
- var CircleWaveShader = "czm_material czm_getMaterial(czm_materialInput materialInput) {\n czm_material material = czm_getDefaultMaterial(materialInput);\n material.diffuse = 1.5 * color.rgb;\n\n vec2 st = materialInput.st;\n vec3 str = materialInput.str;\n float dis = distance(st, vec2(0.5));\n float per = fract(time);\n float perDis = 0.5 / count;\n\n // discard if str.z != 0\n float discardByStr = step(0.001, abs(str.z));\n // discard if dis > 0.5\n float discardByDis = step(0.5, dis);\n\n if (discardByStr > 0.0 || discardByDis > 0.0) {\n discard;\n }\n\n float bl = 0.0;\n\n for (int i = 0; i <= 9; i++) {\n float idx = float(i);\n float valid = step(idx, count); // 1.0 if i <= count, else 0.0\n\n float disNum = perDis * idx - dis + per / count;\n float inFirst = step(0.0, disNum) * (1.0 - step(perDis, disNum));\n float inSecond = step(perDis, disNum) * (1.0 - step(2.0 * perDis, disNum));\n\n float bl1 = 1.0 - disNum / perDis;\n float bl2 = 1.0 - abs(1.0 - disNum / perDis);\n\n float thisBl = mix(0.0, bl1, inFirst) + mix(0.0, bl2, inSecond);\n thisBl *= valid; // only apply if i <= count\n\n bl = max(bl, thisBl); // \u4FDD\u7559\u6700\u5F3A\u7684\u4E00\u5C42\u6CE2\u7EB9\n }\n\n material.alpha = pow(bl, gradient);\n return material;\n}\n"; // 水波纹材质
27
+ var CircleWaveShader = "czm_material czm_getMaterial(czm_materialInput materialInput) {\n czm_material material = czm_getDefaultMaterial(materialInput);\n material.diffuse = 1.5 * color.rgb;\n vec2 st = materialInput.st;\n vec3 str = materialInput.str;\n float dis = distance(st, vec2(0.5, 0.5));\n float per = fract(time);\n if (abs(str.z) > 0.001) {\n discard;\n }\n if (dis > 0.5) {\n discard;\n } else {\n float perDis = 0.5 / count;\n float disNum;\n float bl = .0;\n for (int i = 0; i <= 9; i++) {\n if (float(i) <= count) {\n disNum = perDis * float(i) - dis + per / count;\n if (disNum > 0.0) {\n if (disNum < perDis) {\n bl = 1.0 - disNum / perDis;\n } else if (disNum - perDis < perDis) {\n bl = 1.0 - abs(1.0 - disNum / perDis);\n }\n material.alpha = pow(bl, gradient);\n }\n }\n }\n }\n return material;\n}\n"; // 水波纹材质
28
28
  var CircleWaveMaterialProperty = /*#__PURE__*/function (_BaseMaterialProperty) {
29
29
  _inherits(CircleWaveMaterialProperty, _BaseMaterialProperty);
30
30
  var _super = _createSuper(CircleWaveMaterialProperty);
@@ -24,7 +24,7 @@ import { DEFAULT_DYNAMIC_WALL_MATERIAL_STYLE } from "../constant";
24
24
  import * as utils from "../tool/utils";
25
25
  import BaseMaterialProperty from "./BaseMaterialProperty";
26
26
  /* babel-plugin-inline-import './shader/DynamicWallShader.glsl' */
27
- var DynamicWallShader = "czm_material czm_getMaterial(czm_materialInput materialInput)\n{\n czm_material material = czm_getDefaultMaterial(materialInput);\n vec2 st = materialInput.st;\n float vertical = 1.0;\n float directionAdd = 1.0;\n // \u4F7F\u7528 abs(a - b) < 0.0001\uFF08\u901A\u8FC7 step\uFF09\u5224\u65AD\u6D6E\u70B9\u76F8\u7B49\uFF0C\u907F\u514D\u7CBE\u5EA6\u8BEF\u5DEE\n // \u5224\u65AD\u6392\u5217\u65B9\u5411\u662F\u5426\u662F\u7EB5\u5411\uFF08freely == vertical\uFF09\n float isVertical = 1.0 - step(0.0001, abs(freely - vertical));\n // \u5224\u65AD\u8FD0\u52A8\u65B9\u5411\u662F\u5426\u662F\u52A0\uFF08direction == directionAdd\uFF09\n float isAdd = 1.0 - step(0.0001, abs(direction - directionAdd));\n\n // \u7EB5\u5411\u6392\u5217\uFF1Auv = (st.s, count * st.t \xB1 time)\n // \u6A2A\u5411\u6392\u5217\uFF1Auv = (count * st.s \xB1 time, st.t)\n vec2 uvVerticalAdd = vec2(fract(st.s), fract(count * st.t + time));\n vec2 uvVerticalSub = vec2(fract(st.s), fract(count * st.t - time));\n vec2 uvHorizontalAdd = vec2(fract(count * st.s + time), fract(st.t));\n vec2 uvHorizontalSub = vec2(fract(count * st.s - time), fract(st.t));\n\n // \u6309\u8FD0\u52A8\u65B9\u5411\u9009\u62E9 mix(a, b, t) \u4F5C\u7528\u7C7B\u4F3C\u4E8E t == 0 ? a : b\n vec2 uvVertical = mix(uvVerticalSub, uvVerticalAdd, isAdd);\n vec2 uvHorizontal = mix(uvHorizontalSub, uvHorizontalAdd, isAdd);\n\n // \u6700\u7EC8\u6839\u636E\u6392\u5217\u65B9\u5411\u9009\u62E9\n vec2 uv = mix(uvHorizontal, uvVertical, isVertical);\n\n vec4 colorImage = texture(image, uv);\n vec3 mixedColor = mix(colorImage.rgb, color.rgb, mixRatio);\n vec4 fragColor;\n fragColor.rgb = mixedColor;\n fragColor = czm_gammaCorrect(fragColor);\n\n material.diffuse = mixedColor;\n material.alpha = colorImage.a * color.a; // \u53EF\u6839\u636E\u9700\u8981\u51B3\u5B9A\u662F\u5426\u76F8\u4E58\n material.emission = fragColor.rgb;\n\n return material;\n}\n"; // 动态墙材质
27
+ var DynamicWallShader = "czm_material czm_getMaterial(czm_materialInput materialInput)\n{\n czm_material material = czm_getDefaultMaterial(materialInput);\n vec2 st = materialInput.st;\n float vertical = 1.0;\n float directionAdd = 1.0;\n vec2 uv = vec2(0, 0);\n // \u5224\u65AD\u6392\u5217\u65B9\u5411\n if (freely == vertical) {\n // \u5224\u65AD\u8FD0\u52A8\u65B9\u5411\n if (direction == directionAdd) {\n uv = vec2(fract(st.s), fract(count * st.t + time));\n } else {\n uv = vec2(fract(st.s), fract(count * st.t - time));\n }\n } else {\n // \u5224\u65AD\u8FD0\u52A8\u65B9\u5411\n if (direction == directionAdd) {\n uv = vec2(fract(count * st.s + time), fract(st.t));\n } else {\n uv = vec2(fract(count * st.s - time), fract(st.t));\n }\n }\n vec4 colorImage = texture(image, uv);\n vec3 mixedColor = mix(colorImage.rgb, color.rgb, mixRatio);\n vec4 fragColor;\n fragColor.rgb = mixedColor;\n fragColor = czm_gammaCorrect(fragColor);\n\n material.diffuse = mixedColor;\n material.alpha = colorImage.a * color.a; // \u53EF\u6839\u636E\u9700\u8981\u51B3\u5B9A\u662F\u5426\u76F8\u4E58\n material.emission = fragColor.rgb;\n\n return material;\n}\n"; // 动态墙材质
28
28
  var DynamicWallMaterialProperty = /*#__PURE__*/function (_BaseMaterialProperty) {
29
29
  _inherits(DynamicWallMaterialProperty, _BaseMaterialProperty);
30
30
  var _super = _createSuper(DynamicWallMaterialProperty);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deeptwins-engine-3d",
3
- "version": "0.0.47",
3
+ "version": "0.0.49",
4
4
  "description": "map for 3d",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",