本文实现的效果是,模型渲染出来后,根据用户点击模型的某部分,将相机定位到鼠标点击的位置,并放大
监听模型点击事件
this.renderer.domElement.addEventListener('click', this.modelMouseClick, false)
点击事件
// 模型的点击事件 modelMouseClick( event ) { var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1) mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; raycaster.setFromCamera(mouse, this.camera); const intersects = raycaster.intersectObjects(this.scene.children); // 根据它来判断点击的什么,length为0即没有点击到模型 console.log(intersects.length ? intersects[0].object.name : intersects, 'intersects----->>>') if(intersects.length){ this.handlePosition(intersects[0].object) } },
调整相机位置
// 动态调整相机位置 handlePosition(obj){ let box3 = new THREE.Box3() box3.expandByObject(obj) // 计算模型包围盒 let size = new THREE.Vector3() box3.getSize(size) // 计算包围盒尺寸 let center = new THREE.Vector3() box3.getCenter(center) // 计算一个层级模型对应包围盒的几何体中心坐标 function maxSize(vec3) { let max if (vec3.x > vec3.y) { max = vec3.x } else { max = vec3.y } if (max > vec3.z) { } else { max = vec3.z } return max } let max = maxSize(size) //包围盒长宽高中最大的一个值,用来表征模型的尺寸 // 1.控制渲染范围,但是不要忘记相机位于模型包围盒之外 this.camera.position.copy(center.clone().addScalar(max)) // 2. 居中渲染:设置相机目标观察点,指向包围盒几何中心 this.camera.lookAt(center) // 3.注意near和far尺寸控制 this.camera.near = max * 0.1//最好和相机位置或者说包围盒关联,别设置0.1 1之类看似小的值 this.camera.far = max * 300//根据相机位置和包围大小设置,把包围盒包含进去即可,宁可把偏大,不可偏小 this.camera.updateProjectionMatrix()//渲染范围改变,注意更新投影矩阵 this.controls.target.copy(center) this.controls.update() },
不过此文的相机调整比较快、生硬,没有那种渐进式的感觉,哪位博主有更好的方法了请在下面留言哦