source: nanovis/trunk/vrmath/Quaternion.cpp @ 5704

Last change on this file since 5704 was 3492, checked in by ldelgass, 11 years ago

Fix camera reset for nanovis. Includes refactoring of vector/matrix classes
in nanovis to consolidate into vrmath library. Also add preliminary canonical
view control to clients for testing.

  • Property svn:eol-style set to native
File size: 1.8 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (c) 2004-2013  HUBzero Foundation, LLC
4 *
5 * Author: Insoo Woo <iwoo@purdue.edu>
6 */
7
8#include <cstdlib>
9#include <cmath>
10#include <float.h>
11
12#include <vrmath/Quaternion.h>
13#include <vrmath/Rotation.h>
14#include <vrmath/Vector3f.h>
15
16#ifndef PI
17#define PI 3.14159264
18#endif
19
20using namespace vrmath;
21
22Quaternion::Quaternion() :
23    x(1.0f), y(0.0f), z(0.0f), w(0.0f)
24{
25}
26
27Quaternion::Quaternion(const Rotation& rot)
28{
29    set(rot);
30}
31
32Quaternion::Quaternion(double x1, double y1, double z1, double w1) :
33    x(x1), y(y1), z(z1), w(w1)
34{
35}
36
37Quaternion& Quaternion::normalize()
38{
39    double n = sqrt(w*w + x*x + y*y + z*z);
40    if (n == 0.0) {
41        w = 1.0;
42        x = y = z = 0.0;
43    } else {
44        double recip = 1.0/n;
45        w *= recip;
46        x *= recip;
47        y *= recip;
48        z *= recip;
49    }
50
51    return *this;
52}
53
54const Quaternion& Quaternion::set(const Rotation& rot)
55{
56    Vector3f q(rot.x, rot.y, rot.z);
57    q.normalize();
58    double s = sin(rot.angle * 0.5);
59    x = s * q.x;
60    y = s * q.y;
61    z = s * q.z;
62    w = cos(rot.angle * 0.5);
63
64    return *this;
65}
66
67void Quaternion::slerp(const Quaternion &a,const Quaternion &b, double t)
68{
69    double alpha, beta;
70    double cosom = a.x * b.x + a.y * b.y +
71        a.z * b.z + a.w * b.w;
72
73    bool flip = (cosom < 0.0);
74    if (flip) cosom = -cosom;
75    if ((1.0 - cosom) > 0.00001) {
76        double omega = acos(cosom);
77        double sinom = sin(omega);
78        alpha = sin((1.0 - t) * omega) / sinom;
79        beta = sin(t * omega) / sinom;
80    } else {
81        alpha = 1.0 - t;
82        beta = t;
83    }
84
85    if (flip) beta = -beta;
86    x = alpha * a.x + beta * b.x;
87    y = alpha * a.y + beta * b.y;
88    z = alpha * a.z + beta * b.z;
89    w = alpha * a.w + beta * b.w;
90}
Note: See TracBrowser for help on using the repository browser.