title: Threejs - How to pick all objects in area?
body: <p>I'm using Three.js and I wonder how to get all objects in a given area?</p>
  
  <p>For example, get all objects that found in the green-square:
  <img src="https://i.stack.imgur.com/n8kFd.jpg" alt="Mass object selection"></p>
  
  <p><strong>Solution:</strong></p>
  
  <pre><code>        getEntitiesInSelection: function(x, z, width, height, inGroup) {
              var self = this,
                  entitiesMap = [],
                  color = 0,
                  colors = [],
                  ids = [],
                  pickingGeometry = new THREE.Geometry(),
                  pickingMaterial = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ),
                  pickingScene = new THREE.Scene(),
                  pickingTexture = new THREE.WebGLRenderTarget( this._renderer.domElement.width, this._renderer.domElement.height),
                  cloneMesh,
                  entities = inGroup ?
                      engine.getObjectsByGroup(inGroup) : engine.getRegisteredEntities();
  
              pickingTexture.generateMipmaps = false;
  
              //Go over each entity, change its color into its ID
              _.forEach(entities, function(entity) {
                  if(undefined == entity.threeRenderable) {
                      return ;
                  }
  
                  //Clone entity
                  cloneMesh = entity.threeRenderable.mesh().clone();
                  cloneMesh.material = entity.threeRenderable.mesh().material.clone();
                  cloneMesh.material.map = null;
                  cloneMesh.material.vertexColors = THREE.VertexColors;
                  cloneMesh.geometry = entity.threeRenderable.mesh().geometry.clone();
                  cloneMesh.position.copy( entity.threeRenderable.mesh().position );
                  cloneMesh.rotation.copy( entity.threeRenderable.mesh().rotation );
                  cloneMesh.scale.copy( entity.threeRenderable.mesh().scale );
  
                  //Cancel shadow
                  cloneMesh.castShadow = false;
                  cloneMesh.receiveShadow  = false;
  
                  //Set color as entity ID
                  entitiesMap[color] = entity.id();
                  self._applyVertexColors(cloneMesh.geometry, new THREE.Color( color ) );
                  color++;
  
                  THREE.GeometryUtils.merge( pickingGeometry,  cloneMesh);
              });
  
              pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) );
  
              //render the picking scene off-screen
              this._renderer.render(pickingScene, this._objs[this._mainCamera], pickingTexture );
              var gl = this._renderer.getContext();
  
              //read the pixel under the mouse from the texture
              var pixelBuffer = new Uint8Array( 4 * width * height );
              gl.readPixels( x, this._renderer.domElement.height - z, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelBuffer );
  
              //Convert RGB in the selected area back to color
              for(var i=0; i&lt;pixelBuffer.length; i+=4) {
                  if( 0 == pixelBuffer[i] &amp;&amp; 0 == pixelBuffer[i+1] &amp;&amp; 0 == pixelBuffer[i+2] &amp;&amp; 0 == pixelBuffer[i+3] ) {
                      continue;
                  }
  
                  color = ( pixelBuffer[i] &lt;&lt; 16 ) | ( pixelBuffer[i+1] &lt;&lt; 8 ) | ( pixelBuffer[i+2] );
                  colors.push(color);
              }
              colors = _.unique(colors);
  
              //Convert colors to ids
              _.forEach(colors, function(color) {
                  ids.push(entitiesMap[color]);
              });
  
              return ids;
          }
  </code></pre>
  
  <p>The line <code>engine.getObjectsByGroup(inGroup) : engine.getRegisteredEntities();</code> 
  just return an array of entities, which in turn, I iterate over the entities:</p>
  
  <pre><code> _.forEach(entities, function(entity) { ...
  </code></pre>
  
  <p>Only entities that have the 'threeRenderable' property (object) are visible, therefore, I ignore those that doesn't have it:</p>
  
  <pre><code>if(undefined == entity.threeRenderable) {
        return ;
  }
  </code></pre>
  
  <p>then I merge the entity's cloned mesh with with the pickingGeometry:</p>
  
  <pre><code>THREE.GeometryUtils.merge( pickingGeometry, cloneMesh);
  </code></pre>
  
  <p>eventually, I add the pickingGeometry to the pickingScene:</p>
  
  <pre><code> pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) );
  </code></pre>
  
  <p>Then I read the colors of the selected area, and return an array of IDs.</p>
  
  <p>You can checkout the <a href="https://github.com/eldad87/game-engine" rel="nofollow noreferrer">Node.js game engine</a> I wrote back then.</p>