How to add a custom object on top of all imported meshes?

I have imported a teeth object which has around 64 meshes. I want to create a cube object on front face of all the meshes. I’m able to do this with scene.pick when clicking on the scene. But I want to do this on loading all the meshes without binding any actions to it. I have tried mesh.getBoundingInfo but it adds the cube in the spherical centre of the object. Any thoughts would greatly help. Thanks in advance!

function addBracketsForAllTooth() {
    if(teethRoot){
        const tooth = teethRoot.getChildMeshes();
        tooth.map((mesh) => {
            const name = mesh.name.split('_')[0];
            if(name.slice(name.length - 1) !== 'r'){
                if (mesh._children && mesh._children[0] && mesh._children[0].name.includes('picker_cube')) {
                    // alert('Bracket already present');
                    return false;
                }
                else{
                    var mat = new BABYLON.StandardMaterial('mat1', this.scene);
                    mat.diffuseColor = new BABYLON.Color3(1, 0, 0);
                    var cube = BABYLON.MeshBuilder.CreateBox(
                        'picker_cube' + bracketCount,
                        { size: 0.20, height: 0.20 },
                        scene
                    );
                    cube.position = mesh.getBoundingInfo().boundingSphere.center;

                    cube.parent = mesh;
                    cube.metadata = {'type': 'bracket'};
                    bracketCount ++;
                    cube.material = mat;

                    /* Rotating the cube -- Start */
                    /*var axis1 = pickResult.getNormal();
                    var axis2 = BABYLON.Vector3.Up();
                    var axis3 = BABYLON.Vector3.Up();
                    var start = new BABYLON.Vector3(Math.PI / 2, Math.PI / 2, 0);	//camera.position

                    BABYLON.Vector3.CrossToRef(start, axis1, axis2);
                    BABYLON.Vector3.CrossToRef(axis2, axis1, axis3);
                    var tmpVec = BABYLON.Vector3.RotationFromAxis(axis3.negate(), axis1, axis2);
                    var quat = BABYLON.Quaternion.RotationYawPitchRoll(tmpVec.y, tmpVec.x, tmpVec.z);
                    cube.rotationQuaternion = quat;*/
                    /* Rotating the cube -- End */
                }

            }
        });
    }
}

Hiya K.

I thought I would make a demo playground…

https://www.babylonjs-playground.com/#JFT1LI#21

Pretend the colored panels are teeth… all parented to root.

In your post, it seems you want click-able labels/buttons. I wanted to show you the BabylonJS AdvancedDynamicTexture (adt)… often called “GUI 2d”. It is a handy way to put clickable labels on mesh… with many extra features.

Here… you can see the MOST complex method… using a target ellipse, indexing lines, and a clickable rectangle with text inside. You/We can easily remove the index lines, the circular targets, and linkOffsets… and just put a basic label or button directly linkWithMesh(tooth). Not important at this time. Main thing… for you to see GUI 2d and see if that is REALLY what you want… instead of making little panels in front of each tooth.

Click on any green “rectangle”, and a report to console happens… saying a label was clicked. Unfortunately, I am currently failing-at determining WHICH tooth/label was clicked. It ALWAYS says “tooth340” because… that was the last tooth added… when making the circle. I need to try to find a fix… and/or ask others for help.

Ok, now, notice lines 134-149. This is the “scene.onPointer” observation system. No need to put an actionManager on each tooth… because these simple lines of code… might do what we need. Click on any mesh (not on a label or rect). Watch console. We are able to determine which tooth was clicked… just by clicking the mesh itself. You could possibly do showBoundingBox on a clicked mesh, or perhaps add a glowLayer or highlightLayer on the clicked tooth… to show it is “selected”.

So, you don’t need GUI labels/buttons/rects/lines/linkWithMesh… but it is included here… to show you what it is and how it COULD be useful to you.

And also, your original addBracketsForAllTooth() function is included, and ready to be called by activating line 132. We can still work-on placing clickable planes on the front of each tooth… if you choose. This playground might help… letting everyone on the forum… get involved and tell ideas.

Talk again soon, K and other friends. Hope I was helpful. Perhaps another forum helper can remove the “extra stuff” from the GUI 2d… and show us a “simpleButton at bottom of each tooth” version… something cleaner than all these index lines and targets. :slight_smile:

Hi @Wingnut
Thanks for the response. I want to place a 3D cube mesh on top of the tooth mesh which is exported from external OBJ file. Main thing is I want to do it on loading the external file without clicking mesh on the screen Is that possible in Babylon?

Hi. In most cases, that is possible… and your function is reasonably on-target.

We probably want to wait for scene.onReadyObservable. Then, in onReady observer handler func… if we can “see” the rotation and position values of each tooth (after load complete), and get the teeth into an array to loop-thru… then I think it can be done.

You/we might need to call ONE scene.render() inside the scene.onReadyObserver handler… so that all the imported mesh get “oriented” once. THEN… we might get better position and rotation values as we loop thru all the teeth mesh… finding out where they are and how they are rotated.

Possibly… getBoundingInfo().boundingBox.extends.z ? I dunno. Not knowing the heirarchy of the model… I’m just guessing. (I guess at solves often) heh

I’ll try to update my demo when I have a moment. It would be nice if we could import your object file into the playground… easier for everyone to help.

Can you publish your object file in a way that can be CORS-clear loaded? Something like this: https://www.babylonjs-playground.com/#3FV2X#40 (There, I loaded an object file from my free github acct. You can have one, too, if wanted.)

If you can get your model imported into playground, that would be great. Then we can “play” better. :slight_smile:

1 Like