[SOLVED] Loading model json blob as asset

I am downloading a json file through my server, so I end up with a JSON object, but I can’t figure out how to load it as an asset…

I have tried several solutions, where this one gave me the most promising result (pcAsync is the same as normal but with a Promise around it):

// file.data is from http request, as a JSON object
const blob = new Blob([JSON.stringify(file.data)]);
const url = URL.createObjectURL(blob);
const asset = await viewer.pcAsync.loadFromUrlAndFilename(
  url,
  element.file.filename,
  element.type
);
asset.id = parseInt(element.id, 10);

This seems to load the asset fine: console.log("new asset", viewer.app.assets.find("34406569_1_cube.json"));

But it still doesnt want to display it on a model component

const ent = new pc.Entity("Testy", viewer.app);
ent.addComponent("model", {
  type: "asset",
  asset: viewer.app.assets.find("34406569_1_cube.json"),
});
viewer.app.root.addChild(ent);
console.log(ent.model);

So how do I actually correctly load a json model as an asset? (I do need it as an asset specifically as I’m loading scene files as well :grimacing:)

I will also add to this that I used to test with this (local files), but it wouldn’t accept a blob url and would complain with Content at http://localhost:8080/ may not load data from blob:http://localhost:8080/ so I started manually loading assets.

const asset = new pc.Asset(data.name, data.type, data.file, data.data);
asset.id = parseInt(data.id, 10);
asset.preload = data.preload ? data.preload : false;
// if this is a script asset and has already been embedded in the page then
// mark it as loaded
asset.loaded =
  data.type === "script" && data.data && data.data.loadingType > 0;
// tags
asset.tags.add(data.tags);
// i18n
if (data.i18n) {
  for (let locale in data.i18n) {
    asset.addLocalizedAssetId(locale, data.i18n[locale]);
  }
}

viewer.app.assets.add(asset);

Hi @Ivolutio,

This post may have a solution for your use case:

I’ve found that too, but when you run the project @yaustar linked there, it now no longer works :confused: :

Right, it seems this is one of the pc classes that went private when the engine transitioned to ES6. You could always create a similar parser based on the source code, but that doesn’t sound elegant at all.

And since you have a valid use case I’d say try posting an issue about it on the engine repo. In case there is another work around or something about it can be added in the engine.

for later reference, I’ve posted an issue on github https://github.com/playcanvas/engine/issues/2371

1 Like

I’ve updated that old project to do it correctly: https://playcanvas.com/editor/scene/709011

1 Like

Thanks @yaustar, I’ll give it a go in a bit!

I haven’t tried it with a blob asset yet so good luck!

The following code, with a blob, works fine. Thanks @yaustar

pc.http.get(Sandbox.URL, function(err, response){
    if(err) return console.error(err);

    var blob = new Blob([JSON.stringify(response)]);
    var url = URL.createObjectURL(blob);

    var filename = 'cube.json';
    var file = {
        url: url,
        filename: filename
    };

    var asset = new pc.Asset(filename, 'model', file);    
    asset.once('load', function (modelAsset) {
        var entity = new pc.Entity();
        entity.addComponent("model");
        entity.model.asset = modelAsset;
        app.root.addChild(entity);
    });

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

});
2 Likes