Page 1 of 1

Need help applying euler angles to btTransform[SOLVED]

Posted: Tue May 10, 2016 1:55 am
by StephenLynx
What I got currently is a vector representing euler angles that I can use on irrlicht:

Code: Select all

vector3df forward = (playerData->camera->getTarget()
      - playerData->camera->getPosition()).normalize();

  new LynxCube("assets/t351sml.jpg",
      (forward * 25) + playerData->camera->getPosition(),
      orientVector(forward, playerData->camera->getUpVector()));
forward is the delta between where I am looking at and where I am looking from and orientVector rotates the vector so my roll is taken in consideration, I implemented a 6dof camera.

Now, this is the constructor being called there:

Code: Select all

LynxCube::LynxCube(const path& texture, vector3df position,
    vector3df rotation) {

  LynxGlobal::LynxGlobalPointers* globalPointers =
      LynxGlobal::getGlobalPointers();

  graphic = globalPointers->smgr->addCubeSceneNode();

  if (graphic) {

    graphic->setMaterialTexture(0, globalPointers->driver->getTexture(texture));
    graphic->setPosition(position);
    graphic->setRotation(rotation);

    //TODO implement destructor

  btQuaternion quat;

    quat.setEulerZYX(rotation.Y, rotation.X, rotation.Z);

    btDefaultMotionState* motionState = new btDefaultMotionState(
        btTransform(quat, btVector3(position.Z, position.Y, position.X))); //here is where I try to initialize it with a rotation

    btScalar mass = 5;
    int size = 5;

    btCollisionShape* shape = new btBoxShape(btVector3(size, size, size));

    btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, motionState,
        shape);

    rigidBody = new btRigidBody(fallRigidBodyCI);
    globalPointers->dynamicsWorld->addRigidBody(rigidBody);

    LynxGlobal::getTickables()->push_back(this);
  }

}
And no matter what I try, the rotation is never right. I tried converting to degree to radians, flipping the order. Nothing matched the rotation I set on the graphic.
Here is how I get, on every frame, the rotation from the rigid body and apply to the graphic:

Code: Select all

void LynxCube::tick(float deltaTime) {

  if (!deltaTime) {
    return;
  }

  btTransform trans;
  rigidBody->getMotionState()->getWorldTransform(trans);

  matrix4 mtrans;
  memcpy(mtrans.pointer(), (void*) &trans, sizeof(float) * 16);

  graphic->setPosition(vector3df(mtrans[14], mtrans[13], mtrans[12]));

  vector3df newRot = mtrans.getRotationDegrees();
  graphic->setRotation(vector3df(newRot.Z, newRot.Y, newRot.X));
}
I have performed a good amount of tests on the tick to make sure it was actually matching what it should.

Any ideas? I tried several methods to apply that rotation and nothing made the placed cubes to face the camera as they should.



Edit: figured it out using opengl matrix conversions.
This went on the constructor:

Code: Select all

   graphic->setPosition(position);
    graphic->setRotation(rotation); //pitch yaw roll
    graphic->updateAbsolutePosition();

    btTransform trans;

    trans.setIdentity();
    trans.setFromOpenGLMatrix(graphic->getAbsoluteTransformation().pointer());

    btDefaultMotionState* motionState = new btDefaultMotionState(trans);

    btScalar mass = 5;
    int size = 5;

    btVector3 localInertia;
    btCollisionShape* shape = new btBoxShape(btVector3(size, size, size));
    shape->calculateLocalInertia(mass, localInertia);

    btRigidBody::btRigidBodyConstructionInfo constructionInfo(mass, motionState,
        shape, localInertia);
And this on the tick:

Code: Select all

  matrix4 mtrans;

  trans.getOpenGLMatrix(mtrans.pointer());

  graphic->setPosition(mtrans.getTranslation());

  graphic->setRotation(mtrans.getRotationDegrees());


Re: Need help applying euler angles to btTransform

Posted: Tue May 10, 2016 7:30 am
by S1L3nCe
Hi,

You can extract btQuaternion from Bullet body with body->getOrientation();
Then you can extract body's rotation from this quaternion.

Don't forget that bullet is a right-handed coordinate system (idk for Irrlicht)

S1L.

Edit:
I saw a Quaternion class in Irrlicht API how have a conversion function Quat->eulerAngle
Convert Bullet Quat to Irrlicht Quat and you have your rotation

Re: Need help applying euler angles to btTransform

Posted: Tue May 10, 2016 12:18 pm
by StephenLynx
That is not what I need.
What I need is to apply correctly angles on a rigid body.

Re: Need help applying euler angles to btTransform

Posted: Tue May 10, 2016 12:53 pm
by S1L3nCe
So do the opposite :wink:

Take your Irrlicht orientation in a quaternion, convert it to btQuaternion and then apply it to your body passing by a btTransform.

I personally use setCenterOfMassTransform to apply rotation by a btTransform.

Code: Select all

transfo.setRotation(btQuat);
body->setCenterOfMassTransform(transfo);

Re: Need help applying euler angles to btTransform

Posted: Tue May 10, 2016 1:04 pm
by Basroil
StephenLynx wrote:That is not what I need.
What I need is to apply correctly angles on a rigid body.
First thing should be to find out what your axis definitions are. You have

Code: Select all

quat.setEulerZYX(rotation.Y, rotation.X, rotation.Z);
, where y is yaw, x is pitch, z is roll, but then you have

Code: Select all

btTransform(quat, btVector3(position.Z, position.Y, position.X))); //here is where I try to initialize it with a rotation
where instead of y,x,z you have z,y,x as your primary axis definitions. That's not to say it's wrong for whatever you are trying to do, but it can certainly be a source of errors if you don't keep track of your axis definitions and make sure everything uses the same ones. Just write it all down on pen an paper and do a single simple step to make sure you don't have any axis definitions (perhaps somewhere else in your code) messed up.

Re: Need help applying euler angles to btTransform

Posted: Tue May 10, 2016 6:22 pm
by StephenLynx
Yeah, I just decided to convert the whole transform everywhere instead of trying to convert correctly rotations and location.
I edited the OP with that.