Can anyone help me with adding morphTargets using react-babylonjs?

Here is my code block.

<Scene
clearColor={new Color4(0.02, 0.022, 0.02, 1)}
onSceneMount={(e) => {
onSceneMount(e);
}}
>

const onSceneMount = (e: any) => {
const { scene } = e;
let casiBody = scene.getMeshByName(“bubble_short_primitive0”);
console.log(casiBody);
}

And I am getting null for getMeshByName(“bubble_short_primitive0”) .

The most obvious thing will be: are you sure the “bubble_short_primitive0” mesh exists? You can load your mesh on the Babylon.js Sandbox - View glTF, glb, obj and babylon files (babylonjs.com) and use the inspector to check for the mesh structure:

Thank you @carolhmj for your reply. Here is the image after importing in the sandbox.
You can see bubble_short_primitive0 and bubble_short_primitive1 under root_/ bubble_short/ Nodes.

[OR] Should I use morphTargetManager prop in to set the morph targets.

<Model
rootUrl={https://raw.githubusercontent.com/ml-bhanuprakash/babylonjs/main/test_3/}
sceneFilename={blouse_03.glb}
scaleToDimension={0}
// morphTargetManager={ MorphTargetManager }

              onModelLoaded={(model) => {
                onModelLoaded(model);
              }}
              name={""}
            ></Model>

I see. Looking at your code, it seems that you are calling getMeshByName right after the scene mounts, which means the model might not be loaded at that time. You should wait for the model itself to be loaded, I’m not sure if there’s a callback for that on react-babylon? @brianzinn

@brianzinn @carolhmj Yes, You might be correct I am also thinking the same. I will give a try using async await once. Thank you

We can use onCreated prop in the Model. Now I can change the morph targets.
Here is the code.

 <Model
              rootUrl={`https://raw.githubusercontent.com/ml-bhanuprakash/babylonjs/main/test_3/`}
              sceneFilename={`blouse_03.glb`}
              scaleToDimension={0}
              // morphTargetManager={  }
              // scaling={new Vector3(1,1,1)}
              onCreated={(e) => {
                onCreatedModel1(e);
              }}
              onModelLoaded={async (model) => {
                await onModelLoaded(model);
                // setLoadModel1(true);
              }}
              name={""}
            ></Model>

const onCreatedModel1 = async (e: any) => {
console.log(e, “Model”);

console.log(e._scene, "Scene");
let casiBody = e._scene.getMeshByName("bubble_short_primitive1");
// console.log(e._scene.morphTargetManagers[0], "e._scene");
casiBody.morphTargetManager.getTarget(0).influence = 1;
casiBody.morphTargetManager.getTarget(1).influence = 1;
casiBody.morphTargetManager.getTarget(2).influence = 1;

};

2 Likes

I’m glad you found a solution that worked - sorry for this late reply.

The onModelLoaded callback is triggered when the model has loaded from the SceneLoader (the Model component is a lightweight wrapper on a hook). At that point you should be able to set morph targets and getMeshByName() would work. The onCreated() works - that is called when the “root” mesh is created for the Model, but has less useful information (in my opinion) - it does not have the callback parameters from the SceneLoader. The <Suspense ../> component you wrap around the <Model ../> component will handle the asynchronous nature of the scene loading. Lastly, I think your await onModelLoaded(model) is not needed as there is nothing to await unless you are processing async code in your callback of same name. :smile:

2 Likes