Trouble loading my .obj file

I have looked through the tutorial on loading with .obj file format and I have even browsed the forums and other wiki items and I still can't seem to get this to work… What I did was basically took the loading tutorial and switched  the file names but left everything else the same.


import com.jme.app.AbstractGame;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.scene.Node;
import com.jme.util.export.binary.BinaryImporter;

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;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Started Date: Jul 22, 2004<br><br>
 *
 * Demonstrates loading formats.
 *
 * @author Jack Lindamood
 */
public class HelloModelLoading extends SimpleGame {

    public static void main(String[] args) {
        HelloModelLoading app = new HelloModelLoading();
        app.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
        // Turn the logger off so we can see the XML later on
        Logger.getLogger(HelloModelLoading.class.getName()).setLevel(Level.OFF);
        app.start();
    }

    protected void simpleInitGame() {
        // Point to a URL of my model
        URL model = HelloModelLoading.class.getClassLoader().getResource
                //("jmetest/data/model/maggie.obj");
                ("jmetest/data/model/Monkey.obj");
                //("Monkey.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);
            Node maggie = (Node) BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));

            // shrink this baby down some
            maggie.setLocalScale(.1f);
            maggie.setModelBound(new BoundingSphere());
            maggie.updateModelBound();

            // Put her on the scene graph
            rootNode.attachChild(maggie);
        } catch (IOException e) {   // Just in case anything happens

            System.out.println("Damn exceptions!" + e);
            e.printStackTrace();
            System.exit(0);
        }
    }
}



I put my .obj and .mtl files in the given file directory, but I keep getting null pointer exceptions. Any ideas of what I am doing wrong?

I think the resource is probably not found. It is possibly not in your classpath.



Try replacing the line where "URL Model" is initialized with this, but modify the path in the File constructor to suit your environment. If the file is not found you will also see an exception.



  // Point to a URL of my model
  URL model = null;
  try {
    model = new File("C:/path/to/jme2/src/jmetest/data/model/maggie.obj").toURL();
  } catch (MalformedURLException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
  }

In the line of code that said:


model = new File("C:/path/to/jme2/src/jmetest/data/model/maggie.obj").toURL();



Did you mean that I should put:

model = new File("C:/path/to/jme2/src/jmetest/data/model/Monkey.obj").toURL();



because the example works fine with maggie, it just doesn't work with the model I am using.


So I changed my code to look like this:


import com.jme.app.AbstractGame;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.scene.Node;
import com.jme.util.export.binary.BinaryImporter;

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;
import java.util.logging.Level;
import java.util.logging.Logger;

import java.net.MalformedURLException;
import java.io.File;

public class monkeyHeadLoading extends SimpleGame
{
    public static void main(String[] args) {
        monkeyHeadLoading app = new monkeyHeadLoading();
        app.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
        // Turn the logger off so we can see the XML later on
        Logger.getLogger(monkeyHeadLoading.class.getName()).setLevel(Level.OFF);
        app.start();
    }

    protected void simpleInitGame() {
        // Point to a URL of my model
        //URL model = monkeyHeadLoading.class.getClassLoader().getResource("Monkey.obj");

        URL model = null;

        try {
                model = new File("C:/Users/Josh/Desktop/Java/jMEpractice/jMEexample07/src/Monkey.obj").toURL();
              } catch (MalformedURLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
              }

        // 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);
            Node maggie = (Node) BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));

            // shrink this baby down some
            maggie.setLocalScale(.1f);
            maggie.setModelBound(new BoundingSphere());
            maggie.updateModelBound();

            // Put her on the scene graph
            rootNode.attachChild(maggie);
        } catch (IOException e) {   // Just in case anything happens

            System.out.println("Damn exceptions!" + e);
            e.printStackTrace();
            System.exit(0);
        }
    }
}



And I get the following error messages:

SEVERE: Exception in game loop
java.lang.ClassCastException: com.jme.scene.TriMesh
        at monkeyHeadLoading.simpleInitGame(monkeyHeadLoading.java:65)
        at com.jme.app.BaseSimpleGame.initGame(Unknown Source)
        at com.jme.app.BaseGame.start(Unknown Source)
        at monkeyHeadLoading.main(monkeyHeadLoading.java:38)


I am really not sure what the problem is?

Wanna change that tutorial after I explain and you understand??



(this gets EVERYONE, dont worry)



A Trimesh is a spatial with geometry; a Node is also a spatial but with no geometry of its own, only 'sub-spatials' (either TriMeshes or other Nodes)…



(the maggie model has just a single mesh, so jME loads it as a TriMesh.  Dr. Freak on the other hand has more than one mesh so gets loaded as a Node)



To be safe, always load you model as a Spatial then after its loaded (if needed) check to see if its a TriMesh w/

model instanceof TriMesh


if its a not TriMesh you know its a Node
(perhaps the tutorial should say something like this...)


Make sense?

I even just got .obj and .mtl files for a different model and I am still getting the same errors… Has anyone else experienced this? Does anyone know what I should do to fix this?

java.lang.ClassCastException: com.jme.scene.TriMesh



That means, the model loader does not return a Node as expected, just a TriMesh.



Try:


Spatial maggie = (Spatial) BinaryImporter.getInstance().load();



Spatial is the base Class of Node and TriMesh.

Okay, that worked and I am glad it did because I was finally able to load my own model into jME, but why did that work and why didn't it work with just casting it as a node like they tutorial showed?

Okay, yes that does make a lot more sense now. That would be nice if it said that in the tutorial.



Also, the textures that were given to the model in Blender aren't showing on the model when it is in jME. Why is this?

WELL… this can be from several things (I have found if there are absolute paths in the resource locate its can get screwed up sometimes)



Basically, search your output for "ResourceLocate"  and you should find a mesg that says it wasn't able to find a texture…



(Also, ResourceLocator is how you specify locations to search for textures when the model is loading; so you might want to look at how that works…)

Well this is my output…



Dec 12, 2008 4:53:01 PM com.jme.app.BaseGame start

INFO: Application started.

Dec 12, 2008 4:53:01 PM com.jme.system.PropertiesIO <init>

INFO: PropertiesIO created

Dec 12, 2008 4:53:01 PM com.jme.system.PropertiesIO load

INFO: Read properties

Dec 12, 2008 4:53:05 PM com.jme.system.PropertiesIO save

INFO: Saved properties

Dec 12, 2008 4:53:05 PM com.jme.app.BaseSimpleGame initSystem

INFO: jME version 1.0

Dec 12, 2008 4:53:05 PM com.jme.input.joystick.DummyJoystickInput <init>

INFO: Joystick support is disabled

Dec 12, 2008 4:53:05 PM com.jme.system.lwjgl.LWJGLDisplaySystem <init>

INFO: LWJGL Display System created.

Dec 12, 2008 4:53:05 PM com.jme.renderer.lwjgl.LWJGLRenderer <init>

INFO: LWJGLRenderer created. W:  640H: 480

Dec 12, 2008 4:53:06 PM com.jme.app.BaseSimpleGame initSystem

INFO: Running on: vga

Driver version: 6.0.6000.16386

NVIDIA Corporation - GeForce Go 7400/PCI/SSE2 - 2.1.0

Dec 12, 2008 4:53:06 PM com.jme.renderer.AbstractCamera <init>

INFO: Camera created.

Dec 12, 2008 4:53:06 PM com.jme.util.lwjgl.LWJGLTimer <init>

INFO: Timer resolution: 1000 ticks per second

Dec 12, 2008 4:53:06 PM com.jme.scene.Node <init>

INFO: Node created.

Dec 12, 2008 4:53:06 PM com.jme.scene.Node <init>

INFO: Node created.

Dec 12, 2008 4:53:06 PM com.jme.scene.Node attachChild

INFO: Child (FPS label) attached to this node (FPS node)

Dec 12, 2008 4:53:06 PM com.jme.scene.Node <init>

INFO: Node created.

Dec 12, 2008 4:53:06 PM com.jme.util.geom.GeometryTool minimizeVerts

INFO: batch: temp0: Batch 0 old: 2288 new: 2288

Dec 12, 2008 4:53:06 PM com.jme.scene.Node attachChild

INFO: Child (temp0) attached to this node (obj file)

Dec 12, 2008 4:53:07 PM com.jme.scene.Node attachChild

INFO: Child (temp0) attached to this node (rootNode)

Dec 12, 2008 4:53:11 PM com.jme.app.BaseSimpleGame cleanup

INFO: Cleaning up resources.

Dec 12, 2008 4:53:11 PM com.jme.app.BaseGame start

INFO: Application ending.

BUILD SUCCESSFUL (total time: 11 seconds)



It doesn't look like there is anything there about the texture?

Treebranch said:

Okay, yes that does make a lot more sense now. That would be nice if it said that in the tutorial.

Also, the textures that were given to the model in Blender aren't showing on the model when it is in jME. Why is this?


did you check http://www.jmonkeyengine.com/wiki/doku.php?id=exporting_.obj_models_from_blender ?

You prolly didn't set/export the UV (texture) coords :wink: