Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreeJS 2D bounding box of 3D object

I need figure out the area on screen which my 3D object uses.

I've tried to Google for an answer but with no success.

The function geometry.computeBoundingBox() is only returning the 3D bounding box.

How could I convert this to a 2D bounding box?

like image 351
vaid Avatar asked Aug 24 '17 11:08

vaid


1 Answers

You simply have to convert all vertices to screen space and make a 2D bounding box from them:

function computeScreenSpaceBoundingBox(mesh, camera) {
  var vertices = mesh.geometry.vertices;
  var vertex = new THREE.Vector3();
  var min = new THREE.Vector3(1, 1, 1);
  var max = new THREE.Vector3(-1, -1, -1);

  for (var i = 0; i < vertices.length; i++) {
    var vertexWorldCoord = vertex.copy(vertices[i]).applyMatrix4(mesh.matrixWorld);
    var vertexScreenSpace = vertexWorldCoord.project(camera);
    min.min(vertexScreenSpace);
    max.max(vertexScreenSpace);
  }

  return new THREE.Box2(min, max);
}

The resulting Box2 is in normalized screen coordinates [-1, 1]. You can get the pixels by multiplying with half of the height and width of your renderer:

function normalizedToPixels(coord, renderWidthPixels, renderHeightPixels) {
  var halfScreen = new THREE.Vector2(renderWidthPixels/2, renderHeightPixels/2)
  return coord.clone().multiply(halfScreen);
}

See a demonstration of it here: http://jsfiddle.net/holgerl/6fy9d54t/

EDIT: Reduced memory usage in inner loop by suggestion from @WestLangley

EDIT2: Fixed a bug discovered by @manthrax

like image 156
Holger L Avatar answered Oct 04 '22 07:10

Holger L