ObjToJme.convert() throwing IndexOutOfBoundsException

Ok, long time listener, first time caller/poster. I'm trying to load an .obj file, but I keep getting tripped up with an IndexOutOfBoundsException in ObjToJme.convert() (even though convert() isn't supposed to throw those).



URL modelURL = null;
ObjToJme converter = new ObjToJme();
      
try {
   modelURL = new File(objfilename).toURI().toURL();  // objfilename is a string holding a valid path
} catch(MalformedURLException mue) {
   throw new RuntimeException("ERROR: malformed URL: "" + objfilename + ""!");
}
       
// Array will receive JME output
ByteArrayOutputStream BO = new ByteArrayOutputStream();       
       
InputStream inputStream = null;
Spatial modelNode = null;
try {
   inputStream = modelURL.openStream();
           
   // Use the format converter to convert .obj to .jme
   new DummyDisplaySystem();  // required, or we get a NullPointerException from convert()
   converter.convert(inputStream, BO);
   modelNode = (Spatial)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
} catch(IOException ioe) {
   throw new RuntimeException("ERROR: Problems converting "" + objfilename + ""!");
} catch(Exception e) {
   e.printStackTrace();
   return false;
}



When I run that on a very simple .obj file, I get:

java.lang.IndexOutOfBoundsException: Index: 13, Size: 8
   at java.util.ArrayList.RangeCheck(Unknown Source)
   at java.util.ArrayList.get(Unknown Source)
   at com.jmex.model.converters.ObjToJme.addFaces(Unknown Source)
   at com.jmex.model.converters.ObjToJme.processLine(Unknown Source)
   at com.jmex.model.converters.ObjToJme.convert(Unknown Source)
   ...(trace through my own code)...



I took a peek at the source code here (if that's up to date) and there are a number of get() calls where this could be happening. There seemed to be a somewhat relevant thread here but that is almost four years old and their supposed fix obviously hasn't changed things for me (if it's at all related).

Anyway, here's hoping someone knows what might be causing this. For completeness' sake, here's the .obj file:

mtllib <...>

vt 0 0
vt 4 0
vt 4 1
vt 0 1

vt 0 1.3
vt 1.3 0
vt 2.6 0
vt 4 1.3
vt 4 2.6
vt 2.6 4
vt 1.3 4
vt 0 2.6

v 259.5 0 3.5
v 507.5 0 3.5
v 507.5 0 252.5
v 259.5 0 252.5
v 259.5 51.71022654283361 3.5
v 507.5 51.71022654283361 3.5
v 507.5 51.71022654283361 252.5
v 259.5 51.71022654283361 252.5
usemtl RedBrick
f 5/1 6/2 2/3 1/4
f 6/1 7/2 3/3 2/4
f 7/1 8/2 4/3 3/4
f 8/1 5/2 1/3 4/4
f 8/1 7/2 6/3 5/4



Thanks.

Actually, that koders link seems to be looking at the cvs for jme 1.0. Not that anything has really changed in this department, but if you are using jME 2.0 then you’ll want to browse the source here.



A good reference for seeing the model loaders in actions is the ModelLoader.java.

Yeah, I sorta just trusted Google to bring me to the right Koders page, but I didn't really have much hope. In any case, a quick 'diff' comparing the 2.0 and 1.0 versions shows no change, at least in the addFaces() call (where the error takes place).



I'll keep looking. Thanks for the quick response though.

This is the code for addFaces(), which is where I'm getting the exception:


private void addFaces(String[] parts) {
        ArraySet thisMat = materialSets.get(curGroup);
        if (thisMat.objName == null && curObjectName != null)
            thisMat.objName = curObjectName;
        IndexSet first = new IndexSet(parts[1]);
        int firstIndex = thisMat.findSet(first);
        IndexSet second = new IndexSet(parts[2]);
        int secondIndex = thisMat.findSet(second);
        for (int i = 3; i < parts.length; i++) {
            IndexSet third = new IndexSet();
            third.parseStringArray(parts[i]);
            int thirdIndex = thisMat.findSet(third);
            thisMat.indexes.add(firstIndex);
            thisMat.indexes.add(secondIndex);
            thisMat.indexes.add(thirdIndex);
            if (first.nIndex == -1 || second.nIndex == -1 || third.nIndex == -1) {
                // Generate flat face normal.  TODO: Smoothed normals?
                Vector3f v = new Vector3f(vertexList.get(second.vIndex));
                Vector3f w = new Vector3f(vertexList.get(third.vIndex));
                v.subtractLocal(vertexList.get(first.vIndex));
                w.subtractLocal(vertexList.get(first.vIndex));
                v.crossLocal(w);
                v.normalizeLocal();
                genNormalList.add(v);
                int genIndex = (-1 * (genNormalList.size() - 1)) - 2;
                if (first.nIndex == -1) {
                    first.nIndex = genIndex;
                }
                if (second.nIndex == -1) {
                    second.nIndex = genIndex;
                }
                if (third.nIndex == -1) {
                    third.nIndex = genIndex;
                }
            }
            secondIndex = thirdIndex; // The second will be the same as the
                                        // last third
        }
    }



There are about four get() calls in there, I suppose it could be any one of them. It'd be nice to step through that in a debugger, but the jme-model.jar that we have doesn't include the source. A bit of a n00b question, but is there a .jar that includes the source out there?

Afraid not. Best solution would be to checkout the source. There has to be something different about your model, because I use the loader every day with models from Blender. What did you export it from?

I literally just wrote it up myself from a template, just to test showing a basic cube. The whole .obj file is as shown above, so I'm not sure where it could go wrong. Weird.

Aaand, tabernac.



The file was being written to on load in an obscure part of the code.  :oops:



My apologies. Nothing to see here.

Glad you got it figured out.