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