Changeset 6616 in orxonox.OLD for trunk/src/lib/math/vector.cc
- Timestamp:
- Jan 19, 2006, 12:27:45 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/math/vector.cc
r5688 r6616 66 66 PRINT(0)(" lenght: %f", len()); 67 67 PRINT(0)("\n"); 68 }69 70 /////////////////71 /* QUATERNIONS */72 /////////////////73 /**74 * calculates a lookAt rotation75 * @param dir: the direction you want to look76 * @param up: specify what direction up should be77 78 Mathematically this determines the rotation a (0,0,1)-Vector has to undergo to point79 the same way as dir. If you want to use this with cameras, you'll have to reverse the80 dir Vector (Vector(0,0,0) - your viewing direction) or you'll point the wrong way. You81 can use this for meshes as well (then you do not have to reverse the vector), but keep82 in mind that if you do that, the model's front has to point in +z direction, and left83 and right should be -x or +x respectively or the mesh wont rotate correctly.84 *85 * @TODO !!! OPTIMIZE THIS !!!86 */87 Quaternion::Quaternion (const Vector& dir, const Vector& up)88 {89 Vector z = dir.getNormalized();90 Vector x = up.cross(z).getNormalized();91 Vector y = z.cross(x);92 93 float m[4][4];94 m[0][0] = x.x;95 m[0][1] = x.y;96 m[0][2] = x.z;97 m[0][3] = 0;98 m[1][0] = y.x;99 m[1][1] = y.y;100 m[1][2] = y.z;101 m[1][3] = 0;102 m[2][0] = z.x;103 m[2][1] = z.y;104 m[2][2] = z.z;105 m[2][3] = 0;106 m[3][0] = 0;107 m[3][1] = 0;108 m[3][2] = 0;109 m[3][3] = 1;110 111 *this = Quaternion (m);112 }113 114 /**115 * calculates a rotation from euler angles116 * @param roll: the roll in radians117 * @param pitch: the pitch in radians118 * @param yaw: the yaw in radians119 */120 Quaternion::Quaternion (float roll, float pitch, float yaw)121 {122 float cr, cp, cy, sr, sp, sy, cpcy, spsy;123 124 // calculate trig identities125 cr = cos(roll/2);126 cp = cos(pitch/2);127 cy = cos(yaw/2);128 129 sr = sin(roll/2);130 sp = sin(pitch/2);131 sy = sin(yaw/2);132 133 cpcy = cp * cy;134 spsy = sp * sy;135 136 w = cr * cpcy + sr * spsy;137 v.x = sr * cpcy - cr * spsy;138 v.y = cr * sp * cy + sr * cp * sy;139 v.z = cr * cp * sy - sr * sp * cy;140 }141 142 /**143 * convert the Quaternion to a 4x4 rotational glMatrix144 * @param m: a buffer to store the Matrix in145 */146 void Quaternion::matrix (float m[4][4]) const147 {148 float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;149 150 // calculate coefficients151 x2 = v.x + v.x;152 y2 = v.y + v.y;153 z2 = v.z + v.z;154 xx = v.x * x2; xy = v.x * y2; xz = v.x * z2;155 yy = v.y * y2; yz = v.y * z2; zz = v.z * z2;156 wx = w * x2; wy = w * y2; wz = w * z2;157 158 m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz;159 m[2][0] = xz + wy; m[3][0] = 0.0;160 161 m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz);162 m[2][1] = yz - wx; m[3][1] = 0.0;163 164 m[0][2] = xz - wy; m[1][2] = yz + wx;165 m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0;166 167 m[0][3] = 0; m[1][3] = 0;168 m[2][3] = 0; m[3][3] = 1;169 }170 171 /**172 * performs a smooth move.173 * @param from where174 * @param to where175 * @param t the time this transformation should take value [0..1]176 * @returns the Result of the smooth move177 */178 Quaternion Quaternion::quatSlerp(const Quaternion& from, const Quaternion& to, float t)179 {180 float tol[4];181 double omega, cosom, sinom, scale0, scale1;182 // float DELTA = 0.2;183 184 cosom = from.v.x * to.v.x + from.v.y * to.v.y + from.v.z * to.v.z + from.w * to.w;185 186 if( cosom < 0.0 )187 {188 cosom = -cosom;189 tol[0] = -to.v.x;190 tol[1] = -to.v.y;191 tol[2] = -to.v.z;192 tol[3] = -to.w;193 }194 else195 {196 tol[0] = to.v.x;197 tol[1] = to.v.y;198 tol[2] = to.v.z;199 tol[3] = to.w;200 }201 202 omega = acos(cosom);203 sinom = sin(omega);204 scale0 = sin((1.0 - t) * omega) / sinom;205 scale1 = sin(t * omega) / sinom;206 return Quaternion(Vector(scale0 * from.v.x + scale1 * tol[0],207 scale0 * from.v.y + scale1 * tol[1],208 scale0 * from.v.z + scale1 * tol[2]),209 scale0 * from.w + scale1 * tol[3]);210 }211 212 213 /**214 * convert a rotational 4x4 glMatrix into a Quaternion215 * @param m: a 4x4 matrix in glMatrix order216 */217 Quaternion::Quaternion (float m[4][4])218 {219 220 float tr, s, q[4];221 int i, j, k;222 223 int nxt[3] = {1, 2, 0};224 225 tr = m[0][0] + m[1][1] + m[2][2];226 227 // check the diagonal228 if (tr > 0.0)229 {230 s = sqrt (tr + 1.0);231 w = s / 2.0;232 s = 0.5 / s;233 v.x = (m[1][2] - m[2][1]) * s;234 v.y = (m[2][0] - m[0][2]) * s;235 v.z = (m[0][1] - m[1][0]) * s;236 }237 else238 {239 // diagonal is negative240 i = 0;241 if (m[1][1] > m[0][0]) i = 1;242 if (m[2][2] > m[i][i]) i = 2;243 j = nxt[i];244 k = nxt[j];245 246 s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + 1.0);247 248 q[i] = s * 0.5;249 250 if (s != 0.0) s = 0.5 / s;251 252 q[3] = (m[j][k] - m[k][j]) * s;253 q[j] = (m[i][j] + m[j][i]) * s;254 q[k] = (m[i][k] + m[k][i]) * s;255 256 v.x = q[0];257 v.y = q[1];258 v.z = q[2];259 w = q[3];260 }261 }262 263 /**264 * outputs some nice formated debug information about this quaternion265 */266 void Quaternion::debug()267 {268 PRINT(0)("real a=%f; imag: x=%f y=%f z=%f\n", w, v.x, v.y, v.z);269 }270 271 void Quaternion::debug2()272 {273 Vector axis = this->getSpacialAxis();274 PRINT(0)("angle = %f, axis: ax=%f, ay=%f, az=%f\n", this->getSpacialAxisAngle(), axis.x, axis.y, axis.z );275 68 } 276 69
Note: See TracChangeset
for help on using the changeset viewer.