AlvinfromDiaspar
AlvinfromDiaspar

Reputation: 6834

How to get picked 3d object (instead of just the clicked face)?

Three.js has examples of getting the clicked face of an object and subsequently highlighting that face. I was wondering how to get the entire object instead of just the face.

Example: I have many asteroids all rendered in a single buffer. How can I get the clicked asteroid object?

* Update *

I think I found a way to achieve object 'picking'. Essentially, I keep a list of the objects in memory. When a object is picked I use that object's point information to do a collision detection against all the objects in the list. The object that is the closest to the intersected point should, in theory, be the object I need.

Upvotes: 0

Views: 483

Answers (1)

leota
leota

Reputation: 1756

There's a good example here

You can achieve that using raycaster to project rays and detect intersections.

This is the part of the code you need for object picking.

// find intersections

            raycaster.setFromCamera( mouse, camera );

            var intersects = raycaster.intersectObjects( scene.children );

            if ( intersects.length > 0 ) {

                if ( INTERSECTED != intersects[ 0 ].object ) {

                    if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );

                    INTERSECTED = intersects[ 0 ].object;
                    INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
                    INTERSECTED.material.emissive.setHex( 0xff0000 );

                }

            } else {

                if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );

                INTERSECTED = null;

            }

            renderer.render( scene, camera );

UPDATE 1: If all your objects are merged into a single BufferGeometry:

  • Have a look at this example: webgl_interactive_buffergeometry
  • That will show you how to pick faces, not objects. So my guess is:

     //pseudo code 
     foreach( object in bufferGeometry){ 
         foreach(face in object){ 
            face.addAttribute ( name[object], attribute[object] ) 
         } 
     }
    

So creating a custom attribute for each of your object and passing it to its faces, you could:

  • intersect a face

  • Get its custom attribute

  • Select all faces with that attribute -> the object

I haven't tested it but I guess it should work, let me know :)

Upvotes: 2

Related Questions