使用的api DragControls

该接口作用为:拖拽时会在摄像机视角垂直的平面上移动,即以摄像机视角方向为法向量的一个平面。

它是如何实现的在摄像机对着的屏幕移动的

文件位置:three/examples/jsm/controls/DragControls
内部代码

//新建一个平面
const _plane = new Plane();
...
//鼠标按下
function onPointerDown( event ){
	...
	//设置平面的法向量和点
	//将摄像机(_camera)的世界方向(getWorldDirection)设置为平面的法向量(_plane.normal)
	//世界位置(_worldPosition),设置世界矩阵(setFromMatrixPosition)为选择的目标的世界矩阵( _selected.matrixWorld)
	_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
	...
}
//鼠标移动
function onPointerMove(event) {
	//这里也有相同的代码
	...
	_plane.setFromNormalAndCoplanarPoint(_camera.getWorldDirection(_plane.normal), _worldPosition.setFromMatrixPosition(object.matrixWorld));
	...
}

如何在我指定的平面上移动?

分析可以得出,只需要将它动态计算的_plane平面设置成我自己的平面就可以了

如何修改源码

1.
先复制粘贴一份。

2.
加一个targetPlane属性
constructor(_objects, _camera, _domElement, targetPlane)
3
如何我有指定的平面,就把平面设置成自己的
 if (targetPlane)
     _plane = targetPlane
4 
上面动态计算的部分,如果我用自己的平面,就不要去计算了
if (!targetPlane)
  _plane.setFromNormalAndCoplanarPoint(_camera.getWorldDirection(_plane.normal), _worldPosition.setFromMatrixPosition(object.matrixWorld));

具体使用代码


  ...
   /*用于模拟平面 Plane 的辅助对象. PlaneHelper.*/
   const plane = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ) );
   const helper = new THREE.PlaneHelper( plane, 10, 0xffff00 );
   scene.add( helper );
  ...
  ...
  /*添加元素*/
        const geometry = new THREE.BoxGeometry( 1, 1, 1 );
        const material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } );
        const cube = new THREE.Mesh( geometry, material );
        cube.position.set(0,0,0)
        scene.add( cube );
   ...
   /*拖拽控制器,使用自己修改版本的*/
  const dragControls = new mDragControls([cube], camera, renderer.domElement,plane);

效果

请添加图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐