How to redefine the clone method of Custom Mesh

Hello,
I’m trying to create custom meshes, I have a problem related to cloning.

I created a javascript class that extends the Mesh class.
I redefined the clone method.

When I clone a custom mesh, it does not contain what the original source mesh contained.

Is there any alternative way to do this.
Cloned meshes must remain of the same original class.
I created an example here on playground:

Sample code:

const A = new CustomMeshA('A');
A.build();

const B = A.clone('B');
B.position.x = 1;

class CustomMeshA extends BABYLON.Mesh
{
constructor(name, scene) {
super(name, scene);
}

clone(name, newParent, doNotCloneChildren)
{
    const newInstance = new CustomMeshA(name, this.getScene());
    //super.clone(name, newInstance, doNotCloneChildren);
    return newInstance;
}

build()
{
    const positions = [-.5, .2, -.3, -.7, -.2, -.3, -.3, -.2, -.3, .5, .2, .3, .7, -.2, .3, .3, -.2, .3];
    const indices = [0, 1, 2, 3, 4, 5];  
  
    const vertexData = new BABYLON.VertexData();

    vertexData.positions = positions;
    vertexData.indices = indices;
    const normals = [];

    BABYLON.VertexData.ComputeNormals(positions, indices, normals);

    vertexData.applyToMesh(this);
}

}

Welcome to the community!
The Mesh constructor can take a source mesh, so you can just redefine your CustomMesh constructor and call it on clone: Mesh Clone Examples | Babylon.js Playground (babylonjs.com)

2 Likes

HI,
Thanks so much, it seems to work.

I created a new example with a custom class that extends another custom class that extends Babylon.Mesh,
and it seems to work.

( Even if there is a strange error in the console. )

Playground:

What kind of error are you seeing?

I think it’s a playground error:

ReferenceError: A is not defined
at createScene (:9:5)
at window.initFunction (:77:16)
at async R._compileAndRunAsync (rendererComponent.tsx:301:17) ‘Retrying if possible. If this error persists please notify the team.’

I’m not seeing it in the playground you shared, but this kind of error happens if a variable is used without being initialized

You’re right, I didn’t delete the console, it was a previous error, sorry.

Hello,
When I insert a custom Mesh into a TransformNode or into a Mesh, when I call the clone method, in the scene I have an additional node in the root.
Is it a bag or did I forget something?

Schermata 2024-01-31 alle 18.07.47

the code:

  const container = new BABYLON.TransformNode("CONTAINER");
  const content = new CustomMeshA('CONTENT');
  content.build();
  content.parent = container;
  container.clone();

class CustomMeshA extends BABYLON.Mesh
{
    constructor(name, scene, parent, source, doNotCloneChildren) {
        super(name, scene, parent, source, doNotCloneChildren);
    }

    clone(name, newParent, doNotCloneChildren)
    {
        const newInstance = new CustomMeshA(name, this.getScene(), newParent, this, doNotCloneChildren);
        return newInstance;
    }

    build()
    {
        var positions = [-.5, .2, -.3, -.7, -.2, -.3, -.3, -.2, -.3, .5, .2, .3, .7, -.2, .3, .3, -.2, .3];
        var indices = [0, 1, 2, 3, 4, 5];  
        var vertexData = new BABYLON.VertexData();
        vertexData.positions = positions;
        vertexData.indices = indices;
        var normals = [];
        BABYLON.VertexData.ComputeNormals(positions, indices, normals);

        vertexData.applyToMesh(this);
    }
}

You are cloning the container, which is a transform node, so it’s going to clone itself and its child (the custom mesh). If you want to clone only the custom mesh, you can clone it directly. In this case, it will have the same parent as the original mesh, then you can set its parent to null if you don’t want the clone to have a parent: Mesh Clone Examples | Babylon.js Playground (babylonjs.com)

Sorry, I’m a bit confused due to a rather complex project that I can’t debug correctly at the moment, in reality what I’ve seen works perfectly.
Thank you

In my project I also created customTransformNodes. In this example it appears that cloning of the CONTAINER node fails.
Nodes are created at the root instead of the source location.
(maybe the parameters in the constructor of the class that extends BABYLON.TransformNode are wrong?)

SCHERMATA

const createScene = () => {
   
...

    const container = new CustomMesh('CONTAINER');
    container.build();

    const content = new CustomTransformNode('CONTENT');
    content.parent = container;

    const subContent = new BABYLON.TransformNode('SUB-CONTENT');
    subContent.parent = content;

    container.clone();

    return scene;

};

class CustomTransformNode extends BABYLON.TransformNode
{
    constructor(name, scene) {
        super(name, scene);
    }

    clone(name, newParent, doNotCloneChildren)
    {
        return new CustomTransformNode(name, this.getScene(), newParent, this, doNotCloneChildren);
    }
}

class CustomMesh extends BABYLON.Mesh
{
    constructor(name, scene, parent, source, doNotCloneChildren) {
        super(name, scene, parent, source, doNotCloneChildren);
    }

    clone(name, newParent, doNotCloneChildren)
    {
        return new CustomMesh(name, this.getScene(), newParent, this, doNotCloneChildren);
    }

    build()
    {
        const box = BABYLON.MeshBuilder.CreateBox("box");
        box.parent = this;
    }
}

I changed the “clone” method code for the customTransformNode. Now it seems to work.
It seems that the TransformNode doesn’t cascade its children’s clone method, so I do it directly inside the clone method.

SCHER

class CustomTransformNode extends BABYLON.TransformNode
{
    constructor(name, scene) {
        super(name, scene);
    }

    clone(name, newParent, doNotCloneChildren)
    {
        const newNode =  new CustomTransformNode(this.name, this.getScene());
        newNode.parent = newParent;
        if( doNotCloneChildren != true) this.getChildren().forEach( child => child.clone( child.name , newNode ) );
        return newNode;
    }
}

The “no name” is because a name wasn’t given to the clone method: Mesh Clone Examples | Babylon.js Playground (babylonjs.com)

1 Like

Sorry, I went into a frenzy trying to resolve a question that I ultimately didn’t understand but was resolved

Thank you