.OBJ Normal inversion - so we don't have to in Blender

Is it possible to write a method that inverts the normals of a .OBJ file before converting it to JME format? It would save a lot of time for our project's modellers whom currently must do so manually in Blender, as well as other project's modellers, I'm sure.

its not normal to have normals inverted in obj files. modellers don't usually export obj's with inverted normals. so imho that's rather a blender issue than a jme issue. i suppose you wrote a conversion tool for converting your models to jme. there's where that normal inversion belongs.

Blender coordinates system as axes oriented this way: Z=down/up, Y=front/back and X=left/right. While jME is a Y up based coordinate system.



Generally this difference causes a lot of problems for vectors orientation in exported formats, mainly because there is no conversion code, implemented in the export scripts of Blender.



Recently I made a modified version of the obj_export script that converts coordinates system for jME. I have to find it and if you can wait a little I could send it to you. It should work. I do not remember if it converts all coordinates or just object loc/rot/scale matrix. In any case, it could be an help for you to make a patch.

Aye, I ran into that problem, too. When I export blender models, I need to make sure they are facing down the Z axis, which gets frustrating at times :slight_smile:



It's not normal for obj's to be inverted? Hmmm… then I'm guessing Wings exports them inverted by default :frowning:



As for the conversion tool - I've been using the addition of

} else if (filename.endsWith(".OBJ")) {
FormatConverter converter = new ObjToJme();
converter.setProperty("mtllib", file.getAbsoluteFile().toURL());
ByteArrayOutputStream BO=new ByteArrayOutputStream();
converter.convert(file.toURL().openStream(), BO);
model = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));


to ModelLoader. Any idea how I can invert the normals there? :)
I tried this:
} else if (filename.endsWith(".OBJ")) {
FormatConverter converter = new ObjToJme();
converter.setProperty("mtllib", file.getAbsoluteFile().toURL());
ByteArrayOutputStream BO=new ByteArrayOutputStream();
converter.convert(file.toURL().openStream(), BO);
model = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
for (int i = 0; i < model.getQuantity(); i++) {
for (int w = 0; w < ((Geometry)model.getChild(i)).getBatchCount(); w++) {
((Geometry)model.getChild(i)).getBatch(w).getNormalBuffer().flip();
}
}


But nothing happens :(

To make the conversion directly into the real time engine (in this case jME) is normally not a good approach to the problem, in my opinion.



It would be better if you modify the Blender export script to flip normals or to convert system axes orientation to obtain a correctly oriented model.



Unfortunately I have lost my modified version of the OBJ export script for Blender. But it should not be so hard to recreate the same thing. I made a similar thing in to the code of the blender2cal3d script: visit the page and download it here to explore my code.