ParticleController RT_CLAMP behaviour when initialized from a GameTaskQueue

This scares me. Try:


    protected void simpleInitGame() {
        Callable c = new Callable(){
            public Object call() throws Exception{
                ParticleMesh pm = ParticleFactory.buildParticles("p", 50);
                ParticleController pc = (ParticleController) pm.getController(0);
                pm.setLocalScale(0.01f);
                pc.setRepeatType(Controller.RT_CLAMP);
                pm.forceRespawn();
                pm.updateRenderState();
                rootNode.attachChild(pm);
                return null;
            }
        };
        GameTaskQueueManager.getManager().update(c);
    }


In a plain SimpleGame.

I'd expect the particle effect to play once. However it seems like the particle size and color update as expected, but the location stays the same. Different warmUp amounts and calling pm.updateWorldData() a few times don't help.
(The problem is the same for the first iteration with RT_WRAP, but it is easier to see what I mean with RT_CLAMP set)

SimpleGame does not work with GameTaskQueueManager.

lex said:

SimpleGame does not work with GameTaskQueueManager.

Yes it does. See BaseSimpleGame.update():


        // Execute updateQueue item
        GameTaskQueueManager.getManager().getQueue(GameTaskQueue.UPDATE).execute();


Currently line 192 in BaseSimpleGame. The same is of course done for GameTaskQueue.RENDER accordingly.
As I stated in my post, the particles are there, but it appears as if the controller is not properly updated.

Wow, I never though GameTaskManager was put in the SimpleGame  :-o



Are you using multiple threads? If you have one thread, there is no need for GameTaskManager. Its very easy to get a deadlock on a single threaded game with GameTaskManager. Queue a task, and then call Futur.get()… and you have a deadlock.



Does your code work if you call it inside simpleInitGame() without using GameTaksManager?



If yes, there problem might be the following:

SimpleGame provides lots of housekeeping calls after initialization, like


rootNode.updateRenderState();
rootNode.updateGeometricState(tpf, true);



When your taks is executed on the GameTask queue, you might be missing some of those housekeeping calls.

I know. This is just a test case simplified as much as possible. In my actual application I have plenty of multithreading, and that's how I first encountered this error. So it exists for multiple threads just the same, it's just not neccessary to multithread to showcase the problem.

it's just not neccessary to multithread to showcase the problem.

Definitely true. I just thought you could fix it by not using the GameTaskQueue, if you were using single threaded SimpleGame.

Other than that, test without the GameTaskQueue by calling your code in simpleInitGame(). I think you might be missing something like


pm.updateGeometricState(0, true);



That call also updates controllers.

try this:


    protected void simpleInitGame() {
        Callable c = new Callable(){
            public Object call() throws Exception{
                ParticleMesh pm = ParticleFactory.buildParticles("p", 50);
                ParticleController pc = (ParticleController) pm.getController(0);
                pm.setLocalScale(0.01f);
                pc.setRepeatType(Controller.RT_CLAMP);
                pm.setControlFlow(true);
                pm.setReleaseRate(10);
                rootNode.attachChild(pm);
                pm.updateRenderState();
                pm.forceRespawn();
                return null;
            }
        };
        GameTaskQueueManager.getManager().update(c);
    }

Wow. Turns out that calling pm.updateGeometricState(0f, true) anywhere inside call() indeed fixes the problem.

Apparently because ParticleGeometry contains a Vector3f "worldEmit" which is initialized to 0,0,0 - setting it "manually" instead of calling updateGeometricState() also fixes the issue. Naturally an emission direction of 0,0,0 does not look very splashy :smiley:



Should I have expected that? Should I always call updateGeometricState() after initializing SceneElements? I feel like a jME noob now, and that with only a few posts left to hero status :smiley:



@renanse:

thanks, but I didn't want flow control for that specific effect - and setting the releaseRate very high gives exactly the same issue. It seems to be fixed, or maybe worked around now however - if the described behavior isn't intended it should be fixed by initializing worldEmit to 0,1,0 instead of 0,0,0. Or am I mistaken?

Since it is dependent on your particle settings (emissionDirection and rotateWithEmitter, etc.) you will indeed need to call updateGS after configuring your particles so they will be aligned properly from frame 1.  Setting the default to 0,1,0 is ok, but kind of masks the problem (people might set the emission direction to 0,0,1 for example and then be confused when it's still going off on Y.  Maybe we need a "makeReady" type method that will beg people to call it at the end of setup?

Looks like this isn't over yet… In my actual game the problem is not fixed only by calling updateGS. But using flow control and a huge release rate plus calling updateGS helps.

I'll look into a "makeReady" method of some kind when I get back to work next week.