Threejs - How to pick all objects in area?

后端 未结 1 1896
生来不讨喜
生来不讨喜 2021-02-04 22:43

I\'m using Three.js and I wonder how to get all objects in a given area?

For example, get all objects that found in the green-square:

1条回答
  •  梦如初夏
    2021-02-04 22:51

    I've wanted to implement something like this and I choose a very different method - maybe much worse, I don't really know - but much easier to do IMO, so I put it here in case someone wants it.

    Basically, I used only 2 raycasts to know the first and last points of the selection rectangle, projected on my ground plane, and iterate over my objects to know which ones are in.

    Some very basic code:

       function onDocumentMouseDown(event) {
          // usual Raycaster stuff ...
    
          // get the ground intersection
          var intersects = raycaster.intersectObject(ground);
    
          GlobalGroundSelection = {
            screen: { x: event.clientX, y: event.clientY },
            ground: intersects[0].point
          };
        }
    
       function onDocumentMouseUp(event) {
          // ends a ground selection
          if (GlobalGroundSelection) {
            // usual Raycaster stuff ...
    
            // get the ground intersection
            var intersects = raycaster.intersectObjects(ground);
    
            var selection = {
              begins: GlobalGroundSelection.ground,
              ends: intersects[0].point
            };
    
            GlobalGroundSelection = null;
            selectCharactersInZone(selection.begins, selection.ends);
          }
        }
    
        function onDocumentMouseMove(event) {
    
          if (GlobalGroundSelection) {
            // in a selection, draw a rectangle
            var p1 = GlobalGroundSelection.screen,
                p2 = { x: event.clientX, y: event.clientY };
    
            /* with these coordinates
              left: p1.x > p2.x ? p2.x : p1.x,
              top: p1.y > p2.y ? p2.y : p1.y,
              width: Math.abs(p1.x - p2.x),
              height: Math.abs(p1.y - p2.y)
            */
          }
        }
    

    Here is my select function:

    function selectCharactersInZone (start, end) {
    
      var selected = _.filter( SELECTABLE_OBJECTS , function(object) {
        // warning: this ignore the Y elevation value
        var itsin = object.position.x > start.x
                && object.position.z > start.z 
                && object.position.x < end.x
                && object.position.z < end.z;
    
        return itsin;
      });
    
      return selected;
    }
    

    Some warnings: as far as I know, this technique is only usable when you don't care about Y positions AND your selection is a basic rectangle.

    My 2c

    0 讨论(0)
提交回复
热议问题