Rotating towers

Started by
36 comments, last by HelderBorges 13 years ago
Hi guys. I´m studying computer engineering and i have to make a little game.

In the game, i need to have towers and a character.

I need the towers to face and focus the player, wen he enters their range zone.

i keep track of the position of the tower (i use post[3]) and the position of the player(i use posb[3]) with an array wish post[0] is the x coordinate the post[1] the y and the post[2] the z .
i use the function (sqrt(pow(a[0]-b[0],2)+pow(a[2]-b[2],2))) to calculate the distance between the 2 points, and if it is lower than the range, the tower needs to turn..... and that is my problem. I dont know how to face the tower to the player. I already tried some function, but i cant calculate that. :S

Can someone help plz????i will order you a pizza :D lol.

I´m using vs with c++. ty guys
Advertisement
There's a few different ways you can orient the tower. One would be to build an orthonormal basis from the normalized direction from the tower position to the player position. Another method (which might be a little more immediately intuitive) is to use atan2() to compute an angle of rotation for the tower that will align it as desired, e.g. (untested):

y_angle = atan2(posb[2] - post[2], posb[0] - post[0]);
Depending on the conventions you're using, you may need to swap and/or negate the arguments to atan2(), or modify the angle that it returns.
Slightly off topic: I have bad experience with pow in c++. Multiplying the number with itself &&/|| creating your own pow function seems faster.

There's a few different ways you can orient the tower. One would be to build an orthonormal basis from the normalized direction from the tower position to the player position. Another method (which might be a little more immediately intuitive) is to use atan2() to compute an angle of rotation for the tower that will align it as desired, e.g. (untested):

y_angle = atan2(posb[2] - post[2], posb[0] - post[0]);
Depending on the conventions you're using, you may need to swap and/or negate the arguments to atan2(), or modify the angle that it returns.


Only 1 question. What is atan2()?
tried your tip(the coded one :P) but it dont work, i´m so pissed, cause i need to deliver the work in the next 2 days, and this is the only think not working xD

first i tried to use the product between 2 vectors doing rotatef(post[0]*posb[0]+post[1]*posb[1]+post[2]*posb[2],0,1,0);
then i tried to swap the angle argument for your atan2() function but it still dont work :\.I googled a lot already, but i think this forum is my last hope :\
"still don't work"

Could you be more specific? What are you using? OpenGL? Maybe the order of transformations are wrong
Could you show all the code?
Are you #including <cmath> ? And using atn2 from the std -namespace?

"still don't work"

Could you be more specific? What are you using? OpenGL? Maybe the order of transformations are wrong
Could you show all the code?


Sory for the English :\.

I will try.


My tower is done with this:



void drawTorre(float m,float rtorre,float n){


glColor3f(1.0f, 2.0f, 0.0f);

glPushMatrix();


glTranslatef(0, coiso*distancia*escala,-10); //initial position of the tower
post[0]=0;
post[1]=coiso*distancia*escala;
post[2]=-10;
float d =calculardistancia(post,posb); //Calculate the distance between the tower and the object

if(d<=5) // compare if it is at the desired range
{

glRotatef(atan2(posb[0]-post[0],posb[2]-post[2]),0,1,0); //rotate the tower to the object

}

for(int i=0;i<ndonuts;i++){ ///draw the base of the tower
glPushMatrix();
glRotatef(90,1*escala,0,0);
glutWireTorus(raiointrior,raioexterior,numlados,aneis);
glPopMatrix();
glTranslatef(0, coiso*distancia*escala, 0);
}

//Bule de chá // draw the top of the tower
glTranslatef(0, coiso*distancia*escala-0.2, 0);
glRotatef(ang,m,rtorre,n);
glRotatef(-45,0,0,1*escala);//Incliar bool
glColor3f(0.0f, 1.0f, 0.0f);
glutSolidTeapot(tamanhobule); //Cria bule
glPopMatrix();



}




and my test object till now is



void drawTriangolo(){


glTranslatef(x,y,z); // move o objecto // move the object with the keys
posb[0]=x; //store position of x
posb[1]=y;//store position of y
posb[2]=z;//store position of z
// ângulo em graus
glRotatef(ang2,f,g,h); //ignore
glRotatef(ang3,t,u,v); //ignore
glPushMatrix();
glBegin(GL_TRIANGLES);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
glPopMatrix();
}




ad this is the function that calc the distance




float calculardistancia(float *a,float*b){



return (sqrt(pow(a[0]-b[0],2)+pow(a[2]-b[2],2)));


}




i want the tower to always be turned to the object (the triangle for now) since he get in the range, and until he get out of the range.:\


I´m using Opengl on visual studio 2010 and with c++

Are you #including <cmath> ? And using atn2 from the std -namespace?


Nope, i never used atn2, so i didnt know that i needed other library beside cmath :\ and i´m using opengl

[quote name='SuperVGA' timestamp='1302693743' post='4797900']
Are you #including <cmath> ? And using atn2 from the std -namespace?


Nope, i never used atn2, so i didnt know that i needed other library beside cmath :\ and i´m using opengl
[/quote]

Well, if you do use cmath, you would have #include <cmath> in the top of your code that uses atn2,
and either a using namespace std below that, or std::tan2 where you make your tan2 - invocation.

Hope this will solve your problem! :)
Ty all, but still not working :\
my complete code is





#include <glut.h>
#include <cmath>
#include <math.h>




float x=0,y=0,z=0;
float m=0,rtorre=0,n=0;
float f=0,g=0,h=0;
float t=0,u=0,v=0;

float q=1;

float ang=0;
float ang2=0;
float ang3=0;

GLenum modo=GL_FILL;

float post[3];//posicao da torre
float posb[3]={0,0,0};//posicao do boneco
float rtb[3]; // raio para rodar
float dist=100; //distancia da torre ao boneco
float coiso =1;
float distancia=0.6;
float escala=0.6;
float tamanhobule=1*escala;
float raiointrior=0.4*escala;
float raioexterior=0.6*escala;
int numlados=200*escala;
int aneis=100*escala;
int ndonuts=3;//número de dónuts

void changeSize(int w, int h) {

// Prevent a divide by zero, when window is too short
// (you cant make a window with zero width).
if(h == 0)
h = 1;

// compute window's aspect ratio
float ratio = w * 1.0 / h;

// Set the projection matrix as current
glMatrixMode(GL_PROJECTION);
// Load Identity Matrix
glLoadIdentity();

// Set the viewport to be the entire window
glViewport(0, 0, w, h);

// Set perspective
gluPerspective(45.0f ,ratio, 0.1f ,1000.0f);

// return to the model view matrix mode
glMatrixMode(GL_MODELVIEW);
}

float calculardistancia(float *a,float*b){



return (sqrt(pow(a[0]-b[0],2)+pow(a[2]-b[2],2)));


}




void drawTriangolo(){


glTranslatef(x,y,z); // move o objecto
posb[0]=x;
posb[1]=y;
posb[2]=z;
// ângulo em graus
glRotatef(ang2,f,g,h);
glRotatef(ang3,t,u,v);
glPushMatrix();
glBegin(GL_TRIANGLES);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
glPopMatrix();
}


void drawTorre(float m,float rtorre,float n){

using namespace std;
glColor3f(1.0f, 2.0f, 0.0f);

glPushMatrix();


glTranslatef(0, coiso*distancia*escala,-10);
post[0]=0;
post[1]=coiso*distancia*escala;
post[2]=-10;
float d =calculardistancia(post,posb);

if(d<=5)
{

glRotatef(atan2(posb[2]-post[2],posb[0]-post[0]),0,1,0);

}

for(int i=0;i<ndonuts;i++){
glPushMatrix();
glRotatef(90,1*escala,0,0);
glutWireTorus(raiointrior,raioexterior,numlados,aneis);
glPopMatrix();
glTranslatef(0, coiso*distancia*escala, 0);
}

//Bule de chá
glTranslatef(0, coiso*distancia*escala-0.2, 0);
glRotatef(ang,m,rtorre,n);
glRotatef(-45,0,0,1*escala);//Incliar bool
glColor3f(0.0f, 1.0f, 0.0f);
glutSolidTeapot(tamanhobule); //Cria bule
glPopMatrix();



}


void drawScene() {

drawTorre(m,rtorre,n);
drawTriangolo();

}




void renderScene(void) {



// clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// set the camera
glLoadIdentity();
gluLookAt(0.0,0.0,5.0,
0.0,0.0,-1.0,
0.0f,1.0f,0.0f);

drawScene();



// End of frame
glutSwapBuffers();
}



// escrever função de processamento do teclado

void teclado(unsigned char tecla, int a, int b){
switch (tecla){
case 'w': z+=0.1;
break;
case 's': z-=0.1;
break;
case 'a': x-=0.1;
break;
case 'd': x+=0.1;
break;

case 'i': ang+=5;rtorre=1;m=0;
break;
case 'k': ang-=5;rtorre=1;m=0;
break;
case 'j': ang2+=5;f=0;g=1;
break;
case 'l': ang2-=5;f=0;g=1;
break;

case 'o': ang3+=5;t=0;u=0;v=1;
break;
case 'p': ang3-=5;t=0;u=0;v=1;
break;

case 'r': q+=0.1;
break;
case 't': q-=0.1;
break;

}
glutPostRedisplay();
}



// escrever função de processamento do menu

void menu(int id_op){

switch(id_op){
case 1 : modo=GL_FILL;
break;
case 2 : modo=GL_LINE;
break;
case 3: modo=GL_POINT;
break;
}
glutPostRedisplay();

}




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

// pôr inicialização aqui

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,800);
glutCreateWindow("CG@DI");


// pôr registo de funções aqui

glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);

// pôr aqui registo da funções do teclado e rato
glutKeyboardFunc(teclado);

// pôr aqui a criação do menu

glutCreateMenu(menu);
glutAddMenuEntry("Vermelho",1);
glutAddMenuEntry("Vermelho1",2);
glutAddMenuEntry("Vermelho2",3);
glutAttachMenu(GLUT_RIGHT_BUTTON);


// alguns settings para OpenGL
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);

// entrar no ciclo do GLUT aqui
glutMainLoop();
}







The only think that i want to be working is the damn tower facing for the object.
:| i´m beginning to panic xD

This topic is closed to new replies.

Advertisement