ThreeJS轨道控制中的惯性

Inertia in OrbitControls from ThreeJS

本文关键字:轨道控制 ThreeJS      更新时间:2023-12-21

我正在使用THREE.OrbitControls旋转我的对象。然而,我想添加一些用于相机旋转的神经(如果有人停止移动鼠标,相机会在一段时间后停止)。我怎样才能做到这一点?

这里有一个在OrbitControls.js:中添加惯性的非常简单的方法

在更新函数的末尾(当前为271-272行),您将看到以下两个变量设置为零:

thetaDelta = 0;
phiDelta = 0;

改变这一点,使它们不会立即变为零,而是随着时间的推移变得更小:

thetaDelta /= 1.5;
phiDelta /= 1.5;

就是这样!

对于像我一样在这里登陆的其他开发人员,截至2019年和three.js r111,OrbitControls现在支持开箱即用的惯性,它被称为阻尼(不要问我为什么),但另一个答案将向您展示如何使用它。

我使用了一种快速而肮脏的方法来编写这种效果的代码-

OrbitControls.js中,将此函数添加到主声明内部(或任何真正的地方)-

this.inertiaFunction = function()
{
    scope.rotateLeft( ( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * scope.userRotateSpeed )/dividingFactor);
scope.rotateUp( ( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * scope.userRotateSpeed )/dividingFactor);
dividingFactor+=0.5;
}


onMouseDown(event)函数中,将其添加到第一行-

 dividingFactor = 1;

(这样每次点击时系数都会重置)


onMouseUp(event)函数中,将这些行添加到起始-中

dragging2=false;
timer = setTimeout(function(){dragging=false;}, 500);

draggingdragging2是我们在requestAnimFrame函数中使用的两个标志,用于确定鼠标是否已被抬起,500毫秒是否尚未过去。


将其添加到您的主动画()或requestAnimationFrame()函数中-

if(dragging && !dragging2){ controls.inertiaFunction(); }


这将检查如果(鼠标已被抬起)AND(500毫秒尚未过去)-
调用控件对象的inertiaFunction()(它是THREE.OrbitControls的一个实例)
对于用户在举起鼠标后500ms内单击的情况,我们使用timer对象来取消setTimeOut
在你的onMouseDown功能中,添加这个-

if(dragging)
{
    clearTimeout(timer);
}


不要忘记将draggingtimerdragging2dividingFactor声明为全局变量。使用dividingFactorsetTimeout()中的500ms来更改惯性运动的行进距离和持续时间