来呀一起摆模型啦~
<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>