我写了一个控件来转换对象,但是当我将鼠标移动得太快时,它就无法工作。
我该如何解决这个问题?
这是我的代码:https://jsbin.com/vajunal/edit?html,output
这是主要代码:
var a = 2 * x / this.canvas.width - 1;
var b = 1 - 2 * y / this.canvas.height;
this.raycaster.setFromCamera(new THREE.Vector2(a, b), this.camera);
const intersects = this.raycaster.intersectObject(this.helpPlane);
if (intersects.length == 0) {
return;
}
var pos = intersects[0].point;
this.helpPlane.position.set(pos.x, pos.y, pos.z)
this.object.position.set(pos.x, pos.y, pos.z);
答案 0 :(得分:0)
发生这种情况的原因是鼠标离开"辅助平面"在两个mousemove事件之间。为了捕捉鼠标的任何运动,你需要使辅助平面无限大。一种解决方案可以是使用THREE.Plane
而不是平面网格来计算世界空间中的鼠标位置。请参阅此codepen以获取如何执行此操作的示例:https://codepen.io/usefulthink/pen/XqYqRL(其中包含更多文档)。
简而言之,这就是程序:
// --- somewhere outside:
const ray = new THREE.Ray();
const target = new THREE.Vector3();
const xzPlane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
// --- mousemove-handler:
const mouse = new THREE.Vector2();
renderer.domElement.addEventListener("mousemove", ev => {
const { offsetWidth: w, offsetHeight: h } = ev.target;
mouse.x = 2 * ev.clientX / w - 1;
mouse.y = 1 - 2 * ev.clientY / h;
});
// --- in the animation-loop:
// Compute the ray from the camera through the cursor-position and intersect
// with the xz-plane.
ray.origin.setFromMatrixPosition(camera.matrixWorld);
ray.direction.set(mouse.x, mouse.y, 0.5).unproject(camera);
ray.direction.sub(ray.origin).normalize();
ray.intersectPlane(xzPlane, target);
// `target` now contains the world-space coordinates of the mouse-cursor
这可以处理整个场景中直到地平线的鼠标移动。现在,如果您想支持其他移动方向,则需要以不同的方式配置xzPlane
,例如通过计算mousedown处理程序中的移动平面。
另请查看three.js附带的TransformControls
,可能已经是您正在寻找的内容:https://threejs.org/examples/?q=trans#misc_controls_transform
另一个注意事项:mousemove事件通常与动画循环不同步,并且可能比渲染更频繁地发生。通常希望将所有昂贵的操作(如光线投射)放入主动画循环中,并仅将最后看到的鼠标位置存储在mousemove事件的处理程序中。但这可能只是一个小问题,对你所看到的问题没什么贡献。