Custom Asset Types? [Solved]

Hi. I’ve written my own terrain generation system, by creating a custom mesh. But because it takes ages to generate, I’d like to implement saving & loading terrain data, using JSON perhaps.

How would you do this? Is there a built-in JSON Encoder/Decoder in JME?

It would be nice to use the assetManager, for cleanliness, is that possible?

assetManager.saveTerrain(terrain.mesh, "terrain01.json");

Then it appears in assets/terrains/terrain01.json.

Perhaps it would be a better idea to save the mesh object itself, if that sort of functionality is built-in to JME?

You can save the mesh. Or you can save custom formats. AssetManager is what you want to look at for the latter. (though you will be happier with a custom extension rather then the generic .json)

Meshes can already be saved.

Ok, how do I exactly save the mesh? I can’t find it in the documentation :stuck_out_tongue:

http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:save_and_load

Ah, sweet. Thanks for the quick reply! :smiley:

Wait, using this code:

    String userHome = System.getProperty("user.home");
    BinaryExporter exporter = BinaryExporter.getInstance();

    File file = new File(userHome + "/Models/Terrain/" + name + ".j3o");
    try {
        exporter.save(mesh, file);
    } catch (IOException ex) {
        Logger.getLogger(Terrain.class.getName()).log(Level.SEVERE, "Failed to save terrain " + name, ex);
    }

That doesn’t save stuff to the Assets directory in the project root.

How do I get the path to the projects assets directory?

I figured out how to get the path to the assets directory, so I can save the model now, using this:

public void save(String name) {
    String dir = System.getProperty("user.dir");
    BinaryExporter exporter = BinaryExporter.getInstance();
    
    File file = new File(dir + "/assets/Models/Terrain/" + name + ".j3o");
    try {
        exporter.save(mesh, file);
    } catch (IOException ex) {
        Logger.getLogger(Terrain.class.getName()).log(Level.SEVERE, "Failed to save terrain " + name, ex);
    }
}

But when I try to load the mesh, using the following code:

public void load(AssetManager assetManager, String name) {
    Geometry geom = (Geometry) assetManager.loadModel("Models/Terrain/" + name + ".j3o");
    mesh = geom.getMesh();
}

I get this exception:

java.lang.ClassCastException: com.jme3.scene.Mesh cannot be cast to com.jme3.asset.CloneableSmartAsset
at com.jme3.asset.cache.WeakRefCloneAssetCache.addToCache(WeakRefCloneAssetCache.java:127)
at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:309)
at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:374)
at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:378)
at net.gentlefox.arties.terrain.Terrain.load(Terrain.java:360)

What’s going on? And, why exactly is it returning a spatial and not a mesh, which is what I want.

This will only work in an app run in the SDK, in a deployed app the assets folder doesn’t exist, its packed in a jar file. Even if you were to distribute your app with the folder still intact, modern operating systems don’t allow apps to write in the applications folder. You’ll have to create a folder in the user directory, add it to the asset manager with a locator and store models created in-app there. (This doesn’t address your current issue though)

I won’t save assets when I deploy. I’m just using this as a dev tool, essentially.

Solved it by saving a Geometry object with the mesh instead of just saving the Mesh object.