00001 #pragma once
00002
00003 #include <math.h>
00004 #include "VCommon.h"
00005 #include "VVector.h"
00006
00007
00008 class VQuaternion
00009 {
00010 public:
00011
00012 static VVector WORLD_X_AXIS;
00013 static VVector WORLD_Y_AXIS;
00014 static VVector WORLD_Z_AXIS;
00015 static VVector FORWARD_VECTOR;
00016
00017 VQuaternion()
00018 {
00019 set(VVector(0.0f,0.0f,0.0f),1.0f);
00020 };
00021
00022 VQuaternion(const VVector &vecV, const float fS)
00023 {
00024 set(vecV,fS);
00025 };
00026
00027 VQuaternion(const VVector &vecV)
00028 {
00029 set(vecV,0.0f);
00030 };
00031
00032 VQuaternion(const float fAngle, const VVector &vecAxis)
00033 {
00034 float fD = fAngle * 0.5f;
00035 set(vecAxis.getNormalized() * sinf(fD),cosf(fD));
00036 };
00037
00038 VQuaternion(const VVector &vecFrom, const VVector &vecTo)
00039 {
00040 const float fAngle = acosf(vecFrom.getNormalized().getDot(vecTo.getNormalized()));
00041 const VVector vecAxis = vecFrom.getNormalized().getCross(vecTo.getNormalized());
00042 (*this) = VQuaternion(fAngle,vecAxis);
00043 };
00044
00045 ~VQuaternion()
00046 {
00047 };
00048
00049 void set(const VVector &vecV, const float fS)
00050 {
00051 m_vecVector = vecV;
00052 m_fScalar = fS;
00053 normalize();
00054 };
00055
00056 void setVector(const VVector &vecV)
00057 {
00058 set(vecV,getScalar());
00059 };
00060
00061 void setScalar(const float fS)
00062 {
00063 set(getVector(),fS);
00064 };
00065
00066 const VVector & getVector() const
00067 {
00068 return m_vecVector;
00069 };
00070
00071 const float & getScalar() const
00072 {
00073 return m_fScalar;
00074 };
00075
00076 const float getMagnitude() const
00077 {
00078 return sqrtf( getScalar()*getScalar() + getVector().getMagnitude() * getVector().getMagnitude());
00079 };
00080
00081 const VQuaternion getNormalized() const
00082 {
00083 VQuaternion quaNew = *this;
00084 float fMagnitude = quaNew.getMagnitude();
00085
00086 if (fMagnitude > 0.0f)
00087 {
00088 quaNew.m_vecVector /= fMagnitude;
00089 quaNew.m_fScalar /= fMagnitude;
00090 }
00091
00092 return quaNew;
00093 };
00094
00095 const VQuaternion getInverse() const
00096 {
00097 return VQuaternion(getVector()*-1.0f,getScalar()).getNormalized();
00098 };
00099
00100 void normalize()
00101 {
00102 (*this) = getNormalized();
00103 };
00104
00105 void invert()
00106 {
00107 (*this) = getInverse();
00108 };
00109
00110 VVector getForwardVector()
00111 {
00112 return (*this) * FORWARD_VECTOR;
00113 }
00114
00115 VVector getUpVector()
00116 {
00117 return (*this) * WORLD_Y_AXIS;
00118 }
00119
00120 VVector getRightVector()
00121 {
00122 return (*this) * WORLD_X_AXIS;
00123 }
00124
00125 static VQuaternion generateRotationX(float mdegrees)
00126 {
00127 return VQuaternion(WORLD_X_AXIS, mdegrees);
00128 }
00129
00130 static VQuaternion generateRotationY(float mdegrees)
00131 {
00132 return VQuaternion(WORLD_Y_AXIS, mdegrees);
00133 }
00134
00135 static VQuaternion generateRotationZ(float mdegrees)
00136 {
00137 return VQuaternion (WORLD_Z_AXIS, mdegrees);
00138 }
00139
00140 void applyRotationX(float mdegrees)
00141 {
00142 VQuaternion tmp = generateRotationX(mdegrees);
00143 (*this) = (*this) * tmp;
00144 }
00145
00146 void applyRotationY(float mdegrees)
00147 {
00148 VQuaternion tmp = generateRotationY(mdegrees);
00149 (*this) = (*this) * tmp;
00150 }
00151
00152 void applyRotationZ(float mdegrees)
00153 {
00154 VQuaternion tmp = generateRotationZ(mdegrees);
00155 (*this) = (*this) * tmp;
00156 }
00157
00158 const bool operator==(const VQuaternion & quaOther) const
00159 {
00160 return (getVector() == quaOther.getVector()) && (getScalar() == quaOther.getScalar());
00161 };
00162
00163 const bool operator!=(const VQuaternion & quaOther) const
00164 {
00165 return !(*this == quaOther);
00166 };
00167
00168 const VQuaternion & operator*=(const float & fOther)
00169 {
00170 set(getVector() * fOther,getScalar() * fOther);
00171 return *this;
00172 };
00173
00174 const VQuaternion & operator/=(const float & fOther)
00175 {
00176 set(getVector() / fOther,getScalar() / fOther);
00177 return *this;
00178 };
00179
00180 const VQuaternion & operator+=(const VQuaternion & quaOther)
00181 {
00182 set(getVector() + quaOther.getVector(),getScalar() + quaOther.getScalar());
00183 return *this;
00184 };
00185
00186 const VQuaternion & operator-=(const VQuaternion & quaOther)
00187 {
00188 set(getVector() - quaOther.getVector(),getScalar() - quaOther.getScalar());
00189 return *this;
00190 };
00191
00192 const VQuaternion & operator*=(const VQuaternion& quaOther)
00193 {
00194 set(
00195 getVector().getCross(quaOther.getVector()) + getVector() * quaOther.getScalar() + quaOther.getVector() * getScalar(),
00196 getScalar() * quaOther.getScalar() - getVector().getDot(quaOther.getVector()));
00197 return *this;
00198 };
00199
00200 const VQuaternion operator*(const float fOther) const
00201 {
00202 VQuaternion quaNew = *this;
00203 quaNew *= fOther;
00204 return quaNew;
00205 };
00206
00207 const VQuaternion operator/(const float fOther) const
00208 {
00209 VQuaternion quaNew = *this;
00210 quaNew *= fOther;
00211 return quaNew;
00212 };
00213
00214 const VQuaternion operator+(const VQuaternion & quaOther) const
00215 {
00216 VQuaternion quaNew = *this;
00217 quaNew += quaOther;
00218 return quaNew;
00219 };
00220
00221 const VQuaternion operator-(const VQuaternion & quaOther) const
00222 {
00223 VQuaternion quaNew = *this;
00224 quaNew += quaOther;
00225 return quaNew;
00226 };
00227
00228 const VQuaternion operator*(const VQuaternion & quaOther) const
00229 {
00230 VQuaternion quaNew = *this;
00231 quaNew *= quaOther;
00232 return quaNew;
00233 };
00234
00235 const VVector operator*(const VVector &vecOther) const
00236 {
00237 VQuaternion quaRotated = (*this * VQuaternion(vecOther) * getInverse());
00238 return quaRotated.getVector() * vecOther.getMagnitude();
00239 };
00240
00241 private:
00242 VVector m_vecVector;
00243 float m_fScalar;
00244 };
00245
00246
00247 inline std::ostream & operator << (std::ostream & os, const VQuaternion & quaQuaternion)
00248 {
00249 os << "(" << quaQuaternion.getVector() << ";" << quaQuaternion.getScalar() << ")";
00250 return os;
00251 }
00252
00253 inline std::istream & operator>> (std::istream & is, VQuaternion & quaQuaternion)
00254 {
00255 VVector vecV;
00256 float fS;
00257
00258 if (is >> eat("(") >> vecV >> eat(";") >> fS >> eat(")"))
00259 quaQuaternion.set(vecV,fS);
00260
00261 return is;
00262 }