凯~
文章11
标签12
分类4
如何建立一个室内3d导航项目(三)- mapbox引入模型

如何建立一个室内3d导航项目(三)- mapbox引入模型

如何建立一个室内3d导航项目(三)- mapbox引入模型

上一篇我们创建了mapbox工程,接下来笔者会介绍如何引入3d模型

一、库的选择

mapbox旧版并没有直接引入模型的办法,查找资料发现threebox库可以直接引入模型,但这个库已经停止维护了,笔者经过测试也无法正常使用,网上查到的各种示例代码基本都是有问题的

image-20250422160057191

好在有热心网友提供了兼容的fork版本

image-20250422160302391

链接如下

https://github.com/jscastro76/threebox

按照文档直接安装

1
npm install threebox-plugin

二、引入库

1
import { Threebox } from 'threebox-plugin'; 

三、加载模型

根据文档,在地图初始化时加载模型,以glb模型为例(其他模型请查看文档)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//初始化控制模型显示隐藏的标志
const preloadedModels = {};

//控制指定id模型的显示,并隐藏其他模型
const toggleModelVisibility = (id) => {
Object.keys(preloadedModels).forEach((key) => {
const model = preloadedModels[key];
if (key === id) {
model.hidden = false;
} else {
model.hidden = true;
}
});
};

//多个模型的初始化参数
const floors = [
{
drawableName: "model0",
model: true,
rotation: {
x: 90,
y: -155.54446027115023,
z: 0,
},
scale: 5.66,
modelCoords: [121, 31, 2],
},
{
drawableName: "model1",
model: false,
rotation: {
x: 0,
y: 0,
z: 0,
},
scale: 1,
modelCoords: [0, 0, 0],
},
{
drawableName: "model2",
model: true,
rotation: {
x: 90,
y: -154.54739701601238,
z: 0,
},
scale: 10.03,
modelCoords: [121, 31, 4],
},
{
drawableName: "model3",
model: false,
rotation: {
x: 0,
y: 0,
z: 0,
},
scale: 1,
modelCoords: [0, 0, 0],
},
]

//批量加载模型函数
const preloadModels = (onComplete) => {
let loadedCount = 0;
const total = floors.length;

floors.forEach(({ drawableName, scale, modelCoords, rotation }) => {
const newModelUrl = './model/' + PROJ + '/' + drawableName + '.glb';
const options = {
id: drawableName,
obj: newModelUrl,
type: 'gltf',
scale: scale,
units: 'meters',
};

tb.loadObj(options, (model) => {
model.setCoords(modelCoords);//设置模型经纬度
model.setRotation(rotation);//设置旋转角度
window.tb.add(model);
preloadedModels[drawableName] = model;//将模型对象放入preloadedModels以便后续控制

model.hidden = true;//加载模型后隐藏该模型

// 每个模型加载完成后检查进度
loadedCount++;
if(loadedCount === total && onComplete) {
onComplete(); // 全部加载完成时执行回调
}
});
});
};

//地图初始化时批量加载模型
mapInstance.on('load', async () => {

mapInstance.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function(map, mbxContext) {
window.tb = new Threebox(map, mbxContext, {
defaultLights: true,
antialias: true,
});
window.tb.enableSelectingObjects = true; //允许拾取对象,值为false的情况下点击获取不到gltf

// 调用时传入回调函数
preloadModels(() => {
console.log('所有模型加载完成!');

});
},
render: function(gl, matrix) {
tb.update();
}
});



});

以下是模型加载后的效果

image-20250422164404664

可能有人要问,如何确定模型的初始化参数,这需要我们搞清楚模型坐标和经纬度之间的关系,先确定一个旋转角度,然后手动平移缩放调整便可,可以参考我另一篇文章Three.js下的经纬度坐标转换

四、结束语

根据以上代码,我们可以轻松地批量加载模型到mapbox地图上指定经纬度的位置,并可以在后续控制这些模型的显示隐藏等。

本文作者:凯~
本文链接:https://blog.diyultra.top/2025/04/22/07navi3d3/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×