@kimap/indoor-positioning-sdk-vue2 5.3.9 → 5.4.0

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.9",
3
+ "version": "5.4.0",
4
4
  "description": "Vue2自包含室内定位SDK - 完全兼容Webpack3+Babel6 | Vue2 Self-Contained Indoor Positioning SDK",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -887,7 +887,7 @@ SceneCore.prototype._isHiddenGroundMesh = function(name) {
887
887
 
888
888
  /**
889
889
  * 检测并隐藏模型自带的大面积底垫mesh
890
- * 基于世界空间包围盒的启发式判断(薄片+贴底+相对面积)
890
+ * 基于世界空间包围盒的启发式判断(薄片+贴底+相对面积+颜色)
891
891
  * @private
892
892
  */
893
893
  SceneCore.prototype._hideLargeBlackGroundMesh = function(object) {
@@ -900,45 +900,124 @@ SceneCore.prototype._hideLargeBlackGroundMesh = function(object) {
900
900
  modelBox.getSize(modelSize);
901
901
  var maxDim = Math.max(modelSize.x, modelSize.z);
902
902
 
903
- // 2. 动态阈值(相对于模型尺度)
904
- var slabMaxThickness = Math.max(0.05, 0.01 * maxDim); // 厚度上限
905
- var minFootprint = Math.max(1, 0.05 * modelSize.x * modelSize.z); // 最小占地面积(比固定 1000 更灵活)
906
- var epsilon = Math.max(0.01, 0.002 * modelSize.y); // 贴底判定容差
903
+ // 2. 动态阈值(相对于模型尺度,调整为更宽松的值)
904
+ // slabMaxThickness: 厚度上限,降低以检测更薄的底板
905
+ var slabMaxThickness = Math.max(0.02, 0.003 * maxDim);
906
+ // minFootprint: 最小占地面积,降低以检测更小的底板
907
+ var minFootprint = Math.max(0.5, 0.005 * modelSize.x * modelSize.z);
908
+ // epsilon: 贴底判定容差,放宽以检测更多情况
909
+ var epsilon = Math.max(0.05, 0.01 * modelSize.y);
907
910
 
908
911
  var debugMode = this.config && this.config.debugBottomMeshes === true;
909
912
 
913
+ /**
914
+ * 获取材质的亮度(检查是否为黑色/深色)
915
+ * @param {THREE.Object3D} child - 3D对象
916
+ * @returns {number} 亮度值(0-1),-1表示无颜色信息
917
+ */
918
+ function getMaterialLuminance(child) {
919
+ var mat = child.material;
920
+ if (!mat) return -1;
921
+ var color = mat.color;
922
+ if (!color) return -1;
923
+ var r = color.r, g = color.g, b = color.b;
924
+ return 0.299 * r + 0.587 * g + 0.114 * b;
925
+ }
926
+
927
+ /**
928
+ * 检查是否为需要跳过颜色检测的物体类型
929
+ * 这些物体即使颜色较深也不应该被隐藏
930
+ * @param {string} name - 物体名称
931
+ * @returns {boolean} 是否跳过
932
+ */
933
+ function shouldSkipColorCheck(name) {
934
+ if (!name) return false;
935
+ var lowerName = name.toLowerCase();
936
+ // 跳过有明确类型的物体
937
+ var skipPatterns = ['wall_', 'area_', 'shape_', 'stair_', 'door_', 'window_', 'furniture_', 'desk_', 'chair_', 'table_', 'cabinet_', 'bed_', 'sofa_', 'shelf_', 'rack_', 'plant_', 'tree_', 'lamp_', 'light_'];
938
+ return skipPatterns.some(function(pattern) {
939
+ return lowerName.startsWith(pattern);
940
+ });
941
+ }
942
+
943
+ /**
944
+ * 检查是否为底垫mesh
945
+ * 条件1: 贴底 + 薄片 + 够大(原有逻辑)
946
+ * 条件2: 贴底 + 超薄 + 深色(新增:检测无名称的黑色底板)
947
+ * 条件3: 贴底 + 中等厚度 + 超大深色(新增:检测无名称的厚深色底板)
948
+ * 条件4: 极薄 + 极大深色面(检测超大面积薄板)
949
+ * @param {THREE.Mesh} child - 网格对象
950
+ * @param {THREE.Vector3} sizeWorld - 世界空间尺寸
951
+ * @param {number} worldMinY - 世界空间最小Y
952
+ * @returns {boolean} 是否为底垫mesh
953
+ */
954
+ function isBottomSlab(child, sizeWorld, worldMinY) {
955
+ var luminance = getMaterialLuminance(child);
956
+ var childName = child.name || '';
957
+ var skipColor = shouldSkipColorCheck(childName);
958
+
959
+ // 条件1: 原有逻辑(贴底 + 薄片 + 够大)- 始终适用
960
+ var cond1 = (
961
+ worldMinY <= modelMinY + epsilon &&
962
+ sizeWorld.y < slabMaxThickness &&
963
+ sizeWorld.x * sizeWorld.z > minFootprint
964
+ );
965
+
966
+ // 条件2: 贴底 + 超薄 + 深色(只对无明确名称的物体生效)
967
+ var cond2 = !skipColor && (
968
+ worldMinY <= modelMinY + epsilon * 2 &&
969
+ sizeWorld.y < slabMaxThickness * 0.5 &&
970
+ luminance >= 0 && luminance < 0.15
971
+ );
972
+
973
+ // 条件3: 贴底 + 较大面积 + 深色(只对无明确名称的物体生效)
974
+ var cond3 = !skipColor && (
975
+ worldMinY <= modelMinY + epsilon &&
976
+ sizeWorld.x * sizeWorld.z > minFootprint * 5 &&
977
+ luminance >= 0 && luminance < 0.1
978
+ );
979
+
980
+ // 条件4: 极薄 + 极大深色面(只对无明确名称的物体生效)
981
+ var cond4 = !skipColor && (
982
+ worldMinY <= modelMinY + epsilon &&
983
+ sizeWorld.y < slabMaxThickness * 0.3 &&
984
+ sizeWorld.x * sizeWorld.z > minFootprint * 2 &&
985
+ luminance >= 0 && luminance < 0.2
986
+ );
987
+
988
+ return cond1 || cond2 || cond3 || cond4;
989
+ }
990
+
910
991
  object.traverse(function(child) {
911
992
  if (!(child instanceof THREE.Mesh)) return;
912
993
  if (child.visible === false) return;
913
994
 
914
- // 名称已明确匹配的,保持隐藏(不在此重复打印)
995
+ // 名称已明确匹配的,保持隐藏
915
996
  if (self._isHiddenGroundMesh(child.name)) return;
916
997
 
917
998
  if (!child.geometry || !child.geometry.attributes.position) return;
918
999
 
919
- // 2. 计算世界空间包围盒(考虑旋转/缩放)
1000
+ // 计算世界空间包围盒(考虑旋转/缩放)
920
1001
  child.geometry.computeBoundingBox();
921
1002
  var worldBox = new THREE.Box3().setFromObject(child);
922
1003
  var sizeWorld = new THREE.Vector3();
923
1004
  worldBox.getSize(sizeWorld);
924
1005
  var worldMinY = worldBox.min.y;
925
1006
 
926
- // 3. 底垫判定:必须同时满足「贴底」+「薄片」+「够大」
927
- var isBottomSlab = (
928
- worldMinY <= modelMinY + epsilon && // 贴底
929
- sizeWorld.y < slabMaxThickness && // 薄片
930
- sizeWorld.x * sizeWorld.z > minFootprint // 够大
931
- );
1007
+ // 底垫判定
1008
+ var isSlab = isBottomSlab(child, sizeWorld, worldMinY);
932
1009
 
933
1010
  if (debugMode) {
1011
+ var luminance = getMaterialLuminance(child);
934
1012
  console.log('[debugBottomMeshes]', child.name || 'unnamed',
935
1013
  'worldMinY:', worldMinY.toFixed(3),
936
1014
  'size:', sizeWorld.x.toFixed(1), 'x', sizeWorld.z.toFixed(1), 'x', sizeWorld.y.toFixed(3),
937
- 'isBottomSlab:', isBottomSlab
1015
+ 'luminance:', luminance >= 0 ? luminance.toFixed(2) : 'N/A',
1016
+ 'isSlab:', isSlab
938
1017
  );
939
1018
  }
940
1019
 
941
- if (isBottomSlab) {
1020
+ if (isSlab) {
942
1021
  child.visible = false;
943
1022
  console.log('[KimapSDK] Hidden bottom slab mesh:', child.name || 'unnamed',
944
1023
  'size:', sizeWorld.x.toFixed(1), 'x', sizeWorld.z.toFixed(1), 'x', sizeWorld.y.toFixed(3));