I have a weird problem moving something into a thread.
So, inside a SimpleGame I have code which generates a 3D object, a TriMesh, which is attached to a node, along with several other nodes, such as Text nodes and extrusions. When I do everything inside the Callable, it works all fine. However, as soon as I move the actual computation part of the TriMesh, including adding all the "helper" nodes into a thread, the extrusions start to look buggy (screenshot below) in that suddenly strange wild triangles get added. In the screenshots the green lines/tubes are what is supposed to be there, those strange triangles should not be there.
So, this is the pseudocode which works:
protected void simpleUpdate()
{
if ( update )
{
GameTaskQueueManager.getManager().update( new Callable<Void>()
{
public Void call() throws Exception
{
Node newNode = doAllComputations();
rootNode.attachChild(newNode);
rootNode.updateRenderState();
rootNode.updateWorldVectors();
}
});
}
}
And this is the pseudocode which produces the screenshot below:
when a button is pressed, this thread is started:
class ComputationThread extends Thread
{
public void run()
{
newNode = doAllComputations();
update=true;
}
}
once update is true, the newly computed node is added inside the callable:
protected void simpleUpdate()
{
if ( update )
{
GameTaskQueueManager.getManager().update( new Callable<Void>()
{
public Void call() throws Exception
{
rootNode.attachChild(newNode);
rootNode.updateRenderState();
rootNode.updateWorldVectors();
}
});
}
}
For the computation: I take care of instantiating all Material- and Renderstates inside a Callable as well to avoid OpenGL Exceptions. Everything works, except that these lines/tubes produce these strange triangles.
The creation of these lines works like this:
BezierCurve curve = new BezierCurve("name",p);
float subDivs = (float)Math.floor(dist/minDist);
for ( int i = 1 ; i < subDivs ; i++ )
{
float time = ((float)i)/subDivs;
Vector3f v = curve.getPoint(time);
v = getNextCoordinate();
list.add(v);
}
com.jme.scene.Line line = new com.jme.scene.Line();
line.appendCircle((float)Math.log(20, 0, 0, 8, false);
Extrusion ext = new Extrusion("lineCyl",line,list,new Vector3f(0,0,-1));
ext.setDefaultColor(new ColorRGBA(10.9f,0.0f,0.0f,0.5f));
ext.setRenderState(lineState);
ext.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
ext.setRenderState(alphaState);
node.attachChild(ext);
All I've wanted to achieve is to move the computation of the entire TriMesh into a thread because it takes up to 20 seconds and I didn't want to freeze the user interface during that time. Why are these triangles happening, especially since everything else works?
I did some more experimentation. It really boils down to some kind of bug in the implementation of Extrusion in jme. I can compute and generate any shape (based on jme Shapes) or mesh on my own in an extra thread as described above. But Extrusions just tend to produce these weird stray triangles. Not always, but in out of 20 extrusions one will be buggy.
Now, I tried to understand the code of Extrusion.java - but failed. Apparently something in that code really wants to be executed during the OpenGL thread (inside the Callable structure), but I fail to notice what it could possibly be. Does anyone have an idea?
Well it probably has something to do with the renderstates, is my guess at least.
When you attach x to a node it might call an upate on the states (due to inherit override ect behaviour) wich causes random problems.
However as you quite easily see, jme2 is not designed to be used multi threaded. I suggest you generate your triangles / vertexes in a seperate thread, and use the gameallmanagerthing then to generate the mesh actually without any further compution inside the opengl thread.
Alsy why the use of update variable?
Create a method to get the rootnode, then you can produce far cleaner code.
Antoher idea would be to join the Opengl thread and the other once calucations are finsihed.