three.js一步一步来--加载模型并修改其大小、按照规定的区域把一堆模型摆得整整齐齐~~~

来呀一起摆模型啦~

<template>
  <div class="container">
    <canvas ref="mainCanvas16" id="canvas16"></canvas>
  </div>
</template>

<script>
import * as THREE from 'three'
import utils from './js/utils.js'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
export default {
  props: {},
  data() {
    return {
      // 公共项目1
      scene: new THREE.Scene(),
      camera: null,
      renderer: new THREE.WebGLRenderer(), // 渲染器
      directionalLight: new THREE.DirectionalLight(0xffffff, 1.0, 0),
      controls: OrbitControls,
      cars: [],
       '',
      height: '',
      config: {
        isMobile: false,
        background: 0x282828
      },
      // 公共项目2
      //  交互
      raycaster: new THREE.Raycaster(),
      mouse: new THREE.Vector2(),
      instersected: null
      //  交互
    }
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {
    this.width = window.innerWidth
    this.height = window.innerHeight - 50
    this.scene = new THREE.Scene()
    this.camera = new THREE.PerspectiveCamera(
      45, // 视野角fov
      this.width / this.height,
      1,
      5000
    )
    this.camera.position.set(1200, 1200, 1200) // 调大了可以离的远点看
    this.camera.lookAt(this.scene.position)
    this.canvas = this.$refs.mainCanvas16
    this.renderer = new THREE.WebGLRenderer({
      antialias: true, // antialias:true/false是否开启反锯齿
      canvas: this.canvas
    })
    document.addEventListener('mouseup', this.onDocumentMouseUp, false) // 交互
    document.addEventListener('mousedown', this.onDocumentMouseDown, false) // 交互
    this.renderer.setSize(this.width, this.height)
    this.renderer.setClearColor(this.config.background)
    this.renderer.shadowMap.enabled = true // 輔助線
    this.renderer.shadowMap.type = THREE.PCFSoftShadowMap // 柔化边缘的软阴影映射
    this.checkUserAgent() // 检测浏览器类型
    this.bulidAuxSystem() // 构建辅助系统
    this.buildLightSystem() // 光线
    this.addMash()
    // this.createMetarial()
    this.loop()
  },
  methods: {
    createMetarial() {
      const a = {
        one: {
          materialUrl: '/images/camera/camera.mtl',
          objUrl: '/images/camera/camera.obj',
          positiony: 3,
          positionx: -400,
          positionz: 300,
          scalex: 1,
          scaley: 1,
          scalez: 1
        },
        two: {
          materialUrl: '/images/annihilator/annihilator.mtl',
          objUrl: '/images/annihilator/annihilator.obj',
          positiony: 3,
          positionx: -200,
          positionz: 300,
          scalex: 0.01,
          scaley: 0.01,
          scalez: 0.01
        },
        three: {
          materialUrl: '/images/camera/camera.mtl',
          objUrl: '/images/camera/camera.obj',
          positiony: 3,
          positionx: 0,
          positionz: 300,
          scalex: 1,
          scaley: 1,
          scalez: 1
        },
        four: {
          materialUrl: '/images/annihilator/annihilator.mtl',
          objUrl: '/images/annihilator/annihilator.obj',
          positiony: 3,
          positionx: 200,
          positionz: 300,
          scalex: 0.01,
          scaley: 0.01,
          scalez: 0.01
        },
        five: {
          materialUrl: '/images/camera/camera.mtl',
          objUrl: '/images/camera/camera.obj',
          positiony: 3,
          positionx: 400,
          positionz: 300,
          scalex: 1,
          scaley: 1,
          scalez: 1
        }
      }

      Object.values(a).forEach(_ => {
        this.createObjAnnihilator(
          _.materialUrl,
          _.objUrl,
          _.positionx,
          _.positiony,
          _.positionz,
          _.scalex,
          _.scaley,
          _.scalez
        )
      })
    },
    createObjAnnihilator(
      materialUrl,
      objUrl,
      positionx,
      positiony,
      positionz,
      scalex,
      scaley,
      scalez
    ) {
      var manager = new THREE.LoadingManager()
      new MTLLoader(manager).load(materialUrl, materials => {
        materials.preload()
        const objLoader = new OBJLoader(manager)
        objLoader.materials = materials
        objLoader.load(
          objUrl,
          object => {
            object.position.y = positiony
            object.position.x = positionx
            object.position.z = positionz
            object.scale.set(scalex, scaley, scalez) // 这行代码负责调整模型大小
            this.scene.add(object)
          },
          xhr => {
            console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
          },
          err => {
            console.log('111An error happened', err)
          }
        )
      })
    },
    createObjAnnihilator1() {
      var manager = new THREE.LoadingManager()
      new MTLLoader(manager).load(
        '/obj-assets/CISCO4506_jixiang.mtl',
        materials => {
          materials.preload()
          const objLoader = new OBJLoader(manager)
          objLoader.materials = materials
          objLoader.load(
            '/obj-assets/CISCO4506_jixiang.obj',
            object => {
              object.position.y = 300
              this.scene.add(object)
            },
            xhr => {
              console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
            },

            err => {
              console.log('111An error happened', err)
            }
          )
        }
      )
    },
    // 交互
    onDocumentMouseDown(e) {
      // console.log(e)
    },
    onDocumentMouseUp(event) {
      event.preventDefault()
      this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1 // 如果记得点击变色感觉点不中,那就需要改一下这里哦event.clientX ~~
      this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
      
    },
    // 交互
    addMash() {
      const planeGeometry = new THREE.BoxBufferGeometry(3000, 6, 2000) // 这里控制的是地板的大小
      const plane = utils.makeMesh('lambert', planeGeometry, 0xe2d5d5)
      plane.position.y = -3
      this.scene.add(plane)
      /**
       * 创建网格模型
       */
      //  立方体网格模型
      var geometry1 = new THREE.BoxGeometry(100, 100, 100)
      var material1 = new THREE.MeshLambertMaterial({
        color: 0x0000ff, // 材质颜色半透明蓝色
        transparent: true, // 开启透明度
        opacity: 0.5 // 设置透明度具体值
      }) // 材质对象Material
      var mesh1 = new THREE.Mesh(geometry1, material1) // 网格模型对象Mesh
      mesh1.position.y = 50
      this.scene.add(mesh1) // 网格模型添加到场景中

      //  球体网格模型
      var geometry2 = new THREE.SphereGeometry(60, 40, 40)
      var material2 = new THREE.MeshLambertMaterial({
        color: 0xff00f,
        transparent: true, // 开启透明度
        opacity: 0.5 // 设置透明度具体值
      })
      var mesh2 = new THREE.Mesh(geometry2, material2) // 网格模型对象Mesh
      mesh2.translateY(120) // 球体网格模型沿Y轴正方向平移100
      this.scene.add(mesh2)

      //  圆柱网格模型
      var geometry3 = new THREE.CylinderGeometry(50, 50, 100, 25)
      var material3 = new THREE.MeshLambertMaterial({
        color: 0xffff00,
        transparent: true, // 开启透明度
        opacity: 0.5 // 设置透明度具体值
      })
      var mesh3 = new THREE.Mesh(geometry3, material3) // 网格模型对象Mesh
      mesh3.translateX(120) // 球体网格模型沿Y轴正方向平移100
      mesh3.position.y = 50
      this.scene.add(mesh3)
    },
    // 检测浏览器类型1
    checkUserAgent() {
      const n = navigator.userAgent
      if (
        n.match(/Android/i) ||
        n.match(/webOs/i) ||
        n.match(/iPhone/i) ||
        n.match(/iPad/i) ||
        n.match(/iPod/i) ||
        n.match(/BlackBerry/i)
      ) {
        this.config.isMobile = true
        this.camera.position.set(1000, 420, 420)
        this.renderer.shadowMap.enabled = false // 輔助線
      }
    },
    // 检测浏览器类型2
    // 构建辅助系统1
    bulidAuxSystem() {
      var axisHelper = new THREE.AxisHelper(2500) // 这里控制辅助线的大小长短,就是红绿蓝线条
      this.scene.add(axisHelper)
      // const gridHelper = new THREE.GridHelper(1000, 32) // 这里控制表格的大小长宽
      // this.scene.add(gridHelper)
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
      this.controls.enableDamping = true
      this.controls.dampingFactor = 0.25
      this.controls.rotateSpeed = 0.35
    },
    // 构建辅助系统2
    buildLightSystem() {
      if (!this.config.isMobile) {
        this.directionalLight.position.set(300, 1000, 500)
        this.directionalLight.target.position.set(0, 0, 0)
        this.directionalLight.castShadow = true
        this.directionalLight.shadow.bias = 0.0001
        this.directionalLight.shadow.mapSize.width = this.directionalLight.shadow.mapSize.height = 1024
        this.scene.add(this.directionalLight)
        const light = new THREE.AmbientLight(0xffffff, 0.3)
        this.scene.add(light)
      } else {
        const hemisphereLight = new THREE.HemisphereLight(0xffffff, 1)
        this.scene.add(hemisphereLight)
        this.scene.add(new THREE.AmbientLight(0xffffff, 0.15))
      }
    },
    loop() {
      this.renderer.render(this.scene, this.camera)
      requestAnimationFrame(this.loop)
      this.raycaster.setFromCamera(this.mouse, this.camera)
      var intersects = this.raycaster.intersectObjects(this.scene.children)
      if (intersects.length > 0) {
        if (this.instersected !== intersects[0].object) {
          if (this.instersected) {
            this.instersected.material.color.setHex(
              this.instersected.currentHex
            )
          }
          this.instersected = intersects[0].object
          this.instersected.currentHex = this.instersected.material.color.getHex()
          this.instersected.material.color.set(0xff0000)
        }
      } else {
        if (this.instersected) {
          this.instersected.material.color.set(this.instersected.currentHex)
        }
        this.instersected = null
      }
    }
  },
  beforeDestory() {
    // 下面这些代码 是为了清除缓存,具体怎么写更加好,不太清楚,希望路过的大佬可以指点一下~~
    this.scene.dispose()
    this.controls.dispose()
    this.scene = null
    this.camera = null
    this.directionalLight = null
    this.controls = null
    this.raycaster = null
    this.renderer.dispose()
    this.renderer.forceContextLoss()
    this.renderer.context = null
    this.renderer.domElement = null
    this.renderer = null

    var canvas = document.getElementById('canvas16')
    var gl = canvas.getContext('webgl')
    gl.getExtension('WEBGL_lose_context').loseContext()
  }
}
</script>

<style scoped lang="less">
</style>

原文地址:https://www.cnblogs.com/sugartang/p/13605896.html