Bake the displacement.

Given
I used a gltf camera path which I exported from a video game, so Its
just a keyframe animation
Here is a quick baking script,
Whenever the animation of the camera has been changed, run the script to bake some simple physics.
- Set scene to first frame of action save the location as previous location
- For each frame of camera action
- Calculate the distance from frame location to previous location and store
- Set the location as previous.
From the data bake in 3 animations on custom properties
"speed" The amount of distance travelled that frame
"disp" The accumulative displacement
"offset" The frame displacement as a fraction of total
The values of the 3 are keyframed into the camera action
The cube in GIF has a follow path constraint to circle, the relative offset is being driven by cameras custom property "offset" added by script.
Baked in graph editor

Here is a test script, assuming the animated object is scene camera, and it is animated by active action
import bpy
import numpy as np
context = bpy.context
scene = context.scene
cam = scene.camera
action = cam.animation_data.action
frames = np.arange(*action.frame_range)
def gloc(ob):
return ob.matrix_world.to_translation()
locs = []
scene.frame_set(frames[0])
ploc = gloc(cam)
for f in frames:
print(f)
scene.frame_set(f)
loc = gloc(cam)
s = (loc - ploc).length
locs.append(s)
ploc = loc
def flatten(a, b):
c = np.empty((a.size + b.size,), dtype=b.dtype)
c[0::2] = a
c[1::2] = b
return c
def fcurve(fcurves, datapath, data):
cam[datapath] = 0.0
fc = fcurves.find(datapath)
if fc:
fcurves.remove(fc)
fc = fcurves.new(datapath)
fc.data_path = f'["{datapath}"]'
fc.keyframe_points.add(len(frames))
fc.keyframe_points.foreach_set(
"co",
flatten(frames, data)
)
fc.convert_to_samples(*action.frame_range)
# per frame speed
speed = np.array(locs)
fcurve(action.fcurves, "speed", speed)
# displacement
disp = np.cumsum(speed)
fcurve(action.fcurves, "disp", disp)
# Offset of total displacement
offset = disp / disp[-1]
fcurve(action.fcurves, "offset", offset)
Note, GIFs shown are not moving two objects same distance each frame, rather the same offset fraction along their asscociated paths per frame. To make it 1:1 distance would require calculating the length of the constraint curve
d
units, the path object will moved
along the curve? Doing it live, is do-able but tricky. Baking it post animation is simpler, eg using a slow empty one frame behind the camera,d
is the distance between. Knowing the length of the curve, offset the path object. $\endgroup$