Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- El uso sería algo así:
- Ogre::Quaternion q1 = fromEulerToQuaternion( Ogre::Vector3(45, 90, -90) ); // por defecto en grados
- Tengo un enumerado muy tonto, para especificar la unidad en la que van.
- typedef enum
- {
- DEGREE,
- RADIAN
- } MeasureEnum;
- Mi función seria esta, que usa 2 funciones de Ogre:
- Ogre::Quaternion fromEulerToQuaternion(const Ogre::Vector3& rotation, MeasureEnum measure = MeasureEnum::DEGREE)
- {
- // inicialmente es la identidad
- Ogre::Quaternion ret;
- switch(measure)
- {
- case RADIAN:
- // orden ZYX
- ret = ret * Ogre::Quaternion(Ogre::Radian(rotation.z), Ogre::Vector3(0, 0, 1));
- ret = ret * Ogre::Quaternion(Ogre::Radian(rotation.y), Ogre::Vector3(0, 1, 0));
- ret = ret * Ogre::Quaternion(Ogre::Radian(rotation.x), Ogre::Vector3(1, 0, 0));
- break;
- case DEGREE:
- default:
- // orden ZYX
- ret = ret * Ogre::Quaternion(Ogre::Degree(rotation.z), Ogre::Vector3(0, 0, 1));
- ret = ret * Ogre::Quaternion(Ogre::Degree(rotation.y), Ogre::Vector3(0, 1, 0));
- ret = ret * Ogre::Quaternion(Ogre::Degree(rotation.x), Ogre::Vector3(1, 0, 0));
- break;
- }
- return ret;
- }
- Lo que hace Ogre en los constructores es crear el Quaternion a partir de un angulo y un eje con este algoritmo:
- void Quaternion::FromAngleAxis (const Radian& rfAngle, const Vector3& rkAxis)
- {
- // assert: axis[] is unit length
- //
- // The quaternion representing the rotation is
- // q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)
- Radian fHalfAngle ( 0.5*rfAngle );
- Real fSin = Math::Sin(fHalfAngle);
- w = Math::Cos(fHalfAngle);
- x = fSin*rkAxis.x;
- y = fSin*rkAxis.y;
- z = fSin*rkAxis.z;
- }
- Tambien se usa la multiplicación de Quaterniones que según Ogre es así:
- Quaternion Quaternion::operator* (const Quaternion& rkQ) const
- {
- // NOTE: Multiplication is not generally commutative, so in most
- // cases p*q != q*p.
- return Quaternion
- (
- w * rkQ.w - x * rkQ.x - y * rkQ.y - z * rkQ.z,
- w * rkQ.x + x * rkQ.w + y * rkQ.z - z * rkQ.y,
- w * rkQ.y + y * rkQ.w + z * rkQ.x - x * rkQ.z,
- w * rkQ.z + z * rkQ.w + x * rkQ.y - y * rkQ.x
- );
- }
- // Por último, como al final OpenGL lo que pide son matrices, (y es medio normal que algunos engines se quedan en la matriz) tendrias que convertir el Quaternion a Matriz.
- // En Ogre lo hacen así:
- void Quaternion::ToRotationMatrix (Matrix3& kRot) const
- {
- Real fTx = x+x;
- Real fTy = y+y;
- Real fTz = z+z;
- Real fTwx = fTx*w;
- Real fTwy = fTy*w;
- Real fTwz = fTz*w;
- Real fTxx = fTx*x;
- Real fTxy = fTy*x;
- Real fTxz = fTz*x;
- Real fTyy = fTy*y;
- Real fTyz = fTz*y;
- Real fTzz = fTz*z;
- kRot[0][0] = 1.0f-(fTyy+fTzz);
- kRot[0][1] = fTxy-fTwz;
- kRot[0][2] = fTxz+fTwy;
- kRot[1][0] = fTxy+fTwz;
- kRot[1][1] = 1.0f-(fTxx+fTzz);
- kRot[1][2] = fTyz-fTwx;
- kRot[2][0] = fTxz-fTwy;
- kRot[2][1] = fTyz+fTwx;
- kRot[2][2] = 1.0f-(fTxx+fTyy);
- }
- Aunque esto es una matriz de 3x3, sin la translación.
- Esto seria fácil implementarlo en Lua ... IMHO
- Un saludo. Ricardo
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement