Jump to content

Particle Velocity Grid Advection


Recommended Posts

The title of this post, is a terrible amalgamation of words, so i apologize. The question i'm trying to tackle is, to take particles that are being advected by a volume in pops, and remap the animation so the particles only travel in a grid like manner. I'm aware of a few techniques that can accomplish this, but none of them work if the particles are being advected. I really don't even know where to start on this, my first thought is filter the velocity volume that's advecting the particles into basically voxels where each voxel can only have a velocity in one of six directions, based on the average velocity of that given voxel.. Writing that out, sounds kind of silly... But it makes the most sense currently to my brain, as opposed to some crazy pop vops magic.

 

If anyone knows of any reference that could help me get to a solution that'd be greatly appreciated. I've been scratching my brain over this for a fairly large chunk of time, but can never seem to make any actual progress. Maybe i can use some chops post advection to do it... I'll keep playing with it in the mean time. 

 

Anyways thanks for reading this terribly written post, and i look forward to any and all input! This forum is legit incredible, so honestly thanks in advance if you post at all. It means the world to me :) 

 

-Jake 

 

 

Link to comment
Share on other sites

tl;dr At each step make sure your particles only go in one direction, up, down, left, right, forward, or backward.

 

You want to quantize your velocities to only point in the 6 cardinal directions at each time step, X+, X-, Y+, Y-, Z+, Z- aka (1,0,0) , (-1,0,0), (0,1,0) , (0,-1,0) , (0,0,1) , (0,0-1) .

 

Quickest way I've found to do this (with my remedial math skills), is to create a switch based on the greatest of the directions (and of course in a logical way that takes into account ties) that switches between hard coded direction vectors.

 

You can do that in the particles or in the velocity field to slightly different effects. You can do this with a wrangle node, in VOPs, in python, heck it can probably be done in CHOPS.

  • Like 1
Link to comment
Share on other sites

OH that makes so much sense. Sweet, so it is easier than i was realistically making it out to be! I tend to over think problems.... Anyways, I will try this out for a bit, and then try it some more in the morning when i have a lot more time, and i will report back with my results!!! You're the best.

 

-Jake 

  • Like 1
Link to comment
Share on other sites

Not sure if this is proper protocol, but i wanted to report back with results! I initially set this whole thing up in VOPs over the weekend. However the set up with 6 switch comparisons, and loads of if statements became super messy, and my VOP flow just wasn't easy for me to tweak, let alone share with ya'll. However yesterday i had a bit of a lull at work, so i wrote the set up in VEX which ended up being so much easier. It's really my first time writing VEX, coming from python for C4D, but coding is pretty universal so it wasn't hard to get the syntax down, especially for such a simple set up! There's tons more i want to add to it, especially randomizing the angular velocity a bit so that the particles all kind of take there own path. 

 

I set this project file up with a simple velocity field to advect the points. But really this should work with any type of advection or particle motion.... Maybe... No promises. I tried to comment the code, so it could be useful to someone potentially?

 

Anyways, thanks again Kleer for the help!!!!!!! Much appreciated. 

HOUDINI_GridAdvection_v003_ODFORCE.hipnc

Link to comment
Share on other sites

  • 3 weeks later...

I find it much easier to do angular constraints with polar coordinates. Try replacing the code in your wrangle with this:

vector toPolar(vector v)
{
    float r = length(v);
    float th = acos(v.z/r);
    float phi = atan2(v.y, v.x);
    vector a = set(r,th,phi);
    return a;
}

vector toCartesian(vector v)
{
    float x=v.x*sin(v.y)*cos(v.z);
    float y=v.x*sin(v.y)*sin(v.z);
    float z=v.x*cos(v.y);
    vector a = set(x,y,z);
    return a;
}

vector a = toPolar(v@padd);

float ang = radians(90); // constraint angle. Could use different values for theta and phi
a.y = ang*floor(a.y/ang); // theta
a.z = ang*floor(a.z/ang); // phi
a.x = 1; // comment out to keep velocity field magnitude

v@padd = toCartesian(a);

@P += (v@padd* @TimeInc);

This will constrain theta and phi to 90 degree angles, but it will work just as well for any angle.

 

 

  • Like 3
Link to comment
Share on other sites

Wow Nick, this is a much, much smarter implementation than the bung i came up with. So much cleaner. If you don't mind me asking, what other situations benefit from switching out of cartesian and into polar? I'm definitely a novice at coding, especially when dealing with vector math, so i'm super interested in learning possible applications of this. 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...