vue集成three.js加载外部模型
版本号:vue:2.6.10vue-cli3.xthree.js:0.115.0引入方式:import * as THREE from 'three'import Stats from 'stats.js'import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'import { STLLoader } from 'thre
·
版本号:
vue:2.6.10
vue-cli3.x
three.js:0.115.0
引入方式:
import * as THREE from 'three'
import Stats from 'stats.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
模型目录:
glb经过了webpack的处理,需要把.obj文件放到vue中处理静态文件的文件夹中,
在vue-cli3中public文件夹下的文件不需要经过webpack处理,
在vue-cli3.0之前就是放在static静态文件文件夹下,
在vue-cli3.0中需要放在public文件夹下,并且在组件中通过
process.env.BASE_URL+public文件夹下的.obj文件的路径来引用。
组件引用:
通过全局process.env.BASE_URL直接引入及可`${process.env.BASE_URL}model/Soldier.glb`
this.gltfLoader.load(
`${process.env.BASE_URL}model/Soldier.glb`,
gltf => {
alert('11')
gltf.scene.name = 'Soldier'
gltf.scene.rotation.y = Math.PI
this.scene.add(gltf.scene)
this.treeData = [gltf.scene]
this.scene.add(new AmbientLight(0xffffff, 2))
this.orbitControls.target.set(0, 1, 0)
const animationClip = gltf.animations.find(
animationClip => animationClip.name === 'Walk'
)
this.walkAction = this.animationMixer.clipAction(
animationClip
)
this.walkAction.play()
}
)
其他:
赠送一个官方的glb格式的文件
http://www.webgl3d.cn/threejs/examples/models/gltf/Soldier.glb
附上代码
<template>
<div>
<el-row>
<el-col :span="5" class="left-trees">
</el-col>
<el-col :span="19">
<div id="container"></div>
</el-col>
</el-row>
</div>
</template>
<script>
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export default {
name: 'ThreeTest',
data() {
return {
}
},
methods: {
init() {
this.scene = new THREE.Scene()
this.clock = new THREE.Clock()
this.camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
100
)
console.log(Twidth, Theight)
this.renderer = new THREE.WebGLRenderer({ antialias: true })
this.gltfLoader = new GLTFLoader()
this.stlLoader = new STLLoader()
this.orbitControls = new OrbitControls(
this.camera,
this.renderer.domElement
)
this.animationMixer = new THREE.AnimationMixer(this.scene)
this.renderer.setSize(window.innerWidth, window.innerHeight)
// document.body.appendChild(this.renderer.domElement)
document
.getElementById('container')
.appendChild(this.renderer.domElement)
window.addEventListener('resize', () => this.onWindowResize())
this.camera.position.set(-0.5, 2, 1)
const planeBufferGeometry = new THREE.PlaneBufferGeometry(80, 80)
const plane = new THREE.Mesh(
planeBufferGeometry,
new THREE.MeshBasicMaterial({
color: 0xffffff,
side: THREE.DoubleSide
})
)
plane.name = 'plane'
plane.rotation.x = -Math.PI / 2
this.scene.add(plane)
this.scene.add(new THREE.GridHelper(10, 10))
this.gltfLoader.load(
`${process.env.BASE_URL}model/Soldier.glb`,
gltf => {
gltf.scene.name = 'Soldier'
gltf.scene.rotation.y = Math.PI
this.scene.add(gltf.scene)
this.treeData = [gltf.scene]
this.scene.add(new THREE.AmbientLight(0xffffff, 2))
this.orbitControls.target.set(0, 1, 0)
const animationClip = gltf.animations.find(
animationClip => animationClip.name === 'Walk'
)
this.walkAction = this.animationMixer.clipAction(
animationClip
)
this.walkAction.play()
}
)
this.renderer.domElement.addEventListener('click', event => {
const { offsetX, offsetY } = event
const x = (offsetX / window.innerWidth) * 2 - 1
const y = -(offsetY / window.innerHeight) * 2 + 1
const mousePoint = new THREE.Vector2(x, y)
const raycaster = new THREE.Raycaster()
// 设置鼠标位置和参考相机
raycaster.setFromCamera(mousePoint, this.camera)
// 鼠标点击对应的物体(所有鼠标映射到的物体,包括被遮挡的)
const intersects = raycaster.intersectObjects(
this.scene.children,
true
)
// console.log(intersects)
// 过滤网格和地面
const intersect = intersects.filter(
intersect =>
!(intersect.object instanceof THREE.GridHelper) &&
intersect.object.name !== 'plane'
)[0]
if (intersect && this.isClickSoldier(intersect.object)) {
// 停止动画
// this.walkAction.stop();
// 暂停动画
this.walkAction.paused = !this.walkAction.paused
console.log(intersect)
intersect.object.material.color.set(0xff0000)
}
})
this.render()
},
isClickSoldier(object) {
if (object.name === 'Soldier') {
return object
} else if (object.parent) {
return this.isClickSoldier(object.parent)
} else {
return null
}
},
render() {
// 更新动画
this.animationMixer.update(this.clock.getDelta())
this.renderer.render(this.scene, this.camera)
this.orbitControls.update()
window.requestAnimationFrame(() => this.render())
// this.stats.update()
},
onWindowResize() {
this.renderer.setSize(window.innerWidth, window.innerHeight)
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
},
},
mounted() {
this.init()
}
}
</script>
<style >
#container {
height: 400px;
}
</style>
还在摸索中可以交流哈
更多推荐
已为社区贡献5条内容
所有评论(0)