Blender Importer notes

Hi all,

starting to import some blender models into jmp I realized, that I’ll have a closer look what goes wrong when importing blender files. Most files just did not load.

Here are some notes on the behavior of the blender loader. If a patch is attached, this is only for showing the lines, not a REAL PATCH. I just wanted to analyse where the causes come from.

A zip with all the files and a testcalss can be found here:

The models are all from opengameart


The loader has some problems with IndexBuffers, as this is way to internal for me I didn’t touch it.

@Kaelthas Perhaps some of the devs can have a look at this.

IntBuffer cloneIndexes = (IntBuffer) clone.getBuffer(Type.Index).getData();

com.jme3.asset.AssetLoadException: An exception has occured while loading asset: cementery_gate.blend

at com.jme3.asset.DesktopAssetManager.loadAsset(

at com.jme3.asset.DesktopAssetManager.loadModel(

at com.jme3.asset.DesktopAssetManager.loadModel(

at TestBlenderFile.simpleInitApp(


at com.jme3.system.NullContext.initInThread(


at Source)

Caused by: java.lang.ClassCastException: java.nio.DirectShortBufferU cannot be cast to java.nio.IntBuffer

at com.jme3.scene.plugins.blender.modifiers.MirrorModifier.apply(

at com.jme3.scene.plugins.blender.objects.ObjectHelper.toObject(

at com.jme3.scene.plugins.blender.AbstractBlenderLoader.toObject(

at com.jme3.scene.plugins.blender.BlenderLoader.toObject(

at com.jme3.scene.plugins.blender.BlenderModelLoader.toObject(

at com.jme3.scene.plugins.blender.BlenderModelLoader.load(

at com.jme3.scene.plugins.blender.BlenderModelLoader.load(

at com.jme3.asset.DesktopAssetManager.loadAsset(

… 7 more


Next one:

It seems to me the properties in blender and the user data use different IDs for the data types (or blender loader tries to store userdata which is not atomized/converted to userdata)

Unsupported type: com.jme3.scene.plugins.blender.objects.Properties

In UserData.getObjectType() line:98

called through com.jme3.scene.plugins.blender.meshesMeshHelper.toMesh() line:340


There are some issues with catching Exceptions. I had the following exceptions on this one (ClassCastException, AssetNotFoundException, IllegalstateException), though it only catches IOExceptions.

Index: src/core/com/jme3/asset/


— src/core/com/jme3/asset/ (revision 9466)

+++ src/core/com/jme3/asset/ (working copy)

@@ -280,7 +280,7 @@

try {


obj = loader.load(info);

  •        } catch (IOException ex) {<br />
  •        } catch (Exception ex) {<br />

throw new AssetLoadException("An exception has occured while loading asset: " + key, ex);

} finally {



getTextureFromImage might return null, resulting in an NPE. Saw on other use cases it is queried for null before usage, so I did the same here. And further down also added more exception catching, for the same reasons as above.

Index: src/blender/com/jme3/scene/plugins/blender/textures/


— src/blender/com/jme3/scene/plugins/blender/textures/ (revision 9466)

+++ src/blender/com/jme3/scene/plugins/blender/textures/ (working copy)

@@ -137,7 +137,9 @@

if (pImage.isNotNull()) {

Structure image = pImage.fetchData(blenderContext.getInputStream()).get(0);

result = this.getTextureFromImage(image, blenderContext);

  •   			this.applyColorbandAndColorFactors(tex, result.getImage(), blenderContext);<br />
  •   			if(result != null) {<br />
  •   				this.applyColorbandAndColorFactors(tex, result.getImage(), blenderContext);<br />
  •   			}<br />




@@ -497,6 +499,8 @@

LOGGER.log(Level.FINE, “Adding texture {0} to the loaded features with OMA = {1}”, new Object[] { texturePath, image.getOldMemoryAddress() });


blenderContext.addLoadedFeatures(image.getOldMemoryAddress(), image.getName(), image, result);

  •   	} else {<br />
  •   		LOGGER.log(Level.SEVERE, "Failed to load texture from file: {0}", texturePath);<br />



return result;

@@ -606,7 +610,7 @@

result = assetManager.loadTexture(key);

break;// if no exception is thrown then accept the located asset

// and break the loop

  •   	} catch (AssetNotFoundException e) {<br />
  •   	} catch (Exception e) {<br />





Here’s my comments regarding those issues:

  1. Instead of assuming the index buffer is in “UnsignedInt” format, the code should use “clone.getIndexBuffer()”

  2. Yes you’re correct about the lack of conversion to UserData.

  3. I don’t know if it is such a good idea to catch all those exceptions. IOException generally indicates that the supplied data or asset is corrupted or invalid. The other exceptions indicate an inherent problem in the code of the loader itself.

  4. Perhaps the question you should be asking yourself is why getTextureFromImage is returning null. We don’t want to end up in a situation where a texture which should be there is missing because of some variable being null but the texture data being located elsewhere. Remember that the blend format often stores data in multiple places, depending on the format of the data and options selected in the interface. This means you may have to dig in other places to find it, so its not as straightforward as you make it seem.

    In any case, I think @Kaelthas is the only person who can look and fix these issues. We can apply the changes but we won’t know if it is the correct fix or not.

Hi @ghoust

I have downloaded your models and managed to fix several bugs:

  1. setting properties for mesh
  2. fixes to mirror modifier regarding NPE and ClassCasts, and one fix with choosing wrong mirror axis
  3. NPE fix when image texture was not found

    So great thanks for uploading them :slight_smile:

    There are two issued though.

    First is that you might get AssetNotFound exception or see no texture on the model. The reason is using the absolute path in your texture reference. When it is stored in blender,I cannot find the image using it.

    The workaround is storing your texture inside the blend file.

    The other issue is OutOfMemory error while loading fisherman’s hut. You use about 14 materials and each containing a generated texture of some kind. And these materials are applied to many separate objects.

    Using generated textures is supported but you need to tak extra care. because every object will have a separate texture created. Generated textures are baked into 2D images to cover each face of the object and that takes lots of memory.

    I will use your model to try reduce the amount of memory and maybe I’ll succeed at least a little. But do not expect miracles :wink:

@Kaelthas Thank you very much for the fixes.

As I try to get the models into jme at all I left the textures unatended at some point,because I had too much trouble getting any meshes at all int jme through blender.

The models are from by the way.

I also have seen problems with a particle effect which emitts generated textures it seemed. The exporter was creating the cloud texture each time a pixel of the final map was computed. I left this also. GenerratedTexture.trinagulate line 113 looped endlessly. Guess this could be cached or optimized otherwise.

In my code I also added a try catch in BlenderModelLoader.load inside the for loop so it would load what it was able to and left the rest.

Anyways good work, with that fixes I’m closing on my goal of using blender directly and no longer need the way about the ogre export. great!