Threejs 创建一个虚拟城市三维场景

简介: Threejs 创建一个虚拟城市三维场景

前情回顾

前几篇文章大概讲述了threejs如何创建场景,创建几何体,纹理贴图等...

本篇文章主要讲述threejs如何去搭建一个智慧城市虚拟场景(主要讲述如何去加载模型以及加载贴图)

开发前准备

1. 从官方下载threejs的包,引入到项目中2. 智慧城市模型一份( 本篇文章主要加载的 OBJ + MTL )
3. 具备前几章节讲到的一些基础知识(如果还不会的话请看前几篇文章哦)4. 学习了解 MTLLoader.js 和 OBJLoader.js (加载模型主要用到这两个js)
5. vue 基础 ( 本人做的所有实例都是基于vue来开发的 )

先看一波效果吧 :image.png主要代码如下所示:
1. 引入 MTLLoader.js 和 OBJLoader.js 文件


// MTLimport { MTLLoader } from "../threeLibs/loaders/MTLLoader.js";// ObjLoaderimport { OBJLoader } from "../threeLibs/loaders/OBJLoader.js";

2. 参考官方的例子,首先加载MTL,再去加载对应的OBJ; 这里由于模型比较多,每一个都写一次加载感觉比较麻烦,所以对加载的方法做了封装,具体代码如下:


// 模型按照数组的方式一一对应const list = [        // 一般建筑模型        ["./city/ny1.mtl", "./city/ny1.obj"],        ["./city/ny2.mtl", "./city/ny2.obj"],        ["./city/ny3.mtl", "./city/ny3.obj"],        ["./city/ny4.mtl", "./city/ny4.obj"],        ["./city/ny5.mtl", "./city/ny5.obj"],        ["./city/ny6.mtl", "./city/ny6.obj"],        ["./city/ny7.mtl", "./city/ny7.obj"],        ["./city/ny8.mtl", "./city/ny8.obj"],      ];
      const list2 = [        // 其他模型        ["./city/multi_storied_01.mtl", "./city/multi_storied_01.obj"],        ["./city/triangle_01.mtl", "./city/triangle_01.obj"],        ["./city/white_house.mtl", "./city/white_house.obj"],      ];            // 加载方法封装      // 加载MTL OBJ    MOLoader(group, list) {      list.forEach((urlList) => {        const mtlLoader = new MTLLoader();        const objLoader = new OBJLoader();        mtlLoader.load(urlList[0], (materials) => {          materials.preload();          //实例化obj加载方法          //设置mtl文件的材质          objLoader.setMaterials(materials);          //文件名          objLoader.load(urlList[1], (object) => {            object.position.set(6691, 604.35216, 2154.6111);            group.add(object);          });        });      });    },

3. 按照分组的方式加载模型,具体 api 方法自行查阅官方文档 :  http://www.webgl3d.cn/threejs/docs/


// 执行加载方法this.building = new THREE.Group();this.othersBuilding = new THREE.Group();this.scene.add(this.building);this.scene.add(this.othersBuilding);
this.MOLoader(this.building, list);this.MOLoader(this.othersBuilding, list2);


完整代码如下:


<template>  <div class>    <div ref="content" style="position: absolute;top:0;left:0;right:0;bottom: 0;overflow: hidden"></div>    <div class style="position: fixed;z-index: 999;background: #fff">      <span class="btn" @click="getCameraPosition">获取相机位置</span>    </div>  </div></template>
<script>// 引入threejsimport * as THREE from "../threeLibs/three.module.js";//鼠标控制import { OrbitControls } from "../threeLibs/controls/OrbitControls.js";// MTLimport { MTLLoader } from "../threeLibs/loaders/MTLLoader.js";// ObjLoaderimport { OBJLoader } from "../threeLibs/loaders/OBJLoader.js";
export default {  components: {},  data() {    return {      // 创建一个场景      scene: null,      // 创建一个相机      camera: null,      // 创建一个渲染器      renderer: null,      // 模型对象      mesh: null,      // 平面      plane: null,      // 点光源      point: null,
      // step      step: 0,
      building: undefined,      othersBuilding: undefined,    };  },
  mounted() {    this.init();  },  methods: {    // 初始化    init() {      // 初始化容器      var content = this.$refs.content;
      // 创建一个场景      this.scene = new THREE.Scene();      this.scene.background = new THREE.Color("#000");      this.scene.updateMatrixWorld(true);
      // 创建几何体      //   var geometry = new THREE.SphereGeometry(30, 50, 50);      // // 纹理加载器 ( 此处加载贴图 )      // // var texture = new THREE.TextureLoader().load(require('./Earth.png'));
      //   // 几何体材质对象      //   var material = new THREE.MeshLambertMaterial({      //       color:"#000"      //   });
      //   // 创建网格模型对象      //   this.mesh = new THREE.Mesh(geometry, material);      //   //设置几何体位置      //   this.mesh.position.x = 0;      //   this.mesh.position.y = 10;      //   this.mesh.position.z = 0;      //   this.scene.add(this.mesh);
      //创建环境光      var ambient = new THREE.AmbientLight(0xffffff);      this.scene.add(ambient);
      const directionalLight = new THREE.DirectionalLight(0xffffff, 2);      directionalLight.position.set(50, 25, 10);      directionalLight.castShadow = true;      this.scene.add(directionalLight);
      // 创建一个相机      this.camera = new THREE.PerspectiveCamera(        70,        window.innerWidth / window.innerHeight,        1,        1000000      );      this.camera.position.set(6691, 604.35216, 2154.6111);
      //照相机帮助线      // var cameraHelper = new THREE.CameraHelper( this.camera);      // this.scene.add(cameraHelper);
      //坐标轴辅助器,X,Y,Z长度30      // var axes = new THREE.AxesHelper(3000);      // this.scene.add(axes);      // 辅助网格      // let gridHelper = new THREE.GridHelper(3000, 3000);      // this.scene.add(gridHelper);
      // 创建一个平面      const planeGeometry = new THREE.PlaneGeometry(6000, 6000);      const planeMaterial = new THREE.MeshLambertMaterial({        color: 0xffffff,        side: THREE.DoubleSide, //两面 // THREE.FrontSide 、THREE.BackSide      });      const plane = new THREE.Mesh(planeGeometry, planeMaterial);      //水平面旋转并且设置位置      plane.rotation.x = -0.5 * Math.PI;      plane.position.x = 0;      plane.position.y = 0;      plane.position.z = 0;      // this.scene.add(plane);
      // 创建渲染器      this.renderer = new THREE.WebGLRenderer({        // 开启抗锯齿        antialias: true,        // 开启背景透明        alpha: true,      });      this.renderer.setSize(window.innerWidth, window.innerHeight);      //插入 dom 元素      content.appendChild(this.renderer.domElement);
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      // this.controls.target.set(-8148, -604, -3919)
      // this.camera.position.set(-10176, 1666, -1674)      this.camera.position.set(6691, 604.35216, 2154.6111);
      const list = [        // 一般建筑模型        ["./city/ny1.mtl", "./city/ny1.obj"],        ["./city/ny2.mtl", "./city/ny2.obj"],        ["./city/ny3.mtl", "./city/ny3.obj"],        ["./city/ny4.mtl", "./city/ny4.obj"],        ["./city/ny5.mtl", "./city/ny5.obj"],        ["./city/ny6.mtl", "./city/ny6.obj"],        ["./city/ny7.mtl", "./city/ny7.obj"],        ["./city/ny8.mtl", "./city/ny8.obj"],      ];
      const list2 = [        // 其他模型        ["./city/multi_storied_01.mtl", "./city/multi_storied_01.obj"],        ["./city/triangle_01.mtl", "./city/triangle_01.obj"],        ["./city/white_house.mtl", "./city/white_house.obj"],      ];
      this.building = new THREE.Group();      this.othersBuilding = new THREE.Group();      this.scene.add(this.building);      this.scene.add(this.othersBuilding);
      this.MOLoader(this.building, list);      // this.MOLoader(this.othersBuilding, list2)
      const t = this;      function render() {        t.controls.update();        t.renderer.render(t.scene, t.camera);        requestAnimationFrame(render);      }      render();    },
    // 加载MTL OBJ    MOLoader(group, list) {      list.forEach((urlList) => {        const mtlLoader = new MTLLoader();        const objLoader = new OBJLoader();        mtlLoader.load(urlList[0], (materials) => {          materials.preload();          //实例化obj加载方法          //设置mtl文件的材质          objLoader.setMaterials(materials);          //文件名          objLoader.load(urlList[1], (object) => {            object.position.set(6691, 604.35216, 2154.6111);            group.add(object);          });        });      });    },
    getCameraPosition() {      console.log("控制器中心", this.controls.target);      console.log("相机位置", this.camera.position);    },  },};</script>
<style lang="scss" scoped>body {  margin: 0;  overflow: hidden;  background: url("http://pic.sc.chinaz.com/files/pic/pic9/202001/zzpic22739.jpg")    center no-repeat;  background-size: cover;}</style>



本人,某个不知名小公司的前端小菜鸡,由于技术太菜,业余时间总是喜欢捣鼓一些花里胡哨的东西,一边学习一边分享,希望能够和大家一起成长,梦想着成为一位前端大大牛。

相关文章
|
数据可视化 搜索推荐 JavaScript
数据可视化大屏百度地图区域掩膜MapMask实现地图指定区域非省市县行政区显示的实战案例解析(JavaScript API GL、个性化地图定制、指定区域经纬度拾取转化)
数据可视化大屏百度地图区域掩膜MapMask实现地图指定区域非省市县行政区显示的实战案例解析(JavaScript API GL、个性化地图定制、指定区域经纬度拾取转化)
924 0
|
25天前
|
数据采集 监控 安全
厂区地图导航制作:GIS技术与路径导航算法融合
在智能化、数字化时代,GIS技术为厂区的运营管理带来了革命性变化。本文探讨了如何利用GIS技术,通过数据采集、地图绘制、路径规划、位置定位和信息查询等功能,打造高效、精准的智能厂区地图导航系统,提升企业的竞争力和管理水平。
34 0
厂区地图导航制作:GIS技术与路径导航算法融合
|
22天前
|
JSON JavaScript 定位技术
Vue结合ECharts绘制省市地图:数据驱动区域颜色展示,支持省市下钻与经纬度打点功能
Vue结合ECharts绘制省市地图:数据驱动区域颜色展示,支持省市下钻与经纬度打点功能
52 0
|
定位技术 内存技术
GIS空间分析 三维分析4 制作飞行动画
本文中,我们利用ArcScene软件用3种方法制作了飞行动画
287 0
|
数据可视化 JavaScript 定位技术
地图开发实战案例:高德地图实现区域掩膜的是地图可视化效果
地图开发实战案例:高德地图实现区域掩膜的是地图可视化效果
539 0
|
存储
医院PACS系统源码(三维多平面重建、三维容积重建、三维表面重建、三维虚拟内窥镜)
PACS部分主要提供医学影像获取、影像信息网络传递、大容量数据存储、影像显示和处理、影像打印等功能。RIS主要提供分诊登记、叫号、检查报告生成和打印等功能。本套影像存储与传输系统将二者进行无缝对接,提供了一个完整的集患者登记、图像采集、图像存储、报告产生的影像检查诊疗业务流程系统。
230 0
医院PACS系统源码(三维多平面重建、三维容积重建、三维表面重建、三维虚拟内窥镜)
|
数据可视化 物联网
Threejs物联网,工厂3D可视化,加载模型,水流监测,标签动态数据展示
Threejs物联网,工厂3D可视化,加载模型,水流监测,标签动态数据展示
914 15
Threejs物联网,工厂3D可视化,加载模型,水流监测,标签动态数据展示
|
传感器 算法 前端开发
【应用SLAM技术建立二维栅格化地图】
【应用SLAM技术建立二维栅格化地图】
447 0
|
定位技术
无须任何数据,六十秒快速制作三维影像图用以作为城市空间格局分析的底图
无须任何数据,六十秒快速制作三维影像图用以作为城市空间格局分析的底图
124 0
|
编解码 定位技术 数据处理
【从零开始学GIS再到精通GIS】专题图制作-地图渲染-地图整饰
【从零开始学GIS再到精通GIS】专题图制作-地图渲染-地图整饰
【从零开始学GIS再到精通GIS】专题图制作-地图渲染-地图整饰