POP Store last x-frames of an attribute and interpolate those values

   2785   9   3
User Avatar
Member
8 posts
Joined: April 2016
Offline
Hey there,

I'm currently trying to get started with Houdini, coming from XSI.
So here is one idea, which works for me in XSI and I try to convert it to Houdini:

I have particles and set their direction by their velocity, which works fine. If at one frame they move quickly in another direction and back, it doesn't look very nice though. So I'd like to accumulate the previous x-amount-of-frames of velocities and then average them, so I get a smoothed version.
In XSI I can store the previous values into a per point array - so I can tell it, for every point to store the previous x-amount of velocities onto every point. After that I can average that array, so I get one vector per point, which I can use for my direction.

Does anybody know, how to achieve that in POP - I didn't even find out how to get values of a previous frame. So for now I tried a timeshift after my POP network and get the last three frames. After that I use a point VOP to average them but I have to manually set this up for every extra previous frame and the point VOP also just takes four inputs, so it just works for the last three frames maximum, so this solution isn't a particularly elegant solution.

I attached a video showing, what's the result, I'm getting with XSI - I created particles, which move in their opposite direction every tenth frame to visualize the problem. Left is, if I just use their velocity for direction - right, if I use the averaged version.

Cheers, Lukas

Attachments:
directionFromVelocity_vs_interpolatedVelocity.mp4 (4.6 MB)

User Avatar
Member
402 posts
Joined: June 2014
Offline
Hi _EL,

Not sure if I've understood completely, but try this in a POP wrangle and see if that's the kind of technique you're looking for:
append(v[]@prev, v@v);
if(len(v[]@prev) > chi("trail_length"))
    v[]@prev = v[]@prev[1 : (chi("trail_length")+1)];

EDIT: Sorry Lukas, your name was there after all!
Cheers,
Henry
Edited by friedasparagus - April 11, 2017 13:42:01
Henry Dean
User Avatar
Staff
5551 posts
Joined: July 2005
Offline
Nice answer using the slice index.

There are two distinct ways of doing this:
1) Augment your POP sim to store your trailed velocities as it simulates. Then you can just average out that trailed point attribute when done.

2) In SOPs, load the previous N frames with Time Shift and average them there.

Attached shows both in action. The first approach is the most straightforward, but does use more memory, disk storage, and simulation time, so may not be practical for huge sims.
Edited by jlait - April 11, 2017 14:07:13

Attachments:
average_vel.hip (270.9 KB)

User Avatar
Member
8 posts
Joined: April 2016
Offline
Hey, thank you very much guys!

I'll try those things and see if I understand, how it works.

Cheers, Lukas
User Avatar
Member
8 posts
Joined: April 2016
Offline
Hi,

@Henry - sorry, but I can't get my head around that expression, I can't find out what chi(“trail_length”) is doing at all. And if I try to put this into my network nevertheless, the “prev” array it creates is empty. Sorry my knowledge is still too low level to understand this kind of expression but thanks for your effort!

@jlait - thanks, this is exactly what I was looking for!
Version 1 I now understand completely and it seems to be pretty much the same thing I do in XSI.
Very cool, that you also pointed out a more efficient alternative to that. Though in version 2 I don't quite understand that expression “self + point(1, ‘v’, idtopoint(1, @id))”. Would be really cool, if you could tell a little bit, how this is working.

Thanks guys!
Cheers, Lukas
User Avatar
Member
402 posts
Joined: June 2014
Offline
Hi Lukas,

sorry! Didn't know how familiar you were with wrangles! To the right of the expression field you'll see a little button. After pasting in the expression, you click that and the wrangle will automatically generate those parameters on the node, so you can adjust things.

jlait's examples are far more rounded!
Henry Dean
User Avatar
Member
8 posts
Joined: April 2016
Offline
Hey thanks,

yeah, I didn't know that yet. So now this is working too, cool!
So, if I get it right, you just create this trail_length value to tell it the maximum number of values, you'd like to store in that array. Nevertheless I don't quite understand, why this is working - you say if(the size of the array is bigger than the trail_length value), which makes sense to me but why does that second part limit the array size?

Cheers
Edited by _EL - April 12, 2017 04:20:23
User Avatar
Member
402 posts
Joined: June 2014
Offline
That's my rough attempt at getting a queue to work in VEX, the values are appended (stuck on the end of the array) and we want to discard the values from the beginning of the array when it reaches the desired size.

These might be handy:
Stack [en.wikipedia.org]
Queue [en.wikipedia.org]

I haven't got jlait's version open right now, but he does basically the same thing with different functions (I think the removevalue(some_val)? which removes the first found instance of that value, so gives the same behaviour).

Does that help?
Henry Dean
User Avatar
Member
8 posts
Joined: April 2016
Offline
I will read through that, thanks!
jlait used this:
vector @vel_list[];
append(@vel_list, @v);
if (len(@vel_list) > 10)
    removeindex(@vel_list, 0);

“removeindex” was easier to understand for me
User Avatar
Member
402 posts
Joined: June 2014
Offline
Ah! That's the one! Note made to self (K.I.S.S.)
Henry Dean
  • Quick Links