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…
- Each part of your model can be extracted from within it by using either
model.traverse
ormodel.getObjectByName / model.getObjectById
(docs.) - 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);
}
- As for zooming in - it should work the same way as zooming in on a decal (or any other object.)
@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
-
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.) -
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.
-
Mind, you can use
Object3D.lookAt
with both floats and vector values (docs.) No need to create a new vector there. -
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.)
@mjurczyk great example - thanks - i’m checking!
Hi Roy @roy I would like to do exactly the same. I have currently someone making some avatar in blender. But don’t really know what / how to tell him so I can load these parts separately.
Can you share a bit, how you implemented these ‘split body parts’ and how you again combine? them in glb loading them in three js?