Can't you just rotate around the origin, and then translate the dino back a little when you render?
Can't you just rotate around the origin, and then translate the dino back a little when you render?
-Clark
What is moveDino() supposed to do in your program? If it changes the coordinates of the vertices from which you build your dino, then this is not the good way to move your dino. All the movement should be accomplished through glTransfer. The vertices from which you build your dino should be constant relatively to the point O. So the code should look something like this:
--
moveDino();
glPushMatrix();
glLoadIdentity();
glTranslatef(X,Y,Z);
// X,Y,Z calculated in moveDino.
glRotatef(angle,0.0,1.0,0.0);
drawDino();
glPopMatrix();
glFlush();
--
This way your Dino will be rotated round his legs and then displaced to the new point.
GA
The moveDino method should determine the new position of the dino and make sure it won't fall of the earth. Right now it is not correct, because before the dino could only move in the x or z direction....
You might take a look at the following picture to see what it should look like...
http://www.nat.vu.nl/~pwgroen/cg/images/screen-dino.jpg
Below is my complete code....
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <glutil.h>
#include <math.h>
#include <dino.h>
#include <readtex.h>
typedef GLfloat point3[3];
point3 dino_pos = {0.0, 0.0, 0.0};
point3 dino_dir = {0.0, 0.0, 0.0};
int move;
int current = 0;
int direction = 0;
int body = 1,
arm = 2,
leg = 3,
eye = 4;
GLfloat angle;
GLfloat left = 2.0;
GLfloat right = -2.0;
GLfloat floor_end = 100.0;
double camera[3] = {15.0, 15.0, 15.0}; /* The position of the camera */
double view[3] = {0.0, 0.0, 0.0}; /* Viewing position of the camera */
double up[3] = {0.0, 1.0, 0.0}; /* Up direction of the camera */
RGBImage *ground, *dino, *brick, *rock; /* The textures */
void init(void)
{
GLfloat mat_ambient[]={1.0,1.0,1.0,1.0};
GLfloat mat_diffuse[]={1.0,1.0,1.0,1.0};
GLfloat mat_specular[]={1.0,1.0,1.0,1.0};
GLfloat mat_shininess={100.0};
GLfloat light_ambient[]={0.0,0.0,0.0,1.0};
GLfloat light_diffuse[]={1.0,1.0,1.0,1.0};
GLfloat light_specular[]={1.0,1.0,1.0,1.0};
GLfloat light_position[]={0.0,150.0,150.0,1.0};
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GLUT_RGB);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
glClearColor(0.611764705, 0.878431372, 0.964705882, 1.0);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
#if defined(WIN32)
ground = LoadRGB("/Courses 2000/Cg/resources/texture/ground.rgb");
dino = LoadRGB("/Courses 2000/Cg/resources/texture/lez.rgb");
brick = LoadRGB("/Courses 2000/Cg/resources/texture/brick.rgb");
rock = LoadRGB("/Courses 2000/Cg/resources/texture/rock.rgb");
#else
ground = LoadRGB("../../resources/texture/ground.rgb");
dino = LoadRGB("../../resources/texture/lez.rgb");
brick = LoadRGB("../../resources/texture/brick.rgb");
rock = LoadRGB("../../resources/texture/rock.rgb");
#endif
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
MakeDino(&body, &arm, &leg, &eye);
glMatrixMode(GL_PROJECTION); /* Setup the viewing volume */
glLoadIdentity();
//glOrtho(-200.0, 200.0, -200.0, 200.0, -200.0, 200.0);
//glFrustum(-150.0, 150.0, -150.0, /*150.0 * (GLfloat) height / (GLfloat) width*/ 150.0, 0.1, 50.0);
glOrtho(-150.0, 150.0, -150.0, 150.0, -150.0, 150.0);
glMatrixMode(GL_MODELVIEW);
}
void loadTexture(RGBImage *image)
{
glTexImage2D(GL_TEXTURE_2D, 0, image->components,
image->sizeX, image->sizeY,0, image->format,
GL_UNSIGNED_BYTE, image->data);
}
void drawFloor(void)
{
loadTexture(brick);
glDisable(GL_LIGHTING);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(-floor_end, 0.0, -floor_end);
glTexCoord2f(8.0, 0.0);
glVertex3f(-floor_end, 0.0, floor_end);
glTexCoord2f(8.0, 8.0);
glVertex3f(floor_end, 0.0, floor_end);
glTexCoord2f(0.0, 8.0);
glVertex3f(floor_end, 0.0, -floor_end);
glEnd();
}
void drawBuildings(void)
{
}
void drawEnvironment(void)
{
drawFloor();
drawBuildings();
}
void drawEyes(void)
{
loadTexture(brick);
glCallList(eye);
}
void drawBody(void)
{
loadTexture(ground);
glTranslatef(0.0,0.0,-3.1);
glCallList(body);
}
void drawArms(void)
{
glTranslatef(0.0,0.0,-0.4);
glCallList(arm);
glTranslatef(0.0,0.0,-3.7);
glCallList(arm);
}
void drawLegs(void)
{
glTranslatef(0.0, 0.0, 1.7);
glCallList(leg);
glTranslatef(0.0,0.0,-4.2);
glCallList(leg);
}
void rotateDino(GLfloat rot)
{
if (angle >= 360.0)
angle -= 360.0;
else if (angle <= -360.0)
angle += 360.0;
angle += rot;
}
void moveDino(void)
{
/* Now we have to move the dino, and be sure the
* dino won't fall off the earth
*/
if (current == 0) { /* moving along the x axis */
if (direction < 0) { /* moving in the negative direction */
if (dino_pos[current] - 12.3 <= -floor_end) {
current = 2;
if (dino_pos[2] - 4.1 <= -floor_end) {
direction = 1;
rotateDino(left);
dino_pos[0] -= 8.2;
dino_pos[current] -= 12.7;
dino_pos[current] += 0.5;
} else {
direction = -1;
rotateDino(right);
dino_pos[0] -= 11.4;
dino_pos[current] += 9.0;
dino_pos[current] -= 0.5;
}
} else {
dino_pos[current] -= 0.5;
}
} else { /* direction > 0 */
if (dino_pos[current] + 12.3 >= floor_end) {
current = 2;
if (dino_pos[current] + 4.1 >= floor_end) {
direction = -1;
rotateDino(left);
dino_pos[0] += 8.2;
dino_pos[current] += 12.7;
dino_pos[current] -= 0.5;
} else {
rotateDino(right);
dino_pos[0] += 11.4;
dino_pos[current] -= 9.0;
dino_pos[current] += 0.5;
}
} else {
dino_pos[current] += 0.5;
}
}
} else { /* moving along the z axis */
if (direction < 0) {
if (dino_pos[current] - 12.3 <= -floor_end) {
current = 0;
if (dino_pos[0] + 4.1 >= floor_end) {
rotateDino(left);
dino_pos[2] -= 8.2;
dino_pos[current] += 12.7;
dino_pos[current] -= 0.5;
} else {
direction = 1;
rotateDino(right);
dino_pos[2] -= 11.4;
dino_pos[current] -= 9.0;
dino_pos[current] += 0.5;
}
} else {
dino_pos[current] -= 0.5;
}
} else { /* direction > 0 */
if (dino_pos[current] + 12.3 >= floor_end) {
current = 0;
if (dino_pos[0] - 4.1 <= -floor_end) {
rotateDino(left);
dino_pos[2] += 8.2;
dino_pos[current] -= 12.7;
dino_pos[current] += 0.5;
} else {
direction = -1;
rotateDino(right);
dino_pos[2] += 11.4;
dino_pos[current] += 9.0;
dino_pos[current] -= 0.5;
}
} else {
dino_pos[current] += 0.5;
}
}
}
}
void drawDino(void)
{
drawEyes();
drawBody();
drawArms();
drawLegs();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(camera[0], camera[1], camera[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
drawEnvironment();
if (move)
moveDino();
dino_pos[0] = 10.0;
dino_pos[2] = 15.0;
glPushMatrix();
glTranslatef(10.5, 0.0, 1.55);
glRotatef(angle, 0.0, 1.0, 0.0);
glTranslatef(-10.5, 0.0, -1.55);
glTranslatef(dino_pos[0], dino_pos[1], dino_pos[2]);
printf("[%04f], [%04f], [%04f]\n", dino_pos[0], dino_pos[1], dino_pos[2]);
drawDino();
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
}
void keyboard(unsigned char key, int posx, int posy)
{
if (tolower(key) == 'q')
exit(0);
if (key == '8')
move = GL_TRUE;
else if (key == '4')
rotateDino(left);
else if (key == '6')
rotateDino(right);
else if (key == '2')
move = GL_FALSE;
}
void passiveMouse(int posx, int posy)
{
}
void idle(void)
{
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(750, 750);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutPassiveMotionFunc(passiveMouse);
glutMainLoop();
return 0;
IMPORTANT NOTE: I think you must load identity after calling glPushMatrix in the function display().
Well, I understood from your program that MakeDino initializes some display lists that help in rebdering the whole dino. Now, these display lists contains primitives you loaded somewhere, and these primitives have coordinates. These coordinates are in respect to some origin other than between-the-legs. Now, you must recalculate these coordinates so that they are in respect to the between-the-legs point and use the code I mentioned before.
If I do that, the whole dino won't even show up!
If you do what? Did you try to recalculate the coordinates of the dino'sprimitives so that they became in respect to the between-the-legs point. If you do so you won't need to write:
glTranslatef(10.5, 0.0, 1.55)
and
glTranslatef(-10.5, 0.0, -1.55)
GA
Let's see if I understand your problem correctly... The origin of your dinosaur is positined on the tail. You want it to rotate around the legs. Try something like this... Assume the following variables...
(X1, Y1, Z1) = world position you want to place the dinosaur
A = angle to rotate the dino
(X2, Y2, Z2) = Offset from the tail to the point between the legs.
Assuming those variables this SHOULD work.
glTranslatef(X1, Y1, Z1);
glRotatef(A, 0.0, 1.0, 0.0);
glTranslatef(X2, Y2, Z2);
The way matrix math works, you effectively do the last call first. (It's one way of looking at it anyway.) That means the above code will first position your dino so that his feet are at the origin. The dino will be turned to the orientation you want, then the dino will be placed at the appropriate world position. Note that with this, the point between the feet is what will be positioned. If you want to position based on the tail again, just add the X2, Y2, Z2 offsets to that first glTranslate.
Also.. it might just be easier to change the vertex data for your dino so that the origin is where you want, rather than the tail.
Deiussum
Software Engineer and OpenGL enthusiast
Thanx Deiussum!!
This works perfectly![]()
No problem. Glad I could help.![]()
Deiussum
Software Engineer and OpenGL enthusiast