Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*
   Copyright (c) 2017 DIVIDE-Studio
   Copyright (c) 2009 Ionut Cava

   This file is part of DIVIDE Framework.

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software
   and associated documentation files (the "Software"), to deal in the Software
   without restriction,
   including without limitation the rights to use, copy, modify, merge, publish,
   distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so,
   subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED,
   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
   PARTICULAR PURPOSE AND NONINFRINGEMENT.
   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
   DAMAGES OR OTHER LIABILITY,
   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
   IN CONNECTION WITH THE SOFTWARE
   OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 */

#ifndef _QUATERNION_H_
#define _QUATERNION_H_

/*
http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation
Quaternion class based on code from " OpenGL:Tutorials:Using Quaternions to
represent rotation "
*/
#include "Core/Math/Headers/MathMatrices.h"

namespace Divide {

template <typename T>
class Quaternion {
    static_assert(std::is_arithmetic<T>::value &&
                  !std::is_same<T, bool>::value,
                  "non-arithmetic quaternion type");
   public:
    Quaternion();
    Quaternion(T x, T y, T z, T w);
    Quaternion(const vec4<T>& values);

    template <typename U = T>
    Quaternion(__m128 reg, typename std::enable_if<std::is_same<U, F32>::value>::type* = nullptr);

    Quaternion(const mat3<T>& rotationMatrix);
    Quaternion(const vec3<T>& axis, Angle::DEGREES<T> angle);
    Quaternion(Angle::DEGREES<T> pitch, Angle::DEGREES<T> yaw, Angle::DEGREES<T> roll);
    Quaternion(const Quaternion& q);

    Quaternion& operator=(const Quaternion& q);

    inline T dot(const Quaternion& rq) const;
    inline T magnitude() const;
    inline T magnituteSq() const;

    inline bool compare(const Quaternion& rq, Angle::DEGREES<T> tolerance = 1e-3f) const;

    inline void set(const vec4<T>& values);
    inline void set(T x, T y, T z, T w);
    inline void set(const Quaternion& q);

    //! normalizing a quaternion works similar to a vector. This method will not
    //do anything
    //! if the quaternion is close enough to being unit-length.
    inline void normalize();
    inline Quaternion inverse() const;

    //! We need to get the inverse of a quaternion to properly apply a
    //quaternion-rotation to a vector
    //! The conjugate of a quaternion is the same as the inverse, as long as the
    //quaternion is unit-length
    inline Quaternion getConjugate() const;

    //! Multiplying q1 with q2 applies the rotation q2 to q1
    //! the constructor takes its arguments as (x, y, z, w)
    inline Quaternion operator*(const Quaternion& rq) const;

    //! Multiply so that rotations are applied in a left to right order.
    inline Quaternion& operator*=(const Quaternion& rq);


    //! Dividing q1 by q2
    inline Quaternion operator/(const Quaternion& rq) const;
    inline Quaternion& operator/=(const Quaternion& rq);

    //! Multiplying a quaternion q with a vector v applies the q-rotation to v
    vec3<T> operator*(const vec3<T>& vec) const;

    bool operator==(const Quaternion& rq) const;
    bool operator!=(const Quaternion& rq) const;

    inline Quaternion& operator+=(const Quaternion& rq);

    inline Quaternion& operator-=(const Quaternion& rq);

    inline Quaternion& operator*=(T scalar);

    inline Quaternion& operator/=(T scalar);

    inline Quaternion operator+(const Quaternion& rq) const;

    inline Quaternion operator-(const Quaternion& rq) const;

    inline Quaternion operator*(T scalar) const;

    inline Quaternion operator/(T scalar) const;

    inline void slerp(const Quaternion& q, F32 t);

    void slerp(const Quaternion& q0, const Quaternion& q1, F32 t);

    //! Convert from Axis Angle
    void fromAxisAngle(const vec3<T>& v, Angle::DEGREES<T> angle);

    inline void fromEuler(const vec3<Angle::DEGREES<T>>& v);

    //! Convert from Euler Angles
    void fromEuler(Angle::DEGREES<T> pitch, Angle::DEGREES<T> yaw, Angle::DEGREES<T> roll);

    void fromLookAt(const vec3<F32>& fwdDirection, const vec3<F32>& upDirection);

    // a la Ogre3D
    void fromMatrix(const mat3<T>& rotationMatrix);

    //! Convert to Matrix
    void getMatrix(mat3<F32>& outMatrix) const;

    //! Convert to Axis/Angles
    void getAxisAngle(vec3<T>* axis, Angle::DEGREES<T>* angle) const;

    void getEuler(vec3<Angle::RADIANS<T>>& euler) const;


    /// X/Y/Z Axis get/set a la Ogre: OgreQuaternion.cpp
    void fromAxes(const vec3<T>* axis);
    void fromAxes(const vec3<T>& xAxis, const vec3<T>& yAxis, const vec3<T>& zAxis);
    void toAxes(vec3<T>* axis) const;
    void toAxes(vec3<T>& xAxis, vec3<T>& yAxis, vec3<T>& zAxis) const;
    vec3<T> xAxis() const;
    vec3<T> yAxis() const;
    vec3<T> zAxis() const;

    inline F32 X() const;
    inline F32 Y() const;
    inline F32 Z() const;
    inline F32 W() const;

    inline void X(F32 x);
    inline void Y(F32 y);
    inline void Z(F32 z);
    inline void W(F32 w);

    inline void identity();

    inline const vec4<T>& asVec4() const;

   private:
    vec4<T> _elements;
};

/// get the shortest arc quaternion to rotate vector 'v' to the target vector 'u'
/// (from Ogre3D!)
template <typename T>
inline Quaternion<T> RotationFromVToU(const vec3<T>& v, const vec3<T>& u,
                                      const vec3<T>& fallbackAxis = VECTOR3_ZERO);
template <typename T>
inline Quaternion<T> Slerp(const Quaternion<T>& q0, const Quaternion<T>& q1, F32 t);

template <typename T>
inline mat3<T> GetMatrix(const Quaternion<T>& q);

template <typename T>
inline vec3<Angle::RADIANS<T>> GetEuler(const Quaternion<T>& q);

};  // namespace Divide

#endif

#include "Quaternion.inl"

Commits for Divide-Framework/trunk/Source Code/Core/Math/Headers/Quaternion.h

Diff revisions: vs.
Revision Author Commited Message
869 Diff Diff IonutCava picture IonutCava Sun 26 Feb, 2017 23:25:54 +0000

[IonutCava]
- Reduce loading time using profile guided optimizations
- Camera/Quaternion work in an attempt to fix a weird Yaw-rotation bug.

867 Diff Diff IonutCava picture IonutCava Mon 20 Feb, 2017 17:01:12 +0000

[IonutCava]
- Rename to_XNN and to_const_XNN functions to reflect the target data type they are converting to.
- Cleanup Angle namespace and remove all “inDegrees” parameters from rotation functions. Use aliases to differentiate between Degree and Radian parameters.
- Profile guided optimizations.

853 Diff Diff IonutCava picture IonutCava Tue 07 Feb, 2017 21:43:58 +0000

[IonutCava]
- More work on water rendering.

836 Diff Diff IonutCava picture IonutCava Fri 27 Jan, 2017 14:59:56 +0000

[IonutCava]
- Update copyright notice

750 Diff Diff IonutCava picture IonutCava Thu 07 Jul, 2016 16:02:03 +0000

[IonutCava]
- Static analysis based fixes and improvements

720 Diff Diff IonutCava picture IonutCava Mon 06 Jun, 2016 15:51:06 +0000

[IonutCava]
- PVS-Studio guided static analysis fixes and optimizations
- Added a flag to SceneState to bypass the Save/Load system not needed for certain types of scenes (menus, cinematics, etc)

706 Diff Diff IonutCava picture IonutCava Fri 13 May, 2016 16:29:40 +0000

[IonutCava]
- Renamed LightManager to LightPool and changed it from a Singleton to a scene specific pointer
- More scene load / unload updates (changing scenes now works properly!)
- Allowed GUI interface to hold per-scene elements and only render relevant ones
- Reduced dependencies between nodes, scenemanager, scene, loaders and kernel
- Removed Reflector base class as it was useless and integrate Water class with the Reflection system already in place
- Extended RenderingComponent’s reflection system to allow refraction as well

680 Diff Diff IonutCava picture IonutCava Thu 14 Apr, 2016 16:15:38 +0000

[IonutCava]
- Added a mat2 class (untested)
- Added static asserts to matrices, vectors and quaternions to allow only arithmetic (sans bool) data types
- Added more vector unit tests
- Added unit tests for matrices
- D32 finally renamed to D64 as the VC++ compiler is considered as the reference compiler

648 Diff Diff IonutCava picture IonutCava Sun 21 Feb, 2016 16:32:52 +0000

[IonutCava]
- Update copyright notice
- Move BoundingBox and BoundingSphere to a new BoundsComponent
— Add a temp hack in SceneGraphNode to update these

433 IonutCava picture IonutCava Wed 13 May, 2015 15:57:17 +0000

[Ionut]
- Some code cleanup (global functions now start with a capital case)
- Some fixed timestep adjustments
- Input logging (key presses & mouse button presses with location at event time)