genesisyell
asked on
OpenGL Grouping multiple object -
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,1 6);
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();
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,1
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.