Node creation slow in Implementor


I'm setting up a tiled terrain which eventually needs to be 33 by 33 quads in dimension. Right now I'm working with 4x4 for speeds sake. I've got several panels set up with Swing with a JMECanvas as main focus for the user. This is where the terrain is visible. Before using the panels and the implementor I had it set up in such a way that you could select a tile with the mouse and it would rise up, change texture and all neighbouring nodes would change shape too.

The terrain is tile are quads on top of a node. All these nodes are connected to a central mapnode which in turn is connected to the rootnode.

First of all, now that I've switched to the implementor, the picking has gone crazy. I tried to find a system behind the strange behaviour but as of yet I cannot.

Last of all, the performance has taken a dramatic fall. The creation of the terrain takes ages to create 16 tiles where at first it took a split second to create 33x33. After debugging I think I can conclude that the creation of new Nodes is what costing such a large amount of time.

Can anyone give me an idea what's wrong and how I can solve these problems?


I've fixed the picking in the JMECanvas after finding that the x-position of the mouse hotspot was ok, but the y-position was somehow inverted. I've changed it by subtracting the mouse's y-hotpostposition from the display's height. Now it works well.

I was wondering whether anyone else has experienced serious performance drops when using the JMECanvas/Implementor in a swing application. My init code is like this:

canvas = DisplaySystem.getDisplaySystem( "lwjgl" ).createCanvas( leftWidth, focusHeight );
        ((JMECanvas) canvas).setUpdateInput( true );

        canvas.addFocusListener( new FocusListener() {

            public void focusGained( FocusEvent arg0 ) {

                ((AWTKeyInput) KeyInput.get()).setEnabled( true );
                ((AWTMouseInput) MouseInput.get()).setEnabled( true );

            public void focusLost( FocusEvent arg0 ) {

                ((AWTKeyInput) KeyInput.get()).setEnabled( false );
                ((AWTMouseInput) MouseInput.get()).setEnabled( false );
        } );
        KeyInput.setProvider( InputSystem.INPUT_SYSTEM_AWT );
        ((AWTKeyInput) KeyInput.get()).setEnabled( false );
        KeyListener kl = (KeyListener) KeyInput.get();

        canvas.addKeyListener( kl );

        MouseInput.setProvider( InputSystem.INPUT_SYSTEM_AWT );
        ((AWTMouseInput) MouseInput.get()).setEnabled( false );
        ((AWTMouseInput) MouseInput.get()).setRelativeDelta( canvas );

        canvas.addMouseListener( (MouseListener) MouseInput.get() );
        canvas.addMouseWheelListener( (MouseWheelListener) MouseInput.get() );
        canvas.addMouseMotionListener( (MouseMotionListener) MouseInput.get() );
        // Add the actually look into jme
        float zoom = 4f;
        implementor = new ClientImplementor( leftWidth, focusHeight, zoom, status );
        ((JMECanvas) canvas).setImplementor( implementor );

This ClientImplementor sets up like this

package nl.tygron.simport.client.gui;

import nl.tygron.simport.client.communication.Status;
import nl.tygron.simport.client.gui.input.SimPortInputHandler;

import com.jme.bounding.BoundingBox;
import com.jme.input.InputHandler;
import com.jme.input.ThirdPersonHandler;
import com.jme.intersection.TrianglePickResults;
import com.jme.light.DirectionalLight;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.lwjgl.LWJGLRenderer;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.state.LightState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jmex.awt.JMECanvas;
import com.jmex.awt.JMECanvasImplementor;
import com.jmex.awt.SimpleCanvasImpl;

public class ClientImplementor extends JMECanvasImplementor {

    private Quaternion rotQuat;

    private Vector3f axis;

    private Box box;

    private float angle = 0, fps = 0;
    private int width, height;

    private long startTime = 0;

    private DisplaySystem display;

    private Node scene;

    private SimMap mapNode;

    private Camera camera;

    private InputHandler input;

    private TrianglePickResults pickResults;

    private float zoom;
    private boolean doZoom = false;
    private Status status;
    protected ClientImplementor( int width, int height, float zoom, Status n_status ) {

        this.width = width;
        this.height = height;       
        this.zoom = zoom;
        status = n_status;

    public void doSetup() {

        display = DisplaySystem.getDisplaySystem();
        renderer = new LWJGLRenderer(width, height);
        renderer.setHeadless( true );
        display.setRenderer( renderer );
        DisplaySystem.updateStates( renderer );
        camera = renderer.createCamera(width, height);
        camera.setParallelProjection( true );
        float aspect = (float) display.getWidth() / display.getHeight();
        camera.setFrustum( -100, 1000, -50f * aspect, 50f * aspect, -50, 50 );
        // Position the camera in a more interesting way
        camera.setLocation( new Vector3f( 0, -25, 25 ) );
        camera.setDirection( new Vector3f( 0, -1, 1 ) );
        // Update the camera
        renderer.setCamera( camera );
        // Get ready to work with collision
        pickResults = new TrianglePickResults();

        // Load the mesh manager
        MeshManager meshManager = new MeshManager();
        SceneManager.setMeshManager( meshManager );
        SceneManager.setDisplay( display );

        scene = new Node("Root node");

        ZBufferState buf = display.getRenderer().createZBufferState();
        buf.setEnabled( true );
        buf.setFunction( ZBufferState.CF_LEQUAL );
        scene.setRenderState( buf );

        mapNode = new SimMap( "Map node", display, 1f, status.getMap() );

        Quaternion rotation = new Quaternion();
        rotation.fromAngleAxis( -0.25f * (float) Math.PI, new Vector3f( 0, 0, 1 ) );
        scene.setLocalRotation( rotation );

        scene.attachChild( mapNode );
        // Rotate the scene to faace north
        scene.setLocalScale( zoom );


        MeshManager mm = new MeshManager();

        scene.updateGeometricState( 0.0f, true );

        SceneManager.setMeshManager( mm );
        SceneManager.setRootNode( scene );

        input = new SimPortInputHandler( camera, pickResults );

        startTime = System.currentTimeMillis() + 5000;


    public void simpleUpdate() {

        input.update( fps );
            scene.setLocalScale( zoom );
            doZoom = false;

    private void buildLighting() {

        /** Set up a basic, default light. */
        /*DirectionalLight light = new DirectionalLight();
        light.setDiffuse( new ColorRGBA( 1.0f, 1.0f, 1.0f, 1.0f ) );
        light.setAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) );
        light.setDirection( new Vector3f( 1, 0, -1 ) );
        light.setEnabled( true );

        /** Attach the light to a lightState and the lightState to rootNode. */
        /*LightState lightState = display.getRenderer().createLightState();
        lightState.setEnabled( true );
        lightState.attach( light );
        scene.setRenderState( lightState );*/
    public void zoom( final float n_zoom ){
        zoom = n_zoom;
        doZoom = true;

    public void doUpdate() {

        // TODO Auto-generated method stub

    public void doRender() {

        // TODO Auto-generated method stub


When creating the mapNode object 33 new nodes with Quads are made, but this takes ages. Am I missing something?

I haven't heard of such issues yet. Consider using a profiler to find out why it takes that long…