Iterative loop

   515   6   0
User Avatar
Member
29 posts
Joined: Sept. 2019
Offline
I'm trying to automate a character blinking, which I've been able to do with a CHOP, but want more flexibility, especially the ability to add random variation. Without even getting into the mechanics of driving the blink, which has also bedeviled me, I'm also just not an experienced programmer. I've got the following in an Attribute Wrangle SOP:

@br = ch("../../blinkrate");
@bv = ch("../../blinkratevar");
@f = 0;
@fr = @br + rint(fit(rand(@f), 0, 1, -@bv, @bv));
@f += @fr;
if ($F == @f) {
    @fr = @br + rint(fit(rand(@f), 0, 1, -@bv, @bv));
    @f += @fr;    }

The idea is that @fr (@br +/- a random integer within @bv of @br) is the number of frames before the next blink, and @f is the absolute frame number of the blink. Currently, @br = 60 and @bv = 5, and I start with initial values of 59 for @f and @fr, so far so good. At frame 59, I get new values of @f = 115 and @fr = 56. Sounds good, right? But after frame 59, it reverts to the initial values, so there's never a second blink. Why isn't the last line, which should add the interval of the next blink onto the frame number of the previous blink, actually doing that?
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
gordig
At frame 59, I get new values of @f = 115 and @fr = 56. Sounds good, right? But after frame 59, it reverts to the initial values, so there's never a second blink.

That's because at frame 59 it ($F) matches your code you have set up for only that Frame.

gordig
Why isn't the last line, which should add the interval of the next blink onto the frame number of the previous blink, actually doing that?

Unless it's a specialized node, the wrangle does not 'see/know' what the values are for the previous frame, and so neither what values where calculated. It is only calculating what you have on any given frame.

If you want a blink at other specific frames you will have to make a conditional statement for those specific frames,
or you could make use of a solver sop which can remember previous frame values so that your code can accommodate that scenario.
Edited by BabaJ - April 26, 2024 08:49:42
User Avatar
Member
29 posts
Joined: Sept. 2019
Offline
BabaJ
gordig
At frame 59, I get new values of @f = 115 and @fr = 56. Sounds good, right? But after frame 59, it reverts to the initial values, so there's never a second blink.

That's because at frame 59 it ($F) matches your code you have set up for only that Frame.

gordig
Why isn't the last line, which should add the interval of the next blink onto the frame number of the previous blink, actually doing that?

Unless it's a specialized node, the wrangle does not 'see/know' what the values are for the previous frame, and so neither what values where calculated. It is only calculating what you have on any given frame.

I'm just having trouble figuring out the logic, because I declared @f outside the conditional, and when the conditional executes, I would expect it to store the new value of @f, but it isn't. It's not about the values of the previous frame, it's the += inside the conditional. If that gets stored by the conditional executing, then the new value of @f will drive the next blink. If I'm conceptualizing this wrong, please explain how, because like I said, I'm not very experienced in thinking like a programmer.

BabaJ
If you want a blink at other specific frames you will have to make a conditional statement for those specific frames,
or you could make use of a solver sop which can remember previous frame values so that your code can accommodate that scenario.
It did occur to me last night in bed that I could pre-generate a list of blink frames based on the total frame number of the timeline, so I'll probably attempt that next.
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
gordig
If that gets stored by the conditional executing, then the new value of @f will drive the next blink.

But it doesn't get 'stored'. It only knows what the current values as they are per frame.


gordig
I could pre-generate a list of blink frames based

Yes...that's kind of a 'brute' force way of doing things.
You might want to look at how sop solvers work, as you can work as if values are stored.

If you look at this page, the initial explanation should help show how it is similar with what you are doing.
https://tokeru.com/cgwiki/The_solver_sop.html#prev-frame-vs-previous-frame [tokeru.com]
User Avatar
Member
29 posts
Joined: Sept. 2019
Offline
Everything I'm reading about the Solver SOP suggests that it's meant to run every frame, so how would I incorporate that into a setup like I'm trying to build? If I plug that same VEX code into the Solver SOP, I get the same results as before, and I'm having trouble conceptualizing any other way to do it.
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
gordig
Everything I'm reading about the Solver SOP suggests that it's meant to run every frame,

Yes it does run every frame, but it also has the capacity to 'know/get' values from the previous frame.


gordig
If I plug that same VEX code into the Solver SOP, I get the same results as before

Yes of course you will have to modify your code to reflect what you want to do.
At the moment you actually don't have any 'absolute' values to reference to carry forward for each next frame, because you are constantly changing your reference every frame (@f) and changing it twice on those instances in which it matches a frame number.
Edited by BabaJ - April 28, 2024 09:08:57

Attachments:
Turn_Green.hiplc (128.4 KB)

User Avatar
Member
29 posts
Joined: Sept. 2019
Offline
I finally had a chance to look at that scene file.

At first, I was furious that I either didn't know or had forgotten that @Frame and $F are equivalent, and that swapping my $Fs out for @Frames might help not just this, but my experiments with CHOPs. But the problem wasn't solved.

I kept at it, making my VEX look more and more like yours, swapping between @ and local variables, adding variables outside of the Solver, changing the syntax on different snippets of code, moving variables around, and I was furious because I couldn't see a single reason why effectively the same code wasn't acting the same way.

I finally got it to work, and I'm furious that I don't know exactly what I did to fix it.

Thank you.
  • Quick Links