How to zoom to selected area in split glb file?

Hey, I have a glb file of human body - split into body parts, i wonder how can i zoom to selected body part.
Thanks to @Mugen87 i understand now how to zoom in to decal ( here is the answer - zoom to decal), but for zooming to selected part - i guess i first need to find it’s center points and then face the camera to that area - but i can’t figure out how to get the center’s coordinates … sorry for not having a proper code example - but i couldn’t find any free split glb for creating a codepen example…

  1. Each part of your model can be extracted from within it by using either model.traverse or model.getObjectByName / model.getObjectById (docs.)
  2. After you extract the submesh you need, you can calculate the center of it using Box3:
const boneMesh = model.getObjectByName('bone1');

if (boneMesh) {
  // Calculate bounding box of the bone geometry
  const boneBox3 = new Three.Box3();
  boneBox3.setFromObject(boneMesh);

  // Save mesh centre location to a vector
  const boneCenter = new Three.Vector3();
  boneBox3.getCenter(boneCenter);
}
  1. As for zooming in - it should work the same way as zooming in on a decal (or any other object.)
1 Like

@mjurczyk - thanks - i almost got it, here is what i got so far:

This is the object that i want to select

  let  dataObj =  {
      "coordinates": {
        "position": [
          7.712649905426842,
          93.1981643233244,
          9.358817642852408
        ],
        "rotation": [
          -0.23358251329383378,
          0.038226607826516074,
          0.009092618097089653
        ],
        "scale": [
          5,
          5,
          5
        ]
      },
      "selectedName": "BendOfHipLeft",
      "selectedIntensity": {
        "painType": "aching",
        "painIntensity": 2,
        "painIntensityColor": "#AEE00B"
      },
    
    }

So i got it by name like this

   let boneMesh = {};
   
   boneMesh = scene.getObjectByName(dataObj.selectedName);

 if (boneMesh) {

              // Calculate bounding box of the bone geometry
              const boneBox3 = new THREE.Box3();
              boneBox3.setFromObject(boneMesh);
            
              // Save mesh centre location to a vector
              const boneCenter = new THREE.Vector3(); // here something is wrong - i get 0.0.0
              boneBox3.getCenter(boneCenter);

            }

Now - i’m not so sure about how to use the camera.position function

I guess it should be something like this

camera.position.fromArray( marksPosition); // dont know what to set here ...
camera.lookAt( new THREE.Vector3(boneBox3.x, boneBox3.y, boneBox3.z) );

thanks!

Still needs help with this one - if any one can - i’ll be happy :slight_smile:

  1. camera.position is not a function - it’s a property you can set. In the reply on SO, @Mugen87 shown you how to calculate the offset for the camera - which then should be set as the position (as before, it works the same for decals / points / models / abstract vector values.)

  2. Note that setting the position to targeted bone centre will result in that bone being hidden “behind” the camera (docs.) You probably don’t want that.

  3. Mind, you can use Object3D.lookAt with both floats and vector values (docs.) No need to create a new vector there.

  4. If I understand correctly what you’re trying to achieve - it’d be best if you hard-code the “zoomed” position and rotation for each bone - either in JSON or in the model itself. Then just move camera to specific position whenever a bone is selected.
    Zooming-in on models is not as straight-forward as decals in terms of readability - while decals have only 1 normal vector, model has 1 for every single triangle. Clicking on decal will always give you the same “forward” direction, clicking on the model will give you a different direction depending on the face you clicked.

Maybe this example can clarify it a bit (click on any part of the cat and note how jumpy the zooming in when using face directions to determine camera rotation.)

2 Likes

@mjurczyk great example - thanks - i’m checking!