iflow-engine-base 4.0.15 → 4.0.18

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.
Files changed (148) hide show
  1. package/dist/bim-engine-sdk.es.js +33 -13
  2. package/dist/bim-engine-sdk.umd.js +2811 -342
  3. package/dist/chunks/EngineKernel-BucDRg23.js +20761 -0
  4. package/dist/chunks/engine-2d-BjtuYZUi.js +6119 -0
  5. package/dist/chunks/{engine-3d-DAEOqkkS.js → engine-3d-DnlK2vTK.js} +19422 -18597
  6. package/dist/chunks/engine-720-DJsweyG9.js +1565 -0
  7. package/dist/chunks/engine-gaussian-DklK6vdJ.js +8127 -0
  8. package/dist/chunks/gis-tiles-vendor-DIbUOKJM.js +11781 -0
  9. package/dist/chunks/index-BtsyaVm2.js +2640 -0
  10. package/dist/chunks/index-Ct7RfnLw.js +474 -0
  11. package/dist/chunks/index-Cyv0HpPm.js +438 -0
  12. package/dist/chunks/index-DZmXdy4v.js +717 -0
  13. package/dist/chunks/{sdk-assets-Eo-SBV02.js → sdk-assets-DtcFvuth.js} +10 -10
  14. package/dist/chunks/sdk-runtime-CFM9OAcx.js +1364 -0
  15. package/dist/chunks/sdk-vendor-6wYtfmXR.js +31826 -0
  16. package/dist/chunks/three-vendor-CGmeNMm5.js +81889 -0
  17. package/dist/gis-fixtures/terrain/0/0/0.terrain +0 -0
  18. package/dist/gis-fixtures/terrain/0/1/0.terrain +0 -0
  19. package/dist/gis-fixtures/terrain/1/2/0.terrain +0 -0
  20. package/dist/gis-fixtures/terrain/1/2/1.terrain +0 -0
  21. package/dist/gis-fixtures/terrain/1/3/0.terrain +0 -0
  22. package/dist/gis-fixtures/terrain/1/3/1.terrain +0 -0
  23. package/dist/gis-fixtures/terrain/10/1694/650.terrain +0 -0
  24. package/dist/gis-fixtures/terrain/10/1694/651.terrain +0 -0
  25. package/dist/gis-fixtures/terrain/10/1694/652.terrain +0 -0
  26. package/dist/gis-fixtures/terrain/10/1695/650.terrain +0 -0
  27. package/dist/gis-fixtures/terrain/10/1695/651.terrain +0 -0
  28. package/dist/gis-fixtures/terrain/10/1695/652.terrain +0 -0
  29. package/dist/gis-fixtures/terrain/10/1696/650.terrain +0 -0
  30. package/dist/gis-fixtures/terrain/10/1696/651.terrain +0 -0
  31. package/dist/gis-fixtures/terrain/10/1696/652.terrain +0 -0
  32. package/dist/gis-fixtures/terrain/11/3390/1301.terrain +0 -0
  33. package/dist/gis-fixtures/terrain/11/3390/1302.terrain +0 -0
  34. package/dist/gis-fixtures/terrain/11/3390/1303.terrain +0 -0
  35. package/dist/gis-fixtures/terrain/11/3391/1301.terrain +0 -0
  36. package/dist/gis-fixtures/terrain/11/3391/1302.terrain +0 -0
  37. package/dist/gis-fixtures/terrain/11/3391/1303.terrain +0 -0
  38. package/dist/gis-fixtures/terrain/11/3392/1301.terrain +0 -0
  39. package/dist/gis-fixtures/terrain/11/3392/1302.terrain +0 -0
  40. package/dist/gis-fixtures/terrain/11/3392/1303.terrain +0 -0
  41. package/dist/gis-fixtures/terrain/12/6782/2604.terrain +0 -0
  42. package/dist/gis-fixtures/terrain/12/6782/2605.terrain +0 -0
  43. package/dist/gis-fixtures/terrain/12/6782/2606.terrain +0 -0
  44. package/dist/gis-fixtures/terrain/12/6783/2604.terrain +0 -0
  45. package/dist/gis-fixtures/terrain/12/6783/2605.terrain +0 -0
  46. package/dist/gis-fixtures/terrain/12/6783/2606.terrain +0 -0
  47. package/dist/gis-fixtures/terrain/12/6784/2604.terrain +0 -0
  48. package/dist/gis-fixtures/terrain/12/6784/2605.terrain +0 -0
  49. package/dist/gis-fixtures/terrain/12/6784/2606.terrain +0 -0
  50. package/dist/gis-fixtures/terrain/13/13565/5209.terrain +0 -0
  51. package/dist/gis-fixtures/terrain/13/13565/5210.terrain +0 -0
  52. package/dist/gis-fixtures/terrain/13/13565/5211.terrain +0 -0
  53. package/dist/gis-fixtures/terrain/13/13566/5209.terrain +0 -0
  54. package/dist/gis-fixtures/terrain/13/13566/5210.terrain +0 -0
  55. package/dist/gis-fixtures/terrain/13/13566/5211.terrain +0 -0
  56. package/dist/gis-fixtures/terrain/13/13567/5209.terrain +0 -0
  57. package/dist/gis-fixtures/terrain/13/13567/5210.terrain +0 -0
  58. package/dist/gis-fixtures/terrain/13/13567/5211.terrain +0 -0
  59. package/dist/gis-fixtures/terrain/14/27131/10419.terrain +0 -0
  60. package/dist/gis-fixtures/terrain/14/27131/10420.terrain +0 -0
  61. package/dist/gis-fixtures/terrain/14/27131/10421.terrain +0 -0
  62. package/dist/gis-fixtures/terrain/14/27132/10419.terrain +0 -0
  63. package/dist/gis-fixtures/terrain/14/27132/10420.terrain +0 -0
  64. package/dist/gis-fixtures/terrain/14/27132/10421.terrain +0 -0
  65. package/dist/gis-fixtures/terrain/14/27133/10419.terrain +0 -0
  66. package/dist/gis-fixtures/terrain/14/27133/10420.terrain +0 -0
  67. package/dist/gis-fixtures/terrain/14/27133/10421.terrain +0 -0
  68. package/dist/gis-fixtures/terrain/2/5/1.terrain +0 -0
  69. package/dist/gis-fixtures/terrain/2/5/2.terrain +0 -0
  70. package/dist/gis-fixtures/terrain/2/5/3.terrain +0 -0
  71. package/dist/gis-fixtures/terrain/2/6/1.terrain +0 -0
  72. package/dist/gis-fixtures/terrain/2/6/2.terrain +0 -0
  73. package/dist/gis-fixtures/terrain/2/6/3.terrain +0 -0
  74. package/dist/gis-fixtures/terrain/2/7/1.terrain +0 -0
  75. package/dist/gis-fixtures/terrain/2/7/2.terrain +0 -0
  76. package/dist/gis-fixtures/terrain/2/7/3.terrain +0 -0
  77. package/dist/gis-fixtures/terrain/3/12/4.terrain +0 -0
  78. package/dist/gis-fixtures/terrain/3/12/5.terrain +0 -0
  79. package/dist/gis-fixtures/terrain/3/12/6.terrain +0 -0
  80. package/dist/gis-fixtures/terrain/3/13/4.terrain +0 -0
  81. package/dist/gis-fixtures/terrain/3/13/5.terrain +0 -0
  82. package/dist/gis-fixtures/terrain/3/13/6.terrain +0 -0
  83. package/dist/gis-fixtures/terrain/3/14/4.terrain +0 -0
  84. package/dist/gis-fixtures/terrain/3/14/5.terrain +0 -0
  85. package/dist/gis-fixtures/terrain/3/14/6.terrain +0 -0
  86. package/dist/gis-fixtures/terrain/4/25/10.terrain +0 -0
  87. package/dist/gis-fixtures/terrain/4/25/11.terrain +0 -0
  88. package/dist/gis-fixtures/terrain/4/25/9.terrain +0 -0
  89. package/dist/gis-fixtures/terrain/4/26/10.terrain +0 -0
  90. package/dist/gis-fixtures/terrain/4/26/11.terrain +0 -0
  91. package/dist/gis-fixtures/terrain/4/26/9.terrain +0 -0
  92. package/dist/gis-fixtures/terrain/4/27/10.terrain +0 -0
  93. package/dist/gis-fixtures/terrain/4/27/11.terrain +0 -0
  94. package/dist/gis-fixtures/terrain/4/27/9.terrain +0 -0
  95. package/dist/gis-fixtures/terrain/5/51/19.terrain +0 -0
  96. package/dist/gis-fixtures/terrain/5/51/20.terrain +0 -0
  97. package/dist/gis-fixtures/terrain/5/51/21.terrain +0 -0
  98. package/dist/gis-fixtures/terrain/5/52/19.terrain +0 -0
  99. package/dist/gis-fixtures/terrain/5/52/20.terrain +0 -0
  100. package/dist/gis-fixtures/terrain/5/52/21.terrain +0 -0
  101. package/dist/gis-fixtures/terrain/5/53/19.terrain +0 -0
  102. package/dist/gis-fixtures/terrain/5/53/20.terrain +0 -0
  103. package/dist/gis-fixtures/terrain/5/53/21.terrain +0 -0
  104. package/dist/gis-fixtures/terrain/6/104/39.terrain +0 -0
  105. package/dist/gis-fixtures/terrain/6/104/40.terrain +0 -0
  106. package/dist/gis-fixtures/terrain/6/104/41.terrain +0 -0
  107. package/dist/gis-fixtures/terrain/6/105/39.terrain +0 -0
  108. package/dist/gis-fixtures/terrain/6/105/40.terrain +0 -0
  109. package/dist/gis-fixtures/terrain/6/105/41.terrain +0 -0
  110. package/dist/gis-fixtures/terrain/6/106/39.terrain +0 -0
  111. package/dist/gis-fixtures/terrain/6/106/40.terrain +0 -0
  112. package/dist/gis-fixtures/terrain/6/106/41.terrain +0 -0
  113. package/dist/gis-fixtures/terrain/7/210/80.terrain +0 -0
  114. package/dist/gis-fixtures/terrain/7/210/81.terrain +0 -0
  115. package/dist/gis-fixtures/terrain/7/210/82.terrain +0 -0
  116. package/dist/gis-fixtures/terrain/7/211/80.terrain +0 -0
  117. package/dist/gis-fixtures/terrain/7/211/81.terrain +0 -0
  118. package/dist/gis-fixtures/terrain/7/211/82.terrain +0 -0
  119. package/dist/gis-fixtures/terrain/7/212/80.terrain +0 -0
  120. package/dist/gis-fixtures/terrain/7/212/81.terrain +0 -0
  121. package/dist/gis-fixtures/terrain/7/212/82.terrain +0 -0
  122. package/dist/gis-fixtures/terrain/8/422/161.terrain +0 -0
  123. package/dist/gis-fixtures/terrain/8/422/162.terrain +0 -0
  124. package/dist/gis-fixtures/terrain/8/422/163.terrain +0 -0
  125. package/dist/gis-fixtures/terrain/8/423/161.terrain +0 -0
  126. package/dist/gis-fixtures/terrain/8/423/162.terrain +0 -0
  127. package/dist/gis-fixtures/terrain/8/423/163.terrain +0 -0
  128. package/dist/gis-fixtures/terrain/8/424/161.terrain +0 -0
  129. package/dist/gis-fixtures/terrain/8/424/162.terrain +0 -0
  130. package/dist/gis-fixtures/terrain/8/424/163.terrain +0 -0
  131. package/dist/gis-fixtures/terrain/9/846/324.terrain +0 -0
  132. package/dist/gis-fixtures/terrain/9/846/325.terrain +0 -0
  133. package/dist/gis-fixtures/terrain/9/846/326.terrain +0 -0
  134. package/dist/gis-fixtures/terrain/9/847/324.terrain +0 -0
  135. package/dist/gis-fixtures/terrain/9/847/325.terrain +0 -0
  136. package/dist/gis-fixtures/terrain/9/847/326.terrain +0 -0
  137. package/dist/gis-fixtures/terrain/9/848/324.terrain +0 -0
  138. package/dist/gis-fixtures/terrain/9/848/325.terrain +0 -0
  139. package/dist/gis-fixtures/terrain/9/848/326.terrain +0 -0
  140. package/dist/gis-fixtures/terrain/layer.json +141 -0
  141. package/dist/gis-fixtures/tilesets/xiamen-local/scene.gltf +31 -0
  142. package/dist/gis-fixtures/tilesets/xiamen-local/tileset.json +12 -0
  143. package/dist/iflow-engine-base.css +1 -1
  144. package/dist/index.d.ts +13908 -68
  145. package/package.json +8 -18
  146. package/dist/chunks/sdk-runtime-CB2jwkGL.js +0 -1177
  147. package/dist/chunks/sdk-vendor-DtYOqJWo.js +0 -23208
  148. package/dist/chunks/three-vendor-rBTtPKhu.js +0 -44788
@@ -0,0 +1,1565 @@
1
+ import { i as S, as as R, ae as E, d as x, M as A, P as b, s as k, Q as F, m as I, W as y, k as v, f, S as P, L as m, a as p, V as D } from "./three-vendor-CGmeNMm5.js";
2
+ import { C as L, W as w, E as T, c as z, r as _ } from "./sdk-runtime-CFM9OAcx.js";
3
+ class V {
4
+ scene;
5
+ panoramaSphere = null;
6
+ sphereRadius;
7
+ constructor(e = 500) {
8
+ this.sphereRadius = e, this.scene = new S(), this.init();
9
+ }
10
+ /**
11
+ * 初始化场景
12
+ */
13
+ init() {
14
+ this.panoramaSphere = this.createPanoramaSphere(this.sphereRadius), this.scene.add(this.panoramaSphere);
15
+ }
16
+ /**
17
+ * 创建全景球体
18
+ * @param radius 球体半径(建议 500-1000)
19
+ * @param segments 分段数(建议 64)
20
+ * @returns 球体网格对象
21
+ */
22
+ createPanoramaSphere(e = 500, t = 64) {
23
+ const n = new R(
24
+ e,
25
+ // 半径
26
+ t,
27
+ // 水平分段
28
+ t / 2
29
+ // 垂直分段
30
+ );
31
+ n.scale(-1, 1, 1);
32
+ const o = new E({
33
+ map: null,
34
+ // 纹理后续加载
35
+ side: x,
36
+ // Render inner surface; geometry is flipped via scale(-1,1,1)
37
+ transparent: !0
38
+ }), a = new A(n, o);
39
+ return a.name = "panorama-sphere", a;
40
+ }
41
+ /**
42
+ * 更新全景图纹理
43
+ * @param texture Three.js 纹理对象
44
+ */
45
+ updatePanoramaTexture(e) {
46
+ if (!this.panoramaSphere) {
47
+ console.warn("SceneModule720: Panorama sphere not initialized");
48
+ return;
49
+ }
50
+ const t = this.panoramaSphere.material;
51
+ t.map && t.map.dispose(), t.map = e, t.needsUpdate = !0;
52
+ }
53
+ /**
54
+ * 清除当前全景纹理
55
+ */
56
+ clearPanoramaTexture() {
57
+ if (!this.panoramaSphere)
58
+ return;
59
+ const e = this.panoramaSphere.material;
60
+ e.map && (e.map.dispose(), e.map = null, e.needsUpdate = !0);
61
+ }
62
+ /**
63
+ * 获取场景对象
64
+ */
65
+ getScene() {
66
+ return this.scene;
67
+ }
68
+ /**
69
+ * 获取全景球体对象
70
+ */
71
+ getPanoramaSphere() {
72
+ return this.panoramaSphere;
73
+ }
74
+ /**
75
+ * 设置球体半径(需要重新创建球体)
76
+ * @param radius 新的半径
77
+ */
78
+ setSphereRadius(e) {
79
+ if (this.sphereRadius !== e) {
80
+ if (this.sphereRadius = e, this.panoramaSphere) {
81
+ const t = this.panoramaSphere.material, n = t.map;
82
+ this.scene.remove(this.panoramaSphere), this.panoramaSphere.geometry.dispose(), t.dispose(), n && n.dispose();
83
+ }
84
+ this.panoramaSphere = this.createPanoramaSphere(e), this.scene.add(this.panoramaSphere);
85
+ }
86
+ }
87
+ /**
88
+ * 获取球体半径
89
+ */
90
+ getSphereRadius() {
91
+ return this.sphereRadius;
92
+ }
93
+ /**
94
+ * 销毁模块
95
+ */
96
+ dispose() {
97
+ if (this.panoramaSphere) {
98
+ const e = this.panoramaSphere.material;
99
+ e.map && e.map.dispose(), e.dispose(), this.panoramaSphere.geometry.dispose(), this.scene.remove(this.panoramaSphere), this.panoramaSphere = null;
100
+ }
101
+ this.scene.clear();
102
+ }
103
+ }
104
+ class K {
105
+ camera;
106
+ minFov;
107
+ maxFov;
108
+ container;
109
+ /**
110
+ * 当前相机姿态(球面坐标)
111
+ */
112
+ currentPose;
113
+ constructor(e, t = 75, n = 30, o = 90) {
114
+ this.container = e, this.minFov = n, this.maxFov = o, this.currentPose = {
115
+ theta: 0,
116
+ // 水平角度
117
+ phi: 0
118
+ // 垂直角度
119
+ }, this.camera = this.createCamera(t), this.init();
120
+ }
121
+ /**
122
+ * 创建透视相机
123
+ */
124
+ createCamera(e) {
125
+ const t = this.container.clientWidth / this.container.clientHeight, n = new b(e, t, 0.1, 2e3);
126
+ return n.position.set(0, 0, 0), n;
127
+ }
128
+ /**
129
+ * 初始化相机
130
+ */
131
+ init() {
132
+ this.updateCameraRotation();
133
+ }
134
+ /**
135
+ * 更新相机旋转(基于当前姿态)
136
+ */
137
+ updateCameraRotation() {
138
+ const { theta: e, phi: t } = this.currentPose, n = new k(t, e, 0, "YXZ"), o = new F();
139
+ o.setFromEuler(n), this.camera.quaternion.copy(o);
140
+ }
141
+ /**
142
+ * 设置 FOV(视野角度)
143
+ * @param fov 视野角度(度)
144
+ */
145
+ setFov(e) {
146
+ const t = Math.max(this.minFov, Math.min(this.maxFov, e));
147
+ this.camera.fov = t, this.camera.updateProjectionMatrix();
148
+ }
149
+ /**
150
+ * 获取当前 FOV
151
+ */
152
+ getFov() {
153
+ return this.camera.fov;
154
+ }
155
+ /**
156
+ * 获取相机姿态
157
+ */
158
+ getCameraPose() {
159
+ return { ...this.currentPose };
160
+ }
161
+ /**
162
+ * 设置相机姿态(球面坐标)
163
+ * @param theta 水平角度(弧度)
164
+ * @param phi 垂直角度(弧度)
165
+ */
166
+ setCameraPose(e, t) {
167
+ this.currentPose.theta = e, this.currentPose.phi = t, this.updateCameraRotation();
168
+ }
169
+ /**
170
+ * 更新相机姿态(增量更新)
171
+ * @param deltaTheta 水平角度增量(弧度)
172
+ * @param deltaPhi 垂直角度增量(弧度)
173
+ */
174
+ updatePose(e, t) {
175
+ this.currentPose.theta += e, this.currentPose.phi += t, this.currentPose.theta < 0 ? this.currentPose.theta += 2 * Math.PI : this.currentPose.theta >= 2 * Math.PI && (this.currentPose.theta -= 2 * Math.PI), this.currentPose.phi = Math.max(
176
+ -Math.PI / 2 + 0.01,
177
+ Math.min(Math.PI / 2 - 0.01, this.currentPose.phi)
178
+ ), this.updateCameraRotation();
179
+ }
180
+ /**
181
+ * 获取相机对象
182
+ */
183
+ getCamera() {
184
+ return this.camera;
185
+ }
186
+ /**
187
+ * 调整相机宽高比
188
+ * @param width 容器宽度
189
+ * @param height 容器高度
190
+ */
191
+ updateAspectRatio(e, t) {
192
+ const n = e / t;
193
+ this.camera.aspect = n, this.camera.updateProjectionMatrix();
194
+ }
195
+ /**
196
+ * 销毁相机
197
+ */
198
+ dispose() {
199
+ this.camera = null;
200
+ }
201
+ }
202
+ class O {
203
+ renderer;
204
+ container;
205
+ animationId = null;
206
+ isRenderingPaused = !1;
207
+ watermark;
208
+ // FPS 监控
209
+ fpsFrameCount = 0;
210
+ fpsLastTime = performance.now();
211
+ currentFps = 60;
212
+ // 渲染回调
213
+ onBeforeRenderCallback;
214
+ onAfterRenderCallback;
215
+ constructor(e, t = !0) {
216
+ this.container = e, this.renderer = this.createRenderer(t), this.watermark = new L(I), this.init();
217
+ }
218
+ /**
219
+ * 创建 WebGL 渲染器
220
+ */
221
+ createRenderer(e) {
222
+ const t = new y({
223
+ antialias: e,
224
+ alpha: !0,
225
+ preserveDrawingBuffer: !1
226
+ }), n = this.container.clientWidth, o = this.container.clientHeight;
227
+ return t.setSize(n, o), t.setPixelRatio(Math.min(window.devicePixelRatio, 2)), this.container.appendChild(t.domElement), t;
228
+ }
229
+ /**
230
+ * 初始化渲染器
231
+ */
232
+ init() {
233
+ }
234
+ /**
235
+ * 设置渲染前回调
236
+ */
237
+ setOnBeforeRender(e) {
238
+ this.onBeforeRenderCallback = e;
239
+ }
240
+ /**
241
+ * 设置渲染后回调
242
+ */
243
+ setOnAfterRender(e) {
244
+ this.onAfterRenderCallback = e;
245
+ }
246
+ /**
247
+ * 渲染场景
248
+ */
249
+ render(e, t) {
250
+ this.onBeforeRenderCallback && this.onBeforeRenderCallback(), this.renderer.render(e, t), this.watermark.render(this.renderer), this.onAfterRenderCallback && this.onAfterRenderCallback(), this.updateFps();
251
+ }
252
+ /**
253
+ * 启动渲染循环
254
+ * @param scene Three.js 场景
255
+ * @param camera Three.js 相机
256
+ */
257
+ startRenderLoop(e, t) {
258
+ if (this.animationId !== null) {
259
+ console.warn("RenderModule720: Render loop already running");
260
+ return;
261
+ }
262
+ this.isRenderingPaused = !1, this.animate(e, t);
263
+ }
264
+ /**
265
+ * 动画循环
266
+ */
267
+ animate(e, t) {
268
+ this.isRenderingPaused || (this.animationId = requestAnimationFrame(() => {
269
+ this.animate(e, t);
270
+ }), this.render(e, t));
271
+ }
272
+ /**
273
+ * 暂停渲染
274
+ */
275
+ pauseRendering() {
276
+ this.isRenderingPaused = !0, this.animationId !== null && (cancelAnimationFrame(this.animationId), this.animationId = null);
277
+ }
278
+ /**
279
+ * 恢复渲染
280
+ */
281
+ resumeRendering(e, t) {
282
+ this.isRenderingPaused && (this.isRenderingPaused = !1, this.startRenderLoop(e, t));
283
+ }
284
+ /**
285
+ * 检查渲染是否暂停
286
+ */
287
+ isRenderingPausedState() {
288
+ return this.isRenderingPaused;
289
+ }
290
+ /**
291
+ * 更新 FPS
292
+ */
293
+ updateFps() {
294
+ this.fpsFrameCount++;
295
+ const e = performance.now();
296
+ e >= this.fpsLastTime + 1e3 && (this.currentFps = Math.round(this.fpsFrameCount * 1e3 / (e - this.fpsLastTime)), this.fpsFrameCount = 0, this.fpsLastTime = e, this.currentFps < 30 && console.warn("RenderModule720: Low FPS detected:", this.currentFps));
297
+ }
298
+ /**
299
+ * 获取当前 FPS
300
+ */
301
+ getCurrentFps() {
302
+ return this.currentFps;
303
+ }
304
+ /**
305
+ * 调整渲染器大小
306
+ * @param width 容器宽度
307
+ * @param height 容器高度
308
+ */
309
+ resize(e, t) {
310
+ this.renderer.setSize(e, t), this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
311
+ }
312
+ /**
313
+ * 获取渲染器 DOM 元素
314
+ */
315
+ getDomElement() {
316
+ return this.renderer.domElement;
317
+ }
318
+ /**
319
+ * 获取渲染器对象
320
+ */
321
+ getRenderer() {
322
+ return this.renderer;
323
+ }
324
+ /**
325
+ * 销毁渲染器
326
+ */
327
+ dispose() {
328
+ this.pauseRendering(), this.container.contains(this.renderer.domElement) && this.container.removeChild(this.renderer.domElement), this.watermark.dispose(), this.renderer.dispose(), this.renderer.forceContextLoss(), this.onBeforeRenderCallback = void 0, this.onAfterRenderCallback = void 0;
329
+ }
330
+ }
331
+ class H {
332
+ camera;
333
+ domElement;
334
+ cameraModule;
335
+ // CameraModule720 引用
336
+ // 配置参数
337
+ enableZoom = !0;
338
+ enableRotate = !0;
339
+ minFov = 30;
340
+ // 最小 FOV (最大缩放)
341
+ maxFov = 90;
342
+ // 最大 FOV (最小缩放)
343
+ rotateSpeed = 0.5;
344
+ zoomSpeed = 1;
345
+ enableDamping = !0;
346
+ dampingFactor = 0.05;
347
+ // 内部状态
348
+ isDragging = !1;
349
+ startX = 0;
350
+ startY = 0;
351
+ // 旋转增量
352
+ thetaDelta = 0;
353
+ phiDelta = 0;
354
+ isPinching = !1;
355
+ pinchStartDistance = null;
356
+ pinchStartFov = 75;
357
+ // 事件监听器绑定
358
+ _onMouseDown;
359
+ _onMouseMove;
360
+ _onMouseUp;
361
+ _onWheel;
362
+ _onTouchStart;
363
+ _onTouchMove;
364
+ _onTouchEnd;
365
+ // 视角变化回调
366
+ onViewAngleChange;
367
+ constructor(e, t) {
368
+ this.cameraModule = e, this.camera = e.getCamera(), this.pinchStartFov = this.camera.fov, this.domElement = t, this._onMouseDown = this.onMouseDown.bind(this), this._onMouseMove = this.onMouseMove.bind(this), this._onMouseUp = this.onMouseUp.bind(this), this._onWheel = this.onWheel.bind(this), this._onTouchStart = this.onTouchStart.bind(this), this._onTouchMove = this.onTouchMove.bind(this), this._onTouchEnd = this.onTouchEnd.bind(this), this.init();
369
+ }
370
+ /**
371
+ * 初始化控制器
372
+ */
373
+ init() {
374
+ this.domElement.addEventListener("mousedown", this._onMouseDown), this.domElement.addEventListener("mousemove", this._onMouseMove), this.domElement.addEventListener("mouseup", this._onMouseUp), this.domElement.addEventListener("mouseleave", this._onMouseUp), this.domElement.addEventListener("wheel", this._onWheel, { passive: !1 }), this.domElement.addEventListener("touchstart", this._onTouchStart, { passive: !1 }), this.domElement.addEventListener("touchmove", this._onTouchMove, { passive: !1 }), this.domElement.addEventListener("touchend", this._onTouchEnd);
375
+ }
376
+ /**
377
+ * 鼠标按下
378
+ */
379
+ onMouseDown(e) {
380
+ e.button === 0 && (this.isDragging = !0, this.startX = e.clientX, this.startY = e.clientY);
381
+ }
382
+ /**
383
+ * 鼠标移动
384
+ */
385
+ onMouseMove(e) {
386
+ if (!this.isDragging || !this.enableRotate) return;
387
+ const t = e.clientX - this.startX, n = e.clientY - this.startY, { horizontal: o, vertical: a } = this.getRotationFactors();
388
+ this.thetaDelta += t * o * this.rotateSpeed * 0.06, this.phiDelta += n * a * this.rotateSpeed * 0.06, this.startX = e.clientX, this.startY = e.clientY, this.applyRotation();
389
+ }
390
+ /**
391
+ * 鼠标弹起
392
+ */
393
+ onMouseUp() {
394
+ this.isDragging = !1;
395
+ }
396
+ /**
397
+ * 鼠标滚轮
398
+ */
399
+ onWheel(e) {
400
+ if (!this.enableZoom) return;
401
+ e.preventDefault();
402
+ const n = (e.deltaY > 0 ? 1 : -1) * this.zoomSpeed * 2;
403
+ this.applyZoom(n);
404
+ }
405
+ /**
406
+ * 触摸开始
407
+ */
408
+ onTouchStart(e) {
409
+ e.touches.length === 1 ? (this.isDragging = !0, this.isPinching = !1, this.startX = e.touches[0].clientX, this.startY = e.touches[0].clientY) : e.touches.length === 2 && (e.preventDefault(), this.isDragging = !1, this.isPinching = !0, this.pinchStartDistance = this.getTouchDistance(e.touches), this.pinchStartFov = this.cameraModule.getFov());
410
+ }
411
+ /**
412
+ * 触摸移动
413
+ */
414
+ onTouchMove(e) {
415
+ if (e.touches.length === 1 && this.isDragging && this.enableRotate) {
416
+ const t = e.touches[0].clientX - this.startX, n = e.touches[0].clientY - this.startY, { horizontal: o, vertical: a } = this.getRotationFactors();
417
+ this.thetaDelta -= t * o * this.rotateSpeed, this.phiDelta -= n * a * this.rotateSpeed, this.startX = e.touches[0].clientX, this.startY = e.touches[0].clientY, this.applyRotation();
418
+ } else if (e.touches.length === 2 && this.enableZoom) {
419
+ e.preventDefault(), this.isPinching || (this.isPinching = !0, this.pinchStartDistance = this.getTouchDistance(e.touches), this.pinchStartFov = this.cameraModule.getFov());
420
+ const t = this.getTouchDistance(e.touches);
421
+ if (this.pinchStartDistance && t > 0) {
422
+ const n = this.pinchStartDistance / t, o = v.clamp(
423
+ this.pinchStartFov * n,
424
+ this.minFov,
425
+ this.maxFov
426
+ );
427
+ this.cameraModule.setFov(o);
428
+ }
429
+ }
430
+ }
431
+ /**
432
+ * 触摸结束
433
+ */
434
+ onTouchEnd(e) {
435
+ e.touches && e.touches.length > 0 ? this.isDragging = e.touches.length === 1 : this.isDragging = !1, e.touches.length < 2 && (this.isPinching = !1, this.pinchStartDistance = null);
436
+ }
437
+ /**
438
+ * 应用旋转
439
+ */
440
+ applyRotation() {
441
+ if (this.cameraModule.updatePose(this.thetaDelta, this.phiDelta), this.enableDamping ? (this.thetaDelta *= 1 - this.dampingFactor, this.phiDelta *= 1 - this.dampingFactor) : (this.thetaDelta = 0, this.phiDelta = 0), this.onViewAngleChange) {
442
+ const e = this.cameraModule.getCameraPose();
443
+ this.onViewAngleChange(e.theta, e.phi);
444
+ }
445
+ }
446
+ /**
447
+ * 根据容器尺寸计算旋转灵敏度
448
+ */
449
+ getRotationFactors() {
450
+ const e = Math.max(1, this.domElement.clientWidth), t = Math.max(1, this.domElement.clientHeight);
451
+ return {
452
+ horizontal: Math.PI * 2 / e,
453
+ vertical: Math.PI / t
454
+ };
455
+ }
456
+ /**
457
+ * 统一缩放逻辑
458
+ */
459
+ applyZoom(e) {
460
+ const t = this.cameraModule.getFov(), n = v.clamp(
461
+ t + e,
462
+ this.minFov,
463
+ this.maxFov
464
+ );
465
+ this.cameraModule.setFov(n);
466
+ }
467
+ /**
468
+ * 计算多指距离
469
+ */
470
+ getTouchDistance(e) {
471
+ if (e.length < 2)
472
+ return 0;
473
+ const t = e[0].clientX - e[1].clientX, n = e[0].clientY - e[1].clientY;
474
+ return Math.sqrt(t * t + n * n);
475
+ }
476
+ /**
477
+ * 每帧更新(用于阻尼效果)
478
+ */
479
+ update() {
480
+ this.enableDamping && (Math.abs(this.thetaDelta) > 1e-4 || Math.abs(this.phiDelta) > 1e-4) && this.applyRotation();
481
+ }
482
+ /**
483
+ * 设置相机朝向(通过经纬度)
484
+ * @param theta 水平角度(弧度)
485
+ * @param phi 垂直角度(弧度)
486
+ */
487
+ lookAt(e, t) {
488
+ this.thetaDelta = e, this.phiDelta = Math.max(
489
+ -Math.PI / 2 + 0.01,
490
+ Math.min(Math.PI / 2 - 0.01, t)
491
+ ), this.cameraModule.setCameraPose(e, t), this.thetaDelta = 0, this.phiDelta = 0;
492
+ }
493
+ /**
494
+ * 获取当前视角
495
+ */
496
+ getViewAngle() {
497
+ return this.cameraModule.getCameraPose();
498
+ }
499
+ /**
500
+ * 设置视角变化回调
501
+ */
502
+ setOnViewAngleChange(e) {
503
+ this.onViewAngleChange = e;
504
+ }
505
+ /**
506
+ * 重置控制器
507
+ */
508
+ reset() {
509
+ this.thetaDelta = 0, this.phiDelta = 0, this.lookAt(0, 0);
510
+ }
511
+ /**
512
+ * 更新旋转灵敏度
513
+ */
514
+ setRotateSpeed(e) {
515
+ this.rotateSpeed = Math.max(0.05, e);
516
+ }
517
+ /**
518
+ * 更新缩放灵敏度
519
+ */
520
+ setZoomSpeed(e) {
521
+ this.zoomSpeed = Math.max(0.1, e);
522
+ }
523
+ /**
524
+ * 更新阻尼配置
525
+ */
526
+ setEnableDamping(e) {
527
+ this.enableDamping = e;
528
+ }
529
+ setDampingFactor(e) {
530
+ this.dampingFactor = Math.max(0, Math.min(1, e));
531
+ }
532
+ /**
533
+ * 更新 FOV 限制
534
+ */
535
+ setZoomLimits(e, t) {
536
+ this.minFov = e, this.maxFov = t;
537
+ }
538
+ /**
539
+ * 销毁控制器
540
+ */
541
+ dispose() {
542
+ this.domElement.removeEventListener("mousedown", this._onMouseDown), this.domElement.removeEventListener("mousemove", this._onMouseMove), this.domElement.removeEventListener("mouseup", this._onMouseUp), this.domElement.removeEventListener("mouseleave", this._onMouseUp), this.domElement.removeEventListener("wheel", this._onWheel), this.domElement.removeEventListener("touchstart", this._onTouchStart), this.domElement.removeEventListener("touchmove", this._onTouchMove), this.domElement.removeEventListener("touchend", this._onTouchEnd), this.onViewAngleChange = void 0;
543
+ }
544
+ }
545
+ class X {
546
+ controls;
547
+ domElement;
548
+ cameraModule;
549
+ constructor(e, t) {
550
+ this.cameraModule = e, this.domElement = t, this.controls = new H(e, t);
551
+ }
552
+ /**
553
+ * 初始化控制模块
554
+ */
555
+ init() {
556
+ }
557
+ /**
558
+ * 激活控制器
559
+ */
560
+ active() {
561
+ }
562
+ /**
563
+ * 禁用控制器
564
+ */
565
+ disActive() {
566
+ this.controls.enableRotate = !1, this.controls.enableZoom = !1;
567
+ }
568
+ /**
569
+ * 重新启用控制器
570
+ */
571
+ enable() {
572
+ this.controls.enableRotate = !0, this.controls.enableZoom = !0;
573
+ }
574
+ /**
575
+ * 更新控制器(每帧调用)
576
+ */
577
+ update() {
578
+ this.controls.update();
579
+ }
580
+ /**
581
+ * 设置视角
582
+ */
583
+ lookAt(e, t) {
584
+ this.controls.lookAt(e, t);
585
+ }
586
+ /**
587
+ * 获取当前视角
588
+ */
589
+ getViewAngle() {
590
+ return this.controls.getViewAngle();
591
+ }
592
+ /**
593
+ * 设置视角变化回调
594
+ */
595
+ setOnViewAngleChange(e) {
596
+ this.controls.setOnViewAngleChange(e);
597
+ }
598
+ /**
599
+ * 重置控制器
600
+ */
601
+ reset() {
602
+ this.controls.reset();
603
+ }
604
+ /**
605
+ * 获取控制器对象
606
+ */
607
+ getControls() {
608
+ return this.controls;
609
+ }
610
+ /**
611
+ * 动态更新交互参数
612
+ */
613
+ updateInteractionOptions(e) {
614
+ if (e.rotateSpeed !== void 0 && this.controls.setRotateSpeed(e.rotateSpeed), e.zoomSpeed !== void 0 && this.controls.setZoomSpeed(e.zoomSpeed), e.enableDamping !== void 0 && this.controls.setEnableDamping(e.enableDamping), e.dampingFactor !== void 0 && this.controls.setDampingFactor(e.dampingFactor), e.enableRotate !== void 0 && (this.controls.enableRotate = e.enableRotate), e.enableZoom !== void 0 && (this.controls.enableZoom = e.enableZoom), e.minFov !== void 0 || e.maxFov !== void 0) {
615
+ const t = e.minFov ?? this.controls.minFov, n = e.maxFov ?? this.controls.maxFov;
616
+ this.controls.setZoomLimits(t, n);
617
+ }
618
+ }
619
+ /**
620
+ * 销毁控制模块
621
+ */
622
+ dispose() {
623
+ this.controls.dispose();
624
+ }
625
+ }
626
+ class Z {
627
+ cache = /* @__PURE__ */ new Map();
628
+ loadingPromises = /* @__PURE__ */ new Map();
629
+ /**
630
+ * 加载纹理(带缓存)
631
+ * @param url 纹理 URL
632
+ * @returns 纹理对象 Promise
633
+ */
634
+ loadTexture(e) {
635
+ if (this.cache.has(e))
636
+ return Promise.resolve(this.cache.get(e));
637
+ if (this.loadingPromises.has(e))
638
+ return this.loadingPromises.get(e);
639
+ const t = new Promise((n, o) => {
640
+ new f().load(
641
+ e,
642
+ (s) => {
643
+ s.colorSpace = P, s.minFilter = m, s.magFilter = m, this.cache.set(e, s), this.loadingPromises.delete(e), n(s);
644
+ },
645
+ void 0,
646
+ (s) => {
647
+ this.loadingPromises.delete(e), o(s);
648
+ }
649
+ );
650
+ });
651
+ return this.loadingPromises.set(e, t), t;
652
+ }
653
+ /**
654
+ * 预加载多个纹理
655
+ * @param urls 纹理 URL 数组
656
+ * @returns Promise,所有纹理加载完成后 resolve
657
+ */
658
+ async preloadTextures(e) {
659
+ const t = e.map((n) => this.loadTexture(n));
660
+ return Promise.all(t);
661
+ }
662
+ /**
663
+ * 检查纹理是否已缓存
664
+ * @param url 纹理 URL
665
+ */
666
+ has(e) {
667
+ return this.cache.has(e);
668
+ }
669
+ /**
670
+ * 获取缓存的纹理
671
+ * @param url 纹理 URL
672
+ * @returns 纹理对象,如果不存在则返回 undefined
673
+ */
674
+ get(e) {
675
+ return this.cache.get(e);
676
+ }
677
+ /**
678
+ * 清除特定纹理的缓存
679
+ * @param url 纹理 URL
680
+ */
681
+ remove(e) {
682
+ const t = this.cache.get(e);
683
+ t && (t.dispose(), this.cache.delete(e));
684
+ }
685
+ /**
686
+ * 清空所有缓存
687
+ */
688
+ clear() {
689
+ this.cache.forEach((e) => e.dispose()), this.cache.clear(), this.loadingPromises.clear();
690
+ }
691
+ /**
692
+ * 获取缓存大小
693
+ */
694
+ size() {
695
+ return this.cache.size;
696
+ }
697
+ /**
698
+ * 销毁缓存
699
+ */
700
+ dispose() {
701
+ this.clear();
702
+ }
703
+ }
704
+ class U {
705
+ textureCache;
706
+ currentUrl = null;
707
+ loadProgress = 0;
708
+ onProgressCallback;
709
+ constructor() {
710
+ this.textureCache = new Z();
711
+ }
712
+ /**
713
+ * 加载全景图纹理
714
+ * @param url 全景图 URL
715
+ * @returns 纹理对象 Promise
716
+ */
717
+ async loadTexture(e) {
718
+ this.currentUrl = e, this.loadProgress = 0, this.onProgressCallback && this.onProgressCallback(0);
719
+ try {
720
+ const t = await this.loadTextureInternal(e);
721
+ return this.loadProgress = 100, this.onProgressCallback && this.onProgressCallback(100), t;
722
+ } catch (t) {
723
+ throw console.error("PanoramaLoader: Failed to load texture:", t), t;
724
+ }
725
+ }
726
+ /**
727
+ * 内部加载方法(支持进度)
728
+ */
729
+ loadTextureInternal(e) {
730
+ return new Promise((t, n) => {
731
+ if (this.textureCache.has(e)) {
732
+ const a = this.textureCache.get(e);
733
+ if (a) {
734
+ t(a);
735
+ return;
736
+ }
737
+ }
738
+ new f().load(
739
+ e,
740
+ (a) => {
741
+ a.colorSpace = P, a.minFilter = m, a.magFilter = m, this.textureCache.cache.set(e, a), t(a);
742
+ },
743
+ (a) => {
744
+ a.total > 0 && (this.loadProgress = a.loaded / a.total * 100, this.onProgressCallback && this.onProgressCallback(this.loadProgress));
745
+ },
746
+ (a) => {
747
+ n(a);
748
+ }
749
+ );
750
+ });
751
+ }
752
+ /**
753
+ * 预加载多个全景图
754
+ * @param urls 全景图 URL 数组
755
+ * @returns Promise,所有纹理加载完成后 resolve
756
+ */
757
+ async preloadPanoramas(e) {
758
+ try {
759
+ await this.textureCache.preloadTextures(e);
760
+ } catch (t) {
761
+ throw console.error("PanoramaLoader: Failed to preload panoramas:", t), t;
762
+ }
763
+ }
764
+ /**
765
+ * 获取当前加载进度
766
+ * @returns 进度百分比(0-100)
767
+ */
768
+ getLoadProgress() {
769
+ return this.loadProgress;
770
+ }
771
+ /**
772
+ * 设置进度回调
773
+ * @param callback 进度回调函数
774
+ */
775
+ setOnProgress(e) {
776
+ this.onProgressCallback = e;
777
+ }
778
+ /**
779
+ * 获取当前加载的 URL
780
+ */
781
+ getCurrentUrl() {
782
+ return this.currentUrl;
783
+ }
784
+ /**
785
+ * 检查纹理是否已缓存
786
+ * @param url 纹理 URL
787
+ */
788
+ isCached(e) {
789
+ return this.textureCache.has(e);
790
+ }
791
+ /**
792
+ * 获取缓存的纹理
793
+ * @param url 纹理 URL
794
+ */
795
+ getCachedTexture(e) {
796
+ return this.textureCache.get(e);
797
+ }
798
+ /**
799
+ * 清除纹理缓存
800
+ */
801
+ clearCache() {
802
+ this.textureCache.clear();
803
+ }
804
+ /**
805
+ * 移除特定纹理缓存
806
+ * @param url 纹理 URL
807
+ */
808
+ removeCachedTexture(e) {
809
+ this.textureCache.remove(e);
810
+ }
811
+ /**
812
+ * 销毁加载器
813
+ */
814
+ dispose() {
815
+ this.textureCache.dispose(), this.onProgressCallback = void 0, this.currentUrl = null;
816
+ }
817
+ }
818
+ class C {
819
+ /**
820
+ * 球面坐标转笛卡尔坐标
821
+ * @param position 球面坐标 { theta, phi, radius }
822
+ * @returns 笛卡尔坐标 { x, y, z }
823
+ */
824
+ static sphericalToCartesian(e) {
825
+ const t = e.radius || 500, { theta: n, phi: o } = e, a = t * Math.cos(o) * Math.cos(n), s = t * Math.sin(o), h = t * Math.cos(o) * Math.sin(n);
826
+ return { x: a, y: s, z: h };
827
+ }
828
+ /**
829
+ * 笛卡尔坐标转球面坐标
830
+ * @param x X 坐标
831
+ * @param y Y 坐标
832
+ * @param z Z 坐标
833
+ * @returns 球面坐标 { theta, phi, radius }
834
+ */
835
+ static cartesianToSpherical(e, t, n) {
836
+ const o = Math.sqrt(e * e + t * t + n * n), a = Math.asin(t / o);
837
+ let s = Math.atan2(n, e);
838
+ return s < 0 && (s += 2 * Math.PI), { theta: s, phi: a, radius: o };
839
+ }
840
+ /**
841
+ * 规范化角度到指定范围
842
+ * @param angle 角度(弧度)
843
+ * @param min 最小值(默认 -π)
844
+ * @param max 最大值(默认 π)
845
+ * @returns 规范化后的角度
846
+ */
847
+ static normalizeAngle(e, t = -Math.PI, n = Math.PI) {
848
+ const o = n - t;
849
+ let a = e;
850
+ for (; a < t; )
851
+ a += o;
852
+ for (; a > n; )
853
+ a -= o;
854
+ return a;
855
+ }
856
+ /**
857
+ * 限制 phi 角度在有效范围内(避免翻转)
858
+ * @param phi 垂直角度(弧度)
859
+ * @param minPhi 最小值(默认 -π/2 + 0.01)
860
+ * @param maxPhi 最大值(默认 π/2 - 0.01)
861
+ * @returns 限制后的角度
862
+ */
863
+ static clampPhi(e, t = -Math.PI / 2 + 0.01, n = Math.PI / 2 - 0.01) {
864
+ return Math.max(t, Math.min(n, e));
865
+ }
866
+ /**
867
+ * 计算两个球面坐标之间的角度距离
868
+ * @param pos1 第一个球面坐标
869
+ * @param pos2 第二个球面坐标
870
+ * @returns 角度距离(弧度)
871
+ */
872
+ static sphericalDistance(e, t) {
873
+ const n = Math.sin(e.phi) * Math.sin(t.phi) + Math.cos(e.phi) * Math.cos(t.phi) * Math.cos(e.theta - t.theta);
874
+ return Math.acos(Math.max(-1, Math.min(1, n)));
875
+ }
876
+ /**
877
+ * 线性插值两个球面坐标
878
+ * @param pos1 起始球面坐标
879
+ * @param pos2 目标球面坐标
880
+ * @param t 插值因子(0-1)
881
+ * @returns 插值后的球面坐标
882
+ */
883
+ static lerpSpherical(e, t, n) {
884
+ let o = t.theta - e.theta;
885
+ o > Math.PI ? o -= 2 * Math.PI : o < -Math.PI && (o += 2 * Math.PI);
886
+ const a = e.theta + o * n, s = e.phi + (t.phi - e.phi) * n, h = e.radius || 500, l = t.radius || 500, c = h + (l - h) * n;
887
+ return { theta: a, phi: s, radius: c };
888
+ }
889
+ }
890
+ var d = /* @__PURE__ */ ((i) => (i.ICON = "icon", i.TEXT = "text", i.LINK = "link", i))(d || {});
891
+ class W {
892
+ annotations = /* @__PURE__ */ new Map();
893
+ container;
894
+ annotationContainer;
895
+ worldToScreen;
896
+ sphereRadius;
897
+ camera;
898
+ renderer;
899
+ // 事件监听器
900
+ onClickAnnotation;
901
+ onHoverAnnotation;
902
+ constructor(e, t, n, o) {
903
+ this.container = e, this.camera = t, this.renderer = n, this.sphereRadius = o, this.worldToScreen = new w(t, n), this.createAnnotationContainer();
904
+ }
905
+ /**
906
+ * 创建标注容器
907
+ */
908
+ createAnnotationContainer() {
909
+ this.annotationContainer = document.createElement("div"), this.annotationContainer.className = "panorama-annotation-container", this.annotationContainer.style.cssText = `
910
+ position: absolute;
911
+ top: 0;
912
+ left: 0;
913
+ width: 100%;
914
+ height: 100%;
915
+ pointer-events: none;
916
+ z-index: 1000;
917
+ overflow: hidden;
918
+ `, this.container.appendChild(this.annotationContainer);
919
+ }
920
+ /**
921
+ * 添加标注
922
+ * @param config 标注配置
923
+ * @returns 标注 ID
924
+ */
925
+ addAnnotation(e) {
926
+ const t = this.generateId(), n = this.sphericalToCartesian(e.position), o = this.createAnnotationElement(e, t), a = {
927
+ id: t,
928
+ config: e,
929
+ element: o,
930
+ worldPosition: n,
931
+ screenPosition: { x: 0, y: 0 },
932
+ visible: !1
933
+ };
934
+ return this.annotationContainer.appendChild(o), this.annotations.set(t, a), this.updateAnnotationPosition(a), t;
935
+ }
936
+ /**
937
+ * 批量添加标注
938
+ * @param configs 标注配置数组
939
+ * @returns 标注 ID 数组
940
+ */
941
+ addAnnotations(e) {
942
+ return e.map((t) => this.addAnnotation(t));
943
+ }
944
+ /**
945
+ * 创建标注 DOM 元素
946
+ */
947
+ createAnnotationElement(e, t) {
948
+ const n = document.createElement("div");
949
+ switch (n.className = `panorama-annotation panorama-annotation-${e.type}`, n.dataset.annotationId = t, n.style.cssText = `
950
+ position: absolute;
951
+ pointer-events: auto;
952
+ cursor: pointer;
953
+ transform: translate(-50%, -50%);
954
+ transition: opacity 0.2s ease;
955
+ `, e.type) {
956
+ case d.ICON:
957
+ this.createIconAnnotation(n, e);
958
+ break;
959
+ case d.TEXT:
960
+ this.createTextAnnotation(n, e);
961
+ break;
962
+ case d.LINK:
963
+ this.createLinkAnnotation(n, e);
964
+ break;
965
+ }
966
+ return this.attachAnnotationEvents(n, t), n;
967
+ }
968
+ /**
969
+ * 创建图标标注
970
+ */
971
+ createIconAnnotation(e, t) {
972
+ const n = t.size || { width: 40, height: 40 };
973
+ e.style.width = `${n.width}px`, e.style.height = `${n.height}px`;
974
+ const o = document.createElement("img");
975
+ o.src = t.iconUrl, o.style.cssText = `
976
+ width: 100%;
977
+ height: 100%;
978
+ object-fit: contain;
979
+ display: block;
980
+ `, o.onerror = () => {
981
+ console.error(`Failed to load annotation icon: ${t.iconUrl}`);
982
+ }, e.appendChild(o), t.tooltip && (e.title = t.tooltip);
983
+ }
984
+ /**
985
+ * 创建文字标注
986
+ */
987
+ createTextAnnotation(e, t) {
988
+ const n = t.style || {};
989
+ e.style.cssText += `
990
+ padding: ${n.padding || "8px 12px"};
991
+ background-color: ${n.backgroundColor || "rgba(0, 0, 0, 0.7)"};
992
+ color: ${n.color || "#ffffff"};
993
+ font-size: ${n.fontSize || 14}px';
994
+ border-radius: 4px;
995
+ white-space: nowrap;
996
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
997
+ `, e.textContent = t.text, t.tooltip && (e.title = t.tooltip);
998
+ }
999
+ /**
1000
+ * 创建超链接标注
1001
+ */
1002
+ createLinkAnnotation(e, t) {
1003
+ const n = t.style || {};
1004
+ if (e.style.cssText += `
1005
+ padding: 8px 12px;
1006
+ background-color: rgba(59, 130, 246, 0.9);
1007
+ color: ${n.color || "#ffffff"};
1008
+ font-size: ${n.fontSize || 14}px';
1009
+ border-radius: 4px;
1010
+ text-decoration: ${n.textDecoration || "none"};
1011
+ display: flex;
1012
+ align-items: center;
1013
+ gap: 8px;
1014
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1015
+ transition: background-color 0.2s ease;
1016
+ `, e.addEventListener("mouseenter", () => {
1017
+ e.style.backgroundColor = "rgba(37, 99, 235, 0.95)";
1018
+ }), e.addEventListener("mouseleave", () => {
1019
+ e.style.backgroundColor = "rgba(59, 130, 246, 0.9)";
1020
+ }), t.iconUrl) {
1021
+ const a = document.createElement("img");
1022
+ a.src = t.iconUrl, a.style.cssText = `
1023
+ width: 16px;
1024
+ height: 16px;
1025
+ display: block;
1026
+ `, e.appendChild(a);
1027
+ }
1028
+ const o = document.createElement("span");
1029
+ o.textContent = t.text || t.url, e.appendChild(o), t.tooltip && (e.title = t.tooltip);
1030
+ }
1031
+ /**
1032
+ * 附加标注事件
1033
+ */
1034
+ attachAnnotationEvents(e, t) {
1035
+ e.addEventListener("click", (n) => {
1036
+ n.stopPropagation();
1037
+ const o = this.annotations.get(t);
1038
+ o && this.handleClickAnnotation(o);
1039
+ }), e.addEventListener("mouseenter", () => {
1040
+ const n = this.annotations.get(t);
1041
+ n && this.handleHoverAnnotation(n);
1042
+ }), e.addEventListener("mouseleave", () => {
1043
+ this.onHoverAnnotation && this.onHoverAnnotation(null);
1044
+ });
1045
+ }
1046
+ /**
1047
+ * 球面坐标转笛卡尔坐标
1048
+ */
1049
+ sphericalToCartesian(e) {
1050
+ const t = e.radius ?? this.sphereRadius;
1051
+ return C.sphericalToCartesian({
1052
+ ...e,
1053
+ radius: t
1054
+ });
1055
+ }
1056
+ /**
1057
+ * 更新标注位置(单个标注)
1058
+ */
1059
+ updateAnnotationPosition(e) {
1060
+ const t = new p(
1061
+ e.worldPosition.x,
1062
+ e.worldPosition.y,
1063
+ e.worldPosition.z
1064
+ ), n = this.worldToScreen.worldToScreen(t);
1065
+ e.screenPosition = { x: n.x, y: n.y };
1066
+ const o = this.isPositionInFront(t), a = this.isPositionInView(n);
1067
+ e.visible = o && a, e.visible ? (e.element.style.display = "block", e.element.style.left = `${n.x}px`, e.element.style.top = `${n.y}px`) : e.element.style.display = "none";
1068
+ }
1069
+ /**
1070
+ * 检查点是否在相机前方
1071
+ */
1072
+ isPositionInFront(e) {
1073
+ const t = new p();
1074
+ return this.camera.getWorldDirection(t), e.clone().normalize().dot(t) > 0;
1075
+ }
1076
+ /**
1077
+ * 检查点是否在视野内
1078
+ */
1079
+ isPositionInView(e) {
1080
+ const t = this.renderer.domElement.clientWidth, n = this.renderer.domElement.clientHeight;
1081
+ return e.x >= 0 && e.x <= t && e.y >= 0 && e.y <= n;
1082
+ }
1083
+ /**
1084
+ * 更新所有标注(每帧调用)
1085
+ */
1086
+ update() {
1087
+ this.annotations.forEach((e) => {
1088
+ this.updateAnnotationPosition(e);
1089
+ });
1090
+ }
1091
+ /**
1092
+ * 处理标注点击
1093
+ */
1094
+ handleClickAnnotation(e) {
1095
+ if (e.config.type === d.LINK) {
1096
+ const t = e.config;
1097
+ window.open(t.url, "_blank");
1098
+ }
1099
+ this.onClickAnnotation && this.onClickAnnotation(e);
1100
+ }
1101
+ /**
1102
+ * 处理标注悬停
1103
+ */
1104
+ handleHoverAnnotation(e) {
1105
+ this.onHoverAnnotation && this.onHoverAnnotation(e);
1106
+ }
1107
+ /**
1108
+ * 设置点击回调
1109
+ */
1110
+ setOnClickAnnotation(e) {
1111
+ this.onClickAnnotation = e;
1112
+ }
1113
+ /**
1114
+ * 设置悬停回调
1115
+ */
1116
+ setOnHoverAnnotation(e) {
1117
+ this.onHoverAnnotation = e;
1118
+ }
1119
+ /**
1120
+ * 移除标注
1121
+ * @param id 标注 ID
1122
+ */
1123
+ removeAnnotation(e) {
1124
+ const t = this.annotations.get(e);
1125
+ t && (t.element.remove(), this.annotations.delete(e));
1126
+ }
1127
+ /**
1128
+ * 清空所有标注
1129
+ */
1130
+ clearAll() {
1131
+ this.annotations.forEach((e) => {
1132
+ e.element.remove();
1133
+ }), this.annotations.clear();
1134
+ }
1135
+ /**
1136
+ * 获取所有标注
1137
+ */
1138
+ getAnnotations() {
1139
+ return Array.from(this.annotations.values());
1140
+ }
1141
+ /**
1142
+ * 获取标注
1143
+ * @param id 标注 ID
1144
+ */
1145
+ getAnnotation(e) {
1146
+ return this.annotations.get(e);
1147
+ }
1148
+ /**
1149
+ * 更新相机引用(当相机发生变化时调用)
1150
+ */
1151
+ updateCamera(e) {
1152
+ this.camera = e, this.worldToScreen.updateCamera(e);
1153
+ }
1154
+ /**
1155
+ * 销毁管理器
1156
+ */
1157
+ dispose() {
1158
+ this.clearAll(), this.annotationContainer.remove(), this.onClickAnnotation = void 0, this.onHoverAnnotation = void 0;
1159
+ }
1160
+ /**
1161
+ * 生成唯一 ID
1162
+ */
1163
+ generateId() {
1164
+ return `annotation-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
1165
+ }
1166
+ }
1167
+ class Y {
1168
+ listeners = /* @__PURE__ */ new Map();
1169
+ /**
1170
+ * 订阅事件
1171
+ * @param event 事件类型(字符串或枚举)
1172
+ * @param callback 回调函数
1173
+ */
1174
+ on(e, t) {
1175
+ const n = String(e);
1176
+ this.listeners.has(n) || this.listeners.set(n, []), this.listeners.get(n).push(t);
1177
+ }
1178
+ /**
1179
+ * 取消订阅事件
1180
+ * @param event 事件类型
1181
+ * @param callback 要移除的回调函数
1182
+ */
1183
+ off(e, t) {
1184
+ const n = String(e), o = this.listeners.get(n);
1185
+ if (o) {
1186
+ const a = o.indexOf(t);
1187
+ a !== -1 && o.splice(a, 1), o.length === 0 && this.listeners.delete(n);
1188
+ }
1189
+ }
1190
+ /**
1191
+ * 触发事件
1192
+ * @param event 事件类型
1193
+ * @param data 事件数据
1194
+ */
1195
+ trigger(e, t) {
1196
+ const n = String(e), o = this.listeners.get(n);
1197
+ if (o && o.length > 0) {
1198
+ const a = [...o];
1199
+ for (const s of a)
1200
+ try {
1201
+ s(t);
1202
+ } catch (h) {
1203
+ console.error(`EventModule: Error in event handler for "${n}":`, h);
1204
+ }
1205
+ }
1206
+ }
1207
+ /**
1208
+ * 移除某个事件的所有监听器
1209
+ * @param event 事件类型
1210
+ */
1211
+ removeAllListeners(e) {
1212
+ const t = String(e);
1213
+ this.listeners.delete(t);
1214
+ }
1215
+ /**
1216
+ * 清空所有事件监听器
1217
+ */
1218
+ clear() {
1219
+ this.listeners.clear();
1220
+ }
1221
+ /**
1222
+ * 获取某个事件的监听器数量
1223
+ * @param event 事件类型
1224
+ */
1225
+ listenerCount(e) {
1226
+ const t = String(e), n = this.listeners.get(t);
1227
+ return n ? n.length : 0;
1228
+ }
1229
+ /**
1230
+ * 销毁事件模块
1231
+ */
1232
+ dispose() {
1233
+ this.clear();
1234
+ }
1235
+ }
1236
+ var r = /* @__PURE__ */ ((i) => (i.PanoramaLoadStart = "panorama-load-start", i.PanoramaLoadProgress = "panorama-load-progress", i.PanoramaLoaded = "panorama-loaded", i.PanoramaLoadError = "panorama-load-error", i.AnnotationClick = "annotation-click", i.AnnotationHover = "annotation-hover", i.AnnotationAdd = "annotation-add", i.AnnotationRemove = "annotation-remove", i.ViewAngleChanged = "view-angle-changed", i))(r || {});
1237
+ class N {
1238
+ options;
1239
+ // 核心模块(使用 definite assignment assertions)
1240
+ sceneModule;
1241
+ cameraModule;
1242
+ renderModule;
1243
+ controlModule;
1244
+ eventModule;
1245
+ // 功能管理器
1246
+ panoramaLoader;
1247
+ annotationManager;
1248
+ worldToScreen;
1249
+ // 内部状态
1250
+ isInitialized = !1;
1251
+ version = T;
1252
+ localPanoramaResource = null;
1253
+ constructor(e) {
1254
+ this.options = e, this.initialize(e);
1255
+ }
1256
+ /**
1257
+ * 初始化引擎
1258
+ */
1259
+ initialize(e) {
1260
+ const t = {
1261
+ fov: 75,
1262
+ enableZoom: !0,
1263
+ enableRotate: !0,
1264
+ minFov: 30,
1265
+ maxFov: 90,
1266
+ sphereRadius: 500,
1267
+ rotateSpeed: 0.35,
1268
+ zoomSpeed: 0.8,
1269
+ enableDamping: !0,
1270
+ dampingFactor: 0.08,
1271
+ ...e
1272
+ }, n = document.getElementById(t.containerId);
1273
+ if (!n)
1274
+ throw new Error(`Container with id "${t.containerId}" not found`);
1275
+ try {
1276
+ this.eventModule = new Y(), this.sceneModule = new V(t.sphereRadius), this.cameraModule = new K(
1277
+ n,
1278
+ t.fov,
1279
+ t.minFov,
1280
+ t.maxFov
1281
+ ), this.renderModule = new O(n, !0), this.controlModule = new X(
1282
+ this.cameraModule,
1283
+ this.renderModule.getDomElement()
1284
+ );
1285
+ const o = this.controlModule.getControls();
1286
+ o.enableZoom = t.enableZoom, o.enableRotate = t.enableRotate, o.setRotateSpeed(t.rotateSpeed), o.setZoomSpeed(t.zoomSpeed), o.setEnableDamping(t.enableDamping), o.setDampingFactor(t.dampingFactor), o.setZoomLimits(t.minFov, t.maxFov), o.setOnViewAngleChange((a, s) => {
1287
+ this.eventModule.trigger(r.ViewAngleChanged, { theta: a, phi: s });
1288
+ }), this.panoramaLoader = new U(), this.worldToScreen = new w(
1289
+ this.cameraModule.getCamera(),
1290
+ this.renderModule.getRenderer(),
1291
+ this.sceneModule.getScene()
1292
+ ), this.annotationManager = new W(
1293
+ n,
1294
+ this.cameraModule.getCamera(),
1295
+ this.renderModule.getRenderer(),
1296
+ t.sphereRadius
1297
+ ), this.annotationManager.setOnClickAnnotation((a) => {
1298
+ this.eventModule.trigger(r.AnnotationClick, {
1299
+ id: a.id,
1300
+ config: a.config,
1301
+ metadata: a.config.metadata
1302
+ });
1303
+ }), this.annotationManager.setOnHoverAnnotation((a) => {
1304
+ this.eventModule.trigger(r.AnnotationHover, {
1305
+ annotation: a ? {
1306
+ id: a.id,
1307
+ config: a.config,
1308
+ metadata: a.config.metadata
1309
+ } : null
1310
+ });
1311
+ }), this.setupRenderLoop(), this.isInitialized = !0, console.log("EngineKernel720: Initialized successfully");
1312
+ } catch (o) {
1313
+ throw console.error("EngineKernel720: Initialization failed", o), o;
1314
+ }
1315
+ }
1316
+ /**
1317
+ * 设置渲染循环
1318
+ */
1319
+ setupRenderLoop() {
1320
+ this.renderModule.setOnBeforeRender(() => {
1321
+ this.controlModule.update(), this.annotationManager.update();
1322
+ }), this.renderModule.startRenderLoop(
1323
+ this.sceneModule.getScene(),
1324
+ this.cameraModule.getCamera()
1325
+ );
1326
+ }
1327
+ // --- 全景图加载 ---
1328
+ /**
1329
+ * 加载全景图
1330
+ * @param imageUrl 全景图 URL(png, jpg)
1331
+ */
1332
+ async loadPanorama(e) {
1333
+ this.checkInitialized(), this.eventModule.trigger(r.PanoramaLoadStart, { url: e });
1334
+ try {
1335
+ this.panoramaLoader.setOnProgress((n) => {
1336
+ this.eventModule.trigger(r.PanoramaLoadProgress, {
1337
+ url: e,
1338
+ progress: n
1339
+ });
1340
+ });
1341
+ const t = await this.panoramaLoader.loadTexture(e);
1342
+ this.sceneModule.updatePanoramaTexture(t), this.eventModule.trigger(r.PanoramaLoaded, {
1343
+ url: e,
1344
+ progress: 100
1345
+ }), console.log("EngineKernel720: Panorama loaded successfully");
1346
+ } catch (t) {
1347
+ throw console.error("EngineKernel720: Failed to load panorama", t), this.eventModule.trigger(r.PanoramaLoadError, {
1348
+ url: e,
1349
+ error: t
1350
+ }), t;
1351
+ }
1352
+ }
1353
+ async loadPanoramaFile(e) {
1354
+ this.checkInitialized(), this.revokeLocalPanoramaResource();
1355
+ const t = z(e);
1356
+ this.localPanoramaResource = t;
1357
+ try {
1358
+ await this.loadPanorama(t.url);
1359
+ } catch (n) {
1360
+ throw this.revokeLocalPanoramaResource(), n;
1361
+ }
1362
+ }
1363
+ async loadModelFile(e) {
1364
+ if (e.length === 0)
1365
+ throw new Error("EngineKernel720: no file selected");
1366
+ await this.loadPanoramaFile(e[0]);
1367
+ }
1368
+ /**
1369
+ * 通过 viewToken 解析全景资源地址,再复用现有全景加载逻辑。
1370
+ */
1371
+ async loadPanoramaByViewToken(e) {
1372
+ const t = await _(
1373
+ this.options,
1374
+ e,
1375
+ "720"
1376
+ );
1377
+ if (t.assetCategory === "composite_model" && t.urls.length > 1)
1378
+ throw new Error("EngineKernel720: composite_model viewToken is not supported");
1379
+ await this.loadPanorama(t.url);
1380
+ }
1381
+ /**
1382
+ * 预加载多个全景图
1383
+ * @param urls 全景图 URL 数组
1384
+ */
1385
+ async preloadPanoramas(e) {
1386
+ this.checkInitialized();
1387
+ try {
1388
+ await this.panoramaLoader.preloadPanoramas(e), console.log(`EngineKernel720: Preloaded ${e.length} panoramas`);
1389
+ } catch (t) {
1390
+ throw console.error("EngineKernel720: Failed to preload panoramas", t), t;
1391
+ }
1392
+ }
1393
+ // --- 标注管理 ---
1394
+ /**
1395
+ * 添加标注
1396
+ * @param config 标注配置
1397
+ * @returns 标注 ID
1398
+ */
1399
+ addAnnotation(e) {
1400
+ this.checkInitialized();
1401
+ const t = this.annotationManager.addAnnotation(e);
1402
+ return this.eventModule.trigger(r.AnnotationAdd, { id: t, config: e }), t;
1403
+ }
1404
+ /**
1405
+ * 批量添加标注
1406
+ * @param configs 标注配置数组
1407
+ * @returns 标注 ID 数组
1408
+ */
1409
+ addAnnotations(e) {
1410
+ return this.checkInitialized(), e.map((t) => this.addAnnotation(t));
1411
+ }
1412
+ /**
1413
+ * 移除标注
1414
+ * @param id 标注 ID
1415
+ */
1416
+ removeAnnotation(e) {
1417
+ this.checkInitialized(), this.annotationManager.removeAnnotation(e), this.eventModule.trigger(r.AnnotationRemove, { id: e });
1418
+ }
1419
+ /**
1420
+ * 清空所有标注
1421
+ */
1422
+ clearAnnotations() {
1423
+ this.checkInitialized(), this.annotationManager.clearAll();
1424
+ }
1425
+ /**
1426
+ * 获取所有标注
1427
+ */
1428
+ getAnnotations() {
1429
+ return this.checkInitialized(), this.annotationManager.getAnnotations();
1430
+ }
1431
+ /**
1432
+ * 更新交互参数(旋转/缩放/阻尼等)
1433
+ */
1434
+ updateInteractionOptions(e) {
1435
+ this.checkInitialized(), this.controlModule.updateInteractionOptions(e);
1436
+ }
1437
+ /**
1438
+ * 根据屏幕坐标拾取全景球面坐标
1439
+ */
1440
+ pickPanoramaPoint(e, t) {
1441
+ this.checkInitialized();
1442
+ const o = this.renderModule.getRenderer().domElement, a = o.clientWidth, s = o.clientHeight;
1443
+ if (a === 0 || s === 0)
1444
+ return null;
1445
+ const h = new D(
1446
+ e / a * 2 - 1,
1447
+ -(t / s * 2 - 1)
1448
+ ), l = this.cameraModule.getCamera(), c = new p(h.x, h.y, 0.5);
1449
+ c.unproject(l), c.sub(l.position).normalize();
1450
+ const g = this.sceneModule.getSphereRadius(), u = l.position.clone().add(c.multiplyScalar(g)), M = C.cartesianToSpherical(u.x, u.y, u.z);
1451
+ return {
1452
+ theta: M.theta,
1453
+ phi: M.phi,
1454
+ radius: g
1455
+ };
1456
+ }
1457
+ // --- 视角控制 ---
1458
+ /**
1459
+ * 设置视角(通过经纬度)
1460
+ * @param theta 水平角度(弧度)
1461
+ * @param phi 垂直角度(弧度)
1462
+ * @param animate 是否动画过渡(暂未实现)
1463
+ */
1464
+ lookAt(e, t, n) {
1465
+ this.checkInitialized(), n && console.warn("EngineKernel720: Animated lookAt not implemented yet"), this.controlModule.lookAt(e, t);
1466
+ }
1467
+ /**
1468
+ * 获取当前视角
1469
+ */
1470
+ getViewAngle() {
1471
+ return this.checkInitialized(), this.controlModule.getViewAngle();
1472
+ }
1473
+ /**
1474
+ * 设置 FOV
1475
+ * @param fov 视野角度(30-90)
1476
+ */
1477
+ setFov(e) {
1478
+ this.checkInitialized(), this.cameraModule.setFov(e);
1479
+ }
1480
+ /**
1481
+ * 获取当前 FOV
1482
+ */
1483
+ getFov() {
1484
+ return this.checkInitialized(), this.cameraModule.getFov();
1485
+ }
1486
+ // --- 事件监听 ---
1487
+ /**
1488
+ * 监听事件
1489
+ * @param event 事件类型
1490
+ * @param callback 回调函数
1491
+ */
1492
+ on(e, t) {
1493
+ this.checkInitialized(), this.eventModule.on(e, t);
1494
+ }
1495
+ /**
1496
+ * 取消监听
1497
+ * @param event 事件类型
1498
+ * @param callback 回调函数
1499
+ */
1500
+ off(e, t) {
1501
+ this.checkInitialized(), this.eventModule.off(e, t);
1502
+ }
1503
+ // --- 生命周期 ---
1504
+ /**
1505
+ * 调整尺寸
1506
+ * @param width 容器宽度(可选,默认使用容器尺寸)
1507
+ * @param height 容器高度(可选,默认使用容器尺寸)
1508
+ */
1509
+ resize(e, t) {
1510
+ this.checkInitialized();
1511
+ const n = e ?? this.renderModule.getRenderer().domElement.clientWidth, o = t ?? this.renderModule.getRenderer().domElement.clientHeight;
1512
+ this.renderModule.resize(n, o), this.cameraModule.updateAspectRatio(n, o), console.log("EngineKernel720: Resized to", n, "x", o);
1513
+ }
1514
+ /**
1515
+ * 暂停渲染
1516
+ */
1517
+ pauseRendering() {
1518
+ this.checkInitialized(), this.renderModule.pauseRendering();
1519
+ }
1520
+ /**
1521
+ * 恢复渲染
1522
+ */
1523
+ resumeRendering() {
1524
+ this.checkInitialized(), this.renderModule.resumeRendering(
1525
+ this.sceneModule.getScene(),
1526
+ this.cameraModule.getCamera()
1527
+ );
1528
+ }
1529
+ /**
1530
+ * 检查渲染是否暂停
1531
+ */
1532
+ isRenderingPausedState() {
1533
+ return this.isInitialized ? this.renderModule.isRenderingPausedState() : !0;
1534
+ }
1535
+ /**
1536
+ * 获取版本
1537
+ */
1538
+ getVersion() {
1539
+ return this.version;
1540
+ }
1541
+ /**
1542
+ * 销毁引擎
1543
+ */
1544
+ dispose() {
1545
+ if (this.isInitialized)
1546
+ try {
1547
+ this.renderModule.pauseRendering(), this.annotationManager.dispose(), this.panoramaLoader.dispose(), this.controlModule.dispose(), this.cameraModule.dispose(), this.renderModule.dispose(), this.sceneModule.dispose(), this.eventModule.dispose(), this.isInitialized = !1, this.revokeLocalPanoramaResource(), console.log("EngineKernel720: Disposed successfully");
1548
+ } catch (e) {
1549
+ console.error("EngineKernel720: Error during dispose", e);
1550
+ }
1551
+ }
1552
+ /**
1553
+ * 检查是否已初始化
1554
+ */
1555
+ checkInitialized() {
1556
+ if (!this.isInitialized)
1557
+ throw new Error("EngineKernel720: Not initialized");
1558
+ }
1559
+ revokeLocalPanoramaResource() {
1560
+ this.localPanoramaResource?.revoke(), this.localPanoramaResource = null;
1561
+ }
1562
+ }
1563
+ export {
1564
+ N as EngineKernel720
1565
+ };