Home | History | Annotate | Download | only in sensorservice
      1 /*
      2  * Copyright (C) 2011 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 #ifndef ANDROID_VEC_H
     18 #define ANDROID_VEC_H
     19 
     20 #include <math.h>
     21 
     22 #include <stdint.h>
     23 #include <stddef.h>
     24 
     25 #include "traits.h"
     26 
     27 // -----------------------------------------------------------------------
     28 
     29 #define PURE __attribute__((pure))
     30 
     31 namespace android {
     32 
     33 // -----------------------------------------------------------------------
     34 // non-inline helpers
     35 
     36 template <typename TYPE, size_t SIZE>
     37 class vec;
     38 
     39 template <typename TYPE, size_t SIZE>
     40 class vbase;
     41 
     42 namespace helpers {
     43 
     44 template <typename T> inline T min(T a, T b) { return a<b ? a : b; }
     45 template <typename T> inline T max(T a, T b) { return a>b ? a : b; }
     46 
     47 template < template<typename T, size_t S> class VEC,
     48     typename TYPE, size_t SIZE, size_t S>
     49 vec<TYPE, SIZE>& doAssign(
     50         vec<TYPE, SIZE>& lhs, const VEC<TYPE, S>& rhs) {
     51     const size_t minSize = min(SIZE, S);
     52     const size_t maxSize = max(SIZE, S);
     53     for (size_t i=0 ; i<minSize ; i++)
     54         lhs[i] = rhs[i];
     55     for (size_t i=minSize ; i<maxSize ; i++)
     56         lhs[i] = 0;
     57     return lhs;
     58 }
     59 
     60 
     61 template <
     62     template<typename T, size_t S> class VLHS,
     63     template<typename T, size_t S> class VRHS,
     64     typename TYPE,
     65     size_t SIZE
     66 >
     67 VLHS<TYPE, SIZE> PURE doAdd(
     68         const VLHS<TYPE, SIZE>& lhs,
     69         const VRHS<TYPE, SIZE>& rhs) {
     70     VLHS<TYPE, SIZE> r;
     71     for (size_t i=0 ; i<SIZE ; i++)
     72         r[i] = lhs[i] + rhs[i];
     73     return r;
     74 }
     75 
     76 template <
     77     template<typename T, size_t S> class VLHS,
     78     template<typename T, size_t S> class VRHS,
     79     typename TYPE,
     80     size_t SIZE
     81 >
     82 VLHS<TYPE, SIZE> PURE doSub(
     83         const VLHS<TYPE, SIZE>& lhs,
     84         const VRHS<TYPE, SIZE>& rhs) {
     85     VLHS<TYPE, SIZE> r;
     86     for (size_t i=0 ; i<SIZE ; i++)
     87         r[i] = lhs[i] - rhs[i];
     88     return r;
     89 }
     90 
     91 template <
     92     template<typename T, size_t S> class VEC,
     93     typename TYPE,
     94     size_t SIZE
     95 >
     96 VEC<TYPE, SIZE> PURE doMulScalar(
     97         const VEC<TYPE, SIZE>& lhs,
     98         typename TypeTraits<TYPE>::ParameterType rhs) {
     99     VEC<TYPE, SIZE> r;
    100     for (size_t i=0 ; i<SIZE ; i++)
    101         r[i] = lhs[i] * rhs;
    102     return r;
    103 }
    104 
    105 template <
    106     template<typename T, size_t S> class VEC,
    107     typename TYPE,
    108     size_t SIZE
    109 >
    110 VEC<TYPE, SIZE> PURE doScalarMul(
    111         typename TypeTraits<TYPE>::ParameterType lhs,
    112         const VEC<TYPE, SIZE>& rhs) {
    113     VEC<TYPE, SIZE> r;
    114     for (size_t i=0 ; i<SIZE ; i++)
    115         r[i] = lhs * rhs[i];
    116     return r;
    117 }
    118 
    119 }; // namespace helpers
    120 
    121 // -----------------------------------------------------------------------
    122 // Below we define the mathematical operators for vectors.
    123 // We use template template arguments so we can generically
    124 // handle the case where the right-hand-size and left-hand-side are
    125 // different vector types (but with same value_type and size).
    126 // This is needed for performance when using ".xy{z}" element access
    127 // on vec<>. Without this, an extra conversion to vec<> would be needed.
    128 //
    129 // example:
    130 //      vec4_t a;
    131 //      vec3_t b;
    132 //      vec3_t c = a.xyz + b;
    133 //
    134 //  "a.xyz + b" is a mixed-operation between a vbase<> and a vec<>, requiring
    135 //  a conversion of vbase<> to vec<>. The template gunk below avoids this,
    136 // by allowing the addition on these different vector types directly
    137 //
    138 
    139 template <
    140     template<typename T, size_t S> class VLHS,
    141     template<typename T, size_t S> class VRHS,
    142     typename TYPE,
    143     size_t SIZE
    144 >
    145 inline VLHS<TYPE, SIZE> PURE operator + (
    146         const VLHS<TYPE, SIZE>& lhs,
    147         const VRHS<TYPE, SIZE>& rhs) {
    148     return helpers::doAdd(lhs, rhs);
    149 }
    150 
    151 template <
    152     template<typename T, size_t S> class VLHS,
    153     template<typename T, size_t S> class VRHS,
    154     typename TYPE,
    155     size_t SIZE
    156 >
    157 inline VLHS<TYPE, SIZE> PURE operator - (
    158         const VLHS<TYPE, SIZE>& lhs,
    159         const VRHS<TYPE, SIZE>& rhs) {
    160     return helpers::doSub(lhs, rhs);
    161 }
    162 
    163 template <
    164     template<typename T, size_t S> class VEC,
    165     typename TYPE,
    166     size_t SIZE
    167 >
    168 inline VEC<TYPE, SIZE> PURE operator * (
    169         const VEC<TYPE, SIZE>& lhs,
    170         typename TypeTraits<TYPE>::ParameterType rhs) {
    171     return helpers::doMulScalar(lhs, rhs);
    172 }
    173 
    174 template <
    175     template<typename T, size_t S> class VEC,
    176     typename TYPE,
    177     size_t SIZE
    178 >
    179 inline VEC<TYPE, SIZE> PURE operator * (
    180         typename TypeTraits<TYPE>::ParameterType lhs,
    181         const VEC<TYPE, SIZE>& rhs) {
    182     return helpers::doScalarMul(lhs, rhs);
    183 }
    184 
    185 
    186 template <
    187     template<typename T, size_t S> class VLHS,
    188     template<typename T, size_t S> class VRHS,
    189     typename TYPE,
    190     size_t SIZE
    191 >
    192 TYPE PURE dot_product(
    193         const VLHS<TYPE, SIZE>& lhs,
    194         const VRHS<TYPE, SIZE>& rhs) {
    195     TYPE r(0);
    196     for (size_t i=0 ; i<SIZE ; i++)
    197         r += lhs[i] * rhs[i];
    198     return r;
    199 }
    200 
    201 template <
    202     template<typename T, size_t S> class V,
    203     typename TYPE,
    204     size_t SIZE
    205 >
    206 TYPE PURE length(const V<TYPE, SIZE>& v) {
    207     return sqrt(dot_product(v, v));
    208 }
    209 
    210 template <
    211     template<typename T, size_t S> class V,
    212     typename TYPE,
    213     size_t SIZE
    214 >
    215 TYPE PURE length_squared(const V<TYPE, SIZE>& v) {
    216     return dot_product(v, v);
    217 }
    218 
    219 template <
    220     template<typename T, size_t S> class V,
    221     typename TYPE,
    222     size_t SIZE
    223 >
    224 V<TYPE, SIZE> PURE normalize(const V<TYPE, SIZE>& v) {
    225     return v * (1/length(v));
    226 }
    227 
    228 template <
    229     template<typename T, size_t S> class VLHS,
    230     template<typename T, size_t S> class VRHS,
    231     typename TYPE
    232 >
    233 VLHS<TYPE, 3> PURE cross_product(
    234         const VLHS<TYPE, 3>& u,
    235         const VRHS<TYPE, 3>& v) {
    236     VLHS<TYPE, 3> r;
    237     r.x = u.y*v.z - u.z*v.y;
    238     r.y = u.z*v.x - u.x*v.z;
    239     r.z = u.x*v.y - u.y*v.x;
    240     return r;
    241 }
    242 
    243 
    244 template <typename TYPE, size_t SIZE>
    245 vec<TYPE, SIZE> PURE operator - (const vec<TYPE, SIZE>& lhs) {
    246     vec<TYPE, SIZE> r;
    247     for (size_t i=0 ; i<SIZE ; i++)
    248         r[i] = -lhs[i];
    249     return r;
    250 }
    251 
    252 // -----------------------------------------------------------------------
    253 
    254 // This our basic vector type, it just implements the data storage
    255 // and accessors.
    256 
    257 template <typename TYPE, size_t SIZE>
    258 struct vbase {
    259     TYPE v[SIZE];
    260     inline const TYPE& operator[](size_t i) const { return v[i]; }
    261     inline       TYPE& operator[](size_t i)       { return v[i]; }
    262 };
    263 template<> struct vbase<float, 2> {
    264     union {
    265         float v[2];
    266         struct { float x, y; };
    267         struct { float s, t; };
    268     };
    269     inline const float& operator[](size_t i) const { return v[i]; }
    270     inline       float& operator[](size_t i)       { return v[i]; }
    271 };
    272 template<> struct vbase<float, 3> {
    273     union {
    274         float v[3];
    275         struct { float x, y, z; };
    276         struct { float s, t, r; };
    277         vbase<float, 2> xy;
    278         vbase<float, 2> st;
    279     };
    280     inline const float& operator[](size_t i) const { return v[i]; }
    281     inline       float& operator[](size_t i)       { return v[i]; }
    282 };
    283 template<> struct vbase<float, 4> {
    284     union {
    285         float v[4];
    286         struct { float x, y, z, w; };
    287         struct { float s, t, r, q; };
    288         vbase<float, 3> xyz;
    289         vbase<float, 3> str;
    290         vbase<float, 2> xy;
    291         vbase<float, 2> st;
    292     };
    293     inline const float& operator[](size_t i) const { return v[i]; }
    294     inline       float& operator[](size_t i)       { return v[i]; }
    295 };
    296 
    297 // -----------------------------------------------------------------------
    298 
    299 template <typename TYPE, size_t SIZE>
    300 class vec : public vbase<TYPE, SIZE>
    301 {
    302     typedef typename TypeTraits<TYPE>::ParameterType pTYPE;
    303     typedef vbase<TYPE, SIZE> base;
    304 
    305 public:
    306     // STL-like interface.
    307     typedef TYPE value_type;
    308     typedef TYPE& reference;
    309     typedef TYPE const& const_reference;
    310     typedef size_t size_type;
    311 
    312     typedef TYPE* iterator;
    313     typedef TYPE const* const_iterator;
    314     iterator begin() { return base::v; }
    315     iterator end() { return base::v + SIZE; }
    316     const_iterator begin() const { return base::v; }
    317     const_iterator end() const { return base::v + SIZE; }
    318     size_type size() const { return SIZE; }
    319 
    320     // -----------------------------------------------------------------------
    321     // default constructors
    322 
    323     vec() { }
    324     vec(const vec& rhs)  : base(rhs) { }
    325     vec(const base& rhs) : base(rhs) { }
    326 
    327     // -----------------------------------------------------------------------
    328     // conversion constructors
    329 
    330     vec(pTYPE rhs) {
    331         for (size_t i=0 ; i<SIZE ; i++)
    332             base::operator[](i) = rhs;
    333     }
    334 
    335     template < template<typename T, size_t S> class VEC, size_t S>
    336     explicit vec(const VEC<TYPE, S>& rhs) {
    337         helpers::doAssign(*this, rhs);
    338     }
    339 
    340     explicit vec(TYPE const* array) {
    341         for (size_t i=0 ; i<SIZE ; i++)
    342             base::operator[](i) = array[i];
    343     }
    344 
    345     // -----------------------------------------------------------------------
    346     // Assignment
    347 
    348     vec& operator = (const vec& rhs) {
    349         base::operator=(rhs);
    350         return *this;
    351     }
    352 
    353     vec& operator = (const base& rhs) {
    354         base::operator=(rhs);
    355         return *this;
    356     }
    357 
    358     vec& operator = (pTYPE rhs) {
    359         for (size_t i=0 ; i<SIZE ; i++)
    360             base::operator[](i) = rhs;
    361         return *this;
    362     }
    363 
    364     template < template<typename T, size_t S> class VEC, size_t S>
    365     vec& operator = (const VEC<TYPE, S>& rhs) {
    366         return helpers::doAssign(*this, rhs);
    367     }
    368 
    369     // -----------------------------------------------------------------------
    370     // operation-assignment
    371 
    372     vec& operator += (const vec& rhs);
    373     vec& operator -= (const vec& rhs);
    374     vec& operator *= (pTYPE rhs);
    375 
    376     // -----------------------------------------------------------------------
    377     // non-member function declaration and definition
    378     // NOTE: we declare the non-member function as friend inside the class
    379     // so that they are known to the compiler when the class is instantiated.
    380     // This helps the compiler doing template argument deduction when the
    381     // passed types are not identical. Essentially this helps with
    382     // type conversion so that you can multiply a vec<float> by an scalar int
    383     // (for instance).
    384 
    385     friend inline vec PURE operator + (const vec& lhs, const vec& rhs) {
    386         return helpers::doAdd(lhs, rhs);
    387     }
    388     friend inline vec PURE operator - (const vec& lhs, const vec& rhs) {
    389         return helpers::doSub(lhs, rhs);
    390     }
    391     friend inline vec PURE operator * (const vec& lhs, pTYPE v) {
    392         return helpers::doMulScalar(lhs, v);
    393     }
    394     friend inline vec PURE operator * (pTYPE v, const vec& rhs) {
    395         return helpers::doScalarMul(v, rhs);
    396     }
    397     friend inline TYPE PURE dot_product(const vec& lhs, const vec& rhs) {
    398         return android::dot_product(lhs, rhs);
    399     }
    400 };
    401 
    402 // -----------------------------------------------------------------------
    403 
    404 template <typename TYPE, size_t SIZE>
    405 vec<TYPE, SIZE>& vec<TYPE, SIZE>::operator += (const vec<TYPE, SIZE>& rhs) {
    406     vec<TYPE, SIZE>& lhs(*this);
    407     for (size_t i=0 ; i<SIZE ; i++)
    408         lhs[i] += rhs[i];
    409     return lhs;
    410 }
    411 
    412 template <typename TYPE, size_t SIZE>
    413 vec<TYPE, SIZE>& vec<TYPE, SIZE>::operator -= (const vec<TYPE, SIZE>& rhs) {
    414     vec<TYPE, SIZE>& lhs(*this);
    415     for (size_t i=0 ; i<SIZE ; i++)
    416         lhs[i] -= rhs[i];
    417     return lhs;
    418 }
    419 
    420 template <typename TYPE, size_t SIZE>
    421 vec<TYPE, SIZE>& vec<TYPE, SIZE>::operator *= (vec<TYPE, SIZE>::pTYPE rhs) {
    422     vec<TYPE, SIZE>& lhs(*this);
    423     for (size_t i=0 ; i<SIZE ; i++)
    424         lhs[i] *= rhs;
    425     return lhs;
    426 }
    427 
    428 // -----------------------------------------------------------------------
    429 
    430 typedef vec<float, 2> vec2_t;
    431 typedef vec<float, 3> vec3_t;
    432 typedef vec<float, 4> vec4_t;
    433 
    434 // -----------------------------------------------------------------------
    435 
    436 }; // namespace android
    437 
    438 #endif /* ANDROID_VEC_H */
    439