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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.3",
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,102 +1276,7 @@ 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
1279
  };
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
1280
  var animationLoop = function() {
1366
1281
  requestAnimationFrame(animationLoop);
1367
1282
  var time = performance.now() * 0.001;
@@ -1525,6 +1440,8 @@ KimapSDK.prototype.getCoordinateSystem = function() {
1525
1440
  * @param {number} [options.xFactor=0.5] - X轴偏移因子
1526
1441
  * @param {number} [options.yFactor=0.4] - Y轴偏移因子(高度)
1527
1442
  * @param {number} [options.zFactor=0.5] - Z轴偏移因子
1443
+ * @param {boolean} [options.animate=false] - 是否使用动画过渡
1444
+ * @param {number} [options.duration=600] - 动画持续时间(毫秒),仅当animate为true时有效
1528
1445
  */
1529
1446
  KimapSDK.prototype.autoAdjustCamera = function(options) {
1530
1447
  var self = this;
@@ -1539,6 +1456,8 @@ KimapSDK.prototype.autoAdjustCamera = function(options) {
1539
1456
  var xFactor = opts.xFactor !== undefined ? opts.xFactor : 0.5;
1540
1457
  var yFactor = opts.yFactor !== undefined ? opts.yFactor : 0.4;
1541
1458
  var zFactor = opts.zFactor !== undefined ? opts.zFactor : 0.5;
1459
+ var animate = opts.animate === true;
1460
+ var duration = opts.duration || 600;
1542
1461
 
1543
1462
  // 优先使用楼层组(多楼层模式),否则使用mapModel(单楼层模式)
1544
1463
  var targetObject = null;
@@ -1573,25 +1492,40 @@ KimapSDK.prototype.autoAdjustCamera = function(options) {
1573
1492
  var maxDim = Math.max(size.x, size.y, size.z);
1574
1493
  var distance = maxDim * distanceFactor;
1575
1494
 
1576
- self.core.camera.position.set(
1495
+ var targetPosition = new THREE.Vector3(
1577
1496
  center.x + distance * xFactor,
1578
1497
  center.y + distance * yFactor,
1579
1498
  center.z + distance * zFactor
1580
1499
  );
1581
1500
 
1582
- self.core.camera.lookAt(center);
1583
-
1584
- if (self.core.controls) {
1585
- self.core.controls.target.copy(center);
1586
- self.core.controls.update();
1501
+ // 根据animate参数决定是否使用动画
1502
+ if (animate) {
1503
+ self._animateCamera({
1504
+ position: targetPosition,
1505
+ lookAt: center
1506
+ }, duration, function() {
1507
+ console.log('KimapSDK: 相机动画调整完成', {
1508
+ center: center,
1509
+ distance: distance,
1510
+ size: size
1511
+ });
1512
+ });
1513
+ } else {
1514
+ self.core.camera.position.copy(targetPosition);
1515
+ self.core.camera.lookAt(center);
1516
+
1517
+ if (self.core.controls) {
1518
+ self.core.controls.target.copy(center);
1519
+ self.core.controls.update();
1520
+ }
1521
+
1522
+ console.log('KimapSDK: 相机已自动调整', {
1523
+ center: center,
1524
+ distance: distance,
1525
+ size: size
1526
+ });
1587
1527
  }
1588
1528
 
1589
- console.log('KimapSDK: 相机已自动调整', {
1590
- center: center,
1591
- distance: distance,
1592
- size: size
1593
- });
1594
-
1595
1529
  return self;
1596
1530
  };
1597
1531
 
@@ -1649,6 +1583,23 @@ KimapSDK.prototype.getConfig = function() {
1649
1583
  return config;
1650
1584
  };
1651
1585
 
1586
+ /**
1587
+ * 加载3D家具模型数据
1588
+ * 注意:此方法需要在SDK初始化成功后(init回调后)手动调用!
1589
+ * 用法:
1590
+ * sdk.init().then(function(sdk) {
1591
+ * sdk.loadKMData().then(function(result) {
1592
+ * console.log('家具加载结果:', result);
1593
+ * });
1594
+ * });
1595
+ *
1596
+ * 多楼层模式说明:
1597
+ * - 如果kidata中包含floors信息,家具会按楼层分组
1598
+ * - 切换楼层时自动显示对应楼层的家具
1599
+ * - ALL模式下隐藏所有家具
1600
+ *
1601
+ * @returns {Promise<Object>} 返回加载结果 { success: true/false, loaded: number, failed: number }
1602
+ */
1652
1603
  KimapSDK.prototype.loadKMData = function() {
1653
1604
  var self = this;
1654
1605
 
@@ -1745,23 +1696,23 @@ KimapSDK.prototype._decryptKidata = function(encrypted) {
1745
1696
 
1746
1697
  KimapSDK.prototype._loadFurnitureModels = function(kidataObj) {
1747
1698
  var self = this;
1748
-
1699
+
1749
1700
  if (!kidataObj.furnitures || kidataObj.furnitures.length === 0) {
1750
1701
  return Promise.resolve({ loaded: 0, failed: 0 });
1751
1702
  }
1752
-
1703
+
1753
1704
  // 创建家具组(如果不存在)
1754
1705
  if (!this.furnitureGroup) {
1755
1706
  this.furnitureGroup = new THREE.Group();
1756
1707
  this.furnitureGroup.name = 'furnitures';
1757
1708
  this.core.scene.add(this.furnitureGroup);
1758
1709
  }
1759
-
1710
+
1760
1711
  // 清空现有家具
1761
1712
  while (this.furnitureGroup.children.length > 0) {
1762
1713
  var child = this.furnitureGroup.children[0];
1763
1714
  this.furnitureGroup.remove(child);
1764
-
1715
+
1765
1716
  // 释放资源
1766
1717
  if (child.geometry) child.geometry.dispose();
1767
1718
  if (child.material) {
@@ -1772,31 +1723,62 @@ KimapSDK.prototype._loadFurnitureModels = function(kidataObj) {
1772
1723
  }
1773
1724
  }
1774
1725
  }
1775
-
1726
+
1776
1727
  // 优先使用dataUrl,如果不存在则使用serverUrl(兼容旧版本)
1777
1728
  var serverUrl = kidataObj.dataUrl || kidataObj.serverUrl;
1778
1729
  var loadPromises = [];
1779
1730
  var loadedCount = 0;
1780
1731
  var failedCount = 0;
1781
-
1782
- // 加载每个家具模型
1732
+
1733
+ // 检查kidata是否包含楼层信息,用于多楼层家具分组
1734
+ var hasFloorInfo = kidataObj.floors && kidataObj.floors.length > 0;
1735
+
1736
+ // 按楼层分组家具(如果kidata包含楼层信息)
1737
+ var furnitureByFloor = {};
1738
+ if (hasFloorInfo) {
1739
+ kidataObj.floors.forEach(function(floor) {
1740
+ furnitureByFloor[floor.id] = [];
1741
+ });
1742
+ }
1743
+
1744
+ // 收集所有家具到对应楼层
1783
1745
  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 {
1746
+ var floorId = furniture.floorId || furniture.floor || 'floor_0';
1747
+ if (!furnitureByFloor[floorId]) {
1748
+ furnitureByFloor[floorId] = [];
1749
+ }
1750
+ furnitureByFloor[floorId].push(furniture);
1751
+ });
1752
+
1753
+ // 加载每个楼层的家具
1754
+ Object.keys(furnitureByFloor).forEach(function(floorId) {
1755
+ var floorFurnitures = furnitureByFloor[floorId];
1756
+ if (!floorFurnitures || floorFurnitures.length === 0) return;
1757
+
1758
+ // 为每个楼层创建子Group
1759
+ var floorFurnitureGroup = new THREE.Group();
1760
+ floorFurnitureGroup.name = 'furniture_' + floorId;
1761
+ floorFurnitureGroup.userData.floorId = floorId;
1762
+ self.furnitureGroup.add(floorFurnitureGroup);
1763
+
1764
+ floorFurnitures.forEach(function(furniture) {
1765
+ var promise = self._loadSingleFurniture(furniture, serverUrl)
1766
+ .then(function(mesh) {
1767
+ if (mesh) {
1768
+ floorFurnitureGroup.add(mesh);
1769
+ loadedCount++;
1770
+ } else {
1771
+ failedCount++;
1772
+ }
1773
+ })
1774
+ .catch(function(error) {
1790
1775
  failedCount++;
1791
- }
1792
- })
1793
- .catch(function(error) {
1794
- failedCount++;
1795
- });
1796
-
1797
- loadPromises.push(promise);
1776
+ });
1777
+
1778
+ loadPromises.push(promise);
1779
+ });
1798
1780
  });
1799
-
1781
+
1800
1782
  return Promise.all(loadPromises).then(function() {
1801
1783
  return { loaded: loadedCount, failed: failedCount };
1802
1784
  });
@@ -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