Sign in to follow this  

VBO - Quaternion rotation - SOLVED

This topic is 3864 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 - i have a model load into a VBO wich i need to rotate - the problem is that when i rotate with specific values like (0, 270, -90) it gives me the rotation for (0,0 -90) - this is not always the same. During rendering i give different values for the rotation - sometimes the rotation is made ok sometime not - always the same rotations dont work - i have tested and i give the right rotation angles - so there is not a problem there. Can you help me figure out what could be the problem? Ill post the code bellow - thanks! //Code for creating VBO
void GL_Game::CreateDYNAMIC_VBO(CModel &model)
{
	for(int i = 0; i<MAX_VERTICES; i++)
	{
		g_DiceManager.actorManager.playerCoordinates[i] = model.VertexVector[i];
		g_DiceManager.actorManager.DefaultPlayerCoordinates[i] = model.VertexVector[i];
	}

	//Vertex
	glGenBuffersARB(1,	&model.playerVBuffer);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, model.playerVBuffer);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB,	model.k*3*sizeof(float), g_DiceManager.actorManager.playerCoordinates, GL_STREAM_DRAW_ARB);
	
	//Texture
	glGenBuffersARB(1,	&model.playerTBuffer);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, model.playerTBuffer);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, model.k*2*sizeof(float), model.TextureVector, GL_STATIC_DRAW_ARB);
	
	//Normal
	glGenBuffersARB(1, &model.playerNBuffer);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, model.playerNBuffer);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, model.k*3*sizeof(float), model.NormalsVector, GL_STREAM_DRAW_ARB);


}


//CODE FOR RENDERING VBO
void GL_Game::DrawDYNAMIC_VBO(CModel& model)
{
	glBindTexture(GL_TEXTURE_2D, model.texID);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, model.playerVBuffer);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, model.k*3*sizeof(float), g_DiceManager.actorManager.playerCoordinates, GL_STREAM_DRAW_ARB);
	glVertexPointer(3,GL_FLOAT,0,(char*)NULL);
	
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, model.playerNBuffer);
	glNormalPointer(GL_FLOAT,0, (char*)NULL);
	
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, model.playerTBuffer);
	glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL );		
	glDrawArrays(RENDER_MODE,0, model.k);
}


//CODE FOR MAKING THE ROTATION
void CDiceManager::RotateDice(float RotAngleX, float RotAngleY, float RotAngleZ) 
{
	

	int PozV = actorManager.PlayerLocationV;
	int PozH = actorManager.PlayerLocationH;


		//GO TO 0,0,0 (DEFAULT POSITION

			for(int m = 0; m<actorManager.DiceDimension; m++)
			{
				actorManager.playerCoordinates[m]= actorManager.DefaultPlayerCoordinates[m];
			}
			actorManager.MatrixObj.Clear();

			//SE ROTESTE LA NUMARUL DORIT
	
			
				
							actorManager.Quaternion.Rotatef(RotAngleX,1,0,0);
			actorManager.Quaternion.CreateMatrix(actorManager.MatrixObj.matrix);
			
			for(int m = 0; m<actorManager.DiceDimension+1; m++)
			{
				actorManager.playerCoordinates[m] = actorManager.MatrixObj.TransformPoint(actorManager.playerCoordinates[m]);
			}
			actorManager.MatrixObj.Clear();
			
		
		actorManager.Quaternion.Rotatef(RotAngleY,0,1,0);
			actorManager.Quaternion.CreateMatrix(actorManager.MatrixObj.matrix);
			
			for(int m = 0; m<actorManager.DiceDimension+1; m++)
			{
				actorManager.playerCoordinates[m] = actorManager.MatrixObj.TransformPoint(actorManager.playerCoordinates[m]);
			}
			actorManager.MatrixObj.Clear();

				
			actorManager.Quaternion.Rotatef(RotAngleZ,0,0,1);
			actorManager.Quaternion.CreateMatrix(actorManager.MatrixObj.matrix);


			for(int m = 0; m<actorManager.DiceDimension+1; m++)
			{
				actorManager.playerCoordinates[m] = actorManager.MatrixObj.TransformPoint(actorManager.playerCoordinates[m]);
			}
			actorManager.MatrixObj.Clear();
	


			//TRANSLATE TO THE POSITION YOU WANT

	
			actorManager.MatrixObj.Translatef(2*1.828f * PozH, 0 , 2*1.828f * PozV);		
			for(int m = 0; m<actorManager.DiceDimension+1; m++)
			{
				actorManager.playerCoordinates[m] = actorManager.MatrixObj.TransformPoint(actorManager.playerCoordinates[m]);
			}

		
	
}


//CODE FOR THE ROTATEF FUNCTION
 void Rotatef(float amount, float xAxis, float yAxis, float zAxis)
         {
            // Normalize if we have to.
            if((xAxis + yAxis + zAxis) != 1)
            {
               float length = (float)sqrt(xAxis * xAxis + yAxis * yAxis + zAxis * zAxis);
               xAxis /= length; yAxis /= length; zAxis /= length;
            }

            // Convert the angle degrees into radians.
            float angle = GET_RADIANS(amount);

			//g_Angle = angle;
			//g_Angle = angle;
			// Call this once for optimization.
	         float sine = (float)sin(angle / 2.0f);

            // Create the quaternion.
	         x = xAxis * sine;
	         y = yAxis * sine;
	         z = zAxis * sine;
            w = (float)cos(angle / 2.0f);
         }


Any addvice will be much apreciated - Thanks! [Edited by - guvidu on May 18, 2007 3:42:45 AM]

Share this post


Link to post
Share on other sites
I'd say it's a problem with your rotation code and not with VBO creation.

RotateDice:
You're doing a rotation around each axis and after each step you build the matrix and transform the point. First that's highly inefficient and second it's not a quaternion rotation but rather an euler angle rotation (and it may not even be correct since you rotate around the global axes and not around the local exes which are transformed by each rotation).

Try creating a matrix for each rotation (x, y and z) first, then multiply them in correct order (depends on what rotation you want to achieve) and FINALLY transform the vertices with that matrix.(or send the rotation matrix to OpenGL).

Or really use quaterions without converting them to matrices. Build the quaterions for the needed rotations, multiply them and AFTER THAN build a matrix from the resulting quaternion and transform the vertices (or send the rotation matrix to OpenGL) or transform the vertices directly by the quaterion.

RotateF
First your check for unit length if wrong. Consider a unit length vector of x and y = 0.714, z = 0. The vector has unit length but x + y = 1.4.
Second, you're getting the sine of the angle and then multiply it with the vector. You shrink the vector to a length of sine rather than rotating it (which would involve different sine and cosine operations oin each component of the vector).

Share this post


Link to post
Share on other sites
Thanks you for the help - i manage to do the rotation right after making different quaternions for each rotation axis. Thanks for the tip - I know the code is not efficient - it was like that becouse off all the test i've made with it:P Thanks again

Share this post


Link to post
Share on other sites

This topic is 3864 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