@kimap/indoor-positioning-sdk-vue2 6.0.2 → 6.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kimap/indoor-positioning-sdk-vue2",
3
- "version": "6.0.2",
3
+ "version": "6.0.5",
4
4
  "description": "Vue2自包含室内定位SDK - 完全兼容Webpack3+Babel6 | Vue2 Self-Contained Indoor Positioning SDK",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -652,6 +652,9 @@ KimapSDK.prototype.showSingleFloor = function(floorIndex) {
652
652
  if (!this.floorGroups || this.floorGroups.length === 0) return;
653
653
  var self = this;
654
654
 
655
+ // 切换单楼层时移除 ALL 周边建筑物
656
+ this.core._removeAllModeBuildings();
657
+
655
658
  var isFromAll = (this._currentMode === 'all');
656
659
  var ANIM_DURATION = 300; // ms
657
660
  var startTime = Date.now();
@@ -792,12 +795,15 @@ KimapSDK.prototype.showAllFloors = function() {
792
795
  // 相机动画飞到 ALL 外景视角(参考正式版 _zoomToShowAllFloors)
793
796
  this._zoomToShowAllFloors();
794
797
 
798
+ // 渲染 ALL 模式周边建筑物
799
+ this.core._addAllModeBuildings();
800
+
795
801
  this._currentShowingFloorIndex = -1; // ALL 状态
796
802
  this._currentMode = 'all';
797
803
  };
798
804
 
799
805
  /**
800
- * 多楼层:相机动画飞到能看到所有楼层的位置(ALL 外景视角,从侧方斜俯视,俯角约 45°)
806
+ * 多楼层:相机动画飞到能看到所有楼层的位置(ALL 外景视角,从侧方斜俯视,俯角25°,拉远)
801
807
  * @private
802
808
  */
803
809
  KimapSDK.prototype._zoomToShowAllFloors = function() {
@@ -821,10 +827,11 @@ KimapSDK.prototype._zoomToShowAllFloors = function() {
821
827
  box.getSize(size);
822
828
  var maxSize = Math.max(size.x, size.z);
823
829
 
824
- // ALL侧方斜俯视:方位角-45°,俯角45°,模型占屏幕80%
830
+ // ALL侧方斜俯视:方位角-45°,俯角25°(polar≈65°),模型占屏幕60%(拉远)
825
831
  var azimuthDeg = -45;
826
- var pitchDeg = 45;
827
- var screenFillFactor = 0.8;
832
+ var pitchDeg = 25;
833
+ var pitchDeg = 35;
834
+ var screenFillFactor = 0.6;
828
835
  var aspect = (this.core.camera && this.core.camera.aspect) || (window.innerWidth / window.innerHeight);
829
836
  var fovRad = (this.core.camera && this.core.camera.fov) ? this.core.camera.fov * Math.PI / 180 : (60 * Math.PI / 180);
830
837
  var hDist = maxSize / 2 / screenFillFactor / Math.tan(Math.atan(Math.tan(fovRad / 2) / aspect));
@@ -70,6 +70,7 @@ function SceneCore(config) {
70
70
  this.floorOriginalY = []; // 每个楼层的原始世界Y偏移(含间隙)
71
71
  // 楼层切换动画状态
72
72
  this.floorAnim = null; // { running: bool, startTime: ms, duration: ms, steps: [] }
73
+ this._allModeBuildings = []; // ALL 模式下的周边模拟建筑物
73
74
  }
74
75
 
75
76
  /**
@@ -95,6 +96,7 @@ SceneCore.prototype.init = function() {
95
96
  self.initRenderer();
96
97
  self.initControls(OrbitControls);
97
98
  self.setupLights();
99
+ self.setupGround();
98
100
  self.addCoordinateHelper();
99
101
  return Promise.all([loadOBJLoader(), loadMTLLoader()]);
100
102
  })
@@ -230,6 +232,39 @@ SceneCore.prototype.setupLights = function() {
230
232
  this.scene.add(hemisphereLight);
231
233
  };
232
234
 
235
+ /**
236
+ * 设置地面(纯色 + 网格)
237
+ */
238
+ SceneCore.prototype.setupGround = function() {
239
+ var origin = this.coordinateSystem.origin;
240
+ var maxX = this.coordinateSystem.maxX;
241
+ var maxZ = this.coordinateSystem.maxY;
242
+
243
+ // 地面尺寸稍大于地图,留出边距
244
+ var groundSize = Math.max(maxX, maxZ) * 1.6;
245
+
246
+ // 地面纯色平面(不接收阴影、不投射阴影)
247
+ var groundGeo = new THREE.PlaneGeometry(groundSize, groundSize);
248
+ var groundMat = new THREE.MeshLambertMaterial({
249
+ color: 0xf7f7f7,
250
+ side: THREE.DoubleSide
251
+ });
252
+ var ground = new THREE.Mesh(groundGeo, groundMat);
253
+ ground.rotation.x = -Math.PI / 2;
254
+ ground.position.set(origin.x + maxX / 2, -0.001, origin.z);
255
+ ground.receiveShadow = false;
256
+ this.scene.add(ground);
257
+
258
+ // 网格线(与地面颜色协调,线色 #d0d0d0,格间距 maxX/10)
259
+ var gridSize = Math.max(maxX, maxZ) * 1.5;
260
+ var gridDivisions = Math.max(10, Math.round(gridSize / (maxX / 10)));
261
+ var grid = new THREE.GridHelper(gridSize, gridDivisions, 0xbdbdbd, 0xd0d0d0);
262
+ grid.position.set(origin.x + maxX / 2, 0, origin.z);
263
+ grid.material.opacity = 0.5;
264
+ grid.material.transparent = true;
265
+ this.scene.add(grid);
266
+ };
267
+
233
268
  /**
234
269
  * 添加坐标辅助器
235
270
  */
@@ -510,11 +545,15 @@ SceneCore.prototype._adjustCameraToAllFloors = function() {
510
545
  box.getSize(size);
511
546
  var maxSize = Math.max(size.x, size.z);
512
547
 
513
- // 从侧方斜俯视:方位角 -45°(侧方),俯角 45°(polar≈60°,与调试值对应)
514
- var pitchDeg = 45;
548
+ // 从侧方斜俯视:方位角-45°,俯角25°(polar≈65°),模型占屏幕60%(拉远)
549
+ var pitchDeg = 25;
515
550
  var azimuthDeg = -45;
516
- var baseDistance = maxSize > 0 ? maxSize * 0.8 : 10;
517
- var distance = baseDistance;
551
+ var screenFillFactor = 0.6;
552
+ var aspect = this.camera ? this.camera.aspect : (this.container.clientWidth / this.container.clientHeight);
553
+ var fovRad = this.camera ? this.camera.fov * Math.PI / 180 : (60 * Math.PI / 180);
554
+ var hDist = maxSize / 2 / screenFillFactor / Math.tan(Math.atan(Math.tan(fovRad / 2) / aspect));
555
+ var vDist = maxSize / 2 / screenFillFactor / Math.tan(fovRad / 2);
556
+ var distance = Math.max(hDist, vDist);
518
557
 
519
558
  var pitchRad = pitchDeg * Math.PI / 180;
520
559
  var azimuthRad = azimuthDeg * Math.PI / 180;
@@ -540,6 +579,84 @@ SceneCore.prototype._adjustCameraToAllFloors = function() {
540
579
  }
541
580
  };
542
581
 
582
+ /**
583
+ * ALL 模式:在四周渲染 4 栋模拟建筑物(淡蓝色 0.5 透明度,无光遮挡)
584
+ * @private
585
+ */
586
+ SceneCore.prototype._addAllModeBuildings = function() {
587
+ this._removeAllModeBuildings();
588
+
589
+ try {
590
+ var allMeshes = [];
591
+ this.floorGroups.forEach(function(group) {
592
+ group.traverse(function(child) {
593
+ if (child.isMesh) allMeshes.push(child);
594
+ });
595
+ });
596
+ if (allMeshes.length === 0) return;
597
+
598
+ var box = new THREE.Box3();
599
+ allMeshes.forEach(function(mesh) { box.expandByObject(mesh); });
600
+ var boxMin = new THREE.Vector3();
601
+ var boxMax = new THREE.Vector3();
602
+ box.getMin(boxMin);
603
+ box.getMax(boxMax);
604
+ var centerX = (boxMin.x + boxMax.x) / 2;
605
+ var centerZ = (boxMin.z + boxMax.z) / 2;
606
+ var modelW = boxMax.x - boxMin.x;
607
+ var modelD = boxMax.z - boxMin.z;
608
+ var modelH = boxMax.y - boxMin.y;
609
+
610
+ // 建筑物高度:取模型高度的 1.5~2.5 倍,宽度为模型宽度的 0.4~0.6 倍
611
+ var baseW = modelW * 0.45;
612
+ var baseD = modelD * 0.45;
613
+ var heights = [modelH * 1.8, modelH * 2.2, modelH * 1.5, modelH * 2.5];
614
+ // 四周分布:前后左右,距模型边缘约 0.6 倍模型尺寸
615
+ var offsets = [
616
+ { x: 0, z: -(modelD / 2 + modelD * 0.55), w: baseW * 1.1, d: baseD * 0.9 },
617
+ { x: 0, z: modelD / 2 + modelD * 0.55, w: baseW, d: baseD },
618
+ { x: modelW / 2 + modelW * 0.55, z: 0, w: baseW * 0.9, d: baseD * 1.1 },
619
+ { x: -(modelW / 2 + modelW * 0.55), z: 0, w: baseW, d: baseD * 1.0 }
620
+ ];
621
+
622
+ var self = this;
623
+ heights.forEach(function(h, i) {
624
+ var o = offsets[i];
625
+ var geo = new THREE.BoxGeometry(o.w, h, o.d);
626
+ var mat = new THREE.MeshBasicMaterial({
627
+ color: 0x9ecfef,
628
+ transparent: true,
629
+ opacity: 0.5,
630
+ depthWrite: false
631
+ });
632
+ var mesh = new THREE.Mesh(geo, mat);
633
+ mesh.position.set(centerX + o.x, h / 2, centerZ + o.z);
634
+ mesh.castShadow = false;
635
+ mesh.receiveShadow = false;
636
+ self.scene.add(mesh);
637
+ self._allModeBuildings.push(mesh);
638
+ });
639
+
640
+ console.log('ALL 模式:已添加 ' + self._allModeBuildings.length + ' 栋周边建筑物');
641
+ } catch (e) {
642
+ console.warn('添加 ALL 模式建筑物失败:', e);
643
+ }
644
+ };
645
+
646
+ /**
647
+ * 移除 ALL 模式的周边建筑物
648
+ * @private
649
+ */
650
+ SceneCore.prototype._removeAllModeBuildings = function() {
651
+ var self = this;
652
+ this._allModeBuildings.forEach(function(mesh) {
653
+ self.scene.remove(mesh);
654
+ mesh.geometry.dispose();
655
+ mesh.material.dispose();
656
+ });
657
+ this._allModeBuildings = [];
658
+ };
659
+
543
660
  /**
544
661
  * 相机对准指定楼层(多楼层切换/ALL 时分别调用)
545
662
  * @param {number} floorIndex - 楼层索引