@kimap/indoor-positioning-sdk-vue2 4.2.1 → 4.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 +1 -1
- package/src/core/KimapSDK.js +131 -30
- package/src/core/loaders.js +21 -1
package/package.json
CHANGED
package/src/core/KimapSDK.js
CHANGED
|
@@ -10,6 +10,9 @@ var SceneCore = require('./SceneCore.js');
|
|
|
10
10
|
// THREE.js 将在运行时加载
|
|
11
11
|
var THREE = null;
|
|
12
12
|
var loadThree = loaders.loadThree;
|
|
13
|
+
var loadOBJLoader = loaders.loadOBJLoader;
|
|
14
|
+
var loadFBXLoader = loaders.loadFBXLoader;
|
|
15
|
+
var loadGLTFLoader = loaders.loadGLTFLoader;
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* KimapSDK 构造函数
|
|
@@ -140,7 +143,98 @@ KimapSDK.prototype.startRenderLoop = function() {
|
|
|
140
143
|
* @private
|
|
141
144
|
*/
|
|
142
145
|
KimapSDK.prototype._extractWallsFromModel = function() {
|
|
143
|
-
|
|
146
|
+
var self = this;
|
|
147
|
+
|
|
148
|
+
if (!self.core || !self.core.mapModel) {
|
|
149
|
+
console.warn('KimapSDK: 3D模型未加载,无法提取墙面数据');
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
var walls = [];
|
|
154
|
+
var floorGroups = {};
|
|
155
|
+
|
|
156
|
+
// 遍历场景中的所有对象,查找墙面
|
|
157
|
+
self.core.mapModel.traverse(function(child) {
|
|
158
|
+
if (child.name && child.name.startsWith('Wall_')) {
|
|
159
|
+
var box = new THREE.Box3().setFromObject(child);
|
|
160
|
+
var min = box.min;
|
|
161
|
+
var max = box.max;
|
|
162
|
+
|
|
163
|
+
var centerX = (min.x + max.x) / 2;
|
|
164
|
+
var centerZ = (min.z + max.z) / 2;
|
|
165
|
+
var width = max.x - min.x;
|
|
166
|
+
var depth = max.z - min.z;
|
|
167
|
+
var height = max.y - min.y;
|
|
168
|
+
|
|
169
|
+
var isHorizontal = width > depth;
|
|
170
|
+
var thickness = isHorizontal ? depth : width;
|
|
171
|
+
|
|
172
|
+
var points;
|
|
173
|
+
if (isHorizontal) {
|
|
174
|
+
points = [
|
|
175
|
+
{ x: min.x * 100, y: centerZ * 100 },
|
|
176
|
+
{ x: max.x * 100, y: centerZ * 100 }
|
|
177
|
+
];
|
|
178
|
+
} else {
|
|
179
|
+
points = [
|
|
180
|
+
{ x: centerX * 100, y: min.z * 100 },
|
|
181
|
+
{ x: centerX * 100, y: max.z * 100 }
|
|
182
|
+
];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
var floorLevel = Math.floor(min.y / 3);
|
|
186
|
+
|
|
187
|
+
var wallData = {
|
|
188
|
+
type: 'wall',
|
|
189
|
+
id: child.name,
|
|
190
|
+
visible: true,
|
|
191
|
+
passable: false,
|
|
192
|
+
points: points,
|
|
193
|
+
thickness: thickness * 1000,
|
|
194
|
+
height: height * 1000,
|
|
195
|
+
floorLevel: floorLevel
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
walls.push(wallData);
|
|
199
|
+
|
|
200
|
+
if (!floorGroups[floorLevel]) {
|
|
201
|
+
floorGroups[floorLevel] = [];
|
|
202
|
+
}
|
|
203
|
+
floorGroups[floorLevel].push(wallData);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
console.log('✅ 从3D模型中提取墙面数据:', walls.length, '个墙面');
|
|
208
|
+
|
|
209
|
+
var floors = [];
|
|
210
|
+
Object.keys(floorGroups).sort().forEach(function(level) {
|
|
211
|
+
var floorId = 'floor_' + level;
|
|
212
|
+
var floorName = (parseInt(level) + 1) + '楼';
|
|
213
|
+
|
|
214
|
+
floors.push({
|
|
215
|
+
id: floorId,
|
|
216
|
+
name: floorName,
|
|
217
|
+
level: parseInt(level),
|
|
218
|
+
height: 3000,
|
|
219
|
+
elevation: parseInt(level) * 3000,
|
|
220
|
+
isDefault: level === '0',
|
|
221
|
+
layers: [
|
|
222
|
+
{
|
|
223
|
+
id: floorId + '_layer_walls',
|
|
224
|
+
name: '墙体图层',
|
|
225
|
+
visible: true,
|
|
226
|
+
elements: floorGroups[level]
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
if (floors.length > 0) {
|
|
233
|
+
self.setFloors(floors);
|
|
234
|
+
console.log('✅ 已自动设置楼层数据(从3D模型提取)');
|
|
235
|
+
} else {
|
|
236
|
+
console.warn('⚠️ 未从3D模型中提取到墙面数据');
|
|
237
|
+
}
|
|
144
238
|
};
|
|
145
239
|
|
|
146
240
|
// ==================== DOM 标记相关方法 ====================
|
|
@@ -306,19 +400,7 @@ KimapSDK.prototype.getDrawPoints = function() {
|
|
|
306
400
|
};
|
|
307
401
|
|
|
308
402
|
// ==================== 3D 模型加载相关方法 ====================
|
|
309
|
-
//
|
|
310
|
-
// 为了保持文件精简,这里只保留核心方法签名
|
|
311
|
-
// 完整实现请参考原 KimapCore.js 文件
|
|
312
|
-
|
|
313
|
-
KimapSDK.prototype.loadKidata = function(kidataUrl) {
|
|
314
|
-
// 实现:加载 kidata 文件
|
|
315
|
-
// 原代码约 200 行
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
KimapSDK.prototype._loadFurnitureModels = function() {
|
|
319
|
-
// 实现:加载家具 3D 模型
|
|
320
|
-
// 原代码约 150 行
|
|
321
|
-
};
|
|
403
|
+
// loadKidata 和 _loadFurnitureModels 的完整实现在文件后面部分
|
|
322
404
|
|
|
323
405
|
// ==================== 楼层管理相关方法 ====================
|
|
324
406
|
|
|
@@ -747,19 +829,34 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
|
|
|
747
829
|
}
|
|
748
830
|
|
|
749
831
|
var modelUrl;
|
|
750
|
-
var
|
|
832
|
+
var loaderPromise;
|
|
751
833
|
|
|
752
|
-
|
|
834
|
+
// 根据文件扩展名选择合适的loader
|
|
835
|
+
if (ext === '.fbx') {
|
|
753
836
|
modelUrl = baseUrl + '/' + furniture.type + '/' + id + ext;
|
|
754
|
-
|
|
837
|
+
loaderPromise = loadFBXLoader().then(function(FBXLoader) {
|
|
838
|
+
return new FBXLoader();
|
|
839
|
+
});
|
|
840
|
+
} else if (ext === '.glb' || ext === '.gltf') {
|
|
841
|
+
modelUrl = baseUrl + '/' + furniture.type + '/' + id + ext;
|
|
842
|
+
loaderPromise = loadGLTFLoader().then(function(GLTFLoader) {
|
|
843
|
+
return new GLTFLoader();
|
|
844
|
+
});
|
|
755
845
|
} else {
|
|
846
|
+
// 默认使用OBJ格式
|
|
756
847
|
modelUrl = baseUrl + '/' + furniture.type + '/' + id + '.obj';
|
|
757
|
-
|
|
848
|
+
loaderPromise = loadOBJLoader().then(function(OBJLoader) {
|
|
849
|
+
return new OBJLoader();
|
|
850
|
+
});
|
|
758
851
|
}
|
|
759
|
-
|
|
760
|
-
loader
|
|
761
|
-
|
|
762
|
-
|
|
852
|
+
|
|
853
|
+
// 等待loader加载完成后再加载模型
|
|
854
|
+
loaderPromise.then(function(loader) {
|
|
855
|
+
loader.load(
|
|
856
|
+
modelUrl,
|
|
857
|
+
function(result) {
|
|
858
|
+
// GLTF/GLB格式返回的是gltf对象,需要提取scene
|
|
859
|
+
var obj = (ext === '.glb' || ext === '.gltf') ? result.scene : result;
|
|
763
860
|
// 应用旋转
|
|
764
861
|
obj.rotation.set(
|
|
765
862
|
furniture.rotation.x,
|
|
@@ -825,14 +922,18 @@ KimapSDK.prototype._loadSingleFurniture = function(furniture, serverUrl) {
|
|
|
825
922
|
furnitureType: furniture.type
|
|
826
923
|
};
|
|
827
924
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
925
|
+
resolve(obj);
|
|
926
|
+
},
|
|
927
|
+
undefined,
|
|
928
|
+
function(error) {
|
|
929
|
+
console.error('❌ 家具模型加载失败:', furniture.type, error);
|
|
930
|
+
reject(error);
|
|
931
|
+
}
|
|
932
|
+
);
|
|
933
|
+
}).catch(function(error) {
|
|
934
|
+
console.error('❌ 加载家具模型loader失败:', furniture.type, error);
|
|
935
|
+
reject(error);
|
|
936
|
+
});
|
|
836
937
|
});
|
|
837
938
|
};
|
|
838
939
|
|
package/src/core/loaders.js
CHANGED
|
@@ -108,11 +108,31 @@ function loadMTLLoader() {
|
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
/**
|
|
112
|
+
* 加载GLTFLoader
|
|
113
|
+
*/
|
|
114
|
+
function loadGLTFLoader() {
|
|
115
|
+
return new Promise(function(resolve, reject) {
|
|
116
|
+
if (!THREE) {
|
|
117
|
+
reject(new Error('Three.js未初始化,请先调用loadThree()'));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
var module = require('three/examples/jsm/loaders/GLTFLoader.js');
|
|
123
|
+
resolve(module.GLTFLoader);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
reject(new Error('Failed to load GLTFLoader: ' + error.message));
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
111
130
|
module.exports = {
|
|
112
131
|
setThreeInstance: setThreeInstance,
|
|
113
132
|
loadThree: loadThree,
|
|
114
133
|
loadOrbitControls: loadOrbitControls,
|
|
115
134
|
loadOBJLoader: loadOBJLoader,
|
|
116
135
|
loadFBXLoader: loadFBXLoader,
|
|
117
|
-
loadMTLLoader: loadMTLLoader
|
|
136
|
+
loadMTLLoader: loadMTLLoader,
|
|
137
|
+
loadGLTFLoader: loadGLTFLoader
|
|
118
138
|
};
|