13301542828febc768e1df42892cfac4992c35474Mathias Agopian/*
23301542828febc768e1df42892cfac4992c35474Mathias Agopian * Copyright (C) 2011 The Android Open Source Project
33301542828febc768e1df42892cfac4992c35474Mathias Agopian *
43301542828febc768e1df42892cfac4992c35474Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
53301542828febc768e1df42892cfac4992c35474Mathias Agopian * you may not use this file except in compliance with the License.
63301542828febc768e1df42892cfac4992c35474Mathias Agopian * You may obtain a copy of the License at
73301542828febc768e1df42892cfac4992c35474Mathias Agopian *
83301542828febc768e1df42892cfac4992c35474Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
93301542828febc768e1df42892cfac4992c35474Mathias Agopian *
103301542828febc768e1df42892cfac4992c35474Mathias Agopian * Unless required by applicable law or agreed to in writing, software
113301542828febc768e1df42892cfac4992c35474Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
123301542828febc768e1df42892cfac4992c35474Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133301542828febc768e1df42892cfac4992c35474Mathias Agopian * See the License for the specific language governing permissions and
143301542828febc768e1df42892cfac4992c35474Mathias Agopian * limitations under the License.
153301542828febc768e1df42892cfac4992c35474Mathias Agopian */
163301542828febc768e1df42892cfac4992c35474Mathias Agopian
173301542828febc768e1df42892cfac4992c35474Mathias Agopian#ifndef ANDROID_QUAT_H
183301542828febc768e1df42892cfac4992c35474Mathias Agopian#define ANDROID_QUAT_H
193301542828febc768e1df42892cfac4992c35474Mathias Agopian
203301542828febc768e1df42892cfac4992c35474Mathias Agopian#include <math.h>
213301542828febc768e1df42892cfac4992c35474Mathias Agopian
223301542828febc768e1df42892cfac4992c35474Mathias Agopian#include "vec.h"
233301542828febc768e1df42892cfac4992c35474Mathias Agopian#include "mat.h"
243301542828febc768e1df42892cfac4992c35474Mathias Agopian
253301542828febc768e1df42892cfac4992c35474Mathias Agopian// -----------------------------------------------------------------------
263301542828febc768e1df42892cfac4992c35474Mathias Agopiannamespace android {
273301542828febc768e1df42892cfac4992c35474Mathias Agopian// -----------------------------------------------------------------------
283301542828febc768e1df42892cfac4992c35474Mathias Agopian
293301542828febc768e1df42892cfac4992c35474Mathias Agopiantemplate <typename TYPE>
303301542828febc768e1df42892cfac4992c35474Mathias Agopianmat<TYPE, 3, 3> quatToMatrix(const vec<TYPE, 4>& q) {
313301542828febc768e1df42892cfac4992c35474Mathias Agopian    mat<TYPE, 3, 3> R;
323301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q0(q.w);
333301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q1(q.x);
343301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q2(q.y);
353301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q3(q.z);
363301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE sq_q1 = 2 * q1 * q1;
373301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE sq_q2 = 2 * q2 * q2;
383301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE sq_q3 = 2 * q3 * q3;
393301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q1_q2 = 2 * q1 * q2;
403301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q3_q0 = 2 * q3 * q0;
413301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q1_q3 = 2 * q1 * q3;
423301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q2_q0 = 2 * q2 * q0;
433301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q2_q3 = 2 * q2 * q3;
443301542828febc768e1df42892cfac4992c35474Mathias Agopian    TYPE q1_q0 = 2 * q1 * q0;
453301542828febc768e1df42892cfac4992c35474Mathias Agopian    R[0][0] = 1 - sq_q2 - sq_q3;
463301542828febc768e1df42892cfac4992c35474Mathias Agopian    R[0][1] = q1_q2 - q3_q0;
473301542828febc768e1df42892cfac4992c35474Mathias Agopian    R[0][2] = q1_q3 + q2_q0;
483301542828febc768e1df42892cfac4992c35474Mathias Agopian    R[1][0] = q1_q2 + q3_q0;
493301542828febc768e1df42892cfac4992c35474Mathias Agopian    R[1][1] = 1 - sq_q1 - sq_q3;
503301542828febc768e1df42892cfac4992c35474Mathias Agopian    R[1][2] = q2_q3 - q1_q0;
513301542828febc768e1df42892cfac4992c35474Mathias Agopian    R[2][0] = q1_q3 - q2_q0;
523301542828febc768e1df42892cfac4992c35474Mathias Agopian    R[2][1] = q2_q3 + q1_q0;
533301542828febc768e1df42892cfac4992c35474Mathias Agopian    R[2][2] = 1 - sq_q1 - sq_q2;
543301542828febc768e1df42892cfac4992c35474Mathias Agopian    return R;
553301542828febc768e1df42892cfac4992c35474Mathias Agopian}
563301542828febc768e1df42892cfac4992c35474Mathias Agopian
573301542828febc768e1df42892cfac4992c35474Mathias Agopiantemplate <typename TYPE>
583301542828febc768e1df42892cfac4992c35474Mathias Agopianvec<TYPE, 4> matrixToQuat(const mat<TYPE, 3, 3>& R) {
593301542828febc768e1df42892cfac4992c35474Mathias Agopian    // matrix to quaternion
603301542828febc768e1df42892cfac4992c35474Mathias Agopian
613301542828febc768e1df42892cfac4992c35474Mathias Agopian    struct {
623301542828febc768e1df42892cfac4992c35474Mathias Agopian        inline TYPE operator()(TYPE v) {
633301542828febc768e1df42892cfac4992c35474Mathias Agopian            return v < 0 ? 0 : v;
643301542828febc768e1df42892cfac4992c35474Mathias Agopian        }
653301542828febc768e1df42892cfac4992c35474Mathias Agopian    } clamp;
663301542828febc768e1df42892cfac4992c35474Mathias Agopian
673301542828febc768e1df42892cfac4992c35474Mathias Agopian    vec<TYPE, 4> q;
683301542828febc768e1df42892cfac4992c35474Mathias Agopian    const float Hx = R[0].x;
693301542828febc768e1df42892cfac4992c35474Mathias Agopian    const float My = R[1].y;
703301542828febc768e1df42892cfac4992c35474Mathias Agopian    const float Az = R[2].z;
713301542828febc768e1df42892cfac4992c35474Mathias Agopian    q.x = sqrtf( clamp( Hx - My - Az + 1) * 0.25f );
723301542828febc768e1df42892cfac4992c35474Mathias Agopian    q.y = sqrtf( clamp(-Hx + My - Az + 1) * 0.25f );
733301542828febc768e1df42892cfac4992c35474Mathias Agopian    q.z = sqrtf( clamp(-Hx - My + Az + 1) * 0.25f );
743301542828febc768e1df42892cfac4992c35474Mathias Agopian    q.w = sqrtf( clamp( Hx + My + Az + 1) * 0.25f );
753301542828febc768e1df42892cfac4992c35474Mathias Agopian    q.x = copysignf(q.x, R[2].y - R[1].z);
763301542828febc768e1df42892cfac4992c35474Mathias Agopian    q.y = copysignf(q.y, R[0].z - R[2].x);
773301542828febc768e1df42892cfac4992c35474Mathias Agopian    q.z = copysignf(q.z, R[1].x - R[0].y);
783301542828febc768e1df42892cfac4992c35474Mathias Agopian    // guaranteed to be unit-quaternion
793301542828febc768e1df42892cfac4992c35474Mathias Agopian    return q;
803301542828febc768e1df42892cfac4992c35474Mathias Agopian}
813301542828febc768e1df42892cfac4992c35474Mathias Agopian
823301542828febc768e1df42892cfac4992c35474Mathias Agopiantemplate <typename TYPE>
833301542828febc768e1df42892cfac4992c35474Mathias Agopianvec<TYPE, 4> normalize_quat(const vec<TYPE, 4>& q) {
843301542828febc768e1df42892cfac4992c35474Mathias Agopian    vec<TYPE, 4> r(q);
853301542828febc768e1df42892cfac4992c35474Mathias Agopian    if (r.w < 0) {
863301542828febc768e1df42892cfac4992c35474Mathias Agopian        r = -r;
873301542828febc768e1df42892cfac4992c35474Mathias Agopian    }
883301542828febc768e1df42892cfac4992c35474Mathias Agopian    return normalize(r);
893301542828febc768e1df42892cfac4992c35474Mathias Agopian}
903301542828febc768e1df42892cfac4992c35474Mathias Agopian
913301542828febc768e1df42892cfac4992c35474Mathias Agopian// -----------------------------------------------------------------------
923301542828febc768e1df42892cfac4992c35474Mathias Agopian
933301542828febc768e1df42892cfac4992c35474Mathias Agopiantypedef vec4_t quat_t;
943301542828febc768e1df42892cfac4992c35474Mathias Agopian
953301542828febc768e1df42892cfac4992c35474Mathias Agopian// -----------------------------------------------------------------------
963301542828febc768e1df42892cfac4992c35474Mathias Agopian}; // namespace android
973301542828febc768e1df42892cfac4992c35474Mathias Agopian
983301542828febc768e1df42892cfac4992c35474Mathias Agopian#endif /* ANDROID_QUAT_H */
99