onMouseClick()办法实现射线拾取
创立模型的时候能够将mesh的group特地提出来
gltf.scene.traverse((child) => { if (child.isGroup) { child.name = 'dikuai' this.groups.push(child); } });
上面是残缺代码
<template> <div class="main-3d"> <div id="scene-container" ref="sceneContainer"></div> <div class="tool-box"> <div class="tool-site flexC" @click="show">隐身</div> <div class="tool-site flexC" @click="isRotate=!isRotate">旋转</div> </div> </div></template><script>import * as THREE from 'three'import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'export default { name: 'HelloWorld', data () { return { container: null, scene: null, camera: null, controls: null, renderer: null, stats: null, models:null, isRotate:false, groups:[] } }, methods: { onMouseClick() { let that = this; debugger function onMouseClick(event) { let a = document.getElementsByTagName("canvas") var canvas for(let i of a){ if(i.parentElement&&i.parentElement.id&&i.parentElement.id =="scene-container"){ canvas = i } } let x = ((event.clientX - canvas.getBoundingClientRect().left) / canvas.offsetWidth) * 2 - 1; // 规范设施横坐标 // 这里的mainCanvas是个dom元素,getBoundingClientRectangle会返回以后元素的视口大小. let y = -( (event.clientY - canvas.getBoundingClientRect().top) / canvas.offsetHeight ) * 2 + 1; // 规范设施纵坐标 let standardVector = new THREE.Vector3(x, y, 1); // 规范设施坐标 // 规范设施坐标转世界坐标 let worldVector = standardVector.unproject(that.camera); // 射线投射方向单位向量(worldVector坐标减相机地位坐标) let ray = worldVector.sub(that.camera.position).normalize(); // 创立射线投射器对象 let raycaster = new THREE.Raycaster(that.camera.position, ray); // 获取raycaster直线和所有模型相交的数组汇合 var intersects = raycaster.intersectObjects(that.scene.children, true); if (intersects.length > 0) { console.log(1); } } //这个中央肯定用renderer.domElement千万别用window!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!坑 that.renderer.domElement.addEventListener("click", onMouseClick, false); }, show(){ }, hide(){ let a = this.groups.find( item => item.name=='dikuai') a.children.forEach(element => { element.material.transparent = true element.material.opacity = 0 }); }, init () { // set container this.container = this.$refs.sceneContainer // add stats // add camera const fov = 60 // Field of view const aspect = this.container.clientWidth / this.container.clientHeight const near = 20 // the near clipping plane const far = 300 // the far clipping plane const camera = new THREE.PerspectiveCamera(fov, aspect, near, far) camera.position.set(0, 50, 100) this.camera = camera // create scene this.scene = new THREE.Scene() this.scene.background = new THREE.Color('skyblue') var hemiLight = new THREE.HemisphereLight( 0xffff55, 0x00ffff, 0.6 ); hemiLight.position.set(0,-100,0) var helper = new THREE.HemisphereLightHelper( hemiLight, 5 ); this.scene.add( helper ); const mainLight = new THREE.DirectionalLight(0xffffff, 4.0) mainLight.position.set(10, 50, 10) this.scene.add(mainLight,hemiLight) const mainLight2 = new THREE.DirectionalLight(0xffffff, 4.0) mainLight2.position.set(-10, -50, -10) this.scene.add(mainLight2,hemiLight) // add controls this.controls = new OrbitControls(this.camera, this.container) // create renderer this.renderer = new THREE.WebGLRenderer({ antialias: true }) this.renderer.setSize(this.container.clientWidth, this.container.clientHeight) this.renderer.setPixelRatio(window.devicePixelRatio) this.renderer.gammaFactor = 2.2 this.renderer.outputEncoding = THREE.sRGBEncoding this.renderer.physicallyCorrectLights = true this.container.appendChild(this.renderer.domElement) // set aspect ratio to match the new browser window aspect ratio this.camera.aspect = this.container.clientWidth / this.container.clientHeight this.camera.updateProjectionMatrix() this.renderer.setSize(this.container.clientWidth, this.container.clientHeight) const loader = new GLTFLoader() loader.load( '/glb/aaa.glb', gltf => { debugger this.models = gltf.scene this.scene.add(this.models) gltf.scene.traverse((child) => { if (child.isGroup) { child.name = 'dikuai' this.groups.push(child); } }); console.log(this.groups); }, undefined, undefined ) this.renderer.setAnimationLoop(() => { this.rotate() this.render() }) }, render () { this.renderer.render(this.scene, this.camera) }, rotate() { if(!this.isRotate){return false} // this.models.rotation.z += 0.01; // this.models.rotation.x += 0.01; // this.models.rotation.y += 0.01; this.models.rotateY(0.01); } }, mounted () { this.init() this.onMouseClick() }}</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped lang="scss">.main-3d{ width: 100%; height: 100%; .tool-box{ position: fixed; bottom: 10px; right: 10px; .tool-site{ width: 48px; height: 36px; background: red; cursor: pointer; } }}h3 { margin: 40px 0 0;}ul { list-style-type: none; padding: 0;}li { display: inline-block; margin: 0 10px;}a { color: #42b983;}#scene-container { height: 100%;}</style>