Skip to main content

Making 3D Motion Smooth (Spline Interpolation)

📌 What is this for? (Quick Summary for New Interns)​

In Simple Words:
When you watch YouTube or play a game, the video runs at 60 frames per second (60 FPS).
But over the internet from AWS, our dashboard only receives new position numbers once every second (1 FPS).

If you simply moved the 3D model whenever a new number arrived, the pod would freeze for a second, then teleport forward, then freeze again. It would look terrible!

This file (src/utils/splineInterpolator.js) solves that using a smooth math curve called a Hermite Spline:
It takes where the pod was 1 second ago, where it is now, and its speed, and calculates 60 smooth in-between steps so the vehicle glides smoothly without jumping.


1. Why Normal Linear Stepping Looks Stiff​

If you draw a straight line between points:

  • The speed changes abruptly at each corner, causing jarring visual jerks.
  • With a Cubic Hermite Spline, the curve takes into account the vehicle's velocity at both ends of the interval. This makes both the position and the speed change smoothly with zero visual kinks.
graph LR
PointA["Point A: Position 100m, Speed 40 km/h"] --> Spline["Hermite Math Curve"]
PointB["Point B: Position 115m, Speed 50 km/h"] --> Spline
ScreenTimer["60 FPS Render Loop"] --> Spline
Spline --> SmoothMove["Calculates 60 fluid micro-steps per second\nZero stutter • Completely smooth gliding"]

2. The 1-Second Delayed Buffer Trick​

How can the math know what curve to draw if it hasn't seen the future yet?
We use a classic video game trick: we render the 3D world with a 1.0-second delay.

  1. At $t = 5.0\text{s}$, the dashboard receives the reading for where the pod is at second 5.
  2. The 3D scene renders where the pod moved between second 4 and second 5.
  3. Because the computer already knows both the start (second 4) and the destination (second 5), it can draw the mathematically perfect smooth curve between them.
// Simple concept in splineInterpolator.js:
const targetTime = currentTime - 1000; // 1 second in the past
const currentPosition = calculateSmoothCurve(lastPoint, nextPoint, targetTime);
podModel.position.x = currentPosition;

This guarantees that even if your Wi-Fi is slightly laggy, the 3D pod never stutters or jerks.