.Obj Model Import

I copied the exact code from the “howto jme2 and Blender2.48” (http://www.jmonkeyengine.com/wiki/doku.php/howto_jme2_and_blender2.48) for importing .obj models to JME… and it isnt working…



It keeps throwing a NullPointer exception at line 42 ( converter.convert(model.openStream(), BO); )



import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.PointLight;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.CameraNode;
import com.jme.scene.Spatial;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;

public class TestModelImport extends SimpleGame {

    private Spatial map;
   
    public static void main(String[] args) {
        TestModelImport app = new TestModelImport();  //changed name of program
        app.setConfigShowMode(ConfigShowMode.AlwaysShow);
        Logger.getLogger("").setLevel(Level.SEVERE);
        app.start();
    }
 
    protected void simpleInitGame() { 
        display.setTitle("Test Import Models: Shade Mk.I");  // changed model name
        URL folder= TestModelImport.class.getClassLoader().getResource("gameResources/");  // changed path
        URL model = TestModelImport.class.getClassLoader().getResource("gameResources/Shade Mk.I");  // changed path
        FormatConverter converter=new ObjToJme();
        converter.setProperty("mtllib", folder);
        converter.setProperty("texdir", folder);
 
        ByteArrayOutputStream BO=new ByteArrayOutputStream();
        try {
            converter.convert(model.openStream(), BO);
            map=(Spatial) BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            map.setLocalScale(4f);
 
            map.setModelBound(new BoundingBox());
            map.updateModelBound();
            rootNode.attachChild(map);
        } catch (Exception e) {
            System.out.println("Damn exceptions! O_o n" + e);
            e.printStackTrace();
            System.exit(0);
        }
        PointLight light = new PointLight();
        light.setDiffuse( new ColorRGBA( 0.75f, 0.75f, 0.75f, 0.75f ) );
        light.setAmbient( new ColorRGBA( 200f, 200f, 200f, 1.0f ) );
        light.setLocation( new Vector3f( 0, 0, 0 ) );
        light.setEnabled( true );
        lightState = display.getRenderer().createLightState();
        lightState.setEnabled( true );
        lightState.attach( light );
        rootNode.setRenderState( lightState );       
 
        KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);
        CameraNode camNode = new CameraNode("", cam);
        camNode.setLocalTranslation(0, 1.5f, 0);
    }

}


the converter can't locate the file. make sure the path is right. And can you tell me

what kind of obj-file is called "Shade Mk.I"? :smiley: PLZPLZ, use a filename without blank and with the right extension (.obj) just to be sure or you will be lost…sooner or later

facepalm



i totally forgot to remove the ending there. that was intended for personal reference and not to be used on the .obj file.



i am still getting the NullPointerException, even though the file is in the right location…



Here is console text:



java.io.FileNotFoundException: C:UsersGettinrim33workspaceBloodSugarbingameResourcesShade (The system cannot find the file specified)

java.io.FileNotFoundException: C:UsersGettinrim33workspaceBloodSugarbingameResourcesShade (The system cannot find the file specified)

at java.io.FileInputStream.open(Native Method)

at java.io.FileInputStream.<init>(Unknown Source)

at java.io.FileInputStream.<init>(Unknown Source)

at sun.net.www.protocol.file.FileURLConnection.connect(Unknown Source)

at sun.net.www.protocol.file.FileURLConnection.getInputStream(Unknown Source)

at java.net.URL.openStream(Unknown Source)

at com.jmex.model.converters.ObjToJme.loadMaterials(ObjToJme.java:432)

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

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

at game3d.TestModelImport.simpleInitGame(TestModelImport.java:42)

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

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

at game3d.TestModelImport.main(TestModelImport.java:29)



code, again… :

public class TestModelImport extends SimpleGame {

    private Spatial map;
    
    public static void main(String[] args) {
        TestModelImport app = new TestModelImport();
        app.setConfigShowMode(ConfigShowMode.AlwaysShow);
        Logger.getLogger("").setLevel(Level.SEVERE);
        app.start();
    }
 
    protected void simpleInitGame() {  
        display.setTitle("Test Import Models: Shade Mk.I");
        URL folder= TestModelImport.class.getClassLoader().getResource("gameResources/");
        URL model = TestModelImport.class.getClassLoader().getResource("gameResources/Shade.obj");
        FormatConverter converter=new ObjToJme();
        converter.setProperty("mtllib", folder);
        converter.setProperty("texdir", folder);
 
        ByteArrayOutputStream BO=new ByteArrayOutputStream();
        try {
            converter.convert(model.openStream(), BO);
            map=(Spatial) BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            map.setLocalScale(4f);
 
            map.setModelBound(new BoundingBox());
            map.updateModelBound();
            rootNode.attachChild(map);
        } catch (Exception e) {
            System.out.println("Damn exceptions! O_o n" + e);
            e.printStackTrace();
            System.exit(0);
        }
        PointLight light = new PointLight();
        light.setDiffuse( new ColorRGBA( 0.75f, 0.75f, 0.75f, 0.75f ) );
        light.setAmbient( new ColorRGBA( 200f, 200f, 200f, 1.0f ) );
        light.setLocation( new Vector3f( 0, 0, 0 ) );
        light.setEnabled( true );
        lightState = display.getRenderer().createLightState();
        lightState.setEnabled( true );
        lightState.attach( light );
        rootNode.setRenderState( lightState );        
 
        KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);
        CameraNode camNode = new CameraNode("", cam);
        camNode.setLocalTranslation(0, 1.5f, 0);
    }

}



EDIT: I copied the JMETest file for loading models and it works perfectly with the maggie model on there.... but it will not accept mine....

i exported the model from Blender 2.49 as a Wavefront .obj. The options i selected were Normals, HQ, Edges, Objects, rotate x90. Is this something to do with Blender and a new export "style" or something?

Hmm,…



I wonder why java is cutting off the extension of your filename in the exception. This problem is definetly on the java side and has nothing to do with your exporting.



Well…two last options:

  1. Are you using eclipse? If yes, did you refresh your project after creating the file? Otherwise it will not be copied to your binary-directory
  2. Your application searches the file in the classpath-direcotry gameResources. Which means you have to place this directory in your src-directory. Not above…



    If both is not working. Pack it as zip and upload it here and I will have a look.


urg… so, i just started up Eclipse again and ran the program and it threw me this:



SEVERE: Exception in game loop

java.lang.ClassCastException: com.jme.scene.TriMesh cannot be cast to com.jme.scene.Node

at game3d.TestModelImport.simpleInitGame(TestModelImport.java:42)

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

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

at game3d.TestModelImport.main(TestModelImport.java:24)





i read the code a little and see that it says that the converter needs to find the .mtl file and not the .obj (both are in the same file…). So i change the path from .obj to .mtl and run the program.



this time it works… well, works as in it doesnt crash. everything is black, so i push f4 to see if anything is happening.



frames are at a steady 450, but the avg. Tex binds is 0 and nothing else is displayed…

Class-Cast exception was a good exception, showing us you finally got your model loaded.

So go back and use the .obj-file.



Your problem was that you tried to Cast a TriMesh to a Node what is not possible. Just replace

this cast to TriMesh. This tree-mesh you can add to your rootNode.



If the folder-url is set up right the COnverter should find the .mat-file on its own.



Good luck

ah, okay. works now! Thanks!



here is the final code for future reference:


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.scene.Node;
import com.jme.scene.TriMesh;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;

public class TestModelImport extends SimpleGame {
   
    private static final Logger logger = Logger
   .getLogger(TestModelImport.class.getName());
   
    public static void main(String[] args) {
        TestModelImport app = new TestModelImport();
        app.setConfigShowMode(ConfigShowMode.AlwaysShow);
        app.start();
    }
 
    protected void simpleInitGame() { 
      // Point to a URL of my model
       URL model = TestModelImport.class.getClassLoader().getResource(
         "gameResources/Shade.obj");
 
      // Create something to convert .obj format to .jme
      FormatConverter converter = new ObjToJme();
      // Point the converter to where it will find the .mtl file from
      converter.setProperty("mtllib", model);
 
      // This byte array will hold my .jme file
      ByteArrayOutputStream BO = new ByteArrayOutputStream();
      try {
         // Use the format converter to convert .obj to .jme
         converter.convert(model.openStream(), BO);
         TriMesh shade = (TriMesh) BinaryImporter.getInstance().load(
            new ByteArrayInputStream(BO.toByteArray()));
         // shrink this baby down some
         shade.setLocalScale(1f);
         shade.setModelBound(new BoundingSphere());
         shade.updateModelBound();
         // Put her on the scene graph
         rootNode.attachChild(shade);
      } catch (IOException e) { // Just in case anything happens
         logger.logp(Level.SEVERE, this.getClass().toString(),
            "simpleInitGame()", "Exception", e);
         System.exit(0);
      }
    }

}