Sign in to follow this  

Picking & Independant Rotation

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

I'm having some trouble with picking an object then just having that object be rotated. Currently my code allows me to pick one object and have it rotate, but the other object no longer responses to being picked after putting in push and pop matrix commands. If I remove the pushMatrix and popMatrix commands I can click on either object, but they are both rotated. Any ideas on making the other object pickable again?
#include <stdio.h>
#include <stdlib.h>
#include <GLUT/glut.h>

   const GLint pickBuffSize = 32;
   
   GLfloat rotate;
   GLfloat rotate2;
   bool leftClick = false;
   bool rightClick = false;
   bool rotate30 = false;
   bool rotate20 = false;

   GLsizei winWidth = 400, winHeight = 400;


   void init (void)
   {
      glClearColor (0.0, 0.0, 0.0, 0.0);
	  glShadeModel(GL_SMOOTH);
	  glClearDepth(1.0f);
	  glEnable(GL_DEPTH_TEST);
	  glEnable(GL_CULL_FACE);
	  glDepthFunc(GL_LEQUAL);

   }
   
   void pyramid()
   {
	 
     glBegin(GL_TRIANGLES);
	    //initial front face
	   
		glColor3f(.79, .20, 0.10);
		glVertex3f(0.0, 6.0, 0.0);
		glVertex3f(-3.0, 0.0, 3.0);
		glVertex3f(3.0, 0.0, 3.0);
		
		//right side
		glColor3f(.30, .51, 0.20);
		glVertex3f(0.0, 6.0, 0.0);
		glVertex3f(3.0, 0.0, 3.0);
        glVertex3f(3.0, 0.0, -3.0);
		
		//back side
		glColor3f(0.0, 0.80, .68);
		glVertex3f(0.0, 6.0, 0.0);
		glVertex3f(3.0, 0.0, -3.0);
		glVertex3f(-3.0, 0.0, -3.0);
		
		//left side
		glColor3f(.50, 0.60, 0.10);
		glVertex3f(0.0, 6.0, 0.0);
		glVertex3f(-3.0, 0.0, -3.0);
		glVertex3f(-3.0, 0.0, 3.0);
		
	glEnd();

	}

   void draw (GLenum mode)
   {
   	  glClear (GL_COLOR_BUFFER_BIT |  GL_DEPTH_BUFFER_BIT);
	  
	  glPushMatrix();
	  glPushName (30);
      if(mode != GL_SELECT)
			glRotatef(rotate,0.0f,1.0f,0.0f);
	  pyramid();
	  glPopMatrix();
	 	  
	  glPushMatrix();

	  glPushName(20);
	  if(mode != GL_SELECT)
			glRotatef(rotate2,0.0f,1.0f,0.0f);
	  glTranslatef(8,0.0,0.0);
	  pyramid();
	
	  glPopMatrix();
	 
	 if(leftClick == true && rotate30 == true)
			rotate+=0.1f;
	 if(rightClick == true && rotate30 == true)
			rotate-=0.1f;
     if(leftClick == true && rotate20 == true)
			rotate2+=0.1f;
	 if(rightClick == true && rotate20 == true)
			rotate2-=0.1f;
	
	}

   /*  Print the contents of the pick buffer for each mouse selection.  */
   void processPicks (GLint nPicks, GLuint pickBuffer [ ], int button)
   {
      GLint j, k;
      GLuint objID, *ptr;

      printf (" Number of objects picked = %d\n", nPicks);
      printf ("\n");
      ptr = pickBuffer;

      /*  Output all items in each pick record.  */
      for (j = 0; j < nPicks; j++) {
         objID = *ptr;

         printf ("   Stack position = %d\n", objID);
         ptr++;

         printf ("   Min depth = %g,", float (*ptr/0x7fffffff));
         ptr++;

         printf ("   Max = %g\n", float (*ptr/0x7fffffff));
         ptr++;

         printf ("   Stack IDs are: \n");
         for (k = 0; k < objID; k++) {
            printf ("   %d ",*ptr);
			if(*ptr == 30)
			{	
				if(leftClick == false && button == GLUT_LEFT_BUTTON)
				{
					leftClick = true;
					rotate30 = true;
				}
				else if(leftClick == true && button == GLUT_LEFT_BUTTON)
				{
					leftClick = false;
					rotate30 = false;
				}
				if(rightClick == false && button == GLUT_RIGHT_BUTTON)
				{
					rightClick = true;
					rotate30 = true;
				}
				else if(rightClick == true && button == GLUT_RIGHT_BUTTON)
				{
					rightClick = false;
					rotate30 = false;
				}
			}
			
            ptr++;
         }
         printf ("\n\n");
      }
   }

   void pickPyramids (int button, int action, int xMouse, int yMouse)
   {
      GLuint pickBuffer [pickBuffSize];
      GLint nPicks, vpArray [4];

      if (action != GLUT_DOWN) //removed this code: button != GLUT_LEFT_BUTTON || 
         return;

      glSelectBuffer (pickBuffSize, pickBuffer);  //  Designate pick buffer.
      glRenderMode (GL_SELECT);             //  Activate picking operations.
      glInitNames ( );                   //  Initialize the object-ID stack.

      /*  Save current viewing matrix.  */
      glMatrixMode (GL_PROJECTION);
      glPushMatrix ( );
      glLoadIdentity ( );

      glGetIntegerv (GL_VIEWPORT, vpArray);
      gluPickMatrix (GLdouble (xMouse), GLdouble (vpArray [3] - yMouse),
                        5.0, 5.0, vpArray);

      gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);	
      draw (GL_SELECT);       // Process

      /*  Restore original viewing matrix.  */
      glMatrixMode (GL_PROJECTION);
      glPopMatrix ( );
	  glLoadIdentity();
	  gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);	
      glMatrixMode (GL_MODELVIEW);

	  glutSwapBuffers();
	  
      nPicks = glRenderMode (GL_RENDER);

      processPicks (nPicks, pickBuffer, button);  // Process picked objects.

      glutPostRedisplay ( );
   }

   void displayFcn (void)
   {
	  glLoadIdentity();
	  gluLookAt(5,10,-30,0,0,0,0,1,0);
      
      draw (GL_RENDER);      
   
	  glutSwapBuffers();	
   }

   void winReshapeFcn (int newWidth, int newHeight)
   {
      /*  Reset viewport and projection parameters.  */
      glViewport (0, 0, newWidth, newHeight);
      glMatrixMode (GL_PROJECTION);
      glLoadIdentity ( );

      gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);	
      glMatrixMode (GL_MODELVIEW);

      /* Reset display-window size parameters.  */
      winWidth  = newWidth;
      winHeight = newHeight;
   }

   int main (int argc, char** argv)
   {
      glutInit (&argc, argv);
      glutInitDisplayMode (GLUT_DEPTH | GLUT_SINGLE | GLUT_RGB);
      glutInitWindowPosition (100, 100);
      glutInitWindowSize (winWidth, winHeight);
      glutCreateWindow ("Picking Demo");
	  
      glutDisplayFunc (displayFcn);
	  glutIdleFunc(displayFcn);
      glutReshapeFunc (winReshapeFcn);
      glutMouseFunc (pickPyramids);
	  init ( );

      glutMainLoop ( );
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Rather than have us try reading code.
Why dont you tell us, on a conceptual level, exactly what you are doing, and why it doesnt work.
Conceptual- that is, dont tell us, 'but if i remove this line... then'; actually say what the line does in terms of the program flow


I'd bet that the process of putting that into words, will probably end up conceptualizing the whole thing for you and ending up self-solving...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Anyhow

It sounds to me like you took some glpicking tutorial, which contains a single object that you can rotate
and are trying to add a second object

and your problem most likely stems from adding a second object, but not adding the associated transforms (glrotate, etc) to let it move independantly from the first one

additionally, the picking id stuff is probably intertwined in a similar manner
(since picking is usually done as a second rendering pass)

so your approach should be, identify the picking id related functions and duplicate for object2
identify the meaning of each transform (this includes the popmatrix stuff) and reorganize them to handle two objects (generally a set of push/pop for each separate object)

this will involve figuring out what each part of the tutorial actually means

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
hmmh, Actually

now that I look at the code, the render stuff seems ok

I think you just need to fix the logic that decides which object is currently picked. your processPicks function has a branch to check for id30, but not 20
so... that probably causes issue with trying to select the one who is 20...

Share this post


Link to post
Share on other sites
Sorry, the code that processed a pick for object was originally there. That bit of code must've been deleted when trying to get the program to work correctly.

Thanks for your help so far. I'm pushing and popping for each object and the picking is set up to recognize the picking of either object. When I'm pushing and popping matrices for objects I can't get any hit recognition on the second object (the object named 20), but if I remove those pushes and pops surrounding the objects I can recognize the hits on either object, but then they both rotate together.

Share this post


Link to post
Share on other sites
Here is the updated code:



#include <stdio.h>
#include <stdlib.h>
#include <GLUT/glut.h>

const GLint pickBuffSize = 32;

GLfloat rotate;
GLfloat rotate2;
bool leftClick = false;
bool rightClick = false;
bool rotate30 = false;
bool rotate20 = false;

GLsizei winWidth = 400, winHeight = 400;


void init (void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);

}

void pyramid()
{

glBegin(GL_TRIANGLES);
//initial front face

glColor3f(.79, .20, 0.10);
glVertex3f(0.0, 6.0, 0.0);
glVertex3f(-3.0, 0.0, 3.0);
glVertex3f(3.0, 0.0, 3.0);

//right side
glColor3f(.30, .51, 0.20);
glVertex3f(0.0, 6.0, 0.0);
glVertex3f(3.0, 0.0, 3.0);
glVertex3f(3.0, 0.0, -3.0);

//back side
glColor3f(0.0, 0.80, .68);
glVertex3f(0.0, 6.0, 0.0);
glVertex3f(3.0, 0.0, -3.0);
glVertex3f(-3.0, 0.0, -3.0);

//left side
glColor3f(.50, 0.60, 0.10);
glVertex3f(0.0, 6.0, 0.0);
glVertex3f(-3.0, 0.0, -3.0);
glVertex3f(-3.0, 0.0, 3.0);

glEnd();

}

void draw (GLenum mode)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
glPushName (30);
if(mode != GL_SELECT)
glRotatef(rotate,0.0f,1.0f,0.0f);
pyramid();
glPopMatrix();

glPushMatrix();

glPushName(20);
if(mode != GL_SELECT)
glRotatef(rotate2,0.0f,1.0f,0.0f);
glTranslatef(8,0.0,0.0);
pyramid();

glPopMatrix();

if(leftClick == true && rotate30 == true)
rotate+=0.1f;
if(rightClick == true && rotate30 == true)
rotate-=0.1f;
if(leftClick == true && rotate20 == true)
rotate2+=0.1f;
if(rightClick == true && rotate20 == true)
rotate2-=0.1f;

}

/* Print the contents of the pick buffer for each mouse selection. */
void processPicks (GLint nPicks, GLuint pickBuffer [ ], int button)
{
GLint j, k;
GLuint objID, *ptr;

printf (" Number of objects picked = %d\n", nPicks);
printf ("\n");
ptr = pickBuffer;

/* Output all items in each pick record. */
for (j = 0; j < nPicks; j++) {
objID = *ptr;

printf (" Stack position = %d\n", objID);
ptr++;

printf (" Min depth = %g,", float (*ptr/0x7fffffff));
ptr++;

printf (" Max = %g\n", float (*ptr/0x7fffffff));
ptr++;

printf (" Stack IDs are: \n");
for (k = 0; k < objID; k++) {
printf (" %d ",*ptr);
if(*ptr == 20)
{
if(leftClick == false && button == GLUT_LEFT_BUTTON)
{
leftClick = true;
rotate20 = true;
}
else if(leftClick == true && button == GLUT_LEFT_BUTTON)
{
leftClick = false;
rotate20 = false;
}
if(rightClick == false && button == GLUT_RIGHT_BUTTON)
{
rightClick = true;
rotate20 = true;
}
else if(rightClick == true && button == GLUT_RIGHT_BUTTON)
{
rightClick = false;
rotate20 = false;
}
}
if(*ptr == 30)
{
if(leftClick == false && button == GLUT_LEFT_BUTTON)
{
leftClick = true;
rotate30 = true;
}
else if(leftClick == true && button == GLUT_LEFT_BUTTON)
{
leftClick = false;
rotate30 = false;
}
if(rightClick == false && button == GLUT_RIGHT_BUTTON)
{
rightClick = true;
rotate30 = true;
}
else if(rightClick == true && button == GLUT_RIGHT_BUTTON)
{
rightClick = false;
rotate30 = false;
}
}

ptr++;
}
printf ("\n\n");
}
}

void pickPyramids (int button, int action, int xMouse, int yMouse)
{
GLuint pickBuffer [pickBuffSize];
GLint nPicks, vpArray [4];

if (action != GLUT_DOWN) //removed this code: button != GLUT_LEFT_BUTTON ||
return;

glSelectBuffer (pickBuffSize, pickBuffer); // Designate pick buffer.
glRenderMode (GL_SELECT); // Activate picking operations.
glInitNames ( ); // Initialize the object-ID stack.

/* Save current viewing matrix. */
glMatrixMode (GL_PROJECTION);
glPushMatrix ( );
glLoadIdentity ( );

glGetIntegerv (GL_VIEWPORT, vpArray);
gluPickMatrix (GLdouble (xMouse), GLdouble (vpArray [3] - yMouse),
5.0, 5.0, vpArray);

gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);
draw (GL_SELECT); // Process

/* Restore original viewing matrix. */
glMatrixMode (GL_PROJECTION);
glPopMatrix ( );
glLoadIdentity();
gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);
glMatrixMode (GL_MODELVIEW);

glutSwapBuffers();

nPicks = glRenderMode (GL_RENDER);

processPicks (nPicks, pickBuffer, button); // Process picked objects.

glutPostRedisplay ( );
}

void displayFcn (void)
{
glLoadIdentity();
gluLookAt(5,10,-30,0,0,0,0,1,0);

draw (GL_RENDER);

glutSwapBuffers();
}

void winReshapeFcn (int newWidth, int newHeight)
{
/* Reset viewport and projection parameters. */
glViewport (0, 0, newWidth, newHeight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );

gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);
glMatrixMode (GL_MODELVIEW);

/* Reset display-window size parameters. */
winWidth = newWidth;
winHeight = newHeight;
}

int main (int argc, char** argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DEPTH | GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition (100, 100);
glutInitWindowSize (winWidth, winHeight);
glutCreateWindow ("Pyramids!");

glutDisplayFunc (displayFcn);
glutIdleFunc(displayFcn);
glutReshapeFunc (winReshapeFcn);
glutMouseFunc (pickPyramids);
init ( );

glutMainLoop ( );
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
did you remember to set rotate30 to false when rotate20 is true
and vice versa?
looks like with your pick evaluation, each one only consider's itself for activation, but I dont see where you ever UnSet them...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
the variables rotate20 and rotate30 are global
this means they 'remember' their values from the previous update
make sure to reset them, or their past values might be messing up the new user inputs

Share this post


Link to post
Share on other sites

This topic is 3940 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this