I don’t know if it’s expected, or a bug.
My guess is that engine.runRenderLoop(callback) adds a listener to the keyboard, in addition to the adding the callback to the active render loops.
If you want to to trigger render like you did, and still preserve the keyboard listener, maybe you could try to still run
engine.runRenderLoop(() => {});
Without explicitly triggering the scene render inside
@Devs : I had a look at source code, and indeed as I can see HERE :
public runRenderLoop(renderFunction: () => void): void {
if (this._activeRenderLoops.indexOf(renderFunction) !== -1) {
return;
}
this._activeRenderLoops.push(renderFunction);
// On the first added function, start the render loop.
if (this._activeRenderLoops.length === 1 && this._frameHandler === 0) {
this._frameHandler = this._queueNewFrame(this._boundRenderFunction, this.getHostWindow());
}
}
The function runRenderLoop starts the render loop on the first call. But it appears that if you call engine.runRenderLoop(); it triggers an error, undefined is pushed to activeRenderLoops
and then a call it triggered on this undefined function : TypeError: (0 , this._activeRenderLoops[e]) is not a function. The only way to call the runRenderLoop is to actually send an empty function. Maybe this could be changed (Ex : ignoring the callback if undefined, but still launch the render loop)
I have found out the reason for this behavior. The FreeCamera (as well as other cameras) calculates the move speed from the engine’s delta time and FPS. If no render loop has ever been registered to the engine, then the engine’s delta time and FPS will be invalid, so the speed for the camera will always be zero.
So the exact behavior is, for all cameras, if engine.runRenderLoop() has never been called, then the movement input will be inactive.
As @Tricotou said, we can register an empty function to bypass this problem.
engine.runRenderLoop(() => {});
I personally think this behavior is a little bit confusing. Delta time and FPS should also be available if the user chooses to trigger scene.render() or camera.update() on their own. (e.g. the render on demand thread)
Let’s see if other experts have any suggestions for this.