Setting camera up-vector and object rotation

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Setting camera up-vector and object rotation

Post by robmar »

Thought this might be useful as it took me a while to get my head around object rotation to direction and up-vector maths

Code: Select all

 
// Input: Direction of travel vector, and an up vector that does not need to allow for elevation in travel direction, result is the node´s required rotation in degrees
 
vector3df createRotations(vector3df const &fromDirection, vector3df const &fromUp, ISceneNode *testNode)
{
   vector3df masterDirection(fromDirection);
   masterDirection.normalize();
 
   vector3df masterUp(fromUp);
   masterUp.normalize();
 
   // *** First calculate the true up vector in relation to the direction vector, which may be elevated:-
   // Get a vector perpendicular to the two angles input.  The two angles form an L of a plane, the result is an up vector from this plane
   // Project the up vector onto a vector that's orthogonal (perpendicual/at 90 degrees) to the direction
   vector3df realUp = masterDirection.crossProduct(masterUp).normalize();       // Result is vector pointing right to the directon vector and at 90 deg to the up
   // Now realUp is actually the real Left!
   realUp = realUp.crossProduct(masterDirection);       // Now produce the real (corrected) upvector in relation to the direction of travel (which may be elevated for example)
 
   // *** Set the quaternion´s rotation to that of the direction vector:-
   quaternion quatDirection;                                                                                 // Set the quaternion´s rotation to that of the master direction vector
   quatDirection.rotationFromTo(vector3df(0, 0, 1), masterDirection);       // Calc the rotation required from the standard forward direction to the master direction
 
   // *** Calculate true upvector related to direction of travel:-
   vector3df worldUp(0, 1, 0);                                               // Apply that rotation to the world up vector
   matrix4 mat;
   mat = quatDirection.getMatrix();
   mat.rotateVect(worldUp);                                             // Rotate worldUp vector by up vector of direction vector (which could be an elevated direction of travel for example
    // Now we have an upvector related correctly to the direction of travel
 
   quaternion quatUp;                                   // Get the quaternion to rotate to the required up
    quatUp.rotationFromTo(worldUp, realUp);             // Set quat´s rotation equal to that needed to go from world up (010) to required (real)up
 
    quaternion quat = quatDirection * quatUp;                // Concatenate them to get a total rotation for the node so that it face in the direction set, and is also elevated correctly
 
    // Convert to euler rotations
    vector3df eulers;
    quat.toEuler(eulers);   //... in radians
    eulers *= RADTODEG;   //... and now in degrees
    // This is the euler rotations required. 
  
    if ( testNode )
    {
        // Now let's test them.   
        testNode->setRotation(eulers);
        testNode->updateAbsolutePosition();
        mat = testNode->getAbsoluteTransformation();
 
        vector3df slaveDirection(0, 0, 1);
        mat.rotateVect(slaveDirection);         // Rotate a standard forward direction to the same as the node
 
        vector3df slaveUp(0, 1, 0);
        mat.rotateVect(slaveUp);                // Rotate a standard world up direction to that of the node
 
        (void)printf("\nEulers %.2f %.2f %.2f\n",
            eulers.X, eulers.Y, eulers.Z);
        (void)printf("From dir %.2f %.2f %.2f, up %.2f %.2f %.2f\n",
            masterDirection.X, masterDirection.Y, masterDirection.Z,
            realUp.X, realUp.Y, realUp.Z);
        (void)printf("  to dir %.2f %.2f %.2f, up %.2f %.2f %.2f\n",
            slaveDirection.X, slaveDirection.Y, slaveDirection.Z,
            slaveUp.X, slaveUp.Y, slaveUp.Z);
 
        (void)printf("           %s                      %s\n",
                masterDirection == slaveDirection ? "PASS" : "FAIL",
                realUp == slaveUp ? "PASS" : "FAIL");
    }
    return eulers;
}
 
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Setting camera up-vector and object rotation

Post by thanhle »

Great stuff mate.

Remember irrlicht used left handed coordinate system

realUp should be

realUp = dir.crossProduct(right) // from dir to right.

I hope that's how irrlicht implement it.

Cheers,
Thanh
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: Setting camera up-vector and object rotation

Post by robmar »

Left is 1,0,0 as my camera looks from 0,0,-80 to 0,0,80 :)

One man's left n all!
Post Reply