Howto: time-based animations in BabylonJS?

Theoretical question here.

I’m looking into implementing a time-based animation in BabylonJS.
I’ll create a custom use case for this question:

Use Case

I want to show an animation of a driving car based on historical data.
This historical data states:
At 0 seconds the car is standing still on the road.
At 1 second, the car is at 10 meters.
At 2 seconds, the car is at 50 meters
At 5 seconds, the car is at 200 meters.

I prefer to display this with a “time-based animation” if possible. If it’s not, please let me know.

Here is the required behavior (and what should be avoided):
There are two users: someone with a fast computer, another with a slow computer
Fast user runs the Babylon app at 60 fps.
Slow user runs the Babylon app at 20 fps.

After 5 seconds in real time, both the fast and slow user must see the car at 200 meters.
The slow user might have experienced a more jerky-movement, but that doesn’t matter.
Priority here is that both users see the car at the exact same spot on the road after 5 seconds.
It must be avoided that the users see the car on 2 different locations after 5 seconds due to them running different FPS speeds.

Questions this raises in BablyonJS:

In BabylonJS, I was originally thinking of building the driving animation as a new Animation(),
and then use “keys” to state:

  • on frame: 0 the car is at position 0 meters.
  • on frame: 60 the car is at position 10 meters
  • on frame: 300 the car is at position 200 meters.

The thought I run into here, is that, since the slow user only has a 20 fps system, it will take him 15 seconds to reach frame 300, and thus 15 seconds to see the car at position 200 meters.
This would be very problematic and not the behavior I’m looking for.

My second thought is:
Maybe BabylonJS already taking that into account? And the framerate in new Animation() is meant to define a relative framerate of the animation, relative to my keys. And BabylonJS knows that when I say that the car should be at 200 meters after 300 frames, it will know that the programmer expects the car to be at 200 meters after 5 seconds instead of after a literal 300 frames?
In this case, I shouldn’t break my head over this because BabylonJS already implements it time-based by default.

Those are my questions.
Or shouldn’t I be using animations at all for this and is there something else I should be doing to reach the requested behavior?

I think all your questions are answered in the docs from

and the pages that follow. You could also carry out a simple test with a cube rather than a car to check yourself

I’ve read through this documentation first but since it didn’t clearly answer my above questions,
I’ve decided to ask this question to the community.

From the docs Introduction to Animations | Babylon.js Documentation

Frame - an animation frame not a rendered frame of the scene

  • the rate of change of the property in frames per second,

From Designing Animations | Babylon.js Documentation

The key frames are at 0, 1 and 2 seconds. To find the frame number after t seconds multiply the time by the frame rate, i.e. t x frameRate.
In this case the key frames are at frame numbers, 0, 1 x frameRate and 2 x frame Rate.

So it is already time based. You can do a simple check in a playground changing the positions in

to those of you example.

3 Likes

If you think the docs could be made clearer please add to it.

1 Like

Thank you very much for your answer.
I have gone to your playground and added the following code right before “return scene”:

for(let i=0;i<10000;i++){
        const xtrabox = BABYLON.MeshBuilder.CreateBox("box2", {});
         xtrabox.position.z = Math.random() * 2 + 1.5
            xtrabox.animations.push(xSlide);
            scene.beginAnimation(xtrabox, 0, 2 * frameRate, true);

}

This adds 10 000 moving boxes and lets the framerate drop down to 11 FPS on my system.
Therefore I could test:
I have the original open in another browser, running at 144 FPS.
The 10 001 moving boxes opened in another browser, running at 11 FPS.
And in both browsers, the boxes kept hitting the edge and bounce back, at the same moment. Thus the animation in the low-fps did not slow down, but just became jerkier.

I believe this confirms that the part “My second thought is:” of my question is the correct one: BabylonJS indeed takes it into account under the hood, so I can safely rely on the Animation frames being time-based frames.

… as you’ve also noted in your reply with the docs.

Thanks for helping me reaching that insight.
I don’t really know how this could be worded clearly in the docs. (don’t have a github account yet)
Maybe something along the lines of:

“The framerate property of the Animation function determines how many times the animation will update every second. If a person’s computer doesn’t have a high enough frame rate, some of the animation frames might not be displayed, but the animation will still run for the same amount of time.”