Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 2112 in orxonox.OLD for orxonox/branches/chris/src/vector.cc


Ignore:
Timestamp:
Jul 12, 2004, 10:28:25 PM (20 years ago)
Author:
chris
Message:

orxonox/branches/chris: Implemented quaternion class… but something is still f up… the camera keeps pointing into the wrong direction… matrix rotation calculation seems not to be my strenght…

File:
1 edited

Legend:

Unmodified
Added
Removed
  • orxonox/branches/chris/src/vector.cc

    r2101 r2112  
    1414   main-programmer: Christian Meyer
    1515   co-programmer: ...
     16   
     17   Quaternion code borrowed from an Gamasutra article by Nick Bobick and Ken Shoemake
    1618*/
    1719
     
    177179  f = acos( v1 * v2 / (v1.len() * v2.len()));
    178180  return f * 180 / PI;
     181}
     182
     183Quaternion::Quaternion ()
     184{
     185        w = 1;
     186        v = Vector(0,0,0);
     187}
     188
     189Quaternion::Quaternion (float angle, const Vector& axis)
     190{
     191        w = cos(angle/2);
     192        v = axis * sin(angle/2);
     193}
     194
     195Quaternion::Quaternion (const Vector& dir, const Vector& up)
     196{
     197        Vector z = dir;
     198  z.normalize();
     199  Vector x = up.cross(z);
     200  x.normalize();
     201  Vector y = z.cross(x);
     202 
     203  float m[4][4];
     204  m[0][0] = x.x;
     205  m[0][1] = x.y;
     206  m[0][2] = x.z;
     207  m[0][3] = 0;
     208  m[1][0] = y.x;
     209  m[1][1] = y.y;
     210  m[1][2] = y.z;
     211  m[1][3] = 0;
     212  m[2][0] = z.x;
     213  m[2][1] = z.y;
     214  m[2][2] = z.z;
     215  m[2][3] = 0;
     216  m[3][0] = 0;
     217  m[3][1] = 0;
     218  m[3][2] = 0;
     219  m[3][3] = 1;
     220 
     221  *this = Quaternion (m);
     222}
     223
     224Quaternion::Quaternion (float roll, float pitch, float yaw)
     225{
     226        float cr, cp, cy, sr, sp, sy, cpcy, spsy;
     227       
     228        // calculate trig identities
     229        cr = cos(roll/2);
     230        cp = cos(pitch/2);
     231        cy = cos(yaw/2);
     232       
     233        sr = sin(roll/2);
     234        sp = sin(pitch/2);
     235        sy = sin(yaw/2);
     236       
     237        cpcy = cp * cy;
     238        spsy = sp * sy;
     239       
     240        w = cr * cpcy + sr * spsy;
     241        v.x = sr * cpcy - cr * spsy;
     242        v.y = cr * sp * cy + sr * cp * sy;
     243        v.z = cr * cp * sy - sr * sp * cy;
     244}
     245
     246Quaternion Quaternion::operator*(const Quaternion& q) const
     247{
     248        float A, B, C, D, E, F, G, H;
     249        Quaternion r;
     250       
     251        A = (w   + v.x)*(q.w   + q.v.x);
     252        B = (v.z - v.y)*(q.v.y - q.v.z);
     253        C = (w   - v.x)*(q.v.y + q.v.z);
     254        D = (v.y + v.z)*(q.w   - q.v.x);
     255        E = (v.x + v.z)*(q.v.x + q.v.y);
     256        F = (v.x - v.z)*(q.v.x - q.v.y);
     257        G = (w   + v.y)*(q.w   - q.v.z);
     258        H = (w   - v.y)*(q.w   + q.v.z);
     259       
     260        r.w = B +  (-E - F + G + H)/2;
     261        r.v.x = A - (E + F + G + H)/2;
     262        r.v.y = C + (E - F + G - H)/2;
     263        r.v.z = D + (E - F - G + H)/2;
     264       
     265        return r;
     266}
     267
     268Quaternion Quaternion::operator+(const Quaternion& q) const
     269{
     270        Quaternion r(*this);
     271        r.w = r.w + q.w;
     272        r.v = r.v + q.v;
     273        return r;
     274}
     275
     276Quaternion Quaternion::operator- (const Quaternion& q) const
     277{
     278        Quaternion r(*this);
     279        r.w = r.w - q.w;
     280        r.v = r.v - q.v;
     281        return r;
     282}
     283
     284Vector Quaternion::apply (Vector& v) const
     285{
     286        Quaternion q;
     287        q.v = v;
     288        q.w = 0;
     289        q = *this * q * conjugate();
     290        return q.v;
     291}
     292
     293Quaternion Quaternion::operator*(const float& f) const
     294{
     295        Quaternion r(*this);
     296        r.w = r.w*f;
     297        r.v = r.v*f;
     298        return r;
     299}
     300
     301Quaternion Quaternion::operator/(const float& f) const
     302{
     303        if( f == 0) return Quaternion();
     304        Quaternion r(*this);
     305        r.w = r.w/f;
     306        r.v = r.v/f;
     307        return r;
     308}
     309
     310Quaternion Quaternion::conjugate() const
     311{
     312        Quaternion r(*this);
     313        r.v = Vector() - r.v;
     314        return r;
     315}
     316
     317float Quaternion::norm() const
     318{
     319        return w*w + v.x*v.x + v.y*v.y + v.z*v.z;
     320}
     321
     322Quaternion Quaternion::inverse() const
     323{
     324        float n = norm();
     325        if (n != 0)
     326        {
     327                return conjugate() / norm();
     328        }
     329        else return Quaternion();
     330}
     331
     332void Quaternion::matrix (float m[4][4]) const
     333{
     334        float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
     335
     336        // calculate coefficients
     337        x2 = v.x + v.x;
     338  y2 = v.y + v.y;
     339        z2 = v.z + v.z;
     340        xx = v.x * x2; xy = v.x * y2; xz = v.x * z2;
     341        yy = v.y * y2; yz = v.y * z2; zz = v.z * z2;
     342        wx = w * x2; wy = w * y2; wz = w * z2;
     343       
     344        m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz;
     345        m[2][0] = xz + wy; m[3][0] = 0.0;
     346       
     347        m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz);
     348        m[2][1] = yz - wx; m[3][1] = 0.0;
     349       
     350        m[0][2] = xz - wy; m[1][2] = yz + wx;
     351        m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0;
     352       
     353        m[0][3] = 0; m[1][3] = 0;
     354        m[2][3] = 0; m[3][3] = 1;
     355}
     356
     357Quaternion::Quaternion (float m[4][4])
     358{
     359       
     360  float  tr, s, q[4];
     361  int    i, j, k;
     362
     363  int nxt[3] = {1, 2, 0};
     364
     365  tr = m[0][0] + m[1][1] + m[2][2];
     366
     367        // check the diagonal
     368  if (tr > 0.0)
     369  {
     370    s = sqrt (tr + 1.0);
     371    w = s / 2.0;
     372    s = 0.5 / s;
     373    v.x = (m[1][2] - m[2][1]) * s;
     374    v.y = (m[2][0] - m[0][2]) * s;
     375    v.z = (m[0][1] - m[1][0]) * s;
     376        }
     377        else
     378        {
     379                // diagonal is negative
     380        i = 0;
     381        if (m[1][1] > m[0][0]) i = 1;
     382    if (m[2][2] > m[i][i]) i = 2;
     383    j = nxt[i];
     384    k = nxt[j];
     385
     386    s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + 1.0);
     387     
     388    q[i] = s * 0.5;
     389           
     390    if (s != 0.0) s = 0.5 / s;
     391       
     392          q[3] = (m[j][k] - m[k][j]) * s;
     393    q[j] = (m[i][j] + m[j][i]) * s;
     394    q[k] = (m[i][k] + m[k][i]) * s;
     395
     396        v.x = q[0];
     397        v.y = q[1];
     398        v.z = q[2];
     399        w = q[3];
     400  }
    179401}
    180402
Note: See TracChangeset for help on using the changeset viewer.