# Problems building a frustum from 2D screen rectangle

Hi all,

I’m trying to do a object selection based in a 2D rectagle drawn in the screen.

The steps that I follow are the next:

1. I obtain the limit of the rectangle in the 2D screen.
2. I generate 8 points in world space ( 4 in the “near” plane and 4 in the “far” ) according the 2D coordinates of this rectangle with a function like glUnproject.
3. With these points I build 6 planes, which normal and distance will be the sides of the frustum.
4. With this frustum, I perform a octree selection of the objects in the scene ( it checks if the AABB is inside o partial inside in the frustum ).

Following the explained algorithm the selection only works if the objects are in the origin ( 0, 0, 0 ) of the scene, but I have noticed a strange behaviour, this is, if the object is not in the origin, the selection works reflected on X.

I have checked the normals and distances of each plane that form the frustum, and apparently are built right, ( the planes surrond the selection according the 2D rectangle ).

I’m almost certain that my problem is in the steps explained above, I put the function that I wrote:

``````Octree *oct = this->GetOctree();

if ( oct )
{
Camera *cam = this->GetCamera();

if ( cam )
{
GLfloat x0, y0, x1, y1;
Vec3 l0, l1, l2, l3;
Vec3 r0, r1, r2, r3;
Mat4 projMat, viewMat;
Frustum frustum;
Viewport *viewport;

cam->GenerateMats();

// perspective projection matrix
projMat = cam->GetProjMat();

// view matrix ( inverse of camera model matrix )
viewMat = cam->GetViewMat();

viewport = cam->GetViewport();

// 2D limits of the rectangle in the screen
this->GetLimits( x0, y0, x1, y1 );

// ToWorld is equal to gluUnproject

// Generate the rectangle points in the NEAR plane
Camera::ToWorld( projMat, viewMat, viewport, Vec3( x0, y0, 0.0f ), l0 );
Camera::ToWorld( projMat, viewMat, viewport, Vec3( x1, y0, 0.0f ), r0 );
Camera::ToWorld( projMat, viewMat, viewport, Vec3( x0, y1, 0.0f ), l2 );
Camera::ToWorld( projMat, viewMat, viewport, Vec3( x1, y1, 0.0f ), r2 );

// Generate the rectangle points in the FAR plane
Camera::ToWorld( projMat, viewMat, viewport, Vec3( x0, y0, 1.0f ), l1 );
Camera::ToWorld( projMat, viewMat, viewport, Vec3( x1, y0, 1.0f ), r1 );
Camera::ToWorld( projMat, viewMat, viewport, Vec3( x0, y1, 1.0f ), l3 );
Camera::ToWorld( projMat, viewMat, viewport, Vec3( x1, y1, 1.0f ), r3 );

// LEFT / RIGHT
frustum.SetSide( 0, Plane( l3, l1, l0 ) );
frustum.SetSide( 1, Plane( r0, r1, r3 ) );

// FRONT / BACK
frustum.SetSide( 2, Plane( l0, r0, l2 ) );
frustum.SetSide( 3, Plane( l3, r1, l1 ) );

// BOTTOM / TOP
frustum.SetSide( 4, Plane( l1, r0, l0 ) );
frustum.SetSide( 5, Plane( l2, r2, l3 ) );

NodeList result = OctreeSelector::Get( oct, frustum );

for ( Node *node : result )
{
Print( node->GetName() );
}
}
}
``````

So can somebody tell me if I’m wrong?

Wherever the bug is, it’s not in the code you posted.

1 Like

You are right, my problem was in the frustum test.

Thanks you.