xref: /aosp_15_r20/frameworks/native/services/sensorservice/quat.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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