1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #ifndef ANDROID_QUAT_H
18*38e8c45fSAndroid Build Coastguard Worker #define ANDROID_QUAT_H
19*38e8c45fSAndroid Build Coastguard Worker
20*38e8c45fSAndroid Build Coastguard Worker #include <math.h>
21*38e8c45fSAndroid Build Coastguard Worker
22*38e8c45fSAndroid Build Coastguard Worker #include "vec.h"
23*38e8c45fSAndroid Build Coastguard Worker #include "mat.h"
24*38e8c45fSAndroid Build Coastguard Worker
25*38e8c45fSAndroid Build Coastguard Worker // -----------------------------------------------------------------------
26*38e8c45fSAndroid Build Coastguard Worker namespace android {
27*38e8c45fSAndroid Build Coastguard Worker // -----------------------------------------------------------------------
28*38e8c45fSAndroid Build Coastguard Worker
29*38e8c45fSAndroid Build Coastguard Worker template <typename TYPE>
quatToMatrix(const vec<TYPE,4> & q)30*38e8c45fSAndroid Build Coastguard Worker mat<TYPE, 3, 3> quatToMatrix(const vec<TYPE, 4>& q) {
31*38e8c45fSAndroid Build Coastguard Worker mat<TYPE, 3, 3> R;
32*38e8c45fSAndroid Build Coastguard Worker TYPE q0(q.w);
33*38e8c45fSAndroid Build Coastguard Worker TYPE q1(q.x);
34*38e8c45fSAndroid Build Coastguard Worker TYPE q2(q.y);
35*38e8c45fSAndroid Build Coastguard Worker TYPE q3(q.z);
36*38e8c45fSAndroid Build Coastguard Worker TYPE sq_q1 = 2 * q1 * q1;
37*38e8c45fSAndroid Build Coastguard Worker TYPE sq_q2 = 2 * q2 * q2;
38*38e8c45fSAndroid Build Coastguard Worker TYPE sq_q3 = 2 * q3 * q3;
39*38e8c45fSAndroid Build Coastguard Worker TYPE q1_q2 = 2 * q1 * q2;
40*38e8c45fSAndroid Build Coastguard Worker TYPE q3_q0 = 2 * q3 * q0;
41*38e8c45fSAndroid Build Coastguard Worker TYPE q1_q3 = 2 * q1 * q3;
42*38e8c45fSAndroid Build Coastguard Worker TYPE q2_q0 = 2 * q2 * q0;
43*38e8c45fSAndroid Build Coastguard Worker TYPE q2_q3 = 2 * q2 * q3;
44*38e8c45fSAndroid Build Coastguard Worker TYPE q1_q0 = 2 * q1 * q0;
45*38e8c45fSAndroid Build Coastguard Worker R[0][0] = 1 - sq_q2 - sq_q3;
46*38e8c45fSAndroid Build Coastguard Worker R[0][1] = q1_q2 - q3_q0;
47*38e8c45fSAndroid Build Coastguard Worker R[0][2] = q1_q3 + q2_q0;
48*38e8c45fSAndroid Build Coastguard Worker R[1][0] = q1_q2 + q3_q0;
49*38e8c45fSAndroid Build Coastguard Worker R[1][1] = 1 - sq_q1 - sq_q3;
50*38e8c45fSAndroid Build Coastguard Worker R[1][2] = q2_q3 - q1_q0;
51*38e8c45fSAndroid Build Coastguard Worker R[2][0] = q1_q3 - q2_q0;
52*38e8c45fSAndroid Build Coastguard Worker R[2][1] = q2_q3 + q1_q0;
53*38e8c45fSAndroid Build Coastguard Worker R[2][2] = 1 - sq_q1 - sq_q2;
54*38e8c45fSAndroid Build Coastguard Worker return R;
55*38e8c45fSAndroid Build Coastguard Worker }
56*38e8c45fSAndroid Build Coastguard Worker
57*38e8c45fSAndroid Build Coastguard Worker template <typename TYPE>
matrixToQuat(const mat<TYPE,3,3> & R)58*38e8c45fSAndroid Build Coastguard Worker vec<TYPE, 4> matrixToQuat(const mat<TYPE, 3, 3>& R) {
59*38e8c45fSAndroid Build Coastguard Worker // matrix to quaternion
60*38e8c45fSAndroid Build Coastguard Worker
61*38e8c45fSAndroid Build Coastguard Worker struct {
62*38e8c45fSAndroid Build Coastguard Worker inline TYPE operator()(TYPE v) {
63*38e8c45fSAndroid Build Coastguard Worker return v < 0 ? 0 : v;
64*38e8c45fSAndroid Build Coastguard Worker }
65*38e8c45fSAndroid Build Coastguard Worker } clamp;
66*38e8c45fSAndroid Build Coastguard Worker
67*38e8c45fSAndroid Build Coastguard Worker vec<TYPE, 4> q;
68*38e8c45fSAndroid Build Coastguard Worker const float Hx = R[0].x;
69*38e8c45fSAndroid Build Coastguard Worker const float My = R[1].y;
70*38e8c45fSAndroid Build Coastguard Worker const float Az = R[2].z;
71*38e8c45fSAndroid Build Coastguard Worker q.x = sqrtf( clamp( Hx - My - Az + 1) * 0.25f );
72*38e8c45fSAndroid Build Coastguard Worker q.y = sqrtf( clamp(-Hx + My - Az + 1) * 0.25f );
73*38e8c45fSAndroid Build Coastguard Worker q.z = sqrtf( clamp(-Hx - My + Az + 1) * 0.25f );
74*38e8c45fSAndroid Build Coastguard Worker q.w = sqrtf( clamp( Hx + My + Az + 1) * 0.25f );
75*38e8c45fSAndroid Build Coastguard Worker q.x = copysignf(q.x, R[2].y - R[1].z);
76*38e8c45fSAndroid Build Coastguard Worker q.y = copysignf(q.y, R[0].z - R[2].x);
77*38e8c45fSAndroid Build Coastguard Worker q.z = copysignf(q.z, R[1].x - R[0].y);
78*38e8c45fSAndroid Build Coastguard Worker // guaranteed to be unit-quaternion
79*38e8c45fSAndroid Build Coastguard Worker return q;
80*38e8c45fSAndroid Build Coastguard Worker }
81*38e8c45fSAndroid Build Coastguard Worker
82*38e8c45fSAndroid Build Coastguard Worker template <typename TYPE>
normalize_quat(const vec<TYPE,4> & q)83*38e8c45fSAndroid Build Coastguard Worker vec<TYPE, 4> normalize_quat(const vec<TYPE, 4>& q) {
84*38e8c45fSAndroid Build Coastguard Worker vec<TYPE, 4> r(q);
85*38e8c45fSAndroid Build Coastguard Worker if (r.w < 0) {
86*38e8c45fSAndroid Build Coastguard Worker r = -r;
87*38e8c45fSAndroid Build Coastguard Worker }
88*38e8c45fSAndroid Build Coastguard Worker return normalize(r);
89*38e8c45fSAndroid Build Coastguard Worker }
90*38e8c45fSAndroid Build Coastguard Worker
91*38e8c45fSAndroid Build Coastguard Worker // -----------------------------------------------------------------------
92*38e8c45fSAndroid Build Coastguard Worker
93*38e8c45fSAndroid Build Coastguard Worker typedef vec4_t quat_t;
94*38e8c45fSAndroid Build Coastguard Worker
95*38e8c45fSAndroid Build Coastguard Worker // -----------------------------------------------------------------------
96*38e8c45fSAndroid Build Coastguard Worker }; // namespace android
97*38e8c45fSAndroid Build Coastguard Worker
98*38e8c45fSAndroid Build Coastguard Worker #endif /* ANDROID_QUAT_H */
99