SO3Engine
SO3Euler.h
Go to the documentation of this file.
1
9#ifndef OGREEULER_H
10#define OGREEULER_H
11
12#include <Ogre.h>
13
14namespace Ogre
15{
16
24class Euler
25{
26public:
29 : mYaw(Ogre::Radian(0.0f)), mPitch(Ogre::Radian(0.0f)), mRoll(Ogre::Radian(0.0f)), mChanged(true)
30 {
31 }
32
39 Euler(const Ogre::Radian &y, const Ogre::Radian &p = Ogre::Radian(0.0f), const Ogre::Radian &r = Ogre::Radian(0.0f))
40 : mYaw(y), mPitch(p), mRoll(r), mChanged(true)
41 {
42 }
43
50 Euler(Ogre::Real y, Ogre::Real p = 0.0f, Ogre::Real r = 0.0f)
51 : mYaw(Ogre::Radian(y)), mPitch(Ogre::Radian(p)), mRoll(Ogre::Radian(r)), mChanged(true)
52 {
53 }
54
59 explicit Euler(const Ogre::Quaternion &quaternion)
60 {
61 fromQuaternion(quaternion);
62 }
63
64 explicit Euler(const Ogre::Matrix3 &matrix)
65 {
66 fromMatrix3(matrix);
67 }
68
70 inline Ogre::Radian getYaw() const { return mYaw; }
71
73 inline Ogre::Radian getPitch() const { return mPitch; }
74
76 inline Ogre::Radian getRoll() const { return mRoll; }
77
82 inline Euler &setYaw(Ogre::Radian y)
83 {
84 mYaw = y;
85 mChanged = true;
86 return *this;
87 }
88
93 inline Euler &setPitch(Ogre::Radian p)
94 {
95 mPitch = p;
96 mChanged = true;
97 return *this;
98 }
99
104 inline Euler &setRoll(Ogre::Radian r)
105 {
106 mRoll = r;
107 mChanged = true;
108 return *this;
109 }
110
117 inline Euler &setRotation(const Ogre::Radian &y, const Ogre::Radian &p, const Ogre::Radian &r)
118 {
119 mYaw = y;
120 mPitch = p;
121 mRoll = r;
122 mChanged = true;
123 return *this;
124 }
125
130 inline Euler &yaw(const Ogre::Radian &y)
131 {
132 mYaw += y;
133 mChanged = true;
134 return *this;
135 }
136
141 inline Euler &pitch(const Ogre::Radian &p)
142 {
143 mPitch += p;
144 mChanged = true;
145 return *this;
146 }
147
152 inline Euler &roll(const Ogre::Radian &r)
153 {
154 mRoll += r;
155 mChanged = true;
156 return *this;
157 }
158
165 inline Euler &rotate(const Ogre::Radian &y, const Ogre::Radian &p, const Ogre::Radian &r)
166 {
167 mYaw += y;
168 mPitch += p;
169 mRoll += r;
170 mChanged = true;
171 return *this;
172 }
173
175 inline Ogre::Vector3 getForward() { return toQuaternion() * Ogre::Vector3::NEGATIVE_UNIT_Z; }
176
178 inline Ogre::Vector3 getRight() { return toQuaternion() * Ogre::Vector3::UNIT_X; }
179
181 inline Ogre::Vector3 getUp() { return toQuaternion() * Ogre::Vector3::UNIT_Y; }
182
187 inline Ogre::Quaternion toQuaternion()
188 {
189 if(mChanged)
190 {
191 mCachedQuaternion = Ogre::Quaternion(mYaw, Ogre::Vector3::UNIT_Y) * Ogre::Quaternion(mPitch, Ogre::Vector3::UNIT_X) * Ogre::Quaternion(mRoll, Ogre::Vector3::UNIT_Z);
192 mChanged = false;
193 }
194 return mCachedQuaternion;
195 }
196
198 inline operator Ogre::Quaternion()
199 {
200 return toQuaternion();
201 }
202
207 inline Euler &fromQuaternion(const Ogre::Quaternion &quaternion)
208 {
209 Ogre::Matrix3 rotmat;
210 quaternion.ToRotationMatrix(rotmat);
211 fromMatrix3(rotmat);
212 return *this;
213 }
214
219 inline Euler &fromMatrix3(const Ogre::Matrix3 &matrix)
220 {
221 matrix.ToEulerAnglesYXZ(mYaw,mPitch,mRoll);
222 mChanged = true;
223 return *this;
224 }
225
232 inline Euler &setDirection(const Ogre::Vector3 &v, bool setYaw = true, bool setPitch = true)
233 {
234 Ogre::Vector3 d(v.normalisedCopy());
235 if(setPitch)
236 mPitch = Ogre::Math::ASin(d.y);
237 if(setYaw)
238 mYaw = Ogre::Math::ATan2(-d.x, -d.z);//+Ogre::Math::PI/2.0;
240 return *this;
241 }
242
250 inline Euler &normalise(bool normYaw = true, bool normPitch = true, bool normRoll = true)
251 {
252 if(normYaw)
253 {
254 Ogre::Real yaw = mYaw.valueRadians();
255 if(yaw < -Ogre::Math::PI)
256 {
257 yaw = fmod(yaw, Ogre::Math::PI * 2.0f);
258 if(yaw < -Ogre::Math::PI)
259 {
260 yaw += Ogre::Math::PI * 2.0f;
261 }
262 mYaw = yaw;
263 mChanged = true;
264 }
265 else if(yaw > Ogre::Math::PI)
266 {
267 yaw = fmod(yaw, Ogre::Math::PI * 2.0f);
268 if(yaw > Ogre::Math::PI)
269 {
270 yaw -= Ogre::Math::PI * 2.0f;
271 }
272 mYaw = yaw;
273 mChanged = true;
274 }
275 }
276 if(normPitch)
277 {
278 Ogre::Real pitch = mPitch.valueRadians();
279 if(pitch < -Ogre::Math::PI)
280 {
281 pitch = fmod(pitch, Ogre::Math::PI * 2.0f);
282 if(pitch < -Ogre::Math::PI)
283 {
284 pitch += Ogre::Math::PI * 2.0f;
285 }
286 mPitch = pitch;
287 mChanged = true;
288 }
289 else if(pitch > Ogre::Math::PI)
290 {
291 pitch = fmod(pitch, Ogre::Math::PI * 2.0f);
292 if(pitch > Ogre::Math::PI)
293 {
294 pitch -= Ogre::Math::PI * 2.0f;
295 }
296 mPitch = pitch;
297 mChanged = true;
298 }
299 }
300 if(normRoll)
301 {
302 Ogre::Real roll= mRoll.valueRadians();
303 if(roll < -Ogre::Math::PI)
304 {
305 roll = fmod(roll, Ogre::Math::PI * 2.0f);
306 if(roll < -Ogre::Math::PI)
307 {
308 roll += Ogre::Math::PI * 2.0f;
309 }
310 mRoll = roll;
311 mChanged = true;
312 }
313 else if(roll > Ogre::Math::PI)
314 {
315 roll = fmod(roll, Ogre::Math::PI * 2.0f);
316 if(roll > Ogre::Math::PI)
317 {
318 roll -= Ogre::Math::PI * 2.0f;
319 }
320 mRoll = roll;
321 mChanged = true;
322 }
323 }
324 return *this;
325 }
326
338 inline Euler getRotationTo(const Ogre::Vector3 &dir, bool setYaw = true, bool setPitch = true, bool shortest = true)
339 {
340 Euler t1;
341 Euler t2;
342 t1.setDirection(dir, setYaw, setPitch);
343 t2 = t1 - *this;
344 if(shortest && setYaw)
345 {
346 t2.normalise();
347 }
348 return t2;
349 }
350
352 inline Euler &limitYaw(const Ogre::Radian &limit)
353 {
354 if(mYaw > limit)
355 {
356 mYaw = limit;
357 mChanged = true;
358 }
359 else if(mYaw < -limit)
360 {
361 mYaw = -limit;
362 mChanged = true;
363 }
364 return *this;
365 }
366
368 inline Euler &limitPitch(const Ogre::Radian &limit)
369 {
370 if(mPitch > limit)
371 {
372 mPitch = limit;
373 mChanged = true;
374 }
375 else if(mPitch < -limit)
376 {
377 mPitch = -limit;
378 mChanged = true;
379 }
380 return *this;
381 }
382
384 inline Euler &limitRoll(const Ogre::Radian &limit)
385 {
386 if(mRoll > limit)
387 {
388 mRoll = limit;
389 mChanged = true;
390 }
391 else if(mRoll < -limit)
392 {
393 mRoll = -limit;
394 mChanged = true;
395 }
396 return *this;
397 }
398
400 inline friend std::ostream &operator<<(std::ostream &o, const Euler &e)
401 {
402 o << "<Y:" << e.mYaw << ", P:" << e.mPitch << ", R:" << e.mRoll << ">";
403 return o;
404 }
405
407 inline Euler operator+(const Euler &rhs) const
408 {
409 return Euler(mYaw + rhs.mYaw, mPitch + rhs.mPitch, mRoll + rhs.mRoll);
410 }
411
416 inline Euler operator-(const Euler &rhs) const
417 {
418 return Euler(mYaw - rhs.mYaw, mPitch - rhs.mPitch, mRoll - rhs.mRoll);
419 }
420
422 inline Euler operator*(Ogre::Real rhs) const
423 {
424 return Euler(mYaw * rhs, mPitch * rhs, mRoll * rhs);
425 }
426
428 inline friend Euler operator*(Ogre::Real lhs, const Euler &rhs)
429 {
430 return Euler(lhs * rhs.mYaw, lhs * rhs.mPitch, lhs * rhs.mRoll);
431 }
432
438 inline Ogre::Quaternion operator*(const Euler &rhs) const
439 {
440 Euler e1(*this), e2(rhs);
441 return e1.toQuaternion()*e2.toQuaternion();
442 }
443
445 inline Ogre::Vector3 operator*(const Ogre::Vector3 &rhs)
446 {
447 return toQuaternion() * rhs;
448 }
449
451 inline Euler& operator=(const Euler& src)
452 {
453 setRotation(src.getYaw(), src.getPitch(), src.getRoll());
454 return *this;
455 }
456
458 inline Euler& operator=(const Ogre::Quaternion &quaternion)
459 {
460 fromQuaternion(quaternion);
461 return *this;
462 }
463
465 inline Euler& operator=(const Ogre::Matrix3 &matrix)
466 {
467 fromMatrix3(matrix);
468 return *this;
469 }
470
471protected:
472 Ogre::Radian mYaw;
473 Ogre::Radian mPitch;
474 Ogre::Radian mRoll;
475 Ogre::Quaternion mCachedQuaternion;
476 bool mChanged;
477};
478
479}
480
481#endif
Class for Euler rotations.
Definition SO3Euler.h:25
friend Euler operator*(Ogre::Real lhs, const Euler &rhs)
Interpolate the euler angle by lhs.
Definition SO3Euler.h:428
Ogre::Radian mPitch
Rotation around the X axis.
Definition SO3Euler.h:473
bool mChanged
Is the cached quaternion out of date?
Definition SO3Euler.h:476
Euler & rotate(const Ogre::Radian &y, const Ogre::Radian &p, const Ogre::Radian &r)
Apply all relative rotations at once.
Definition SO3Euler.h:165
Euler & limitYaw(const Ogre::Radian &limit)
Clamp the yaw angle to a range of +/-limit.
Definition SO3Euler.h:352
Euler & setPitch(Ogre::Radian p)
Set the pitch.
Definition SO3Euler.h:93
Euler()
Default constructor.
Definition SO3Euler.h:28
Ogre::Radian mYaw
Rotation around the Y axis.
Definition SO3Euler.h:472
Euler getRotationTo(const Ogre::Vector3 &dir, bool setYaw=true, bool setPitch=true, bool shortest=true)
Return the relative euler angles required to rotate from the current forward direction to the specifi...
Definition SO3Euler.h:338
Ogre::Vector3 getUp()
Get a vector pointing up.
Definition SO3Euler.h:181
Ogre::Radian getYaw() const
Get the Yaw angle.
Definition SO3Euler.h:70
Euler & fromMatrix3(const Ogre::Matrix3 &matrix)
Calculate the current euler angles of a given matrix object.
Definition SO3Euler.h:219
Ogre::Vector3 operator*(const Ogre::Vector3 &rhs)
Apply the euler rotation to the vector rhs.
Definition SO3Euler.h:445
Euler(Ogre::Real y, Ogre::Real p=0.0f, Ogre::Real r=0.0f)
Constructor which takes yaw, pitch and roll values as reals (radians).
Definition SO3Euler.h:50
Euler & yaw(const Ogre::Radian &y)
Apply a relative yaw.
Definition SO3Euler.h:130
Ogre::Vector3 getForward()
Get a vector pointing forwards.
Definition SO3Euler.h:175
Euler & fromQuaternion(const Ogre::Quaternion &quaternion)
Calculate the current euler angles of a given quaternion object.
Definition SO3Euler.h:207
Ogre::Vector3 getRight()
Get a vector pointing to the right.
Definition SO3Euler.h:178
Ogre::Quaternion toQuaternion()
Calculate the quaternion of the euler object.
Definition SO3Euler.h:187
Euler & roll(const Ogre::Radian &r)
Apply a relative roll.
Definition SO3Euler.h:152
Euler(const Ogre::Matrix3 &matrix)
Definition SO3Euler.h:64
Euler & operator=(const Euler &src)
Copy assignment operator (Euler)
Definition SO3Euler.h:451
Euler & operator=(const Ogre::Matrix3 &matrix)
Copy assignment operator (Matrix3)
Definition SO3Euler.h:465
Ogre::Radian getRoll() const
Get the Roll angle.
Definition SO3Euler.h:76
Ogre::Quaternion operator*(const Euler &rhs) const
Multiply two eulers.
Definition SO3Euler.h:438
Euler & pitch(const Ogre::Radian &p)
Apply a relative pitch.
Definition SO3Euler.h:141
Ogre::Quaternion mCachedQuaternion
Cached quaternion equivalent of this euler object.
Definition SO3Euler.h:475
Euler(const Ogre::Quaternion &quaternion)
Default constructor with presets.
Definition SO3Euler.h:59
Euler & normalise(bool normYaw=true, bool normPitch=true, bool normRoll=true)
Normalise the selected rotations to be within the +/-180 degree range.
Definition SO3Euler.h:250
Euler operator-(const Euler &rhs) const
Subtract two euler objects.
Definition SO3Euler.h:416
Euler & setRoll(Ogre::Radian r)
Set the roll.
Definition SO3Euler.h:104
Euler & setRotation(const Ogre::Radian &y, const Ogre::Radian &p, const Ogre::Radian &r)
Set all rotations at once.
Definition SO3Euler.h:117
Euler & setYaw(Ogre::Radian y)
Set the yaw.
Definition SO3Euler.h:82
Euler & limitRoll(const Ogre::Radian &limit)
Clamp the roll angle to a range of +/-limit.
Definition SO3Euler.h:384
Euler & setDirection(const Ogre::Vector3 &v, bool setYaw=true, bool setPitch=true)
Set the yaw and pitch to face in the given direction.
Definition SO3Euler.h:232
Euler & limitPitch(const Ogre::Radian &limit)
Clamp the pitch angle to a range of +/-limit.
Definition SO3Euler.h:368
Ogre::Radian getPitch() const
Get the Pitch angle.
Definition SO3Euler.h:73
friend std::ostream & operator<<(std::ostream &o, const Euler &e)
Stream operator, for printing the euler component angles to a stream.
Definition SO3Euler.h:400
Euler operator*(Ogre::Real rhs) const
Interpolate the euler angles by rhs.
Definition SO3Euler.h:422
Euler & operator=(const Ogre::Quaternion &quaternion)
Copy assignment operator (Quaternion)
Definition SO3Euler.h:458
Ogre::Radian mRoll
Rotation around the Z axis.
Definition SO3Euler.h:474
Euler operator+(const Euler &rhs) const
Add two euler objects.
Definition SO3Euler.h:407
Euler(const Ogre::Radian &y, const Ogre::Radian &p=Ogre::Radian(0.0f), const Ogre::Radian &r=Ogre::Radian(0.0f))
Constructor which takes yaw, pitch and roll values.
Definition SO3Euler.h:39