文章目录
前言
代码地址 : https://gitee.com/txcst/3-dmap.git 只想好好做开源。
上一期我们已经把地图构建好了,现在我们给地图添加一些模型和精灵
一、如何引入外部模型
1.three.js想要使用模型,需要使用加载器,它本身内置了很多加载器,在 ‘three/examples/jsm/loaders/’ 地址下,可以根据自己的需要去找,简单介绍几个常用的加载器,
- TextureLoader(),纹理加载器,加载一张图片,返回的是纹理
- GLTFLoader(),gltl模型加载器,会返回一个gltf模型对象,
- FileLoader(),文件加载器,返回字符串
2.加载模型,打算在北京放置一个故宫的模型,在sketchfab白嫖了一个免费的模型,我们把他下载到本地,现在我们要开始处理两件事
- 获取北京的地图坐标
- 引入模型放置到北京的坐标上
先获取坐标
我们来到generateGeometry方法,再循环坐标处,增加一个筛选,添加到special数组里
jsondata.features.forEach((elem) => {
if (
elem.properties.name == "陕西省" ||
elem.properties.name == "北京市"
) {
let obj = {
name: elem.properties.name,
arr: [projection(elem.properties.center)],
};
special.push(obj);
}
引入模型
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
注意,gltf模型的scene是我们要使用到,我们调整模型的坐标轴和角度和大小,使他贴到地图上,然后加到地图的map对象里,记住要加到地图的对象里,不要直接加在scene里,这样会使坐标对不上
- position:模型坐标方位
- rotation:模型的角度
- scale:模型的大小
//获取故宫的模型
GetGLTFLoader(x, y, z) {
const loader = new GLTFLoader();
//加载模型文件,返回gltf对象
loader.load("/data/gugong.glb", function (gltf) {
gltf.scene.scale.set(0.02, 0.02, 0.02);
gltf.scene.position.set(x, y, z);
gltf.scene.rotation.x = 1.5;
gltf.scene.rotation.y = 1.5;
map.add(gltf.scene);
});
},
设置到北京坐标的位置
getSpiritAndGltf() {
// let spriteMaterial;
// let bingmayong = new THREE.TextureLoader().load("/data/bingmayong.png");
special.forEach((item, index) => {
switch (item.name) {
case "北京市":
this.GetGLTFLoader(item.arr[0][0], item.arr[0][1], 8);
break;
}
});
},
设置光源,如果没有光源的照射 ,模型将漆黑一片
setLight() {
ambientLight = new THREE.AmbientLight(0xffffff); // 环境光
//平行光 用来照亮地图
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(20, 20, 20);
scene.add(directionalLight);
//平行光灯光辅助器,可以看见灯光的位置
const lightHelper = new THREE.DirectionalLightHelper(directionalLight);
scene.add(lightHelper);
// scene.add(ambientLight)
},
引入成功
二、添加sprite(精灵)
sprite的特点,他总会面对着摄像机,你往哪里移动,它朝向哪里,跟向阳花一样
getSpiritAndGltf() {
let spriteMaterial;
//使用纹理加载器加载图片作为纹理使用
let bingmayong = new THREE.TextureLoader().load("/data/bingmayong.png");
special.forEach((item, index) => {
switch (item.name) {
case "北京市":
this.GetGLTFLoader(item.arr[0][0], item.arr[0][1], 8);
break;
//在前面获取坐标的时候顺带获取别的坐标
case "陕西省":
//创建精灵贴图
spriteMaterial = new THREE.SpriteMaterial({
map: bingmayong,
transparent: true,
});
//创建精灵,调整位置
let sprite = new THREE.Sprite(spriteMaterial);
sprite.position.set(item.arr[0][0], item.arr[0][1], 8);
sprite.scale.set(8, 8, 8);
sprite.name="bingmayong"
map.add(sprite);
break;
}
});
},
效果:
总结
当前我们已经引入了模型和sprite,下期我们将使用射线,去做一些交互。