Home | History | Annotate | Download | only in algos
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <algos/quat.h>
     18 #include <nanohub_math.h>
     19 
     20 static float clamp(float x) {
     21     return x < 0.0f ? 0.0f : x;
     22 }
     23 
     24 void initQuat(Quat *q, const struct Mat33 *R) {
     25     float Hx = R->elem[0][0];
     26     float My = R->elem[1][1];
     27     float Az = R->elem[2][2];
     28 
     29     q->x = sqrtf(clamp(Hx - My - Az + 1.0f) * 0.25f);
     30     q->y = sqrtf(clamp(-Hx + My - Az + 1.0f) * 0.25f);
     31     q->z = sqrtf(clamp(-Hx - My + Az + 1.0f) * 0.25f);
     32     q->w = sqrtf(clamp(Hx + My + Az + 1.0f) * 0.25f);
     33     q->x = copysignf(q->x, R->elem[1][2] - R->elem[2][1]);
     34     q->y = copysignf(q->y, R->elem[2][0] - R->elem[0][2]);
     35     q->z = copysignf(q->z, R->elem[0][1] - R->elem[1][0]);
     36 }
     37 
     38 void quatToMatrix(struct Mat33 *R, const Quat *q) {
     39     float q0 = q->w;
     40     float q1 = q->x;
     41     float q2 = q->y;
     42     float q3 = q->z;
     43     float sq_q1 = 2.0f * q1 * q1;
     44     float sq_q2 = 2.0f * q2 * q2;
     45     float sq_q3 = 2.0f * q3 * q3;
     46     float q1_q2 = 2.0f * q1 * q2;
     47     float q3_q0 = 2.0f * q3 * q0;
     48     float q1_q3 = 2.0f * q1 * q3;
     49     float q2_q0 = 2.0f * q2 * q0;
     50     float q2_q3 = 2.0f * q2 * q3;
     51     float q1_q0 = 2.0f * q1 * q0;
     52 
     53     R->elem[0][0] = 1.0f - sq_q2 - sq_q3;
     54     R->elem[1][0] = q1_q2 - q3_q0;
     55     R->elem[2][0] = q1_q3 + q2_q0;
     56     R->elem[0][1] = q1_q2 + q3_q0;
     57     R->elem[1][1] = 1.0f - sq_q1 - sq_q3;
     58     R->elem[2][1] = q2_q3 - q1_q0;
     59     R->elem[0][2] = q1_q3 - q2_q0;
     60     R->elem[1][2] = q2_q3 + q1_q0;
     61     R->elem[2][2] = 1.0f - sq_q1 - sq_q2;
     62 }
     63 
     64 void quatNormalize(Quat *q) {
     65     if (q->w < 0.0f) {
     66         q->x = -q->x;
     67         q->y = -q->y;
     68         q->z = -q->z;
     69         q->w = -q->w;
     70     }
     71 
     72     float invNorm =
     73         1.0f / sqrtf(q->x * q->x + q->y * q->y + q->z * q->z + q->w * q->w);
     74 
     75     q->x *= invNorm;
     76     q->y *= invNorm;
     77     q->z *= invNorm;
     78     q->w *= invNorm;
     79 }
     80 
     81