How to attach custom data to mesh? Extend Mesh class, .metadata or somethink else?

I’m quite well new in the world of the BabylonJs, JavaScript and TypeScript but I love the project and the possibilities it offers.

I know something about the Unity3D engine and I’m trying to achieve in BabylonJS something that’s is the basis of the Unity, namely Components. I want to add my custom properties and logic to the meshes. Currently, I have 2 ideas:

  1. Extend the Mesh class, but I want to compose over the inheritance
  2. Use the .metadata property of the Node class to store my custom data for the object. In my case, it’s ok to have only one object per mesh and this approach for me looks most similar to Unity components and GetComponent function. But I’m wondering if it’s ok to use .metadata property when I’m writing in TypeScript. Here is an example: Playground

I read also about using the Behaviours to similar problems, but I want to be able to get access to my custom data like in the example when I pick mesh with raycaster.

Do you have any other idea on how to achieve that? Or maybe my solution with using the .metadata for it is a good choice?

Hi. Look in mesh object… they have metadata property by default and i think its right way to store additional data for meshes or something other scene elements

I’m not sure if there is a performance gain including data directly on the mesh. You may prefer to just include a reference to the mesh in your own component class.

I was thinking about that kind of solution, but as I understand I need to store somewhere those Objects, like in array and then for example, when I pick the mesh with ray I need to find and return the object with this mesh from the array.
Or is there a different way to achieve that? Because I’m thinking about the performance of searching through the entire array for the correct object. Of course, in the example for ray predicate instead of looking for the object inside the array, I can attach Tag to the mesh and use tags with ray predicates.

1 Like

I have another idea, but I’m not sure if it’s totally stupid or brilliant :smiley: at least it’s working.

So, like in the previous version, I’m creating the object with data for “sphere” with Mesh property(SphereComponent) inside it, but additionally, to that, I’m also assigning function to mesh.metadata property, which will return this object(SphereComponent). Here is the function to create a new sphere with a data component:

function createSphere(xPos: number, sphereComponentText: string){
        const sphere = BABYLON.Mesh.CreateSphere("sphere", 16, 2, scene);
        sphere.position = new BABYLON.Vector3(xPos, 1, 0);
        BABYLON.Tags.AddTagsTo(sphere, "Sphere");

        const sphereComponent = new SphereComponent(sphereComponentText, sphere);
        sphere.metadata = function() { return sphereComponent; };

As I logged the sphere mesh with this solution the metadata property is different compare to the first version where I assigned data object to metadata field:

  1. First idea: mesh.metadata = new SphereComponent();
  2. New idea: mesh.metadata = function() { return sphereComponent}

But as I said, I’m not sure if it’s pointless, stupid and the same like mesh.metadata = new SphereComponent(). At least I don’t need to store all of the data inside the array :slight_smile:

Here is a running example of it: