Influencer-based ParticleEmitter candidate (mesh-based animated particles)

@t0neg0d said: And... on the subject of motion blur... can you post a vid to show an example of what the final effect looks like? I would love to see this as an influencer with settings.

First one which I have found:

[video]http://youtu.be/adwPJFqHEZQ[/video]

Not sure why it got downscaled to 480p… it was some time since I have last played with youtube. Anyway, imagine that pixels are not so pixxelated :wink:
Look at the rays when they are reversing. They go out of center being long (fast), then they get short when reversing and then again getting longer as they get into the center.

I’m cheating at the moment a bit - I’m extending particle in both directions, instead of only forward. This means that in some cases, when you increase the speed fast enough, end of the particle can actually travel backwards. Fortunately, it is not visible with most models.

2 Likes

If I’m at youtubing, here is another one

[video]http://www.youtube.com/watch?v=_i2WPHNqFKI&hd=1[/video]

Blue and red thingies are showing ‘billboard to ground’ for the rings. Yellow column is align-to-vertical-axis (z in my case, y in common case).

2 Likes

@abies That’s a great looking effect!

EDIT: Umm… they all are =)

1 Like

They are indeed very nice, but I don’t see any motion blur. Like, nothing at all.

Maybe it’s the low resolution.

1 Like

Sorry for jumping from topic to topic, but I forgot to describe the current SpriteInfluencer and list the options to see if this is all it needs to do.

si.setUseRandomImage(boolean);

Allows for random start images. If animated it will determine the time per frame from the current to last and animate over the life of the particle

si.setAnimate(boolean);

Will either do the above if that option is enabled, or determine the time per frame from 0 to n frames over the life of the particle

si.setFixedDuration(int targetFPS);

This will enabled cycling of animation and attempt to display the frame according to the specified FPS

Does this need to do anything else? Or does this about cover it?

1 Like
@madjack said: They are indeed very nice, but I don't see any motion blur. Like, nothing at all.

Maybe it’s the low resolution.

It’s stretching the particle based on velocity… it’s a great approximation considering… and an even better effect if used with what it does in mind (like in the vids)

1 Like
@t0neg0d said: It's stretching the particle based on velocity... it's a great approximation considering... and an even better effect if used with what it does in mind (like in the vids)

Ah, in that case what we’re seeing makes perfect sense. Good.

1 Like

The main thing I don’t like is the switch on the enum. Sometimes it’s unavoidable but a much better pattern is to define the behaviours inside the enum itself.

Make sure the mesh type is set to streaming.

The only other possible saving would be to use a local buffer and then do a batch call to stream it all across. That would need to be measured to see if it actually helps. It’s something I’ve been meaning to investigate but never had a chance.

1 Like

@abies
Sooo… here was my solution for particles not following the emitter… this look ok to you?

[java]
tempV3.set(p.position).subtractLocal(emitter.getNode().getWorldTranslation().subtract(p.initialPosition));
[/java]

1 Like

There are a few assumptions in that line that I wouldn’t be comfortable with depending on how things may or may not move.

Why do particles need to follow the emitter? Better off just having them always work in local space and if people want them to follow the emitter just attach the particles to the same node.

1 Like
@zarch said: There are a few assumptions in that line that I wouldn't be comfortable with depending on how things may or may not move.

Why do particles need to follow the emitter? Better off just having them always work in local space and if people want them to follow the emitter just attach the particles to the same node.

Oh… this isn’t what you just described.

follows emitter = particle moves along velocity vector local to the node.
doesn’t follow emitter = particle simulates being in world space (without being in world space).

It will be a flag of the emitter itself… I wanted to make sure it wasn’t coupled to the particle update in any way that would a) be the only option and b) not work in the GUI node.

And… while we are on zeee subject. Here is what is going to end up happening with the billboarding stuff after give some thought to what you said. There are so many options possibilities that I am going to allow different billboarding per axis and move the single flag setting to a more robust influencer.

So, in theory:

x = BillboardMode.Camera
y = BillboardMode.Velocity
z = BillboardMode.UNIT_Z

This should allow for absolutely any configuration that you could dream up. (I hope)

1 Like

Regarding switching between local and world space - this is a pain. Basic rules are simple - if you go to world space, everything which you persist between updates is world-space, otherwise it is localspace. Unfortunately, this means that at every operation, you have to think twice in which space you are applying modifications. For example - initial velocity. If you have local-space emitter, you just set velocity to whatever is specified. If you have world-space emitter, you set it to local-to-world.multNormal(velocity). So, if you have gun spewing bullets attached to hand and gun is firing particles at 0,0,1 direction, you want to have it translated as soon as possible in world space. On the other hand, if you have lightsaber emulated by frequently firing particles particles, also shining in 0,0,1 direction, velocity stays in local space - you want to move it in straight local line, without converting there and back each time.

Gravity is even more messy - it will be probably always in world space, even if particles are in local space. This means that you need to multiple gravity force by world-to-local translation (inverse of local-to-world) to apply it to velocity in local-particles case.

And so on - every time you do addition or multiplication, you have to think twice about coordinate space.

Maybe it is not needed for your case? Maybe just moving emitters is good enough with particles always detaching immediately and staying in world space? Will save a lot of work and it is a lot more common case.

1 Like
@abies said: Regarding switching between local and world space - this is a pain. Basic rules are simple - if you go to world space, everything which you persist between updates is world-space, otherwise it is localspace. Unfortunately, this means that at every operation, you have to think twice in which space you are applying modifications. For example - initial velocity. If you have local-space emitter, you just set velocity to whatever is specified. If you have world-space emitter, you set it to local-to-world.multNormal(velocity). So, if you have gun spewing bullets attached to hand and gun is firing particles at 0,0,1 direction, you want to have it translated as soon as possible in world space. On the other hand, if you have lightsaber emulated by frequently firing particles particles, also shining in 0,0,1 direction, velocity stays in local space - you want to move it in straight local line, without converting there and back each time.

Gravity is even more messy - it will be probably always in world space, even if particles are in local space. This means that you need to multiple gravity force by world-to-local translation (inverse of local-to-world) to apply it to velocity in local-particles case.

And so on - every time you do addition or multiplication, you have to think twice about coordinate space.

Maybe it is not needed for your case? Maybe just moving emitters is good enough with particles always detaching immediately and staying in world space? Will save a lot of work and it is a lot more common case.

Actually, you should be able to keep everything in local space…set a temp variable with the final local position and then subtract the current world space (of the emitter) and add the initial world space (of the emitter when the particle was emitted). This should simplify everything allowng you to always work in one or the other.

1 Like

@abies
Ok… bare with me here. I want to make sure the emitter will do everything that you talked about (which means at some point, you’ll have to run me through the particle stretching technique… or maybe write an influencer or 5?

I know absolutely NOTHING about creating effects with particle emitters, so I tried to approximate some of the stuff I saw in your vids. I really appreciate you sharing this stuff, the idea of non-random particles hadn’t crossed my mind (embarrassing). So, here was the result of some of the updates to a few of the influencers to ensure they do what you showed as examples.

[video]http://youtu.be/AKyTXdIGnLY[/video]

4 Likes

Often, perfect is the enemy of good.

I wonder if it’s better to nail down the particle emitter and a few solid influencers and then iterate the rest. In the mean time, users can always create their own influencers if they don’t exist yet.

1 Like

Yes I agree with Paul, your system looks pretty solid now.
It’s time to post a patch, you’ll add other influencers later

1 Like

Wow f***, last videos are amazing !!! Can’t wait to play with this new emitter system…Possibilities seem infinites…

1 Like
@t0neg0d said: Actually, you should be able to keep everything in local space...set a temp variable with the final local position and then subtract the current world space (of the emitter) and add the initial world space (of the emitter when the particle was emitted). This should simplify everything allowng you to always work in one or the other.

Rotation and scale are your enemy in this. At the very least you will need to do getParent().getWorldTransform().transformInverseVector()

Honestly I’d just say attach the emitter to the root node if you want it in world space - but then tie the source of the particles to whatever you like and not require emitter and source to be in the same node.

1 Like
@zarch said: Rotation and scale are your enemy in this. At the very least you will need to do getParent().getWorldTransform().transformInverseVector()

Honestly I’d just say attach the emitter to the root node if you want it in world space - but then tie the source of the particles to whatever you like and not require emitter and source to be in the same node.

Same thing can be done for rotation and scale.

The problem with the second statement is… that would only work if the particles were individual meshes. No matter where you attach it, the particles are still going to move as a group unless you account for it via code. They are one mesh. Also, the source emitter shape only has to reside in the scene graph if it is animated, otherwise it is just handled as data.

1 Like
@nehon said: Yes I agree with Paul, your system looks pretty solid now. It's time to post a patch, you'll add other influencers later

I just need to document and I can do this.

I need to know a few things:

  1. Do you want the influencers pre-loaded?
  2. Do you want them all enabled by default? Or just gravity, color, size and rotation?
  3. The entire emitter and related classes are complete rewrites. How should I prepare the source for you?
1 Like