Loading landscape causes Java Heap Space error

The title speaks for it self… I'm trying to load a model made with blender, it's in .obj format, but I get Java Heap Space Error when the game starts, but the problem isn't with loading it. The file is like, 8 MB sized.



Stack trace:



       

java.lang.OutOfMemoryError: Java heap space

        at java.util.HashMap.resize(HashMap.java:462)

        at java.util.LinkedHashMap.addEntry(LinkedHashMap.java:414)

        at java.util.HashMap.put(HashMap.java:385)

        at java.util.HashSet.add(HashSet.java:200)

        at com.jmex.model.converters.ObjToJme$ArraySet.findSet(ObjToJme.java:630)

        at com.jmex.model.converters.ObjToJme.addFaces(ObjToJme.java:463)

        at com.jmex.model.converters.ObjToJme.processLine(ObjToJme.java:329)

        at com.jmex.model.converters.ObjToJme.convert(ObjToJme.java:158)

        at jme.game.Main.createScene(Main.java:39)

        at jme.game.Main.simpleInitGame(Main.java:25)

        at com.jme.app.BaseSimpleGame.initGame(BaseSimpleGame.java:545)

        at com.jme.app.BaseGame.start(BaseGame.java:74)

        at jme.game.Main.main(Main.java:21)



Code to loading the model (I don't know if this matters, but...)

private Node createScene() {
            Node scene = new Node("scene");

            Spatial landscape;

            URL model = Main.class.getClassLoader().getResource("jme/data/models/landscape.obj");
            FormatConverter converter = new ObjToJme();
            converter.setProperty("mtllib", model);

            ByteArrayOutputStream BO = new ByteArrayOutputStream();
            try {
                converter.convert(model.openStream(), BO);
                landscape = (Spatial) BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));

                landscape.setModelBound(new BoundingBox());
                landscape.updateModelBound();

                scene.attachChild(landscape);
            } catch (IOException e) {
                System.exit(0);
            }
            return scene;
        }



Happy easter.

This just means that your model isn't fitting into the amount of memory allocated by your JVM.  Add -Xmx256M (or 512 or 1024) to the command line arguments when running your application.

Where's that in NetBeans?

Just as i see it:



  URL model = Main.class.getClassLoader().getResource("jme/data/models/landscape.obj");

        FormatConverter converter = new ObjToJme();

        converter.setProperty("mtllib", model);



        ByteArrayOutputStream BO = new ByteArrayOutputStream();



save the Bo data, in like landscape_cached.jme

And load then that file if it exists.

I would say between obj and jmenative format there is a factor 10X or larger in speedup.



(Just keep the obj and generate the cached from them, cause even if it is unlikly there may be the possibilty that the jmenativ format changes over versions, while obj is standarized)


lolz ^^

It loads,  but the model looks cuby and it take about 5min to skip a whole black screen.

well 8mb and obj, how much polygons does the model have? I suspect that youa re wasting huge amounts of performans due to to much polygons.

Are you using shadows?  On larger scenes, shadow creation can be a lengthy process on startup.  I've loaded ~55mb OBJ's previously and while loading took a little while longer, it wasn't anything astronomical like 5 mins.  (though this all depends on the speed of your processor ;))

The model was too small, so i set the scale for 1000f, yes I know it's too much. Yes, there are a lot of shadows in the scene. If you want some pictures tell me. There is nothing important in my code, so I'll show for you guys:


package jme.game;

import java.nio.FloatBuffer;

import com.jme.app.SimplePassGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.Plane;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.pass.RenderPass;
import com.jme.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.Spatial.TextureCombineMode;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.CullState;
import com.jme.scene.state.FogState;
import com.jme.scene.state.ZBufferState;
import com.jme.util.TextureManager;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.effects.water.WaterRenderPass;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;

public class Main extends SimplePassGame {
    private WaterRenderPass waterEffectRenderPass;
    private Skybox skybox;
    private Quad waterQuad;
    private float farPlane = 10000.0f;
    private float textureScale = 0.02f;

    public static void main(String[] args) {
        Main app = new Main();
        app.setConfigShowMode(ConfigShowMode.ShowIfNoConfig);
        app.start();
    }

    @Override
    protected void cleanup() {
        super.cleanup();
        waterEffectRenderPass.cleanup();
    }

    @Override
    protected void simpleUpdate() {
        if (KeyBindingManager.getKeyBindingManager().isValidCommand("TAB", false)) {
            // Open the GUI
        }

        skybox.getLocalTranslation().set(cam.getLocation());
        skybox.updateGeometricState(0.0f, true);

        Vector3f transVec = new Vector3f(cam.getLocation().x,
                waterEffectRenderPass.getWaterHeight(), cam.getLocation().z);

        setTextureCoords(0, transVec.x, -transVec.z, textureScale);
        setVertexCoords(transVec.x, transVec.y, transVec.z);
    }

    protected void simpleInitGame() {
        display.setTitle("Water Test");
        cam.setFrustumPerspective(45.0f, (float) display.getWidth()
                / (float) display.getHeight(), 1f, farPlane);
        cam.setLocation(new Vector3f(100, 50, 100));
        cam.lookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y);
        cam.update();

        setupKeyBindings();
        setupFog();

        Node reflectedNode = new Node("reflectNode");

        buildSkyBox();
        reflectedNode.attachChild(skybox);
        reflectedNode.attachChild(createObjects());

        rootNode.attachChild(reflectedNode);

        waterEffectRenderPass = new WaterRenderPass(cam, 4, false, true);

        waterEffectRenderPass.setWaterPlane(new Plane(new Vector3f(0.0f, 1.0f,
                0.0f), 0.0f));

        waterQuad = new Quad("waterQuad", 1, 1);
        FloatBuffer normBuf = waterQuad.getNormalBuffer();
        normBuf.clear();
        normBuf.put(0).put(1).put(0);
        normBuf.put(0).put(1).put(0);
        normBuf.put(0).put(1).put(0);
        normBuf.put(0).put(1).put(0);

        waterEffectRenderPass.setWaterEffectOnSpatial(waterQuad);
        rootNode.attachChild(waterQuad);

        waterEffectRenderPass.setReflectedScene(reflectedNode);
        waterEffectRenderPass.setSkybox(skybox);
        pManager.add(waterEffectRenderPass);

        RenderPass rootPass = new RenderPass();
        rootPass.add(rootNode);
        pManager.add(rootPass);

        RenderPass statPass = new RenderPass();
        statPass.add(statNode);
        pManager.add(statPass);

        rootNode.setCullHint(Spatial.CullHint.Never);
        rootNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
    }

    private void setVertexCoords(float x, float y, float z) {
        FloatBuffer vertBuf = waterQuad.getVertexBuffer();
        vertBuf.clear();

        vertBuf.put(x - farPlane).put(y).put(z - farPlane);
        vertBuf.put(x - farPlane).put(y).put(z + farPlane);
        vertBuf.put(x + farPlane).put(y).put(z + farPlane);
        vertBuf.put(x + farPlane).put(y).put(z - farPlane);
    }

    private void setTextureCoords(int buffer, float x, float y,
            float textureScale) {
        x *= textureScale * 0.5f;
        y *= textureScale * 0.5f;
        textureScale = farPlane * textureScale;
        FloatBuffer texBuf;
        texBuf = waterQuad.getTextureCoords(buffer).coords;
        texBuf.clear();
        texBuf.put(x).put(textureScale + y);
        texBuf.put(x).put(y);
        texBuf.put(textureScale + x).put(y);
        texBuf.put(textureScale + x).put(textureScale + y);
    }

    private void setupFog() {
        FogState fogState = display.getRenderer().createFogState();
        fogState.setDensity(1.0f);
        fogState.setEnabled(true);
        fogState.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
        fogState.setEnd(farPlane);
        fogState.setStart(farPlane / 10.0f);
        fogState.setDensityFunction(FogState.DensityFunction.Linear);
        fogState.setQuality(FogState.Quality.PerVertex);
        rootNode.setRenderState(fogState);
    }

    private void buildSkyBox() {
        skybox = new Skybox("skybox", 10, 10, 10);

        String dir = "jme/data/textures/skybox/";
        Texture north = TextureManager.loadTexture(Main.class
                .getClassLoader().getResource(dir + "1.jpg"),
                Texture.MinificationFilter.BilinearNearestMipMap,
                Texture.MagnificationFilter.Bilinear);
        Texture south = TextureManager.loadTexture(Main.class
                .getClassLoader().getResource(dir + "3.jpg"),
                Texture.MinificationFilter.BilinearNearestMipMap,
                Texture.MagnificationFilter.Bilinear);
        Texture east = TextureManager.loadTexture(Main.class
                .getClassLoader().getResource(dir + "2.jpg"),
                Texture.MinificationFilter.BilinearNearestMipMap,
                Texture.MagnificationFilter.Bilinear);
        Texture west = TextureManager.loadTexture(Main.class
                .getClassLoader().getResource(dir + "4.jpg"),
                Texture.MinificationFilter.BilinearNearestMipMap,
                Texture.MagnificationFilter.Bilinear);
        Texture up = TextureManager.loadTexture(Main.class
                .getClassLoader().getResource(dir + "6.jpg"),
                Texture.MinificationFilter.BilinearNearestMipMap,
                Texture.MagnificationFilter.Bilinear);
        Texture down = TextureManager.loadTexture(Main.class
                .getClassLoader().getResource(dir + "5.jpg"),
                Texture.MinificationFilter.BilinearNearestMipMap,
                Texture.MagnificationFilter.Bilinear);

        skybox.setTexture(Skybox.Face.North, north);
        skybox.setTexture(Skybox.Face.West, west);
        skybox.setTexture(Skybox.Face.South, south);
        skybox.setTexture(Skybox.Face.East, east);
        skybox.setTexture(Skybox.Face.Up, up);
        skybox.setTexture(Skybox.Face.Down, down);
        skybox.preloadTextures();

        CullState cullState = display.getRenderer().createCullState();
        cullState.setCullFace(CullState.Face.None);
        cullState.setEnabled(true);
        skybox.setRenderState(cullState);

        ZBufferState zState = display.getRenderer().createZBufferState();
        zState.setEnabled(false);
        skybox.setRenderState(zState);

        FogState fs = display.getRenderer().createFogState();
        fs.setEnabled(false);
        skybox.setRenderState(fs);

        skybox.setLightCombineMode(Spatial.LightCombineMode.Off);
        skybox.setCullHint(Spatial.CullHint.Never);
        skybox.setTextureCombineMode(TextureCombineMode.Replace);
        skybox.updateRenderState();

        skybox.lockBounds();
        skybox.lockMeshes();
    }

    private Node createObjects() {
        Node objects = new Node("objects");

        Spatial landscape;

        URL model = Main.class.getClassLoader().getResource("jme/data/models/landscape.obj");
        FormatConverter converter = new ObjToJme();
        converter.setProperty("mtllib", model);

        ByteArrayOutputStream BO = new ByteArrayOutputStream();
        try {
            converter.convert(model.openStream(), BO);
            landscape = (Spatial) BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));

            landscape.setLocalTranslation(new Vector3f(0, -3, 0));
            landscape.setLocalScale(1000f);

            landscape.setModelBound(new BoundingBox());
            landscape.updateModelBound();

            objects.attachChild(landscape);
        } catch (IOException e) {
            System.exit(0);
        }      
        return objects;
    }

    private void setupKeyBindings() {
        KeyBindingManager.getKeyBindingManager().set("TAB", KeyInput.KEY_TAB);

        Text t = Text.createDefaultTextLabel("Text", " Press TAB to open the menu.");
        t.setRenderQueueMode(Renderer.QUEUE_ORTHO);
        t.setRandomColors();
        t.setLightCombineMode(Spatial.LightCombineMode.Off);
        t.setLocalTranslation(new Vector3f(0, 455, 1));
        statNode.attachChild(t);
    }
}

I was not able to find any example of what you're talking about at TestChooser. I don't wanna bother you, but you can give me a simple example?





Regards, Gustavo Borba.

Assuming for this example that your loaded model is called "myModel":



FileOutputStream fos = new FileOutputStream(new File("binary_model.jme"));
BinaryExporter.getInstance().save(myModel, fos);