Loading custom textured mesh into scene graph

Hi,

I have a OBJ (with respective material files, MTL, etc.) model that I created myself and that I can load into Blender just fine.

I am now trying to load that model into jME3 and am having difficulty getting it to display correctly.

My full source code can be found here, and if you’re interested in reproducing what I’m seeing you just need to clone it and run gradlew run (or ./gradlew run on Mac) from a terminal. But the long-story short is that this code:

    public class SampleApp extends SimpleApplication {
        public static void main(String[] args) {
            new SampleApp().start();
        }

        @Override
          public void simpleInitApp() {
            Spatial spatial = assetManager.loadModel("house-ext-front/house-ext-front.obj");
            rootNode.attachChild(spatial);

    /*
            // Attempt to zoom the camera closer to the model...
            float aspect = (float) settings.getWidth() / settings.getHeight();
                float invZoom = 20f;
                float product = aspect * invZoom;
                cam.setParallelProjection( true );
                cam.setFrustum( 0f, 150f, -product, product, -invZoom, invZoom );
                cam.update();
    */

            DirectionalLight sun = new DirectionalLight();
            sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));

            rootNode.addLight(sun);
        }
    }

…produces this scene graph/display.

Squinting at the model, it seems I have several issues:

  • The model is not rotated/oriented as I had expected; and
  • The model is fairly far away from the camera; and
  • It almost looks like the OBJ file isn’t being read correctly, and/or the full mesh and textures aren’t being read correctly. But it’s hard to tell because the spatial is so far away from the camera.

For the rotation/orientation issue, I have tried adding and tweaking the arguments of this setter, but to no avail:

    spatial.setLocalTranslation(0.0f, -5.0f, -2.0f) // I've played with many different arg values

For the issue regarding the model being far away from the camera, the following code (which is also in the snippet above) is what I tried to “zoom” the camera in, but that doesn’t help either:

    /*
        // Attempt to zoom the camera closer to the model...
        float aspect = (float) settings.getWidth() / settings.getHeight();
            float invZoom = 20f;
            float product = aspect * invZoom;
            cam.setParallelProjection( true );
            cam.setFrustum( 0f, 150f, -product, product, -invZoom, invZoom );
            cam.update();
    */

As for the model or its textures not being loaded correctly, I simply have no idea where that might be going wrong. It will be easier to tell once I have the first two issue solved. However, perhaps there is bad dat in the model/texture files that Blender simply ignores (or auto-corrects) that jME3 does not.

Can anybody steer me in the right direction here?

As for the scaling / distance you could try this:

cam.setLocation(Vector3f.ZERO);

and in the simpleUpdate method:

spatial.setLocalTranslation(cam.getDirection().mult(some_distance));

Maybe this helps to debug your problem.
BTW: The orientation of your model may depend on the orientation of the axes that you chose while exporting the model (from blender?). At least I always had this problem.

Hello, does your model looks as it should in the,SDK? If not, I would suggest to open that model in blender, apply location, rotation and scale and export it as .blend or as ogre format and have a look again. I hope it helps you!

Thanks both!

@Apollo - any suggestions for a starting value (or range of values) for some_distance?

Also, both @Apollo and @Domenic - I assume that I can use jME3 to apply my own location/rotation/scale on a model, regardless of what its values are in the OBJ/MTL files, yes?

Thanks again!

Yes, for that the SDK is very handy!

Well, it depends on the field-of-view angle of the camera and the size of the object.
You can either use trigonometry to calculate the exact distance, such that your object fits inside the view nicely OR you do a little bit of trial and error. What about 10 times the size of your object as a starting point?

Feel free to use spatial.setLocalRotation and spatial.setLocalScale.

…or… since it seems like the default app setup (assuming all of the code for the app class has been included) then FlyCam will be enabled by default and so will the debug keys.

Fly the camera using WASD to get a view you like then press ‘c’. Look at the console to get the code for where the camera should be.

Edit: note it sounds like your model is super tiny. I guess 1 unit = 1 meter wasn’t used when it was created.

Edit2: though looking at the image it seems like the obj itself has bad data… so who knows.

Thanks @pspeed I’ll give your suggestions (using the fy cam) a try in a little bit.

When you say that the OBJ file itself has bad data, can you elaborate? Again, I’m able to load the same file in Blender and it displays exactly as it should (see the first picture in my question). Although, admittedly, when I load it in Blender, I have to zoom way in on it and rotate it a bit (so yes, it is tiny).

But your comment about it having “bad data” concerns me. Thoughts?

“Bad data” from JME’s perspective. Our OBJ loader is bound to be simpler than Blender’s… though really OBJ is a super simple format.

And comparing the images, maybe it’s fine and it’s just messed up when zoomed so far out.

Personally, I’d scale it up in Blender, apply the scale, and then re-export it… or just save it as a .blend file and see if JME’s .blend importer will read it properly. (In the SDK)

Thanks @pspeed - though I be a rookie, I think I can say this is definitely a transformation + lighting issue, not something with the OBJ file (or how jME3 is loading it):

see-the-window

I tried your suggestion to use the FlyCam to zoom in on the model and fly around it. Admittedly I struggled with that, but if you look closely in the screenshot above, you should be able to make out my bedroom window (lol).

So I think this is a metter of my orienting the model correctly (in the center of the screen) and applying light to it at the right angle.

I will attempt to solve the orientation problem via the process that creates these models (manually correcting them in a tool like Blender or the jME3 SDK isn’t an option for me, they have to be corrected automatically/programmatically due to the nature of my game).

As for the lighting, I currently have:

DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));

Admittedly, I stole this from a tutorial/jME3 question somewhere, and it is likely incorrect. Is there a way in jME3 to apply “everywhere” or to apply multiple lights, evenly distributed (in spherical pattern) around a center point? I can probably figure out the code for this but was wondering if it would help rule lighting out as an issue, or even cause more problems/red herrings for me. Thanks for any input!

If you don’t want lighting then don’t use the lighting material. Just use the unshaded material… then you don’t even need any lights.

Thanks again @pspeed, I removed those lines (that created and added the sun) and it had no effect whatsoever on the rendered model. That rules lighting out as a culprit.

I’ll need a day or two to review the process that creates these models and fix the obvious rotation/scale issue. Next step will be to see if I can run this process, generate a model from it and then open it up in Blender, and have Blender display the model in the right rotation/scale/etc. Figure if I can do that, the next step (getting it to load in jME3) will be much more straight forward.

I’ll post back with results in a few days - thanks again for the help with this!

OK I’m still troubleshooting my model-generation process and haven’t pegged down exactly where the unwanted transformations (scale & rotation) are being applied to the model, but I did take your advice (both @pspeed + @Domenic) and I:

  1. Imported the model into Blender; then
  2. Applied manual scale & rotation transformations to get the model displaying “correctly”; then
  3. Saved it the changes as a .blend file; then
  4. Changed my code above to load the Blender file:
spatial = assetManager.loadModel('house-ext-front/house-ext-front.blend')

When I run my game now:

Progress!!! So the scale is more or less correct, and it looks like the rotation is correct, the only problem now is that the texture doesn’t seem to be getting applied. I assume I either didn’t export/save the Blender file correctly, or that I’m not loading the textures in jME3 correctly. Any ideas as to why this is happening?