# AssetManager

JME3 has an integrated an asset manager that helps you keep your project assets organized. By assets we mean media files, such as 3D models, materials, textures, scenes, shaders, sounds, and fonts. Think of the asset manager as the filesystem of your game, independent of the actual deployment platform. It also manages the appropriate managing of OpenGL objects like textures so that they are e.g. not uploaded to the graphics card multiple times when multiple models use them.

The `assetManager` object is an com.jme3.asset.AssetManager instance that every com.jme3.app.Application can access. It maintains a root that also includes your project's classpath by default, so you can load any asset that's on the classpath, that is, the top level of your project directory.

You can use the inherited `assetManager` object directly, or use the accessor `getAssetManager()`.

Here is an example how you load assets using the AssetManager. This lines loads a default Material from the Common directory:

    Material mat = (Material) assetManager.loadAsset(
        new AssetKey("Common/Materials/RedColor.j3m"));

The Material is “somewhere” in the jME3 JAR, but the default Asset Manager is configured to handle a `Common/…` path correctly, so you don't have to specify the whole path.

Additionally, You can configure the Asset Manager and add any path to its root. This means, you can load assets from any project directory you specify.

In project created with jMonkeyPlatform, jME3 searches for models in the `assets` directory of your project by default. This is our recommended directory structure for storing assets:

    MyGame/assets/Interface/
    MyGame/assets/MatDefs/
    MyGame/assets/Materials/
    MyGame/assets/Models/
    MyGame/assets/Scenes/
    MyGame/assets/Shaders/
    MyGame/assets/Sounds/
    MyGame/assets/Textures/
    MyGame/build.xml
    MyGame/src/...

These are just the most common examples, you can name the directories inside the assets directory how you like.

## Loading Assets

    // Creating a material instance with the definition "Unshaded.j3md".
    Material mat_brick = new Material(
        assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

    // Applying a texture to the material
    mat_brick.setTexture("ColorMap",
        assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"));

    // Loading a font
    guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");

    // Loading a model
    Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");

    // Loading a scene from an Ogre3D dotScene file stored inside a zip
    assetManager.registerLocator("town.zip", ZipLocator.class.getName());
    Spatial scene = assetManager.loadModel("main.scene");
    rootNode.attachChild(scene);

Here is a HttpZipLocator that can stream models from a zip file online:

        assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/wildhouse.zip",
                                     HttpZipLocator.class.getName());
        Spatial scene = assetManager.loadModel("main.scene");
        rootNode.attachChild(scene);

JME3 offers ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, and UrlLocator (see `com.jme3.asset.plugins`).

Task? | Solution!
--- | ---

Load a model with materials

Use the asset managers `loadModel()` method and attach the Spatial to the rootNode.

    Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml");
    rootNode.attachChild(elephant);

    Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.j3o");
    rootNode.attachChild(elephant);

Load a model without materials

If you have a model without materials, you have to add a default material to make it visible.

    Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
    Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");
    teapot.setMaterial(mat);
    rootNode.attachChild(teapot);

Load a scene

You load scenes just like you load models:

    Spatial scene = assetManager.loadModel("Scenes/house/main.scene");
    rootNode.attachChild(scene);

## NullPointerException: Cannot locate resource?

An error mesage similar to the following can occur in the console when you run executables, even if the game runs fine when started from the jMoneykPlatform.

    com.jme3.asset.DesktopAssetManager loadAsset
    WARNING: Cannot locate resource: Scenes/town/main.scene
    com.jme3.app.Application handleError
    SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
    java.lang.NullPointerException

Reason: If you use the default build script created by the jMonkeyPlatform then the original OgreXML files are not included in the executable.

For a stand-alone build, you work with .j3o files only. The default build script makes sure to include .j3o files in the executable.

You must use the jMonkeyPlatform's context menu action to convert OgreXML models to .j3o format to get rid of this error.

1. Open the JME3 Project in the jMonkeyplatform.
2. Browse the Assets directory in the Projects window.
3. Right-click a .mesh.xml file, and choose “convert to JME3 binary”.
4. The converted file appears in the same directory as the .mesh.xml file. It has the same name and a .j3o suffix.

## Asset Handling: Codeless Projects

If you are using another IDE than jMonkeyPlatform, you can create a codeless project in the jMonkeyPlatform to maintain assets. This method will not meddle with your sources or custom build scripts, but you can still browse your assets, and preview, arrange, and convert models. You can, for example, give the designers in your team access to such a codeless project.

view online version