Skip to main content

Loading an .OBJ file along with its .MTL

No replies
lyfox
Offline
Joined: 2010-08-17

Yesterday I came upon a very unpleasant situation, when trying to create an application, which could load any .OBJ files on user's demand.

So, it actually goes like this: you convert your model from .MAX or whatever-that-3Deditor-is to .OBJ, get your materials and textures stored separately, load your model through ObjectFile class and get a tremendously beautiful white-coloured empty mesh. I've seen some posts about such problems recently, and since neither of the answers there helped me, it took me some time to make an analysis on this. Hope this would be of some use to anyone.

The reason of failure was actually hidden deep inside the source files. So here's a fragment of ObjectFileMaterials.java

void readMaterialFile(boolean fromUrl, String basePath, String fileName)
throws ParsingErrorException {
<...somecode...>
/**/ try {
/**//**/ if (fromUrl) {
/**//**//**/ reader = (Reader)
/**//**//**//**/ (new InputStreamReader(
/**//**//**//**//**/ new BufferedInputStream(
/**//**//**//**//**//**/ (new URL(basePath + fileName).openStream()))));
/**//**/ } else {
/**//**//**/ reader = new BufferedReader(new FileReader(basePath + fileName));
/**//**/ }
/**/ }
catch (IOException e) {
// couldn't find it - ignore mtllib
return;
}
<...somecode...>
} // End of readMaterialFile

Thanks to all the people, catching those tiresome exceptions and saying NOTHING to us about it... The .MTL file was mentioned inside .OBJ, but Loader could not find it nearby - so let it go to hell, right? At least you could warn or something...

I was almost going to begin developing my own obj-parser, when I stumbled upon this (gotta read those documentations carefully.. well, takes helluva time):

mtllib filename
Load material properties from the named file. Materials with the same name as the predefined materials above will override the default value. Any directory path information in (filename) is ignored. The .mtl files are assumed to be in the same directory as the .obj file. If they are in a different directory, use Loader.setBasePath() (or Loader.setBaseUrl() ).

So, here we are and our trousers.
Before you call .load() method, make sure you've set the Base Path for ALL your model-concerned files (that means, all the maps should be in the same folder as OBJ and MTL).

Hope this could help. Good luck.

P.S. One more thing. Don't forget about directory separators being different on Linux(/) and Windows(\\). Use java.io.File.separator to make sure your application is cross-platform. Otherwise your .setBasePath() call will be ignored and set to default.