@kimap/indoor-positioning-sdk-vue2 4.2.1 → 4.2.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 +1 -1
- package/src/core/KimapSDK.js +131 -30
- package/src/core/SceneCore.js +38 -18
- 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/SceneCore.js
CHANGED
|
@@ -405,27 +405,47 @@ SceneCore.prototype._loadKimapFile = function(kimapUrl, themeUrl, objLoader, mtl
|
|
|
405
405
|
SceneCore.prototype._loadOBJFile = function(url, objLoader, resolve, reject) {
|
|
406
406
|
var self = this;
|
|
407
407
|
|
|
408
|
-
console.log('加载OBJ文件...');
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
function(
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if (
|
|
419
|
-
|
|
420
|
-
console.log('OBJ加载进度:', percent + '%');
|
|
408
|
+
console.log('加载OBJ文件...', url);
|
|
409
|
+
|
|
410
|
+
// 先验证URL是否返回正确的内容
|
|
411
|
+
fetch(url, { method: 'HEAD' })
|
|
412
|
+
.then(function(response) {
|
|
413
|
+
if (!response.ok) {
|
|
414
|
+
throw new Error('文件不存在或无法访问 (HTTP ' + response.status + ')');
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
var contentType = response.headers.get('content-type');
|
|
418
|
+
if (contentType && contentType.includes('text/html')) {
|
|
419
|
+
throw new Error('URL返回的是HTML页面而不是OBJ文件,请检查URL是否正确');
|
|
421
420
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
421
|
+
|
|
422
|
+
// URL验证通过,开始加载
|
|
423
|
+
objLoader.load(
|
|
424
|
+
url,
|
|
425
|
+
function(object) {
|
|
426
|
+
console.log('OBJ文件下载完成,开始处理...');
|
|
427
|
+
self._processLoadedModel(object, null, {});
|
|
428
|
+
resolve();
|
|
429
|
+
},
|
|
430
|
+
function(progress) {
|
|
431
|
+
if (progress.lengthComputable) {
|
|
432
|
+
var percent = (progress.loaded / progress.total * 100).toFixed(2);
|
|
433
|
+
console.log('OBJ加载进度:', percent + '%');
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
function(error) {
|
|
437
|
+
console.error('❌ OBJ文件加载失败:', error);
|
|
438
|
+
console.error('URL:', url);
|
|
439
|
+
reject(error);
|
|
440
|
+
}
|
|
441
|
+
);
|
|
442
|
+
})
|
|
443
|
+
.catch(function(error) {
|
|
444
|
+
console.error('❌ OBJ文件URL验证失败:', error.message);
|
|
425
445
|
console.error('URL:', url);
|
|
446
|
+
console.error('提示: 请确保URL指向有效的.obj文件');
|
|
426
447
|
reject(error);
|
|
427
|
-
}
|
|
428
|
-
);
|
|
448
|
+
});
|
|
429
449
|
};
|
|
430
450
|
|
|
431
451
|
/**
|
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
|
};
|