# 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.

## Asset Folder

By default, jME3 searches for models in a directory named `assets`. In Java projects created with the jMonkeyEngine SDK, an assets folder is created by default. Using any other IDE or the command line, you have to create this assets directory as an extra step (see the Codeless Project tip below).

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        # build script
    MyGame/src/...          # source code

These are just the most common examples. You can name the directories inside the `assets` directory what ever you like.

## Examples: 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);

Alternatively to ZipLocator, there is also 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 also offers a ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, and UrlLocator (see `com.jme3.asset.plugins`).

Note: The custom build script does not automatically include ZIP files in the executable build.

## Comon AssetManager Tasks

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

Load a model with materials

Use the asset manager's `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?

Even if the game runs fine when started from the jMoneykPlatform, an error message similar to the following can occur in the console when you run the stand-alone executables (.JAR, .JNLP, etc).

    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 jMonkeyEngine SDK then the original OgreXML files are not included in the executable. A stand-alone executable works with .j3o files only. The default build script makes sure to include .j3o files in the executable.

Solution

Before building the executable, you must use the jMonkeyEngine SDK's context menu action to convert OgreXML models to .j3o format.

1. Open the jME3 Project in the jMonkeyEngine SDK.
2. Browse the `assets` directory in the Projects window.
3. Right-click a .mesh.xml or .obj or .scene 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.
5. Make sure to change the loading code to load the file with a .j3o suffix now.

If you load the scene from a non.j3o ZIP file, expand the default_build_script to copy the ZIP files.

## Asset Handling: Codeless Projects

If you are using another IDE than jMonkeyEngine SDK for coding, you should create a so-called codeless project in the jMonkeyEngine SDK to maintain assets. This method will not meddle with your sources or custom build scripts. It simply makes it easier for you to browse game assets, and preview, arrange, and especially convert models to binary.

- You use your favorite IDE to code and use the jMonkeyEngine SDK only for jME3 assets maintenance.
- You can also ask the graphic designers in your team to install the jMonkeyEngine SDK and give them access to such a codeless project.

view online version