Rectangle Picking

Is there any way in Panda to get a list of objects that are within a given rectangle on the screen? I need to let the user click the mouse and drag to define a rectangle in screen coordinates, and then select all the objects that appear within that rectangle on the screen.

I know the standard OpenGL way to do this using glRenderMode(GL_SELECTION) and the name stack; does Panda provide python classes implementing this?


you can do it yourself, using … 3D_Objects

That takes care of single clicks, but to handle a rectangle using that method I’d need to make a separate CollisionRay for each pixel, which will be prohibitively expensive.

Yeah… This is a really important question imo… I know in 2d you would go through each object, check their positions to see if they are within range of the rectangle…

But in 3d scene though… At first I was thinking take a collision plane and orient it on the camera… get a list of objects behind it and then it should be able to tell you their position on the plane. But this means it would be orthographic…

Maybe something where you make a pyramid thing out of planes where the camera is the tip and the width and length is based on the rectangle… then anything that was hit by all of the planes is considered selected.

I’m going to have to do this too later for an editor type thing… and I’m sure a lot of other people doing RTS games will need to figure it out as well. Any help would be… helpful… :slight_smile:

you could try to set up 4 planes to set up a pyramide and get all objects which are colliding with all 4 or none planes (depending on if which way you set up the 4 planes in space)

This is a tough problem to handle directly in Panda3D. The best solution is probably to go outside of Panda:

  1. identify all objects in the scene, and associate a bounding box with each based on approximate size.

  2. ignore objects behind the camera.

  3. calculate the center point position of the object in the camera view (this requires a knowledge of camera parameters in Panda such as FOV, as well as good vector match skills).

  4. expand the points into 2D bounding boxes based on 3D size and distance from the camera (this is imprecise since objects can have weird shapes and rotate in different ways).

  5. Test each object box against the screen rectangle. You need to test whether any box corner point lies within the rectangle, or whether the box spans the rectangle (like a plus sign).

There might be an easier way to do step 3. In OpenGL there are commands to project vertices from 3D into 2D screen coordinates without actually rendering anything, if there’s a similar way in Panda that I’m not aware of this would be easier.

Thomas’s plane collision test would be easier but would miss any objects completely within the selection rectangle, so I normally wouldn’t recommend it, but now that I think about it since you always start dragging from a single point this might not be a problem.

Actually, the plane solution wouldn’t miss the interior of the rectangle, because a “plane” in Panda’s collision system is actually an infinite volume more accurately called a “half space”. A CollisionPlane divides the universe into two infinite regions, an inside (behind the plane) and an outside (in front of the plane). An object is considered to be intersecting the plane if it is anywhere behind the plane, even if it is miles behind the plane.

So if you oriented the planes with all the normals facing outside of the rectangle, and built a list of all the objects that intersected all four planes, you would reliably have a list of all objects that are partly or completely within the rectangular region.