Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

Troubleshooting
Research
Professional Opinions
Ask a Question
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

troubleshooting Question

OpenGL Grouping multiple object -

Avatar of genesisyell
genesisyell asked on
Game ProgrammingC++
1 Comment1 Solution1366 ViewsLast Modified:
Hi. I'm relatively new to OpenGL (in VC++) and trying to make a scene with a robot which has

a shoulder, elbow, wrist and hand to have a robot arm function.

I just want this arm to be rotating itself (when the shoulder moves, other parts of arm should
also move) with other parts that need to rotate.

So I think the problem is since each of arm object is using different pivot point

(different object coordinate) when it's rotating or translating. Is there any way that I can make a group and

using a same pivot point to rotate the arm?

I'm the priority should be 1)shoulder 2)elbow 3)wrist 4)hand.

But just can't find how to make a group to do this work correctly (or is my approach wrong?)

The simple example of this can be a head and hat situation where I put torus on top of a sphere (which is a head of the robot), and when I try to rotate head and hat at the same time by
type certain key, the rotation doesn't work well, since both parts are using different pivot point!
you can run my code and type 'p' or 'o' couple times to see what I meant. the pivot points are different so you can't rotate the head and the torus (hat) parts together...

Please help me out to solve this problem.... And thanks for reading my question!
here's the head and hat part specifically, and I attached my code..
//hat
        glPushMatrix();
            glTranslatef(0.0,14.5,0.0);
            glRotatef(90.0, 1.0,0.0,0.0);
            glRotatef(headBang, 0.0,1.0,0.0);       //headBang is a angle variable for the head movement
            glutSolidTorus(0.3,2.5,8,16);
      glPopMatrix();

      //head
      glPushMatrix();
            glTranslatef(0.0,13.0,0.0);
            glRotatef(headBang, 0.0,1.0,0.0);       // //headBang is a angle variable for the head movement
            glutSolidSphere(3.0,20,20);
      glPopMatrix();
#include <iostream>
#include <GL/glut.h>
#include <math.h>

using namespace std;

// function prototypes
void display(void);
void reshape(int width, int height);
void keyboard(unsigned char key, int x, int y);
void motion(int x, int y);
void init(void);
void idle(void);
void head(void);
void body(void);
void left_sh(void);
void left_arm(void);
void left_elbow(void);
void left_arm_bottom(void);
void left_wrist(void);
void left_hand(void);

// viewpoint
double theta=0, phi=0, d=100;
/*
double globalCamCentre[3];
double globalUp[3];
*/
double globalRight[3] = {1,0,0};

double center[3]={0,0,0};
double up[3]={0,1,0};

// window
int width = 400;
int height = 400;

float TorusRotated = 0.0;
float headBang = 0.0;

static GLfloat MatSpec[] = {1.0,1.0,1.0,1.0};
static GLfloat MatShininess[] = {45.0};
static GLfloat LightPos[] = {-2.0,1.0,3.0,0.0};
static GLfloat SpotLightPos[] = {0.0, 5.0, 0.0, 0.0};

	//color material
	GLfloat white[] = {1.0f,1.0f,1.0f,1.0f};			// white
	GLfloat purple[] = {1.0f,0.0f,1.0f,1.0f};			// purple
	GLfloat green[] = {0.0f,1.0f,0.0f,1.0f};				// green
	GLfloat blue[] = {0.0f,0.0f,1.0f,1.0f};				// blue

	//quadricObj for cylinder
	GLUquadricObj *quadObj = gluNewQuadric();

int 
main(int argc, char **argv)
{

  // set up window
  glutInitWindowSize(400, 400);
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutCreateWindow("Viewpoint Demo");

  // register callback functions
  glutDisplayFunc(display);
  glutReshapeFunc(reshape); 
  glutKeyboardFunc(keyboard);
  glutMotionFunc(motion);
  glutIdleFunc(idle);

  // initalize opengl parameters
  init();

  // loop until something happens
  glutMainLoop();
  return 0;           
}

void init()
{

  // initialize viewing system
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0, 1.0, 1.0, 1000.0);
  glMatrixMode(GL_MODELVIEW);

  // shading model
  glEnable(GL_SMOOTH);

  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, MatSpec);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, MatShininess);

  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0); 

  // initialize background color to black
  glClearColor(0.0,0.0,0.0,0.0);

  // enable depth buffering
  glEnable(GL_DEPTH_TEST);

}

void reshape(int newWidth, int newHeight)
{
	width = newWidth;
	height = newHeight;
	// preserve aspect ratio
	if (width < height)
		glViewport(0,0,width,width);
	else
		glViewport(0,0,height,height);
}

void display()
{

	glLoadIdentity();
	double eye[3]={0,0,0};
	eye[0] = center[0] + (float) d * cos(theta) * sin(phi);
	eye[1] = center[1] + (float) d * sin(theta);
	eye[2] = center[2] + (float) d * cos(theta) * cos(phi);

	gluLookAt(eye[0],eye[1],eye[2], center[0],center[1],center[2],up[0], up[1], up[2]);

	// clear buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//lights
	//glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
	glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, SpotLightPos);

	//draw shapes
	//draw a net
	glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
	glMateriali(GL_FRONT,GL_SHININESS,40);
	glBegin(GL_LINES);
		GLint LinesX = 10;
		GLint LinesZ = 10;
		GLfloat size = 5;
		for (int xc = 0; xc < LinesX; xc++)
		{
			glVertex3f(	-size / 2.0 + xc / (GLfloat)(LinesX-1)*size,
					0.0,
					size / 2.0);
			glVertex3f(	-size / 2.0 + xc / (GLfloat)(LinesX-1)*size,
					0.0,
					size / -2.0);
		}
		for (int zc = 0; zc < LinesX; zc++)
		{
			glVertex3f(	size / 2.0,
					0.0,
					-size / 2.0 + zc / (GLfloat)(LinesZ-1)*size);
			glVertex3f(	size / -2.0,
					0.0,
					-size / 2.0 + zc / (GLfloat)(LinesZ-1)*size);
		}
	glEnd();
	//floor
	//glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
	glMateriali(GL_FRONT,GL_SHININESS,40);
	glBegin(GL_QUADS);
		glVertex3f(-10.0,0.0,-10.0);
		glVertex3f(-10.0,0.0,10.0);
		glVertex3f(10.0,0.0,10.0);
		glVertex3f(10.0,0.0,-10.0);
	glEnd();

/*
	glMaterialfv(GL_FRONT, GL_DIFFUSE, green);
	glMateriali(GL_FRONT,GL_SHININESS,50);
	glutSolidSphere(1.0,20,20);
	glPushMatrix();
		glTranslatef(0.0,3.0,0.0);
		glutSolidSphere(1.0,20,20);
	glPopMatrix();
	glTranslatef(0.0,0.0,2.0);
*/
	head();
	body();
	left_sh();
	left_arm();
	left_elbow();
	left_arm_bottom();
	left_wrist();
	left_hand();

	glFlush();
	glutSwapBuffers();
}

void head(){
//hat
	glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
	glMateriali(GL_FRONT,GL_SHININESS,10);
	glPushMatrix();
		glTranslatef(0.0,14.5,0.0);
		glRotatef(90.0, 1.0,0.0,0.0);
		glRotatef(headBang, 0.0,1.0,0.0);
		glutSolidTorus(0.3,2.5,8,16);
	glPopMatrix();

	//head
	glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
	glMateriali(GL_FRONT,GL_SHININESS,20);
	glPushMatrix();
		glTranslatef(0.0,13.0,0.0);
		glRotatef(headBang, 0.0,1.0,0.0);
		glutSolidSphere(3.0,20,20);
	glPopMatrix();
}

void body(){
//body

	glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
	glPushMatrix();
		glTranslatef(0.0,12.0,0.0);
		glRotatef(90.0, 1.0, 0.0, 0.0); //rotate on the z axis
		gluCylinder(quadObj,3.0f,3.0f,8.0f,15,15);
	glPopMatrix();
}

void left_sh(){
//shoulder
	glMaterialfv(GL_FRONT, GL_DIFFUSE, green);	
	glPushMatrix();
		glTranslatef(-3.5,10.0,0.0);
		glutSolidSphere(1.0,20,10);
	glPopMatrix();

	glMaterialfv(GL_FRONT, GL_DIFFUSE, green);	
	glPushMatrix();
		glTranslatef(3.5,10.0,0.0);
		glutSolidSphere(1.0,20,10);
	glPopMatrix();
}

void left_arm(){
	//arm
	glMaterialfv(GL_FRONT, GL_DIFFUSE, purple);
	glPushMatrix();
		glTranslatef(3.5,10.0,0.0);
		glRotatef(90.0, 1.0, 0.0, 0.0); //rotate on the z axis
		gluCylinder(quadObj,0.5f,0.5f,2.0f,15,15);
	glPopMatrix();
}

void left_elbow(){
//elbow
	glMaterialfv(GL_FRONT, GL_DIFFUSE, green);	
	glPushMatrix();
		glTranslatef(3.5,8.0,0.0);
		glutSolidSphere(1.0,20,10);
	glPopMatrix();
}
void left_arm_bottom(){
	//arm bottom
	glMaterialfv(GL_FRONT, GL_DIFFUSE, purple);
	glPushMatrix();
		glTranslatef(3.5,7.0,0.0);
		glRotatef(90.0, 1.0, 0.0, 0.0); //rotate on the z axis
		gluCylinder(quadObj,0.5f,0.5f,1.0f,15,15);
	glPopMatrix();
}

void left_wrist(){
	//wrist
	glMaterialfv(GL_FRONT, GL_DIFFUSE, green);	
	glPushMatrix();
		glTranslatef(3.5,6.0,0.0);
		glutSolidSphere(1.0,20,10);
	glPopMatrix();
}

void left_hand(){
	//hand
	glMaterialfv(GL_FRONT, GL_DIFFUSE, purple);
	glPushMatrix();
		glTranslatef(3.5,4.0,0.0);
		glRotatef(-90.0, 1.0, 0.0, 0.0); //rotate on the x axis
		gluCylinder(quadObj,0.0f,0.5f,2.0f,15,15);
	glPopMatrix();
}

void keyboard(unsigned char key, int mouseX, int mouseY)
{
	switch (key) {

		case 'h':
			cout << "You should add instructions on your UI. " <<endl;
			cout << "'d' is zoom in." <<endl;
			cout << "'f' is	zoom out " <<endl;
			cout << "'v' is change center of attntion ->right " <<endl;
			cout << "'c' is change center of attntion ->left" <<endl;
			cout << "'a' is change center of attntion ->up " <<endl;
			cout << "'z' is change center of attntion ->down " <<endl;
			cout << "'p' is play ani	" <<endl;				
							
		break;

		case 'd':	//zoom in
			cout << "zoom in." << endl;
			d=d+10;
			break;

		case 'f':	//zoom out
			cout << "zoom out." <<endl;
			if(d>10)
				d=d-10;
			break;

		case 'v':		//4. change center of attntion ->right
				center[0] = center[0] + (globalRight[0]*(-5));
			display();
		break;

		case 'c':		//4. change center of attntion ->left
		center[0] = center[0] + (globalRight[0]*5);
		display();
		break;

		case 'z':		//4. change center of attntion ->up
		center[1] = center[1] +  (up[1]*(-5));
		//	Position = Position + (UpVector*Distance);
		display();
		break;

		case 'a':		//4. change center of attntion ->down
		center[1] = center[1] +  (up[1]*5);
		display();
		break;

		case 'p':
			headBang += 2.0;
			display();
			break;

		case 'o':
			headBang -= 2.0;
			display();
			break;

	}
	glutPostRedisplay();
}





/*
*	This routine reads mouse movement and adjusts
*	camera position/orientation.
*/

void motion(int x, int y)
{

	static int currX=-1;
	static int currY=-1;

	// wait until a mouse position is recorded and
	// avoid really big jumps
	if (currX>0  && abs(x-currX) < width/6 && abs(y-currY) < height/6) {
		phi += (double) (x-currX)/ (double) width * 3.14159;
		theta += (double) (y-currY)/ (double) height * 3.14159;
		
		// limit theta to -4pi/9 and 4pi/9
		// it is disorienting to lose "up"
		if (theta < -4*3.14159/9.0)
			theta = -4*3.14159/9.0;
		if (theta > 4*3.14159/9.0)
			theta = 4*3.14159/9.0;
	}
	currX = x;
	currY = y;
	glutPostRedisplay();
}

void idle(void)
{
	//make it stop
	//TorusRotated += 2.0;
	//display();
}
ASKER CERTIFIED SOLUTION
Avatar of mccarl
mccarlFlag of Australia imageIT Business Systems Analyst / Software Developer
Commented:
This problem has been solved!
Unlock 1 Answer and 1 Comment.
See Answers