Sign in to follow this  

How to rotate a 3D Object by modifying it's vertex coordinates

This topic is 1270 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Everyone, 

I would like to understand how to rotate a 3D Object around it's Center, by modifying it's Vertex Coordinates.

Not by using glRotatef...

The reason is that I need to keep track of the new coordinates because of my collision system, which is based on Vertex Coords.


Here is the Code for an Object Thanks Guys!

void DrawHouse(GLfloat x1, GLfloat x2, GLfloat y1, GLfloat y2, GLfloat z1,GLfloat z2, GLfloat u1, GLfloat u2, GLfloat v1, GLfloat v2, GLuint textid)
{

glBindTexture(GL_TEXTURE_2D, textid);

glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(u1,v1); glVertex3f(x1,y1,z2);
glTexCoord2f(u2,v1); glVertex3f(x2,y1,z2);
glTexCoord2f(u2,v2); glVertex3f(x2,y2,z2);
glEnd();

glBindTexture(GL_TEXTURE_2D, textid);

glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(u2,v2); glVertex3f(x2,y2,z2);
glTexCoord2f(u1,v2); glVertex3f(x1,y2,z2);
glTexCoord2f(u1,v1); glVertex3f(x1,y1,z2);
glEnd();

glBindTexture(GL_TEXTURE_2D, textid);

glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(u1,v1); glVertex3f(x1,y1,z1);
glTexCoord2f(u2,v1); glVertex3f(x2,y1,z1);
glTexCoord2f(u2,v2); glVertex3f(x2,y2,z1);
glEnd();

glBindTexture(GL_TEXTURE_2D, textid);

glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(u2,v2); glVertex3f(x2,y2,z1);
glTexCoord2f(u1,v2); glVertex3f(x1,y2,z1);
glTexCoord2f(u1,v1); glVertex3f(x1,y1,z1);
glEnd();

glBindTexture(GL_TEXTURE_2D, textid);

glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(u1,v1); glVertex3f(x2,y1,z2);
glTexCoord2f(u2,v1); glVertex3f(x2,y1,z1);
glTexCoord2f(u2,v2); glVertex3f(x2,y2,z1);
glEnd();

glBindTexture(GL_TEXTURE_2D, textid);

glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(u2,v2); glVertex3f(x2,y2,z1);
glTexCoord2f(u1,v2); glVertex3f(x2,y2,z2);
glTexCoord2f(u1,v1); glVertex3f(x2,y1,z2);
glEnd();

glBindTexture(GL_TEXTURE_2D, textid);

glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(u1,v1); glVertex3f(x1,y1,z2);
glTexCoord2f(u2,v1); glVertex3f(x1,y1,z1);
glTexCoord2f(u2,v2); glVertex3f(x1,y2,z1);
glEnd();

glBindTexture(GL_TEXTURE_2D, textid);

glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(u2,v2); glVertex3f(x1,y2,z1);
glTexCoord2f(u1,v2); glVertex3f(x1,y2,z2);
glTexCoord2f(u1,v1); glVertex3f(x1,y1,z2);
glEnd();

//COLLISION WITH CHARACTER
if(xtrans <= -(x1-0.2) && xtrans >= -(x2+0.2) && ztrans <= -(z1-0.2) && ztrans >= -(z2+0.2))
{

if(MoveForward)
{
xpos += 2*(float)sin(heading*piover180) * 0.0005f;
zpos += 2*(float)cos(heading*piover180) * 0.0005f;
}

if(MoveBackward)
{
xpos -= 2*(float)sin(heading*piover180) * 0.0005f;
zpos -= 2*(float)cos(heading*piover180) * 0.0005f;
}

}

DrawDoor(x2, x2 + 0.1, 0.0 , 0.5, z2 - (z2-z1)/2 + 0.25, z2 - (z2-z1)/2 - 0.25, 0.0, 1.0, 0.0, 1.0, texture[1], texture[3]);


}

Share this post


Link to post
Share on other sites

I wont go into detail but you need to read up on matrix vector math. Once you can build a rotation matrix (or quaternion), you would use it to rotate each of your vertices. This is what glrotate would be doing for you. So you would build a rotation matrix, apply it to your x1y1z1 and x2y2z2 and draw as normal, but without calling glrotate.

Share this post


Link to post
Share on other sites

heres an example code:

 

VBO_V is an array of vertices.

void __fastcall TachoGLModel::RotateModel(int dimension, float angle)
{

int i;

t3dpoint p,addme;

for (i = 0; i < VBO_V.Length; i++) {
		  p = vectors_add(VBO_V[i], reverse_point(CENTER_POINT));    //move center of a poly to 0,0,0

				   addme = CENTER_POINT;
		   if (dimension == 0) { //XZ
		   addme.y = 0.0f;
VBO_V[i].x = cos(angle*imopi)*p.x - sin(angle*imopi)*p.z;
VBO_V[i].z = sin(angle*imopi)*p.x + cos(angle*imopi)*p.z;
		   }

		   if (dimension == 1) { //XY
		   addme.z = 0.0f;
VBO_V[i].x = cos(angle*imopi)*p.x - sin(angle*imopi)*p.y;
VBO_V[i].y = sin(angle*imopi)*p.x + cos(angle*imopi)*p.y;
		   }

		   if (dimension == 2) { //ZY
		   addme.x = 0.0f;
VBO_V[i].z = cos(angle*imopi)*p.z - sin(angle*imopi)*p.y;
VBO_V[i].y = sin(angle*imopi)*p.z + cos(angle*imopi)*p.y;
		   }

VBO_V[i] = vectors_add(VBO_V[i],addme);                         //restore old position

}

}


calculation of a center point



void __fastcall TachoGLModel::CalcCenterPoint()
{
	CENTER_POINT.x = 0.0;
		CENTER_POINT.y = 0.0;
			CENTER_POINT.z = 0.0;
int i;
for (i = 0; i < VBO_V.Length; i++) {
	CENTER_POINT.x = CENTER_POINT.x + VBO_V[i].x;
		CENTER_POINT.y = CENTER_POINT.y + VBO_V[i].y;
			CENTER_POINT.z = CENTER_POINT.z + VBO_V[i].z;
}

CENTER_POINT = vector_multiple(CENTER_POINT,1.0f / float(VBO_V.Length));

}

there are many ways to rotate.

Share this post


Link to post
Share on other sites

void rotatePoint( float* x, float* y, float* z, float xRotation, float yRotation )
{

    float sinPitch = sinf( xRotation );
    float cosPitch = cosf( xRotation );
    float sinYaw = sinf( yRotation );
    float cosYaw = cosf( yRotation );

    float sinPitch_y = sinPitch * *y;
    float cosPitch_z = cosPitch * *z;

    *x = cosYaw * *x + sinYaw * sinPitch_y - sinYaw * cosPitch_z;
    *y = cosPitch * *y + sinPitch * z;
    *z = sinYaw * *x + -sinPitch_y * cosYaw + cosYaw * cosPitch_z;

}

// ...

float x1, y1, z1, x2, y2, z2, u1, u2, v1, v2, textid;

// x1 = ..., y1 = ..., z1 = ...
// x2 = ..., y2 = ..., z2 = ...

rotatePoint( &x1, &y1, &z1, xRotation1, yRotation1 );
rotatePoint( &x2, &y2, &z2, xRotation2, yRotation2 );

DrawHouse( x1, x2, y1, y2, z1, z2, u1,  u2,  v1, v2, textid );

Rendering and collision systems can be related, but are still different.

 

What kind of collision system are you using?

 

It's possible (and I'm guessing probable - partially based on observation of your code) that you could be going about it in a less-than-optimal fashion - meaning, direct vertex manipulation probably shouldn't be necessary.

Edited by 3TATUK2

Share this post


Link to post
Share on other sites

Hi Everyone and Thank you for your replies.

 

 

It's not really working the way I would like it to.

 

I need to rotate these objects around their center, and its not doing that.

 

This is mosstly for Buildings. 

 

I need to run some tests with the formulas to make it work.

 

 

Thanks a lot though it's giving me a nice direction to start with.

 

 

Thank you so much.

Share this post


Link to post
Share on other sites

Mm... my rotatePoint will probably work, assuming the centerpoint is origin (0,0,0), so you can temporarily readjust for that, try something like this maybe..

void rotatePoint( float* x, float* y, float* z, float xRotation, float yRotation, float centerX, float centerY, float centerZ )
{
	*x -= centerX;
	*y -= centerY;
	*z -= centerZ;

	float sinPitch = sinf( xRotation );
	float cosPitch = cosf( xRotation );
	float sinYaw = sinf( yRotation );
	float cosYaw = cosf( yRotation );

	float sinPitch_y = sinPitch * *y;
	float cosPitch_z = cosPitch * *z;

	*x = cosYaw * *x + sinYaw * sinPitch_y - sinYaw * cosPitch_z;
	*y = cosPitch * *y + sinPitch * z;
	*z = sinYaw * *x + -sinPitch_y * cosYaw + cosYaw * cosPitch_z;

	*x += centerX;
	*y += centerY;
	*z += centerZ;
}

Share this post


Link to post
Share on other sites

Ok I figured it out:

 

 

void CNPC::Draw()
{
 
glBindTexture(GL_TEXTURE_2D, m_textid);
 
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(m_u1,m_v1); glVertex3f(m_xa1,m_y1,m_za1);
glTexCoord2f(m_u2,m_v1); glVertex3f(m_xa1,m_y2,m_za1);
glTexCoord2f(m_u2,m_v2); glVertex3f(m_xa2,m_y2,m_za2);
glTexCoord2f(m_u1,m_v1); glVertex3f(m_xa2,m_y1,m_za2);
glEnd();
 
if(TurnNPC)
{
 
m_Angle += 1.0f;
 
if(m_Angle > 360.0f)
{
m_Angle = 0.0f;
}
 
m_xa1 =  (GLfloat)cos(m_Angle*piover180) * 0.125f + 0.875f;
m_za1 =  (GLfloat)sin(m_Angle*piover180) * 0.125f - 5.0f;
m_xa2 =  (GLfloat)cos((m_Angle+180)*piover180) * 0.125f + 0.875f;
m_za2 =  (GLfloat)sin((m_Angle+180)*piover180) * 0.125f - 5.0f;
 
TurnNPC = false;
}
 
}

Share this post


Link to post
Share on other sites

This topic is 1270 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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