Importing and attaching a mesh to a custom mesh generated in real time

I have a custom mesh of a human head that is getting generated in real-time. (so the coordinates keep on changing).

I want to attach peripherals to this head (like say a cap). I made this in Maya and exported as a .obj file.

Now, I have a scene with mesh of human head already there and I’m trying to

  1. import cap.obj to the existing scene
  2. attach it to the top of the head

I tried reproducing in the playground but could not reproduce that too :frowning:
https://playground.babylonjs.com/#CYDTLA#1
Please find the cap object zipped with this.

Please help if possible. Thanks!

cap.zip (22.9 KB)

You can use this page to help you make your asset usable from the playground: Using External Assets - Babylon.js Documentation

1 Like

Use scene.createDefaultCamera to create a camera that will make your objects visible by default:

https://playground.babylonjs.com/#CYDTLA#3

I’m sorry @Evgeni_Popov but doesn’t work. My canvas just has the rendered human head.

Your triangle is very small, you have to make it bigger:

https://playground.babylonjs.com/#CYDTLA#4

@Evgeni_Popov got that. If you click on play again and again, you’ll notice that the custom mesh gets generated first and then imported mesh is created. But if you click on play again and again quickly then the imported mesh just doesn’t get rendered.

Since in my case the mesh vertices are changing every second could this be an issue of why I am facing issues locally?

I think your .obj is not valid because there is this warning in the console log:

babylon.js:16 BJS - [15:44:01]: Setting vertex data kind 'position' with an empty array

It seems one of your mesh is empty(?).

However, even with the warning, when I keep pressing play I still get everything displayed correctly (except of course if I click too quickly for the obj mesh to have time to be loaded before the refresh!).

Also @Evgeni_Popov adding scene.createDefaultCamera(true, true, true);
after newMeshes[0].scaling = new BABYLON.Vector3(0.100, 0.100, 0.100);
doesn’t do anything locally and all I see is the rendered head

and adding scene.createDefaultCamera(true, true, true); just before return scene as in the playground result in a blank canvas

Have you used my PG? You should see one triangle and the cap.

Sometimes you may not see the triangle because the 3 vertices are generated randomly: just restart the playground.

// Babylon JS code start


            // createScene function that creates and return the scene
			var createScene = async function () {
				var scene = new BABYLON.Scene(engine);
								  
				//Create a custom mesh  
				var customMesh = new BABYLON.Mesh("custom", scene);

				//Set arrays for positions and indices
				var positions = kps.slice(0,kps.length)
				var indices = [];
                var colors = [];
                for(var i=0;i<positions.length/3;i++)	
				{
                 	indices.push(i);
                }

                for(var i=0;i<positions.length/3;i++)	
				{
                    if (lipsUpperOuter.includes(TRIANGULATION[i]))
                    {
                 	colors.push(0.725);
                 	colors.push(0.443);
                 	colors.push(0.376);
                 	colors.push(0);
                    }
                    else if(lipsLowerOuter.includes(TRIANGULATION[i]))
                    {
                 	colors.push(0.874);
                 	colors.push(0.427);
                 	colors.push(0.356);
                 	colors.push(0);
                    }
                    else if(lipsUpperInner.includes(TRIANGULATION[i]))
                    {
                 	colors.push(0.717);
                 	colors.push(0.431);
                 	colors.push(0.364);
                 	colors.push(0);
                    }
                    else if(lipsLowerInner.includes(TRIANGULATION[i]))
                    {
                 	colors.push(0.533);
                 	colors.push(0.145);
                 	colors.push(0.121);
                 	colors.push(0);
                    }
                    else if(rightEyeUpper0.includes(TRIANGULATION[i]))
                    {
                 	colors.push(1);
                 	colors.push(1);
                 	colors.push(1);
                 	colors.push(0);
                    }
                    else if(rightEyeLower0.includes(TRIANGULATION[i]))
                    {
                 	colors.push(1);
                 	colors.push(1);
                 	colors.push(1);
                 	colors.push(0);
                    }
                    else if(rightEyebrowLower.includes(TRIANGULATION[i]) && TRIANGULATION[i] != 35 && TRIANGULATION[i] != 124)
                    {
                 	colors.push(0);
                 	colors.push(0);
                 	colors.push(0);
                 	colors.push(0);
                    }
                    else if(leftEyeUpper0.includes(TRIANGULATION[i]))
                    {
                 	colors.push(1);
                 	colors.push(1);
                 	colors.push(1);
                 	colors.push(0);
                    }
                    else if(leftEyeLower0.includes(TRIANGULATION[i]))
                    {
                 	colors.push(1);
                 	colors.push(1);
                 	colors.push(1);
                 	colors.push(0);
                    }
                    else if(leftEyebrowLower.includes(TRIANGULATION[i]) && TRIANGULATION[i] != 265 && TRIANGULATION[i] != 353)
                    {
                 	colors.push(0);
                 	colors.push(0);
                 	colors.push(0);
                 	colors.push(0);
                    }
                    else
                    {
                 	colors.push(0.835);
                 	colors.push(0.615);
                 	colors.push(0.541);
                 	colors.push(0);
                    }
                }
				//Empty array to contain calculated values
				var normals = [];


				var vertexData = new BABYLON.VertexData();
				BABYLON.VertexData.ComputeNormals(positions, indices, normals);

				//Assign positions, indices and normals to vertexData
				vertexData.positions = positions;
				vertexData.indices = indices;
				vertexData.normals = normals;
                vertexData.colors = colors; //Assignment of colors to vertexData

				//Apply vertexData to custom mesh
				vertexData.applyToMesh(customMesh,true);

                var pivot = new BABYLON.TransformNode("root");
                pivot.position =customMesh.getBoundingInfo().boundingBox.centerWorld;
                customMesh.parent = pivot;
                pivot.rotation.z -= Math.PI

                customMesh.forceSharedVertices();

				var camera = new BABYLON.ArcRotateCamera("camera1",  Math.PI/2, Math.PI/2, 500, customMesh.position, scene);
				camera.attachControl(canvas_overlay, true);

                var light = new BABYLON.DirectionalLight("DirectionalLight", new BABYLON.Vector3(0, 0, -1), scene);
                light.intensity = 0.5;





                    BABYLON.SceneLoader.ImportMesh("", "./", "cap.obj", scene, function (newMeshes) {
                    
                    newMeshes[0].position = pivot.position;
                    newMeshes[0].scaling = new BABYLON.Vector3(0.100, 0.100, 0.100);
                    scene.createDefaultCamera(true, true, true);
                    console.log(newMeshes[0]);
        
    });

				return scene;
			};

            // call the createScene function
            var scene = await createScene();

            // run the render loop
            scene.render();

            // the canvas/window resize event handler
            window.addEventListener('resize', function(){
                engine.resize();
            });

@Evgeni_Popov this is my code
kps is an array that changes dynamically
Canvas just shows the rendered head. What am I missing?

Unfortunately, without a proper repro I won’t be able to help much more.

You should start with something that works (take the code from the PG in this thread) and add progressively your own code and see when it stops working.

I was able to produce this. Can you help me in attaching the cap to the face @Evgeni_Popov
https://playground.babylonjs.com/#CYDTLA#5

You can try something like this:

https://playground.babylonjs.com/#CYDTLA#6

1 Like

The same thing doesn’t work locally :confused:

is there some other way out to import the cap mesh?

Could async calls to createScene be a problem?

If the code works in the PG there’s no reason it should not work locally for you but it’s hard to diagnose without a repro.

Are you using a local web server to serve your pages? How to setup a local webserver for BabylonJs - Babylon.js Documentation

Yes @Evgeni_Popov all that is working fine. The face mesh is getting rendered, but not the imported cap.

1 Like

Continuing here as I don’t want to spam the forum

So I added the debugger by scene.debugLayer.show();
and it shows that the cap mesh has been successfully imported to the scene and the previously existing face mesh is its parent too
But it’s still not visible still due to some weird reason :expressionless:

It may be nothing to see, but I had a problem like this once using an octree after my scene loaded. Then when I added new mesh afterwards, I did not update the octree. I ended up with meshes not visible.

But you may not be using octree, so my post may not help. But it happens that a problem comes from there or we do not expect it.

Interesting. But what I have here is a obj file (linked above) that I exported from Maya. I’m trying to import that into an existing scene with a custom mesh.
So issue not related to octrees i guess (?)

Have you tried to use scene.createDefaultCamera(true, true, true) in case your mesh is not visible from your current camera?