OpenSceneGraph/include/osg/Quat
Robert Osfield 12226e4371 Converted the instances of const built in types being returned from methods
and passed as paramters into straight forward non const built in types,
i.e. const bool foogbar(const int) becomes bool foobar(int).
2002-09-02 12:31:35 +00:00

269 lines
7.9 KiB
Plaintext

//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_QUAT
#define OSG_QUAT 1
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Matrix>
namespace osg {
/** A quaternion class. It can be used to represent an orientation in 3D space.*/
class SG_EXPORT Quat
{
public:
/* ----------------------------------------------------------
DATA MEMBERS
The only data member is a
Vec4 which holds the elements
In other words, osg:Quat is composed of an osg::Vec4
The osg::Quat aggregates an osg::Vec4
These seem to be different jargon for the same thing :-)
---------------------------------------------------------- */
Vec4 _fv; // a four-vector
Quat(): _fv(0.0f,0.0f,0.0f,1.0f) {}
Quat( float x, float y, float z, float w ): _fv(x,y,z,w) {}
Quat( const Vec4& v ): _fv(v) {}
/* ----------------------------------
Methods to access data members
---------------------------------- */
inline Vec4& asVec4()
{
return _fv;
}
inline const Vec4& asVec4() const
{
return _fv;
}
inline const Vec3 asVec3() const
{
return Vec3(_fv[0], _fv[1], _fv[2]);
}
inline void set(float x, float y, float z, float w)
{
_fv.set(x,y,z,w);
}
inline void set(const osg::Vec4& v)
{
_fv = v;
}
inline float& operator [] (int i) { return _fv[i]; }
inline float operator [] (int i) const { return _fv[i]; }
inline float& x() { return _fv[0]; }
inline float& y() { return _fv[1]; }
inline float& z() { return _fv[2]; }
inline float& w() { return _fv[3]; }
inline float x() const { return _fv[0]; }
inline float y() const { return _fv[1]; }
inline float z() const { return _fv[2]; }
inline float w() const { return _fv[3]; }
/* -------------------------------------------------------------
BASIC ARITHMETIC METHODS
Implemented in terms of Vec4s. Some Vec4 operators, e.g.
operator* are not appropriate for quaternions (as
mathematical objects) so they are implemented differently.
Also define methods for conjugate and the multiplicative inverse.
------------------------------------------------------------- */
/// Multiply by scalar
inline const Quat operator * (float rhs) const
{
return Quat(_fv*rhs);
}
/// Unary multiply by scalar
inline Quat& operator *= (float rhs)
{
_fv*=rhs;
return *this; // enable nesting
}
/// Binary multiply
inline const Quat operator*(const Quat& rhs) const
{
return Quat( rhs._fv[3]*_fv[0] + rhs._fv[0]*_fv[3] + rhs._fv[1]*_fv[2] - rhs._fv[2]*_fv[1],
rhs._fv[3]*_fv[1] - rhs._fv[0]*_fv[2] + rhs._fv[1]*_fv[3] + rhs._fv[2]*_fv[0],
rhs._fv[3]*_fv[2] + rhs._fv[0]*_fv[1] - rhs._fv[1]*_fv[0] + rhs._fv[2]*_fv[3],
rhs._fv[3]*_fv[3] - rhs._fv[0]*_fv[0] - rhs._fv[1]*_fv[1] - rhs._fv[2]*_fv[2] );
}
/// Unary multiply
inline Quat& operator*=(const Quat& rhs)
{
float x = rhs._fv[3]*_fv[0] + rhs._fv[0]*_fv[3] + rhs._fv[1]*_fv[2] - rhs._fv[2]*_fv[1];
float y = rhs._fv[3]*_fv[1] - rhs._fv[0]*_fv[2] + rhs._fv[1]*_fv[3] + rhs._fv[2]*_fv[0];
float z = rhs._fv[3]*_fv[2] + rhs._fv[0]*_fv[1] - rhs._fv[1]*_fv[0] + rhs._fv[2]*_fv[3];
_fv[3] = rhs._fv[3]*_fv[3] - rhs._fv[0]*_fv[0] - rhs._fv[1]*_fv[1] - rhs._fv[2]*_fv[2];
_fv[2] = z;
_fv[1] = y;
_fv[0] = x;
return (*this); // enable nesting
}
/// Divide by scalar
inline const Quat operator / (float rhs) const
{
return Quat(_fv/rhs);
}
/// Unary divide by scalar
inline Quat& operator /= (float rhs)
{
_fv/=rhs;
return *this;
}
/// Binary divide
inline const Quat operator/(const Quat& denom) const
{
return ( (*this) * denom.inverse() );
}
/// Unary divide
inline Quat& operator/=(const Quat& denom)
{
(*this) = (*this) * denom.inverse();
return (*this); // enable nesting
}
/// Binary addition
inline const Quat operator + (const Quat& rhs) const
{
return Quat( _fv + rhs._fv );
}
/// Unary addition
inline Quat& operator += (const Quat& rhs)
{
_fv += rhs._fv;
return *this; // enable nesting
}
/// Binary subtraction
inline const Quat operator - (const Quat& rhs) const
{
return Quat( _fv - rhs._fv );
}
/// Unary subtraction
inline Quat& operator -= (const Quat& rhs)
{
_fv-=rhs._fv;
return *this; // enable nesting
}
/** Negation operator - returns the negative of the quaternion.
Basically just calls operator - () on the Vec4 */
inline const Quat operator - () const
{
return Quat ( -_fv );
}
/// Length of the quaternion = sqrt( vec . vec )
float length() const
{
return _fv.length();
}
/// Length of the quaternion = vec . vec
float length2() const
{
return _fv.length2();
}
/// Conjugate
inline Quat conj () const
{
return Quat( -_fv[0], -_fv[1], -_fv[2], _fv[3] );
}
/// Multiplicative inverse method: q^(-1) = q^*/(q.q^*)
inline const Quat inverse () const
{
return conj() / length2();
}
/* --------------------------------------------------------
METHODS RELATED TO ROTATIONS
Set a quaternion which will perform a rotation of an
angle around the axis given by the vector (x,y,z).
Should be written to also accept an angle and a Vec3?
Define Spherical Linear interpolation method also
Not inlined - see the Quat.cpp file for implementation
-------------------------------------------------------- */
void makeRotate ( float angle,
float x, float y, float z );
void makeRotate ( float angle, const Vec3& vec );
void makeRotate ( float angle1, const Vec3& axis1,
float angle2, const Vec3& axis2,
float angle3, const Vec3& axis3);
/** Make a rotation Quat which will rotate vec1 to vec2.
Generally take adot product to get the angle between these
and then use a cross product to get the rotation axis
Watch out for the two special cases of when the vectors
are co-incident or opposite in direction.*/
void makeRotate( const Vec3& vec1, const Vec3& vec2 );
/** Return the angle and vector components represented by the quaternion.*/
void getRotate ( float& angle, float& x, float& y, float& z ) const;
/** Return the angle and vector represented by the quaternion.*/
void getRotate ( float& angle, Vec3& vec ) const;
/** Spherical Linear Interpolation.
As t goes from 0 to 1, the Quat object goes from "from" to "to". */
void slerp ( float t, const Quat& from, const Quat& to);
/** Set quaternion to be equivalent to specified matrix.*/
void set( const Matrix& m );
/** Get the equivalent matrix for this quaternion.*/
void get( Matrix& m ) const;
/** Get the equivalent matrix for this quaternion.*/
Matrix getMatrix() const
{
Matrix matrix;
get(matrix);
return matrix;
}
friend inline std::ostream& operator << (std::ostream& output, const Quat& vec);
}; // end of class prototype
inline std::ostream& operator << (std::ostream& output, const Quat& vec)
{
output << vec._fv[0] << " "
<< vec._fv[1] << " "
<< vec._fv[2] << " "
<< vec._fv[3];
return output; // to enable cascading
}
} // end of namespace
#endif