There are two ways of loading IMVU assets. You can either use the AssetLoader directly or use the LoadAssetComponent. The former is better if you want to create and place an asset dynamically from code. The latter is better if you want to place an asset in the scene in the editor.

AssetLoader

The API for the AssetLoader is very simple:

static Promise<GameObject, string> Load(Uri url);
static Promise<GameObject, string> Load(UserModel user);

If the Promise is accepted, the GameObject it returns will be disabled. You will need to call SetActive(true) in order for it to show up in the scene. This is to prevent the avatar from showing up before it's fully loaded and placed in the scene. So to load an avatar in this way, you would do something like this:

IMVU.AssetLoader.Load(uri).Then(
obj => {
SetupAvatar(obj);
obj.SetActive(true);
},
err => Debug.Log(err)
};

LoadAssetComponent

The LoadAssetComponent is a MonoBehaviour. If it's placed on a GameObject, you can then call its Load() method to load that asset onto that GameObject. Its signature is:

void Load(Uri url, Action callback);
void Load(UserModel user, Action callback);

This is useful if you want to place an asset in the editor. The intended use case is actually to derive from theLoadAssetComponent, adding whatever other code you need to load and manage the avatar there. An example of such:

class MyAvatar : IMVU.LoadAssetComponent {
void Start() {
Load(url, Setup);
}

void Setup() {
// Do stuff to setup the avatar once it's loaded
}
}

Specifying levels of detail

The AssetLoader supports loading asset meshes at several different levels of detail and can set up loaded GameObjects to automatically switch between them depending on the percentage of screen space that they occupy. This lets you display assets with dense meshes when close up, when detail is needed, but then switch to meshes with fewer triangles when at a distance, to improve drawing performance.

By default, the AssetLoader is configured to load each GameObject with several levels of detail and automatically switch between them. However, there are cases when you may want to specify custom level-of-detail settings:

  • If you specify fewer levels of detail than the default, the AssetLoader will make fewer network requests for mesh data, saving some loading time.
  • If you specify just one level of detail, the AssetLoader can omit the LodComponent that does the automated switching between levels, saving some per-frame CPU overhead.
  • Custom settings also let you tune the default transition points for display quality or performance.

Custom level-of-detail settings are specified by passing in a list of LodSetting objects to the lodSetting keyword parameter of the appropriate Load() method. Each LodSetting object specifies a LodLevel and a maximum screen coverage percentage. There are four LodLevels available:

  • LodLevel.Maximum - the highest level-of-detail mesh, as originally authored
  • LodLevel.Medium - an automatically generated mesh with lower level of detail (about 50%)
  • LodLevel.Low - an automatically generated mesh with very low level of detail (about 10%)
  • LodLevel.Hidden - displays no meshes at all

Note that the actual amount of detail reduction depends on the geometry of the mesh. For some models, reduction may not be possible, in which case the original mesh is used for all levels.

Screen coverage percentage is expressed as a float from 0-100. At runtime, the screen coverage is estimated from the bounding boxes of the meshes, and the level with the smallest coverage value greater than the object's current coverage (capped to 100%) is used. If you do not specify levels up to 100% coverage, the maximum level will be automatically included.

For example, if we were loading an asset that we know will never be displayed in detail, we could save some network bandwidth by omitting the maximum level when loading, like so:

IMVU.AssetLoader.Load(
uri,
lodSettings: new List<LodSetting>() {
new LodSetting(LodLevel.Hidden, 0.01f),
new LodSetting(LodLevel.Low, 1.0f),
new LodSetting(LodLevel.Medium, 100.0f),
}
).Then(
obj => {
SetupAvatar(obj);
obj.SetActive(true);
},
err => Debug.Log(err)
};

Or, if we were loading an asset to only be displayed in detail, we could save some network requests and runtime CPU by loading just the maximum level, like so:

IMVU.AssetLoader.Load(
uri,
lodSettings: new List<LodSetting>() {
new LodSetting(LodLevel.Maximum, 100.0f),
}
).Then(
obj => {
SetupAvatar(obj);
obj.SetActive(true);
},
err => Debug.Log(err)
};