Jump to content

  • Log In with Google      Sign In   
  • Create Account


Mouse ray picking not working.


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 cec19   Members   -  Reputation: 102

Like
0Likes
Like

Posted 09 January 2012 - 03:35 PM

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[i]);
   Vector3d origin = nearPoint - parentBodyPos;

   CelestialBody *currentBody = sceneLayout->GetCelestialBody(parentNames[i]);
   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 Posted Image.

Sponsor:

#2 cec19   Members   -  Reputation: 102

Like
1Likes
Like

Posted 10 January 2012 - 05:10 AM

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. :)




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS