Expresso: Controlling speed on ThinkingParticles


#1

Hi all,

I’m trying to figure out how I might set up a particle emitter system using TP so that EACH particle that is birthed from a sphere moves at high speed at first and then slows down the farther it travels from its source, at which point a wind or gravity force carries it off in new linear direction. I was playing around with the Texture & Light parameters in the PMatterWaves node, along with some forces nodes (Gravity, Wind, etc) but not really getting the results I’m after.

Another potential solution I figure might work would be some kind of setup based on each particles’ distance traveled, where a particle can only be affected by an extraneous force after it has traveled past a distance threshold, though I don’t know how to set this up either.

Link here to a downloadable file where I’m trying number of different things (but again, not quite getting the results I’m after.) Hoping someone can lend some insight.

Many thanks!

NpF


#2

You could store the original emission position in a data channel and slow the particle down according to the distance to that. Or if the particles all travel at the same speed use the particle age for this.


#3

Hi Srek,

Many thanks for the reply!
I was able to accomplish what I needed using the PAge node , so thanks a lot for the suggestion. It’s still not entirely clear to me what all the various parameters of this node are useful for, and also how the functionality differs from PAge output port on GetData node. When I get a little free time I’ll be looking for tutorials on the topic.

I’d like to try the other method you suggested as well, though I’m still somewhat of a novice with Xpresso so I only have the faintest clue on how to begin setting that up. I imagine some basic math nodes would be employed here (Compare node, for example)? Would you happen to know of any tutorials that shed light on the topic?

Thank you again!
Nik


#4

Hi,
please be aware that from a physics pov you have a bit of a problem with what you want. The particles are basically balistic after emission, this means that there is no force connecting them to their origin in any way that you could reduce. This means you have to create a force that stops them over time/age/distance. At the same time you want another force to push them in a specific direction. These two forces will act against each other. You should make realy clear to yourself what you expect to happen exactly, otherwise you won’t be able to create a satisfying solution.
Please find attached an example on how to use data channels to store initial values and evaluate them.
I haven’t kept track of what is available regarding Xpresso/TP Tutorials, sorry.
ReduceVelocityOverDistance.c4d (127.5 KB)


#5

Hi Srek,

Many thanks for the reply and for the sample scene - and apologies for the delayed reply.

You’re right, I should have given a little more thought to defining my problem statement, though I think I mentioned I am still very much a novice using node-based / procedural 3d. In any event, I appreciate your help and insights. The setup you sent me is very cool, though I think it only solves part of my problem.

To better phrase my intentions, the thing I would initially like to achieve is to emit particles outward from a moving, spherical emitter, and then essentially offset the absolute position of each emitted particle by the exact same distance that the emitter has moved, per frame. This would give the illusion that the particles are somehow caught in the emitter’s field of gravity, and hence the particles follow the emitter object rather than lag behind, and this is ok with me even if the results are not based on forces or physics. I’ve configured a node network that attempts to create the positional offset, though I’m not getting the results I would like as I don’t think I have a grasp on what the a lot of the different inputs and outputs refer to, and also how to get them talking to each other in the same math language.

As a side note, a potentially hackier way of achieving this would be to cache the particles, and then attach the cached geo to the animated sphere that’s supposed to look like the emitter, though at that point I might as well use a MoGraph cloner setup… though if I can achieve the positional offset via TP/Xpresso, I would assume I could add a multiplier to the network in case I’d want to attenuate the results over time, and add forces too, which would be nice.

Anyway, I’ve attached my file, and included some ‘Remark’ nodes in the Xpresso network in those areas that I find unclear. Below is the text in those ‘Remark’ node repeated, in case you’d want to respond directly here in the forum: Xpresso_ParticleEmitterFollow_01.c4d (411.7 KB)

Thank you again for your help, and apologies again for not stating the primary goal more clearly!
NpF

Overall initial goal is to have the particles follow the sphere, rather than drag behind it, More specifically, each particle’s absolute position should be directly offset by the emitter’s global position, as the emitter moves through space.

Regarding PGetData Position output - I would assume that the ‘Position’ values we get from 'PGetData’s Position output would give us the absolute or at least relative position values for every and all particles emitted, but maybe not? Attaching a ‘Result’ node set to ‘Vector’ seems to only give us a single vector3 value, so I 'm led to conclude that maybe it returns the position value for the PMatterWaves node only (rather than the particles), though I’m not sure this makes sense either, since in theory, shouldn’t this give us same values as the Sphere object’s ‘Global Position’ ?

Regarding PGetData Origin(Vector) output I suppose ‘Origin(Vector)’ refers simply to the world space origin’s vector value (0,0,0) or maybe the emitter’s local xyz coords, and I suppose this is used to somehow compare distance, though I’d also presume this may be irrelevant to the immediate problem (of getting particles’ position to be offset by emitter’s position).

Regarding Sphere object’s Position and Previous Position outputs Judging by results I would guess that ‘Position’ and ‘Previous Position’ can refer only to our object’s local coordinates?

Regarding Sphere object’s Position and Previous Position outputs Judging by results I would guess that ‘Position’ and ‘Previous Position’ can refer only to our object’s local coordinates?


#6

Please find attached a simple example on how to make particles follow an objects movement.
FollowEmitter.c4d (153.9 KB)

Particle Positions (PGetData-Position) are always in global space, any conversion to local object space need to be done by hand, though i don’t think that is neccesary in this case, see example.
Result only works if you have a single particle since it will only ever show the value for the last particle iterated. If you want to see results for all particles you have to print to the console.
Object Position and Previous Position are always local. you can use the memory node to store other values. For your problem Position Velocity should be the better solution, see example.


#7

Hi Srek,

Many thanks again for the insights and for sending over your sample scene.

I took your PStorm derived setup and attached it to the PMatterWaves emitter I had which was using an orbiting sphere driven by its parent’s node’s rotation. (For my needs, these things are kind of important)

Unfortunately, I don’t see too much a difference in the emission-style when the emitter’s Position Velocity is added to the particles’ positions. That said, I put together a little scene that shows three things:

  1. the node setup you shared with me applied to my orbiting PMatterWaves emitter
  2. a slightly different Xpresso setup that’s also meant to get the emitted particles to inherit position values from the emitter position. This one offers a little more control but is still doesn’t quite give the effect I’m looking for as there’s still too much drag and drift
  3. this simply shows a cached TP sim that’s a child of the original emitter sphere. This is generally the effect I’d like to achieve, all the while keeping things in TP/Xpresso so that I can add forces, or pump the particles into a new group based on an event, using PAge or whatever.

I realize this might be akin to use a hammer to turn some screws, but maybe not - happy hear your opinion,
Anyway, here’s the work file, Xpresso_ParticleEmitterFollow_04.c4d (2.3 MB)
and below is a gif showing the above 3 setups in action…


#8

You put the sphere into a null and animated the null. This leads to psition velocity of the sphere being zero.
Check the attached scene for a memory node setup as i describe before.
Also you are using math:Multiply nodes with a third port with a value of 0/0/0, this ensures that the result of any multiplication will always be 0, don’t do that :wink:
FollowEmitter001.c4d (309.0 KB)


#9

Hi again Srek!

This is true - I noticed Position Velocity was returning 0;0;0 so I supposed that to mean that only a local transform animation could return a value for PV, whereas Global Position calls on an object’s relationship to the world’s origin, so I switched the output to GP just to see if I could figure out how to make use of its return values. Obviously I did not figure out how to take it further :confounded:

Thanks for bringing this to my attention! I’m not sure it would have occured to me that simply setting up a new port would automatically introduce a new # value. I’ll certainly pay attention to this going forward.

In any event, Wow Srek - thanks a ton for the History -based setup. This is exactly the effect I was aiming for, and I’m not sure I could have ever arrived at this at my current skill level of xpresso. I did do a break-down for myself below to wrap my head around what each node is doing. This is the extent of my understand of things, and I called out some questions in all caps (not shouting, just inquiring :smiley: ), but if you do have another minute, maybe you could correct any false assumptions I have…

Thanks so much again! :pray:
Nik

Part1
Time: with the Time output, we get a numeric value expressed in seconds and fractions of seconds (0.00) based on where we are in the timeline

Compare: In this case, we’re comparing the Time value from the Time node, with a value of 00:00:00 and returning ‘yes’ or ‘1’ to any value greater than 00:00:00 and then putting this into the emitter’s ‘On’ input. I suppose this simply turns the emitter on after the first frame in timeline.
I CAN’T SAY I UNDERSTAND WHY WE NEED TO DO THIS. IS IT A MATTER OF EXTRACTING A USABLE DATA TYPE? OR DOES IT RELATE TO USING THE MEMORY NODE SOMEHOW?

PMatterWaves: Drives / returns a full set of values for the array of particles being emitted

PGroup: Passes all p values into a particle group which can be referenced by other nodes or functions

Part2
Object Operator: Sphere1: this is where we plug in our sphere geo. Global Position output gives us absolute x/y/z coords for every frame. History Depth parameter is set to ‘2’ instead of ‘1’ so that history can be passed on to the next node, which is…

Memory: This node looks at the previous node’s return, in this case a Global Position vector, and takes the values from not the current frame, but the frame before it.
DO WE NEED TO INCLUDE THE HISTORY LEVEL INPUT (SET TO 1) IF WE SET THE HISTORY LEVEL ON THIS NODE TO ‘2’ ?

Math: Subtract: Here, we are subtracting the Memory node’s output (xyz) from Sphere1’s Global Position output (pos xyz). This gives us not the distance value (which would be a single real or float value per particle) but rather the difference in value for each xyz vector component.

Result: “Leave this node, it forces the evaluation of the memory node on frame 0”
HOW / WHY? OR IS THIS JUST AN XPRESSO IDIOSYNCRASY?

P Pass: This node just holds all the p values from the particle group we specify

PGetData: Here, we are extracting vector position values for every particle per every frame at the first frame it appears, and all frames thereafter.
I PRESUME THESE ARE ALWAYS ABSOLUTE XYZ VALUES RATHER THAN RELATIVE TO EMITTER’S LOCAL XYZ?

Math: Add: Here, we are adding the current particle positions to the difference in distance that the emitter’s local xyz traveled per each frame.

PSetData: This node tells C4D that this is the final evaluation we should call on, or in other words, “this should override the original emitter values”


#10

Compare: The problem with the memory node is that it needs an advance of one frame to work correctly, otherwise it will return the value from the END of the animation.
Memory: History Level 2 would mean the value of two frames before. History Depth is just the number of previous values that can be memorized, it has to be at least the value of History Level. Keep in mind that this can be used in an iterative setup where more than one previous value is used.
Result: Again an artifact of the memory node not having a correct value on frame 0. I use the Result node to make sure the Xpresso setup is evaluated even though no particle is emitted on frame 0.
PGetData: A fundamental thing you have to keep in mind is that once emitted there is NO CONNECTION AT ALL between the emission setup and the particle. The particle is completely independent after emission! You are a bit stuck in the old Standard particle way of thinking here where things work differently.


#11

Compare: The problem with the memory node is that it needs an advance of one frame to work correctly, otherwise it will return the value from the END of the animation.

Yes, this makes sense to me now. A 1-frame call-back at frame 0 would have to call on something, so it makes sense that it would loop back to the last frame.

Memory: History Level 2 would mean the value of two frames before. History Depth is just the number of previous values that can be memorized, it has to be at least the value of History Level. Keep in mind that this can be used in an iterative setup where more than one previous value is used.

I get it now - thanks for lending clarity to this as well!

Result: Again an artifact of the memory node not having a correct value on frame 0. I use the Result node to make sure the Xpresso setup is evaluated even though no particle is emitted on frame 0.

Does the Result node need to be here for the network to do its thing? or do you just include it to verify for yourself that you’re getting the proper value?

PGetData: A fundamental thing you have to keep in mind is that once emitted there is NO CONNECTION AT ALL between the emission setup and the particle. The particle is completely independent after emission! You are a bit stuck in the old Standard particle way of thinking here where things work differently.

I think I understand what you’re saying here - you mentioned earlier that “particles are … balistic after emission”. I take this to mean that they are given a mathematical speed and trajectory at birth, and will follow both of these things until some other value gets introduced.

In any event, thanks very much again for helping me get a better grasp on all of these things!

Cheers,
Nik


#12

Result: Xpresso is evaluated from right to left. The first thing that needs to be there for Xpresso to work is the request for a value to do something with it, then, going left, all nodes neccesary to get that value are evaluated. Without such a trigger nothing happens. The result is the trigger since the other possible trigger is disabled on frame 0.


#13

Thanks again for the reply and the overall lesson, Srek. I think I understand regarding evaluation happening from right to left. I was not aware of this before so I feel enlightened now. :baby: However…

The result is the trigger since the other possible trigger is disabled on frame 0.

What would this trigger be? Ultimately, the PSetData node, correct?


#14

Correct