GLB Loading from external URL. Best practices and recommendations

The PlayCanvas demo on loading an OBJ is straightforward (PlayCanvas Examples), demonstrating well how to add an asset from an external URL. The following code snippet is used to load an OBJ:

app.assets.loadFromUrl(scripturl, "script", function () {
  // The OBJ Parser is not enabled by default in the engine. Here's how to add it.
  app.loader.getHandler("model").addParser(new ObjModelParser(app.graphicsDevice), function (url) {
      return pc.path.getExtension(url) === ".obj";
  });

  app.assets.loadFromUrl(objurl, "model", function (err, asset) {
    app.start();

    let entity = new pc.Entity();
    entity.addComponent("model");
    entity.model.model = asset.resource;
    app.root.addChild(entity);

    // Randomly generate and add materials to all mesh instances.
    const mis = entity.model.meshInstances;
    for (let i = 0; i < mis.length; i++) {
      let material = new pc.StandardMaterial();
      material.diffuse = new pc.Color(
          pc.math.random(0, 1),
          pc.math.random(0, 1),
          pc.math.random(0, 1)
      );
      material.update();
      mis[i].material = material;
    }
  });
});

However, guidelines on importing a GLB and its textures/materials to an existing scene as assets are less evident. The given demo seems to focus on loading a GLB as a scene itself (PlayCanvas Examples). The sample code to load a GLB as a scene is as follows:

const assets = {
    scene: new pc.Asset("scene", "container", {
        url: "/static/assets/models/geometry-camera-light.glb",
    }),
};

const assetListLoader = new pc.AssetListLoader(
    Object.values(assets),
    app.assets
);

Could we have a demo project or your guidelines on the optimal way for async importing a GLB and its associated textures/materials into an existing scene as assets?

Thank you very much,

Hi @Change2,

There is this editor based example in addition: Loading glTF GLBs | Learn PlayCanvas

Thank you very much! Also, we were wondering about how to get % loading info from this process.

var loadGlbContainerFromUrl = function (url, options, assetName, callback) {
    var filename = assetName + '.glb';
    var file = {
        url: url,
        filename: filename
    };

    var asset = new pc.Asset(filename, 'container', file, null, options);
    asset.once('load', function (containerAsset) {
        if (callback) {
            // As we play animations by name, if we have only one animation, keep it the same name as
            // the original container otherwise, postfix it with a number
            var animations = containerAsset.resource.animations;
            if (animations.length === 1) {
                animations[0].name = assetName;
            } else if (animations.length > 1) {
                for (var i = 0; i < animations.length; ++i) {
                    animations[i].name = assetName + ' ' + i.toString();
                }
            }
            callback(null, containerAsset);
        }
    });

    app.assets.add(asset);
    app.assets.load(asset);

    return asset;
};

Hi @Change2,

Sadly that’s not possible right now when using standard PC API, there is a feature request to add support in the future: Give more control and information to the developer when loading resources · Issue #2021 · playcanvas/engine · GitHub

1 Like