实施阻尼(惯性)到全景旋转

时间:2018-03-20 19:02:05

标签: javascript three.js easing

我知道OrbitControls.js具有阻尼功能,可以平滑拖动全景,也称为缓动。我想实现相同的功能,但不使用此库。原因是我需要减少使用的代码量并更严格地控​​制鼠标或点击事件。

我已经构建了这个Plunker来展示我用作全景视图的启动项目的演示。

https://plnkr.co/edit/eX2dwgbrfNoX9RwWaPaH?p=preview

在此演示中,鼠标坐标将转换为纬度/经度,这将调整摄像机位置。这是来自three.js网站的最基本,最小的全景示例。

当我在OrbitControls.jssee this line)玩弄阻尼时,我无法获得相同的平滑行为 - 互动导致全景跳跃:

if ( scope.enableDamping === true ) {
    sphericalDelta.theta *= ( 1 - scope.dampingFactor );
    sphericalDelta.phi *= ( 1 - scope.dampingFactor );
    panOffset.multiplyScalar( 1 - scope.dampingFactor );
}

我不相信我完全可以理解如何将它应用于Plunker中的示例。

任何人都可以指导我朝着正确的方向将damping应用于我的Plunker示例吗?

更新

我设法通过为经度和纬度添加新的增量值来取得进展:请参阅更新的Plunker中的latDeltalonDelta。我明白了它在OrbitControls.js中是如何运作的。由于lonDelta = 0.35,您现在可以在初始页面加载时观察到理想的平滑滚动。但是,我不确定在用户鼠标滚动期间如何操作它。至少我正朝着正确的方向前进。

1 个答案:

答案 0 :(得分:7)

你很亲密!基本思路是计算用户平移的速度,并以相同的速度继续平移。然后你可以逐渐降低速度来模拟摩擦力。如果您不知道,'delta'或d,通常表示距离。如果您可以获得用户移动的距离以及他们花费的时间,那么您可以使用高中物理来计算速度并应用它。

https://plnkr.co/edit/xgDTcdOY5ZfnoVuW599u?p=preview

这是重要的部分,来自update

// Get time since last frame
var now = Date.now();
var dT = now - then;

if ( isUserInteracting ) {
    // Get distance travelled since last frame
    var dLon = lon - prevLon;
    var dLat = lat - prevLat;
    // velocity = distance / time
    lonVelocity = dLon / dT;
    latVelocity = dLat / dT;
} else {
    // old position + ( velocity * time ) = new position
    lon += lonVelocity * dT;
    lat += latVelocity * dT;
    // friction
    lonVelocity *= ( 1 - dampingFactor );
    latVelocity *= ( 1 - dampingFactor );
}

// Save these for next frame
then = now;
prevLon = lon;
prevLat = lat;