Jump to content
  • Advertisement
Sign in to follow this  
arczev

multiple object picking

This topic is 3495 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, how can I gain selection for multiple objects? I'd like to have it like in RTS games: I make a rectangle with cursor and those object which are inside it are picked. Thx 4 response :)

Share this post


Link to post
Share on other sites
Advertisement
I didn't use OpenGL picking yet but AFAIK you'll have to provide a picking projection matrix to OpenGL. Make that matrix fit your selection rectangle and render the scene in selection mode. For creating the matrix you could use gluPickMatrix with x and y being the center of your rectangle and width/height being set appropriately.

For rendering in the selection mode you could only render a point per unit (for example at the unit's center) in order to reject units that are only slightly touched by your selection rectangle.

After rendering you should have the corresponding picking info for all hits in your selection buffer (provided it is big enough).

Hope that helps.

Thomas

Share this post


Link to post
Share on other sites
A more simple method ( assuming this is a 2D RTS ) would be to make the rectangle and then see what objects are inside of it.


class SelectionBox
{
public:
void SetFirstCorner( const int _x, const int _y )
{
m_Point[0][0] = (double)_x;
m_Point[0][1] = (double)_y;
m_Corner[0] = true;
}

void SetSecondCorner( const int _x, const int_y )
{
m_Point[1][0] = (double)_x;
m_Point[1][1] = (double)_y;
m_Corner[1] = true;
}

void EraseCorner( const int _corner )
{
m_Point[corner][0] = m_Point[_corner][1] = 0;
m_Corner[_corner] = false;
}

void Render( void )
{
glPushMatrix();
glColor3d( 1.0, 0.0, 0.0 );

if( m_Corner[0] && m_Corner[1] )
{
glBegin(GL_LINE_STRIP);
}
else if( !m_Corner[0] && !m_Corner[1] )
{
glPopMatrix();
return;
}
else
{
glBegin(GL_POINTS); // I think it was called "GL_POINTS"
}

if( m_Corner[0] && !m_Corner[1] )
{
glVertex2d( m_Point[0][0], m_Point[0][1] );
glVertex2d( (double)GetMouseX(), m_Point[0][1] );
}
else if( m_Corner[1] && !m_Corner[0] )
{
glVertex2d( m_Point[1][0], m_Point[1][1] );
glVertex2d( m_Point[1][0], (double)GetMouseY() );
}
else
{
glVertex2d( m_Point[0][0], m_Point[0][1] );
glVertex2d( m_Point[1][0], m_Point[0][1] );
glVertex2d( m_Point[1][0], m_Point[1][1] );
glVertex2d( m_Point[0][0], m_Point[1][1] );
}


glEnd();
glPopMatrix();
}

const bool ObjectIsInside( const int _objx1, const int _objy1, const int _objx2, const int objy2 )
{
if( _objx1 >= m_Point[0][0] && _objx2 <= m_Point[1][0]
&& _objy1 >= m_Point[0][1] && _objy2 <= m_Point[1][1] )
{
return true;
}

return false;
}

const int NumberOfCorners( void )
{
int amount = 0;
m_Corner[0]? amount++;
m_Croner[1]? amount++;
return amount;
}

SelectionBox()
{
m_Point[0][0] = m_Point[0][1] = m_Point[1][0] = m_Point[1][1] = 0.0 ;
m_Corner[0] = m_Corner[1] = false;
}

virtual ~SelectionBox()
{}
protected:
double m_Point[2][2];
m_Corner[2];
};

SelectionBox *g_SelectionBox;

//...In game
if( MouseClicked() && g_SelectionBox->NumberOfCorners() == 0 )
{
g_SelectionBox->SetFirstCorner( GetMouseX(), GetMouseY() );
}
else if( MouseClicked() && g_SelectionBox->NumberOfCorners() == 1 )
{
g_SelectionBox->SetSecondCorner( GetMouseX(), GetMouseY() );
}
else if( MouseClicked() && g_SelectionBox->NumberOfCorners() == 2 )
{
for( RTSUnitsListIterator = RTSUnitsList.begin();
RTSUnitsListIterator != RTSUnitsList.end();
RTSUnitsListIterator++ )
{
if( g_SelectionBox->ObjectIsInside(
RTSUnitsListIterator->GetBounds().GetFirstX(),
RTSUnitsListIterator->GetBounds().GetFirstY(),
RTSUnitsListIterator->GetBounds().GetSecondX(),
RTSUnitsListIterator->GetBounds().GetSecondY() )
{
RTSUnitsListIterator->SetIsSelected();
}
}

g_SelectionBox->EraseCorner( 0 );
g_SelectionBox->EraseCorner( 1 );
}

//Drawing
g_SelectionBox->Render();




I think you get the overall idea. If this is 3D, I have no clue on how to set that one up. Sorry. :]

Share this post


Link to post
Share on other sites
If you want to do the picking yourself, you could build up a volume in 3D and do the check. For an ortho projection it would be an oriented box, for a perspective projection (which you most likely use) it would be a capped pyramid, much like the view frustum.

There are several methods for building that pyramid, one being to create the projection matrix and extract the pyramid geometry from it, another being to unproject the corners of your rectangle at both depth = 0 and depth = 1 and building the pyramid with those 8 points.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!