Particle System Source Code if ya want it…

@t0neg0d said:

It’s useful with billboarding modes that follow velocity, so you don’t get the invisible particle band at certain views (or certain areas of your particle mesh).

I was doing follow-velocity by having 1-degree of freedom billboarding (y axis fixed to velocity and rotation around that to make it most perpendicular to view) - it is working ok with 1-quad particles.

I agree that for grass-like particles which are not billboarding to view, it makes sense to have 3 quads.

1 Like

@normen

please , answer this question ,

http://hub.jmonkeyengine.org/forum/topic/jme3-error-in-applet-only-no-loader-registered-for-type-fnt/

@abies said: I was doing follow-velocity by having 1-degree of freedom billboarding (y axis fixed to velocity and rotation around that to make it most perpendicular to view) - it is working ok with 1-quad particles.

I agree that for grass-like particles which are not billboarding to view, it makes sense to have 3 quads.

These are completely open to change… they were an initial take on various types of billboarding that may be useful.

It would likely be a good idea to centralize this into an enum that has the code for defining up, left and dir in it…seeing as multiple classes make use of this and would make it far easier to modify.

I’m also not sold on my method of particle stretching, as it really isn’t complete and only works with a few of the billboarding options.

Perhaps you can take a crack at moving the billboarding code to an enum, changing what needs to be changed and then have a look at the one line of code particle stretching to see what can be done about it?

@mihir said: @normen

please , answer this question ,

http://hub.jmonkeyengine.org/forum/topic/jme3-error-in-applet-only-no-loader-registered-for-type-fnt/

For real?? O.o Here?

Just for the sake of posting it until I’m able to update the file: Interpolation was written by:

@author Nathan Sweet

As for an enum that contains an overridable method, I’m a little new to the concept… so, I have a question about how to centralize a portion of the following. You’ll notice that Pow2, Pow3, Pow4, Pow5 all have the same code in the overrided apply method. My question is:

  • Is there a way to have one enum value call another with the power as a variable?
    ex: Pow2(2) calls Interpolate(int power), then when apply is called on Pow2, it calls apply from a generalized Pow.apply method? Man, I hope this makes sense.

[java]
enum InterpolationNew {
linear {
@Override
public float apply (float a) {
return a;
}
},
fade {
@Override
public float apply (float a) {
return FastMath.clamp(a * a * a * (a * (a * 6 - 15) + 10), 0, 1);
}
},
Pow(1) { // << I would like this to be the implementation that all other Pow’s call for setting power and when apply is called.
@Override
public float apply (float a) {
return (float)Math.pow(a, power);
}
},
Pow2(2) {
@Override
public float apply(float a) {
if (a <= 0.5f) return FastMath.pow(a * 2, power) / 2;
return FastMath.pow((a - 1) * 2, power) / (power % 2 == 0 ? -2 : 2) + 1;
}
},
Pow3(3) {
@Override
public float apply(float a) {
if (a <= 0.5f) return FastMath.pow(a * 2, power) / 2;
return FastMath.pow((a - 1) * 2, power) / (power % 2 == 0 ? -2 : 2) + 1;
}
},
Pow4(4) {
@Override
public float apply(float a) {
if (a <= 0.5f) return FastMath.pow(a * 2, power) / 2;
return FastMath.pow((a - 1) * 2, power) / (power % 2 == 0 ? -2 : 2) + 1;
}
},
Pow5(5) {
@Override
public float apply(float a) {
if (a <= 0.5f) return FastMath.pow(a * 2, power) / 2;
return FastMath.pow((a - 1) * 2, power) / (power % 2 == 0 ? -2 : 2) + 1;
}
};

final float value, power, min, scale;

InterpolationNew() {
	this.value = 0;
	this.power = 0;
	this.min = 0;
	this.scale = 0;
}
InterpolationNew(int power) {
	this.value = 0;
	this.power = (float)power;
	this.min = 0;
	this.scale = 0;
}
InterpolationNew(float value, float power) {
	this.value = value;
	this.power = power;
	this.min = FastMath.pow(value, -power);
	this.scale = 1 / (1 - min);
}
abstract public float apply (float a);

}
[/java]

Forgive the class name… I’m trying to figure out how to write this before trying to actually implement it.

@t0neg0d
Ignore my comments about three quads - I haven’t noticed that there are multiple subclasses of ParticleDataMesh… just found Impostor one and assumed it is THE implementation. ParticleDataTrimMesh is what I was looking for and thinking about.

1 Like

In reference to my above question about enum, it is as simple as something like this:

[java]
Pow2(2) {
@Override
public void apply(float a) {
return Pow.apply(a);
}
}
[/java]

Or will this create a new object every time it is called?

And, now I’m even more confused…

When using an enum in this fashion, does it create a new instance of Interpolation when you use it?

Not on each apply, just when calling Interpolation.linear?

i.e. if you have one object using Interpolation.linear and the next using Interpolation.swing… it stores new values associated with scale, say for instance… is scale now unique to Interpolation.linear and Interpolation.swing? Or are the values shared… making this a losing proposition and I just need to scratch the idea?

Ugh… ignore me…

I have an issue related to fixedDuration in one of the influencers and I thought it was due to this, as I wasn’t aware of the other issue >.<

You cannot create enum instances dynamically. They are precreated and cached. In example above, there will be only 7 instances of that enum and no amount of referencing and trickery can create different one. Thanks to that, you can for example compare enums with ==.

1 Like

I guess the biggest problem with using an enum as an implementation of a strategy pattern is that no one could ever easily add their own interpolators. Personally, I think you’re better off with an Interpolator interface and some static constants. None of the downsides.

1 Like
@abies said: You cannot create enum instances dynamically. They are precreated and cached. In example above, there will be only 7 instances of that enum and no amount of referencing and trickery can create different one. Thanks to that, you can for example compare enums with ==.
@pspeed said: I guess the biggest problem with using an enum as an implementation of a strategy pattern is that no one could ever easily add their own interpolators. Personally, I think you're better off with an Interpolator interface and some static constants. None of the downsides.

Enough for me… I’ll leave this alone for now. When it does get updated I’ll do this as @pspeed suggest.

@t0neg0d said: Enough for me... I'll leave this alone for now. When it does get updated I'll do this as @pspeed suggest.

A common pattern (used by Guava and other libraries but guava is perhaps the best example and is just a great library) is to have an interface like Interpolator and then a static utility class Interpolators that has factory methods on it.

Interpolators could also have constants for particular instances or depending on your style and the particular use-case, you could have factory methods that just return the constants in the constants case.

I have a similar concept that I used in Mythruna and ported a subset to Monkey Trap. I used the idea of interpolators differently but the interface to class thing might make a good example. I don’t know.
http://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/zay-es/examples/MonkeyTrap/src/trap/task/Interpolator.java
http://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/zay-es/examples/MonkeyTrap/src/trap/task/Interpolators.java

For context, those are some standard ones and then I have an animation specific one that lets me drive different objects as interpolators:
http://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/zay-es/examples/MonkeyTrap/src/trap/anim/AnimInterpolators.java

Not quite the same as what you are doing but is an example of the interface, utility class split.

1 Like
@pspeed said: A common pattern (used by Guava and other libraries but guava is perhaps the best example and is just a great library) is to have an interface like Interpolator and then a static utility class Interpolators that has factory methods on it.

Interpolators could also have constants for particular instances or depending on your style and the particular use-case, you could have factory methods that just return the constants in the constants case.

I have a similar concept that I used in Mythruna and ported a subset to Monkey Trap. I used the idea of interpolators differently but the interface to class thing might make a good example. I don’t know.
http://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/zay-es/examples/MonkeyTrap/src/trap/task/Interpolator.java
http://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/zay-es/examples/MonkeyTrap/src/trap/task/Interpolators.java

For context, those are some standard ones and then I have an animation specific one that lets me drive different objects as interpolators:
http://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/zay-es/examples/MonkeyTrap/src/trap/anim/AnimInterpolators.java

Not quite the same as what you are doing but is an example of the interface, utility class split.

Thanks so much! This is a perfect example of how to do what I was hoping to do!

Gonna jot down things that need to be looked at as I find them…

I was running some more tests… the last one I ran was attaching a series of emitters to a node attached to root and then rotating that node, moving it, attaching a BillboardControl to it, etc, to ensure that it acted the way it should.

This is the results of doing so:

if the emitters are set to setParticlesFollowEmitter(true), all works as you would expect… This is particles in local space.

If it is set to setParticlesFollowEmitter(false), it doesn’t quite do what I thought it would… This is particles in world space (which functions properly if the emitter is attached to the root node, but has some odd results nested).

Here is the relevant code for putting particles into world space, in case someone can spot the issue. I know it has to do with particle position being in local space and subtracting the emitter world translation minus the particles initial position (again in local space). The answer is probably translating the 3 vectors needed into world space, calculating the update, the reverting it back to local space before applying it, but I wanted to ask smart people first.

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

Eh… I think I know what the problem is now.

initialPosition is in local space and has no reference to where the emitter was when it was emitted. So, either initialPosition needs to add the emitter’s current world position, or a snap shot of the emitter’s world position needs to be stored at the time of emission. Probably the latter, just in case the local position is needed for something else at some point.

I’ll fix this tomorrow.

Translation is one thing, but how this works if emitter is being rotated around? Won’t you have to play around with entire matrix transform/inverse transform to make sure that particles really stay in world space?

In NWN emitter, they had 3 modes of operation. Either particle was immediately put into world space (so emitter transform was only defining spawn point), or particle was fully attached to emitter (so every rotation/translation was moving particle as well) or middle-ground - particle positions were in emitter local space, so they were following center of node, but NOT reacting to rotations. I’m not sure if this middle ground solution really adds that much, but for two others certainly are needed.

@abies said: Translation is one thing, but how this works if emitter is being rotated around? Won't you have to play around with entire matrix transform/inverse transform to make sure that particles really stay in world space?

In NWN emitter, they had 3 modes of operation. Either particle was immediately put into world space (so emitter transform was only defining spawn point), or particle was fully attached to emitter (so every rotation/translation was moving particle as well) or middle-ground - particle positions were in emitter local space, so they were following center of node, but NOT reacting to rotations. I’m not sure if this middle ground solution really adds that much, but for two others certainly are needed.

Both of these two options currently work… world space just gets odd funked when the emitter is nested. Hopefully, I’ll get it fixed tomorrow… hopefully.

Sorry… that’s is for the entire transform… either attached or independent… The issues actually may be rotation, not translation… as I can’t find anything wrong with the current implementation. Maybe after sleep all will look shiny again.

hey @t0neg0d, im late to the game here but ive got a little minor input on the bug youre speaking about (where setParticlesFollowEmitter(false) ) seems to not work to create the effect of particles being casted into the world, i think this might help reveal how to fix the problem. I think your underlying concept works, just perhaps you have a typo or a minor mistake somewhere in the logic.

anyways using your example code from the original post (with the exception that I make an “attachmentNode” where i add the control to, isntead of adding the emitter control to the rootnode.

anyway my first try to make this work i did just this:
[java]
e1.setParticlesFollowEmitter(false);

@Override
public void simpleUpdate(float tpf) {
super.simpleUpdate(tpf);

            attachmentNode.move(tpf, 0, 0); // emitter moves to the right



    }

[/java]

of course the smoke trail effect is going straight up, so i thought, “i wonder if i move the emitter node instead?”

so i do this

[java]
@Override
public void simpleUpdate(float tpf) {
super.simpleUpdate(tpf);

            e1.getEmitterNode().move(tpf, 0, 0);



    }

[/java]

well now it looks like the emitter is moving to the right, because its trailing off in to the left… however the emitter itself is standing still.

but if you combine the two lines of code… 0_o it creates the desired effect (moving particle emitter, and particles appear to be cast in to the world).

so its like its just using the translation of the wrong parent node.

i havent yet had the chance to fully understand your emitter system, but from your previous post it looks like the relevant code for this is in ParticleDataTriMesh.java on line 297ish… so I put this in there

[java]
if (emitter.getEmitterNode().getParent() != null) {
System.out.println(“not null”);
tempV3.set(p.position).subtractLocal(emitter.getEmitterNode().getParent().getWorldTranslation().subtract(p.initialPosition));
} else {
System.out.println(“wtf null?”);
tempV3.set(p.position).subtractLocal(emitter.getEmitterNode().getWorldTranslation().subtract(p.initialPosition));
}
[/java]

however its always “wtf null”. this goes into a subthought: perhaps the fact that the emitter node’s parent is null is why the trailing effect isnt working properly.

or maybe you already know all this and im wasting your time >.<. just trying to throw in my discoveries here so that maybe this could be figured out.