Problem with statistic and statistic rootnode

hi every one,

I have a problem in my project. as you can see on the screen the frame rate is 2 and i have 8 millions of triangles…

in my rootNode i have 3 objects : a plan, a cube and an other big object (a scene from blender) and my rootnode contain 130845 triangle… i don’t understand see println in output.

My architecture is like this :

  • a class Scene who extends simpleApplication and contain only simpleInitApp() and some listener.

  • a class GameCanvas who instantiate an object myScene of Scene class, set appsetting of this object create canvas and start it …

  • to finish a class software who is a frame with Jtabbedpane, JPanel, etc and instantiate an object of GameCanvas and load it in a panel.

i must separate the game and the software, and create 2 class one for the display (GameCanvas) and one to contain the scene to change the scene of the game easily.

So I don’t understand why with my println i found 100000 triangles and JME found 8M thus i think that my root node is duplicate but i don’t now how.

Do you have an idea?
Thanks everyone

How are we supposed to have an idea? We don’t know the code, we don’t know the model, we just know what you think you are doing.

I thought you could meet the problem is to know roughly where it can come.

the code is a bit long which is why I have not posted, but here :slight_smile: :

here the objects :

package animation;

import com.jme3.asset.plugins.FileLocator;
import com.jme3.cinematic.MotionPath;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.CameraControl.ControlDirection;
import com.jme3.scene.shape.Quad;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import com.jme3.util.BufferUtils;

public class Scene extends SimpleApplication {

                        private AppSettings LiveviewSettings;
                        private Node metroNode;
                        private CameraNode camNode ;
                        boolean playing = false;
                        private MotionPath path;
                        private Spatial metro;
                        private MotionEvent motionControlcam;
                        private MotionEvent motionControl ;
                        static JmeCanvasContext ctx;
                        private Spatial tunnel;
                        private Node tunnelNode;
                        private ChaseCamera chaser;

//////////////// Accesseur mutateur

                        public JmeCanvasContext getCtx() {
                                       return ctx;

                        public void setCtx(JmeCanvasContext ctx) {
                                       Scene.ctx = ctx;

                        public Spatial getMetro() {
                                       return metro;

                        public void setMetro(Spatial metro) {
                                       this.metro = metro;

                        public AppSettings getLiveviewSettings() {
                                       return LiveviewSettings;

                        public void setLiveviewSettings(AppSettings liveviewSettings) {
                                       LiveviewSettings = liveviewSettings;


public void animetro(Boolean value){
if (value == true){;
/* while ( metroNode.getWorldTranslation().toString().equals("(30.0, 0.0, -35.0)") )
try {
} catch (InterruptedException ex) {
Logger.getLogger(SceneMetro.class.getName()).log(Level.SEVERE, null, ex);
} */
if (value == false){

              public void simpleInitApp() {

// Definition du Path Asset : le repertoire ou se trouvent les resources 3D
String assetPath = “D:\Users\h\workspace\Import3D\assets”;
this.assetManager.registerLocator(assetPath, FileLocator.class);

// load metro

                         metro = assetManager.loadModel("Models\\cube\\test4.j3o");
                         metro.scale(1f, 1f, 1f);
                         metro.rotate(0.0f, 0.0f, 0.0f);
                         metro.setLocalTranslation(0.0f, 0.0f, 0.0f);

// load tunnel
tunnel = assetManager.loadModel(“Models\metro\metro scene test.j3o”);
tunnel.scale(20f, 20f, 20f);
tunnel.rotate(0.0f, 0.0f, 0.0f);
tunnel.setLocalTranslation(0.0f, -2f, 0.0f);

// creation de node to attach the carremobile and the camera node
tunnelNode = new Node(“tunnelNode”);
metroNode = new Node(“metronode”);

// load carrefixe
Spatial carrefixe = assetManager.loadModel(“Models\cube\test4.j3o”);
carrefixe.scale(1f, 1f, 1f);
carrefixe.rotate(0.0f, 0.0f, 0.0f);
carrefixe.setLocalTranslation(0.0f, 0.0f, 5.0f);

// creation de node to attach the carrefixe

                     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
                     mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
                     Geometry ground = new Geometry("ground", new Quad(150, 150));
                     ground.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
                     ground.setLocalTranslation(-50, 0, 50);

// Light
AmbientLight al = new AmbientLight();
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-1f, -1f, -1.0f));

                     // flyCam.setDragToRotate(true);
                     //disable the default 1st-person flyCam

                      path = new MotionPath();
                      path.addWayPoint(new Vector3f(-50, 0, 0));
                      path.addWayPoint(new Vector3f(-35, 0, 0));
                      path.addWayPoint(new Vector3f(0, 0, 10));
                      path.addWayPoint(new Vector3f(20, 0, -20));
                      path.addWayPoint(new Vector3f(30, 0, -35));
                      path.addWayPoint(new Vector3f(50, 0, -40));
                      path.addWayPoint(new Vector3f(80, 0, -40));
                      path.addWayPoint(new Vector3f(20, 0, -80));
                      path.enableDebugShape(assetManager, rootNode);

// camera chase
// cam.setLocation(new Vector3f(8.4399185f, 11.189463f, 14.267577f));

                        chaser = new ChaseCamera(cam, metro);
                        chaser.setUpVector(new Vector3f(0f, 1f, 0f));

//creating the camera Node
camNode = new CameraNode(“CamNode”, cam);
//Setting the direction to Spatial to camera, this means the camera will copy the movements of the Node
//attaching the camNode
//setting the local translation of the cam node to move it away from the teanNode a bit
camNode.setLocalTranslation(new Vector3f(-10, 5, 0));

                               //setting the camNode to look at the carreNode
                               //camNode.lookAt(metroNode.getLocalTranslation(), new Vector3f(0, 1, 0));
                      camNode.lookAt(metroNode.getWorldTranslation(), new Vector3f(0, 1, 0));


                      motionControl = new MotionEvent(metroNode,path);

                      motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y));

              /*        motionControlcam = new MotionEvent(camNode,path);
                    //  motionControlcam.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y));

ChaseCamera chaser = new ChaseCamera(cam, teapot);
// motionControl.setSpeed(-3f);
// motionControl.setLoopMode(LoopMode.Loop);
// path.setCycle(true);

    // chaser.setEnabled(false);

System.out.println(“Vertices cube” + metro.getTriangleCount());
System.out.println("Vertices cubeNode " + metroNode.getVertexCount());
System.out.println(“Vertices plan” + ground.getVertexCount());
// System.out.println(“Vertices plan” + groundNode.getVertexCount());
// System.out.println("Vertices tunnel " + tunnel.getVertexCount());
// System.out.println("Vertices tunnelNode " + tunnelNode.getVertexCount());
System.out.println("Vertices rootNode " + rootNode.getVertexCount());
System.out.println("triangles rootNode " + rootNode.getTriangleCount());


              private void setupKeys() {
                  inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_LEFT));
                  inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_RIGHT));
                  inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_UP));
                  inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_DOWN));
                  inputManager.addMapping("Camera", new KeyTrigger(KeyInput.KEY_C));
                  inputManager.addMapping("play_stop", new KeyTrigger(KeyInput.KEY_SPACE));
                  inputManager.addMapping("question", new KeyTrigger(KeyInput.KEY_Q));
                  inputManager.addMapping("delete", new KeyTrigger(KeyInput.KEY_M));
                  inputManager.addListener(actionListener, new String[]{"play_stop", "delete"});
                  inputManager.addListener(analogListener, new String[]{"Ups","Rights","Lefts","Downs","question"});

                        private ActionListener actionListener = new ActionListener() {
                  public void onAction(String name, boolean keyPressed, float tpf) {
                         if (name.equals("play_stop") && keyPressed) {
                              if (playing) {
                                  playing = false;
                                  animetro( false);

                              } else {
                                  playing = true;
                                  animetro( true);

                      if (name.equals("delete") && keyPressed) {
                   /*          getMonliveview().destroy();

              private AnalogListener analogListener = new AnalogListener() {
                  public void onAnalog(String name, float value, float tpf) {

                      if (name.equals("Ups")) {
                        metroNode.move(-0.05f, 0f, 0f);
                      if (name.equals("Downs")) {
                        metroNode.move(0.05f, 0f, 0f);
                      if (name.equals("Rights")) {
                      //             metroNode.move(0f, 0f, -0.05f);
                        metroNode.rotate(0, 0.01f, 0);
                      if (name.equals("Lefts")) {
                        //metroNode.move(0f, 0f, 0.05f);
                       metroNode.rotate(0, -0.01f, 0);
                      if (name.equals("question")) {



import java.awt.Dimension;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;

public class GameCanvas {

                        private Scene myScene;
                        private AppSettings sceneSettings;
                        private Dimension dim;

public GameCanvas () {

    this.myScene = new Scene();
    this.sceneSettings=(new AppSettings(false));
    this.sceneSettings.setResolution(600, 300);


    this.myScene.setCtx((JmeCanvasContext) this.myScene.getContext());
    this.dim = new Dimension(800, 400);


//////////////// Accesseur mutateur

public Scene getScene() {
return myScene;

public void setScene(Scene Scene) {
this.myScene = Scene;
public AppSettings getSceneSettings() {
return sceneSettings;

public void setSceneSettings(AppSettings mySceneSettings) {
this.sceneSettings = mySceneSettings;

public Dimension getDim() {
return dim;

public void setDim(Dimension myDim ) {
this.dim = myDim;




package animation;

import animation.*;
import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

public class Software {

public JDialog dialog;
String name;
int x,y;
private static GameCanvas anim;

private JTabbedPane  tbpSessions;
private  JPanel panel1;
private  JPanel panel2;
private  JPanel panel3;

public JDialog getDialog() {
                        return dialog;

          public void setDialog(JDialog dialog) {
                        this.dialog = dialog;

          public JPanel getPanel() {
                        return panel1;

          public void setPanel(JPanel panel) {
                        this.panel1 = panel;

          Software (String name, int x, int y ){
                        dialog= new JDialog();
                        dialog.setSize(x, y);
                        panel2 = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 5));
                        panel3 = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 5));
                        panel1 = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 5));
                      //  panel.add(new JButton("Some Swing Component"));
                      //  dialog.add(panel);
                        tbpSessions = new JTabbedPane();
                        tbpSessions.addTab("tab1", panel1);
                        tbpSessions.addTab("tab2", panel2);
                        tbpSessions.addTab("tab3", panel3);
                        dialog.addWindowListener(new WindowAdapter() {
        public void windowClosed(WindowEvent e) {


public static void main(String[] args) throws InterruptedException {

    anim = new GameCanvas();
    Software test = new Software("d1" ,1000,700);



Put your code inside JAVA code tags. Nobody will read that wall-o-text.

i am agree with you madjack, i edited.

nobody have an idea ?

Well 8 million triangles is to much, optimize that down if you want to run it smooth. Also you use graficdrivers?

Of course 8 millions is too much but i don’t understand that in blender my scene is around 350000 triangles, in the rootnoot i found 130000 triangles, and in the statistic it is 8 millions…

you can see the screen. :slight_smile:

thanks for help.

Hm, well while I dont imideatly see a error in the code, I would just do a small test.

Modify one of the Examples that load only a model to load your model, and watch performance there.
Replace the model (each one seperatly) with a cube and see if one of them is responsible for the strange numbers, or if both are related.

@hedi said: Of course 8 millions is too much but i don't understand that in blender my scene is around 350000 triangles, in the rootnoot i found 130000 triangles, and in the statistic it is 8 millions....
Well first there is no guarantee that you'll have the same amount of vertices in blender and JME. There is usually more depending on how the uv layout is done and so on. Second, the statistics displays the triangles that are actually rendered on screen, not the ones in the scenegraph. A geomertry can be rendered several times if you have several lights or using shadows...or combinations of those factors. Doesn't seem so, looking at your code, but maybe there are a lot of lights in your blender scene that are imported along with the model by the blender loader. Also look at how many objects you have in you scene graph and how many are rendered, this can give us some hint on what's going on.
@hedi said: you can see the screen. :)
Actually we can't the link is now dead. Could you re-post the picture on

here the link

yes i have many light in blender i though that only mesh are load in JME
I will do tests without light.

i will back probably next week with the result of tests.

Thank you nehon

Having Intel hardware doesn’t help FPS either.

What is it we’re supposed to see in that screenshot? That render screen is mostly black, nothing distinguishable there.

i have a problem of texturing in the render that’s why it’s black

in the screen it’s important to see what is the difference between statistics and the result println.