Do not understand simple attachChild method

Hi,



I have got following code…


public class PraxitelesCanvasImplementor extends JMECanvasImplementor {

    private static final Logger LOG = Logger.getLogger(PraxitelesCanvasImplementor.class.getCanonicalName());
    private static PraxitelesCanvasImplementor instance = null;
    private Node sceneGraphRootNode = null;
    protected Timer nanoTimer;
    private Canvas canvas = null;
    private BasicPassManager passManager = null;
    private RenderPass sceneGraphRenderPass = null;
    private DisplaySystem displaySystem = null;
    private ComponentListener canvasListener = new ComponentAdapter() {

        @Override
        public void componentResized(ComponentEvent e) {
            resizeCanvas(canvas.getWidth(), canvas.getHeight());
        }
    };

    private PraxitelesCanvasImplementor() {
        displaySystem = DisplaySystem.getDisplaySystem();
        canvas = (Canvas) displaySystem.createCanvas(displaySystem.getWidth(), displaySystem.getHeight());
        canvas.addComponentListener(canvasListener);
        LOG.info("Attach Implementor...");
        ((JMECanvas) canvas).setImplementor(this);
    }

    @Override
    public void doSetup() {
        if (!setup) {

            LOG.info("Do Setup...");



            renderer = displaySystem.getRenderer();

            Camera camera = renderer.createCamera(displaySystem.getWidth(), displaySystem.getHeight());
            camera.setFrustumPerspective(45.0f, (float) displaySystem.getWidth() / (float) displaySystem.getHeight(), 1, 1000);
            camera.setFrame(
                    new Vector3f(01.0f, 0.0f, 25.0f),
                    new Vector3f(-1.0f, 0.0f, 0.0f),
                    new Vector3f(0.0f, 1.0f, 0.0f),
                    new Vector3f(0.0f, 0f, -1.0f));
            camera.update();
            renderer.setCamera(camera);

            renderer.setBackgroundColor(ColorRGBA.black.clone());

            nanoTimer = new NanoTimer();

            passManager = new BasicPassManager();
            sceneGraphRenderPass = new RenderPass();
            passManager.add(sceneGraphRenderPass);

            sceneGraphRootNode = new AxisRods("Root Node");
            //Add the sceneGraphRootNode to the sceneGraphRenderPass
            sceneGraphRenderPass.add(sceneGraphRootNode);


            ZBufferState zBufferState = renderer.createZBufferState();
            zBufferState.setEnabled(true);
            zBufferState.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
            sceneGraphRootNode.setRenderState(zBufferState);
            sceneGraphRootNode.updateRenderState();


            PointLight defaultLight = new PointLight();
            defaultLight.setDiffuse(ColorRGBA.white);
            defaultLight.setLocation(new Vector3f(0, 0, 0));
            defaultLight.setEnabled(true);


            LightState defaultLightState = renderer.createLightState();
            defaultLightState.setEnabled(true);
            defaultLightState.attach(defaultLight);
            sceneGraphRootNode.setRenderState(defaultLightState);
            sceneGraphRootNode.updateRenderState();

            sceneGraphRootNode.updateGeometricState(0.0f, true);
            sceneGraphRootNode.updateRenderState();

            nanoTimer.reset();
            setup = true;
            new PraxitelesCanvasThread().start();
        }

    }

    @Override
    public void doUpdate() {
        if (setup && sceneGraphRootNode != null) {
            nanoTimer.update();

            float tpf = nanoTimer.getTimePerFrame();
            passManager.updatePasses(tpf);
            sceneGraphRootNode.updateGeometricState(tpf, true);
        }

    }

    @Override
    public void doRender() {
        if (setup && canvas != null && canvas.isShowing() && renderer.getCamera() != null) {
            renderer.clearBuffers();
            passManager.renderPasses(renderer);
            renderer.displayBackBuffer();
        }
    }

    public final Canvas getCanvas() {
        return canvas;


    }

    public static PraxitelesCanvasImplementor getInstance() {
        if (instance == null) {
            LOG.info("Create Implementor...");
            instance = new PraxitelesCanvasImplementor();

        }
        return instance;


    }

    public void setPraxitelesSceneWorldOrigin(final PraxitelesSceneWorldOrigin praxitelesSceneWorldOrigin) {
        if (praxitelesSceneWorldOrigin != null) {
            sceneGraphRootNode.detachAllChildren();
            sceneGraphRootNode.attachChild(praxitelesSceneWorldOrigin.getSpatial());
            sceneGraphRootNode.updateWorldVectors();
            sceneGraphRootNode.updateRenderState();
            sceneGraphRootNode.updateGeometricState(0, true);
            sceneGraphRootNode.updateWorldData(0);
        }
    }

    private class PraxitelesCanvasThread extends Thread {

        {
            setDaemon(true);
        }

        public PraxitelesCanvasThread() {
        }

        @Override
        public void run() {
            while (true) {
                if (canvas.isShowing()) {
                    canvas.repaint();
                }
                yield();
            }
        }
    }
}



This code works perfect. The AxisRods is the root node. However. If I add two simple lines, to see a second AxisRods shifted 2 unit to the left

...
sceneGraphRootNode = new AxisRods("Root Node");
AxisRods newAxisRods = new AxisRods();     
sceneGraphRootNode.attachChild(newAxisRods );
axisRods.setLocalTranslation(new Vector3f(2, 0, 0));



The second Axisrods is not shown. My problem is that I don't relly understand when I have to call update methods. Can they already be called BEFORE a Node has been attached to the parent, do they HAVE to be called AFTER they have been attached. Which update node MUST I call under which circumstances.

Thanks a lot for help.

Regards,
Equilibrium
     

Usually, you set up your scene, then call updateRendetState() / updateGeometricstate() once for the root node.

Then always after you attach something to the scene, call updateRenderState()

In your render/update cycle, call updateGeometricState() once for the root node.



in your code you do:

sceneGraphRootNode = new AxisRods("Root Node");


why not do:

sceneGraphRootNode = new Node("Root Node");


Then attach the two AxisRods to this node