A little script to ease exporting from 3dsmax

First: hi, I’m new to JME and thanks for this great project.



My minions artists use primarily 3DS Max and refuse to use such “obnoxious” thing as Blender, even after hours of [verbal] whip-slapping.

So I spent a few last hours on figuring out how to get skeleton animations to the SDK.

Since the process is not exactly straightforward I thought I’d contribute in scripts and docs and maybe get some help in the process.



So here’s a script that should speed the pipeline if completed:

[snippet id=“35”]



So to complete it I need something to convert the ogre scene to JME format, like the SDK does, but from the command line. Is there something similar or should I write my own. I don’t mind if it pulls entire osgi and netbeans planet with it as long as i can run it from the command line.

If it gets too complex I can just slap the .scene, but it seems a bit cleaner to me if I can put just the .j3o-s an .j3m-s in the project without polluting my tree with the intermediary files.



A side note:

I’ve seen the OgreXMLConvert.java in the sources that seems to do the conversion for me but I don’t find it in the SDK, is it only in nightlies?

Also converting the .scene in the project doesn’t seem to work. I’ll file a proper bug report in its thread when I feel like it have some time.

Why do you need command line conversion? Are you aware that the path structure for j3o files has to be kept? E.g. texture files have to be in the exact folder they were accessible when the j3o was created, much like compiled class files. Thats why the SDK manages them on the project-level. You can easily add other file formats to the SDK for conversion via right-click (you can also select multiple files) incl. using command line tools, the ogre binary conversion is an example for this. A command line tool is also easily realized but again, it would have to convert the models in a complete path structure to avoid all image references to be flattened (else you need to put them all in the root of your project, disallowing textures with the same name).

Edit: Wiki entry about saving j3o files

How about OgreMax? It can export to orgexml with animations, (at least it is supposed to do so, I’m still trial and erroring the right settings a bit)

The j3o conversion then is done with a selfmade batchcompiling tool,e all modelas are loaded, the additinal maps and materials are created, based on a naming schema (so if I know the diffusetexture name,I know how the others are named if present, and create a j3m automagically) + a few folder based additional config files that can override behaviour, like setting a folderinternal scale factor.

@normen, thanks the link was helpful.

I wanted to run the command from the maxscript, and so I did. It may also be useful in other ways.

I know I can use conversion in the SDK, but I don’t wan’t to do it this way because:

  1. I use eclipse. I don’t want to use netbeans just to convert the assets.
  2. I don’t want the intermediate .ogre files in my project’s tree, just the final binaries. It’s a pain to clean up, original assets are .max anyway and go elsewhere.



    I’m still figuring out the best ways to do things, so I’m open to critics and suggestions.

    As said I had to launch the OgreXMLConverter tool myselft, otherwise the SDK just doesn’t import anything.

    Regarding importing the .scene in SDK: it only worked for me when I converted the meshes to XML and put all files in the same directory manually (Easy Ogre Exporter puts meshes and materials in sub-directories, don’t know why). Otherwise the SDK did the conversion, but there either where no meshes or there was a wrong mesh, that didn’t exist in the original scene, just somewhere else in the project.



    In the end the script just automates the steps that I had to do manually.

    Anyway here’s the updated script and the conversion part:



    /*
  • Copyright © 2012, Maciej Kacper Jagiello (maciej [at] jagiello.it)
  • All rights reserved.

    *
  • Redistribution and use in source and binary forms, with or without
  • modification, are permitted provided that the following conditions are met:

    *
    • Redistributions of source code must retain the above copyright notice, this
  • list of conditions and the following disclaimer.

    *
    • Redistributions in binary form must reproduce the above copyright notice,
  • this list of conditions and the following disclaimer in the documentation
  • and/or other materials provided with the distribution.

    *
  • THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
  • AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  • IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  • ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  • LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  • CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  • SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  • INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  • CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  • ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  • POSSIBILITY OF SUCH DAMAGE.

    *

    *
  • This is a JMonkeyEngine exporter, se http://hub.jmonkeyengine.org/.
  • It uses Ogre .scene as intermediary format.

    *
  • Prerequisites:
  • *Java runtime
  • *ogre exporter plugin: http://www.ogre3d.org/tikiwiki/Easy+Ogre+Exporter
  • *ogre binary to xml converter: http://www.ogre3d.org/tikiwiki/OgreXmlConverter

    *
  • Instructions:
    1. Copy jme3export.ms and jme3export-tools to <3dsmax_path>ScriptsStartup
    1. Go to Utilities panel click on MAXScript button and choose
  • "JMonkeyEngine export and tools" in the combo. A new rollout should appear.<br />
    

*

*

  • Tested with 3Ds Max 2012 only, may eat you kitten.



    /



    function exportj3o selectionOnly =

    (

    – path to convert from ogre tools, should find it if it’s in the same directory as the script

    scriptsDir = getDir #scripts

    temp = sysinfo.tempdir + “\jmeexport”



    ogreconverter = “”" +scriptsDir + “\Startup\jme3export-tools\OgreXMLConverter.exe” -log " + temp + “\OgreXMLConverter.log”

    j3oconverter = “java -jar “” + scriptsDir + “\Startup\jme3export-tools\ogrexml2j30.jar””



    – ask for output file, only proceed if chosen

    filename = getSaveFileName caption:“export triangle strip” types:"JMonkeyEngine 3 scene(
    .j3o)|
    .j3o|All|.|"



    if filename != undefined then

    (



    – define a temporary directory and file name for the ogre scene

    ogrefilename = temp + “\temp.scene”



    – make the temp directory if it doesn’t exist yet

    makeDir temp

    – clear the temp directory of any files from previous exports

    for f in getFiles (temp + “*.") do

    deleteFile f

    for d in getDirectories (temp + “*”) do

    for f in getFiles (d + "*.
    ”) do

    deleteFile f



    – run the exporter, deduce the exorter from extension, entire scene

    exportFile ogrefilename #noPrompt selectedOnly:selectionOnly



    – convert binary ogre to xml readable by JME

    for f in getFiles (temp + “\mesh*.mesh”) do

    HiddenDOSCommand (ogreconverter + " " + f + " " + f + “.xml”)

    for f in getFiles (temp + “\mesh*.skeleton”) do

    HiddenDOSCommand (ogreconverter + " " + f + " " + f + “.xml”)



    – convert to binary JME scene

    HiddenDOSCommand (j3oconverter + " " + ogrefilename + " " + filename)

    )

    )



    utility JMETools “JMonkeyEngine export and tools”

    (

    button exportjSceneAs3o “Export scene as .j3o”

    on exportjSceneAs3o pressed do

    exportj3o (false)



    button exportSelectionAsj3o “Export selection as .j3o”

    on exportSelectionAsj3o pressed do

    exportj3o (true)

    )



    [java]/*
  • Copyright © 2012, Maciej Kacper Jagiello (maciej [at] jagiello.it)
  • All rights reserved.

    *
  • Redistribution and use in source and binary forms, with or without
  • modification, are permitted provided that the following conditions are met:

    *
    • Redistributions of source code must retain the above copyright notice, this
  • list of conditions and the following disclaimer.

    *
    • Redistributions in binary form must reproduce the above copyright notice,
  • this list of conditions and the following disclaimer in the documentation
  • and/or other materials provided with the distribution.

    *
  • THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  • AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  • IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  • ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  • LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  • CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  • SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  • INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  • CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  • ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  • POSSIBILITY OF SUCH DAMAGE.

    */

    package it.jagiello.tools.jme3;



    import java.io.File;

    import java.net.URL;



    import com.jme3.asset.AssetManager;

    import com.jme3.asset.plugins.UrlLocator;

    import com.jme3.export.binary.BinaryExporter;

    import com.jme3.scene.Spatial;

    import com.jme3.system.JmeSystem;



    /**

    *
  • Command line utility that reads OgreXML scene and converts it to the
  • binary JMonkeyEngine format with all meshes bundled in it.

    *
  • This program needs the path to a .scene file and the path to the output .j3o file.

    *
  • @author Maciej Kacper Jagiello

    */

    public class Ogrexml2j3o {

    public static void main(String[] args) {

    try {

    if (args.length == 0 || args.length > 2) {

    System.out.println(“usage: ogrexml2j30 <in.scene> [<out.j3o>]”);

    System.out.println(" Input file is an ogre .scene file. All files that the scene depends on should eiter be in the same directory or one of ./mesh, ./material or ./bitmap directories.");

    System.out.println(" All the .mesh and .skeleton files should be in the ogrexml format. To convert from the binary to xml format use the converter from ogre tools.");

    System.out.println(" If the output file is not specified a file in the same directory and with the same name as the scene is created.");

    System.exit(1);

    }



    File sceneFile = new File(args[0]);

    if (!sceneFile.getName().toLowerCase().endsWith(".scene")) {

    System.err.println(“input file should be an Ogre .scene file”);

    System.exit(1);

    }



    File sceneDir = sceneFile.getParentFile();



    File outFile;

    if (args.length > 1) {

    outFile = new File(args[1]);

    if (!outFile.getName().endsWith(".j3o")) {

    System.err.println(“output file should be an JME .j3o file”);

    System.exit(1);

    }



    } else {

    String name = sceneFile.getName();

    name = name.substring(0, name.length() - “.scene”.length());

    outFile = new File(sceneDir, name + “.j3o”);

    }



    URL cfgUrl = Thread.currentThread().getContextClassLoader().getResource(“com/jme3/asset/Desktop.cfg”);

    AssetManager assetManager = JmeSystem.newAssetManager(cfgUrl);

    assetManager.registerLocator(sceneDir.toURI().toString(), UrlLocator.class.getName());

    assetManager.registerLocator(new File(sceneDir, “mesh”).toURI().toString(), UrlLocator.class.getName());

    assetManager.registerLocator(new File(sceneDir, “material”).toURI().toString(), UrlLocator.class.getName());

    assetManager.registerLocator(new File(sceneDir, “bitmap”).toURI().toString(), UrlLocator.class.getName());

    Spatial sceneNode = assetManager.loadModel(sceneFile.getName());



    BinaryExporter exporter = BinaryExporter.getInstance();

    exporter.save(sceneNode, outFile);

    } catch (Exception e) {

    e.printStackTrace();

    System.exit(1);

    }

    }

    }

    [/java]



    As a side effect it bundles everything inside the j3o, which may not be desired.

    Haven’t tested anything materials related yet and multiple animations don’t seem to work. I have to try OgreMax too.



    Edit: the script got messed up, how should I escape it? If you qoute the post you can read it correctly.

Heh, you should have read not just the link. This tool now does exactly what I said, it flattens the image names. Try converting two models with different textures that have the same name (e.g. texture.jpg) and display them both at once they way you’d do it now. The application cannot discern between the two textures as they have no path because you registered a locator right on their folder.