@mapless/core 1.0.24 → 1.0.25

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 (31) hide show
  1. package/dist/index.js +541 -169
  2. package/dist/types/Mapless/Base.d.ts +2 -0
  3. package/dist/types/Mapless/Base.d.ts.map +1 -1
  4. package/dist/types/Mapless/draw/index.d.ts +1 -0
  5. package/dist/types/Mapless/draw/index.d.ts.map +1 -1
  6. package/dist/types/Mapless/extensions/MapboxResizeFixer.d.ts +8 -0
  7. package/dist/types/Mapless/extensions/MapboxResizeFixer.d.ts.map +1 -0
  8. package/dist/types/Mapless/icons/Singleton.d.ts.map +1 -1
  9. package/dist/types/Mapless/lang/MapboxLanguage.d.ts +1 -0
  10. package/dist/types/Mapless/lang/MapboxLanguage.d.ts.map +1 -1
  11. package/dist/types/Mapless/layer/FixedRectangleLayer.d.ts +2 -0
  12. package/dist/types/Mapless/layer/FixedRectangleLayer.d.ts.map +1 -1
  13. package/dist/types/Mapless/layer/RectangleLayer.d.ts +1 -0
  14. package/dist/types/Mapless/layer/RectangleLayer.d.ts.map +1 -1
  15. package/dist/types/Mapless/mana-3d/mapModel.d.ts.map +1 -1
  16. package/dist/types/Mapless/mana-three/airspace3.d.ts +8 -0
  17. package/dist/types/Mapless/mana-three/airspace3.d.ts.map +1 -1
  18. package/dist/types/Mapless/mana-three/basicObject.d.ts.map +1 -1
  19. package/dist/types/Mapless/mana-three/curve3d.d.ts.map +1 -1
  20. package/dist/types/Mapless/mana-three/index.d.ts +1 -1
  21. package/dist/types/Mapless/mana-three/index.d.ts.map +1 -1
  22. package/dist/types/Mapless/mana-three/instancedModel.d.ts +75 -9
  23. package/dist/types/Mapless/mana-three/instancedModel.d.ts.map +1 -1
  24. package/dist/types/Mapless/mana-three/line2Manager.d.ts +1 -0
  25. package/dist/types/Mapless/mana-three/line2Manager.d.ts.map +1 -1
  26. package/dist/types/Mapless/mana-three/model.d.ts +1 -0
  27. package/dist/types/Mapless/mana-three/model.d.ts.map +1 -1
  28. package/dist/types/Mapless/mana-three/three.d.ts +2 -0
  29. package/dist/types/Mapless/mana-three/three.d.ts.map +1 -1
  30. package/dist/types/Mapless/themeSources.d.ts.map +1 -1
  31. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import mapbox_gl, { LngLat, MapMouseEvent, Marker, MercatorCoordinate, Point, Po
3
3
  import gcoord from "gcoord";
4
4
  import mapbox_gl_draw from "@mapbox/mapbox-gl-draw";
5
5
  import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";
6
- import { GLTFLoader, Line2, LineGeometry, LineMaterial } from "three-stdlib";
6
+ import { DRACOLoader, GLTFLoader, Line2, LineGeometry, LineMaterial } from "three-stdlib";
7
7
  import * as __rspack_external_three from "three";
8
8
  function buildTransformMatrix(transform) {
9
9
  if (transform.matrix) return transform.matrix.clone();
@@ -743,7 +743,7 @@ class Base {
743
743
  return this;
744
744
  };
745
745
  onManaRemove = (handler)=>{
746
- this.emitter.off('managerRemove', handler);
746
+ this.emitter.on('managerRemove', handler);
747
747
  return this;
748
748
  };
749
749
  use(Manager, name, options) {
@@ -824,6 +824,25 @@ class MapboxRequestHandler {
824
824
  });
825
825
  }
826
826
  }
827
+ class MapboxResizeFixer {
828
+ _map;
829
+ _interval = null;
830
+ constructor(map){
831
+ this._map = map;
832
+ this._map?.on('load', this.mapLoad);
833
+ this.startFix();
834
+ }
835
+ mapLoad() {
836
+ this._interval && clearInterval(this._interval);
837
+ }
838
+ startFix() {
839
+ this._interval = setInterval(()=>{
840
+ this._map?.resize();
841
+ const { clientWidth, clientHeight } = this._map?._canvas || {};
842
+ if (clientWidth && clientHeight) this._map?._resizeCanvas(clientWidth, clientHeight);
843
+ }, 20);
844
+ }
845
+ }
827
846
  const COLOR_PRESETS = (()=>{
828
847
  const keys = Object.keys(maplessPreset.STATUS_COLORS);
829
848
  const ret = {};
@@ -11338,6 +11357,10 @@ class Mapless extends Base {
11338
11357
  _mapMode = '2d';
11339
11358
  _mapStyle = null;
11340
11359
  _debug = false;
11360
+ enableThree = true;
11361
+ styleImageMissingHandler = (e)=>{
11362
+ if (this.map) icons_Singleton.handleMissingImage(this.map, e.id);
11363
+ };
11341
11364
  constructor(container, options){
11342
11365
  super();
11343
11366
  this.onInit = options.onMapInit;
@@ -11353,6 +11376,7 @@ class Mapless extends Base {
11353
11376
  initializeMap(container, options) {
11354
11377
  mapbox_gl.accessToken = options.accessToken || Mapless.accessToken;
11355
11378
  this._debug = options.debug || false;
11379
+ this.enableThree = false !== options.enableThree;
11356
11380
  if (!this._debug) {
11357
11381
  mapbox_gl.config.REQUIRE_ACCESS_TOKEN = false;
11358
11382
  mapbox_gl.config.MAX_PARALLEL_IMAGE_REQUESTS = 256;
@@ -11377,13 +11401,12 @@ class Mapless extends Base {
11377
11401
  preserveDrawingBuffer: true,
11378
11402
  transformRequest: maplessPreset.transformRequest
11379
11403
  });
11404
+ new MapboxResizeFixer(this.map);
11380
11405
  const reqHandler = new MapboxRequestHandler();
11381
11406
  reqHandler.setupMapboxInterceptor(this.map);
11382
11407
  this.map.on('zoom', this.mapZoomHandler);
11383
11408
  this.map.on('load', this.initCtrls);
11384
- this.map.on('styleimagemissing', (e)=>{
11385
- if (this.map) icons_Singleton.handleMissingImage(this.map, e.id);
11386
- });
11409
+ this.map.on('styleimagemissing', this.styleImageMissingHandler);
11387
11410
  Promise.resolve().then(()=>{
11388
11411
  this.map && this.onInit?.(this.map);
11389
11412
  });
@@ -11406,7 +11429,7 @@ class Mapless extends Base {
11406
11429
  if (logo) logo.style.display = 'none';
11407
11430
  const attributions = this.map.getContainer().querySelector('.mapboxgl-ctrl-attrib');
11408
11431
  if (attributions) attributions.style.display = 'none';
11409
- this.initMapThree();
11432
+ if (this.enableThree) this.initMapThree();
11410
11433
  }
11411
11434
  };
11412
11435
  mapZoomHandler = ()=>{
@@ -11579,18 +11602,19 @@ class Mapless extends Base {
11579
11602
  if (!this.map) return;
11580
11603
  this.map.flyTo({
11581
11604
  center: this.coordTrans('dataToTile', options.center),
11582
- zoom: options.zoom || this.map.getZoom(),
11583
- bearing: options.bearing || 0,
11584
- pitch: options.pitch || 0,
11585
- speed: options.speed || 1.2,
11586
- curve: options.curve || 1.42,
11587
- duration: options.duration || 2000,
11588
- essential: options.essential || true
11605
+ zoom: options.zoom ?? this.map.getZoom(),
11606
+ bearing: options.bearing ?? 0,
11607
+ pitch: options.pitch ?? 0,
11608
+ speed: options.speed ?? 1.2,
11609
+ curve: options.curve ?? 1.42,
11610
+ duration: options.duration ?? 2000,
11611
+ essential: options.essential ?? true
11589
11612
  });
11590
11613
  }
11591
11614
  toggleLayer(layerId, visible) {
11592
11615
  if (!this.map?.getLayer(layerId)) return;
11593
- const isVisible = void 0 !== visible ? visible : this.map?.getLayoutProperty(layerId, 'visibility') !== 'none';
11616
+ const currentVisible = this.map?.getLayoutProperty(layerId, 'visibility') !== 'none';
11617
+ const isVisible = visible ?? !currentVisible;
11594
11618
  this.map?.setLayoutProperty(layerId, 'visibility', isVisible ? 'visible' : 'none');
11595
11619
  }
11596
11620
  interactionLayers(interaction) {
@@ -11639,7 +11663,12 @@ class Mapless extends Base {
11639
11663
  }
11640
11664
  destroy() {
11641
11665
  if (!this.map) return;
11666
+ this.map?.off('zoom', this.mapZoomHandler);
11667
+ this.map?.off('load', this.initCtrls);
11668
+ this.map?.off('styleimagemissing', this.styleImageMissingHandler);
11642
11669
  this.clear();
11670
+ this.mapThree?.dispose();
11671
+ this.mapThree = null;
11643
11672
  this.map.remove();
11644
11673
  this.map = null;
11645
11674
  }
@@ -12435,7 +12464,7 @@ class PositionTool extends ShapeTool {
12435
12464
  }
12436
12465
  clearLayers = ()=>{
12437
12466
  if (this.draw?.map?.getLayer(this.pointMarkersLayer)) this.draw?.map?.removeLayer(this.pointMarkersLayer);
12438
- if (this.draw?.map?.getLayer(this.pointMarkersSource)) this.draw?.map?.removeLayer(this.pointMarkersSource);
12467
+ if (this.draw?.map?.getSource(this.pointMarkersSource)) this.draw?.map?.removeSource(this.pointMarkersSource);
12439
12468
  };
12440
12469
  }
12441
12470
  const blue = '#3bb2d0';
@@ -12707,6 +12736,10 @@ class Draw {
12707
12736
  areaTool;
12708
12737
  angleTool;
12709
12738
  positionTool;
12739
+ modeChangeHandler = (e)=>{
12740
+ const em = e;
12741
+ if (em?.mode === 'simple_select') this.onDrawOver?.();
12742
+ };
12710
12743
  constructor(mapless){
12711
12744
  this.mapless = mapless;
12712
12745
  this.map = this.mapless.map;
@@ -12720,10 +12753,7 @@ class Draw {
12720
12753
  this.map.addControl(this.drawControl);
12721
12754
  this.map.on('draw.create', this.createMeasure);
12722
12755
  this.map.on('draw.update', this.updateMeasure);
12723
- this.map.on('draw.modechange', (e)=>{
12724
- const em = e;
12725
- if (em?.mode === 'simple_select') this.onDrawOver?.();
12726
- });
12756
+ this.map.on('draw.modechange', this.modeChangeHandler);
12727
12757
  this.map.on('draw.delete', this.deleteMeasure);
12728
12758
  this.pointTool = new PointTool(this);
12729
12759
  this.lineTool = new LineTool(this);
@@ -12835,6 +12865,10 @@ class Draw {
12835
12865
  }
12836
12866
  destroy() {
12837
12867
  try {
12868
+ this.map?.off('draw.create', this.createMeasure);
12869
+ this.map?.off('draw.update', this.updateMeasure);
12870
+ this.map?.off('draw.modechange', this.modeChangeHandler);
12871
+ this.map?.off('draw.delete', this.deleteMeasure);
12838
12872
  this.drawControl && this.map?.removeControl(this.drawControl);
12839
12873
  this.drawControl = void 0;
12840
12874
  } catch (_error) {}
@@ -12879,6 +12913,7 @@ class MapboxLanguage {
12879
12913
  isTokenField = /^\{name/;
12880
12914
  map;
12881
12915
  container;
12916
+ initialStyleUpdateHandler = ()=>this._initialStyleUpdate();
12882
12917
  _current = '';
12883
12918
  get current() {
12884
12919
  return this._current;
@@ -12965,12 +13000,12 @@ class MapboxLanguage {
12965
13000
  }
12966
13001
  onAdd = (map)=>{
12967
13002
  this.map = map;
12968
- this.map.on('style.load', this._initialStyleUpdate.bind(this));
13003
+ this.map.on('style.load', this.initialStyleUpdateHandler);
12969
13004
  this.container = document.createElement('div');
12970
13005
  return this.container;
12971
13006
  };
12972
13007
  onRemove = (_map)=>{
12973
- this.map?.off('style.load', this._initialStyleUpdate);
13008
+ this.map?.off('style.load', this.initialStyleUpdateHandler);
12974
13009
  this.map = void 0;
12975
13010
  };
12976
13011
  getDefaultPosition;
@@ -13118,6 +13153,7 @@ class IdHub {
13118
13153
  const core_IdHub = IdHub;
13119
13154
  class FixedRectangleLayerManager extends EmitManager {
13120
13155
  rectangles = [];
13156
+ redrawFrame = null;
13121
13157
  constructor(mapless, options){
13122
13158
  super(mapless, options, 'fixed-rectangle');
13123
13159
  this.onInitialized();
@@ -13165,6 +13201,13 @@ class FixedRectangleLayerManager extends EmitManager {
13165
13201
  this.map.on('rotate', this.mapMoveHandler);
13166
13202
  this.map.on('zoom', this.mapZoomHandler);
13167
13203
  }
13204
+ scheduleDrawRectangles() {
13205
+ if (null !== this.redrawFrame) return;
13206
+ this.redrawFrame = requestAnimationFrame(()=>{
13207
+ this.redrawFrame = null;
13208
+ this.drawRectangles();
13209
+ });
13210
+ }
13168
13211
  setData(data) {
13169
13212
  this.rectangles = data;
13170
13213
  this.drawRectangles();
@@ -13272,10 +13315,10 @@ class FixedRectangleLayerManager extends EmitManager {
13272
13315
  this.mapless?.setData(this.idHub?.rectangleSourceId, data);
13273
13316
  }
13274
13317
  mapZoomHandler = ()=>{
13275
- if (this.rectangles.length > 0) this.drawRectangles();
13318
+ if (this.rectangles.length > 0) this.scheduleDrawRectangles();
13276
13319
  };
13277
13320
  mapMoveHandler = ()=>{
13278
- if (this.rectangles.length > 0) this.drawRectangles();
13321
+ if (this.rectangles.length > 0) this.scheduleDrawRectangles();
13279
13322
  };
13280
13323
  destroy = ()=>{
13281
13324
  if (this.map) {
@@ -13284,6 +13327,10 @@ class FixedRectangleLayerManager extends EmitManager {
13284
13327
  this.map.off('rotate', this.mapMoveHandler);
13285
13328
  this.map.off('zoom', this.mapZoomHandler);
13286
13329
  }
13330
+ if (null !== this.redrawFrame) {
13331
+ cancelAnimationFrame(this.redrawFrame);
13332
+ this.redrawFrame = null;
13333
+ }
13287
13334
  super.destroy();
13288
13335
  this.rectangles = [];
13289
13336
  };
@@ -13323,6 +13370,7 @@ class RectangleLayerManager extends EmitManager {
13323
13370
  program = null;
13324
13371
  positionBuffer = null;
13325
13372
  colorBuffer = null;
13373
+ clickHandler = null;
13326
13374
  vertexShaderSource = `
13327
13375
  attribute vec2 a_position;
13328
13376
  uniform vec2 u_resolution;
@@ -13544,6 +13592,10 @@ class RectangleLayerManager extends EmitManager {
13544
13592
  this.map?.triggerRepaint();
13545
13593
  }
13546
13594
  destroy = ()=>{
13595
+ if (this.map && this.clickHandler) {
13596
+ this.map.off('click', this.clickHandler);
13597
+ this.clickHandler = null;
13598
+ }
13547
13599
  if (this.map && this.customLayer) this.map.removeLayer(this.customLayer.id);
13548
13600
  this.customLayer = null;
13549
13601
  this.rectangles = [];
@@ -13563,8 +13615,8 @@ class RectangleLayerManager extends EmitManager {
13563
13615
  });
13564
13616
  }
13565
13617
  setupClickHandler() {
13566
- if (!this.map) return;
13567
- this.map.on('click', (e)=>{
13618
+ if (!this.map || this.clickHandler) return;
13619
+ this.clickHandler = (e)=>{
13568
13620
  if (!this.map || !e.point) return;
13569
13621
  for (const rect of this.rectangles){
13570
13622
  const centerPoint = this.map.project(new mapbox_gl.LngLat(rect.lng, rect.lat));
@@ -13585,7 +13637,8 @@ class RectangleLayerManager extends EmitManager {
13585
13637
  break;
13586
13638
  }
13587
13639
  }
13588
- });
13640
+ };
13641
+ this.map.on('click', this.clickHandler);
13589
13642
  }
13590
13643
  }
13591
13644
  const RectangleLayer = RectangleLayerManager;
@@ -18204,6 +18257,7 @@ class MapModelManager extends EmitManager {
18204
18257
  this.themeColorModels.clear();
18205
18258
  this.modelOptions.clear();
18206
18259
  this.clearModels();
18260
+ super.destroy();
18207
18261
  }
18208
18262
  }
18209
18263
  const mapModel = MapModelManager;
@@ -18628,6 +18682,19 @@ class Airspace3Manager extends manager_Manager {
18628
18682
  if (zone.edgeMesh) mapThree.setRenderableObjectVisible(`${zone.id}-edge`, visible);
18629
18683
  });
18630
18684
  }
18685
+ setFill2DVisible(visible) {
18686
+ if (!this.map) return;
18687
+ const visibility = visible ? 'visible' : 'none';
18688
+ if (this.map.getLayer(this.fill2DLayerId)) this.map.setLayoutProperty(this.fill2DLayerId, 'visibility', visibility);
18689
+ if (this.map.getLayer(this.lineLayerId)) this.map.setLayoutProperty(this.lineLayerId, 'visibility', visibility);
18690
+ }
18691
+ setAllEdgesVisible(visible) {
18692
+ const mapThree = this.getMapThree();
18693
+ if (!mapThree) return;
18694
+ this.zones.forEach((zone)=>{
18695
+ if (zone.edgeMesh) mapThree.setRenderableObjectVisible(`${zone.id}-edge`, visible);
18696
+ });
18697
+ }
18631
18698
  }
18632
18699
  const airspace3 = Airspace3Manager;
18633
18700
  const attachAirspace3 = (mapless, name, options)=>mapless?.use(Airspace3Manager, name, options);
@@ -18897,6 +18964,7 @@ class BasicThreeObjectManager extends manager_Manager {
18897
18964
  }
18898
18965
  destroy() {
18899
18966
  this.clearObjects();
18967
+ super.destroy();
18900
18968
  }
18901
18969
  }
18902
18970
  const basicObject = BasicThreeObjectManager;
@@ -19099,26 +19167,30 @@ class Curve3DManager extends manager_Manager {
19099
19167
  }
19100
19168
  destroy() {
19101
19169
  this.clearCurves();
19170
+ super.destroy();
19102
19171
  }
19103
19172
  }
19104
19173
  const curve3d = Curve3DManager;
19105
19174
  const attachCurve3D = (mapless, name, options)=>mapless?.use(Curve3DManager, name, options);
19106
19175
  const getCurve3D = (mapless, name)=>mapless?.get(Curve3DManager, name);
19107
19176
  const detachCurve3D = (mapless, name)=>mapless?.unuse(Curve3DManager, name);
19177
+ const DEFAULT_MODEL_TYPE = '__default__';
19108
19178
  class InstancedModelManager extends manager_Manager {
19109
19179
  scene = null;
19110
19180
  camera = null;
19111
19181
  renderer = null;
19112
19182
  customLayerId;
19113
19183
  isInitialized = false;
19114
- instancedMeshes = new Map();
19184
+ instancedModels = new Map();
19115
19185
  instanceDataMap = new Map();
19116
19186
  rotationAngles = new Map();
19117
19187
  autoRotateEnabled = new Map();
19118
19188
  rotationSpeeds = new Map();
19119
19189
  originalConfigs = new Map();
19120
19190
  clickCallback = null;
19191
+ canvasClickHandler = null;
19121
19192
  lastProjectionMatrix = null;
19193
+ zoomCleanup = null;
19122
19194
  constructor(mapless){
19123
19195
  super(mapless);
19124
19196
  this.map = mapless.map;
@@ -19138,6 +19210,14 @@ class InstancedModelManager extends manager_Manager {
19138
19210
  });
19139
19211
  this.renderer.autoClear = false;
19140
19212
  this.renderer.setPixelRatio(window.devicePixelRatio);
19213
+ const ambientLight = new __rspack_external_three.AmbientLight(0xffffff, 0.8);
19214
+ this.scene.add(ambientLight);
19215
+ const directionalLight1 = new __rspack_external_three.DirectionalLight(0xffffff, 1.5);
19216
+ directionalLight1.position.set(0, -70, 100);
19217
+ this.scene.add(directionalLight1);
19218
+ const directionalLight2 = new __rspack_external_three.DirectionalLight(0xffffff, 1.5);
19219
+ directionalLight2.position.set(0, 70, 100);
19220
+ this.scene.add(directionalLight2);
19141
19221
  this.setupCustomLayer();
19142
19222
  this.isInitialized = true;
19143
19223
  console.log('InstancedModelManager: Initialized');
@@ -19154,25 +19234,40 @@ class InstancedModelManager extends manager_Manager {
19154
19234
  },
19155
19235
  render: (_gl, matrix)=>{
19156
19236
  if (!this.camera || !this.renderer || !this.scene) return;
19157
- if (0 === this.instancedMeshes.size) return;
19158
- this.updateAutoRotate();
19237
+ if (0 === this.instancedModels.size) return;
19159
19238
  const projMatrix = new __rspack_external_three.Matrix4().fromArray(matrix);
19160
- this.camera.projectionMatrix = projMatrix;
19161
- this.lastProjectionMatrix = projMatrix.clone();
19162
- this.instancedMeshes.forEach((mesh)=>{
19163
- mesh.visible = true;
19239
+ this.updateAutoRotate();
19240
+ const camera = this.camera;
19241
+ const renderer = this.renderer;
19242
+ const scene = this.scene;
19243
+ const originalVisibilities = new Map();
19244
+ this.instancedModels.forEach((model)=>{
19245
+ originalVisibilities.set(model.group, model.group.visible);
19246
+ model.group.visible = false;
19247
+ });
19248
+ renderer.resetState();
19249
+ this.instancedModels.forEach((model)=>{
19250
+ if (!model.visible) return;
19251
+ const transformMatrix = this.buildMapboxTransform(model);
19252
+ camera.projectionMatrix = projMatrix.clone().multiply(transformMatrix);
19253
+ this.lastProjectionMatrix = camera.projectionMatrix.clone();
19254
+ model.group.visible = true;
19255
+ renderer.render(scene, camera);
19256
+ model.group.visible = false;
19257
+ });
19258
+ this.instancedModels.forEach((model)=>{
19259
+ const visible = originalVisibilities.get(model.group);
19260
+ if (void 0 !== visible) model.group.visible = visible;
19164
19261
  });
19165
- this.renderer.resetState();
19166
- this.renderer.render(this.scene, this.camera);
19167
19262
  if (this.map) this.map.triggerRepaint();
19168
19263
  }
19169
19264
  };
19170
19265
  this.map.addLayer(customLayer);
19171
19266
  }
19172
19267
  setupClickHandler() {
19173
- if (!this.map) return;
19268
+ if (!this.map || this.canvasClickHandler) return;
19174
19269
  const canvas = this.map.getCanvas();
19175
- const handleClick = (e)=>{
19270
+ this.canvasClickHandler = (e)=>{
19176
19271
  if (!this.camera || !this.scene || !this.lastProjectionMatrix) return;
19177
19272
  const rect = canvas.getBoundingClientRect();
19178
19273
  const ndcX = (e.clientX - rect.left) / rect.width * 2 - 1;
@@ -19182,21 +19277,24 @@ class InstancedModelManager extends manager_Manager {
19182
19277
  nearPoint.divideScalar(nearPoint.w);
19183
19278
  const farPoint = new __rspack_external_three.Vector4(ndcX, ndcY, 1, 1).applyMatrix4(inverseProj);
19184
19279
  farPoint.divideScalar(farPoint.w);
19185
- const origin = new __rspack_external_three.Vector3(0, 0, 0);
19280
+ const origin = new __rspack_external_three.Vector3(nearPoint.x, nearPoint.y, nearPoint.z);
19186
19281
  const direction = new __rspack_external_three.Vector3(farPoint.x - nearPoint.x, farPoint.y - nearPoint.y, farPoint.z - nearPoint.z).normalize();
19187
19282
  const raycaster = new __rspack_external_three.Raycaster(origin, direction);
19188
19283
  let closestHit = null;
19189
19284
  let minDistance = 1 / 0;
19190
- for (const [groupId, instancedMesh] of this.instancedMeshes){
19285
+ for (const [groupId, model] of this.instancedModels)for (const modelMesh of model.meshes){
19286
+ const instancedMesh = modelMesh.mesh;
19191
19287
  const intersects = raycaster.intersectObject(instancedMesh, false);
19192
19288
  if (intersects.length > 0 && intersects[0].distance < minDistance) {
19193
19289
  const intersection = intersects[0];
19194
19290
  const instanceId = intersection.instanceId;
19195
19291
  if (void 0 !== instanceId) {
19292
+ const instanceIndex = modelMesh.instanceIndexes[instanceId];
19293
+ if (void 0 === instanceIndex) continue;
19196
19294
  minDistance = intersection.distance;
19197
19295
  closestHit = {
19198
19296
  groupId,
19199
- instanceIndex: instanceId,
19297
+ instanceIndex,
19200
19298
  point: intersection.point,
19201
19299
  distance: intersection.distance
19202
19300
  };
@@ -19214,7 +19312,7 @@ class InstancedModelManager extends manager_Manager {
19214
19312
  });
19215
19313
  }
19216
19314
  };
19217
- canvas.addEventListener('click', handleClick);
19315
+ canvas.addEventListener('click', this.canvasClickHandler);
19218
19316
  }
19219
19317
  onClick(callback) {
19220
19318
  this.clickCallback = callback;
@@ -19224,121 +19322,226 @@ class InstancedModelManager extends manager_Manager {
19224
19322
  if (!enabled) return;
19225
19323
  const angles = this.rotationAngles.get(id);
19226
19324
  const speed = this.rotationSpeeds.get(id) || 0.01;
19227
- const instancedMesh = this.instancedMeshes.get(id);
19228
- if (!angles || !instancedMesh) return;
19325
+ const model = this.instancedModels.get(id);
19326
+ const instances = this.instanceDataMap.get(id);
19327
+ if (!angles || !model || !instances) return;
19229
19328
  const dummy = new __rspack_external_three.Object3D();
19230
- for(let i = 0; i < instancedMesh.count; i++){
19231
- instancedMesh.getMatrixAt(i, dummy.matrix);
19232
- const pos = new __rspack_external_three.Vector3();
19233
- const quat = new __rspack_external_three.Quaternion();
19234
- const scl = new __rspack_external_three.Vector3();
19235
- dummy.matrix.decompose(pos, quat, scl);
19236
- angles[i] += speed;
19237
- quat.setFromAxisAngle(new __rspack_external_three.Vector3(0, 0, 1), angles[i]);
19238
- dummy.matrix.compose(pos, quat, scl);
19239
- instancedMesh.setMatrixAt(i, dummy.matrix);
19329
+ const instanceMatrix = new __rspack_external_three.Matrix4();
19330
+ for(let i = 0; i < instances.length; i++)angles[i] += speed;
19331
+ for (const modelMesh of model.meshes){
19332
+ modelMesh.instanceIndexes.forEach((instanceIndex, localIndex)=>{
19333
+ const instance = instances[instanceIndex];
19334
+ if (!instance) return;
19335
+ const rotation = [
19336
+ instance.rotation[0],
19337
+ instance.rotation[1],
19338
+ instance.rotation[2] + angles[instanceIndex]
19339
+ ];
19340
+ this._setInstanceMatrixWithZoom(model, modelMesh, localIndex, instance, rotation, dummy, instanceMatrix, model.scaleFollowZoom ? 2 ** (model.referenceZoom - (this.map?.getZoom() ?? 16)) : 1);
19341
+ });
19342
+ modelMesh.mesh.instanceMatrix.needsUpdate = true;
19343
+ if (modelMesh.mesh.instanceColor) modelMesh.mesh.instanceColor.needsUpdate = true;
19240
19344
  }
19241
- instancedMesh.instanceMatrix.needsUpdate = true;
19242
19345
  });
19243
19346
  }
19244
- generateInstances(config) {
19347
+ buildMapboxTransform(model) {
19348
+ return new __rspack_external_three.Matrix4().makeTranslation(model.centerMercator.x, model.centerMercator.y, model.centerMercator.z).scale(new __rspack_external_three.Vector3(model.meterInMercator, -model.meterInMercator, model.meterInMercator));
19349
+ }
19350
+ toTileLngLat(lngLat) {
19351
+ return this.mapless?.coordTrans('dataToTile', lngLat) ?? lngLat;
19352
+ }
19353
+ resolveConfig(config) {
19354
+ const firstInstance = config.instances?.[0];
19355
+ const center = config.center || firstInstance?.lngLat;
19356
+ if (!center) throw new Error('InstancedModelConfig requires center or instances[0].lngLat');
19357
+ return {
19358
+ count: config.count ?? config.instances?.length ?? 0,
19359
+ center,
19360
+ spread: config.spread ?? 0
19361
+ };
19362
+ }
19363
+ generateInstances(config, resolved) {
19245
19364
  const instances = [];
19246
- for(let i = 0; i < config.count; i++){
19247
- const lngOffset = (Math.random() - 0.5) * config.spread * 2;
19248
- const latOffset = (Math.random() - 0.5) * config.spread * 2;
19249
- const altitude = 200 + 100 * Math.random();
19250
- const rotation = Math.random() * Math.PI * 2;
19251
- const scaleVariation = 0.8 + 0.4 * Math.random();
19365
+ for(let i = 0; i < resolved.count; i++){
19366
+ const lngOffset = (Math.random() - 0.5) * resolved.spread * 2;
19367
+ const latOffset = (Math.random() - 0.5) * resolved.spread * 2;
19368
+ const externalInstance = config.instances?.[i];
19252
19369
  instances.push({
19253
- lngLat: [
19254
- config.center[0] + lngOffset,
19255
- config.center[1] + latOffset
19370
+ lngLat: externalInstance?.lngLat || [
19371
+ resolved.center[0] + lngOffset,
19372
+ resolved.center[1] + latOffset
19256
19373
  ],
19257
- altitude,
19258
- rotation,
19259
- scale: scaleVariation
19374
+ type: externalInstance?.type ?? DEFAULT_MODEL_TYPE,
19375
+ altitude: externalInstance?.altitude ?? 80,
19376
+ rotation: externalInstance?.rotation || [
19377
+ 0,
19378
+ 0,
19379
+ 0
19380
+ ],
19381
+ scale: externalInstance?.scale ?? 1,
19382
+ color: externalInstance?.color
19260
19383
  });
19261
19384
  }
19262
19385
  return instances;
19263
19386
  }
19264
19387
  prepareGeometryForInstancing(geometry) {
19265
- const clonedGeometry = geometry.clone();
19266
- if (!(clonedGeometry instanceof __rspack_external_three.BufferGeometry)) {
19267
- console.error('几何体不是 BufferGeometry 类型');
19268
- return clonedGeometry;
19269
- }
19270
- if (!clonedGeometry.getAttribute('normal')) clonedGeometry.computeVertexNormals();
19271
- return clonedGeometry;
19388
+ return geometry.clone();
19272
19389
  }
19273
- prepareMaterialForInstancing(originalMaterial) {
19390
+ prepareMaterialForInstancing(originalMaterial, standardMaterialColor) {
19391
+ if (void 0 !== standardMaterialColor) return new __rspack_external_three.MeshStandardMaterial({
19392
+ color: new __rspack_external_three.Color(standardMaterialColor),
19393
+ roughness: 0.6,
19394
+ metalness: 0,
19395
+ vertexColors: true
19396
+ });
19274
19397
  if (Array.isArray(originalMaterial)) return originalMaterial.map((mat)=>this.cloneMaterialForInstancing(mat));
19275
19398
  return this.cloneMaterialForInstancing(originalMaterial);
19276
19399
  }
19277
19400
  cloneMaterialForInstancing(material) {
19278
19401
  const cloned = material.clone();
19279
- if (cloned instanceof __rspack_external_three.MeshStandardMaterial || cloned instanceof __rspack_external_three.MeshPhysicalMaterial || cloned instanceof __rspack_external_three.MeshPhongMaterial) {
19280
- cloned.toneMapped = false;
19281
- cloned.side = __rspack_external_three.DoubleSide;
19282
- }
19402
+ const supportedTypes = [
19403
+ __rspack_external_three.MeshStandardMaterial,
19404
+ __rspack_external_three.MeshPhysicalMaterial,
19405
+ __rspack_external_three.MeshPhongMaterial,
19406
+ __rspack_external_three.MeshBasicMaterial,
19407
+ __rspack_external_three.MeshLambertMaterial,
19408
+ __rspack_external_three.MeshToonMaterial
19409
+ ];
19410
+ const isSupported = supportedTypes.some((Type)=>cloned instanceof Type);
19411
+ if (isSupported) {
19412
+ const mat = cloned;
19413
+ mat.vertexColors = true;
19414
+ if (mat.map) {
19415
+ mat.emissive = new __rspack_external_three.Color(0xffffff);
19416
+ mat.emissiveIntensity = 0.4;
19417
+ mat.emissiveMap = mat.map;
19418
+ }
19419
+ cloned.needsUpdate = true;
19420
+ } else console.warn(`InstancedModel: Unsupported material type "${cloned.type}" for vertex colors`);
19283
19421
  return cloned;
19284
19422
  }
19423
+ resolveModelTypes(config) {
19424
+ if (config.modelTypes) return config.modelTypes;
19425
+ if (config.url) return {
19426
+ [DEFAULT_MODEL_TYPE]: {
19427
+ url: config.url,
19428
+ scale: config.scale,
19429
+ baseRotation: config.baseRotation,
19430
+ standardMaterialColor: config.standardMaterialColor
19431
+ }
19432
+ };
19433
+ throw new Error('InstancedModelConfig requires url or modelTypes');
19434
+ }
19435
+ groupInstanceIndexesByType(instances) {
19436
+ const grouped = new Map();
19437
+ instances.forEach((instance, index)=>{
19438
+ const indexes = grouped.get(instance.type) || [];
19439
+ indexes.push(index);
19440
+ grouped.set(instance.type, indexes);
19441
+ });
19442
+ return grouped;
19443
+ }
19285
19444
  async load(id, config) {
19286
19445
  this.initThree();
19287
- if (!this.scene || !this.map) throw new Error('Three.js scene not initialized');
19446
+ const scene = this.scene;
19447
+ if (!scene || !this.map) throw new Error('Three.js scene not initialized');
19288
19448
  this.remove(id);
19289
19449
  const loader = new GLTFLoader();
19450
+ const dracoLoader = new DRACOLoader();
19451
+ dracoLoader.setDecoderPath('/draco/gltf/');
19452
+ loader.setDRACOLoader(dracoLoader);
19290
19453
  try {
19291
- console.log('InstancedModel: Loading model', config.url);
19292
- const gltf = await new Promise((resolve, reject)=>{
19293
- loader.load(config.url, resolve, void 0, reject);
19294
- });
19295
- console.log('InstancedModel: Model loaded successfully');
19296
- let mesh;
19297
- gltf.scene.traverse((object)=>{
19298
- if (object instanceof __rspack_external_three.Mesh && !mesh) mesh = object;
19299
- });
19300
- if (!mesh) throw new Error('No mesh found in model');
19301
- const geometry = this.prepareGeometryForInstancing(mesh.geometry);
19302
- const material = this.prepareMaterialForInstancing(mesh.material);
19303
- const instances = this.generateInstances(config);
19304
- const angles = new Float32Array(config.count);
19305
- const centerMercator = mapbox_gl.MercatorCoordinate.fromLngLat(config.center, 0);
19454
+ const resolved = this.resolveConfig(config);
19455
+ const instances = this.generateInstances(config, resolved);
19456
+ const modelTypes = this.resolveModelTypes(config);
19457
+ const groupedInstanceIndexes = this.groupInstanceIndexesByType(instances);
19458
+ const angles = new Float32Array(resolved.count);
19459
+ const centerMercator = mapbox_gl.MercatorCoordinate.fromLngLat(this.toTileLngLat(resolved.center), 0);
19306
19460
  const meterInMercator = centerMercator.meterInMercatorCoordinateUnits();
19307
- const instancedMesh = new __rspack_external_three.InstancedMesh(geometry, material, config.count);
19308
- instancedMesh.instanceMatrix.setUsage(__rspack_external_three.DynamicDrawUsage);
19309
- instancedMesh.frustumCulled = false;
19310
- instancedMesh.position.set(centerMercator.x, centerMercator.y, centerMercator.z);
19311
- instancedMesh.updateMatrix();
19461
+ const group = new __rspack_external_three.Group();
19462
+ const instancedModelMeshes = [];
19463
+ const typeScales = new Map();
19464
+ const baseRotationMatrices = new Map();
19465
+ const modelEntry = {
19466
+ group,
19467
+ meshes: instancedModelMeshes,
19468
+ centerMercator,
19469
+ meterInMercator,
19470
+ typeScales,
19471
+ baseRotationMatrices,
19472
+ visible: true,
19473
+ scaleFollowZoom: false,
19474
+ referenceZoom: 16
19475
+ };
19312
19476
  const dummy = new __rspack_external_three.Object3D();
19313
- for(let i = 0; i < config.count; i++){
19314
- const instance = instances[i];
19315
- const mercator = mapbox_gl.MercatorCoordinate.fromLngLat(instance.lngLat, instance.altitude);
19316
- const dx = mercator.x - centerMercator.x;
19317
- const dy = mercator.y - centerMercator.y;
19318
- const dz = mercator.z - centerMercator.z;
19319
- dummy.position.set(dx, dy, dz);
19320
- const s = meterInMercator * config.scale * instance.scale;
19321
- dummy.scale.set(s, -s, s);
19322
- dummy.updateMatrix();
19323
- instancedMesh.setMatrixAt(i, dummy.matrix);
19324
- angles[i] = instance.rotation;
19325
- }
19326
- instancedMesh.instanceMatrix.needsUpdate = true;
19327
- if (!instancedMesh.geometry.boundingSphere) instancedMesh.geometry.computeBoundingSphere();
19328
- instancedMesh.computeBoundingSphere();
19329
- this.scene.add(instancedMesh);
19330
- console.log(`InstancedModel "${id}" loaded: ${config.count} instances`, {
19477
+ const instanceMatrix = new __rspack_external_three.Matrix4();
19478
+ for (const [type, instanceIndexes] of groupedInstanceIndexes){
19479
+ const typeConfig = modelTypes[type];
19480
+ if (!typeConfig) throw new Error(`Missing modelTypes config for instance type "${type}"`);
19481
+ console.log('InstancedModel: Loading model', type, typeConfig.url);
19482
+ const gltf = await new Promise((resolve, reject)=>{
19483
+ loader.load(typeConfig.url, resolve, void 0, reject);
19484
+ });
19485
+ if (this.scene !== scene || !this.isInitialized) return;
19486
+ console.log('InstancedModel: Model loaded successfully', type);
19487
+ const sourceMeshes = [];
19488
+ gltf.scene.updateMatrixWorld(true);
19489
+ gltf.scene.traverse((object)=>{
19490
+ if (object instanceof __rspack_external_three.Mesh) {
19491
+ const mat = object.material;
19492
+ const matInfo = Array.isArray(mat) ? mat.map((m)=>m.type) : mat.type;
19493
+ console.log(` Mesh found: ${object.name || 'unnamed'}, material:`, matInfo);
19494
+ sourceMeshes.push(object);
19495
+ }
19496
+ });
19497
+ if (0 === sourceMeshes.length) throw new Error(`No mesh found in model type "${type}"`);
19498
+ typeScales.set(type, typeConfig.scale ?? config.scale);
19499
+ baseRotationMatrices.set(type, new __rspack_external_three.Matrix4().makeRotationFromEuler(new __rspack_external_three.Euler(...typeConfig.baseRotation || config.baseRotation || [
19500
+ 0,
19501
+ 0,
19502
+ 0
19503
+ ], 'XYZ')));
19504
+ for (const sourceMesh of sourceMeshes){
19505
+ sourceMesh.updateWorldMatrix(true, false);
19506
+ const geometry = this.prepareGeometryForInstancing(sourceMesh.geometry);
19507
+ const material = this.prepareMaterialForInstancing(sourceMesh.material, typeConfig.standardMaterialColor ?? config.standardMaterialColor);
19508
+ const instancedMesh = new __rspack_external_three.InstancedMesh(geometry, material, instanceIndexes.length);
19509
+ instancedMesh.instanceMatrix.setUsage(__rspack_external_three.DynamicDrawUsage);
19510
+ instancedMesh.frustumCulled = false;
19511
+ const modelMesh = {
19512
+ mesh: instancedMesh,
19513
+ baseMatrix: sourceMesh.matrixWorld.clone(),
19514
+ instanceIndexes
19515
+ };
19516
+ instanceIndexes.forEach((instanceIndex, localIndex)=>{
19517
+ const instance = instances[instanceIndex];
19518
+ this._setInstanceMatrixWithZoom(modelEntry, modelMesh, localIndex, instance, instance.rotation, dummy, instanceMatrix);
19519
+ angles[instanceIndex] = 0;
19520
+ });
19521
+ instancedMesh.instanceMatrix.needsUpdate = true;
19522
+ if (instancedMesh.instanceColor) instancedMesh.instanceColor.needsUpdate = true;
19523
+ if (!instancedMesh.geometry.boundingSphere) instancedMesh.geometry.computeBoundingSphere();
19524
+ instancedMesh.computeBoundingSphere();
19525
+ group.add(instancedMesh);
19526
+ instancedModelMeshes.push(modelMesh);
19527
+ }
19528
+ }
19529
+ if (this.scene !== scene || !this.isInitialized) return;
19530
+ scene.add(group);
19531
+ console.log(`InstancedModel "${id}" loaded: ${resolved.count} instances`, {
19331
19532
  center: {
19332
19533
  x: centerMercator.x,
19333
19534
  y: centerMercator.y,
19334
19535
  z: centerMercator.z
19335
19536
  },
19537
+ meshCount: instancedModelMeshes.length,
19538
+ typeCount: groupedInstanceIndexes.size,
19336
19539
  meterInMercator,
19337
19540
  firstInstanceOffset: {
19338
- x: instances[0] ? mapbox_gl.MercatorCoordinate.fromLngLat(instances[0].lngLat, instances[0].altitude).x - centerMercator.x : 0
19541
+ x: instances[0] ? mapbox_gl.MercatorCoordinate.fromLngLat(this.toTileLngLat(instances[0].lngLat), instances[0].altitude).x - centerMercator.x : 0
19339
19542
  }
19340
19543
  });
19341
- this.instancedMeshes.set(id, instancedMesh);
19544
+ this.instancedModels.set(id, modelEntry);
19342
19545
  this.instanceDataMap.set(id, instances);
19343
19546
  this.rotationAngles.set(id, angles);
19344
19547
  this.autoRotateEnabled.set(id, config.autoRotate || false);
@@ -19347,6 +19550,8 @@ class InstancedModelManager extends manager_Manager {
19347
19550
  } catch (error) {
19348
19551
  console.error(`Failed to load instanced model "${id}":`, error);
19349
19552
  throw error;
19553
+ } finally{
19554
+ dracoLoader.dispose();
19350
19555
  }
19351
19556
  }
19352
19557
  enableAutoRotate(id, speed = 0.01) {
@@ -19356,74 +19561,230 @@ class InstancedModelManager extends manager_Manager {
19356
19561
  disableAutoRotate(id) {
19357
19562
  this.autoRotateEnabled.set(id, false);
19358
19563
  }
19359
- updateInstance(id, index, lngLat, altitude) {
19360
- const instancedMesh = this.instancedMeshes.get(id);
19361
- if (!instancedMesh) return;
19362
- const mercator = mapbox_gl.MercatorCoordinate.fromLngLat(lngLat, altitude);
19564
+ setScaleFollowZoom(id, enabled, referenceZoom = 16) {
19565
+ const model = this.instancedModels.get(id);
19566
+ if (!model) return;
19567
+ model.scaleFollowZoom = enabled;
19568
+ model.referenceZoom = referenceZoom;
19569
+ this._updateZoomListener();
19570
+ if (enabled) this._updateModelScaleWithZoom(id);
19571
+ else this._rebuildAllInstanceMatrices(id);
19572
+ }
19573
+ _updateZoomListener() {
19574
+ const hasScaleFollowZoom = Array.from(this.instancedModels.values()).some((m)=>m.scaleFollowZoom);
19575
+ if (hasScaleFollowZoom && !this.zoomCleanup) {
19576
+ const handleZoom = ()=>{
19577
+ this.instancedModels.forEach((model, id)=>{
19578
+ if (model.scaleFollowZoom) this._updateModelScaleWithZoom(id);
19579
+ });
19580
+ };
19581
+ this.map?.on('zoom', handleZoom);
19582
+ this.zoomCleanup = ()=>{
19583
+ this.map?.off('zoom', handleZoom);
19584
+ };
19585
+ } else if (!hasScaleFollowZoom && this.zoomCleanup) {
19586
+ this.zoomCleanup();
19587
+ this.zoomCleanup = null;
19588
+ }
19589
+ }
19590
+ _updateModelScaleWithZoom(id) {
19591
+ const model = this.instancedModels.get(id);
19592
+ if (!model || !this.map) return;
19593
+ const currentZoom = this.map.getZoom();
19594
+ const zoomScaleFactor = 2 ** (model.referenceZoom - currentZoom);
19595
+ this._rebuildAllInstanceMatrices(id, zoomScaleFactor);
19596
+ }
19597
+ _rebuildAllInstanceMatrices(id, zoomScaleFactor = 1) {
19598
+ const model = this.instancedModels.get(id);
19599
+ const instances = this.instanceDataMap.get(id);
19600
+ if (!model || !instances) return;
19363
19601
  const dummy = new __rspack_external_three.Object3D();
19364
- const pos = new __rspack_external_three.Vector3();
19365
- const quat = new __rspack_external_three.Quaternion();
19366
- const scl = new __rspack_external_three.Vector3();
19367
- instancedMesh.getMatrixAt(index, dummy.matrix);
19368
- dummy.matrix.decompose(pos, quat, scl);
19369
- dummy.position.set(mercator.x, mercator.y, mercator.z);
19602
+ const instanceMatrix = new __rspack_external_three.Matrix4();
19603
+ for (const modelMesh of model.meshes){
19604
+ modelMesh.instanceIndexes.forEach((instanceIndex, localIndex)=>{
19605
+ const instance = instances[instanceIndex];
19606
+ if (!instance) return;
19607
+ const rotationAngle = this.rotationAngles.get(id)?.[instanceIndex] ?? 0;
19608
+ const rotation = [
19609
+ instance.rotation[0],
19610
+ instance.rotation[1],
19611
+ instance.rotation[2] + rotationAngle
19612
+ ];
19613
+ this._setInstanceMatrixWithZoom(model, modelMesh, localIndex, instance, rotation, dummy, instanceMatrix, zoomScaleFactor);
19614
+ });
19615
+ modelMesh.mesh.instanceMatrix.needsUpdate = true;
19616
+ }
19617
+ }
19618
+ _setInstanceMatrixWithZoom(model, modelMesh, index, instance, rotation, dummy, instanceMatrix, zoomScaleFactor = 1) {
19619
+ const mercator = mapbox_gl.MercatorCoordinate.fromLngLat(this.toTileLngLat(instance.lngLat), instance.altitude);
19620
+ const dx = (mercator.x - model.centerMercator.x) / model.meterInMercator;
19621
+ const dy = -(mercator.y - model.centerMercator.y) / model.meterInMercator;
19622
+ const dz = (mercator.z - model.centerMercator.z) / model.meterInMercator;
19623
+ const typeScale = model.typeScales.get(instance.type) ?? 1;
19624
+ const baseRotationMatrix = model.baseRotationMatrices.get(instance.type) ?? new __rspack_external_three.Matrix4();
19625
+ dummy.position.set(dx, dy, dz);
19626
+ dummy.rotation.set(...rotation);
19627
+ dummy.scale.setScalar(typeScale * instance.scale * zoomScaleFactor);
19370
19628
  dummy.updateMatrix();
19371
- instancedMesh.setMatrixAt(index, dummy.matrix);
19372
- instancedMesh.instanceMatrix.needsUpdate = true;
19629
+ instanceMatrix.copy(dummy.matrix).multiply(baseRotationMatrix).multiply(modelMesh.baseMatrix);
19630
+ modelMesh.mesh.setMatrixAt(index, instanceMatrix);
19631
+ if (void 0 !== instance.color) modelMesh.mesh.setColorAt(index, new __rspack_external_three.Color(instance.color));
19632
+ }
19633
+ updateInstance(id, index, lngLat, altitude) {
19634
+ const model = this.instancedModels.get(id);
19635
+ if (!model) return;
19373
19636
  const instances = this.instanceDataMap.get(id);
19374
- if (instances?.[index]) {
19375
- instances[index].lngLat = lngLat;
19376
- instances[index].altitude = altitude;
19637
+ const instance = instances?.[index];
19638
+ if (!instance) return;
19639
+ instance.lngLat = lngLat;
19640
+ instance.altitude = altitude;
19641
+ const dummy = new __rspack_external_three.Object3D();
19642
+ const instanceMatrix = new __rspack_external_three.Matrix4();
19643
+ const rotationAngle = this.rotationAngles.get(id)?.[index] ?? 0;
19644
+ const rotation = [
19645
+ instance.rotation[0],
19646
+ instance.rotation[1],
19647
+ instance.rotation[2] + rotationAngle
19648
+ ];
19649
+ for (const modelMesh of model.meshes){
19650
+ const localIndex = modelMesh.instanceIndexes.indexOf(index);
19651
+ if (-1 !== localIndex) {
19652
+ this._setInstanceMatrixWithZoom(model, modelMesh, localIndex, instance, rotation, dummy, instanceMatrix, model.scaleFollowZoom ? 2 ** (model.referenceZoom - (this.map?.getZoom() ?? 16)) : 1);
19653
+ modelMesh.mesh.instanceMatrix.needsUpdate = true;
19654
+ }
19377
19655
  }
19378
19656
  }
19657
+ updateInstanceScale(id, index, scale) {
19658
+ const model = this.instancedModels.get(id);
19659
+ if (!model) return;
19660
+ const instances = this.instanceDataMap.get(id);
19661
+ const instance = instances?.[index];
19662
+ if (!instance) return;
19663
+ instance.scale = scale;
19664
+ const dummy = new __rspack_external_three.Object3D();
19665
+ const instanceMatrix = new __rspack_external_three.Matrix4();
19666
+ const rotationAngle = this.rotationAngles.get(id)?.[index] ?? 0;
19667
+ const rotation = [
19668
+ instance.rotation[0],
19669
+ instance.rotation[1],
19670
+ instance.rotation[2] + rotationAngle
19671
+ ];
19672
+ for (const modelMesh of model.meshes){
19673
+ const localIndex = modelMesh.instanceIndexes.indexOf(index);
19674
+ if (-1 !== localIndex) {
19675
+ this._setInstanceMatrixWithZoom(model, modelMesh, localIndex, instance, rotation, dummy, instanceMatrix, model.scaleFollowZoom ? 2 ** (model.referenceZoom - (this.map?.getZoom() ?? 16)) : 1);
19676
+ modelMesh.mesh.instanceMatrix.needsUpdate = true;
19677
+ }
19678
+ }
19679
+ }
19680
+ updateInstanceColor(id, index, color) {
19681
+ const model = this.instancedModels.get(id);
19682
+ if (!model) return;
19683
+ const instances = this.instanceDataMap.get(id);
19684
+ const instance = instances?.[index];
19685
+ if (!instance) return;
19686
+ instance.color = color;
19687
+ const colorObj = new __rspack_external_three.Color(color);
19688
+ for (const modelMesh of model.meshes){
19689
+ const localIndex = modelMesh.instanceIndexes.indexOf(index);
19690
+ if (-1 !== localIndex) modelMesh.mesh.setColorAt(localIndex, colorObj);
19691
+ }
19692
+ for (const modelMesh of model.meshes)if (modelMesh.mesh.instanceColor) modelMesh.mesh.instanceColor.needsUpdate = true;
19693
+ }
19694
+ handleCoordSystemChange(_system) {
19695
+ const dummy = new __rspack_external_three.Object3D();
19696
+ const instanceMatrix = new __rspack_external_three.Matrix4();
19697
+ this.instancedModels.forEach((model, id)=>{
19698
+ const instances = this.instanceDataMap.get(id);
19699
+ const config = this.originalConfigs.get(id);
19700
+ const center = config?.center ?? instances?.[0]?.lngLat;
19701
+ if (!instances || !center) return;
19702
+ model.centerMercator = mapbox_gl.MercatorCoordinate.fromLngLat(this.toTileLngLat(center), 0);
19703
+ model.meterInMercator = model.centerMercator.meterInMercatorCoordinateUnits();
19704
+ for (const modelMesh of model.meshes){
19705
+ modelMesh.instanceIndexes.forEach((instanceIndex, localIndex)=>{
19706
+ const instance = instances[instanceIndex];
19707
+ if (!instance) return;
19708
+ const rotationAngle = this.rotationAngles.get(id)?.[instanceIndex] ?? 0;
19709
+ const rotation = [
19710
+ instance.rotation[0],
19711
+ instance.rotation[1],
19712
+ instance.rotation[2] + rotationAngle
19713
+ ];
19714
+ this._setInstanceMatrixWithZoom(model, modelMesh, localIndex, instance, rotation, dummy, instanceMatrix, model.scaleFollowZoom ? 2 ** (model.referenceZoom - (this.map?.getZoom() ?? 16)) : 1);
19715
+ });
19716
+ modelMesh.mesh.instanceMatrix.needsUpdate = true;
19717
+ }
19718
+ });
19719
+ }
19379
19720
  setInstanceVisible(id, visible) {
19380
- const instancedMesh = this.instancedMeshes.get(id);
19381
- if (instancedMesh) instancedMesh.visible = visible;
19721
+ const model = this.instancedModels.get(id);
19722
+ if (model) {
19723
+ model.visible = visible;
19724
+ model.group.visible = visible;
19725
+ }
19382
19726
  }
19383
19727
  setVisible(visible) {
19384
19728
  this.IsVisible = visible;
19385
- this.instancedMeshes.forEach((mesh)=>{
19386
- mesh.visible = visible;
19729
+ this.instancedModels.forEach((model)=>{
19730
+ model.visible = visible;
19731
+ model.group.visible = visible;
19387
19732
  });
19388
19733
  }
19389
19734
  getInstanceCount(id) {
19390
- return this.instancedMeshes.get(id)?.count || 0;
19735
+ return this.instanceDataMap.get(id)?.length || 0;
19736
+ }
19737
+ getMeshCount(id) {
19738
+ return this.instancedModels.get(id)?.meshes.length || 0;
19391
19739
  }
19392
19740
  getIds() {
19393
- return Array.from(this.instancedMeshes.keys());
19741
+ return Array.from(this.instancedModels.keys());
19394
19742
  }
19395
19743
  remove(id) {
19396
- const instancedMesh = this.instancedMeshes.get(id);
19397
- if (instancedMesh && this.scene) {
19398
- this.scene.remove(instancedMesh);
19399
- instancedMesh.geometry.dispose();
19400
- if (Array.isArray(instancedMesh.material)) for (const m of instancedMesh.material)m.dispose();
19401
- else instancedMesh.material.dispose();
19402
- }
19403
- this.instancedMeshes.delete(id);
19744
+ const model = this.instancedModels.get(id);
19745
+ if (model && this.scene) {
19746
+ this.scene.remove(model.group);
19747
+ for (const modelMesh of model.meshes){
19748
+ modelMesh.mesh.geometry.dispose();
19749
+ if (Array.isArray(modelMesh.mesh.material)) for (const m of modelMesh.mesh.material)m.dispose();
19750
+ else modelMesh.mesh.material.dispose();
19751
+ }
19752
+ }
19753
+ this.instancedModels.delete(id);
19404
19754
  this.instanceDataMap.delete(id);
19405
19755
  this.rotationAngles.delete(id);
19406
19756
  this.autoRotateEnabled.delete(id);
19407
19757
  this.rotationSpeeds.delete(id);
19408
19758
  this.originalConfigs.delete(id);
19759
+ this._updateZoomListener();
19409
19760
  }
19410
19761
  clear() {
19411
19762
  const ids = this.getIds();
19412
19763
  for (const id of ids)this.remove(id);
19413
19764
  }
19414
19765
  setColor(id, color) {
19415
- const instancedMesh = this.instancedMeshes.get(id);
19416
- if (!instancedMesh) return;
19766
+ const model = this.instancedModels.get(id);
19767
+ if (!model) return;
19417
19768
  const meshColor = 'string' == typeof color ? new __rspack_external_three.Color(color) : color;
19418
- if (Array.isArray(instancedMesh.material)) {
19419
- for (const m of instancedMesh.material)if ('color' in m) m.color.set(meshColor);
19420
- } else if ('color' in instancedMesh.material) instancedMesh.material.color.set(meshColor);
19769
+ for (const modelMesh of model.meshes)if (Array.isArray(modelMesh.mesh.material)) {
19770
+ for (const m of modelMesh.mesh.material)if ('color' in m) m.color.set(meshColor);
19771
+ } else if ('color' in modelMesh.mesh.material) modelMesh.mesh.material.color.set(meshColor);
19421
19772
  }
19422
19773
  destroy() {
19423
19774
  this.clear();
19424
- if (this.map && this.customLayerId) try {
19425
- this.map.removeLayer(this.customLayerId);
19426
- } catch {}
19775
+ if (this.zoomCleanup) {
19776
+ this.zoomCleanup();
19777
+ this.zoomCleanup = null;
19778
+ }
19779
+ if (this.map) {
19780
+ if (this.canvasClickHandler) {
19781
+ this.map.getCanvas().removeEventListener('click', this.canvasClickHandler);
19782
+ this.canvasClickHandler = null;
19783
+ }
19784
+ if (this.customLayerId && this.map.getLayer(this.customLayerId)) try {
19785
+ this.map.removeLayer(this.customLayerId);
19786
+ } catch {}
19787
+ }
19427
19788
  if (this.renderer) {
19428
19789
  this.renderer.dispose();
19429
19790
  this.renderer = null;
@@ -19432,6 +19793,7 @@ class InstancedModelManager extends manager_Manager {
19432
19793
  this.camera = null;
19433
19794
  this.isInitialized = false;
19434
19795
  this.originalConfigs.clear();
19796
+ super.destroy();
19435
19797
  }
19436
19798
  }
19437
19799
  const instancedModel = InstancedModelManager;
@@ -19669,6 +20031,14 @@ class Line2Manager extends manager_Manager {
19669
20031
  });
19670
20032
  this.lines.clear();
19671
20033
  }
20034
+ setVisible(visible) {
20035
+ super.setVisible(visible);
20036
+ const mapThree = this.getMapThree();
20037
+ if (!mapThree) return;
20038
+ this.lines.forEach((lineData)=>{
20039
+ mapThree.setRenderableObjectVisible(lineData.id, visible);
20040
+ });
20041
+ }
19672
20042
  getLineCount() {
19673
20043
  return this.lines.size;
19674
20044
  }
@@ -19826,6 +20196,7 @@ class Line2Manager extends manager_Manager {
19826
20196
  this.renderCallback = null;
19827
20197
  }
19828
20198
  this.clearLines();
20199
+ super.destroy();
19829
20200
  }
19830
20201
  }
19831
20202
  const line2Manager = Line2Manager;
@@ -19934,6 +20305,7 @@ class ModelManager extends manager_Manager {
19934
20305
  actions = new Map();
19935
20306
  clock = new Timer();
19936
20307
  modelConfigs = new Map();
20308
+ animationCallback = ()=>this.updateAnimations();
19937
20309
  constructor(mapless){
19938
20310
  super(mapless);
19939
20311
  this.map = mapless.map;
@@ -19947,9 +20319,7 @@ class ModelManager extends manager_Manager {
19947
20319
  if (!this.mapless) return;
19948
20320
  this.mapThree = this.mapless.getMapThree();
19949
20321
  if (!this.mapThree) return void console.warn('ModelManager: MapThree not initialized');
19950
- this.mapThree.addAnimationCallback(()=>{
19951
- this.updateAnimations();
19952
- });
20322
+ this.mapThree.addAnimationCallback(this.animationCallback);
19953
20323
  }
19954
20324
  updateAnimations() {
19955
20325
  const delta = this.clock.getDelta();
@@ -20226,12 +20596,11 @@ class ModelManager extends manager_Manager {
20226
20596
  });
20227
20597
  this.mixers.clear();
20228
20598
  this.actions.clear();
20229
- if (this.mapThree) this.mapThree.removeAnimationCallback(()=>{
20230
- this.updateAnimations();
20231
- });
20599
+ if (this.mapThree) this.mapThree.removeAnimationCallback(this.animationCallback);
20232
20600
  }
20233
20601
  destroy() {
20234
20602
  this.dispose();
20603
+ super.destroy();
20235
20604
  }
20236
20605
  }
20237
20606
  const mana_three_model = ModelManager;
@@ -20273,6 +20642,7 @@ class ThreeManager extends manager_Manager {
20273
20642
  isSelected = false;
20274
20643
  clickCleanup = null;
20275
20644
  zoomCleanup = null;
20645
+ animationCallback = ()=>this.updateAnimation();
20276
20646
  originalModelConfig = null;
20277
20647
  constructor(mapless){
20278
20648
  super(mapless);
@@ -20284,9 +20654,7 @@ class ThreeManager extends manager_Manager {
20284
20654
  if (!this.mapless) return;
20285
20655
  this.mapThree = this.mapless.getMapThree();
20286
20656
  if (!this.mapThree) return void console.warn('ThreeManager: MapThree not initialized');
20287
- this.mapThree.addAnimationCallback(()=>{
20288
- this.updateAnimation();
20289
- });
20657
+ this.mapThree.addAnimationCallback(this.animationCallback);
20290
20658
  }
20291
20659
  updateAnimation() {
20292
20660
  const delta = this.clock.getDelta();
@@ -20586,6 +20954,11 @@ class ThreeManager extends manager_Manager {
20586
20954
  this.clickCleanup = cleanup;
20587
20955
  return cleanup;
20588
20956
  }
20957
+ setVisible(visible) {
20958
+ super.setVisible(visible);
20959
+ const mapThree = this.getMapThree();
20960
+ if (mapThree && this.modelId) mapThree.setRenderableObjectVisible(this.modelId, visible);
20961
+ }
20589
20962
  unregisterClick() {
20590
20963
  if (this.clickCleanup) {
20591
20964
  this.clickCleanup();
@@ -20609,9 +20982,7 @@ class ThreeManager extends manager_Manager {
20609
20982
  this.mixer.stopAllAction();
20610
20983
  this.mixer = null;
20611
20984
  }
20612
- if (this.mapThree) this.mapThree.removeAnimationCallback(()=>{
20613
- this.updateAnimation();
20614
- });
20985
+ if (this.mapThree) this.mapThree.removeAnimationCallback(this.animationCallback);
20615
20986
  }
20616
20987
  handleCoordSystemChange(_system) {
20617
20988
  if (!this.originalModelConfig) return;
@@ -20636,6 +21007,7 @@ class ThreeManager extends manager_Manager {
20636
21007
  };
20637
21008
  destroy() {
20638
21009
  this.dispose();
21010
+ super.destroy();
20639
21011
  }
20640
21012
  }
20641
21013
  const three = ThreeManager;