three.js(选中模型并对模型进行拖拽选择缩放等操作)

328 阅读2分钟

接上文中,已经使用three在页面中创建了场景并添加了模型.

4 通过射线拾取选中模型或者点击位置

<script>
export default{
    methods:{
            //在此之前需要在初始化渲染器时绑定点击事件.上文中已添加,不再重复.
            handleClick(event){
              const px = event.offsetX;
              const py = event.offsetY;
              //屏幕坐标px、py转WebGL标准设备坐标x、y
              //width、height表示canvas画布宽高度
              let clickPosition = new THREE.Vector2();
              //计算模型的中心点
              const width = event.target.width
              const height = event.target.height
              clickPosition = {
                x : (px / width) * 2 - 1,
                y: -(py / height) * 2 + 1
              }
              //建立一个空物体
              let mouseVector = new THREE.Vector3();
              //设置空物体的位置
              mouseVector.set(clickPosition.x, clickPosition.y, 0.5);
              //创建一个射线投射器`Raycaster`
              const raycaster = new THREE.Raycaster();
              //.setFromCamera()计算射线投射器`Raycaster`的射线属性.ray
              // 形象点说就是在点击位置创建一条射线,射线穿过的模型代表选中
              raycaster.setFromCamera(mouseVector, camera);
              //.intersectObjects([mesh1, mesh2, mesh3])对参数中的网格模型对象进行射线交叉计算
              // 未选中对象返回空数组[],选中一个对象,数组1个元素,选中两个对象,数组两个元素
              const intersects = raycaster.intersectObjects([mesh]);
              // intersects.length大于0说明,说明选中了模型
              if (intersects.length > 0) {
                  //选中模型,可以在此处对选中的模型做操作.
              }
            },
    }
}
</script>

5 选中模型后对选中模型进行操作-以下功能从vue3改过来

<script>
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'

let mesh //因需要多个地方使用,定义在外面.
let transformControl = new TransformControls(camera, renderer.domElement)
scene.add(transformControl)
export default{
    methods:{
            //在此之前需要在初始化渲染器时绑定点击事件.上文中已添加,不再重复.
            handleClick(event){
              if (intersects.length > 0) {
                  //选中模型,可以在此处对选中的模型做操作.
                  mesh = 需要做操作的模型
                  transformControl.removeEventListener('change', this.transformChange)
                  transformControl.attach(mesh)
                  // 重要: 你需要重新监听change事件,因为在射线拾取逻辑中注销了监听
                  transformControl.addEventListener('change', this.transformChange)
                  this.render()
              }
            },
            transformChange() {
              render()
            },
            transformControl.addEventListener('dragging-changed', (e) => {
              if (!e.value) {
                // console.log('停止拖拽了')
              }
              controls.enabled = !e.value//必要 防止拖拽时或即将结束时获取到其他模型信息.
            })
    }
}
</script>

6 记录操作时的模型的位移旋转缩放等参数 位移和缩放可正常记录,旋转时,three中的参数为旋转的弧度数,可将其转为可读的角度数.

//将角度转为弧度数据
degreesToRadians(degrees) {
  return degrees * (Math.PI / 180)
},
//将弧度数转为角度数
radiansToDegrees(radians) {
  return radians * (180 / Math.PI)
}