Can't reload my models, also DesktopAssetManager.clearCache() doesn't help

Hi everyone!

I made a simple project to test asset “reimporting” because I had problems with it in my previous projects. So here it is what I’m stucked with:

I load simple models from blend files (cone.blend, cylinder.blend, cube.blend, icosphere.blend) and I add them to a Node called “objects”. This object Node is attached to the rootNode. All my object are appearing on the scene fine. But If I made a modification on one of the models and I reload the object (I made key event listener for that) it doesn’t show up. If I close the application and start it again, the modification appears.

I tried to use DesktopAssetManager.clearCache() but it doesn’t work. I tried to use ModelKeys and delete the keys one by one before reloading. Nothing works.

My question is how can I reload objects during runtime?

Here is my code:

package mygame.dev;

import com.jme3.asset.BlenderKey;
import com.jme3.asset.DesktopAssetManager;
import com.jme3.asset.ModelKey;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.scene.Node;
import mygame.DawnApplication;
import mygame.console.Console;
import mygame.states.DebugState;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Created by kruze on 2014.07.05..
 */
public class DevAssetManager extends DawnApplication implements ActionListener {

    private static final Logger logger = Logger.getLogger(DevAssetManager.class.getName());
    private static final Console console = Console.getInstance();
    private static final String RELOAD_ASSETS = "RELOAD_ASSETS";
    private static final String DETACH_OBJECTS = "DETACH_OBJECTS";
    private static final String OBJECTS = "objects";

    private int align = -2;
    private float distance = 10f;
    private float far = 20f;
    private Node objects;
    private DesktopAssetManager desktopAssetManager;

    // Name of assets to load
    String[] assets = new String[] {
            "Models/Models/cube.blend",
            "Models/Models/cone.blend",
            "Models/Models/cylinder.blend",
            "Models/Models/icosphere.blend"
    };

    // ModelKeys of assets based on assets property. See simpleInitApp()
    ModelKey[] modelKeys;

    public DevAssetManager() {
        super();
    }

    public static void main(String[] args) {
        DevAssetManager app = new DevAssetManager();
        app.start();
    }

    @Override
    public void simpleInitApp() {

        // Just... just shut up...
        Logger.getLogger("com.jme3").setLevel(Level.SEVERE);

        desktopAssetManager = (DesktopAssetManager) assetManager;

        // Handling input for reloading and removing assets
        inputManager.addMapping(RELOAD_ASSETS, new KeyTrigger(KeyInput.KEY_SPACE));
        inputManager.addMapping(DETACH_OBJECTS, new KeyTrigger(KeyInput.KEY_BACK));
        inputManager.addListener(this, RELOAD_ASSETS, DETACH_OBJECTS);

        rootNode.addLight(DebugState.getNewDirectionalLight(null, null));

        objects = new Node(OBJECTS);
        rootNode.attachChild(objects);

        // Generate ModelKeys from assets array
        modelKeys = new ModelKey[assets.length];
        for(int i=0; i<assets.length; i++) {
            modelKeys[i] = new ModelKey(assets[i]);

        }
    }

    @Override
    public void onAction(String name, boolean isPressed, float tpf) {

        // Reload every object on scene.
        if(name.equals(RELOAD_ASSETS) && !isPressed) {
//            reloadAllObjects();
            reloadAllObjectsByModelKeys();
        } else if(name.equals(DETACH_OBJECTS) && !isPressed) {
            // just detach everything
            objects.detachAllChildren();
        }

    }

    private void reloadAllObjects() {
        objects.detachAllChildren();

        desktopAssetManager.clearCache();

        loadAllObjects();
    }

    private void reloadAllObjectsByModelKeys() {
        objects.detachAllChildren();

        for(ModelKey mk : modelKeys) {
            desktopAssetManager.deleteFromCache(mk);
        }

        desktopAssetManager.clearCache();

        loadAllObjectsByModelKeys();
    }

    private void loadAllObjects() {

        Node tmp;
        align = -2;

        for(String asset : assets) {
            tmp = loadObject(asset);

            if(tmp!=null) {
                objects.attachChild(tmp);
                tmp.setLocalTranslation(align * distance, 0f, -far);
            } else {
                logger.severe(String.format("%s was null.", asset));
            }

            align++;
        }

    }

    private void loadAllObjectsByModelKeys() {

        Node tmp;
        align = -2;

        for(ModelKey modelKey : modelKeys) {
            tmp = loadObjectByModelKey(modelKey);

            if(tmp!=null) {
                objects.attachChild(tmp);
                tmp.setLocalTranslation(align * distance, 0f, -far);
            } else {
                logger.severe(String.format("%s was null.", modelKey.getName()));
            }

            align++;
        }

    }

    private Node loadObject(String assetName) {

        BlenderKey.LoadingResults results = (BlenderKey.LoadingResults) assetManager.loadModel(assetName);

        if(results.getObjects().size() > 0) {
            return results.getObjects().get(0);
        }

        return null;
    }

    private Node loadObjectByModelKey(ModelKey modelKey) {

        BlenderKey.LoadingResults results = (BlenderKey.LoadingResults) assetManager.loadModel(modelKey);

        if(results.getObjects().size() > 0) {
            return results.getObjects().get(0);
        }

        return null;
    }

}

Edit: reformat code

Are the models in the assets folder? If so then they are packaged into a jar when you build the app (which is done automatically when you run it from the SDK)… so it doesn’t matter if you change the originals because you will still be reloading it from the assets.jar.

You have to load them directly from the file system if you want to be able to reload them… register the appropriate asset locator, etc…

Yeeesss, it worked! Thanks for the help. All I did was register the locator for my files in the file system, remove the classpath locator, and copy the Common folder from jME3-core.jar that my project depends on:

        assetManager.unregisterLocator("/", ClasspathLocator.class);
        assetManager.registerLocator("/the/folder/where/my/project/is/assets/", FileLocator.class);

Well, you should remove the classpath locator. Just put your files NOT in the assets directory and point the file locator to them.