Unable to import 3ds Max Models

Well, I’m trying to load some COLLADA files through the Model importer on the IDE but I got this:

Running blender as converter for file /home/user/cylinder.dae Failed to create model, blend file cannot be found

What I really would like is to load a model (with animations) created on “3ds Max” and there is no way to do that. I tried converting it with “Ogre Max Converter” but I get:

Unrecognized version number in dotScene file: 1.0 Unknown tag: animations. Ignoring.

So I get the model and textures but not the animations. I tried to follow the tutorial in here: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:external:3dsmax.

I tried to convert them to 3ds, fbx, to load all that formats on blender first and export from there to ogre but there is no way, I can’t load the animations outside the 3ds Max itself.

The file generated with “Ogre Max Converter” can be found here

Ok, I find a way but it stills with errors.

I can convert fine the models with their animations and materials with “easy ogre exporter” but with a few issues (I don’t really know if is jme3 fault or easy ogre’s or, even, ogre converter’s). This issues can be easily fix and it are:

1. On the .mesh.xml files: float2 must be changed to 2 on all it matches. 2. On the .material files: the " character must be deleted from the material definition.

The easy ogre exports the models with their meshes and skeleton compiled but these doesn’t work on jme3 so the procedure to export a model is (having in mind the issues too):

1. Export the model (to get the animations working use tags as said on easy ogre exporter official docs) 2. Convert the generated binaries (.mesh and .skeleton) to .xml (for example with OgreXMLConverter, present on ogre-1.9-tools on ubuntu repos) 3. Modify the .material removing the " character from the file 4. Modify the .mesh.xml replacing float2 by 2

For linux users:

#!/bin/bash

# Author: NemesisMate
# Date: 14/05/2014
# Version: X.X.X
# OgreXMLConverter must be accessible: $ apt-get install ogre-1.9-tools
# Remember the chmod +x <script>

MODELDIR=$1

if [ $# -ne 1 ]; then
        echo -e "\nUsage: ./<script> <model_directory>\n"
        exit 1
else
        if [ ! -d $MODELDIR ]; then
                echo -e "\nThe first parameter must be a directory\n"
                exit 1
        fi
fi

for file in <code>ls $MODELDIR | egrep &quot;.mesh$|.skeleton$&quot;</code>; do
        OgreXMLConverter $MODELDIR/$file $MODELDIR/$file.xml
        if [ $? -eq 0 ]
                then rm $MODELDIR/$file
        else
                echo -e "\nAn error has occurred, the script has stopped\n"
                exit -1
        fi
done

for file in <code>ls $MODELDIR | grep &quot;.material$&quot;</code>; do
        sed -i s/\"//g $MODELDIR/$file
done

for file in <code>ls $MODELDIR | grep &quot;.mesh.xml$&quot;</code>; do
        sed -i s/float2/2/g $MODELDIR/$file
done

I have been looking at JME3 source code. For the material quotes fix, maybe it could be in the file com.jme3.scene.plugins.ogre.MaterialLoader:

    private MaterialList load(AssetManager assetManager, AssetKey key, InputStream in) throws IOException{
        folderName = key.getFolder();
        this.assetManager = assetManager;
        
        MaterialList list = null;
        List&lt;Statement&gt; statements = BlockLanguageParser.parse(in);
        
        for (Statement statement : statements){
            if (statement.getLine().startsWith("import")){
                MaterialExtensionSet matExts = null;
                if (key instanceof OgreMaterialKey){
                     matExts = ((OgreMaterialKey)key).getMaterialExtensionSet();
                }

                if (matExts == null){
                    throw new IOException("Must specify MaterialExtensionSet when loading\n"+
                                          "Ogre3D materials with extended materials");
                }

                list = new MaterialExtensionLoader().load(assetManager, key, matExts, statements);
                break;
            }else if (statement.getLine().startsWith("material")){
                if (list == null){
                    list = new MaterialList();
                }
                String[] split = statement.getLine().split(" ", 2);
                matName = split[1].trim();
                readMaterial(statement);
                Material mat = compileMaterial();
                list.put(matName, mat);
            }
        }
        
        return list;
    }

And two possible solutions are (just after the trim).

  1. Assuming there is no double quotes in a material name:
        matName = matName.replace("\"", "");
  1. Allowing double quotes in a material name:
        if (matName.startsWith("\"") &amp;&amp; matName.endsWith("\"")) {
            matName = matName.substring(1, matName.length()).substring(0, matName.length() - 1);
        }

And for the mesh “float2” fix, it should be as easy as changing one line on com.jme3.scene.plugins.ogre.MeshLoader:

    private void startVertexBuffer(Attributes attribs) throws SAXException {
        if (parseBool(attribs.getValue("positions"), false)) {
            vb = new VertexBuffer(Type.Position);
            fb = BufferUtils.createFloatBuffer(vertCount * 3);
            vb.setupData(Usage.Static, 3, Format.Float, fb);
            mesh.setBuffer(vb);
        }
        if (parseBool(attribs.getValue("normals"), false)) {
            vb = new VertexBuffer(Type.Normal);
            fb = BufferUtils.createFloatBuffer(vertCount * 3);
            vb.setupData(Usage.Static, 3, Format.Float, fb);
            mesh.setBuffer(vb);
        }
        if (parseBool(attribs.getValue("colours_diffuse"), false)) {
            vb = new VertexBuffer(Type.Color);
            fb = BufferUtils.createFloatBuffer(vertCount * 4);
            vb.setupData(Usage.Static, 4, Format.Float, fb);
            mesh.setBuffer(vb);
        }
        if (parseBool(attribs.getValue("tangents"), false)) {
            int dimensions = parseInt(attribs.getValue("tangent_dimensions"), 3);
            vb = new VertexBuffer(Type.Tangent);
            fb = BufferUtils.createFloatBuffer(vertCount * dimensions);
            vb.setupData(Usage.Static, dimensions, Format.Float, fb);
            mesh.setBuffer(vb);
        }
        if (parseBool(attribs.getValue("binormals"), false)) {
            vb = new VertexBuffer(Type.Binormal);
            fb = BufferUtils.createFloatBuffer(vertCount * 3);
            vb.setupData(Usage.Static, 3, Format.Float, fb);
            mesh.setBuffer(vb);
        }

        int texCoords = parseInt(attribs.getValue("texture_coords"), 0);
        for (int i = 0; i &lt; texCoords; i++) {
            int dims = parseInt(attribs.getValue("texture_coord_dimensions_" + i), 2);
            if (dims &lt; 1 || dims &gt; 4) {
                throw new SAXException("Texture coord dimensions must be 1 &lt;= dims &lt;= 4");
            }

            if (i &lt;= 7) {
                vb = new VertexBuffer(TEXCOORD_TYPES[i]);
            } else {
                // more than 8 texture coordinates are not supported by ogre.
                throw new SAXException("More than 8 texture coordinates not supported");
            }
            fb = BufferUtils.createFloatBuffer(vertCount * dims);
            vb.setupData(Usage.Static, dims, Format.Float, fb);
            mesh.setBuffer(vb);
        }
    }

Changing the line:

            int dims = parseInt(attribs.getValue("texture_coord_dimensions_" + i), 2);

and letting it:

            int dims = parseInt(attribs.getValue("texture_coord_dimensions_" + i).replaceAll("float2", "2"), 2);

I’m not sure about “float2” corresponding to “2” but it worked for me and for others too. I was looking for more documentation about it on Ogre XML but there It’s really hard to find it (so I couldn’t).