Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 6616 in orxonox.OLD for trunk/src/lib/math/vector.cc


Ignore:
Timestamp:
Jan 19, 2006, 12:27:45 PM (19 years ago)
Author:
bensch
Message:

orxonox/trunk: taken the quaternion outside of Vector.cc to quaternion.cc/h

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/math/vector.cc

    r5688 r6616  
    6666  PRINT(0)(" lenght: %f", len());
    6767  PRINT(0)("\n");
    68 }
    69 
    70 /////////////////
    71 /* QUATERNIONS */
    72 /////////////////
    73 /**
    74  *  calculates a lookAt rotation
    75  * @param dir: the direction you want to look
    76  * @param up: specify what direction up should be
    77 
    78    Mathematically this determines the rotation a (0,0,1)-Vector has to undergo to point
    79    the same way as dir. If you want to use this with cameras, you'll have to reverse the
    80    dir Vector (Vector(0,0,0) - your viewing direction) or you'll point the wrong way. You
    81    can use this for meshes as well (then you do not have to reverse the vector), but keep
    82    in mind that if you do that, the model's front has to point in +z direction, and left
    83    and right should be -x or +x respectively or the mesh wont rotate correctly.
    84  *
    85  * @TODO !!! OPTIMIZE THIS !!!
    86  */
    87 Quaternion::Quaternion (const Vector& dir, const Vector& up)
    88 {
    89   Vector z = dir.getNormalized();
    90   Vector x = up.cross(z).getNormalized();
    91   Vector y = z.cross(x);
    92 
    93   float m[4][4];
    94   m[0][0] = x.x;
    95   m[0][1] = x.y;
    96   m[0][2] = x.z;
    97   m[0][3] = 0;
    98   m[1][0] = y.x;
    99   m[1][1] = y.y;
    100   m[1][2] = y.z;
    101   m[1][3] = 0;
    102   m[2][0] = z.x;
    103   m[2][1] = z.y;
    104   m[2][2] = z.z;
    105   m[2][3] = 0;
    106   m[3][0] = 0;
    107   m[3][1] = 0;
    108   m[3][2] = 0;
    109   m[3][3] = 1;
    110 
    111   *this = Quaternion (m);
    112 }
    113 
    114 /**
    115  *  calculates a rotation from euler angles
    116  * @param roll: the roll in radians
    117  * @param pitch: the pitch in radians
    118  * @param yaw: the yaw in radians
    119  */
    120 Quaternion::Quaternion (float roll, float pitch, float yaw)
    121 {
    122   float cr, cp, cy, sr, sp, sy, cpcy, spsy;
    123 
    124   // calculate trig identities
    125   cr = cos(roll/2);
    126   cp = cos(pitch/2);
    127   cy = cos(yaw/2);
    128 
    129   sr = sin(roll/2);
    130   sp = sin(pitch/2);
    131   sy = sin(yaw/2);
    132 
    133   cpcy = cp * cy;
    134   spsy = sp * sy;
    135 
    136   w = cr * cpcy + sr * spsy;
    137   v.x = sr * cpcy - cr * spsy;
    138   v.y = cr * sp * cy + sr * cp * sy;
    139   v.z = cr * cp * sy - sr * sp * cy;
    140 }
    141 
    142 /**
    143  *  convert the Quaternion to a 4x4 rotational glMatrix
    144  * @param m: a buffer to store the Matrix in
    145  */
    146 void Quaternion::matrix (float m[4][4]) const
    147 {
    148   float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
    149 
    150   // calculate coefficients
    151   x2 = v.x + v.x;
    152   y2 = v.y + v.y;
    153   z2 = v.z + v.z;
    154   xx = v.x * x2; xy = v.x * y2; xz = v.x * z2;
    155   yy = v.y * y2; yz = v.y * z2; zz = v.z * z2;
    156   wx = w * x2; wy = w * y2; wz = w * z2;
    157 
    158   m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz;
    159   m[2][0] = xz + wy; m[3][0] = 0.0;
    160 
    161   m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz);
    162   m[2][1] = yz - wx; m[3][1] = 0.0;
    163 
    164   m[0][2] = xz - wy; m[1][2] = yz + wx;
    165   m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0;
    166 
    167   m[0][3] = 0; m[1][3] = 0;
    168   m[2][3] = 0; m[3][3] = 1;
    169 }
    170 
    171 /**
    172  *  performs a smooth move.
    173  * @param from  where
    174  * @param to where
    175  * @param t the time this transformation should take value [0..1]
    176  * @returns the Result of the smooth move
    177  */
    178 Quaternion Quaternion::quatSlerp(const Quaternion& from, const Quaternion& to, float t)
    179 {
    180   float tol[4];
    181   double omega, cosom, sinom, scale0, scale1;
    182   //  float DELTA = 0.2;
    183 
    184   cosom = from.v.x * to.v.x + from.v.y * to.v.y + from.v.z * to.v.z + from.w * to.w;
    185 
    186   if( cosom < 0.0 )
    187     {
    188       cosom = -cosom;
    189       tol[0] = -to.v.x;
    190       tol[1] = -to.v.y;
    191       tol[2] = -to.v.z;
    192       tol[3] = -to.w;
    193     }
    194   else
    195     {
    196       tol[0] = to.v.x;
    197       tol[1] = to.v.y;
    198       tol[2] = to.v.z;
    199       tol[3] = to.w;
    200     }
    201 
    202   omega = acos(cosom);
    203   sinom = sin(omega);
    204   scale0 = sin((1.0 - t) * omega) / sinom;
    205   scale1 = sin(t * omega) / sinom;
    206   return Quaternion(Vector(scale0 * from.v.x + scale1 * tol[0],
    207                     scale0 * from.v.y + scale1 * tol[1],
    208                     scale0 * from.v.z + scale1 * tol[2]),
    209                     scale0 * from.w + scale1 * tol[3]);
    210 }
    211 
    212 
    213 /**
    214  *  convert a rotational 4x4 glMatrix into a Quaternion
    215  * @param m: a 4x4 matrix in glMatrix order
    216  */
    217 Quaternion::Quaternion (float m[4][4])
    218 {
    219 
    220   float  tr, s, q[4];
    221   int    i, j, k;
    222 
    223   int nxt[3] = {1, 2, 0};
    224 
    225   tr = m[0][0] + m[1][1] + m[2][2];
    226 
    227         // check the diagonal
    228   if (tr > 0.0)
    229   {
    230     s = sqrt (tr + 1.0);
    231     w = s / 2.0;
    232     s = 0.5 / s;
    233     v.x = (m[1][2] - m[2][1]) * s;
    234     v.y = (m[2][0] - m[0][2]) * s;
    235     v.z = (m[0][1] - m[1][0]) * s;
    236         }
    237         else
    238         {
    239                 // diagonal is negative
    240         i = 0;
    241         if (m[1][1] > m[0][0]) i = 1;
    242     if (m[2][2] > m[i][i]) i = 2;
    243     j = nxt[i];
    244     k = nxt[j];
    245 
    246     s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + 1.0);
    247 
    248     q[i] = s * 0.5;
    249 
    250     if (s != 0.0) s = 0.5 / s;
    251 
    252           q[3] = (m[j][k] - m[k][j]) * s;
    253     q[j] = (m[i][j] + m[j][i]) * s;
    254     q[k] = (m[i][k] + m[k][i]) * s;
    255 
    256         v.x = q[0];
    257         v.y = q[1];
    258         v.z = q[2];
    259         w = q[3];
    260   }
    261 }
    262 
    263 /**
    264  *  outputs some nice formated debug information about this quaternion
    265 */
    266 void Quaternion::debug()
    267 {
    268   PRINT(0)("real a=%f; imag: x=%f y=%f z=%f\n", w, v.x, v.y, v.z);
    269 }
    270 
    271 void Quaternion::debug2()
    272 {
    273   Vector axis = this->getSpacialAxis();
    274   PRINT(0)("angle = %f, axis: ax=%f, ay=%f, az=%f\n", this->getSpacialAxisAngle(), axis.x, axis.y, axis.z );
    27568}
    27669
Note: See TracChangeset for help on using the changeset viewer.