[SOLVED] How to load model dynamically with the engine?

I am not using the Editor, only the engine. I get trouble with loading model dynamically.
I’ve try to do it with the following code:

var entity = new pc.Entity();
var url = 'http://example.com/model.json';
app.assets.loadFromUrl(url, 'model', function (err, asset) {
  entity.addComponent('model', { type: 'asset', asset: asset.resource });
  app.root.addChild(entity);
});

The model.json is like:

{
    "model": {
        "vertices": [ ... ],
        "skins": [ ... ],
        "version": 2,
        "parents": [ ... ],
        "meshes": [ ... ],
        "nodes": [ ... ],
        "meshInstances": [ ... ]
    }
}

And the model.mapping.json:

{ "mapping": ["Cube"] }

However, nothing happen and the console do not throw any error.

Here is a codepen.

What’s wrong with it ? Am I doing it in a wrong way ?

Can you provide complete example e.g. in jsfiddle.net?

One of easiest way I found, is to construct actual pc.Asset with underlying data in it, like file and data objects, and then let asset registry to worry about the rest.

I’ve add a codepen at the end of the post.

After reading the source code of application.js#L643-L651, I found an easy way to load model dynamically.

request.get('http://myserver/models/:id/assets', function (err, assets) {
    for (let id in assets) {
        let data = assets[id];
        let asset = new pc.Asset(data.name, data.type, data.file, data.data);
        asset.id = parseInt(data.id);
        asset.preload = data.preload ? data.preload : false;
        asset.tags.add(data.tags);
        app.assets.add(asset);
    }

    var model = new pc.Entity();
    model.addComponent('model');
    model.model.asset = app.assets.get(1); // the model's id set by myself
    app.root.addChild(model);
});

But I am not sure if this is a good way to implement dynamically create model… Please correct me if I am wrong.

1 Like

This approach is much better. Because it has pc.Asset associated with it, and they are much easier to work with. They will automatically load related content - models, materials, textures, and allows you load/unload them if you want using app.assets.load(asset) method. And they do have events when they get loaded: asset.once('load', function() { });.

Using pc.Asset helps to keep content in one registry and easier manage it, as well as auto-loading.

Editor does work with pc.Asset, and generates JSON data regarding them, so engine then treats everything as pc.Asset, this just makes things easier.

1 Like

OK, thanks for your reply!

Just to complete this. Instead of using the asset id, you could load an model by using the Name of the JSON file of your model:

   // Create a new Entity
   _instance = new pc.Entity();

   // Add a new Model Component and add it to the Entity.
   _instance.addComponent("model", {
        type: 'asset',
   });

   // load entity by id
   _instance.model.asset = this.app.assets.get(assetID);
   // load entity by model name
   _instance.model.asset = this.app.assets.find("assetName.json", "model");
2 Likes