Sign in to follow this  
MonkeyDluffy

OpenGL Getting an object to 'orbit' another object

Recommended Posts

I have 2 crates, both rotating about their origin, but I want the second crate to rotate about the first crates origin to 'orbit' it... how would I go about doing this?

[code]
/*-------------------------------------Defininitions----------------------------------------
-------------------------------------------------------------------------------------------*/

float _angle = 0; //The angle of the cube
GLuint _textureId; //The OpenGL ID of the texture
GLuint _textureId2; //The OpenGL ID of the second texture
int level = 1; //The level the player is on
bool helpMenu = true; //Display the help menu during the game? Can be turned on/off during gameplay

struct point3D { //Create the structure for a 3D point which uses the width(x), height(y), and depth(z)
float x, y, z;
};

struct camera{ //Create the structure for a camera which has an (x,y,z) position, an (x,y,z) position of where it is looking, and which way 'up' is
point3D pos, lookAt, up;
};

camera cam = {0, 0, 56.5, 0, 0, 0, 0, 1, 0}; //Create the camera using the above structure(s)

void handleKeypress(unsigned char Key, int x, int y); //Handles all keypresses from the keyboard
void initRendering(); //Loads the texture to be displayed from the texture ID
GLuint loadTexture(Image* image); //Turns the loaded image into a texture, and returns the Texture ID
void handleResize(int w, int h); //Handles decisions for when the window is resized
void drawTexturedCube(int BOX_SIZE); //Draws a textured cube, of boxSize width and height
void drawLevels(); //Draws the scenes for each level
void update(int value); //Updates the game screen
int main(int argc, char** argv);

/*----------------------------------------Methods-------------------------------------------
-------------------------------------------------------------------------------------------*/

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key closes the game
exit(0);
case 32: //Space bar resets the camera coordinates
cam.pos.x = 0;
cam.pos.y = 0;
cam.pos.z = 56.5;
cam.lookAt.x = 0;
cam.lookAt.y = 0;
cam.lookAt.z = 0;
cam.up.x = 0;
cam.up.y = 1;
cam.up.z = 0;
break;
case 97: //'a' key move the camera -0.5 along the x-axis
cam.pos.x -= 0.5;
break;
case 100: //'d' key moves the camera +0.5 along the x-axis
cam.pos.x += 0.5;
break;
case 104: //'h' key turns the help menu on/off
if (helpMenu == true)
helpMenu = false;
else
helpMenu = true;
break;
case 115: //'s' key moves the camera -0.5 along the y-axis
cam.pos.y -= 0.5;
break;
case 119: //'w' key moves the camera +0.5 along the y-axis
cam.pos.y += 0.5;
break;
case 120: //'x' key moves the camera -0.5 along the z-axis
cam.pos.z -= 0.5;
break;
case 122: //'z' key moves the camera +0.5 along the z-axis
cam.pos.z += 0.5;
break;
}
}

GLuint loadTexture(Image* image) {
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
image->width, image->height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
image->pixels);
return textureId;
}

void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);

Image* image = loadBMP("Crate_Sides.bmp");
Image* image2 = loadBMP("Crate_Top.bmp");
_textureId = loadTexture(image);
_textureId2 = loadTexture(image2);
delete image;
}

void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);
}

void drawTexturedCube(int cubeSize){

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);

//Top face

glNormal3f(0.0, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-cubeSize / 2, cubeSize / 2, -cubeSize / 2);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-cubeSize / 2, cubeSize / 2, cubeSize / 2);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(cubeSize / 2, cubeSize / 2, cubeSize / 2);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(cubeSize / 2, cubeSize / 2, -cubeSize / 2);
glEnd();

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);

//Bottom face

glNormal3f(0.0, -1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-cubeSize / 2, -cubeSize / 2, -cubeSize / 2);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(cubeSize / 2, -cubeSize / 2, -cubeSize / 2);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(cubeSize / 2, -cubeSize / 2, cubeSize / 2);
glTexCoord2f(0.0f, 01.0f);
glVertex3f(-cubeSize / 2, -cubeSize / 2, cubeSize / 2);

//Left face

glNormal3f(-1.0, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-cubeSize / 2, -cubeSize / 2, -cubeSize / 2);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-cubeSize / 2, -cubeSize / 2, cubeSize / 2);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-cubeSize / 2, cubeSize / 2, cubeSize / 2);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-cubeSize / 2, cubeSize / 2, -cubeSize / 2);

//Right face

glNormal3f(1.0, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(cubeSize / 2, -cubeSize / 2, -cubeSize / 2);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(cubeSize / 2, cubeSize / 2, -cubeSize / 2);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(cubeSize / 2, cubeSize / 2, cubeSize / 2);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(cubeSize / 2, -cubeSize / 2, cubeSize / 2);

//Front face

glNormal3f(0.0, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-cubeSize / 2, -cubeSize / 2, cubeSize / 2);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(cubeSize / 2, -cubeSize / 2, cubeSize / 2);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(cubeSize / 2, cubeSize / 2, cubeSize / 2);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-cubeSize / 2, cubeSize / 2, cubeSize / 2);

//Back face

glNormal3f(0.0, 0.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-cubeSize / 2, -cubeSize / 2, -cubeSize / 2);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-cubeSize / 2, cubeSize / 2, -cubeSize / 2);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(cubeSize / 2, cubeSize / 2, -cubeSize / 2);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(cubeSize / 2, -cubeSize / 2, -cubeSize / 2);

glEnd();
glDisable(GL_TEXTURE_2D);
}


void drawLevels() {

switch (level) {
case 1:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
cam.lookAt.x, cam.lookAt.y, cam.lookAt.z,
cam.up.x, cam.up.y, cam.up.z);
glEnd();

glPushMatrix();
glTranslatef(0.0f, 0.0f, -30.0f);
glRotatef(_angle, 1.0f, 1.0f, 0.0f);

drawTexturedCube(7);
glPopMatrix();

glPushMatrix();
glTranslatef(15.0f, 0.0f, -30.0f);
glRotatef((_angle*2), 0.0f, 1.0f, 0.0f);
drawTexturedCube(6);
glPopMatrix();

glutSwapBuffers();
}
}

void update(int value) {
_angle += 1.0f; //Increase the angle of the cube by 1
if (_angle > 360) {
_angle -= 360; //If the angle of the cube is over 360 (A full rotation), set the angle back to 0
}
glutPostRedisplay(); //Redisplay the cube
glutTimerFunc(25, update, 0); //Called every 25 milliseconds
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);

glutCreateWindow("Game of Cubes");

initRendering();

glutDisplayFunc(drawLevels);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0);

glutMainLoop();
return 0;
}
[/code]

Also, how would I go about getting the camera to rotate around the scene instead of just moving left/right/up/down...?

Thank you very much!

Share this post


Link to post
Share on other sites
EDIT: Managed to get them rotating just by [color=#333333][background=rgb(249, 249, 249)]swapping the order of glTranslate and glRotate.... but is there now any way to [/background][/color][color=#333333][background=rgb(249, 249, 249)]get an object to rotate one of the objects rotating? (Like the Moon>Earth>Sun as it were)?[/background][/color]

Share this post


Link to post
Share on other sites
I made very basic scenegraph for that. I basically have a node class that consists of the model and all its transforms and such. The class looks like this:

[CODE]
class Model;
class Node
{
public:
Node();
Node(Model* a_Model);
~Node();
void Render();
Node* AddChild(String a_FileName, String a_Name);
const float3& GetPosition() const {return m_Position;}
const float4& GetOrientation() const {return m_Orientation;}
const float3& GetScale() const {return m_Scale;}
void SetPosition(const float3& a_Position) {m_Position = a_Position;}
void SetOrientation(const float4& a_Orientation) {m_Orientation = a_Orientation;}
void SetScale(const float3& a_Scale) {m_Scale = a_Scale;}
protected:
float3 m_Position;
float4 m_Orientation;
float3 m_Scale;
Model* m_Model;
Node* m_Parent;
std::vector<Node*> m_Child;
};
[/CODE]

And when I add a new node as a child, I just push it back into the m_Child vector. Then I render it as following:

[CODE]
void Rld::Node::Render()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(m_Position.x, m_Position.y, m_Position.z);
glRotatef(m_Orientation.w, m_Orientation.x, m_Orientation.y, m_Orientation.z);
glScalef(m_Scale.x, m_Scale.y, m_Scale.z);

if(m_Model != NULL)
m_Model->Render();
for(unsigned int i = 0; i < m_Child.size(); ++i)
m_Child[i]->Render();
if(m_Child.size() == 0)
glPopMatrix();
}
[/CODE]

Perhaps not the most elegant solution and this is done with deprecated stuff, but for the sake of simplicity.. I works

Share this post


Link to post
Share on other sites
In [u]Game Engine Architecture[/u] the author mentions he had a similar problem of trying to get one object to orbit another. I think his solution was to do the orbit in polar coordinates then transform the vertices to the Cartesian system every frame.

Share this post


Link to post
Share on other sites
You have to apply most local orbits first. If you have sun earth moon. To calculate the moon:

Apply translation from Earth.
Apply rotation about Earth.
Translate using Earths translation from Sun.
Rotate using Earths rotation from Sun.
Translate to Suns position.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this