PDA

View Full Version : 3d world navigation help



12-30-2000, 07:59 AM
Can anybody help me with this 3d world navigation problem. I have a 3d world made by the display function:

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ; /* clear the window */

glLoadIdentity() ;

glRotatef(-theta,0,1,0);
glRotatef(-theta2,1,0,0);
glTranslatef(-xpos,-ypos,-zpos);
for(j=0;j < obj;j++)
{
glPushMatrix();
}

for(i=0;i < obj;i++)
{
glPopMatrix();
glTranslatef(array[i][3],((array[i][0] / 50)-1) * 50,array[i][4]);
glScalef(array[i][1] / 50,array[i][0] / 50,array[i][2] / 50);
glTranslatef(0,0,0);
box();
}

glFlush() ;
glutSwapBuffers() ;
}

which gets all the objects and there parameters from an array and then builds a box with hese parameters.
I have the keyboard function :

void keyboardarrow(int key, int x, int y)
{
float xinc,zinc;

if (key == GLUT_KEY_LEFT)
theta = theta + 3 ;
if (key == GLUT_KEY_RIGHT)
theta = theta - 3 ;

if (key == GLUT_KEY_UP)
{
xinc = -sin((6.28/360)*theta)* step ;
zinc = -cos((6.28/360)*theta)* step;

xpos = xpos + xinc;
zpos = zpos + zinc;
}

if (key == GLUT_KEY_DOWN)
{

xinc = -sin((6.28/360)*theta)* step ;
zinc = -cos((6.28/360)*theta)* step;

xpos = xpos - xinc;
zpos = zpos - zinc;
}
display() ;
}

and now I need to make it so the user can ‘fly’ through the world. I.e they press an up or down key to chose the angle of flight and then when forward or back arrow key is pressed they move in this direction. I cant seem to get this to work anybody help???

-kebabinho

12-30-2000, 08:20 AM
If you are using GLUT (at least this way) for your input will the program not run smoothly.
The best is in my opinion to use DirectInput but if you must use GLUT so take a look here: http://www.fatech.com/tech/opengl/glut/

The red book page 85 shows you how to implement the pilot view.

12-31-2000, 05:37 AM
have to use GLUT as its part of my uni course and that is what they use. This code works perfectly well but i need to know the calculations to change xinc and zinc if i move up the y axis. have got the calculations for zinc whihc i will post later but not for the xinc. with my new code it all works if i look down the z-axis but if i then rotate left or right it goes horribly wrong.
anybody help here??

-kebabinho

Deiussum
01-01-2001, 09:08 AM
I don't quite understand part of your code... maybe you didn't post the whole thing, but this part here looks kind of suspicious to me.




for(j=0;j < obj;j++)
{
glPushMatrix();
}

for(i=0;i < obj;i++)
{
glPopMatrix();
glTranslatef(array[i][3],((array[i][0] / 50)-1) * 50,array[i][4]);
glScalef(array[i][1] / 50,array[i][0] / 50,array[i][2] / 50);
glTranslatef(0,0,0);
box();
}


You are pushing the matrix "obj" number of times, and then popping it right away before doing your transformations.

I can see how this could work to a certain extent, but to me it would be more intuitive to just do this.




for(i=0;i < obj;i++)
{
glPushMatrix();
glTranslatef(array[i][3],((array[i][0] / 50)-1) * 50,array[i][4]);
glScalef(array[i][1] / 50,array[i][0] / 50,array[i][2] / 50);
glTranslatef(0,0,0);
box();
glPopMatrix();
}


The way you are doing it, you are pushing at least 1 matrix and popping it right away without making any changes. The state of your matrix will also remain at whatever your final transformations were.

Another problem is that if your number of objects exceeds the maximum stack size of your model-view matrix, you will overflow the stack.

01-01-2001, 11:09 AM
basically i have an array at the top of my code and this holds the parameters for all my boxes. this code then reads each line of the array and draws the box to the required parameters. as i am translating things for the origin each time i am using pushmatrix etc. suppose i could of used glLoadidentity but got told this was wrong by lecturer.

all this code works though as i say. the only thing i need to know is the correct calculations for the forward and back. ie sin(theta) or whatever cause my equations only fork for forward,back, left and right and i need it to go up and down too.
any help?

kebabinho

Deiussum
01-01-2001, 04:50 PM
If you do as I suggested and do:

// Assume it is currently the identity matrix
PushMatrix
transformations
PopMatrix
// it will be the identity matrix again now here.

It should still work and you won't risk pushing too much on the stack. OpenGL only guarantees a stack depth of 16 for the modelview matrix, so using your way if you go over 16, you may overflow the stack.

Anyway, for movement you can take the vector for the orientation, scale it as necessary, add that to the current position. For instance if you have a vector of the direction that the "front" of the cube is facing you just do something like this..

cubePos.x += forwardVec.x;
cubePos.y += forwardVec.y;
cubePos.z += forwardVec.z;

For going backwards, just subtract. For up/down, do the same thing only use the "up" vector of the cube.

01-02-2001, 08:53 AM
thanks for tip about the stakc only taking 16 was not taught this and it may come in handy when i add more objects to my world.
about the second bit the problemis that i dont know what the forwardvec is.well for x and z i do its -sin((6.28/360)*theta)*step and -cos((6.28/360)*theta)*step respectively. now i want to add up and dwon movement i.e y and i dont know what the forward vec is for the ypos.
have a version done that sort of works whihc i will add to this thread later when the computer it is on finally connects to the internet again. cheers for the help

-kebabinho

01-03-2001, 05:29 AM
Think i have it now with the stuff below. the two if statements at the top of the display fucniton are for mouse control so dont worry about them

void display(void)
{


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ; /* clear the window */

glLoadIdentity() ;
if(m1 == 1)
{
xinc1 = -sin((6.28/360)*theta)* step ;
yinc1 = -sin((6.28/360)*theta2)* step ;
zinc1 = -cos((6.28/360)*theta)* step + (-sin((6.28/360)*theta2)* step);

xpos = xpos + xinc1;
ypos = ypos - yinc1;
zpos = zpos + zinc1;
}

if(m2 == 1)
{
xinc1 = -sin((6.28/360)*theta)* step ;
yinc1 = -sin((6.28/360)*theta2)* step ;
zinc1 = -cos((6.28/360)*theta)* step + (-sin((6.28/360)*theta2)* step);

xpos = xpos - xinc1;
ypos = ypos + yinc1;
zpos = zpos - zinc1;
}

glRotatef(-theta,0,1,0);
glRotatef(-theta2,1,0,0);
glTranslatef(-xpos,-ypos,-zpos);
for(j=0;j < obj;j++)
{
glPushMatrix();
}

for(i=0;i < obj;i++)
{
glPopMatrix();
glTranslatef(array[i][3],((array[i][0] / 50)-1) * 50,array[i][4]);
glScalef(array[i][1] / 50,array[i][0] / 50,array[i][2] / 50);
glTranslatef(0,0,0);
box();
}

glFlush() ;
glutSwapBuffers() ;
}

void keyboardarrow(int key, int x, int y)
{
float xinc,yinc,zinc;

if (key == GLUT_KEY_LEFT)
theta = theta + 3 ;
if (key == GLUT_KEY_RIGHT)
theta = theta - 3 ;

if (key == GLUT_KEY_UP)
{
xinc = -sin((6.28/360)*theta)* step ;
yinc = -sin((6.28/360)*theta2)* step ;
zinc = -cos((6.28/360)*theta)* step + (-sin((6.28/360)*theta2)* step);

xpos = xpos + xinc;
ypos = ypos - yinc;
zpos = zpos + zinc;
}

if (key == GLUT_KEY_DOWN)
{

xinc = -sin((6.28/360)*theta)* step ;
yinc = -sin((6.28/360)*theta2)* step ;
zinc = -cos((6.28/360)*theta)* step + (-sin((6.28/360)*theta2)* step);

xpos = xpos - xinc;
ypos = ypos + yinc;
zpos = zpos - zinc;
}
display() ;
}

void keyboard(unsigned char key, int x, int y)
{

if (key == 'u')
theta2 = theta2 + 3;
if (key == 'd')
theta2 = theta2 - 3;
}

if it is wrong (it does act abit wierd sometimes) can anybody tell me why?

-kebabinho