1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // vector_utils.h: Utility classes implementing various vector operations
7*8975f5c5SAndroid Build Coastguard Worker
8*8975f5c5SAndroid Build Coastguard Worker #ifndef COMMON_VECTOR_UTILS_H_
9*8975f5c5SAndroid Build Coastguard Worker #define COMMON_VECTOR_UTILS_H_
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include <cmath>
12*8975f5c5SAndroid Build Coastguard Worker #include <cstddef>
13*8975f5c5SAndroid Build Coastguard Worker #include <ostream>
14*8975f5c5SAndroid Build Coastguard Worker #include <type_traits>
15*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Worker namespace angle
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
21*8975f5c5SAndroid Build Coastguard Worker class Vector;
22*8975f5c5SAndroid Build Coastguard Worker
23*8975f5c5SAndroid Build Coastguard Worker using Vector2 = Vector<2, float>;
24*8975f5c5SAndroid Build Coastguard Worker using Vector3 = Vector<3, float>;
25*8975f5c5SAndroid Build Coastguard Worker using Vector4 = Vector<4, float>;
26*8975f5c5SAndroid Build Coastguard Worker
27*8975f5c5SAndroid Build Coastguard Worker using Vector2I = Vector<2, int>;
28*8975f5c5SAndroid Build Coastguard Worker using Vector3I = Vector<3, int>;
29*8975f5c5SAndroid Build Coastguard Worker using Vector4I = Vector<4, int>;
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker using Vector2U = Vector<2, unsigned int>;
32*8975f5c5SAndroid Build Coastguard Worker using Vector3U = Vector<3, unsigned int>;
33*8975f5c5SAndroid Build Coastguard Worker using Vector4U = Vector<4, unsigned int>;
34*8975f5c5SAndroid Build Coastguard Worker
35*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
36*8975f5c5SAndroid Build Coastguard Worker class VectorBase
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker public:
39*8975f5c5SAndroid Build Coastguard Worker using VectorN = Vector<Dimension, Type>;
40*8975f5c5SAndroid Build Coastguard Worker
41*8975f5c5SAndroid Build Coastguard Worker // Constructors
42*8975f5c5SAndroid Build Coastguard Worker VectorBase() = default;
43*8975f5c5SAndroid Build Coastguard Worker explicit VectorBase(Type element);
44*8975f5c5SAndroid Build Coastguard Worker
45*8975f5c5SAndroid Build Coastguard Worker template <typename Type2>
46*8975f5c5SAndroid Build Coastguard Worker VectorBase(const VectorBase<Dimension, Type2> &other);
47*8975f5c5SAndroid Build Coastguard Worker
48*8975f5c5SAndroid Build Coastguard Worker template <typename Arg1, typename Arg2, typename... Args>
49*8975f5c5SAndroid Build Coastguard Worker VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &...args);
50*8975f5c5SAndroid Build Coastguard Worker
51*8975f5c5SAndroid Build Coastguard Worker // Access the vector backing storage directly
data()52*8975f5c5SAndroid Build Coastguard Worker const Type *data() const { return mData; }
data()53*8975f5c5SAndroid Build Coastguard Worker Type *data() { return mData; }
size()54*8975f5c5SAndroid Build Coastguard Worker constexpr size_t size() const { return Dimension; }
55*8975f5c5SAndroid Build Coastguard Worker
56*8975f5c5SAndroid Build Coastguard Worker // Load or store the pointer from / to raw data
57*8975f5c5SAndroid Build Coastguard Worker static VectorN Load(const Type *source);
58*8975f5c5SAndroid Build Coastguard Worker static void Store(const VectorN &source, Type *destination);
59*8975f5c5SAndroid Build Coastguard Worker
60*8975f5c5SAndroid Build Coastguard Worker // Index the vector
61*8975f5c5SAndroid Build Coastguard Worker Type &operator[](size_t i) { return mData[i]; }
62*8975f5c5SAndroid Build Coastguard Worker const Type &operator[](size_t i) const { return mData[i]; }
63*8975f5c5SAndroid Build Coastguard Worker
64*8975f5c5SAndroid Build Coastguard Worker // Basic arithmetic operations
65*8975f5c5SAndroid Build Coastguard Worker VectorN operator+() const;
66*8975f5c5SAndroid Build Coastguard Worker VectorN operator-() const;
67*8975f5c5SAndroid Build Coastguard Worker VectorN operator+(const VectorN &other) const;
68*8975f5c5SAndroid Build Coastguard Worker VectorN operator-(const VectorN &other) const;
69*8975f5c5SAndroid Build Coastguard Worker VectorN operator*(const VectorN &other) const;
70*8975f5c5SAndroid Build Coastguard Worker VectorN operator/(const VectorN &other) const;
71*8975f5c5SAndroid Build Coastguard Worker VectorN operator*(Type other) const;
72*8975f5c5SAndroid Build Coastguard Worker VectorN operator/(Type other) const;
73*8975f5c5SAndroid Build Coastguard Worker friend VectorN operator*(Type a, const VectorN &b) { return b * a; }
74*8975f5c5SAndroid Build Coastguard Worker
75*8975f5c5SAndroid Build Coastguard Worker // Compound arithmetic operations
76*8975f5c5SAndroid Build Coastguard Worker VectorN &operator+=(const VectorN &other);
77*8975f5c5SAndroid Build Coastguard Worker VectorN &operator-=(const VectorN &other);
78*8975f5c5SAndroid Build Coastguard Worker VectorN &operator*=(const VectorN &other);
79*8975f5c5SAndroid Build Coastguard Worker VectorN &operator/=(const VectorN &other);
80*8975f5c5SAndroid Build Coastguard Worker VectorN &operator*=(Type other);
81*8975f5c5SAndroid Build Coastguard Worker VectorN &operator/=(Type other);
82*8975f5c5SAndroid Build Coastguard Worker
83*8975f5c5SAndroid Build Coastguard Worker // Comparison operators
84*8975f5c5SAndroid Build Coastguard Worker bool operator==(const VectorBase<Dimension, Type> &other) const;
85*8975f5c5SAndroid Build Coastguard Worker bool operator!=(const VectorBase<Dimension, Type> &other) const;
86*8975f5c5SAndroid Build Coastguard Worker
87*8975f5c5SAndroid Build Coastguard Worker // Other arithmetic operations
88*8975f5c5SAndroid Build Coastguard Worker Type length() const;
89*8975f5c5SAndroid Build Coastguard Worker Type lengthSquared() const;
90*8975f5c5SAndroid Build Coastguard Worker Type dot(const VectorBase<Dimension, Type> &other) const;
91*8975f5c5SAndroid Build Coastguard Worker VectorN normalized() const;
92*8975f5c5SAndroid Build Coastguard Worker
93*8975f5c5SAndroid Build Coastguard Worker protected:
94*8975f5c5SAndroid Build Coastguard Worker template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
95*8975f5c5SAndroid Build Coastguard Worker void initWithList(const Vector<OtherDimension, OtherType> &arg1, const Args &...args);
96*8975f5c5SAndroid Build Coastguard Worker
97*8975f5c5SAndroid Build Coastguard Worker // Some old compilers consider this function an alternative for initWithList(Vector)
98*8975f5c5SAndroid Build Coastguard Worker // when the variant above is more precise. Use SFINAE on the return value to hide
99*8975f5c5SAndroid Build Coastguard Worker // this variant for non-arithmetic types. The return value is still void.
100*8975f5c5SAndroid Build Coastguard Worker template <size_t CurrentIndex, typename OtherType, typename... Args>
101*8975f5c5SAndroid Build Coastguard Worker typename std::enable_if<std::is_arithmetic<OtherType>::value>::type initWithList(
102*8975f5c5SAndroid Build Coastguard Worker OtherType arg1,
103*8975f5c5SAndroid Build Coastguard Worker const Args &...args);
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker template <size_t CurrentIndex>
106*8975f5c5SAndroid Build Coastguard Worker void initWithList() const;
107*8975f5c5SAndroid Build Coastguard Worker
108*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension2, typename Type2>
109*8975f5c5SAndroid Build Coastguard Worker friend class VectorBase;
110*8975f5c5SAndroid Build Coastguard Worker
111*8975f5c5SAndroid Build Coastguard Worker Type mData[Dimension];
112*8975f5c5SAndroid Build Coastguard Worker };
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
115*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector);
116*8975f5c5SAndroid Build Coastguard Worker
117*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
118*8975f5c5SAndroid Build Coastguard Worker class Vector<2, Type> : public VectorBase<2, Type>
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker public:
121*8975f5c5SAndroid Build Coastguard Worker // Import the constructors defined in VectorBase
122*8975f5c5SAndroid Build Coastguard Worker using VectorBase<2, Type>::VectorBase;
123*8975f5c5SAndroid Build Coastguard Worker
124*8975f5c5SAndroid Build Coastguard Worker // Element shorthands
x()125*8975f5c5SAndroid Build Coastguard Worker Type &x() { return this->mData[0]; }
y()126*8975f5c5SAndroid Build Coastguard Worker Type &y() { return this->mData[1]; }
127*8975f5c5SAndroid Build Coastguard Worker
x()128*8975f5c5SAndroid Build Coastguard Worker const Type &x() const { return this->mData[0]; }
y()129*8975f5c5SAndroid Build Coastguard Worker const Type &y() const { return this->mData[1]; }
130*8975f5c5SAndroid Build Coastguard Worker };
131*8975f5c5SAndroid Build Coastguard Worker
132*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
133*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector);
134*8975f5c5SAndroid Build Coastguard Worker
135*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
136*8975f5c5SAndroid Build Coastguard Worker class Vector<3, Type> : public VectorBase<3, Type>
137*8975f5c5SAndroid Build Coastguard Worker {
138*8975f5c5SAndroid Build Coastguard Worker public:
139*8975f5c5SAndroid Build Coastguard Worker // Import the constructors defined in VectorBase
140*8975f5c5SAndroid Build Coastguard Worker using VectorBase<3, Type>::VectorBase;
141*8975f5c5SAndroid Build Coastguard Worker
142*8975f5c5SAndroid Build Coastguard Worker // Additional operations
143*8975f5c5SAndroid Build Coastguard Worker Vector<3, Type> cross(const Vector<3, Type> &other) const;
144*8975f5c5SAndroid Build Coastguard Worker
145*8975f5c5SAndroid Build Coastguard Worker // Element shorthands
x()146*8975f5c5SAndroid Build Coastguard Worker Type &x() { return this->mData[0]; }
y()147*8975f5c5SAndroid Build Coastguard Worker Type &y() { return this->mData[1]; }
z()148*8975f5c5SAndroid Build Coastguard Worker Type &z() { return this->mData[2]; }
149*8975f5c5SAndroid Build Coastguard Worker
x()150*8975f5c5SAndroid Build Coastguard Worker const Type &x() const { return this->mData[0]; }
y()151*8975f5c5SAndroid Build Coastguard Worker const Type &y() const { return this->mData[1]; }
z()152*8975f5c5SAndroid Build Coastguard Worker const Type &z() const { return this->mData[2]; }
153*8975f5c5SAndroid Build Coastguard Worker };
154*8975f5c5SAndroid Build Coastguard Worker
155*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
156*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector);
157*8975f5c5SAndroid Build Coastguard Worker
158*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
159*8975f5c5SAndroid Build Coastguard Worker class Vector<4, Type> : public VectorBase<4, Type>
160*8975f5c5SAndroid Build Coastguard Worker {
161*8975f5c5SAndroid Build Coastguard Worker public:
162*8975f5c5SAndroid Build Coastguard Worker // Import the constructors defined in VectorBase
163*8975f5c5SAndroid Build Coastguard Worker using VectorBase<4, Type>::VectorBase;
164*8975f5c5SAndroid Build Coastguard Worker
165*8975f5c5SAndroid Build Coastguard Worker // Element shorthands
x()166*8975f5c5SAndroid Build Coastguard Worker Type &x() { return this->mData[0]; }
y()167*8975f5c5SAndroid Build Coastguard Worker Type &y() { return this->mData[1]; }
z()168*8975f5c5SAndroid Build Coastguard Worker Type &z() { return this->mData[2]; }
w()169*8975f5c5SAndroid Build Coastguard Worker Type &w() { return this->mData[3]; }
170*8975f5c5SAndroid Build Coastguard Worker
x()171*8975f5c5SAndroid Build Coastguard Worker const Type &x() const { return this->mData[0]; }
y()172*8975f5c5SAndroid Build Coastguard Worker const Type &y() const { return this->mData[1]; }
z()173*8975f5c5SAndroid Build Coastguard Worker const Type &z() const { return this->mData[2]; }
w()174*8975f5c5SAndroid Build Coastguard Worker const Type &w() const { return this->mData[3]; }
175*8975f5c5SAndroid Build Coastguard Worker };
176*8975f5c5SAndroid Build Coastguard Worker
177*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
178*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector);
179*8975f5c5SAndroid Build Coastguard Worker
180*8975f5c5SAndroid Build Coastguard Worker // Implementation of constructors and misc operations
181*8975f5c5SAndroid Build Coastguard Worker
182*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
VectorBase(Type element)183*8975f5c5SAndroid Build Coastguard Worker VectorBase<Dimension, Type>::VectorBase(Type element)
184*8975f5c5SAndroid Build Coastguard Worker {
185*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
186*8975f5c5SAndroid Build Coastguard Worker {
187*8975f5c5SAndroid Build Coastguard Worker mData[i] = element;
188*8975f5c5SAndroid Build Coastguard Worker }
189*8975f5c5SAndroid Build Coastguard Worker }
190*8975f5c5SAndroid Build Coastguard Worker
191*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
192*8975f5c5SAndroid Build Coastguard Worker template <typename Type2>
VectorBase(const VectorBase<Dimension,Type2> & other)193*8975f5c5SAndroid Build Coastguard Worker VectorBase<Dimension, Type>::VectorBase(const VectorBase<Dimension, Type2> &other)
194*8975f5c5SAndroid Build Coastguard Worker {
195*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
196*8975f5c5SAndroid Build Coastguard Worker {
197*8975f5c5SAndroid Build Coastguard Worker mData[i] = static_cast<Type>(other.mData[i]);
198*8975f5c5SAndroid Build Coastguard Worker }
199*8975f5c5SAndroid Build Coastguard Worker }
200*8975f5c5SAndroid Build Coastguard Worker
201*8975f5c5SAndroid Build Coastguard Worker // Ideally we would like to have only two constructors:
202*8975f5c5SAndroid Build Coastguard Worker // - a scalar constructor that takes Type as a parameter
203*8975f5c5SAndroid Build Coastguard Worker // - a compound constructor
204*8975f5c5SAndroid Build Coastguard Worker // However if we define the compound constructor for when it has a single arguments, then calling
205*8975f5c5SAndroid Build Coastguard Worker // Vector2(0.0) will be ambiguous. To solve this we take advantage of there being a single compound
206*8975f5c5SAndroid Build Coastguard Worker // constructor with a single argument, which is the copy constructor. We end up with three
207*8975f5c5SAndroid Build Coastguard Worker // constructors:
208*8975f5c5SAndroid Build Coastguard Worker // - the scalar constructor
209*8975f5c5SAndroid Build Coastguard Worker // - the copy constructor
210*8975f5c5SAndroid Build Coastguard Worker // - the compound constructor for two or more arguments, hence the arg1, and arg2 here.
211*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
212*8975f5c5SAndroid Build Coastguard Worker template <typename Arg1, typename Arg2, typename... Args>
VectorBase(const Arg1 & arg1,const Arg2 & arg2,const Args &...args)213*8975f5c5SAndroid Build Coastguard Worker VectorBase<Dimension, Type>::VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &...args)
214*8975f5c5SAndroid Build Coastguard Worker {
215*8975f5c5SAndroid Build Coastguard Worker initWithList<0>(arg1, arg2, args...);
216*8975f5c5SAndroid Build Coastguard Worker }
217*8975f5c5SAndroid Build Coastguard Worker
218*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
219*8975f5c5SAndroid Build Coastguard Worker template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
initWithList(const Vector<OtherDimension,OtherType> & arg1,const Args &...args)220*8975f5c5SAndroid Build Coastguard Worker void VectorBase<Dimension, Type>::initWithList(const Vector<OtherDimension, OtherType> &arg1,
221*8975f5c5SAndroid Build Coastguard Worker const Args &...args)
222*8975f5c5SAndroid Build Coastguard Worker {
223*8975f5c5SAndroid Build Coastguard Worker static_assert(CurrentIndex + OtherDimension <= Dimension,
224*8975f5c5SAndroid Build Coastguard Worker "Too much data in the vector constructor.");
225*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < OtherDimension; ++i)
226*8975f5c5SAndroid Build Coastguard Worker {
227*8975f5c5SAndroid Build Coastguard Worker mData[CurrentIndex + i] = static_cast<Type>(arg1.mData[i]);
228*8975f5c5SAndroid Build Coastguard Worker }
229*8975f5c5SAndroid Build Coastguard Worker initWithList<CurrentIndex + OtherDimension>(args...);
230*8975f5c5SAndroid Build Coastguard Worker }
231*8975f5c5SAndroid Build Coastguard Worker
232*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
233*8975f5c5SAndroid Build Coastguard Worker template <size_t CurrentIndex, typename OtherType, typename... Args>
234*8975f5c5SAndroid Build Coastguard Worker typename std::enable_if<std::is_arithmetic<OtherType>::value>::type
initWithList(OtherType arg1,const Args &...args)235*8975f5c5SAndroid Build Coastguard Worker VectorBase<Dimension, Type>::initWithList(OtherType arg1, const Args &...args)
236*8975f5c5SAndroid Build Coastguard Worker {
237*8975f5c5SAndroid Build Coastguard Worker static_assert(CurrentIndex + 1 <= Dimension, "Too much data in the vector constructor.");
238*8975f5c5SAndroid Build Coastguard Worker mData[CurrentIndex] = static_cast<Type>(arg1);
239*8975f5c5SAndroid Build Coastguard Worker initWithList<CurrentIndex + 1>(args...);
240*8975f5c5SAndroid Build Coastguard Worker }
241*8975f5c5SAndroid Build Coastguard Worker
242*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
243*8975f5c5SAndroid Build Coastguard Worker template <size_t CurrentIndex>
initWithList()244*8975f5c5SAndroid Build Coastguard Worker void VectorBase<Dimension, Type>::initWithList() const
245*8975f5c5SAndroid Build Coastguard Worker {
246*8975f5c5SAndroid Build Coastguard Worker static_assert(CurrentIndex == Dimension, "Not enough data in the vector constructor.");
247*8975f5c5SAndroid Build Coastguard Worker }
248*8975f5c5SAndroid Build Coastguard Worker
249*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
Load(const Type * source)250*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::Load(const Type *source)
251*8975f5c5SAndroid Build Coastguard Worker {
252*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> result;
253*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
254*8975f5c5SAndroid Build Coastguard Worker {
255*8975f5c5SAndroid Build Coastguard Worker result.mData[i] = source[i];
256*8975f5c5SAndroid Build Coastguard Worker }
257*8975f5c5SAndroid Build Coastguard Worker return result;
258*8975f5c5SAndroid Build Coastguard Worker }
259*8975f5c5SAndroid Build Coastguard Worker
260*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
Store(const Vector<Dimension,Type> & source,Type * destination)261*8975f5c5SAndroid Build Coastguard Worker void VectorBase<Dimension, Type>::Store(const Vector<Dimension, Type> &source, Type *destination)
262*8975f5c5SAndroid Build Coastguard Worker {
263*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
264*8975f5c5SAndroid Build Coastguard Worker {
265*8975f5c5SAndroid Build Coastguard Worker destination[i] = source.mData[i];
266*8975f5c5SAndroid Build Coastguard Worker }
267*8975f5c5SAndroid Build Coastguard Worker }
268*8975f5c5SAndroid Build Coastguard Worker
269*8975f5c5SAndroid Build Coastguard Worker // Implementation of basic arithmetic operations
270*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
271*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+() const
272*8975f5c5SAndroid Build Coastguard Worker {
273*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> result;
274*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
275*8975f5c5SAndroid Build Coastguard Worker {
276*8975f5c5SAndroid Build Coastguard Worker result.mData[i] = +mData[i];
277*8975f5c5SAndroid Build Coastguard Worker }
278*8975f5c5SAndroid Build Coastguard Worker return result;
279*8975f5c5SAndroid Build Coastguard Worker }
280*8975f5c5SAndroid Build Coastguard Worker
281*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
282*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-() const
283*8975f5c5SAndroid Build Coastguard Worker {
284*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> result;
285*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
286*8975f5c5SAndroid Build Coastguard Worker {
287*8975f5c5SAndroid Build Coastguard Worker result.mData[i] = -mData[i];
288*8975f5c5SAndroid Build Coastguard Worker }
289*8975f5c5SAndroid Build Coastguard Worker return result;
290*8975f5c5SAndroid Build Coastguard Worker }
291*8975f5c5SAndroid Build Coastguard Worker
292*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
293*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+(
294*8975f5c5SAndroid Build Coastguard Worker const Vector<Dimension, Type> &other) const
295*8975f5c5SAndroid Build Coastguard Worker {
296*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> result;
297*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
298*8975f5c5SAndroid Build Coastguard Worker {
299*8975f5c5SAndroid Build Coastguard Worker result.mData[i] = mData[i] + other.mData[i];
300*8975f5c5SAndroid Build Coastguard Worker }
301*8975f5c5SAndroid Build Coastguard Worker return result;
302*8975f5c5SAndroid Build Coastguard Worker }
303*8975f5c5SAndroid Build Coastguard Worker
304*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
305*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-(
306*8975f5c5SAndroid Build Coastguard Worker const Vector<Dimension, Type> &other) const
307*8975f5c5SAndroid Build Coastguard Worker {
308*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> result;
309*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
310*8975f5c5SAndroid Build Coastguard Worker {
311*8975f5c5SAndroid Build Coastguard Worker result.mData[i] = mData[i] - other.mData[i];
312*8975f5c5SAndroid Build Coastguard Worker }
313*8975f5c5SAndroid Build Coastguard Worker return result;
314*8975f5c5SAndroid Build Coastguard Worker }
315*8975f5c5SAndroid Build Coastguard Worker
316*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
317*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(
318*8975f5c5SAndroid Build Coastguard Worker const Vector<Dimension, Type> &other) const
319*8975f5c5SAndroid Build Coastguard Worker {
320*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> result;
321*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
322*8975f5c5SAndroid Build Coastguard Worker {
323*8975f5c5SAndroid Build Coastguard Worker result.mData[i] = mData[i] * other.mData[i];
324*8975f5c5SAndroid Build Coastguard Worker }
325*8975f5c5SAndroid Build Coastguard Worker return result;
326*8975f5c5SAndroid Build Coastguard Worker }
327*8975f5c5SAndroid Build Coastguard Worker
328*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
329*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(
330*8975f5c5SAndroid Build Coastguard Worker const Vector<Dimension, Type> &other) const
331*8975f5c5SAndroid Build Coastguard Worker {
332*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> result;
333*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
334*8975f5c5SAndroid Build Coastguard Worker {
335*8975f5c5SAndroid Build Coastguard Worker result.mData[i] = mData[i] / other.mData[i];
336*8975f5c5SAndroid Build Coastguard Worker }
337*8975f5c5SAndroid Build Coastguard Worker return result;
338*8975f5c5SAndroid Build Coastguard Worker }
339*8975f5c5SAndroid Build Coastguard Worker
340*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
341*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(Type other) const
342*8975f5c5SAndroid Build Coastguard Worker {
343*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> result;
344*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
345*8975f5c5SAndroid Build Coastguard Worker {
346*8975f5c5SAndroid Build Coastguard Worker result.mData[i] = mData[i] * other;
347*8975f5c5SAndroid Build Coastguard Worker }
348*8975f5c5SAndroid Build Coastguard Worker return result;
349*8975f5c5SAndroid Build Coastguard Worker }
350*8975f5c5SAndroid Build Coastguard Worker
351*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
352*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(Type other) const
353*8975f5c5SAndroid Build Coastguard Worker {
354*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> result;
355*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
356*8975f5c5SAndroid Build Coastguard Worker {
357*8975f5c5SAndroid Build Coastguard Worker result.mData[i] = mData[i] / other;
358*8975f5c5SAndroid Build Coastguard Worker }
359*8975f5c5SAndroid Build Coastguard Worker return result;
360*8975f5c5SAndroid Build Coastguard Worker }
361*8975f5c5SAndroid Build Coastguard Worker
362*8975f5c5SAndroid Build Coastguard Worker // Implementation of compound arithmetic operations
363*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
364*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator+=(
365*8975f5c5SAndroid Build Coastguard Worker const Vector<Dimension, Type> &other)
366*8975f5c5SAndroid Build Coastguard Worker {
367*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
368*8975f5c5SAndroid Build Coastguard Worker {
369*8975f5c5SAndroid Build Coastguard Worker mData[i] += other.mData[i];
370*8975f5c5SAndroid Build Coastguard Worker }
371*8975f5c5SAndroid Build Coastguard Worker return *static_cast<Vector<Dimension, Type> *>(this);
372*8975f5c5SAndroid Build Coastguard Worker }
373*8975f5c5SAndroid Build Coastguard Worker
374*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
375*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator-=(
376*8975f5c5SAndroid Build Coastguard Worker const Vector<Dimension, Type> &other)
377*8975f5c5SAndroid Build Coastguard Worker {
378*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
379*8975f5c5SAndroid Build Coastguard Worker {
380*8975f5c5SAndroid Build Coastguard Worker mData[i] -= other.mData[i];
381*8975f5c5SAndroid Build Coastguard Worker }
382*8975f5c5SAndroid Build Coastguard Worker return *static_cast<Vector<Dimension, Type> *>(this);
383*8975f5c5SAndroid Build Coastguard Worker }
384*8975f5c5SAndroid Build Coastguard Worker
385*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
386*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(
387*8975f5c5SAndroid Build Coastguard Worker const Vector<Dimension, Type> &other)
388*8975f5c5SAndroid Build Coastguard Worker {
389*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
390*8975f5c5SAndroid Build Coastguard Worker {
391*8975f5c5SAndroid Build Coastguard Worker mData[i] *= other.mData[i];
392*8975f5c5SAndroid Build Coastguard Worker }
393*8975f5c5SAndroid Build Coastguard Worker return *static_cast<Vector<Dimension, Type> *>(this);
394*8975f5c5SAndroid Build Coastguard Worker }
395*8975f5c5SAndroid Build Coastguard Worker
396*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
397*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(
398*8975f5c5SAndroid Build Coastguard Worker const Vector<Dimension, Type> &other)
399*8975f5c5SAndroid Build Coastguard Worker {
400*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
401*8975f5c5SAndroid Build Coastguard Worker {
402*8975f5c5SAndroid Build Coastguard Worker mData[i] /= other.mData[i];
403*8975f5c5SAndroid Build Coastguard Worker }
404*8975f5c5SAndroid Build Coastguard Worker return *static_cast<Vector<Dimension, Type> *>(this);
405*8975f5c5SAndroid Build Coastguard Worker }
406*8975f5c5SAndroid Build Coastguard Worker
407*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
408*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(Type other)
409*8975f5c5SAndroid Build Coastguard Worker {
410*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
411*8975f5c5SAndroid Build Coastguard Worker {
412*8975f5c5SAndroid Build Coastguard Worker mData[i] *= other;
413*8975f5c5SAndroid Build Coastguard Worker }
414*8975f5c5SAndroid Build Coastguard Worker return *static_cast<Vector<Dimension, Type> *>(this);
415*8975f5c5SAndroid Build Coastguard Worker }
416*8975f5c5SAndroid Build Coastguard Worker
417*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
418*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(Type other)
419*8975f5c5SAndroid Build Coastguard Worker {
420*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
421*8975f5c5SAndroid Build Coastguard Worker {
422*8975f5c5SAndroid Build Coastguard Worker mData[i] /= other;
423*8975f5c5SAndroid Build Coastguard Worker }
424*8975f5c5SAndroid Build Coastguard Worker return *static_cast<Vector<Dimension, Type> *>(this);
425*8975f5c5SAndroid Build Coastguard Worker }
426*8975f5c5SAndroid Build Coastguard Worker
427*8975f5c5SAndroid Build Coastguard Worker // Implementation of comparison operators
428*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
429*8975f5c5SAndroid Build Coastguard Worker bool VectorBase<Dimension, Type>::operator==(const VectorBase<Dimension, Type> &other) const
430*8975f5c5SAndroid Build Coastguard Worker {
431*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
432*8975f5c5SAndroid Build Coastguard Worker {
433*8975f5c5SAndroid Build Coastguard Worker if (mData[i] != other.mData[i])
434*8975f5c5SAndroid Build Coastguard Worker {
435*8975f5c5SAndroid Build Coastguard Worker return false;
436*8975f5c5SAndroid Build Coastguard Worker }
437*8975f5c5SAndroid Build Coastguard Worker }
438*8975f5c5SAndroid Build Coastguard Worker return true;
439*8975f5c5SAndroid Build Coastguard Worker }
440*8975f5c5SAndroid Build Coastguard Worker
441*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
442*8975f5c5SAndroid Build Coastguard Worker bool VectorBase<Dimension, Type>::operator!=(const VectorBase<Dimension, Type> &other) const
443*8975f5c5SAndroid Build Coastguard Worker {
444*8975f5c5SAndroid Build Coastguard Worker return !(*this == other);
445*8975f5c5SAndroid Build Coastguard Worker }
446*8975f5c5SAndroid Build Coastguard Worker
447*8975f5c5SAndroid Build Coastguard Worker // Implementation of other arithmetic operations
448*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
length()449*8975f5c5SAndroid Build Coastguard Worker Type VectorBase<Dimension, Type>::length() const
450*8975f5c5SAndroid Build Coastguard Worker {
451*8975f5c5SAndroid Build Coastguard Worker static_assert(std::is_floating_point<Type>::value,
452*8975f5c5SAndroid Build Coastguard Worker "VectorN::length is only defined for floating point vectors");
453*8975f5c5SAndroid Build Coastguard Worker return std::sqrt(lengthSquared());
454*8975f5c5SAndroid Build Coastguard Worker }
455*8975f5c5SAndroid Build Coastguard Worker
456*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
lengthSquared()457*8975f5c5SAndroid Build Coastguard Worker Type VectorBase<Dimension, Type>::lengthSquared() const
458*8975f5c5SAndroid Build Coastguard Worker {
459*8975f5c5SAndroid Build Coastguard Worker return dot(*this);
460*8975f5c5SAndroid Build Coastguard Worker }
461*8975f5c5SAndroid Build Coastguard Worker
462*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
dot(const VectorBase<Dimension,Type> & other)463*8975f5c5SAndroid Build Coastguard Worker Type VectorBase<Dimension, Type>::dot(const VectorBase<Dimension, Type> &other) const
464*8975f5c5SAndroid Build Coastguard Worker {
465*8975f5c5SAndroid Build Coastguard Worker Type sum = Type();
466*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < Dimension; ++i)
467*8975f5c5SAndroid Build Coastguard Worker {
468*8975f5c5SAndroid Build Coastguard Worker sum += mData[i] * other.mData[i];
469*8975f5c5SAndroid Build Coastguard Worker }
470*8975f5c5SAndroid Build Coastguard Worker return sum;
471*8975f5c5SAndroid Build Coastguard Worker }
472*8975f5c5SAndroid Build Coastguard Worker
473*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
474*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector)
475*8975f5c5SAndroid Build Coastguard Worker {
476*8975f5c5SAndroid Build Coastguard Worker ostream << "[ ";
477*8975f5c5SAndroid Build Coastguard Worker for (size_t elementIdx = 0; elementIdx < Dimension; elementIdx++)
478*8975f5c5SAndroid Build Coastguard Worker {
479*8975f5c5SAndroid Build Coastguard Worker if (elementIdx > 0)
480*8975f5c5SAndroid Build Coastguard Worker {
481*8975f5c5SAndroid Build Coastguard Worker ostream << ", ";
482*8975f5c5SAndroid Build Coastguard Worker }
483*8975f5c5SAndroid Build Coastguard Worker ostream << vector.data()[elementIdx];
484*8975f5c5SAndroid Build Coastguard Worker }
485*8975f5c5SAndroid Build Coastguard Worker ostream << " ]";
486*8975f5c5SAndroid Build Coastguard Worker return ostream;
487*8975f5c5SAndroid Build Coastguard Worker }
488*8975f5c5SAndroid Build Coastguard Worker
489*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
normalized()490*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::normalized() const
491*8975f5c5SAndroid Build Coastguard Worker {
492*8975f5c5SAndroid Build Coastguard Worker static_assert(std::is_floating_point<Type>::value,
493*8975f5c5SAndroid Build Coastguard Worker "VectorN::normalized is only defined for floating point vectors");
494*8975f5c5SAndroid Build Coastguard Worker ASSERT(length() != Type());
495*8975f5c5SAndroid Build Coastguard Worker return *this / length();
496*8975f5c5SAndroid Build Coastguard Worker }
497*8975f5c5SAndroid Build Coastguard Worker
498*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
499*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector)
500*8975f5c5SAndroid Build Coastguard Worker {
501*8975f5c5SAndroid Build Coastguard Worker return ostream << static_cast<const VectorBase<2, Type> &>(vector);
502*8975f5c5SAndroid Build Coastguard Worker }
503*8975f5c5SAndroid Build Coastguard Worker
504*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
cross(const Vector<3,Type> & other)505*8975f5c5SAndroid Build Coastguard Worker Vector<3, Type> Vector<3, Type>::cross(const Vector<3, Type> &other) const
506*8975f5c5SAndroid Build Coastguard Worker {
507*8975f5c5SAndroid Build Coastguard Worker return Vector<3, Type>(y() * other.z() - z() * other.y(), z() * other.x() - x() * other.z(),
508*8975f5c5SAndroid Build Coastguard Worker x() * other.y() - y() * other.x());
509*8975f5c5SAndroid Build Coastguard Worker }
510*8975f5c5SAndroid Build Coastguard Worker
511*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
512*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector)
513*8975f5c5SAndroid Build Coastguard Worker {
514*8975f5c5SAndroid Build Coastguard Worker return ostream << static_cast<const VectorBase<3, Type> &>(vector);
515*8975f5c5SAndroid Build Coastguard Worker }
516*8975f5c5SAndroid Build Coastguard Worker
517*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
518*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector)
519*8975f5c5SAndroid Build Coastguard Worker {
520*8975f5c5SAndroid Build Coastguard Worker return ostream << static_cast<const VectorBase<4, Type> &>(vector);
521*8975f5c5SAndroid Build Coastguard Worker }
522*8975f5c5SAndroid Build Coastguard Worker
523*8975f5c5SAndroid Build Coastguard Worker } // namespace angle
524*8975f5c5SAndroid Build Coastguard Worker
525*8975f5c5SAndroid Build Coastguard Worker #endif // COMMON_VECTOR_UTILS_H_
526