[SOLVED]RenParticleEditor: loading TriMesh model

Hi to all.

I’m trying to develop a MeshViewer and I’m basing it on the RenParticleEditor example.

I’ve just kept the CameraHandler code and the glCanvas code and then, inside the MyImplementor class I’ve tried to load a simple box with a texture attached. Everything works fine excepts that I had to scale it a bit to see it.

Then I’ve created a simple method that loads a .obj file and returns a TriMesh mesh. The MeshViewer loads the obj file correctly and it returns no exception but it doesn’t show it. I’ve even tried to scale it but nothing, it only shows the grid.

Here are 2 screenshots:



The Blank glCanvas:





The glCanvas with Box:





And here’s the Code:

public class HyperpunkEditor extends JFrame {
    private static final Logger logger = Logger
            .getLogger(HyperpunkEditor.class.getName());



    private static final long serialVersionUID = 1L;
   

    int width = 640, height = 480;

    MyImplementor impl;
    private CameraHandler camhand;
    private Canvas glCanvas;
    private Node root;
    private Geometry grid;
    private TriMesh model;

   
   
   
    private Preferences prefs = Preferences
            .userNodeForPackage(HyperpunkEditor.class);

   
   
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            logger.logp(Level.SEVERE, HyperpunkEditor.class.toString(), "main(args)", "Exception", e);
        }
        new HyperpunkEditor();
    }

    public HyperpunkEditor() {
        try {
            init();
           
            setLocationRelativeTo(null);

            setVisible(true);


            while (glCanvas == null)
                ;

            new Thread() {
                {
                    setDaemon(true);
                }

                public void run() {
                    try {
                        while (true) {
                            if (isVisible())
                                glCanvas.repaint();
                            Thread.sleep(2);
                        }
                    } catch (InterruptedException e) {
                        logger.logp(Level.SEVERE, this.getClass().toString(),
                                "run()", "Exception", e);
                    }
                }
            }.start();

        } catch (Exception ex) {
            logger.logp(Level.SEVERE, this.getClass().toString(),
                    "RenParticleEditor()", "Exception", ex);
        }
    }

    private void init() throws Exception {
       
       updateTitle();
       
       
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setFont(new Font("Arial", 0, 12));

        JTabbedPane tabbedPane = new JTabbedPane();
     
        tabbedPane.setPreferredSize(new Dimension(150, 10));

        JPanel canvasPanel = new JPanel();
        canvasPanel.setLayout(new BorderLayout());
        canvasPanel.add(getGlCanvas(), BorderLayout.CENTER);

        JSplitPane mainSplit = new JSplitPane();
        mainSplit.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
        mainSplit.setLeftComponent(tabbedPane);
        mainSplit.setRightComponent(canvasPanel);
        mainSplit.setPreferredSize(new Dimension(800,600));
        Dimension minimumSize = new Dimension(100, 50);
        tabbedPane.setMinimumSize(minimumSize);
        canvasPanel.setMinimumSize(minimumSize);

        getContentPane().add(mainSplit, BorderLayout.CENTER);

       
        pack();
    }
   
  
    private void updateTitle() {
       
       setTitle("Hyperpunk Editor Framework Version - Coded by Prometheus");
    }
   
    private Color makeColor(ColorRGBA rgba, boolean useAlpha) {
        return new Color(rgba.r, rgba.g, rgba.b, (useAlpha ? rgba.a : 1f));
    }

    private ColorRGBA makeColorRGBA(Color color) {
        return new ColorRGBA(color.getRed() / 255f, color.getGreen() / 255f,
                color.getBlue() / 255f, color.getAlpha() / 255f);
    }

    protected Canvas getGlCanvas() {
        if (glCanvas == null) {

          
            glCanvas = DisplaySystem.getDisplaySystem().createCanvas(width, height);
            glCanvas.setMinimumSize(new Dimension(100, 100));

            glCanvas.addComponentListener(new ComponentAdapter() {
                public void componentResized(ComponentEvent ce) {
                    doResize();
                }
            });

            camhand = new CameraHandler();

            glCanvas.addMouseWheelListener(camhand);
            glCanvas.addMouseListener(camhand);
            glCanvas.addMouseMotionListener(camhand);

            impl = new MyImplementor(width, height);

            ((JMECanvas) glCanvas).setImplementor(impl);

            Callable<?> exe = new Callable() {
                public Object call() {
                    forceUpdateToSize();
                    return null;
                }
            };
            GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(exe);
        }
        return glCanvas;
    }

    public void forceUpdateToSize() {
        // force a resize to ensure proper canvas size.
        glCanvas.setSize(glCanvas.getWidth(), glCanvas.getHeight() + 1);
        glCanvas.setSize(glCanvas.getWidth(), glCanvas.getHeight() - 1);
    }

    class CameraHandler extends MouseAdapter implements MouseMotionListener,
            MouseWheelListener {
        Point last = new Point(0, 0);
        Vector3f focus = new Vector3f();
        private Vector3f vector = new Vector3f();
        private Quaternion rot = new Quaternion();

        public void mouseDragged(final MouseEvent arg0) {
            Callable<?> exe = new Callable() {
                public Object call() {
                    int difX = last.x - arg0.getX();
                    int difY = last.y - arg0.getY();
                    int mult = arg0.isShiftDown() ? 10 : 1;
                    last.x = arg0.getX();
                    last.y = arg0.getY();

                    int mods = arg0.getModifiers();
                    if ((mods & InputEvent.BUTTON1_MASK) != 0) {
                        rotateCamera(Vector3f.UNIT_Y, difX * 0.0025f);
                        rotateCamera(impl.getRenderer().getCamera().getLeft(),
                                -difY * 0.0025f);
                    }
                    if ((mods & InputEvent.BUTTON2_MASK) != 0 && difY != 0) {
                        zoomCamera(difY * mult);
                    }
                    if ((mods & InputEvent.BUTTON3_MASK) != 0) {
                        panCamera(-difX, -difY);
                    }
                    return null;
                }
            };
            GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER)
                    .enqueue(exe);
        }

        public void mouseMoved(MouseEvent arg0) {
        }

        public void mousePressed(MouseEvent arg0) {
            last.x = arg0.getX();
            last.y = arg0.getY();
        }

        public void mouseWheelMoved(final MouseWheelEvent arg0) {
            Callable<?> exe = new Callable() {
                public Object call() {
                    zoomCamera(arg0.getWheelRotation()
                            * (arg0.isShiftDown() ? -100 : -20));
                    return null;
                }
            };
            GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER)
                    .enqueue(exe);
        }

        public void recenterCamera() {
            Callable<?> exe = new Callable() {
                public Object call() {
                    Camera cam = impl.getRenderer().getCamera();
                    Vector3f.ZERO.subtract(focus, vector);
                    cam.getLocation().addLocal(vector);
                    focus.addLocal(vector);
                    cam.onFrameChange();
                    return null;
                }
            };
            GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER)
                    .enqueue(exe);
        }

        private void rotateCamera(Vector3f axis, float amount) {
            Camera cam = impl.getRenderer().getCamera();
            if (axis.equals(cam.getLeft())) {
                float elevation = -FastMath.asin(cam.getDirection().y);
                amount = Math.min(Math.max(elevation + amount,
                        -FastMath.HALF_PI), FastMath.HALF_PI)
                        - elevation;
            }
            rot.fromAngleAxis(amount, axis);
            cam.getLocation().subtract(focus, vector);
            rot.mult(vector, vector);
            focus.add(vector, cam.getLocation());
            rot.mult(cam.getLeft(), cam.getLeft());
            rot.mult(cam.getUp(), cam.getUp());
            rot.mult(cam.getDirection(), cam.getDirection());
            cam.normalize();
            cam.onFrameChange();
        }

        private void panCamera(float left, float up) {
            Camera cam = impl.getRenderer().getCamera();
            cam.getLeft().mult(left, vector);
            vector.scaleAdd(up, cam.getUp(), vector);
            cam.getLocation().addLocal(vector);
            focus.addLocal(vector);
            cam.onFrameChange();
        }

        private void zoomCamera(float amount) {
            Camera cam = impl.getRenderer().getCamera();
            float dist = cam.getLocation().distance(focus);
            amount = dist - Math.max(0f, dist - amount);
            cam.getLocation().scaleAdd(amount, cam.getDirection(),
                    cam.getLocation());
            cam.onFrameChange();
        }
    }

    protected void doResize() {
        if (impl != null) {
            impl.resizeCanvas(glCanvas.getWidth(), glCanvas.getHeight());
            if (impl.getCamera() != null) {
                Callable<?> exe = new Callable() {
                    public Object call() {
                        impl.getCamera().setFrustumPerspective(
                                45.0f,
                                (float) glCanvas.getWidth()
                                        / (float) glCanvas.getHeight(), 1,
                                10000);
                        return null;
                    }
                };
                GameTaskQueueManager.getManager()
                        .getQueue(GameTaskQueue.RENDER).enqueue(exe);
            }
        }
    }

    class MyImplementor extends SimpleCanvasImpl {

        private static final int GRID_LINES = 51;
        private static final float GRID_SPACING = 100f;

       
        protected Node fpsNode;

       
        protected Text fps;

       
        protected StringBuffer tempBuffer = new StringBuffer();

        protected StringBuffer updateBuffer = new StringBuffer(30);

        public MyImplementor(int width, int height) {
            super(width, height);
        }
       
       
        private TriMesh loadModel() {
           
           ObjToJme myObjConverter = new ObjToJme();
           
           try {
              
              URL objFile1 = HyperpunkEditor.class.getClassLoader().getResource("ArchwayUp.obj");
              myObjConverter.setProperty("mtllib", objFile1);
              
              
              ByteArrayOutputStream BO1 = new ByteArrayOutputStream();
              System.out.println("Starting to convert .obj to .jme");
              myObjConverter.convert(objFile1.openStream(), BO1);
              
              
              TriMesh model = (TriMesh) BinaryImporter.getInstance().load(
                             new ByteArrayInputStream(BO1.toByteArray()));
              
              URL textureLocation;
              textureLocation = HyperpunkEditor.class.getClassLoader()
                                .getResource("ArchwayColorMap.jpg");
              
              TextureState ArchwayTS = impl.getRenderer().createTextureState();
              
              Texture ArchwayTexture = TextureManager.loadTexture(textureLocation,
                                                     Texture.MM_LINEAR,
                                                     Texture.FM_LINEAR);
              
              ArchwayTS.setTexture(ArchwayTexture);
              model.setModelBound(new BoundingBox());
              model.updateModelBound();
              model.setLocalScale(25);
      
           } catch (IOException e) {
              
              e.printStackTrace();
           }
           
           return model;
        }
       

        public void simpleSetup() {
            Color bg = new Color(prefs.getInt("bg_color", 0));
            renderer.setBackgroundColor(makeColorRGBA(bg));
            cam.setFrustumPerspective(45.0f, (float) glCanvas.getWidth()
                    / (float) glCanvas.getHeight(), 1, 10000);

            Box b = new Box("MyBOX", new Vector3f(0,0,0), new Vector3f(1,1,1));
           
           
            URL textureLoc = HyperpunkEditor.class.getClassLoader()
         .getResource("ArchwayColorMap.jpg");
            TextureState boxTS = impl.getRenderer().createTextureState();
            Texture boxTexture = TextureManager.loadTexture(textureLoc,
               Texture.MM_LINEAR,
               Texture.FM_LINEAR);
            boxTS.setTexture(boxTexture);
            b.setRenderState(boxTS);
            b.setLocalScale(125);
              
           
            Vector3f loc = new Vector3f(0, 850, -850);
            //Vector3f loc = new Vector3f(0,0,0);
            Vector3f left = new Vector3f(1, 0, 0);
            Vector3f up = new Vector3f(0, 0.7071f, 0.7071f);
            Vector3f dir = new Vector3f(0, -0.7071f, 0.7071f);
            cam.setFrame(loc, left, up, dir);

            root = rootNode;

            /** This is what will actually have the text at the bottom. */
            fps = Text.createDefaultTextLabel("FPS label");
            fps.setCullMode(SceneElement.CULL_NEVER);
            fps.setTextureCombineMode(TextureState.REPLACE);

            // Finally, a stand alone node (not attached to root on purpose)
            fpsNode = new Node("FPS node");
            fpsNode.setRenderState(fps.getRenderState(RenderState.RS_ALPHA));
            fpsNode.setRenderState(fps.getRenderState(RenderState.RS_TEXTURE));
            fpsNode.attachChild(fps);
            fpsNode.setCullMode(SceneElement.CULL_NEVER);

            renderer.enableStatistics(true);

           
            root.attachChild(b);
            root.attachChild(model = loadModel());
           
     
            root.attachChild(grid = createGrid());
            root.updateRenderState();
           
            //grid.updateRenderState();
          
            ZBufferState zbuf = renderer.createZBufferState();
            zbuf.setWritable(false);
            zbuf.setEnabled(true);
            zbuf.setFunction(ZBufferState.CF_LEQUAL);
      
            fpsNode.updateGeometricState(0, true);
            fpsNode.updateRenderState();
           
            logger.info("Running on: "
                    + DisplaySystem.getDisplaySystem().getAdapter()
                    + "nDriver version: "
                    + DisplaySystem.getDisplaySystem().getDriverVersion()
                    + "n"
                    + DisplaySystem.getDisplaySystem().getDisplayVendor()
                    + " - "
                    + DisplaySystem.getDisplaySystem().getDisplayRenderer()
                    + " - "
                    + DisplaySystem.getDisplaySystem().getDisplayAPIVersion());

        };

        public void simpleUpdate() {
            updateBuffer.setLength(0);
            updateBuffer.append("FPS: ").append((int) timer.getFrameRate())
                    .append(" - ");
            updateBuffer.append(renderer.getStatistics(tempBuffer));
            /** Send the fps to our fps bar at the bottom. */
            fps.print(updateBuffer);
        }

        @Override
        public void simpleRender() {
            fpsNode.draw(renderer);
            renderer.clearStatistics();
        }

        private Geometry createGrid() {
            Vector3f[] vertices = new Vector3f[GRID_LINES * 2 * 2];
            float edge = GRID_LINES / 2 * GRID_SPACING;
            for (int ii = 0, idx = 0; ii < GRID_LINES; ii++) {
                float coord = (ii - GRID_LINES / 2) * GRID_SPACING;
                vertices[idx++] = new Vector3f(-edge, 0f, coord);
                vertices[idx++] = new Vector3f(+edge, 0f, coord);
                vertices[idx++] = new Vector3f(coord, 0f, -edge);
                vertices[idx++] = new Vector3f(coord, 0f, +edge);
            }
            Geometry grid = new com.jme.scene.Line("grid", vertices, null,
                    null, null);
            grid.getBatch(0).getDefaultColor().set(ColorRGBA.darkGray.clone());
            return grid;
        }
    }
}



Please let me know if you have a solution.

Your not returning the correct 'model' variable.

The model returned from BinaryImporter is not the same as the one you return.



on line 377:

TriMesh model = (TriMesh) BinaryImporter.getInstance().load(
                                    new ByteArrayInputStream(BO1.toByteArray()));



;)

Thank you so much Core-Dump!!! You saved my day! :smiley:

I didn't see that I had declared two times the same variables and it sees the private TriMesh instead the TriMesh that I created inside the method.

Thanks again for your helpful answer!