PopsSplitAvoid

From cgwiki
Revision as of 16:47, 18 March 2022 by MattEstela (talk | contribs) (Created page with "Someone on the cgwiki discord shared a link to an update from the Insydium C4D XP particles plugin, some cool stuff covering avoidance, splitting, grid noise, replication: ht...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Someone on the cgwiki discord shared a link to an update from the Insydium C4D XP particles plugin, some cool stuff covering avoidance, splitting, grid noise, replication:

https://www.youtube.com/watch?v=Cr9uzVLjjLg

I thought 'surely this can't be too hard to emulate in Houdini?'. Well, it was harder than I expected, so kudos to Insydium for making such behaviour easy to access. From my perspective it was good to get a better handle on pops fundamentals, here's what I discovered.

Basic setup

Using the XP video as reference I emitted from a square (hot trick: make a circle sop, XZ plane, 4 sides, rotated 45 degrees), resampled the square to maybe 15 points per side, open arc mode.

In pops I just wanted the particles to emit from those exact grid points, and only emit one particle on the first frame. To do this I modified the particle source mode to 'all points' instead of scatter. In order to get exactly one particle generated per point, I set const activation and rate to 0 (just to remind myself thats not used at all), impulse count to 1 which means 1 particle per timestep, and impulse activation to $SF==1. This expression will be 1 when the Simulation Frame is 1, otherwise 0, so that gets the result I'm after.

Grid noise

My first instinct here was to see if I could take the default pop force/wind, and grid it up. I'd done this before, but was curious if I could do it without looking at my earlier notes. My instinct was to look at the force vector work out which component was biggest, make it 1, and make the others zero. The max() function if given a vector, will return a vector where all the components are set to the biggest value, eg max( {0.7, 0.3, 0.2} ) would return {0.7,0.7,0.7}. Knowing that, here's a long way to convert that to a 0 or 1 value per component:

vector tmp = {0,0,0};
if ( @force.x == max(@force) ) tmp.x = 1;
if ( @force.y == max(@force) ) tmp.y = 1;
if ( @force.z == max(@force) ) tmp.z = 1;

@force = tmp;

Sort of works, but what happens if the force has negative and positive values? I realised here I don't really want the maximum value, but the one with the biggest magnitude. Tweaking the code...