@kimap/indoor-positioning-sdk-vue2 5.2.0 → 5.2.2

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.2.0",
3
+ "version": "5.2.2",
4
4
  "description": "Vue2自包含室内定位SDK - 完全兼容Webpack3+Babel6 | Vue2 Self-Contained Indoor Positioning SDK",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -277,6 +277,37 @@
277
277
  return wallOpacity;
278
278
  }
279
279
 
280
+ // 从OBJ内容中提取形状透明度信息(矩形、圆形、多边形)
281
+ function extractShapeOpacityFromOBJ(objContent) {
282
+ var shapeOpacity = {};
283
+ var lines = objContent.split('\n');
284
+ var currentShapeId = null;
285
+ var currentShapeType = null;
286
+
287
+ for (var i = 0; i < lines.length; i++) {
288
+ var line = lines[i].trim();
289
+
290
+ if (line.indexOf('o Shape_') === 0) {
291
+ // 提取形状ID和类型(格式:Shape_<type>_<id>)
292
+ var match = line.match(/Shape_([^_]+)_(.+)/);
293
+ if (match) {
294
+ currentShapeType = match[1];
295
+ currentShapeId = match[2];
296
+ }
297
+ } else if (currentShapeId && line.indexOf('# SHAPE_OPACITY') === 0) {
298
+ var opacity = parseFloat(line.split(' ')[2]);
299
+ if (!shapeOpacity[currentShapeId]) {
300
+ shapeOpacity[currentShapeId] = {};
301
+ }
302
+ shapeOpacity[currentShapeId].opacity = opacity;
303
+ shapeOpacity[currentShapeId].type = currentShapeType;
304
+ }
305
+ }
306
+
307
+ console.log('[Parsers] 提取到的形状透明度:', Object.keys(shapeOpacity).length, '个形状');
308
+ return shapeOpacity;
309
+ }
310
+
280
311
  /**
281
312
  * 3D 场景核心
282
313
  */
@@ -406,7 +437,7 @@
406
437
 
407
438
  var centerX = origin.x + maxX / 2;
408
439
  var centerZ = origin.z;
409
- var distance = Math.max(maxX, maxY) * 1.5;
440
+ var distance = Math.max(maxX, maxY) * 1.2;
410
441
 
411
442
  this.camera.position.set(centerX, distance, centerZ + distance * 0.5);
412
443
  this.camera.lookAt(centerX, 0, centerZ);
@@ -646,6 +677,13 @@
646
677
  self._wallOpacity = wallOpacity;
647
678
  }
648
679
 
680
+ // 提取形状透明度信息(矩形、圆形、多边形)
681
+ var shapeOpacity = extractShapeOpacityFromOBJ(objContent);
682
+ if (shapeOpacity && Object.keys(shapeOpacity).length > 0) {
683
+ console.log('✅ 从OBJ提取到形状透明度:', Object.keys(shapeOpacity).length, '个形状');
684
+ self._shapeOpacity = shapeOpacity;
685
+ }
686
+
649
687
  var object = objLoader.parse(objContent);
650
688
  self.processModel(object, colorMap);
651
689
 
@@ -769,11 +807,18 @@
769
807
  child.material.name.startsWith('Stair_')) {
770
808
  roughness = 0.6;
771
809
  metalness = 0;
772
- // 保持从MTL中获取的真实透明度
773
- if (opacity === 1.0) {
774
- opacity = 0.9;
810
+
811
+ // 从OBJ提取的形状透明度数据中读取
812
+ if (self._shapeOpacity) {
813
+ var shapeId = child.material.name.replace('Shape_', '').replace(/^rectangle_/, '').replace(/^circle_/, '').replace(/^polygon_/, '');
814
+ if (self._shapeOpacity[shapeId]) {
815
+ opacity = self._shapeOpacity[shapeId].opacity;
816
+ transparent = opacity < 1.0;
817
+ // 高透明度时关闭depthWrite
818
+ depthWrite = opacity >= 0.8;
819
+ console.log('[SceneCore] 应用形状透明度:', shapeId, '=', opacity);
820
+ }
775
821
  }
776
- transparent = opacity < 1.0;
777
822
  // 混合10%白色,让颜色更浅一点
778
823
  var color = new THREE.Color(mtlColor);
779
824
  color.lerp(new THREE.Color(0xffffff), 0.1);
@@ -906,7 +951,7 @@
906
951
  */
907
952
  SceneCore.prototype.adjustCameraToModel = function(modelSize) {
908
953
  var maxDimension = Math.max(modelSize.x, modelSize.z);
909
- var distance = maxDimension * 1.5;
954
+ var distance = maxDimension * 1.2;
910
955
 
911
956
  // 计算模型中心(模型已经移动到原点,所以中心就是尺寸的一半)
912
957
  var centerX = modelSize.x / 2;
@@ -1771,6 +1816,60 @@
1771
1816
  this.core.controls.target.set(centerX, 0, centerZ);
1772
1817
  this.core.controls.update();
1773
1818
  };
1819
+
1820
+ /**
1821
+ * 自动调整相机视角,使其能够完整看到整个地图模型
1822
+ * @param {Object} options - 配置选项
1823
+ * @param {number} [options.distanceFactor=1.0] - 相机距离因子,值越小相机越近
1824
+ * @param {number} [options.xFactor=0.5] - X轴偏移因子
1825
+ * @param {number} [options.yFactor=0.4] - Y轴偏移因子(高度)
1826
+ * @param {number} [options.zFactor=0.5] - Z轴偏移因子
1827
+ */
1828
+ KimapSDK.prototype.autoAdjustCamera = function(options) {
1829
+ var self = this;
1830
+
1831
+ if (!self.core || !self.core.mapModel) {
1832
+ console.warn('KimapSDK: 地图模型未加载,无法调整相机');
1833
+ return;
1834
+ }
1835
+
1836
+ var opts = options || {};
1837
+ var distanceFactor = opts.distanceFactor !== undefined ? opts.distanceFactor : 1.0;
1838
+ var xFactor = opts.xFactor !== undefined ? opts.xFactor : 0.5;
1839
+ var yFactor = opts.yFactor !== undefined ? opts.yFactor : 0.4;
1840
+ var zFactor = opts.zFactor !== undefined ? opts.zFactor : 0.5;
1841
+
1842
+ var box = new THREE.Box3().setFromObject(self.core.mapModel);
1843
+ var center = new THREE.Vector3();
1844
+ var size = new THREE.Vector3();
1845
+
1846
+ box.getCenter(center);
1847
+ box.getSize(size);
1848
+
1849
+ var maxDim = Math.max(size.x, size.y, size.z);
1850
+ var distance = maxDim * distanceFactor;
1851
+
1852
+ self.core.camera.position.set(
1853
+ center.x + distance * xFactor,
1854
+ center.y + distance * yFactor,
1855
+ center.z + distance * zFactor
1856
+ );
1857
+
1858
+ self.core.camera.lookAt(center);
1859
+
1860
+ if (self.core.controls) {
1861
+ self.core.controls.target.copy(center);
1862
+ self.core.controls.update();
1863
+ }
1864
+
1865
+ console.log('KimapSDK: 相机已自动调整', {
1866
+ center: center,
1867
+ distance: distance,
1868
+ size: size
1869
+ });
1870
+
1871
+ return self;
1872
+ };
1774
1873
 
1775
1874
  /**
1776
1875
  * 相机控制 - 正视图
@@ -1899,8 +1998,6 @@
1899
1998
  var fileName = objUrl.split('/').pop().replace(/\.(obj|kimap)$/i, '');
1900
1999
  var kidataUrl = directory + '/' + fileName + '.kidata';
1901
2000
 
1902
- console.log('📦 开始加载3D家具模型数据:', kidataUrl);
1903
-
1904
2001
  return fetch(kidataUrl)
1905
2002
  .then(function(response) {
1906
2003
  if (!response.ok) {
@@ -1918,31 +2015,25 @@
1918
2015
 
1919
2016
  // 如果kidata包含楼层数据,设置为projectLayers
1920
2017
  if (kidataObj.floors && Array.isArray(kidataObj.floors)) {
1921
- console.log('KimapSDK: kidata包含楼层数据,楼层数量:', kidataObj.floors.length);
1922
2018
  // 设置第一个楼层为当前楼层(如果没有其他楼层数据)
1923
2019
  if (!self.projectLayers && kidataObj.floors.length > 0) {
1924
2020
  self.projectLayers = kidataObj.floors[0].layers;
1925
- console.log('KimapSDK: 从kidata设置楼层数据,图层数量:', self.projectLayers.length);
1926
2021
  }
1927
2022
  }
1928
2023
 
1929
- console.log('✅ Kidata文件解密成功:', {
1930
- version: kidataObj.version,
1931
- serverUrl: kidataObj.serverUrl,
1932
- furnitureCount: kidataObj.furnitures ? kidataObj.furnitures.length : 0,
1933
- floorCount: kidataObj.floors ? kidataObj.floors.length : 0
1934
- });
1935
-
1936
2024
  // 加载3D家具模型
1937
2025
  return self._loadFurnitureModels(kidataObj);
1938
2026
  })
1939
2027
  .then(function(result) {
1940
- console.log('✅ 3D家具模型加载完成:', result);
2028
+ console.log('✅ 家具加载完成:成功 ' + result.loaded + ' 个,失败 ' + result.failed + ' 个');
2029
+
2030
+ // 加载完成后应用形状透明度
2031
+ self._applyShapeOpacity(kidataObj);
1941
2032
 
1942
2033
  return { success: true, loaded: result.loaded, failed: result.failed };
1943
2034
  })
1944
2035
  .catch(function(error) {
1945
- console.error('❌ 加载3D家具模型失败:', error);
2036
+ console.error('❌ 家具加载失败:', error.message);
1946
2037
  return { success: false, error: error.message };
1947
2038
  });
1948
2039
  };
@@ -2026,7 +2117,6 @@
2026
2117
  }
2027
2118
  })
2028
2119
  .catch(function(error) {
2029
- console.error('加载家具模型失败:', furniture.type, error);
2030
2120
  failedCount++;
2031
2121
  });
2032
2122
 
@@ -2082,8 +2172,6 @@
2082
2172
  loader.load(
2083
2173
  modelUrl,
2084
2174
  function(obj) {
2085
- console.log('🔧 [家具模型加载] 开始处理:', furniture.type);
2086
-
2087
2175
  // 计算模型的边界框
2088
2176
  var box = new THREE.Box3().setFromObject(obj);
2089
2177
  var size = new THREE.Vector3();
@@ -2111,16 +2199,6 @@
2111
2199
  var finalScaleY = scaleY * userScaleY;
2112
2200
  var finalScaleZ = scaleZ * userScaleZ;
2113
2201
 
2114
- console.log('🔧 [家具缩放] 原始模型尺寸:', { x: size.x.toFixed(4), y: size.y.toFixed(4), z: size.z.toFixed(4) });
2115
- console.log('🔧 [家具缩放] 目标尺寸:', { width: targetWidth.toFixed(4), height: targetHeight.toFixed(4), depth: targetDepth.toFixed(4) });
2116
- console.log('🔧 [家具缩放] 轴向缩放因子:', { scaleX: scaleX.toFixed(4), scaleY: scaleY.toFixed(4), scaleZ: scaleZ.toFixed(4) });
2117
- console.log('🔧 [家具缩放] 用户缩放:', { x: userScaleX, y: userScaleY, z: userScaleZ });
2118
- console.log('🔧 [家具缩放] 最终缩放:', {
2119
- x: finalScaleX.toFixed(4),
2120
- y: finalScaleY.toFixed(4),
2121
- z: finalScaleZ.toFixed(4)
2122
- });
2123
-
2124
2202
  obj.scale.set(finalScaleX, finalScaleY, finalScaleZ);
2125
2203
 
2126
2204
  // ========== 修复2: 位置处理(与绘制平台一致)==========
@@ -2142,11 +2220,6 @@
2142
2220
  var scaledBottomY = scaledBox.min.y;
2143
2221
  var elevation = furniture.position.y; // 离地高度(米)
2144
2222
 
2145
- console.log('🔧 [家具] scaledCenter:', scaledCenter);
2146
- console.log('🔧 [家具] scaledBottomY:', scaledBottomY);
2147
- console.log('🔧 [家具] elevation:', elevation);
2148
- console.log('🔧 [家具] furniture.position:', furniture.position);
2149
-
2150
2223
  // ========== 旋转处理:使用Group包装(围绕家具中心旋转)==========
2151
2224
  var hasRotation = furniture.rotation && (
2152
2225
  furniture.rotation.x !== 0 ||
@@ -2172,8 +2245,6 @@
2172
2245
  -scaledCenter.z
2173
2246
  );
2174
2247
 
2175
- console.log('🔧 [家具位置] obj.position(中心偏移):', obj.position);
2176
-
2177
2248
  // 2. 将obj添加到Group
2178
2249
  furnitureGroup.add(obj);
2179
2250
 
@@ -2185,20 +2256,15 @@
2185
2256
  furniture.position.z
2186
2257
  );
2187
2258
 
2188
- console.log('🔧 [家具位置] furnitureGroup.position(世界位置):', furnitureGroup.position);
2189
-
2190
2259
  // 4. 应用旋转到Group(围绕Group原点,即家具中心)
2191
2260
  if (furniture.rotation.y) {
2192
2261
  furnitureGroup.rotation.y = furniture.rotation.y;
2193
- console.log('🔧 [家具旋转] 应用Y轴旋转:', furniture.rotation.y.toFixed(4), 'rad =', (furniture.rotation.y * 180 / Math.PI).toFixed(1) + '°');
2194
2262
  }
2195
2263
  if (furniture.rotation.x) {
2196
2264
  furnitureGroup.rotation.x = furniture.rotation.x;
2197
- console.log('🔧 [家具旋转] 应用X轴旋转:', furniture.rotation.x.toFixed(4), 'rad =', (furniture.rotation.x * 180 / Math.PI).toFixed(1) + '°');
2198
2265
  }
2199
2266
  if (furniture.rotation.z) {
2200
2267
  furnitureGroup.rotation.z = furniture.rotation.z;
2201
- console.log('🔧 [家具旋转] 应用Z轴旋转:', furniture.rotation.z.toFixed(4), 'rad =', (furniture.rotation.z * 180 / Math.PI).toFixed(1) + '°');
2202
2268
  }
2203
2269
 
2204
2270
  // 添加层级设置,确保家具在区域之上
@@ -2220,7 +2286,6 @@
2220
2286
  });
2221
2287
  }
2222
2288
 
2223
- console.log('✅ 家具模型加载成功(有旋转):', furniture.type);
2224
2289
  resolve(furnitureGroup);
2225
2290
  } else {
2226
2291
  // 无旋转时直接设置obj的世界位置
@@ -2231,8 +2296,6 @@
2231
2296
  furniture.position.z - scaledCenter.z
2232
2297
  );
2233
2298
 
2234
- console.log('🔧 [家具位置] obj.position(世界位置):', obj.position);
2235
-
2236
2299
  obj.renderOrder = 3000;
2237
2300
 
2238
2301
  // 应用颜色
@@ -2257,13 +2320,11 @@
2257
2320
  furnitureType: furniture.type
2258
2321
  };
2259
2322
 
2260
- console.log('✅ 家具模型加载成功(无旋转):', furniture.type);
2261
2323
  resolve(obj);
2262
2324
  }
2263
2325
  },
2264
2326
  undefined,
2265
2327
  function(error) {
2266
- console.error('❌ 家具模型加载失败:', furniture.type, error);
2267
2328
  reject(error);
2268
2329
  }
2269
2330
  );
@@ -2708,6 +2769,100 @@
2708
2769
  }
2709
2770
  };
2710
2771
 
2772
+ /**
2773
+ * 应用矩形/圆形/多边形透明度
2774
+ * @private
2775
+ */
2776
+ KimapSDK.prototype._applyShapeOpacity = function(kidataObj) {
2777
+ if (!kidataObj || !kidataObj.floors || !this.core || !this.core.scene) {
2778
+ console.log('[KimapSDK] _applyShapeOpacity: 缺少必要数据');
2779
+ return;
2780
+ }
2781
+
2782
+ console.log('[KimapSDK] 开始应用形状透明度...');
2783
+
2784
+ var shapeCount = 0;
2785
+ var shapesInKidata = [];
2786
+ var self = this;
2787
+
2788
+ // 收集kidata中的所有形状数据(rectangle, circle, polygon)
2789
+ kidataObj.floors.forEach(function(floor) {
2790
+ if (floor.layers) {
2791
+ floor.layers.forEach(function(layer) {
2792
+ if (layer.elements) {
2793
+ layer.elements.forEach(function(element) {
2794
+ if (element.type === 'rectangle' || element.type === 'circle' || element.type === 'polygon') {
2795
+ shapesInKidata.push({
2796
+ id: element.id,
2797
+ type: element.type,
2798
+ opacity: element.opacity !== undefined ? element.opacity : 0.9
2799
+ });
2800
+ }
2801
+ });
2802
+ }
2803
+ });
2804
+ }
2805
+ });
2806
+
2807
+ console.log('[KimapSDK] Kidata中形状数量:', shapesInKidata.length);
2808
+
2809
+ if (shapesInKidata.length === 0) {
2810
+ console.log('[KimapSDK] Kidata中没有形状数据');
2811
+ return;
2812
+ }
2813
+
2814
+ // 遍历场景中的所有对象,通过材质名称识别形状
2815
+ this.core.scene.traverse(function(object) {
2816
+ if (object instanceof THREE.Mesh && object.material) {
2817
+ var materialName = object.material.name || '';
2818
+
2819
+ // 通过材质名称识别形状(Shape_前缀)
2820
+ if (materialName.startsWith('Shape_')) {
2821
+ // 从材质名称中提取形状ID(格式:Shape_<type>_<id>)
2822
+ var parts = materialName.split('_');
2823
+ var shapeId = parts[parts.length - 1];
2824
+
2825
+ // 在kidata中查找对应的形状数据
2826
+ var shapeData = shapesInKidata.find(function(s) {
2827
+ return s.id === shapeId;
2828
+ });
2829
+
2830
+ if (shapeData) {
2831
+ var opacity = shapeData.opacity;
2832
+
2833
+ console.log('[KimapSDK] 应用形状透明度:', {
2834
+ id: shapeId,
2835
+ type: shapeData.type,
2836
+ opacity: opacity,
2837
+ materialName: materialName
2838
+ });
2839
+
2840
+ // 应用透明度到材质
2841
+ if (Array.isArray(object.material)) {
2842
+ object.material.forEach(function(mat) {
2843
+ mat.transparent = opacity < 1;
2844
+ mat.opacity = opacity;
2845
+ mat.needsUpdate = true;
2846
+ });
2847
+ } else {
2848
+ object.material.transparent = opacity < 1;
2849
+ object.material.opacity = opacity;
2850
+ object.material.needsUpdate = true;
2851
+ }
2852
+
2853
+ shapeCount++;
2854
+ }
2855
+ }
2856
+ }
2857
+ });
2858
+
2859
+ if (shapeCount > 0) {
2860
+ console.log('[KimapSDK] ✅ 应用形状透明度完成:', shapeCount, '个形状');
2861
+ } else {
2862
+ console.log('[KimapSDK] ⚠️ 未找到匹配的形状对象');
2863
+ }
2864
+ };
2865
+
2711
2866
  /**
2712
2867
  * 从kidata内容加载家具模型(不处理文本和墙体透明度)
2713
2868
  * @param {string} kidataContent - kidata文件内容(加密或未加密)
@@ -2725,27 +2880,21 @@
2725
2880
 
2726
2881
  // 如果kidata包含楼层数据,设置为projectLayers
2727
2882
  if (kidataObj.floors && Array.isArray(kidataObj.floors)) {
2728
- console.log('[KimapSDK] kidata包含楼层数据,楼层数量:', kidataObj.floors.length);
2729
2883
  if (!self.projectLayers && kidataObj.floors.length > 0) {
2730
2884
  self.projectLayers = kidataObj.floors[0].layers;
2731
- console.log('[KimapSDK] 从kidata设置楼层数据,图层数量:', self.projectLayers.length);
2732
2885
  }
2733
2886
  }
2734
2887
 
2735
- console.log('[KimapSDK] ✅ Kidata文件解密成功:', {
2736
- version: kidataObj.version,
2737
- furnitureCount: kidataObj.furnitures ? kidataObj.furnitures.length : 0,
2738
- floorCount: kidataObj.floors ? kidataObj.floors.length : 0
2739
- });
2740
-
2741
2888
  // 只加载3D家具模型
2742
2889
  return self._loadFurnitureModels(kidataObj)
2743
2890
  .then(function(result) {
2744
- console.log('[KimapSDK] ✅ 3D家具模型加载完成:', result);
2891
+ // 加载完成后应用形状透明度
2892
+ self._applyShapeOpacity(kidataObj);
2893
+
2745
2894
  return { success: true, loaded: result.loaded, failed: result.failed };
2746
2895
  });
2747
2896
  } catch (error) {
2748
- console.error('[KimapSDK] ❌ Kidata加载失败:', error);
2897
+ console.error('❌ Kidata加载失败:', error.message);
2749
2898
  return Promise.reject(error);
2750
2899
  }
2751
2900
  };
@@ -603,6 +603,60 @@ KimapSDK.prototype.getCoordinateSystem = function() {
603
603
  return this.core ? this.core.coordinateSystem : null;
604
604
  };
605
605
 
606
+ /**
607
+ * 自动调整相机视角,使其能够完整看到整个地图模型
608
+ * @param {Object} options - 配置选项
609
+ * @param {number} [options.distanceFactor=1.0] - 相机距离因子,值越小相机越近
610
+ * @param {number} [options.xFactor=0.5] - X轴偏移因子
611
+ * @param {number} [options.yFactor=0.4] - Y轴偏移因子(高度)
612
+ * @param {number} [options.zFactor=0.5] - Z轴偏移因子
613
+ */
614
+ KimapSDK.prototype.autoAdjustCamera = function(options) {
615
+ var self = this;
616
+
617
+ if (!self.core || !self.core.mapModel) {
618
+ console.warn('KimapSDK: 地图模型未加载,无法调整相机');
619
+ return;
620
+ }
621
+
622
+ var opts = options || {};
623
+ var distanceFactor = opts.distanceFactor !== undefined ? opts.distanceFactor : 1.0;
624
+ var xFactor = opts.xFactor !== undefined ? opts.xFactor : 0.5;
625
+ var yFactor = opts.yFactor !== undefined ? opts.yFactor : 0.4;
626
+ var zFactor = opts.zFactor !== undefined ? opts.zFactor : 0.5;
627
+
628
+ var box = new THREE.Box3().setFromObject(self.core.mapModel);
629
+ var center = new THREE.Vector3();
630
+ var size = new THREE.Vector3();
631
+
632
+ box.getCenter(center);
633
+ box.getSize(size);
634
+
635
+ var maxDim = Math.max(size.x, size.y, size.z);
636
+ var distance = maxDim * distanceFactor;
637
+
638
+ self.core.camera.position.set(
639
+ center.x + distance * xFactor,
640
+ center.y + distance * yFactor,
641
+ center.z + distance * zFactor
642
+ );
643
+
644
+ self.core.camera.lookAt(center);
645
+
646
+ if (self.core.controls) {
647
+ self.core.controls.target.copy(center);
648
+ self.core.controls.update();
649
+ }
650
+
651
+ console.log('KimapSDK: 相机已自动调整', {
652
+ center: center,
653
+ distance: distance,
654
+ size: size
655
+ });
656
+
657
+ return self;
658
+ };
659
+
606
660
  KimapSDK.prototype.getConfig = function() {
607
661
  var config = {};
608
662
 
@@ -684,8 +738,6 @@ KimapSDK.prototype.loadKMData = function() {
684
738
  var fileName = objUrl.split('/').pop().replace(/\.(obj|kimap)$/i, '');
685
739
  var kidataUrl = directory + '/' + fileName + '.kidata';
686
740
 
687
- console.log('📦 开始加载3D家具模型数据:', kidataUrl);
688
-
689
741
  return fetch(kidataUrl)
690
742
  .then(function(response) {
691
743
  if (!response.ok) {
@@ -703,31 +755,22 @@ KimapSDK.prototype.loadKMData = function() {
703
755
 
704
756
  // 如果kidata包含楼层数据,设置为projectLayers
705
757
  if (kidataObj.floors && Array.isArray(kidataObj.floors)) {
706
- console.log('KimapSDK: kidata包含楼层数据,楼层数量:', kidataObj.floors.length);
707
758
  // 设置第一个楼层为当前楼层(如果没有其他楼层数据)
708
759
  if (!self.projectLayers && kidataObj.floors.length > 0) {
709
760
  self.projectLayers = kidataObj.floors[0].layers;
710
- console.log('KimapSDK: 从kidata设置楼层数据,图层数量:', self.projectLayers.length);
711
761
  }
712
762
  }
713
763
 
714
- console.log('✅ Kidata文件解密成功:', {
715
- version: kidataObj.version,
716
- serverUrl: kidataObj.serverUrl,
717
- furnitureCount: kidataObj.furnitures ? kidataObj.furnitures.length : 0,
718
- floorCount: kidataObj.floors ? kidataObj.floors.length : 0
719
- });
720
-
721
764
  // 加载3D家具模型
722
765
  return self._loadFurnitureModels(kidataObj);
723
766
  })
724
767
  .then(function(result) {
725
- console.log('✅ 3D家具模型加载完成:', result);
768
+ console.log('✅ 家具加载完成:成功 ' + result.loaded + ' 个,失败 ' + result.failed + ' 个');
726
769
 
727
770
  return { success: true, loaded: result.loaded, failed: result.failed };
728
771
  })
729
772
  .catch(function(error) {
730
- console.error('❌ 加载3D家具模型失败:', error);
773
+ console.error('❌ 家具加载失败:', error.message);
731
774
  return { success: false, error: error.message };
732
775
  });
733
776
  };
@@ -787,8 +830,6 @@ KimapSDK.prototype._loadFurnitureModels = function(kidataObj) {
787
830
  var loadedCount = 0;
788
831
  var failedCount = 0;
789
832
 
790
- console.log('📦 开始加载', kidataObj.furnitures.length, '个家具模型');
791
-
792
833
  // 加载每个家具模型
793
834
  kidataObj.furnitures.forEach(function(furniture) {
794
835
  var promise = self._loadSingleFurniture(furniture, serverUrl)
@@ -801,7 +842,6 @@ KimapSDK.prototype._loadFurnitureModels = function(kidataObj) {
801
842
  }
802
843
  })
803
844
  .catch(function(error) {
804
- console.error('加载家具模型失败:', furniture.type, error);
805
845
  failedCount++;
806
846
  });
807
847
 
@@ -888,8 +928,6 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
888
928
  // GLTF/GLB格式返回的是gltf对象,需要提取scene
889
929
  var obj = (ext === '.glb' || ext === '.gltf') ? result.scene : result;
890
930
 
891
- console.log('🔧 [家具模型加载] 开始处理:', furniture.type);
892
-
893
931
  // ========== 修复1: 分别计算X、Y、Z轴的缩放因子 ==========
894
932
  // 计算模型的边界框
895
933
  var box = new THREE.Box3().setFromObject(obj);
@@ -918,16 +956,6 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
918
956
  var finalScaleY = scaleY * userScaleY;
919
957
  var finalScaleZ = scaleZ * userScaleZ;
920
958
 
921
- console.log('🔧 [家具缩放] 原始模型尺寸:', { x: size.x.toFixed(4), y: size.y.toFixed(4), z: size.z.toFixed(4) });
922
- console.log('🔧 [家具缩放] 目标尺寸:', { width: targetWidth.toFixed(4), height: targetHeight.toFixed(4), depth: targetDepth.toFixed(4) });
923
- console.log('🔧 [家具缩放] 缩放因子(预览一致):', { scaleX: scaleX.toFixed(4), scaleY: scaleY.toFixed(4), scaleZ: scaleZ.toFixed(4) });
924
- console.log('🔧 [家具缩放] 用户缩放:', { x: userScaleX, y: userScaleY, z: userScaleZ });
925
- console.log('🔧 [家具缩放] 最终缩放(预览一致):', {
926
- x: finalScaleX.toFixed(4),
927
- y: finalScaleY.toFixed(4),
928
- z: finalScaleZ.toFixed(4)
929
- });
930
-
931
959
  // 应用与预览一致的非等比缩放
932
960
  obj.scale.set(finalScaleX, finalScaleY, finalScaleZ);
933
961
 
@@ -950,11 +978,6 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
950
978
  var scaledBottomY = scaledBox.min.y;
951
979
  var elevation = furniture.position.y; // 离地高度(米)
952
980
 
953
- console.log('🔧 [家具] scaledCenter:', scaledCenter);
954
- console.log('🔧 [家具] scaledBottomY:', scaledBottomY);
955
- console.log('🔧 [家具] elevation:', elevation);
956
- console.log('🔧 [家具] furniture.position:', furniture.position);
957
-
958
981
  // ========== 旋转处理:使用Group包装(围绕家具中心旋转)==========
959
982
  var hasRotation = furniture.rotation && (
960
983
  furniture.rotation.x !== 0 ||
@@ -980,8 +1003,6 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
980
1003
  -scaledCenter.z
981
1004
  );
982
1005
 
983
- console.log('🔧 [家具位置] obj.position(中心偏移):', obj.position);
984
-
985
1006
  // 2. 将obj添加到Group
986
1007
  furnitureGroup.add(obj);
987
1008
 
@@ -993,21 +1014,16 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
993
1014
  furniture.position.z
994
1015
  );
995
1016
 
996
- console.log('🔧 [家具位置] furnitureGroup.position(世界位置):', furnitureGroup.position);
997
-
998
1017
  // 4. 应用旋转到Group(围绕Group原点,即家具中心)
999
1018
  // 注意:kidata JSON中 rotation 存储的是弧度值,直接使用
1000
1019
  if (furniture.rotation.y) {
1001
1020
  furnitureGroup.rotation.y = furniture.rotation.y;
1002
- console.log('🔧 [家具旋转] 应用Y轴旋转:', furniture.rotation.y.toFixed(4), 'rad =', (furniture.rotation.y * 180 / Math.PI).toFixed(1) + '°');
1003
1021
  }
1004
1022
  if (furniture.rotation.x) {
1005
1023
  furnitureGroup.rotation.x = furniture.rotation.x;
1006
- console.log('🔧 [家具旋转] 应用X轴旋转:', furniture.rotation.x.toFixed(4), 'rad =', (furniture.rotation.x * 180 / Math.PI).toFixed(1) + '°');
1007
1024
  }
1008
1025
  if (furniture.rotation.z) {
1009
1026
  furnitureGroup.rotation.z = furniture.rotation.z;
1010
- console.log('🔧 [家具旋转] 应用Z轴旋转:', furniture.rotation.z.toFixed(4), 'rad =', (furniture.rotation.z * 180 / Math.PI).toFixed(1) + '°');
1011
1027
  }
1012
1028
 
1013
1029
  // =====================================================
@@ -1028,12 +1044,6 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
1028
1044
  }
1029
1045
  });
1030
1046
 
1031
- console.log('[KimapSDK] ✅ 家具模型层级设置:', {
1032
- id: furniture.id,
1033
- renderOrder: furnitureGroup.renderOrder,
1034
- depthWriteDisabled: true
1035
- });
1036
-
1037
1047
  // 应用颜色
1038
1048
  if (furniture.color) {
1039
1049
  var color = new THREE.Color(furniture.color);
@@ -1050,7 +1060,6 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
1050
1060
  });
1051
1061
  }
1052
1062
 
1053
- console.log('✅ 家具模型加载成功(有旋转):', furniture.type);
1054
1063
  resolveLoad(furnitureGroup);
1055
1064
  } else {
1056
1065
  // 无旋转时直接设置obj的世界位置
@@ -1061,8 +1070,6 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
1061
1070
  furniture.position.z - scaledCenter.z
1062
1071
  );
1063
1072
 
1064
- console.log('🔧 [家具位置] obj.position(世界位置):', obj.position);
1065
-
1066
1073
  // =====================================================
1067
1074
  // 层级系统:解决多区域与3D家具叠加时的频闪问题
1068
1075
  // =====================================================
@@ -1092,13 +1099,6 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
1092
1099
  }
1093
1100
  });
1094
1101
 
1095
- console.log('[KimapSDK] ✅ 家具模型层级设置:', {
1096
- id: furniture.id,
1097
- renderOrder: obj.renderOrder,
1098
- yOffset: totalYOffset.toFixed(6) + 'm',
1099
- depthWriteDisabled: true
1100
- });
1101
-
1102
1102
  // 应用颜色
1103
1103
  if (furniture.color) {
1104
1104
  var color = new THREE.Color(furniture.color);
@@ -1121,7 +1121,6 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
1121
1121
  furnitureType: furniture.type
1122
1122
  };
1123
1123
 
1124
- console.log('✅ 家具模型加载成功(无旋转):', furniture.type);
1125
1124
  resolveLoad(obj);
1126
1125
  }
1127
1126
  },
@@ -1161,27 +1160,18 @@ KimapSDK.prototype.loadKidataForFurniture = function(kidataContent) {
1161
1160
 
1162
1161
  // 如果kidata包含楼层数据,设置为projectLayers
1163
1162
  if (kidataObj.floors && Array.isArray(kidataObj.floors)) {
1164
- console.log('[KimapSDK] kidata包含楼层数据,楼层数量:', kidataObj.floors.length);
1165
1163
  if (!self.projectLayers && kidataObj.floors.length > 0) {
1166
1164
  self.projectLayers = kidataObj.floors[0].layers;
1167
- console.log('[KimapSDK] 从kidata设置楼层数据,图层数量:', self.projectLayers.length);
1168
1165
  }
1169
1166
  }
1170
1167
 
1171
- console.log('[KimapSDK] ✅ Kidata文件解密成功:', {
1172
- version: kidataObj.version,
1173
- furnitureCount: kidataObj.furnitures ? kidataObj.furnitures.length : 0,
1174
- floorCount: kidataObj.floors ? kidataObj.floors.length : 0
1175
- });
1176
-
1177
1168
  // 只加载3D家具模型
1178
1169
  return self._loadFurnitureModels(kidataObj)
1179
1170
  .then(function(result) {
1180
- console.log('[KimapSDK] ✅ 3D家具模型加载完成:', result);
1181
1171
  return { success: true, loaded: result.loaded, failed: result.failed };
1182
1172
  });
1183
1173
  } catch (error) {
1184
- console.error('[KimapSDK] ❌ Kidata加载失败:', error);
1174
+ console.error('❌ Kidata加载失败:', error.message);
1185
1175
  return Promise.reject(error);
1186
1176
  }
1187
1177
  };
@@ -28,6 +28,7 @@ var extractMapConfigFromOBJ = parsers.extractMapConfigFromOBJ;
28
28
  var extractColorsFromOBJ = parsers.extractColorsFromOBJ;
29
29
  var extractTextElementsFromOBJ = parsers.extractTextElementsFromOBJ;
30
30
  var extractWallOpacityFromOBJ = parsers.extractWallOpacityFromOBJ;
31
+ var extractShapeOpacityFromOBJ = parsers.extractShapeOpacityFromOBJ;
31
32
 
32
33
  /**
33
34
  * SceneCore 构造函数
@@ -385,6 +386,13 @@ SceneCore.prototype._loadKimapFile = function(kimapUrl, themeUrl, objLoader, mtl
385
386
  console.log('[SceneCore] ✅ 从OBJ提取到墙体透明度:', Object.keys(wallOpacity).length, '个墙体');
386
387
  self._wallOpacity = wallOpacity;
387
388
  }
389
+
390
+ // 提取形状透明度信息(矩形、圆形、多边形)
391
+ var shapeOpacity = extractShapeOpacityFromOBJ(objContent);
392
+ if (shapeOpacity && Object.keys(shapeOpacity).length > 0) {
393
+ console.log('[SceneCore] ✅ 从OBJ提取到形状透明度:', Object.keys(shapeOpacity).length, '个形状');
394
+ self._shapeOpacity = shapeOpacity;
395
+ }
388
396
 
389
397
  // 解析OBJ内容
390
398
  var object = objLoader.parse(objContent);
@@ -627,11 +635,17 @@ SceneCore.prototype._processMaterial = function(child, materials, colorMap) {
627
635
  } else if (child.material.name.startsWith('Shape_') || child.material.name.startsWith('Stair_')) {
628
636
  roughness = 0.6;
629
637
  metalness = 0;
630
- // 保持从MTL中获取的真实透明度
631
- if (opacity === 1.0) {
632
- opacity = 0.9;
638
+ // 从OBJ提取的形状透明度数据中读取
639
+ if (self._shapeOpacity) {
640
+ var shapeId = child.material.name.replace('Shape_', '').replace(/^rectangle_/, '').replace(/^circle_/, '').replace(/^polygon_/, '');
641
+ if (self._shapeOpacity[shapeId]) {
642
+ opacity = self._shapeOpacity[shapeId].opacity;
643
+ transparent = opacity < 1.0;
644
+ // 高透明度时关闭depthWrite
645
+ depthWrite = opacity >= 0.8;
646
+ console.log('[SceneCore] 应用形状透明度:', shapeId, '=', opacity);
647
+ }
633
648
  }
634
- transparent = opacity < 1.0;
635
649
  // 混合10%白色,让颜色更浅一点
636
650
  var color = new THREE.Color(mtlColor);
637
651
  color.lerp(new THREE.Color(0xffffff), 0.1);
@@ -213,11 +213,46 @@ function extractWallOpacityFromOBJ(objContent) {
213
213
  return wallOpacity;
214
214
  }
215
215
 
216
+ /**
217
+ * 从OBJ内容中提取形状透明度信息(矩形、圆形、多边形)
218
+ * 格式: # SHAPE_OPACITY 0.9
219
+ */
220
+ function extractShapeOpacityFromOBJ(objContent) {
221
+ var shapeOpacity = {};
222
+ var lines = objContent.split('\n');
223
+ var currentShapeId = null;
224
+ var currentShapeType = null;
225
+
226
+ for (var i = 0; i < lines.length; i++) {
227
+ var line = lines[i].trim();
228
+
229
+ if (line.indexOf('o Shape_') === 0) {
230
+ // 提取形状ID和类型(格式:Shape_<type>_<id>)
231
+ var match = line.match(/Shape_([^_]+)_(.+)/);
232
+ if (match) {
233
+ currentShapeType = match[1];
234
+ currentShapeId = match[2];
235
+ }
236
+ } else if (currentShapeId && line.indexOf('# SHAPE_OPACITY') === 0) {
237
+ var opacity = parseFloat(line.split(' ')[2]);
238
+ if (!shapeOpacity[currentShapeId]) {
239
+ shapeOpacity[currentShapeId] = {};
240
+ }
241
+ shapeOpacity[currentShapeId].opacity = opacity;
242
+ shapeOpacity[currentShapeId].type = currentShapeType;
243
+ }
244
+ }
245
+
246
+ console.log('[Parsers] 提取到的形状透明度:', Object.keys(shapeOpacity).length, '个形状');
247
+ return shapeOpacity;
248
+ }
249
+
216
250
  module.exports = {
217
251
  extractBorderFromOBJ: extractBorderFromOBJ,
218
252
  extractMapConfigFromOBJ: extractMapConfigFromOBJ,
219
253
  extractColorsFromOBJ: extractColorsFromOBJ,
220
254
  extractCoordinateSystem: extractCoordinateSystem,
221
255
  extractTextElementsFromOBJ: extractTextElementsFromOBJ,
222
- extractWallOpacityFromOBJ: extractWallOpacityFromOBJ
256
+ extractWallOpacityFromOBJ: extractWallOpacityFromOBJ,
257
+ extractShapeOpacityFromOBJ: extractShapeOpacityFromOBJ
223
258
  };