zoukankan      html  css  js  c++  java
  • 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>
    
    
  • 相关阅读:
    Air-WIFI使用方法
    libeasy代码学习:一次简单的TCP请求处理流程
    log_pipe日志收集分析系统介绍
    asp.net 项目在 IE 11 下出现 “__doPostBack”未定义 的解决办法
    用命令行实现“一键休眠”
    C#几个经常用到的字符串的截取
    MYSQL存储过程怎么写
    如何用myeclipse和eclipse搭建安卓开发环境
    C#随机生成不重复字符串
    Inno setup 简单打包教程
  • 原文地址:https://www.cnblogs.com/sugartang/p/13605896.html
Copyright © 2011-2022 走看看