[SOLVED] Adding assets from loadFromUrl

Hello there,

I get the error >>Uncaught Error: GraphNode is already parented<< when loading assets from my web server in the following function,

  • Can anyone advise me on where i’m going wrong with this? I am attempting to load multiple instances of meshes defined in a JSON-file as shown under the source.
  • The path is OK in the browser (client) and the model is loaded from the webserver successfully. The problem seems to lie in the line
    ‘modelEntity.model.model = model;’
    when the model is being inserted .

a) FUNCTION (BROWSER, CLIENT)

function createScene (jsonSceneObject) {
...
// load models
var sceneObjects = jsonSceneObject['scene'];
var sceneObjectsSize = Object.keys(sceneObjects).length;
for (var i = 0; i < sceneObjectsSize; i++) {
    var sceneModel = sceneObjects[i];

    var loadFilename = '/meshes/' + sceneModel.clean_name + '/' + sceneModel.clean_name + '.json';
    console.log('loading: ' + sceneModel.clean_name);

    var callbackFn = function (err, asset) {
        if(err) {
            return;
        }

        console.log('handling: ' + this.clean_name);
        console.log('with asset: ' + asset.file.url);

        var model = asset.resource;
        var modelEntity = new pc.Entity();
        modelEntity.addComponent('model');
        modelEntity.model.model = model;
        modelEntity.setPosition(this.global_position.x, this.global_position.y, this.global_position.z);
        modelEntity.setRotation(this.global_rotation.p, this.global_rotation.y, this.global_rotation.r);
        modelEntity.setLocalScale(this.local_scale.x, this.local_scale.y, this.local_scale.z);

        app.root.addChild(modelEntity);
    }.bind(sceneModel);
    app.assets.loadFromUrl(loadFilename, 'model', callbackFn);
}
...

}

b) JSON file (extract)

var testScene = {
...
  "scene": {
    "0": {
        "state":"show",
        "collide":"no",
        "name":"DefaultFloorTile10x10m (8)",
        "clean_name":"DefaultFloorTile10x10m",
        "tag":"Model",
        "parent_index":22,
        "local_position":{"x":10,"y":0,"z":-10},
        "local_rotation":{"p":0,"y":0,"r":0},
        "local_scale":{"x":1,"y":1,"z":1},
        "global_position":{"x":10,"y":0,"z":-10},
        "global_rotation":{"p":0,"y":0,"r":0},
        "global_scale":{"x":1,"y":1,"z":1},
        "is_camera":"no",
        "is_light":"no"
    },


}

c) BROWSER OUTPUT (e.g.)

...
handling: DefaultFloorTile10x10m
with asset: /meshes/DefaultFloorTile10x10m/DefaultFloorTile10x10m.json
...

d) NOTE:

The models were previously downloaded out of the PlayCanvas Editor as ZIPs, unpacked and stored on the webserver at the location ‘/meshes/*’.

Thanks in advance for any help here!

You can’t re-use the model resource from the asset in that way, because the model is attached into the scene graph and can only be inserted once.

Either you should assign the asset:

var modelEntity = new pc.Entity();
modelEntity.addComponent('model');
modelEntity.model.asset = asset;

Or you need to clone the model yourself (which is done internally when you assign an asset)

modelEntity.model.model = asset.resource.clone();
1 Like