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

@zarch said: The order doesn't actually matter so long as its the same each time...which it will be.

I’d just use the order they are defined in the index buffer…

Sorry… I was trying to verify that get1() was the first in the buffer. I just didn’t state the question very well. I’ll assume that this is the case and see how it goes!

1 Like

@zarch or whoever else

This is getting a bit more confusing than originally thought.

Here is the problem:

The center point of any given triangle needs to be assumed as 0,0,0 so the random offset could be +/- half the length between point a,b… etc, etc

I’m a bit fried atm trying to fix issues with my machine and the new install of JME. I’m getting the following any time I try and run a project… and though it doesn’t stop anything if I continue… it is pissing me off:

[java]
run:
C:\Users\t0neg0d\AppData\Roaming.jmonkeyplatform\3.0RC2\var\cache\executor-snippets\run.xml:48:
Cancelled by user.
BUILD FAILED (total time: 1 second)
[/java]

The problem line being:

[java]
<translate-classpath classpath="${classpath}" targetProperty=“classpath-translated” />
[/java]

Any way I could request some help on figuring out the random emission point thing? =) And any suggestions for the error I am getting would be a huge help also!! I also don’t see any of the updates you added for card specific resolution options. I have the old settings window /boggle

1 Like

@anyone

I had another thought about finding the random offset. What I have here isn’t quite right… but I think it is heading in the proper direction based on the specific need. Shouldn’t I be able to use interpolate between point A and B and then again between A and C add the two outcomes then divide the total by two? Like so:

[java]
p1.set(triStore.get1().subtract(triStore.getCenter()));
p2.set(triStore.get2().subtract(triStore.getCenter()));
p3.set(triStore.get3().subtract(triStore.getCenter()));

return (p1.interpolate(p2, FastMath.rand.nextFloat()))
.add(p1.interpolate(p3, FastMath.rand.nextFloat()))
.divide(2f);
[/java]

Something along these lines?

Yeah… I’m pig headed, but I can’t seem to properly translate the other method of doing this. =(

1 Like
@t0neg0d said: @anyone

I had another thought about finding the random offset. What I have here isn’t quite right… but I think it is heading in the proper direction based on the specific need. Shouldn’t I be able to use interpolate between point A and B and then again between A and C add the two outcomes then divide the total by two? Like so:

[java]
p1.set(triStore.get1().subtract(triStore.getCenter()));
p2.set(triStore.get2().subtract(triStore.getCenter()));
p3.set(triStore.get3().subtract(triStore.getCenter()));

return (p1.interpolate(p2, FastMath.rand.nextFloat()))
.add(p1.interpolate(p3, FastMath.rand.nextFloat()))
.divide(2f);
[/java]

Something along these lines?

Yeah… I’m pig headed, but I can’t seem to properly translate the other method of doing this. =(

I don’t think that does what you want… but not because of the theory but because of the implementation. interpolate() is resetting the vector p1 each time. So if you imaging that both of your nextFloat() calls returned 1 then you’d end up with p3 + p3. And while the divide by 2 will help take care of it I still can’t help but think it’s not really what you mean.

The divide(2) is always superfluous because it will always give you p1.interpolate(p3, FastMath.rand.nextFloat()))

Edit: where p1 at that point is the result of p1.interp(p2, nextFloat())

2 Likes
@pspeed said: I don't think that does what you want... but not because of the theory but because of the implementation. interpolate() is resetting the vector p1 each time. So if you imaging that both of your nextFloat() calls returned 1 then you'd end up with p3 + p3. And while the divide by 2 will help take care of it I still can't help but think it's not really what you mean.

The divide(2) is always superfluous because it will always give you p1.interpolate(p3, FastMath.rand.nextFloat()))

Edit: where p1 at that point is the result of p1.interp(p2, nextFloat())

That explains the odd offset. I forgot interpolate store the outcome in the original vector.

Awesome. If I use the proper number of temp vectors and fix the divide thingy, this should work.

Thanks for pointing this out!!

1 Like

@zarch Um… need to apologize for earlier lol Yes, there will be a need for more than the point and quad meshes. I completely spaced standard impostors… which would actually make for an awesome particle shape for normal emitters as well.

@myself (keep this in mind):

  1. Default material and sprite setup needs to be separated. Additive is not always the solution :stuck_out_tongue:
1 Like
@t0neg0d said: That explains the odd offset. I forgot interpolate store the outcome in the original vector.

Awesome. If I use the proper number of temp vectors and fix the divide thingy, this should work.

Thanks for pointing this out!!

It’s interesting because:
p1.interpolate(p2, FastMath.rand.nextFloat());
p1.interpolate(p3, FastMath.rand.nextFloat());

…is enough to find a point in the triangle but I don’t know what the distribution looks like. Could be a bit concentrated towards p3.

Edit: but actually that may not matter since I think the add + divide(2) approach (when done properly) will end up concentrated towards p1. Actually, that approach is broken I think because you will basically never get points near p2 or p3 that are on the p2-p3 edge… and points near that edge will be extremely rare.

The one above with just two interpolations may actually be better since it covers the whole triangle.

1 Like

Also, I don’t think it matters at all if you subtract center first.

1 Like
@pspeed said: Also, I don't think it matters at all if you subtract center first.

This is for later use… it only gets the random offset once. It needs to apply that from the center each frame on an animated mesh. This seems to be working pretty good. I ran a quick test (this is the same female model running with 5000 static particles all rotating along the Y axis at random speeds/directions). I know it still needs work, but the outcome has freaking awesome potential.

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

1 Like

I agree that the distribution will need work… on a simple IsoHemisphere mesh with about 20(ish) faces, you can watch the placement as it spawns new particles and the all three edges seem to be a less likely option. Not sure how to handle distributing them though =(

1 Like
@t0neg0d said: This is for later use... it only gets the random offset once. It needs to apply that from the center each frame on an animated mesh. This seems to be working pretty good. I ran a quick test (this is the same female model running with 5000 static particles all rotating along the Y axis at random speeds/directions). I know it still needs work, but the outcome has freaking awesome potential.

But you can do it just on the result and not the three starting points.

@t0neg0d said: I agree that the distribution will need work... on a simple IsoHemisphere mesh with about 20(ish) faces, you can watch the placement as it spawns new particles and the all three edges seem to be a less likely option. Not sure how to handle distributing them though =(

Which method are you using? Mine or yours? Your original one will never place a point anywhere near p2 or p3… and rarely ever anywhere near the edge p2-p3 and when it does it will be near the center of that edge. This is because you always take the midpoint between points on edge p1-p2 and p1-p3. If you interpolate between p1 and p2 and then interpolate that point to p3 then at least you can cover the whole triangle. Points will be concentrated but at least the extents are physically possible.

1 Like

For an even better distribution, you could interpolate three times.
a = interp(p1, p2, random)
b = interp(p1, p3, random)
result = interp(a,b,random)

I cannot easily predict where that will concentrate… I could with the other two.

2 Likes
@pspeed said: For an even better distribution, you could interpolate three times. a = interp(p1, p2, random) b = interp(p1, p3, random) result = interp(a,b,random)

I cannot easily predict where that will concentrate… I could with the other two.

Awesomeness! I’ll use this for sure!

1 Like

For giggles, I fixed the material on the example I posted.

Ever wonder what it would look like if your lawn got up and chased you?

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

3 Likes
@pspeed said: For an even better distribution, you could interpolate three times. a = interp(p1, p2, random) b = interp(p1, p3, random) result = interp(a,b,random)

I cannot easily predict where that will concentrate… I could with the other two.

Does this use the initial value of p1 2x? or the resulting p1 from the first interp?

1 Like

@pspeed
Ah… without. Thanks so much for the help on this. My initial attempt was at least on the right track. This last post from you however, works great.

1 Like
@pspeed said: For an even better distribution, you could interpolate three times. a = interp(p1, p2, random) b = interp(p1, p3, random) result = interp(a,b,random)

I cannot easily predict where that will concentrate… I could with the other two.

It’s going to concentrate near p1 - essentially you have even distribution along the lines heading from p1->p2 and p1->p3 but as the shape is a triangle you then get the same number of points stretched across the width of the triangle - hence far more concentrated near p1 as thats the point of the triangle.

i.e.

/\

The algorithm above picks a random point along the two lines. A point is then placed at a random point along the line between those two lines.
That has 2 effects:
1: Near the top point those points are going to be concentrated into a much smaller space.
2: The overall effect of the criss crossing is going to greatly increase the probability of points near the center.

So p1 and the mid will get more action than p2 and p3.

You could improve the algorithm above by using the same random float for a and b:
float r = random;
a = interp(p1, p2, r)
b = interp(p1, p3, r)
result = interp(a,b,random)

That will remove the tendency towards the center, however it will still leave a bias based on the size of the triangle - but we can counteract that effect by somehow factoring in the different sizes of the lines.

The “mathematically correct” solution is:

However I have a thought. Can anyone see anything wrong with this algorithm?
float a=nextRandomFloat();
float b=nextRandomFloat();

If (a+b > 1) {
a=1-a;
b=1-b;
}

r=p1+rand(p2-p1, a)+rand(p3-p1, b)

Essentially its my original algorithm but corrected down to a triangle by mirroring any point extending past the trangle back. That should double the probabilities evenly.

1 Like
@zarch said: float a=nextRandomFloat(); float b=nextRandomFloat();

If (a+b > 1) {
a=1-a;
b=1-b;
}

r=p1+rand(p2-p1, a)+rand(p3-p1, b)

http://hub.jmonkeyengine.org/forum/topic/first-look-at-a-new-influencer-based-particleemitter-candidate/page/14/#post-211042

If by rand(X,a) you mean X*a, then yes, it will be ok.

1 Like

yes, sorry you are right. r = p1+((p2-p1)*a)+((p3-p1)*b)

1 Like
@zarch said: You could improve the algorithm above by using the same random float for a and b: float r = random; a = interp(p1, p2, r) b = interp(p1, p3, r) result = interp(a,b,random)

To be pedantic, in that version the points will be grossly concentrated towards p1 because the area is smaller. Using two different random numbers for a and b makes it less predictable because you will have a more even distribution of long and short lines. Because most of the lines cross near the center of the triangle, I agree that you would get extra coverage there but at least those lines tend to be long and the third random will stretch it out.

Anyway, probably better not to second guess the mathematically correct way.

Even your latest one feels like it will clump towards p2… again because the area covered by b is much smaller.

1 Like