R3F: Calculate the absolute (relative to the center of the scene) position of a mesh deeply nested in a GLTF model

Hello,
I’m quite new to R3F and Three in general and I’m trying to calculate the position relative to the scene of a mesh that is part of a bigger gltf model.
I loaded the model using: https://gltf.pmnd.rs/.

When I click on the specific mesh I would like to move the camera towards that object.
The problem is that the position I’m getting is always “wrong”.

I understood that reading the position of the object itself will always return 0, 0, 0, since it is part of a bigger model.

I then tried to calculate the center of the mesh using its geometry bounding box (using mesh.geometry.boundingBox.getCenter(new Vector3()), but still the position is nowhere near the actual mesh as I see it.

So I again tried: new Box3().setFromObject(myMesh).getCenter(new Vector3()), and again the position I’m getting is far from the mesh I see, but closer to the center of the model.

I updated the model matrixWorld and worldMatrix (on click and with useEffect), but the results are the same.

Here are the relevant (I believe) bits of code:

export default function Model(props: JSX.IntrinsicElements["group"]) {
  const group = useRef<THREE.Group>(null);

  const [showClicked, setShowClicked] = useState<THREE.Vector3 | null>(null);
  const { nodes, materials } = useGLTF("/path/to/model.glb") as GLTFResult;

  useEffect(() => {
    if (group.current) {
      group.current.updateWorldMatrix(true, true);
      group.current.updateMatrixWorld(true);
    }
  }, []);

  return (
    <>
      <group {...props} ref={group} dispose={null} scale={0.1}>
        <group rotation={[Math.PI / 2, 0, 0]}>
          <mesh
            castShadow
            receiveShadow
            geometry={nodes.node1.geometry}
            material={materials.material1}
            onClick={(e) => {
              const bb = new THREE.Box3();
              bb.setFromObject(e.object, true);
              setShowClicked(bb.getCenter(new THREE.Vector3()));
            }}
          />
        </group>
        {showClicked && (
          <mesh position={showClicked}>
            <boxGeometry args={[0.5, 0.5, 0.5]} />
            <meshStandardMaterial color="red" />
          </mesh>
        )}
      </group>
    </>
  );
}

useGLTF.preload("/path/to/model.glb");

Any help will be appreciated.

No need, you can remove that part of the code since it’s done automatically by three. On your side all you’ll need is just getWorldPosition:

<mesh
  onClick={({ object }) => {
    const worldPosition = new THREE.Vector3();
    object.getWorldPosition(worldPosition);

    setShowClicked(worldPosition);
  })
>{...}</mesh>

Thank you for taking the time to answer my question. I’m sorry, but I tried so many things that I forgot to list all of them. I tried the method you suggested but I still get 0, 0, 0 as worldPosition. That’s why I updated the matrices, I thought it had something to do with that.

Could you share the model you’re trying to read the position from (and the name of the node in the model) ? If the transformation was applied to the meshes, then then all origins are moved to (0,0,0) instead of the mesh centre of gravity.

I will try to get a stripped down version of the model to share, since I do not own it and I’m not sure I can post it here.

But while I go get it can I ask if the transformation that could be possibly applied to the mesh would be visible in the jsx that I get back from gltf-> React Three Fiber? And if there are some what would be the steps (if they could be generalized for any parent model) to calculate its position?

I can share a picture of the mesh I’m trying to calculate the position of. I added a Box3Helper to visualize its bounds. The red dot is the result of getCenter() on the same box: