@kimap/indoor-positioning-sdk-vue2 5.3.2 → 5.3.4

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": "5.3.2",
3
+ "version": "5.3.4",
4
4
  "description": "Vue2自包含室内定位SDK - 完全兼容Webpack3+Babel6 | Vue2 Self-Contained Indoor Positioning SDK",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -93,9 +93,6 @@ KimapSDK.prototype.init = function() {
93
93
  // 创建科技感地面背景
94
94
  self._createTechGround();
95
95
 
96
- // 启动道路动画循环
97
- self._startRoadAnimationLoop();
98
-
99
96
  // 加载背景建筑
100
97
  if (self.backgroundBuildingsConfig.enabled !== false) {
101
98
  self._loadBackgroundBuildings();
@@ -861,9 +858,22 @@ KimapSDK.prototype._showSingleFloor = function(floorIndex) {
861
858
  this.techGroundGroup.visible = false;
862
859
  }
863
860
 
864
- // 显示家具
861
+ // 显示当前楼层的家具(按楼层分组显示)
865
862
  if (this.furnitureGroup) {
866
863
  this.furnitureGroup.visible = true;
864
+ // 如果有按楼层分组的家具子组,只显示当前楼层的
865
+ var currentFloorId = 'floor_' + floorIndex;
866
+ this.furnitureGroup.children.forEach(function(child) {
867
+ if (child.name && child.name.startsWith('furniture_')) {
868
+ // 检查是否是当前楼层的家具
869
+ if (child.name === 'furniture_' + currentFloorId ||
870
+ child.userData.floorId === currentFloorId) {
871
+ child.visible = true;
872
+ } else {
873
+ child.visible = false;
874
+ }
875
+ }
876
+ });
867
877
  }
868
878
 
869
879
  // 调整相机到该楼层(带动画)
@@ -937,8 +947,8 @@ KimapSDK.prototype._fadeInBackgroundBuildings = function(duration) {
937
947
 
938
948
  this.backgroundGroup.visible = true;
939
949
 
940
- // 目标透明度为 0.5
941
- var targetOpacity = 0.5;
950
+ // 目标透明度为 0.7
951
+ var targetOpacity = 0.7;
942
952
 
943
953
  // 设置初始透明度
944
954
  this.backgroundGroup.traverse(function(child) {
@@ -1138,15 +1148,15 @@ KimapSDK.prototype._createFallbackBuilding = function(x, z) {
1138
1148
  // 主楼体 - 淡蓝色半透明
1139
1149
  var geometry = new THREE.BoxGeometry(width, height, depth);
1140
1150
 
1141
- // 淡蓝色 - 0.5透明度效果
1142
- var baseColor = new THREE.Color(0x4488cc);
1151
+ // 淡蓝色 - 0.7透明度效果,颜色加深约10%
1152
+ var baseColor = new THREE.Color(0x3c79b7);
1143
1153
  var material = new THREE.MeshStandardMaterial({
1144
1154
  color: baseColor,
1145
1155
  roughness: 0.4,
1146
1156
  metalness: 0.3,
1147
1157
  transparent: true,
1148
- opacity: 0.5,
1149
- emissive: new THREE.Color(0x224466),
1158
+ opacity: 0.7,
1159
+ emissive: new THREE.Color(0x1e3d5c),
1150
1160
  emissiveIntensity: 0.3
1151
1161
  });
1152
1162
 
@@ -1234,7 +1244,7 @@ KimapSDK.prototype._addGlowingEdges = function(buildingGroup, width, height, dep
1234
1244
  };
1235
1245
 
1236
1246
  /**
1237
- * 创建科技感地面背景
1247
+ * 创建科技感地面背景(简化版:只保留颜色和网格)
1238
1248
  * @private
1239
1249
  */
1240
1250
  KimapSDK.prototype._createTechGround = function() {
@@ -1266,109 +1276,6 @@ KimapSDK.prototype._createTechGround = function() {
1266
1276
  ground.rotation.x = -Math.PI / 2;
1267
1277
  ground.position.y = -0.2;
1268
1278
  this.techGroundGroup.add(ground);
1269
-
1270
- // 创建道路线条
1271
- this._createRoadLines(groundSize);
1272
- };
1273
-
1274
- /**
1275
- * 创建道路流光线条
1276
- * @private
1277
- */
1278
- KimapSDK.prototype._createRoadLines = function(size) {
1279
- var roadGroup = new THREE.Group();
1280
- roadGroup.name = 'roadLines';
1281
- this.roadLinesGroup = roadGroup;
1282
-
1283
- // 减少道路数量,简化效果
1284
- var lineCount = 8;
1285
- var roadWidth = 8;
1286
-
1287
- for (var i = 0; i < lineCount; i++) {
1288
- var angle = Math.random() * Math.PI * 2;
1289
- var length = size * (0.3 + Math.random() * 0.5);
1290
- var x = Math.cos(angle) * size * 0.4;
1291
- var z = Math.sin(angle) * size * 0.4;
1292
-
1293
- // 创建道路
1294
- var roadGeometry = new THREE.PlaneGeometry(length, roadWidth);
1295
- var roadMaterial = new THREE.MeshBasicMaterial({
1296
- color: 0x112233,
1297
- transparent: true,
1298
- opacity: 0.6
1299
- });
1300
- var road = new THREE.Mesh(roadGeometry, roadMaterial);
1301
- road.rotation.x = -Math.PI / 2;
1302
- road.rotation.z = angle;
1303
- road.position.set(x, 0, z);
1304
- roadGroup.add(road);
1305
-
1306
- // 创建中心虚线(简化)
1307
- var dashCount = Math.floor(length / 5);
1308
- for (var d = 0; d < dashCount; d++) {
1309
- var dashGeometry = new THREE.PlaneGeometry(2, 0.3);
1310
- var dashMaterial = new THREE.MeshBasicMaterial({
1311
- color: 0x00aaff,
1312
- transparent: true,
1313
- opacity: 0.8
1314
- });
1315
- var dash = new THREE.Mesh(dashGeometry, dashMaterial);
1316
- dash.rotation.x = -Math.PI / 2;
1317
- dash.rotation.z = angle;
1318
- dash.position.set(
1319
- x + Math.cos(angle) * (d * 5 - length / 2 + 1),
1320
- 0.05,
1321
- z + Math.sin(angle) * (d * 5 - length / 2 + 1)
1322
- );
1323
- dash.userData.baseOpacity = 0.4 + Math.random() * 0.4;
1324
- dash.userData.phase = Math.random() * Math.PI * 2;
1325
- dash.userData.speed = 0.5 + Math.random() * 1.5;
1326
- roadGroup.add(dash);
1327
- }
1328
- }
1329
-
1330
- // 添加到科技感地面组
1331
- if (this.techGroundGroup) {
1332
- this.techGroundGroup.add(roadGroup);
1333
- } else {
1334
- this.core.scene.add(roadGroup);
1335
- }
1336
- };
1337
-
1338
- /**
1339
- * 更新道路流光动画(在render loop中调用)
1340
- * @private
1341
- */
1342
- KimapSDK.prototype._updateRoadAnimation = function(time) {
1343
- if (!this.roadLinesGroup) return;
1344
-
1345
- this.roadLinesGroup.traverse(function(child) {
1346
- if (child.userData && child.userData.baseOpacity !== undefined) {
1347
- var pulse = Math.sin(time * child.userData.speed + child.userData.phase) * 0.3 + 0.5;
1348
- child.material.opacity = child.userData.baseOpacity * pulse;
1349
- }
1350
- });
1351
- };
1352
-
1353
- /**
1354
- * 在渲染循环中添加道路动画更新
1355
- * @private
1356
- */
1357
- KimapSDK.prototype._startRoadAnimationLoop = function() {
1358
- var self = this;
1359
- var originalStartRenderLoop = this.startRenderLoop.bind(this);
1360
-
1361
- this.startRenderLoop = function() {
1362
- originalStartRenderLoop();
1363
-
1364
- // 添加道路动画更新
1365
- var animationLoop = function() {
1366
- requestAnimationFrame(animationLoop);
1367
- var time = performance.now() * 0.001;
1368
- self._updateRoadAnimation(time);
1369
- };
1370
- animationLoop();
1371
- };
1372
1279
  };
1373
1280
 
1374
1281
  /**
@@ -1525,6 +1432,8 @@ KimapSDK.prototype.getCoordinateSystem = function() {
1525
1432
  * @param {number} [options.xFactor=0.5] - X轴偏移因子
1526
1433
  * @param {number} [options.yFactor=0.4] - Y轴偏移因子(高度)
1527
1434
  * @param {number} [options.zFactor=0.5] - Z轴偏移因子
1435
+ * @param {boolean} [options.animate=false] - 是否使用动画过渡
1436
+ * @param {number} [options.duration=600] - 动画持续时间(毫秒),仅当animate为true时有效
1528
1437
  */
1529
1438
  KimapSDK.prototype.autoAdjustCamera = function(options) {
1530
1439
  var self = this;
@@ -1539,6 +1448,8 @@ KimapSDK.prototype.autoAdjustCamera = function(options) {
1539
1448
  var xFactor = opts.xFactor !== undefined ? opts.xFactor : 0.5;
1540
1449
  var yFactor = opts.yFactor !== undefined ? opts.yFactor : 0.4;
1541
1450
  var zFactor = opts.zFactor !== undefined ? opts.zFactor : 0.5;
1451
+ var animate = opts.animate === true;
1452
+ var duration = opts.duration || 600;
1542
1453
 
1543
1454
  // 优先使用楼层组(多楼层模式),否则使用mapModel(单楼层模式)
1544
1455
  var targetObject = null;
@@ -1573,25 +1484,40 @@ KimapSDK.prototype.autoAdjustCamera = function(options) {
1573
1484
  var maxDim = Math.max(size.x, size.y, size.z);
1574
1485
  var distance = maxDim * distanceFactor;
1575
1486
 
1576
- self.core.camera.position.set(
1487
+ var targetPosition = new THREE.Vector3(
1577
1488
  center.x + distance * xFactor,
1578
1489
  center.y + distance * yFactor,
1579
1490
  center.z + distance * zFactor
1580
1491
  );
1581
1492
 
1582
- self.core.camera.lookAt(center);
1583
-
1584
- if (self.core.controls) {
1585
- self.core.controls.target.copy(center);
1586
- self.core.controls.update();
1493
+ // 根据animate参数决定是否使用动画
1494
+ if (animate) {
1495
+ self._animateCamera({
1496
+ position: targetPosition,
1497
+ lookAt: center
1498
+ }, duration, function() {
1499
+ console.log('KimapSDK: 相机动画调整完成', {
1500
+ center: center,
1501
+ distance: distance,
1502
+ size: size
1503
+ });
1504
+ });
1505
+ } else {
1506
+ self.core.camera.position.copy(targetPosition);
1507
+ self.core.camera.lookAt(center);
1508
+
1509
+ if (self.core.controls) {
1510
+ self.core.controls.target.copy(center);
1511
+ self.core.controls.update();
1512
+ }
1513
+
1514
+ console.log('KimapSDK: 相机已自动调整', {
1515
+ center: center,
1516
+ distance: distance,
1517
+ size: size
1518
+ });
1587
1519
  }
1588
1520
 
1589
- console.log('KimapSDK: 相机已自动调整', {
1590
- center: center,
1591
- distance: distance,
1592
- size: size
1593
- });
1594
-
1595
1521
  return self;
1596
1522
  };
1597
1523
 
@@ -1649,6 +1575,23 @@ KimapSDK.prototype.getConfig = function() {
1649
1575
  return config;
1650
1576
  };
1651
1577
 
1578
+ /**
1579
+ * 加载3D家具模型数据
1580
+ * 注意:此方法需要在SDK初始化成功后(init回调后)手动调用!
1581
+ * 用法:
1582
+ * sdk.init().then(function(sdk) {
1583
+ * sdk.loadKMData().then(function(result) {
1584
+ * console.log('家具加载结果:', result);
1585
+ * });
1586
+ * });
1587
+ *
1588
+ * 多楼层模式说明:
1589
+ * - 如果kidata中包含floors信息,家具会按楼层分组
1590
+ * - 切换楼层时自动显示对应楼层的家具
1591
+ * - ALL模式下隐藏所有家具
1592
+ *
1593
+ * @returns {Promise<Object>} 返回加载结果 { success: true/false, loaded: number, failed: number }
1594
+ */
1652
1595
  KimapSDK.prototype.loadKMData = function() {
1653
1596
  var self = this;
1654
1597
 
@@ -1745,23 +1688,23 @@ KimapSDK.prototype._decryptKidata = function(encrypted) {
1745
1688
 
1746
1689
  KimapSDK.prototype._loadFurnitureModels = function(kidataObj) {
1747
1690
  var self = this;
1748
-
1691
+
1749
1692
  if (!kidataObj.furnitures || kidataObj.furnitures.length === 0) {
1750
1693
  return Promise.resolve({ loaded: 0, failed: 0 });
1751
1694
  }
1752
-
1695
+
1753
1696
  // 创建家具组(如果不存在)
1754
1697
  if (!this.furnitureGroup) {
1755
1698
  this.furnitureGroup = new THREE.Group();
1756
1699
  this.furnitureGroup.name = 'furnitures';
1757
1700
  this.core.scene.add(this.furnitureGroup);
1758
1701
  }
1759
-
1702
+
1760
1703
  // 清空现有家具
1761
1704
  while (this.furnitureGroup.children.length > 0) {
1762
1705
  var child = this.furnitureGroup.children[0];
1763
1706
  this.furnitureGroup.remove(child);
1764
-
1707
+
1765
1708
  // 释放资源
1766
1709
  if (child.geometry) child.geometry.dispose();
1767
1710
  if (child.material) {
@@ -1772,31 +1715,62 @@ KimapSDK.prototype._loadFurnitureModels = function(kidataObj) {
1772
1715
  }
1773
1716
  }
1774
1717
  }
1775
-
1718
+
1776
1719
  // 优先使用dataUrl,如果不存在则使用serverUrl(兼容旧版本)
1777
1720
  var serverUrl = kidataObj.dataUrl || kidataObj.serverUrl;
1778
1721
  var loadPromises = [];
1779
1722
  var loadedCount = 0;
1780
1723
  var failedCount = 0;
1781
-
1782
- // 加载每个家具模型
1724
+
1725
+ // 检查kidata是否包含楼层信息,用于多楼层家具分组
1726
+ var hasFloorInfo = kidataObj.floors && kidataObj.floors.length > 0;
1727
+
1728
+ // 按楼层分组家具(如果kidata包含楼层信息)
1729
+ var furnitureByFloor = {};
1730
+ if (hasFloorInfo) {
1731
+ kidataObj.floors.forEach(function(floor) {
1732
+ furnitureByFloor[floor.id] = [];
1733
+ });
1734
+ }
1735
+
1736
+ // 收集所有家具到对应楼层
1783
1737
  kidataObj.furnitures.forEach(function(furniture) {
1784
- var promise = self._loadSingleFurniture(furniture, serverUrl)
1785
- .then(function(mesh) {
1786
- if (mesh) {
1787
- self.furnitureGroup.add(mesh);
1788
- loadedCount++;
1789
- } else {
1738
+ var floorId = furniture.floorId || furniture.floor || 'floor_0';
1739
+ if (!furnitureByFloor[floorId]) {
1740
+ furnitureByFloor[floorId] = [];
1741
+ }
1742
+ furnitureByFloor[floorId].push(furniture);
1743
+ });
1744
+
1745
+ // 加载每个楼层的家具
1746
+ Object.keys(furnitureByFloor).forEach(function(floorId) {
1747
+ var floorFurnitures = furnitureByFloor[floorId];
1748
+ if (!floorFurnitures || floorFurnitures.length === 0) return;
1749
+
1750
+ // 为每个楼层创建子Group
1751
+ var floorFurnitureGroup = new THREE.Group();
1752
+ floorFurnitureGroup.name = 'furniture_' + floorId;
1753
+ floorFurnitureGroup.userData.floorId = floorId;
1754
+ self.furnitureGroup.add(floorFurnitureGroup);
1755
+
1756
+ floorFurnitures.forEach(function(furniture) {
1757
+ var promise = self._loadSingleFurniture(furniture, serverUrl)
1758
+ .then(function(mesh) {
1759
+ if (mesh) {
1760
+ floorFurnitureGroup.add(mesh);
1761
+ loadedCount++;
1762
+ } else {
1763
+ failedCount++;
1764
+ }
1765
+ })
1766
+ .catch(function(error) {
1790
1767
  failedCount++;
1791
- }
1792
- })
1793
- .catch(function(error) {
1794
- failedCount++;
1795
- });
1796
-
1797
- loadPromises.push(promise);
1768
+ });
1769
+
1770
+ loadPromises.push(promise);
1771
+ });
1798
1772
  });
1799
-
1773
+
1800
1774
  return Promise.all(loadPromises).then(function() {
1801
1775
  return { loaded: loadedCount, failed: failedCount };
1802
1776
  });
@@ -265,6 +265,11 @@ SceneCore.prototype._loadMultiFloorMaps = function(OBJLoader, MTLLoader, objUrls
265
265
  });
266
266
  }, Promise.resolve()).then(function() {
267
267
  console.log('SceneCore: 多楼层模型加载完成,共', self.floorGroups.length, '个楼层');
268
+ // 所有楼层加载完成后,调整相机到所有楼层(确保包围盒包含所有层)
269
+ // 这只在有多个楼层时必要,单楼层会被SDK init中的_showSingleFloor处理
270
+ if (self.floorGroups.length > 1) {
271
+ self._adjustCameraToAllFloors();
272
+ }
268
273
  });
269
274
  };
270
275
 
@@ -693,8 +698,8 @@ SceneCore.prototype._processLoadedModel = function(object, materials, colorMap)
693
698
  var areaLevel = 1; // 区域层级从1开始
694
699
 
695
700
  self.mapModel.traverse(function(child) {
696
- // 隐藏底平面交互层
697
- if (child.name === 'HiddenGroundPlane' || child.name.includes('InteractionLayer')) {
701
+ // 隐藏底平面交互层(扩展匹配规则)
702
+ if (self._isHiddenGroundMesh(child.name)) {
698
703
  child.visible = false;
699
704
  console.log('✅ 隐藏交互层底平面:', child.name);
700
705
  return;
@@ -784,7 +789,7 @@ SceneCore.prototype._processLoadedModelToGroup = function(object, materials, col
784
789
 
785
790
  // 处理材质
786
791
  object.traverse(function(child) {
787
- if (child.name === 'HiddenGroundPlane' || child.name.includes('InteractionLayer')) {
792
+ if (self._isHiddenGroundMesh(child.name)) {
788
793
  child.visible = false;
789
794
  return;
790
795
  }
@@ -793,11 +798,6 @@ SceneCore.prototype._processLoadedModelToGroup = function(object, materials, col
793
798
  self._processMaterial(child, materials, colorMap);
794
799
  }
795
800
  });
796
-
797
- // 只在第一个楼层调整相机
798
- if (floorIndex === 0) {
799
- self._adjustCameraToAllFloors();
800
- }
801
801
  };
802
802
 
803
803
  /**
@@ -853,6 +853,29 @@ SceneCore.prototype._adjustCameraToAllFloors = function() {
853
853
  }
854
854
  };
855
855
 
856
+ /**
857
+ * 判断是否为需要隐藏的底面/交互层mesh
858
+ * @private
859
+ */
860
+ SceneCore.prototype._isHiddenGroundMesh = function(name) {
861
+ if (!name) return false;
862
+ var lowerName = name.toLowerCase();
863
+ // 扩展匹配规则:包含以下关键字的mesh将被隐藏
864
+ var hiddenPatterns = [
865
+ 'hiddengroundplane',
866
+ 'interactionlayer',
867
+ 'groundplane',
868
+ 'baseplate',
869
+ 'groundlayer',
870
+ 'floor_ground',
871
+ 'bottom',
872
+ 'ground_base'
873
+ ];
874
+ return hiddenPatterns.some(function(pattern) {
875
+ return lowerName.includes(pattern);
876
+ });
877
+ };
878
+
856
879
  /**
857
880
  * 处理材质(内部方法)
858
881
  * @private