deeptwins-engine-3d 0.1.1 → 0.1.3
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.
- package/LICENSE +6 -21
- package/README.md +0 -35
- package/dist/esm/cameraControl/ModelRoamRealTime.d.ts +26 -9
- package/dist/esm/cameraControl/ModelRoamRealTime.js +197 -102
- package/dist/esm/constant.js +2 -1
- package/dist/esm/graphicLayer/BaseSource.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/map/Event.js +1 -1
- package/dist/esm/map/Map.d.ts +1 -0
- package/dist/esm/map/Map.js +10 -4
- package/dist/esm/material/PolylineTrailLinkMaterialProperty.d.ts +6 -2
- package/dist/esm/material/PolylineTrailLinkMaterialProperty.js +46 -9
- package/dist/esm/material/shader/PolylineTrailLinkShader.glsl +1 -1
- package/dist/esm/tool/utils.d.ts +15 -0
- package/dist/esm/tool/utils.js +46 -0
- package/dist/umd/deeptwins-engine-3d.min.js +1 -1
- package/package.json +2 -2
package/LICENSE
CHANGED
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
COPYRIGHT NOTICE & COMMERCIAL LICENSE
|
|
2
|
+
Copyright (c) 2025 sdzl. All rights reserved.
|
|
3
|
+
This software is proprietary and commercial. Unauthorized use, copying, modification,
|
|
4
|
+
or redistribution is strictly prohibited without a valid license agreement.
|
|
5
|
+
For licensing and pricing information, please contact:
|
|
6
|
+
Email: shenduzhilian@gmail.com
|
package/README.md
CHANGED
|
@@ -2,38 +2,3 @@
|
|
|
2
2
|
map for 3d
|
|
3
3
|
|
|
4
4
|
## Usage
|
|
5
|
-
|
|
6
|
-
TODO
|
|
7
|
-
|
|
8
|
-
## Options
|
|
9
|
-
|
|
10
|
-
TODO
|
|
11
|
-
|
|
12
|
-
## Development
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
# install dependencies
|
|
16
|
-
$ npm install
|
|
17
|
-
|
|
18
|
-
# develop library by docs demo
|
|
19
|
-
$ npm start
|
|
20
|
-
|
|
21
|
-
# build library source code
|
|
22
|
-
$ npm run build
|
|
23
|
-
|
|
24
|
-
# build library source code in watch mode
|
|
25
|
-
$ npm run build:watch
|
|
26
|
-
|
|
27
|
-
# build docs
|
|
28
|
-
$ npm run docs:build
|
|
29
|
-
|
|
30
|
-
# Locally preview the production build.
|
|
31
|
-
$ npm run docs:preview
|
|
32
|
-
|
|
33
|
-
# check your project for potential problems
|
|
34
|
-
$ npm run doctor
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## LICENSE
|
|
38
|
-
|
|
39
|
-
MIT
|
|
@@ -6,7 +6,7 @@ interface Position {
|
|
|
6
6
|
lng: number;
|
|
7
7
|
lat: number;
|
|
8
8
|
alt: number;
|
|
9
|
-
timestamp
|
|
9
|
+
timestamp: number;
|
|
10
10
|
}
|
|
11
11
|
export default class ModelRoamRealTime {
|
|
12
12
|
readonly _map: any;
|
|
@@ -17,17 +17,21 @@ export default class ModelRoamRealTime {
|
|
|
17
17
|
private readonly _onPositionUpdate;
|
|
18
18
|
modelLayer: any;
|
|
19
19
|
polylineLayer: any;
|
|
20
|
+
historyPolylineLayer: any;
|
|
20
21
|
private _lastFrameTime;
|
|
21
22
|
private _stepAccumulator;
|
|
22
23
|
private _frameCount;
|
|
23
24
|
private _fps;
|
|
24
|
-
private _time;
|
|
25
25
|
private receivedPositions;
|
|
26
26
|
private completedSegments;
|
|
27
27
|
private currentSegment;
|
|
28
28
|
private futureSegments;
|
|
29
29
|
private currentPointIndex;
|
|
30
30
|
private segmentCounter;
|
|
31
|
+
private TRAIL_POSITIONS_THRESHOLD;
|
|
32
|
+
private historyTrailPositions;
|
|
33
|
+
private trailDataUpdated;
|
|
34
|
+
private trailShowState;
|
|
31
35
|
private _eventPostUpdate;
|
|
32
36
|
private modelMatrix;
|
|
33
37
|
private hpRoll;
|
|
@@ -83,23 +87,27 @@ export default class ModelRoamRealTime {
|
|
|
83
87
|
* 初始化轨迹线Entity
|
|
84
88
|
*/
|
|
85
89
|
private initTrailLine;
|
|
90
|
+
/**
|
|
91
|
+
* 创建历史轨迹线Entity
|
|
92
|
+
*/
|
|
93
|
+
private createHistoryTrailLine;
|
|
86
94
|
/**
|
|
87
95
|
* 获取轨迹线位置点
|
|
88
96
|
* 返回:已完成路径段的起始点和结束点 + 当前路径段已飞行的插值点
|
|
89
97
|
*/
|
|
90
98
|
private getTrailLinePositions;
|
|
91
99
|
/**
|
|
92
|
-
*
|
|
100
|
+
* 检查并移动数据到历史轨迹
|
|
93
101
|
*/
|
|
94
|
-
private
|
|
102
|
+
private checkAndMoveToHistory;
|
|
95
103
|
/**
|
|
96
|
-
*
|
|
104
|
+
* 标记已经移动到历史的路径段
|
|
97
105
|
*/
|
|
98
|
-
|
|
106
|
+
private markCompletedSegmentsAsMovedToHistory;
|
|
99
107
|
/**
|
|
100
|
-
*
|
|
108
|
+
* 更新轨迹线 - 现在由CallbackProperty自动更新
|
|
101
109
|
*/
|
|
102
|
-
|
|
110
|
+
private updateTrailLine;
|
|
103
111
|
/**
|
|
104
112
|
* 计算模型朝向
|
|
105
113
|
* @param start 起始点
|
|
@@ -130,7 +138,7 @@ export default class ModelRoamRealTime {
|
|
|
130
138
|
*/
|
|
131
139
|
setFollowFirst(options: any): void;
|
|
132
140
|
/**
|
|
133
|
-
*
|
|
141
|
+
* 设置第三人称视角
|
|
134
142
|
*/
|
|
135
143
|
setFollowThird(options: any): void;
|
|
136
144
|
/**
|
|
@@ -141,6 +149,15 @@ export default class ModelRoamRealTime {
|
|
|
141
149
|
* 飞行定位到模型
|
|
142
150
|
*/
|
|
143
151
|
private _flyToModel;
|
|
152
|
+
/**
|
|
153
|
+
* 显示隐藏飞行轨迹
|
|
154
|
+
* */
|
|
155
|
+
showPolylineLayer(isShow: boolean): void;
|
|
156
|
+
/**
|
|
157
|
+
* 强制更新轨迹数据
|
|
158
|
+
* 用于确保轨迹数据的连续性
|
|
159
|
+
*/
|
|
160
|
+
forceUpdateTrailData(): void;
|
|
144
161
|
/**
|
|
145
162
|
* 监听
|
|
146
163
|
*/
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
3
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
5
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
6
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
7
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
2
8
|
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
3
9
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
10
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -14,7 +20,7 @@ import * as Cesium from 'deeptwins-cesium';
|
|
|
14
20
|
import { cloneDeep, merge } from 'lodash';
|
|
15
21
|
import { v4 as uuidv4 } from 'uuid';
|
|
16
22
|
import * as constant from "../constant";
|
|
17
|
-
import
|
|
23
|
+
import PolylineEntity from "../graphicLayer/PolylineEntity";
|
|
18
24
|
|
|
19
25
|
/**
|
|
20
26
|
* 位置信息
|
|
@@ -48,15 +54,14 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
48
54
|
_defineProperty(this, "modelLayer", void 0);
|
|
49
55
|
// 轨迹layer
|
|
50
56
|
_defineProperty(this, "polylineLayer", void 0);
|
|
57
|
+
// 历史轨迹layer
|
|
58
|
+
_defineProperty(this, "historyPolylineLayer", void 0);
|
|
51
59
|
// 上一帧时间
|
|
52
60
|
_defineProperty(this, "_lastFrameTime", performance.now());
|
|
53
61
|
// 累加器
|
|
54
62
|
_defineProperty(this, "_stepAccumulator", 0);
|
|
55
63
|
_defineProperty(this, "_frameCount", 0);
|
|
56
64
|
_defineProperty(this, "_fps", 'N/A');
|
|
57
|
-
// 重新设计的数据结构
|
|
58
|
-
// 上个点位的时间
|
|
59
|
-
_defineProperty(this, "_time", performance.now());
|
|
60
65
|
// 接收到的原始位置数据
|
|
61
66
|
_defineProperty(this, "receivedPositions", []);
|
|
62
67
|
// 已完成飞行的路径段
|
|
@@ -69,6 +74,14 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
69
74
|
_defineProperty(this, "currentPointIndex", 0);
|
|
70
75
|
// 路径段计数器
|
|
71
76
|
_defineProperty(this, "segmentCounter", 0);
|
|
77
|
+
// 轨迹线数据量阈值
|
|
78
|
+
_defineProperty(this, "TRAIL_POSITIONS_THRESHOLD", 1000);
|
|
79
|
+
// 历史轨迹位置点
|
|
80
|
+
_defineProperty(this, "historyTrailPositions", []);
|
|
81
|
+
// 轨迹数据更新标志
|
|
82
|
+
_defineProperty(this, "trailDataUpdated", false);
|
|
83
|
+
// 轨迹显示状态
|
|
84
|
+
_defineProperty(this, "trailShowState", true);
|
|
72
85
|
// 帧率更新的事件
|
|
73
86
|
_defineProperty(this, "_eventPostUpdate", void 0);
|
|
74
87
|
// 模型参数
|
|
@@ -102,8 +115,9 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
102
115
|
_defineProperty(this, "updateModel", function () {
|
|
103
116
|
var currentTime = performance.now();
|
|
104
117
|
_this._frameCount++;
|
|
105
|
-
|
|
106
|
-
|
|
118
|
+
var elapsed = currentTime - _this._lastFrameTime;
|
|
119
|
+
if (elapsed > 60) {
|
|
120
|
+
_this._fps = Math.min(Math.round(_this._frameCount * 1000 / elapsed), _this._map.targetFrameRate);
|
|
107
121
|
_this._frameCount = 0;
|
|
108
122
|
_this._lastFrameTime = currentTime;
|
|
109
123
|
}
|
|
@@ -114,6 +128,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
114
128
|
// 检查当前路径段是否完成
|
|
115
129
|
if (_this.currentPointIndex >= _this.currentSegment.interpolatedPoints.length) {
|
|
116
130
|
_this.completeCurrentSegment();
|
|
131
|
+
_this._stepAccumulator += 1;
|
|
117
132
|
return;
|
|
118
133
|
}
|
|
119
134
|
var currentPos = _this.currentSegment.interpolatedPoints[_this.currentPointIndex];
|
|
@@ -130,6 +145,9 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
130
145
|
// 初始化轨迹线(如果还未创建)
|
|
131
146
|
_this.updateTrailLine();
|
|
132
147
|
|
|
148
|
+
// 重置轨迹数据更新标志
|
|
149
|
+
_this.trailDataUpdated = false;
|
|
150
|
+
|
|
133
151
|
// 更新模型位置
|
|
134
152
|
if (_this.modelLayer) {
|
|
135
153
|
// 只有位置真正发生变化时才更新矩阵
|
|
@@ -149,19 +167,18 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
149
167
|
_this.updateCameraView();
|
|
150
168
|
}
|
|
151
169
|
}
|
|
152
|
-
_this.currentPointIndex++;
|
|
153
170
|
if (_this._fps === 'N/A') {
|
|
154
171
|
_this.currentPointIndex++;
|
|
155
172
|
} else {
|
|
156
|
-
//
|
|
157
|
-
var exactStep = _this._map.targetFrameRate / _this._fps;
|
|
173
|
+
// 每帧应飞的"点数"(允许小数)
|
|
174
|
+
var exactStep = _this._fps ? _this._map.targetFrameRate / _this._fps : 1;
|
|
158
175
|
// 累加步长
|
|
159
176
|
_this._stepAccumulator += exactStep;
|
|
160
|
-
//
|
|
177
|
+
// 取整:当前帧应飞的"完整点数"
|
|
161
178
|
var step = Math.max(1, Math.floor(_this._stepAccumulator));
|
|
162
179
|
// 剩余留给下帧
|
|
163
|
-
_this._stepAccumulator -= step;
|
|
164
|
-
_this.currentPointIndex
|
|
180
|
+
_this._stepAccumulator -= Math.min(step, _this._stepAccumulator);
|
|
181
|
+
_this.currentPointIndex += step;
|
|
165
182
|
}
|
|
166
183
|
});
|
|
167
184
|
if (!map) {
|
|
@@ -179,6 +196,11 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
179
196
|
this.polylineOptions = merge(constant.DEFAULT_POLYLINE_PRIMITIVE_OPTIONS(), cloneDeep(polyline || {}));
|
|
180
197
|
this.flyTo = flyTo || false;
|
|
181
198
|
this._onPositionUpdate = onPositionUpdate;
|
|
199
|
+
|
|
200
|
+
// 初始化轨迹显示状态
|
|
201
|
+
if (this.polylineOptions && typeof this.polylineOptions.show === 'boolean') {
|
|
202
|
+
this.trailShowState = this.polylineOptions.show;
|
|
203
|
+
}
|
|
182
204
|
}
|
|
183
205
|
|
|
184
206
|
/**
|
|
@@ -193,7 +215,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
193
215
|
|
|
194
216
|
// 添加时间戳
|
|
195
217
|
if (!newPosition.timestamp) {
|
|
196
|
-
newPosition.timestamp =
|
|
218
|
+
newPosition.timestamp = performance.now();
|
|
197
219
|
}
|
|
198
220
|
|
|
199
221
|
// 如果是第一次接收数据,初始化模型
|
|
@@ -240,9 +262,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
240
262
|
var endC3 = Cesium.Cartesian3.fromDegrees(endPos.lng, endPos.lat, endPos.alt);
|
|
241
263
|
|
|
242
264
|
// 计算飞行时间
|
|
243
|
-
var
|
|
244
|
-
var flightTime = (newTime - this._time) / 1000;
|
|
245
|
-
this._time = newTime;
|
|
265
|
+
var flightTime = (endPos.timestamp - startPos.timestamp) / 1000;
|
|
246
266
|
|
|
247
267
|
// 计算插值点
|
|
248
268
|
var interpolatedPoints = this._getInterPosition(startC3, endC3, flightTime);
|
|
@@ -251,7 +271,8 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
251
271
|
endPos: endPos,
|
|
252
272
|
interpolatedPoints: interpolatedPoints,
|
|
253
273
|
segmentIndex: this.segmentCounter++,
|
|
254
|
-
isCompleted: false
|
|
274
|
+
isCompleted: false,
|
|
275
|
+
isMovedToHistory: false
|
|
255
276
|
};
|
|
256
277
|
|
|
257
278
|
// 如果当前没有正在飞行的路径段,则设为当前段
|
|
@@ -309,7 +330,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
309
330
|
}
|
|
310
331
|
|
|
311
332
|
// 计算总的插值点数 用最大帧率*时间计算点位
|
|
312
|
-
var numberOfPoints = Math.max(
|
|
333
|
+
var numberOfPoints = Math.max(2, Math.floor(flightTime * this._map.targetFrameRate) - 1);
|
|
313
334
|
|
|
314
335
|
// 计算时间步长
|
|
315
336
|
var timeStep = 1.0 / (numberOfPoints - 1);
|
|
@@ -422,18 +443,47 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
422
443
|
key: "initTrailLine",
|
|
423
444
|
value: function initTrailLine() {
|
|
424
445
|
var _this3 = this;
|
|
446
|
+
var mergeStyle = merge(constant.DEFAULT_POLYLINE_OPTIONS(), cloneDeep(this.polylineOptions || {}));
|
|
447
|
+
var currStyle = PolylineEntity.handleOptions(mergeStyle);
|
|
425
448
|
// 创建轨迹线Entity,使用callback动态更新位置
|
|
426
449
|
this.polylineLayer = this._map.entities.add({
|
|
427
450
|
id: uuidv4(),
|
|
428
|
-
polyline: {
|
|
451
|
+
polyline: _objectSpread({
|
|
429
452
|
positions: new Cesium.CallbackProperty(function () {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
}
|
|
453
|
+
// 即使轨迹隐藏,也要更新数据
|
|
454
|
+
var positions = _this3.getTrailLinePositions();
|
|
455
|
+
_this3.trailDataUpdated = true;
|
|
456
|
+
return positions;
|
|
457
|
+
}, false)
|
|
458
|
+
}, currStyle)
|
|
436
459
|
});
|
|
460
|
+
|
|
461
|
+
// 设置初始显示状态
|
|
462
|
+
if (this.polylineLayer) {
|
|
463
|
+
this.polylineLayer.polyline.show = this.trailShowState;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* 创建历史轨迹线Entity
|
|
469
|
+
*/
|
|
470
|
+
}, {
|
|
471
|
+
key: "createHistoryTrailLine",
|
|
472
|
+
value: function createHistoryTrailLine() {
|
|
473
|
+
var mergeStyle = merge(constant.DEFAULT_POLYLINE_OPTIONS(), cloneDeep(this.polylineOptions || {}));
|
|
474
|
+
var currStyle = PolylineEntity.handleOptions(mergeStyle);
|
|
475
|
+
// 创建历史轨迹线Entity,使用静态位置
|
|
476
|
+
this.historyPolylineLayer = this._map.entities.add({
|
|
477
|
+
id: uuidv4(),
|
|
478
|
+
polyline: _objectSpread({
|
|
479
|
+
positions: this.historyTrailPositions
|
|
480
|
+
}, currStyle)
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// 同步当前轨迹线的显示状态
|
|
484
|
+
if (this.polylineLayer) {
|
|
485
|
+
this.historyPolylineLayer.polyline.show = this.polylineLayer.polyline.show;
|
|
486
|
+
}
|
|
437
487
|
}
|
|
438
488
|
|
|
439
489
|
/**
|
|
@@ -450,10 +500,10 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
450
500
|
return positions;
|
|
451
501
|
}
|
|
452
502
|
|
|
453
|
-
//
|
|
503
|
+
// 添加已完成路径段的起始点和结束点(只处理未移动到历史的路径段)
|
|
454
504
|
if (Array.isArray(this.completedSegments)) {
|
|
455
505
|
this.completedSegments.forEach(function (segment) {
|
|
456
|
-
if (segment.startPos && segment.endPos) {
|
|
506
|
+
if (segment.startPos && segment.endPos && !segment.isMovedToHistory) {
|
|
457
507
|
// 添加起始点(如果这是第一个路径段或者与上一个路径段不重复)
|
|
458
508
|
if (positions.length === 0) {
|
|
459
509
|
positions.push(Cesium.Cartesian3.fromDegrees(segment.startPos.lng, segment.startPos.lat, segment.startPos.alt));
|
|
@@ -464,6 +514,9 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
464
514
|
});
|
|
465
515
|
}
|
|
466
516
|
|
|
517
|
+
// 检查数据量是否超过阈值,如果超过则将部分数据移到历史轨迹
|
|
518
|
+
this.checkAndMoveToHistory(positions);
|
|
519
|
+
|
|
467
520
|
// 如果当前有正在飞行的路径段,添加已飞行过的插值点
|
|
468
521
|
if (this.currentSegment && Array.isArray(this.currentSegment.interpolatedPoints) && this.currentPointIndex >= 0) {
|
|
469
522
|
// 如果还没有添加过任何点,先添加当前路径段的起始点
|
|
@@ -480,92 +533,76 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
480
533
|
}
|
|
481
534
|
|
|
482
535
|
/**
|
|
483
|
-
*
|
|
536
|
+
* 检查并移动数据到历史轨迹
|
|
484
537
|
*/
|
|
485
538
|
}, {
|
|
486
|
-
key: "
|
|
487
|
-
value: function
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
this.
|
|
539
|
+
key: "checkAndMoveToHistory",
|
|
540
|
+
value: function checkAndMoveToHistory(currentPositions) {
|
|
541
|
+
if (currentPositions.length > this.TRAIL_POSITIONS_THRESHOLD) {
|
|
542
|
+
var _this$historyTrailPos;
|
|
543
|
+
// 将所有超过阈值的点移动到历史轨迹
|
|
544
|
+
var positionsToHistory = currentPositions.slice(0, this.TRAIL_POSITIONS_THRESHOLD);
|
|
545
|
+
|
|
546
|
+
// 从当前轨迹中移除这些点
|
|
547
|
+
currentPositions.splice(0, this.TRAIL_POSITIONS_THRESHOLD);
|
|
548
|
+
|
|
549
|
+
// 标记已经移动到历史的路径段
|
|
550
|
+
this.markCompletedSegmentsAsMovedToHistory();
|
|
551
|
+
(_this$historyTrailPos = this.historyTrailPositions).push.apply(_this$historyTrailPos, _toConsumableArray(positionsToHistory));
|
|
552
|
+
|
|
553
|
+
// 如果历史轨迹图层不存在,创建它
|
|
554
|
+
if (!this.historyPolylineLayer) {
|
|
555
|
+
this.createHistoryTrailLine();
|
|
556
|
+
} else {
|
|
557
|
+
// 更新历史轨迹图层的位置
|
|
558
|
+
this.historyPolylineLayer.polyline.positions = this.historyTrailPositions;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// 同步显示状态
|
|
562
|
+
if (this.polylineLayer && this.historyPolylineLayer) {
|
|
563
|
+
this.historyPolylineLayer.polyline.show = this.polylineLayer.polyline.show;
|
|
564
|
+
}
|
|
492
565
|
}
|
|
493
566
|
}
|
|
494
567
|
|
|
495
568
|
/**
|
|
496
|
-
*
|
|
569
|
+
* 标记已经移动到历史的路径段
|
|
497
570
|
*/
|
|
498
571
|
}, {
|
|
499
|
-
key: "
|
|
500
|
-
value: function
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
};
|
|
572
|
+
key: "markCompletedSegmentsAsMovedToHistory",
|
|
573
|
+
value: function markCompletedSegmentsAsMovedToHistory() {
|
|
574
|
+
if (!Array.isArray(this.completedSegments) || this.completedSegments.length === 0) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// 标记除了最后一个路径段之外的所有已完成路径段
|
|
579
|
+
var segmentsToMark = this.completedSegments.length - 2;
|
|
580
|
+
for (var i = 0; i < segmentsToMark; i++) {
|
|
581
|
+
var segment = this.completedSegments[i];
|
|
582
|
+
if (segment.isCompleted && !segment.isMovedToHistory) {
|
|
583
|
+
segment.isMovedToHistory = true;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
514
586
|
}
|
|
515
587
|
|
|
516
588
|
/**
|
|
517
|
-
*
|
|
589
|
+
* 更新轨迹线 - 现在由CallbackProperty自动更新
|
|
518
590
|
*/
|
|
519
591
|
}, {
|
|
520
|
-
key: "
|
|
521
|
-
value: function
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
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
|
-
};
|
|
592
|
+
key: "updateTrailLine",
|
|
593
|
+
value: function updateTrailLine() {
|
|
594
|
+
// 由于使用了CallbackProperty和getTrailLinePositions方法
|
|
595
|
+
// 轨迹线会自动更新显示:所有原始位置点 + 当前段已飞行的插值点
|
|
596
|
+
if (!this.polylineLayer && this.receivedPositions.length >= 2) {
|
|
597
|
+
this.initTrailLine();
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// 强制更新轨迹数据,确保即使轨迹隐藏时数据也能正确更新
|
|
601
|
+
if (this.polylineLayer && !this.trailDataUpdated) {
|
|
602
|
+
// 手动触发一次数据更新
|
|
603
|
+
this.getTrailLinePositions();
|
|
604
|
+
this.trailDataUpdated = true;
|
|
605
|
+
}
|
|
569
606
|
}
|
|
570
607
|
|
|
571
608
|
/**
|
|
@@ -662,7 +699,20 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
662
699
|
}, {
|
|
663
700
|
key: "updateThirdPersonView",
|
|
664
701
|
value: function updateThirdPersonView(position) {
|
|
665
|
-
|
|
702
|
+
// 计算相机位置(在模型后方一定距离)
|
|
703
|
+
var transform = Cesium.Transforms.headingPitchRollToFixedFrame(position, this.hpRoll, Cesium.Ellipsoid.WGS84, Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west'));
|
|
704
|
+
var offset = new Cesium.Cartesian3(-this.thirdPersonSettings.distance, 0, 500);
|
|
705
|
+
var cameraPosition = Cesium.Matrix4.multiplyByPoint(transform, offset, new Cesium.Cartesian3());
|
|
706
|
+
|
|
707
|
+
// 设置相机位置和朝向
|
|
708
|
+
this._map.camera.setView({
|
|
709
|
+
destination: cameraPosition,
|
|
710
|
+
orientation: {
|
|
711
|
+
heading: this.hpRoll.heading,
|
|
712
|
+
pitch: Cesium.Math.toRadians(this.thirdPersonSettings.pitch),
|
|
713
|
+
roll: 0.0
|
|
714
|
+
}
|
|
715
|
+
});
|
|
666
716
|
}
|
|
667
717
|
|
|
668
718
|
/**
|
|
@@ -678,7 +728,7 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
678
728
|
}
|
|
679
729
|
|
|
680
730
|
/**
|
|
681
|
-
*
|
|
731
|
+
* 设置第三人称视角
|
|
682
732
|
*/
|
|
683
733
|
}, {
|
|
684
734
|
key: "setFollowThird",
|
|
@@ -710,6 +760,44 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
710
760
|
this._map.camera.flyToBoundingSphere(boundingSphere);
|
|
711
761
|
}
|
|
712
762
|
|
|
763
|
+
/**
|
|
764
|
+
* 显示隐藏飞行轨迹
|
|
765
|
+
* */
|
|
766
|
+
}, {
|
|
767
|
+
key: "showPolylineLayer",
|
|
768
|
+
value: function showPolylineLayer(isShow) {
|
|
769
|
+
this.trailShowState = isShow;
|
|
770
|
+
if (this.polylineLayer) {
|
|
771
|
+
this.polylineLayer.polyline.show = isShow;
|
|
772
|
+
}
|
|
773
|
+
if (this.historyPolylineLayer) {
|
|
774
|
+
this.historyPolylineLayer.polyline.show = isShow;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// 如果显示轨迹,强制更新一次数据以确保轨迹连续性
|
|
778
|
+
if (isShow && this.polylineLayer) {
|
|
779
|
+
this.trailDataUpdated = false;
|
|
780
|
+
// 手动触发一次数据更新
|
|
781
|
+
this.getTrailLinePositions();
|
|
782
|
+
this.trailDataUpdated = true;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* 强制更新轨迹数据
|
|
788
|
+
* 用于确保轨迹数据的连续性
|
|
789
|
+
*/
|
|
790
|
+
}, {
|
|
791
|
+
key: "forceUpdateTrailData",
|
|
792
|
+
value: function forceUpdateTrailData() {
|
|
793
|
+
if (this.polylineLayer) {
|
|
794
|
+
this.trailDataUpdated = false;
|
|
795
|
+
// 手动触发一次数据更新
|
|
796
|
+
this.getTrailLinePositions();
|
|
797
|
+
this.trailDataUpdated = true;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
713
801
|
/**
|
|
714
802
|
* 监听
|
|
715
803
|
*/
|
|
@@ -737,12 +825,19 @@ var ModelRoamRealTime = /*#__PURE__*/function () {
|
|
|
737
825
|
this._map.entities.remove(this.polylineLayer);
|
|
738
826
|
this.polylineLayer = null;
|
|
739
827
|
}
|
|
828
|
+
if (this.historyPolylineLayer) {
|
|
829
|
+
this._map.entities.remove(this.historyPolylineLayer);
|
|
830
|
+
this.historyPolylineLayer = null;
|
|
831
|
+
}
|
|
740
832
|
this.receivedPositions = [];
|
|
741
833
|
this.completedSegments = [];
|
|
742
834
|
this.currentSegment = null;
|
|
743
835
|
this.futureSegments = [];
|
|
744
836
|
this.currentPointIndex = 0;
|
|
745
837
|
this.segmentCounter = 0;
|
|
838
|
+
this.historyTrailPositions = [];
|
|
839
|
+
this.trailDataUpdated = false;
|
|
840
|
+
this.trailShowState = true;
|
|
746
841
|
}
|
|
747
842
|
}]);
|
|
748
843
|
return ModelRoamRealTime;
|
package/dist/esm/constant.js
CHANGED
|
@@ -353,10 +353,11 @@ export var DEFAULT_POLYLINE_TRAIL_LINK_MATERIAL_STYLE = function DEFAULT_POLYLIN
|
|
|
353
353
|
mixRatio: 0.5,
|
|
354
354
|
duration: 2,
|
|
355
355
|
count: 3,
|
|
356
|
+
repeat: [1, 1],
|
|
357
|
+
repeatPixel: 1000,
|
|
356
358
|
image: utils.getDeepTwinsFile('Image/line.png')
|
|
357
359
|
};
|
|
358
360
|
};
|
|
359
|
-
|
|
360
361
|
// 动态墙材质默认的配置
|
|
361
362
|
export var DEFAULT_DYNAMIC_WALL_MATERIAL_STYLE = function DEFAULT_DYNAMIC_WALL_MATERIAL_STYLE() {
|
|
362
363
|
return {
|