Loading multiple 3D models with assetmanager

[See Link for what actually happened next and how I figured it all out] Loading multiple 3D models with assetmanager


What is the proper way for loading multiple models via the asset manager ?

I thought that in the following piece of code I should be able to include multiple filenames using strings at the " " space but that doesn’t seem to be the case. What would I have to do to load the skull model too ?

var assetsManager = new BABYLON.AssetsManager(game.scene);
    var meshTask = assetsManager.addMeshTask("dummy model loading", "", "./assets/models/", "dummy.babylon");
    //var meshTask2 = assetsManager.addMeshTask("skull model loading", "", "./assets/models/", "skull.babylon");

    meshTask.onSuccess = function (task) {
        task.loadedMeshes[0].parent = game.scene.getMeshByName("ground");
        task.loadedMeshes[0].setPositionWithLocalVector(new BABYLON.Vector3(0, 8, 0)) // x == z , y == z, z == y from player's view
        task.loadedMeshes[0].rotation = new BABYLON.Vector3(-Math.PI / 2, 0, 0) ;  
        task.loadedMeshes[0].scaling = new BABYLON.Vector3(1, 1, 1);

        //Simple invisble crate that acts as a hitbox to avoid expensive pixel-perfect collision
        var box = BABYLON.MeshBuilder.CreateBox("myBox", {height: 1.5, width: 0.50, depth: 1}, game.scene);
        box.isVisible = false;    
        box.setPositionWithLocalVector(new BABYLON.Vector3(0, 1, 0))
        box.showBoundingBox = true;
        box.parent =  task.loadedMeshes[0];
        box.checkCollisions = true;

    }
    meshTask.onError = function (task, message, exception) {
        console.log(message, exception);
    }

    assetsManager.load();

Did I get your question right and you want to load multiple models in one meshTask?
You can load multiple meshes if they are in one *.babylon.file…for example ‘mesh1’ and ‘mesh2’ are both in the ‘test.babylon’ file. But you are loading from two different *.babylon files that only contains one mesh…

var names = ["mesh1","mesh2"];
var meshTask = assetsManager.addMeshTask("task", names, "scenes/", "test.babylon");
1 Like

Do not know if this is the best way or even if it is a way that will work for you but it might be worth a look

1 Like

I think you were getting somewhere with your previous edits.

No the models are not in the same babylon file but thanks for clarifying that too, so the way its done in your edits seems appropriate.

And I get the way with the observables but I would like to do it with the callbacks for now to understand it better.Like how would I access the loaded meshes though like I do in my onSuccess function,while using your playing ground code ?

[EDIT] https://playground.babylonjs.com/#P2EPZI#1

This is the way I access each individual mesh right now with the way you suggested. Is there any better way or am I good with this ? I mean it’s working but I wonder if there is a “standard” way.

Really thank you for replying and going through so many edits to try to find the appropriate solution.

[EDIT2] Yeah my main problem right now is how I’m going to access the imported models.

the

scene.getMeshByName(“name”)

doesn’t work even though I’m using the correct name that is confirmed by doing

console.log(game.scene.meshes)

and looking at the name of the meshes.

[EDIT3] According to this forum post : AssetsManager name and getMeshByName not working - Questions & Answers - HTML5 Game Devs Forum

The proper way to access a loaded model via the assetmanager is by using the getMeshByName() function in the observables cause it’s asynchronous. Though I don’t understand why “asynchronous” make it non accessible outside of the observable it works good. I need to research it a bit.

Thanks to anyone who tried to give me pointers.

2 Likes

This seems interesting but I need to look it more to be sure I understand it.

Thanks my friend !

Hey nice that you were able to manage through this stuff!
For the access question…well I can’t tell you if there is a standard way, but maybe this code will give you some inspiration:

var models = {};
var meshTask = assetsManager.addMeshTask("task2", "", "./scenes/", "skull.babylon");

meshTask.onSuccess = function (task) {
    for (i = 0; i < task.loadedMeshes.length; i++) { 
        task.loadedMeshes[i].setEnabled(false); //this will hide the meshes when loaded
        models[task.loadedMeshes[i].name] = task.loadedMeshes[i];//add them to our models-object, we will call them later via their name
    }
}

var newInstance = models["skull"].createInstance("skull" + scene.meshes.length);

In this example I use a callback-function (just for showing an other way).
I store the loaded meshes in a ‘model’-object, and set them to disabled. This will give me some flexibility in some cases…you still can access them via the scene.object, but this will hold all attached meshes to the scene and is not always what I need…

Later (if needed), I create instances of them…this seems like a ‘eager loading’ approach to me, but I have to say that I am a total beginner and just share my solutions so far! Maybe an asynchronous technique is better for this, but I have no experience with this :sweat_smile:

Any other ideas are welcome for getting better :slightly_smiling_face:

I see , I guess actually that as in programming in general you can do anything however you want to do it and it will work. Optimality applies to only a handful of situations that they have more to do with how it’s AGREED for something to be done between peers who are collaborating and have a common goal.

It’s good to see that I was not the only one kinda confused about the whole asset management side of babylonjs. Hope some of the devs see this thread and maybe put more examples in the documentation if they have a better way to do it than us.

Thanks for staying for the long run of this thread my friend. Good luck !

I think the code shared by @wulf11 is perfect:)

What could we improve to make it simpler? Do you guys want to try to update the doc maybe?

We could use some help there;)

1 Like

If a dev himself says it’s perfect then what can I say.

Have in mind that I’m a JS beginner and I’m used to how things are done in languages like c,c++.

You see most of the I’m concerned of “clean” ways to do things so code is understandable with no hacks and all that. I’m all for getting things working asap but that probably doesn’t help in the long run if it ends in ugly code.

Mostly I would like what would be a recommended project structure, like I can have a huge file with many functions that will work cause it’s Javascript that we are speaking of but that isn’t easy to maintain and collaborate on. General structure and workflow that is recommended by you guys that you know the inside out of babylon. That probably is going to bring more newcomers as I really am amazed by the work and combined with webgpu, microsoft has a goldmine here.

As I said maybe I’m sounding stupid cause I don’t know in general good practices in software engineering,design patterns and all that so please don’t hate :smile: me as you obviously done such a good job and I really can’t even wait for what is coming.

There is not stupid questions:)

We do not have general recommendations because they are so many flavours in the js world.

I prefer the nice and clean way of having separated js files (mostly because I use typescript) but there is no recommended way. Everything is fine as long as it works for you

One thing we encourage is to avoid using any _members from Babylonjs API as they are considered private and this not covered by our backward compatibility support

Also if you did not yet: you should check typescript :wink: