Alex Ramirez
Alex Ramirez

Reputation: 127

Focus the camera in the center of an object in Three.js

I'm loading and object with the ColladaLoader in three.js, so I have an bunch objects in the scene. Some of them are regular shapes such as: cubes, spheres, etc. and for these ones I can do this:

var position = { 
  x: selectedObject.position.x, 
  y: selectedObject.position.y, 
  z: selectedObject.position.z 
};

controls.target = new THREE.Vector3(position);

Where controls are the OrbitControls for the camera. The camera gets centered in that position and works fine, the problem is when the objects are not regular shapes, but geometries generated by vertices. In this case, I already tried 4 different approaches without the expected result.

1.

var position = { 
  x: selectedObject.matrixWorld.getPosition().x, 
  y: selectedObject.matrixWorld.getPosition().y, 
  z: selectedObject.matrixWorld.getPosition().z 
};

2.

var centerX = selectedObject.geometry.boundingSphere.center.x;
var centerY = selectedObject.geometry.boundingSphere.center.y;
var centerZ = selectedObject.geometry.boundingSphere.center.z;

var position = { x: centerX, y: centerY, z: centerZ };

3.

getCentroid(selectedObject.geometry.vertices);

function getCentroid(vertices) {
  var x = y = z = 0;
  vertices.forEach(function (element, index, array) {
    x += element.x;
    y += element.y;
    z += element.z;
  });

  return new THREE.Vector3(
    x / (vertices.length),
    y / (vertices.length),
    z / (vertices.length)
  );
}

4.

var position = getCenter(
  getMaxnMinCenter(selectedObject.geometry.vertices), 
  selectedObject.matrixWorld
);


function getMaxnMinCenter(vertices) {
  var maxX = maxY = maxZ = vertices[0];
  var minX = minY = minZ = vertices[0];

  vertices.forEach(function (element, index, array) {
    if (element.x <= minX.x) {
      minX = element;
    }
    if (element.y <= minY.y) {
      minY = element;
    }
    if (element.z <= minZ.z) {
      minZ = element;
    }
    if (element.x > maxX.x) {
      maxX = element;
    }
    if (element.y > maxY.y) {
      maxY = element;
    }
    if (element.z > maxZ.z) {
      minZ = element;
    }
  });

  return {
    minimumX: minX,
    minimumY: minY,
    minimumZ: minZ,
    maximumX: maxX,
    maximumY: maxY,
    maximumZ: maxZ,
  }
}

It is important to notice that regular shapes use a scale of 1.0 while the other objects use a scale of 0.005.

Thank you.

Upvotes: 2

Views: 13012

Answers (2)

Gero3
Gero3

Reputation: 2887

var bb = new THREE.Box3()
bb.setFromObject(selectedObject);
bb.center(controls.target);

use a boundingbox to find the center of object

Upvotes: 13

mrdoob
mrdoob

Reputation: 19602

Try with:

controls.target.copy( selectedObject.position );

Upvotes: 1

Related Questions