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.
jMonkeyProjects/MyGame/assets/ # You store assets in subfolders here! <------ jMonkeyProjects/MyGame/build/ # SDK generates built classes here (*) jMonkeyProjects/MyGame/build.xml # You customize Ant build script here jMonkeyProjects/MyGame/nbproject/ # SDK stores default build.xml and meta data (*) jMonkeyProjects/MyGame/dist/ # SDK generates executable distribution here (*) jMonkeyProjects/MyGame/src/ # You store Java sources here jMonkeyProjects/MyGame/test/ # You store test classes here (optional) (*) Managed by jMonkeyEngine SDK -- don't edit!
See also Best Practices.
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 app.getAssetManager().
Here is an example how you load assets using the AssetManager. This lines loads a default Material from the built-in Common/ directory:
Material mat = (Material) assetManager.loadAsset( new AssetKey("Common/Materials/RedColor.j3m"));
This Material is "somewhere" in the jME3 JAR; the default Asset Manager is configured to handle a Common/… path correctly, so you don't have to specify the whole path when referring to built-in assets (such as default Materials).
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. The next example shows how you load assets from your project's assets directory.
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:
jMonkeyProjects/MyGame/src/... # Packages, .java source code. jMonkeyProjects/MyGame/assets/... # The assets directory: jMonkeyProjects/MyGame/assets/Interface/ # .font, .jpg, .png, .xml jMonkeyProjects/MyGame/assets/MatDefs/ # .j3md jMonkeyProjects/MyGame/assets/Materials/ # .j3m jMonkeyProjects/MyGame/assets/Models/ # .j3o jMonkeyProjects/MyGame/assets/Scenes/ # .j3o jMonkeyProjects/MyGame/assets/Shaders/ # .j3f, .vert, .frag jMonkeyProjects/MyGame/assets/Sounds/ # .ogg, .wav jMonkeyProjects/MyGame/assets/Textures/ # .jpg, .png; also .mesh.xml+.material, .mtl+.obj, .blend (!)
These are just the most common examples. You can rename/delete/add directories and subdirectories inside the assets directory in any way you like. Note however that there is no automatic refactoring for asset paths in the SDK, so if you modify them late in the development process, you have to refactor all paths manually.
Examples: You can rename assets/Sounds to assets/Audio, you can delete assets/MatDefs if you don't use it, you can create assets/AIscripts, etc. You can rename/move the assets/Textures directory or its subdirectories, but then you have to re-export all models, and re-convert them all to .j3o, so plan ahead!
assets/Textures/ before you work with them in a mesh editor! Export and save 3D model files (.mesh.xml+.material, .mtl+.obj, .blend) into the assets/Textures/ (!) before you convert the model to binary format (.j3o)! This ensures that texture paths correctly point to the assets/Textures directory. assets/Models/ or assets/Scenes/ directories. This way, you can reuse textures, your binaries consistently link the correct textures, and the assets/Models and assets/Scenes directories don't become cluttered.
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); 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); Spatial scene = assetManager.loadModel("main.scene"); rootNode.attachChild(scene);
jME3 also offers a ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, and UrlLocator (see com.jme3.asset.plugins).
| 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); |
Problem:
My game runs fine when I run it right from the jMonkeyEngine SDK. But when I run the stand-alone executables (.jar, .jnlp .exe, .app), a DesktopAssetManager error message occurs in the console, and it quits?
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, original models and scenes, and ZIP files, are excluded from the distribution automatically. A stand-alone executable includes converted .j3o models and scenes only. The default build script makes sure to include existing .j3o files in the distribution, but you need to convert the models manually.
Solution
Before building the executable, you must use the jMonkeyEngine SDK's context menu action to convert 3D models to .j3o binary format.
assets directory in the Projects window. assets/Models/ or assets/Scenes/ directories.load() code to access the .j3o file.
Problem:
I use another IDE than jMonkeyEngine SDK for coding (Eclipse, IntelliJ, text editor). Where is my asset folder and .j3o converter?
Solution:
You can code in any IDE, but you must create a so-called codeless project in the jMonkeyEngine SDK to maintain assets. A code-less jMonkeyEngine project does not meddle with your sources or custom build scripts. You merely use it to convert models to .j3o binaries.
assets.