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

Started by
6 comments, last by Cydriic 9 years, 10 months ago

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]);


}

Advertisement

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.

Yessir! Thank you very much I will do that!

Thanks!

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.



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.

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.

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;
}

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;
}
}

This topic is closed to new replies.

Advertisement