Results of static mesh test

I just wanted to share this, because it worked out so cool. In the process of making changes to the emitter system to ensure read/write works properly, I had to update my test project. One of the tests is an example of how to use the emitter to generate a static mesh (per a conversation between @mifth and myself) that is only updated if you change some property of the emitter.

The picture below is the emitter being used to create a static mesh of leaves for a tree. It uses the tree branches as it’s emitter shape, sets the particle emission point anchor to Particle_Edge_Bottom, and the Billboards to Velocity_Z_Up_Y_Left. The coolest part of the picture is the frame rate. I’m really anxious to set up a vegetation system using the emitter to place everything.

3 Likes

One last bit on this… wanted to post a closeup of the particle placement on the tree branch mesh… it comes across seamless:

Looks good… and very fast! :smiley:

2 Likes

Do you plan to write a tutorial on this?

1 Like
@sgold said: Do you plan to write a tutorial on this?

I’ll be pushing out an update for the emitter and the builder tonight or tomorrow. Why do I mention this? Because it effects how the emitter is created via code (slightly… paramless constructor, setMaxPartilcles method and in initialize(assetManager) method). So, that being said, I’ll likely put together a Wiki (though the builder will also let you view the code, or export the entire project via j3o now). Boy, that was a lot of blah blah blah… to say this:

With the changes, it looks like this:

[java]
Emitter e1 = new Emitter();
e1.setName(“e1”);
e1.setMaxParticles(6000);
e1.addInfluencers(
new ColorInfluencer(),
new SizeInfluencer(),
new SpriteInfluencer()
);
e1.setShape(branchmesh); // The tree branches as the emitter shape

// Screw using Particle.j3md in this case, you can use any material you like. You just need to pass in the new
// uniform name when calling setSprite if the name differs from “Texture”
Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);
mat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
mat.getAdditionalRenderState().setAlphaTest(true);
mat.getAdditionalRenderState().setAlphaFallOff(.5f);

// Override the material used by emitter
e1.setMaterial(mat);

// Set the texture to use
e1.setSprite(“Textures/leaves.png”, “ColorMap”, 2, 2); // ColorMap is the uniform in Unshaded.j3md

e1.setBillboardMode(Emitter.BillboardMode.Velocity_Z_Up_Y_Left);
e1.setParticleEmissionPoint(Emitter.ParticleEmissionPoint.Particle_Edge_Bottom);
e1.setForce(0.001f);
e1.setLife(1f); // Not really important, just anything but 0
e1.setEmissionsPerSecond(0);
e1.setParticlesPerEmission(0);

e1.setUseRandomEmissionPoint(true);

// Change a few influencer params
e1.getInfluencer(SizeInfluencer.class).addSize(1.5f);
e1.getInfluencer(ColorInfluencer.class).addColor(ColorRGBA.White);
e1.getInfluencer(SpriteInfluencer.class).setAnimate(false);
e1.getInfluencer(SpriteInfluencer.class).setUseRandomStartImage(true);

// And initialize
e1.initialize(assetManager);
rootNode.addControl(e1);

// Now, emit all particles and turn the emitter update loop off
e1.emitAllParticles();
e1.setEnabled(false);
[/java]

1 Like

@sgold
Actually… there are other options. If you are simply using the emitter to create these static meshes (like for instance, using the star-shaped impostor mesh for particles to create grass for endless terrain), you only need a single emitter.

set the Particle Shape by calling:

setParticleType(ParticleDataImpostorMesh.class);

Then:

call reset(); on the emitter
Set a new emitter shape (the new terrain tile)
call emitAllParticles();
then call getParticleMesh().clone();

rinse and repeat.

Now, if you want to use it to create rocks, call:

setParticleType(ParticleDataTemplateMesh.class, myRockMesh);

Then follow the steps above.

Though, since the emitter is disabled, creating a new one per tile might be the better option, saving you the .clone() call… either way…

Also note,

All of the emitter setting apply…

So if you need the grass pointing directly Y-up, the set the emission direction to do so before emitting the grass.
If you need the rocks to face the direction of the normals of the terrain, the set the direction type to normal before emitting the rocks.

You start looking like Pythagoras… only you see emitters instead of triangles :D.

I’ll definitely test this out once I sort this mind puzzling problem with the unpredictable Bucket.Sky nodes rendering order :stuck_out_tongue: