• Advertisement
Sign in to follow this  

Mouse ray picking not working.

This topic is 2203 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

Hello everyone!

Recently I have been trying to implement picking via mouse ray. I made a little project with three spheres in it and I simply check for ray-sphere intersection. If there is such, I have a sphere to pick. After I made everything to work fine with that little project I tried to implement this in a bigger one. The bigger project is a solar systems creator. However, when I try to select a sun(that is the only thing I need to be selected) the selection won't work. Below I am posting the code for the solution.

First, the intersection test:



bool CelestialBody::IsClickedOn(Ray mouseRay)
{
float a = DotProduct(mouseRay.GetDirection(), mouseRay.GetDirection());
float b = 2 * DotProduct(mouseRay.GetOrigin(), mouseRay.GetDirection());
float c = DotProduct(mouseRay.GetOrigin(), mouseRay.GetOrigin()) - this->radius * this->radius;

float discriminant = b * b - 4 * a * c;

std::cout<<discriminant<<std::endl;

if(discriminant < 0)
{
return false;
}
return true;
}


Second, the mouse click code:

if(userMouse.IsLeftButtonDown())
{
int cursorX = int(userMouse.GetCurrentPosition().GetX());
int cursorY = int(userMouse.GetCurrentPosition().GetY());

Vector3d nearPoint = userCamera.GetPosition();
Vector3d farPoint = MouseClass::ConvertMouseToOGLCoordinate(cursorX, cursorY, 1.0f);

Vector3d direction = farPoint - nearPoint;
direction.Normalize();

std::vector<std::string> parentNames = sceneLayout->GetParentNames();
int size = parentNames.size();
for(int i = 0; i < size; i++)
{
Vector3d parentBodyPos = sceneLayout->GetCelestialBodyPosition(parentNames);
Vector3d origin = nearPoint - parentBodyPos;

CelestialBody *currentBody = sceneLayout->GetCelestialBody(parentNames);
mouseRay = Ray(origin, direction);

bool isCollided = currentBody->IsClickedOn(mouseRay);
if(isCollided)
{
currentBody->SetColor(Color(0, 0, 255));
}
else
{
currentBody->SetColor(Color(255, 250, 255));
}
}
//userMouse.ReleaseLeftButton();
}


And at last, the ConvertMouseToOGLCoordinate() function code:

Vector3d MouseClass::ConvertMouseToOGLCoordinate(int mouseX, int mouseY, int mouseZ)
{
GLint viewport[4];
GLdouble modelMatrix[16];
GLdouble projectionMatrix[16];

glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);float winY = float(viewport[3] - mouseY);

double x, y, z;
gluUnProject((double)mouseX, winY, mouseZ,
modelMatrix, projectionMatrix, viewport,
&x, &y, &z);

return Vector3d(x, y, z);
}


These are the snippets which correspond to the little project's code.

The thing I suspect to crash the algorithm is the position from which I view the scene. My camera coords are (0.0; 9000.0; 0.0) and when I switch from side view (0.0, 0.0, 9000.0) I am able to pick one of the planets. On the little project, however, I am able to pick from whatever position my camera is.

I know I haven't explained things good enough but that is all I can do... If you want the whole code of both projects, I will supply you with it smile.png.

Share this post


Link to post
Share on other sites
Advertisement
I managed to fix the problem. The code, which made things not work was in the display function:


void Display()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


glPushMatrix();
ApplyCamera();
DrawGrid(10000, 200);
DrawObjects();

glPopMatrix();

DrawText();


glutSwapBuffers();
}


Simply, the push and pop funcs are making sth wrong in my code(I am not so experienced and I can't tell exactly what). By removing them I managed to get good results for the depth buffers.


void Display()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


DrawText();

ApplyCamera();
DrawGrid(10000, 200);
DrawObjects();


glutSwapBuffers();
}


Thats it! If anyone can explain me why the pushing and popping matrices screws the whole algorithm please post. :)

Share this post


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

  • Advertisement