CesiumJS - 如何控制查看器时间和滴答声?

CesiumJS - How can I control viewer time and ticks?

我想做的是控制非实时 Cesium 应用程序的时钟滴答。假设有昂贵的代码 运行,而且我想给查看者时间在继续之前加载图块。那么如何禁用自动滴答,然后在我的代码准备好时手动调用 tick()

Cesium.Clock 的文档说 "The clock will only tick when both Clock#canAnimate and Clock#shouldAnimate are true." 但这不是我得到的。 我目前看到的:

viewer.clock.canAnimate = false;
viewer.clock.shouldAnimate = false;
viewer.clock.onTick.addEventListener(function(clock){
    console.log("Tick");
});

控制台中的结果显示时钟仍在滴答作响:

Tick
Tick
Tick
Tick
...

我想做什么:

viewer.clock.stopTicking(); // or whatever that command would be...
while (someCondition){
    // run expensive code
    tick(); // issue manual tick
}

感谢您的帮助! 最大值

因此,您的 console.log 仍在打印 'Tick',因为 onTick 继续发射,无论时钟是否前进。正如您所怀疑的那样,您需要做的就是同时切换 canAnimateshouldAnimate。因此,您的示例代码基本上是:

viewer.clock.canAnimate = false; 
viewer.clock.shouldAnimate = false;
while (someCondition){
    // run expensive code
    // toggle someCondition so we can exit this
}
// set the animate bools back to true so the clock can advance
viewer.clock.canAnimate = true;
viewer.clock.shouldAnimate = true;

为了更好地了解它的实际效果,试试这个(也许将 if 条件设置为 1000 而不是 100):

viewer.clock.canAnimate = false;
viewer.clock.shouldAnimate = false;
var s = 0;
viewer.clock.onTick.addEventListener(function(clock){
    if (s < 100) {
        console.log(viewer.clock.currentTime);
    } else {
        viewer.clock.canAnimate = true;
        viewer.clock.shouldAnimate = true;        
    }
    s++;
});

您会看到 console.log 打印相同的值 100(或 1000)次...这是因为 currentTime 没有前进,因为 canAnimateshouldAnimate。一旦它们都切换回 truecurrentTime 将前进。

Cesium API 的一个遗留怪癖是 Clock 的 onTick 事件会在渲染的每个动画帧中触发,无论时钟是否及时推进。

如果你想自己控制 Cesium 的渲染循环,你可以这样做:

viewer.useDefaultRenderLoop = false;

function myOwnRenderLoop() {
    viewer.resize();
    viewer.render();
    Cesium.requestAnimationFrame(myOwnRenderLoop);
}

Cesium.requestAnimationFrame(myOwnRenderLoop);

以上,我使用的是 requestAnimationFrame,因此循环运行得尽可能快。但我可以将其替换为 setTimeout 以获得更慢的循环,模拟较差的渲染性能。请注意,当使用较长的时间间隔时,使用这种方法会降低交互性和屏幕更新速度。

viewer.useDefaultRenderLoop = false;

function myOwnRenderLoop() {
    viewer.resize();
    viewer.render();
    window.setTimeout(myOwnRenderLoop, 500);
}

window.setTimeout(myOwnRenderLoop, 500);