How to apply Bullet Quaternion to Irrlicht Mesh?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
dehseth
Posts: 130
Joined: Wed Dec 09, 2009 11:05 am
Contact:

How to apply Bullet Quaternion to Irrlicht Mesh?

Post by dehseth »

Hi guys,

as you can unserstand from topic, I have a sphere ball and I apply torque to this ball, so the ball rotates and moves. I have a mesh in Irrlicht and how can I rotate this mesh, even apply world transform matrix..

To be more clear: I initiate Bullet physics and add a sphere rigid body. And I got World Transform in each frame, and I would like to apply this transform (rotation and position) to my irrlicht mesh... Bullet uses Quaternions for rotation.. How do you deal with this?

I tried smt like:

Code: Select all

btTransform transformTop = rigidBodyTop->getWorldTransform();
			btVector3 posTop = transformTop.getOrigin();
			nodeTop->setPosition(core::vector3df(posTop.x(), posTop.y(), posTop.z()));
			btQuaternion rotTop = transformTop.getRotation();
			core::vector3df rotEulerTop;
			nodeTop->setRotation(QuaternionToEuler(rotTop, rotEulerTop));

Thank you...
FuzzYspo0N
Posts: 914
Joined: Fri Aug 03, 2007 12:43 pm
Location: South Africa
Contact:

Post by FuzzYspo0N »

when the bullet author posted an example he used this :

Code: Select all

	void QuaternionToEuler(const btQuaternion &TQuat, btVector3 &TEuler) {
		btScalar W = TQuat.getW();
		btScalar X = TQuat.getX();
		btScalar Y = TQuat.getY();
		btScalar Z = TQuat.getZ();
		float WSquared = W * W;
		float XSquared = X * X;
		float YSquared = Y * Y;
		float ZSquared = Z * Z;

		TEuler.setX(atan2f(2.0f * (Y * Z + X * W), -XSquared - YSquared + ZSquared + WSquared));
		TEuler.setY(asinf(-2.0f * (X * Z - Y * W)));
		TEuler.setZ(atan2f(2.0f * (X * Y + Z * W), XSquared - YSquared - ZSquared + WSquared));
		TEuler *= core::RADTODEG;
	}
to convert them , but if you use irrlicht core::quaternion, you can just construct it like :


core::quaternion converter = core::quaternion( btQuat.x, btQuat.y, btQuat.z, btQuat.w);

(might cast if you like)
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

You can also use matrices:

Code: Select all

float tMatrix[16];
MotionState->m_graphicsWorldTrans.getOpenGLMatrix(tMatrix);

matrix4 Matrix;
memcpy(Matrix.pointer(), tMatrix, sizeof(float)*16);

Node->setPosition(Matrix.getTranslation());
Node->setRotation(Matrix.getRotationDegrees());
I use this method in my projects.

Cheers,
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
dehseth
Posts: 130
Joined: Wed Dec 09, 2009 11:05 am
Contact:

Post by dehseth »

@FuzzYspo0N yeah that's what I've found and used on internet but converting quaternion to eular coordinates seems a little slow to me. I am more like trying to find a way that I give irrlicht the matrix or quaternion and it rotates mesh using it.


@Nadro Is there a way to apply the matrix itself to node directly? I mean without using getTranslation and getRotationDegrees functions?


And one more thing I am trying to apply torque at direction btVector3(0,0,1) using bullet and see rotation which does not make any sense on mesh..

I have uploaded exe file to here: http://www.2shared.com/file/10448786/1200776a/ball.html

When you press left or right arrow you'll see what's wrong. You can use mouse and WASD keys for camera and arrows for applying torque to ball. Here's ball torque code piece:

Code: Select all

else if (keyss[irr::KEY_UP])
			{
				rigidBodyTop->applyTorque(btVector3(1,0,0));
				rigidBodyTop->activate();				
			}
			else if (keyss[irr::KEY_DOWN])
			{
				rigidBodyTop->applyTorque(btVector3(-1,0,0));
				rigidBodyTop->activate();				
			}
			else if (keyss[irr::KEY_LEFT])
			{
				rigidBodyTop->applyTorque(btVector3(0,0,1));
				rigidBodyTop->activate();				
			}
			else if (keyss[irr::KEY_RIGHT])
			{
				rigidBodyTop->applyTorque(btVector3(0,0,-1));
				rigidBodyTop->activate();
			}
kamikaze942
Posts: 52
Joined: Wed Mar 03, 2010 7:11 pm

Post by kamikaze942 »

did you ever figure it out?
Kamikaze
cobra
Posts: 371
Joined: Fri Jan 23, 2009 2:56 am
Location: United States
Contact:

Post by cobra »

From common.cpp in my irrBullet project:

Code: Select all

void btTransformToIrrlichtMatrix(const btTransform& worldTrans, irr::core::matrix4 &matr)
{
    worldTrans.getOpenGLMatrix(matr.pointer());
}


void btTransformFromIrrlichtMatrix(const irr::core::matrix4& irrmat, btTransform &transform)
{
    transform.setIdentity();

    transform.setFromOpenGLMatrix(irrmat.pointer());
}

This works very well. I improved the first function based off of a snippet that randomMesh gave me, and then aanderse improved my version. I then wrote the second one on my own.
Josiah Hartzell
Image
sosssego
Posts: 2
Joined: Wed Mar 17, 2010 12:55 am

Post by sosssego »

Hi, i think it can help.
I think the bullet coordinates system isn't the same as the Irrlich.

You can see the bullet here: http://bulletphysics.com/ftp/pub/test/p ... Manual.pdf
@ page 12
I can't find an image for the Irrlicht coordinate.

but using the code below i works properly.
I test it on a program with the ground and an Sphere. You can apply some forces to the ball using wsad. The ball and the ground has a texture so we can evaluate the movement.

Code: Select all

				btTransform trans;
				fallRigidBody->getMotionState()->getWorldTransform(trans);
				matrix4 mtrans;
				memcpy(mtrans.pointer(),(void*)&trans,sizeof(float)*16);
				node->setPosition(vector3df(mtrans.getTranslation().Z, mtrans.getTranslation().Y, mtrans.getTranslation().X));
				node->setRotation(vector3df(mtrans.getRotationDegrees().Z, mtrans.getRotationDegrees().Y, mtrans.getRotationDegrees().X));
I used the getRotation and getTranslation, but switch the x and y coordinates. Maybe there are a better way without create another matrix and use memcpy. But it works fine this way...
I hope it can help...

sorry for my bad English

Regards,
kamikaze942
Posts: 52
Joined: Wed Mar 03, 2010 7:11 pm

Post by kamikaze942 »

oh wait sorry i wasn't paying attention. i scoped this out at the bullet forum. if you are applying a rigid body to your mesh use this for translations

Code: Select all

btVector3 wallk(z, y, x);  (seems to me they are reversed)
btTransform xform;
					
yourrigidbody->getMotionState()->getWorldTransform(xform);
yourrigidbody->setLinearVelocity(qmv3(wallk, xform.getRotation()));
					
yourrigidbody->getMotionState()->setWorldTransform(xform);
					yourrigidbody->setCenterOfMassTransform(xform);
for rotations (arbitrary)

Code: Select all

btMatrix3x3 orn = yourrigidbody->getWorldTransform().getBasis();
orn *= btMatrix3x3(btQuaternion(btVector3(z, y, x), 1.5/*(or other amount)*/));
yourrigidbody->getWorldTransform().setBasis(orn);

unfortunately there are no set rotation/setposition functions.


:(
Kamikaze
Post Reply