Create a model asset from a meshInstance

I am working to decompose an imported model into separate entities based on the meshInstances in the model. I have this working in the project link below. But in this implementation, I am adding a model asset to each newly created entity, an entity that I also imported. This is fine for this simple example, because the meshes are all the same, just simple boxes.

My question is: is there a way to create a model asset from a meshInstance? Or just create a model object in code from that meshInstance and assign it to an entity? It seems like all the data you need is in that meshInstance and it’s references. But try as I may, I cannot make this work. Any ideas would be appreciated.

To see the current decomposition function in action, launch the game and open up the console window on the browser. Use an arrow key to move the original entity of 3 cubes out of the way, so that you can see the new entities which look exactly like the old ones. Now click on each of the new cubes. You will see in the console that each one is a separate entity. Click on any of the boxes of the original and you will see they are all one single entity.

https://playcanvas.com/editor/scene/1100247

Hi @Michael_McCrickard,

The way I’ve been doing it from mesh -> mesh instance -> model -> model component is the following, if it helps:

  // --- create a mesh instance from a mesh and a material
  var node = new pc.GraphNode();
  var material = this.material.resource;

  var mesh = pc.createMesh(this.app.graphicsDevice, vertexData.positions, {
    normals: vertexData.normals,
    uvs: vertexData.uvs,
    indices: vertexData.indices,
  });

  var meshInstance = new pc.MeshInstance(node, mesh, material);

  // --- create a model and assign it to a model component
  var model = new pc.Model();
  model.graph = node;
  model.meshInstances.push(meshInstance);

  entity.addComponent("model", {
    layers: [this.app.scene.layers.getLayerByName("World").id],
    castShadows: true,
    receiveShadows: true,
  });
  entity.model.model = model;
2 Likes

This looks like exactly what I want to do – where is the vertexData coming from?

That was in my case a terrain generator, I’ve been creating custom terrain meshes from heightmap data.

If you already have a mesh/mesh instance skip to the second part of the code.

That is very helpful to see how it is done from scratch. Unfortunately, there appears to be an issue with pushing an existing meshInstance onto the meshInstances of a new model. After I do that, this line:

entity.model.model = model;

…gives this error: meshInstances[i].setOverrideAabb is not a function, at least when I use a copy of the original meshInstance. If I just use a regular var to hold the meshInstance (which internally is just a pointer), I don’t get the error but a visible model is not created. Both outcomes seem strange, because in examining both the original meshInstance and the newly added one, they look identical, regardless of the method used (copy or pointer).

https://playcanvas.com/editor/code/769371?tabs=43360928

I got past the error doing this:

var newMeshInstance = new pc.MeshInstance(meshInstance.mesh, material, node);

… and now it creates visible entities with models! And now the collision component on each is no longer working. Sigh.

No, the colliders are fine! I forked the project and forgot that the assetID changes when you do that.
Now to try and figure out how to make those colliders use the same mesh as the model (in code).

Thanks so much for all your help, Leonidas! I’m halfway there.