2
$\begingroup$

I am new to blender and I cant seem to filter through all the resources to find an answer to my question.

enter image description here

How can I create a driver expression that adds the result from last frame to the result of this frame?

I have a very complex formula I have created but realized it is useless unless its result can be added to itself every new frame. Is there a way to accomplish this? I cant find a way to compound the answer each new frame.

As a simplified example, lets say the expression is var + 2. Lets say var = 1 and will never change just for this example. Each frame, the output will always be 2. If I could add the value of the last frame to the current frame, each frame the value would increase by 2 every new frame. Like a summation of the values it puts out each frame from all the frames before.

I hope I didn't over explain it!

I am hoping there is some sort of python expression or input variable I can add that is the result of the expression from the previous frame. I am brand new to learning python and I am no where near understanding how to accomplish this with a separate script.

Any help is greatly appreciated!

$\endgroup$
1
  • $\begingroup$ You can write a 'driver function' that could store the value from the previous frame and use that when calculating the value in the current frame. See blender.stackexchange.com/a/108484/29586 for an example that does similar to 'queue up' the location of an object to replay it back delayed by a number of frames to demonstrate what's possible. I don't have the time to write a full answer or locate a more appropriate answer for your specific problem (it's far more complicated than you'll need) but I hope that helps get you in the right direction. $\endgroup$ Commented Jan 11, 2022 at 14:34

2 Answers 2

2
$\begingroup$

A "vanilla" (restricted access) driver is stateless in a sense that each frame can be calculated independently. For your idea of a driver to work, it would have to access a value on a previous frame (and so jumping to the 100th frame would require calculating all 99 previous frames).

I might have stumbled in the past on a way to create a circular dependence (that Blender avoids, as normally it hangs the program), where I would get a feedback loop by feeding the output to the input. I think it was just constraints without drivers, tried now and couldn't get a feedback loop like that for drivers. Even if I did, controlling it would be hard - even if it updated only once per frame, changing a frame wouldn't read the value from a previous frame, but a value of a previously selected frame (e.g. when moving the slider backwards it would read the next frame).

There might be hacks using solutions that store iterative state like physics simulations or dynamic paint, but I don't think it's worth it to bother, so you need to use a Python script:

import bpy
from bpy import context as C, data as D

start_frame = 1  # when to start
end_frame = 250  # when to end 
starting_value = 1
cache = {start_frame-1: starting_value}
formula = lambda x: x+0.01


def frame_change_pre(scene, depsgraph=None):
    frame = C.scene.frame_current
    if frame < start_frame:
        return
    if frame > end_frame:
        return
    
    cube = D.objects['Cube']
    
    cached_value = cache.get(frame)    
    if cached_value is not None:
        # you don't need to do this if the calculation isn't CPU intensive
        cube.rotation_euler.z = cached_value
        return 
    prev_value = cache.get(frame-1)
    
    if prev_value is None:
        return  # don't compute if a frame was skipped

    cache[frame] = formula(prev_value)
    cube.rotation_euler.z = cache[frame]
    

listeners = bpy.app.handlers.frame_change_pre
listeners.clear()  # remove old handlers before adding updated versions
listeners.append(frame_change_pre)
C.scene.frame_current = start_frame
$\endgroup$
0
$\begingroup$

I believe the #frame wildcard can be used in expressions like this. Maybe multiplying your formula by #frame will work?

The #frame wildcard simply returns the frame number. So on frame 1 it's 1, on frame 2 it's 2 and so on.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .