1 /* ResidualVM - A 3D game interpreter 2 * 3 * ResidualVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 // Quaternion-math borrowed from plib http://plib.sourceforge.net/index.html 24 // Which is covered by LGPL2 25 // And has this additional copyright note: 26 /* 27 Quaternion routines are Copyright (C) 1999 28 Kevin B. Thompson <kevinbthompson@yahoo.com> 29 Modified by Sylvan W. Clebsch <sylvan@stanford.edu> 30 Largely rewritten by "Negative0" <negative0@earthlink.net> 31 */ 32 33 #ifndef MATH_QUAT_H 34 #define MATH_QUAT_H 35 36 #include "common/scummsys.h" 37 #include "common/endian.h" 38 39 #include "math/rotation3d.h" 40 #include "math/vector.h" 41 #include "math/angle.h" 42 #include "math/vector4d.h" 43 #include "math/matrix4.h" 44 45 namespace Math { 46 47 class Quaternion : public Vector4d { 48 public: 49 /** 50 * Default Constructor, creates an identity Quaternion with no rotation. 51 */ Quaternion()52 Quaternion() : Vector4d(0, 0, 0, 1.0) {} 53 54 /** 55 * Constructor from four floats in the order X,Y,Z,W 56 * The initial values should be normalized, otherwise call normalize() after creation 57 * @param lx The X value of the Quaternion 58 * @param ly The Y value of the Quaternion 59 * @param lz The Z value of the Quaternion 60 * @param lw The W value of the Quaternion 61 */ Quaternion(float lx,float ly,float lz,float lw)62 Quaternion(float lx, float ly, float lz, float lw) : Vector4d(lx, ly, lz, lw) {} 63 64 /** 65 * Constructor from an existing Quaternion 66 * @param q The existing quaternion 67 * @return The new Quaternion 68 */ Quaternion(const Quaternion & q)69 Quaternion(const Quaternion &q) : Vector4d(q.x(), q.y(), q.z(), q.w()) {} 70 71 /** 72 * Constructor from a vector of four floats in the order X,Y,Z,W 73 * The initial values should be normalized, otherwise call normalize() after creation 74 * @param vec The vector of floats comprising the quaternion 75 * @return The new Quaternion 76 */ Quaternion(const Vector4d & vec)77 Quaternion(const Vector4d &vec) : Vector4d(vec.x(), vec.y(), vec.z(), vec.w()) {} 78 79 /** 80 * Constructor from a rotation matrix 81 * @param m The rotation matrix 82 * @return The new Quaternion 83 */ 84 Quaternion(const Matrix3 &m); 85 86 /** 87 * Constructor from a rotation matrix 88 * @param m The rotation matrix 89 * @return The new Quaternion 90 */ 91 Quaternion(const Matrix4 &m); 92 93 /** Set the Quaternion from a rotation matrix 94 * @param m The matrix used to set the Quaternion 95 */ 96 void fromMatrix(const Matrix3 &m); 97 98 /** 99 * Constructor from an axis vector and the angle to rotate on that axis 100 * @param axis The axis to perform the rotation around 101 * @param angle The angle amount to rotate 102 * @return The new Quaternion 103 */ 104 Quaternion(const Vector3d &axis, const Angle &angle); 105 106 /** 107 * Constructs a Quaternion from Euler Coordinates 108 * @param first The Euler Angle for the first Axis 109 * @param second The Euler Angle for the second Axis 110 * @param third The Euler Angle for the third Axis 111 * @param order The Euler Order, specified in Rotation3D 112 * @return The new Quaternion 113 */ 114 static Quaternion fromEuler(const Angle &first, const Angle &second, const Angle &third, EulerOrder order); 115 116 /** 117 * Returns Euler Angles based on the Euler Order 118 * @param first The Euler Angle for the first Axis 119 * @param second The Euler Angle for the second Axis 120 * @param third The Euler Angle for the third Axis 121 * @param order The Euler Order, specified in Rotation3D 122 * @return The new Quaternion 123 */ 124 void getEuler(Angle *first, Angle *second, Angle *third, EulerOrder order) const; 125 126 /** 127 * Create a Quaternion from a rotation around the X Axis 128 * @param angle The Euler Angle for rotation 129 * @return The resulting Quaternion 130 */ 131 static Quaternion xAxis(const Angle &angle); 132 133 /** 134 * Create a Quaternion from a rotation around the Y Axis 135 * @param angle The Euler Angle for rotation 136 * @return The resulting Quaternion 137 */ 138 static Quaternion yAxis(const Angle &angle); 139 140 /** 141 * Create a Quaternion from a rotation around the Z Axis 142 * @param angle The Euler Angle for rotation 143 * @return The resulting Quaternion 144 */ 145 static Quaternion zAxis(const Angle &angle); 146 147 /** 148 * Normalize the Quaternion 149 * @return A reference to this quaternion 150 */ 151 Quaternion &normalize(); 152 153 /** 154 * Rotate a vector by a Quaternion 155 * @param v The Vector to be rotated 156 */ 157 void transform(Vector3d &v) const; 158 159 /** 160 * Converts from this Quaternion to a Matrix4 representation 161 * @return The resulting matrix 162 */ 163 Matrix4 toMatrix() const; 164 165 /** 166 * Converts from this Quaternion to a Matrix4 representation 167 * @param dst The resulting matrix 168 */ 169 void toMatrix(Matrix4 &dst) const; 170 171 /** 172 * Make a new Quaternion that's the inverse of this Quaternion 173 * @return The resulting Quaternion 174 */ 175 Quaternion inverse() const; 176 177 /** 178 * Slerps between this quaternion and to by factor t 179 * @param to the quaternion to slerp between 180 * @param t factor to slerp by. 181 * @return the resulting quaternion. 182 */ 183 Quaternion slerpQuat(const Quaternion& to, const float t) const; 184 185 /** 186 * Get the direction vector specified by col 187 * @param col Column in the rotation matrix to get the direction vector from 188 * @return The resulting Vector3d 189 */ 190 Vector3d directionVector(const int col) const; 191 192 /** 193 * Get the angle between two quaternions 194 * @param to The quaternion we're comparing against 195 * @return The angle between the two 196 */ 197 Angle getAngleBetween(const Quaternion &to); 198 199 /** 200 * Assignment operator 201 * @param vec The source quaternion 202 * @return A reference to this Quaternion 203 */ 204 Quaternion& operator=(const Quaternion& quat); 205 206 /** 207 * Multiply two Quaternions 208 * @param quat The Quaternion multiplicand 209 * @return The result of the multiplication 210 */ 211 Quaternion operator*(const Quaternion &quat) const; 212 Quaternion& operator*=(const Quaternion &quat); 213 214 /** 215 * Multiply this Quaternion by a constant 216 * @param quat The Quaternion multiplicand 217 * @return The result of the multiplication 218 */ 219 Quaternion operator*(const float c) const; 220 221 /** 222 * Sum two quaternions 223 * @param quat The Quaternion to be added 224 * @return The result of the addition 225 */ 226 Quaternion operator+(const Quaternion &o) const; 227 Quaternion& operator+=(const Quaternion &o); 228 229 /** 230 * Compare quaternions 231 * @param quat The Quaternion to be compared 232 * @return The result of the comparison 233 */ 234 bool operator==(const Quaternion &o) const; 235 bool operator!=(const Quaternion &o) const; 236 }; 237 238 } // end of namespace Math 239 240 #endif 241