Tizen 2.1 base
[platform/upstream/libbullet.git] / Extras / RigidBodyGpuPipeline / opencl / primitives / AdlPrimitives / Math / Quaternion.h
1 /*
2 Copyright (c) 2012 Advanced Micro Devices, Inc.  
3
4 This software is provided 'as-is', without any express or implied warranty.
5 In no event will the authors be held liable for any damages arising from the use of this software.
6 Permission is granted to anyone to use this software for any purpose, 
7 including commercial applications, and to alter it and redistribute it freely, 
8 subject to the following restrictions:
9
10 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
11 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
12 3. This notice may not be removed or altered from any source distribution.
13 */
14 //Originally written by Takahiro Harada
15
16
17 #ifndef QUATERNION_H
18 #define QUATERNION_H
19
20 #include <AdlPrimitives/Math/Matrix3x3.h>
21
22 namespace adl
23 {
24
25 typedef float4 Quaternion;
26
27 __inline
28 Quaternion qtSet(const float4& axis, float angle);
29
30 __inline
31 Quaternion qtMul(const Quaternion& a, const Quaternion& b);
32
33 __inline
34 float4 qtRotate(const Quaternion& q, const float4& vec);
35
36 __inline
37 float4 qtInvRotate(const Quaternion& q, const float4& vec);
38
39 __inline
40 Quaternion qtInvert(const Quaternion& q);
41
42 __inline
43 Matrix3x3 qtGetRotationMatrix(const Quaternion& quat);
44
45 __inline
46 Quaternion qtNormalize(const Quaternion& q);
47
48 __inline
49 Quaternion qtGetIdentity() { return make_float4(0,0,0,1); }
50
51 __inline
52 Quaternion qtSet(const float4& axis, float angle)
53 {
54         float4 nAxis = normalize3( axis );
55
56         Quaternion q;
57         q.s[0] = nAxis.s[0]*sin(angle/2);
58         q.s[1] = nAxis.s[1]*sin(angle/2);
59         q.s[2] = nAxis.s[2]*sin(angle/2);
60         q.s[3] = cos(angle/2);
61         return q;
62 }
63
64 __inline
65 Quaternion qtMul(const Quaternion& a, const Quaternion& b)
66 {
67         Quaternion ans;
68         ans = cross3( a, b );
69         ans += a.s[3]*b + b.s[3]*a;
70         ans.s[3] = a.s[3]*b.s[3] - (a.s[0]*b.s[0]+a.s[1]*b.s[1]+a.s[2]*b.s[2]);
71         return ans;
72 }
73
74 __inline
75 float4 qtRotate(const Quaternion& q, const float4& vec)
76 {
77         Quaternion vecQ = vec;
78         vecQ.s[3] = 0.f;
79         Quaternion qInv = qtInvert( q );
80         float4 out = qtMul(qtMul(q,vecQ),qInv);
81         return out;
82 }
83
84 __inline
85 float4 qtInvRotate(const Quaternion& q, const float4& vec)
86 {
87         return qtRotate( qtInvert( q ), vec );
88 }
89
90 __inline
91 Quaternion qtInvert(const Quaternion& q)
92 {
93         Quaternion ans;
94         ans.s[0] = -q.s[0];
95         ans.s[1] = -q.s[1];
96         ans.s[2] = -q.s[2];
97         ans.s[3] = q.s[3];
98         return ans;
99 }
100
101 __inline
102 Matrix3x3 qtGetRotationMatrix(const Quaternion& quat)
103 {
104         float4 quat2 = make_float4(quat.s[0]*quat.s[0], quat.s[1]*quat.s[1], quat.s[2]*quat.s[2], 0.f);
105         Matrix3x3 out;
106
107         out.m_row[0].s[0]=1-2*quat2.s[1]-2*quat2.s[2];
108         out.m_row[0].s[1]=2*quat.s[0]*quat.s[1]-2*quat.s[3]*quat.s[2];
109         out.m_row[0].s[2]=2*quat.s[0]*quat.s[2]+2*quat.s[3]*quat.s[1];
110         out.m_row[0].s[3] = 0.f;
111
112         out.m_row[1].s[0]=2*quat.s[0]*quat.s[1]+2*quat.s[3]*quat.s[2];
113         out.m_row[1].s[1]=1-2*quat2.s[0]-2*quat2.s[2];
114         out.m_row[1].s[2]=2*quat.s[1]*quat.s[2]-2*quat.s[3]*quat.s[0];
115         out.m_row[1].s[3] = 0.f;
116
117         out.m_row[2].s[0]=2*quat.s[0]*quat.s[2]-2*quat.s[3]*quat.s[1];
118         out.m_row[2].s[1]=2*quat.s[1]*quat.s[2]+2*quat.s[3]*quat.s[0];
119         out.m_row[2].s[2]=1-2*quat2.s[0]-2*quat2.s[1];
120         out.m_row[2].s[3] = 0.f;
121
122         return out;
123 }
124
125 __inline
126 Quaternion qtGetQuaternion(const Matrix3x3* m)
127 {
128         Quaternion q;
129         q.w = sqrtf( m[0].m_row[0].x + m[0].m_row[1].y + m[0].m_row[2].z + 1 ) * 0.5f;
130         float inv4w = 1.f/(4.f*q.w);
131         q.x = (m[0].m_row[2].y-m[0].m_row[1].z)*inv4w;
132         q.y = (m[0].m_row[0].z-m[0].m_row[2].x)*inv4w;
133         q.z = (m[0].m_row[1].x-m[0].m_row[0].y)*inv4w;
134
135         return q;
136 }
137
138 __inline
139 Quaternion qtNormalize(const Quaternion& q)
140 {
141         return normalize4(q);
142 }
143
144 __inline
145 float4 transform(const float4& p, const float4& translation, const Quaternion& orientation)
146 {
147         return qtRotate( orientation, p ) + translation;
148 }
149
150 __inline
151 float4 invTransform(const float4& p, const float4& translation, const Quaternion& orientation)
152 {
153         return qtRotate( qtInvert( orientation ), p-translation ); // use qtInvRotate
154 }
155
156 };
157
158 #endif
159