Hi,
I am loading a series of geometry into the scene. The problem is how can I detect/feedback when the geometry is added into the scene ? Something like the printout on the ide.
hi can you give us more information.
You know “when” because its you that created them.
//create node.
// i know now the time after this command.
Maybe use System.out.println( new Date()); ?
I’m pumping geometry shapes into the scene buy using enqueue( ) . I need to know when that particular shape is loaded into the scene before calling it to do somehing. StarInvestigate() Sometime cannot find ShapeA
public class TestWorldGeometry {
private MyGeometry GEOMETRY;
private MonkeyCanvas MONKEY_CANVAS;
private Node NODE_A, NODE_B;
public TestWorldGeometry(MonkeyCanvas Canvas) {
MONKEY_CANVAS = Canvas;
MONKEY_CANVAS.getFlyByCamera().setEnabled(false);
InitCameraPosition();
InitNodes();
InitShapePickableA();
// This sometimes will not work. The ShapeA will sometime not found under the rootNode
StartInvestigate();
}
private void InitCameraPosition() {
Quaternion qNew;
float[] values = new float[3];
values[0] = 0f;
values[1] = -FastMath.PI;
values[2] = 0f;
qNew = new Quaternion(values);
MONKEY_CANVAS.getCamera().setRotation(qNew);
MONKEY_CANVAS.getCamera().setLocation(new Vector3f(2f, 2f, 10f));
}
private void InitNodes() {
RenderQueueNodeAdd queueA, queueB;
NODE_A = new Node("NODE_A");
NODE_A.setLocalTranslation(2f, 0f, 0f);
NODE_B = new Node("NODE_B");
NODE_B.setLocalTranslation(0f, 2f, 0f);
queueA = new RenderQueueNodeAdd(MONKEY_CANVAS.getRootNode(), NODE_A);
MONKEY_CANVAS.addRenderQueue(queueA);
queueB = new RenderQueueNodeAdd(NODE_A, NODE_B);
MONKEY_CANVAS.addRenderQueue(queueB);
}
private void InitShapePickableA() {
RenderQueueGeometryAdd queue;
Material mat;
Quad q;
mat = new Material(MONKEY_CANVAS.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", MONKEY_CANVAS.getAssetManager().loadTexture("Interface/Logo/Monkey.jpg"));
mat.setColor("Color", ColorRGBA.Pink);
q = new Quad(2, 2, false);
GEOMETRY = new MyGeometry("ShapeA", q);
GEOMETRY.setMaterial(mat);
queue = new RenderQueueGeometryAdd(NODE_B, GEOMETRY);
MONKEY_CANVAS.addRenderQueue(queue);
}
public void StartInvestigate() {
Matrix4f mat;
MyGeometry geo;
Node nodeA, nodeB;
nodeA = (Node) MONKEY_CANVAS.getRootNode().getChild("NODE_A");
if (nodeA != null) {
System.out.println(" FOUND NODE_A UNDER ROOT NODE ");
} else {
System.out.println(" NOT FOUND NODE_A UNDER ROOT NODE ");
}
System.out.println("==================================================");
nodeB = (Node) MONKEY_CANVAS.getRootNode().getChild("NODE_B");
if (nodeB != null) {
System.out.println(" FOUND NODE_B UNDER ROOT NODE ");
} else {
System.out.println(" NOT FOUND NODE_B UNDER ROOT NODE");
}
System.out.println("==================================================");
geo = (MyGeometry) MONKEY_CANVAS.getRootNode().getChild("ShapeA");
if (geo != null) {
System.out.println(" FOUND ShapeA UNDER ROOT NODE");
} else {
System.out.println(" NOT FOUND ShapeA UNDER ROOT NODE");
}
geo = (MyGeometry) nodeA.getChild("ShapeA");
if (geo != null) {
System.out.println(" FOUND ShapeA UNDER NODE_A");
} else {
System.out.println(" NOT FOUND ShapeA UNDER NODE_A");
}
geo = (MyGeometry) nodeB.getChild("ShapeA");
if (geo != null) {
System.out.println(" FOUND ShapeA UNDER NODE_B");
} else {
System.out.println(" NOT FOUND ShapeA UNDER NODE_B");
}
System.out.println("==================================================");
mat = geo.getWorldMatrix();
System.out.println(" GEOMETRY ShapeA WorldMatrix = " + mat.toString());
// System.out.println(" GEOMETRY WORLD MATRIX = " + mat.toString());
}
i havent learned how to use RenderQueueNodeAdd class yet, does it any methods for that ?
Or is it yout class ? if yes what is its superclass ? maybe you have to save the time when you enter a method you override.
You are not supposed to modify or read the scenegraph from any other thread, so just enqueue the next call too, then it will be called after the first.
The RenderQueueNodeAdd is just a method that calls enqueue
public synchronized void addRenderQueue( final RenderQueueMain renderQueue) {
Future fut = enqueue(new Callable() {
@Override
public Object call() throws Exception {
return renderQueue.doIt(); // Add Shape into scene
//this is where you modify your object, you can return a result value
//return null;
}
});
/*
try {
fut.get();
} catch (InterruptedException ex) {
Logger.getLogger(MonkeyCanvas.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(MonkeyCanvas.class.getName()).log(Level.SEVERE, null, ex);
}
*
*/
}
eltekon said:
I'm pumping geometry shapes into the scene buy using enqueue( ) . I need to know when that particular shape is loaded into the scene before calling it to do somehing. StarInvestigate() Sometime cannot find ShapeA
To me this implies that StartInvestigate() is running from a different thread. Accessing the scene graph from a separate thread may give inconsistent results in a number of ways since none of those data structures are setup for multithreading. And it's not a case where "reading is ok as long as I don't change"... for example, it's possible for a thread that's reading from a HashMap to loop forever if some other thread modifies that HashMap in just the right way at just the right time.
So at best, you'll get concurrent mod exceptions, index out of bounds exceptions, etc. as data changes underneath you while the enqueued things are changing stuff... at worst it can lock up your thread.
And if StartInvestigate() is not running from a separate thread then I don't know how there can be an issue with the other enqueued thing not existing since they should be handled in order.
The way I solve this was to display a dialog box with a fake progress bar. After loading the progress bar it dissapears.