MathFu
An open source project by FPL.
 All Classes Namespaces Files Functions Variables Typedefs Friends Groups Pages
vector_2_simd.h
Go to the documentation of this file.
1 /*
2 * Copyright 2014 Google Inc. All rights reserved.
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 #ifndef MATHFU_VECTOR_2_SIMD_H_
17 #define MATHFU_VECTOR_2_SIMD_H_
18 
19 #include "mathfu/internal/vector_2.h"
20 #include "mathfu/utilities.h"
21 
22 #include <math.h>
23 
24 /// @file mathfu/internal/vector_2_simd.h MathFu Vector<T, 2> Specialization
25 /// @brief 2-dimensional specialization of mathfu::Vector for SIMD optimized
26 /// builds.
27 /// @see mathfu::Vector
28 
29 #if !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT) && defined(__ARM_NEON__)
30 #include <vectorial/simd2f.h>
31 #endif
32 
33 namespace mathfu {
34 
35 #if !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT) && defined(__ARM_NEON__)
36 /// @cond MATHFU_INTERNAL
37 template <>
38 class Vector<float, 2> {
39  public:
40  typedef float Scalar;
41 
42  inline Vector() {}
43 
44  inline Vector(const Vector<float, 2>& v) { simd = v.simd; }
45 
46  explicit inline Vector(const Vector<int, 2>& v) {
47  data_[0] = static_cast<float>(v[0]);
48  data_[1] = static_cast<float>(v[1]);
49  }
50 
51  explicit inline Vector(const simd2f& v) { simd = v; }
52 
53  explicit inline Vector(const float& s) { simd = simd2f_create(s, s); }
54 
55  inline Vector(const float& s1, const float& s2) {
56  simd = simd2f_create(s1, s2);
57  }
58 
59  explicit inline Vector(const float* v) { simd = simd2f_uload2(v); }
60 
61  explicit inline Vector(const VectorPacked<float, 2>& vector) {
62  simd = simd2f_uload2(vector.data);
63  }
64 
65  inline float& operator()(const int i) { return data_[i]; }
66 
67  inline const float& operator()(const int i) const { return data_[i]; }
68 
69  inline float& operator[](const int i) { return data_[i]; }
70 
71  inline const float& operator[](const int i) const { return data_[i]; }
72 
73  inline void Pack(VectorPacked<float, 2>* const vector) const {
74  simd2f_ustore2(simd, vector->data);
75  }
76 
77  inline Vector<float, 2> operator-() const {
78  return Vector<float, 2>(simd2f_sub(simd2f_zero(), simd));
79  }
80 
81  inline Vector<float, 2> operator*(const Vector<float, 2>& v) const {
82  return Vector<float, 2>(simd2f_mul(simd, v.simd));
83  }
84 
85  inline Vector<float, 2> operator/(const Vector<float, 2>& v) const {
86  return Vector<float, 2>(simd2f_div(simd, v.simd));
87  }
88 
89  inline Vector<float, 2> operator+(const Vector<float, 2>& v) const {
90  return Vector<float, 2>(simd2f_add(simd, v.simd));
91  }
92 
93  inline Vector<float, 2> operator-(const Vector<float, 2>& v) const {
94  return Vector<float, 2>(simd2f_sub(simd, v.simd));
95  }
96 
97  inline Vector<float, 2> operator*(const float& s) const {
98  return Vector<float, 2>(simd2f_mul(simd, simd2f_splat(s)));
99  }
100 
101  inline Vector<float, 2> operator/(const float& s) const {
102  return Vector<float, 2>(simd2f_div(simd, simd2f_splat(s)));
103  }
104 
105  inline Vector<float, 2> operator+(const float& s) const {
106  return Vector<float, 2>(simd2f_add(simd, simd2f_splat(s)));
107  }
108 
109  inline Vector<float, 2> operator-(const float& s) const {
110  return Vector<float, 2>(simd2f_sub(simd, simd2f_splat(s)));
111  }
112 
113  inline Vector<float, 2>& operator*=(const Vector<float, 2>& v) {
114  simd = simd2f_mul(simd, v.simd);
115  return *this;
116  }
117 
118  inline Vector<float, 2>& operator/=(const Vector<float, 2>& v) {
119  simd = simd2f_div(simd, v.simd);
120  return *this;
121  }
122 
123  inline Vector<float, 2>& operator+=(const Vector<float, 2>& v) {
124  simd = simd2f_add(simd, v.simd);
125  return *this;
126  }
127 
128  inline Vector<float, 2>& operator-=(const Vector<float, 2>& v) {
129  simd = simd2f_sub(simd, v.simd);
130  return *this;
131  }
132 
133  inline Vector<float, 2>& operator*=(const float& s) {
134  simd = simd2f_mul(simd, simd2f_splat(s));
135  return *this;
136  }
137 
138  inline Vector<float, 2>& operator/=(const float& s) {
139  simd = simd2f_div(simd, simd2f_splat(s));
140  return *this;
141  }
142 
143  inline Vector<float, 2>& operator+=(const float& s) {
144  simd = simd2f_add(simd, simd2f_splat(s));
145  return *this;
146  }
147 
148  inline Vector<float, 2>& operator-=(const float& s) {
149  simd = simd2f_sub(simd, simd2f_splat(s));
150  return *this;
151  }
152 
153  inline bool operator==(const Vector<float, 2>& v) const {
154  for (int i = 0; i < 2; ++i) {
155  if ((*this)[i] != v[i]) return false;
156  }
157  return true;
158  }
159 
160  inline bool operator!=(const Vector<float, 2>& v) const {
161  return !operator==(v);
162  }
163 
164  inline float LengthSquared() const {
165  return simd2f_get_x(simd2f_dot2(simd, simd));
166  }
167 
168  inline float Length() const { return simd2f_get_x(simd2f_length2(simd)); }
169 
170  inline float Normalize() {
171  const float length = Length();
172  simd = simd2f_mul(simd, simd2f_splat(1 / length));
173  return length;
174  }
175 
176  inline Vector<float, 2> Normalized() const {
177  return Vector<float, 2>(simd2f_normalize2(simd));
178  }
179 
180  template <typename CompatibleT>
181  static inline Vector<float, 2> FromType(const CompatibleT& compatible) {
182  return FromTypeHelper<float, 2, CompatibleT>(compatible);
183  }
184 
185  template <typename CompatibleT>
186  static inline CompatibleT ToType(const Vector<float, 2>& v) {
187  return ToTypeHelper<float, 2, CompatibleT>(v);
188  }
189 
190  static inline float DotProduct(const Vector<float, 2>& v1,
191  const Vector<float, 2>& v2) {
192  return simd2f_get_x(simd2f_dot2(v1.simd, v2.simd));
193  }
194 
195  static inline Vector<float, 2> HadamardProduct(const Vector<float, 2>& v1,
196  const Vector<float, 2>& v2) {
197  return Vector<float, 2>(simd2f_mul(v1.simd, v2.simd));
198  }
199 
200  static inline Vector<float, 2> Lerp(const Vector<float, 2>& v1,
201  const Vector<float, 2>& v2,
202  float percent) {
203  const Vector<float, 2> percentv(percent);
204  const Vector<float, 2> one_minus_percent(
205  simd2f_sub(simd2f_splat(1.0f), percentv.simd));
206  return Vector<float, 2>(
207  simd2f_add(simd2f_mul(one_minus_percent.simd, v1.simd),
208  simd2f_mul(percentv.simd, v2.simd)));
209  }
210 
211  /// Generates a random vector, where the range for each component is
212  /// bounded by min and max.
213  static inline Vector<float, 2> RandomInRange(const Vector<float, 2>& min,
214  const Vector<float, 2>& max) {
215  return Vector<float, 2>(mathfu::RandomInRange<float>(min[0], max[0]),
216  mathfu::RandomInRange<float>(min[1], max[1]));
217  }
218 
219  static inline Vector<float, 2> Max(const Vector<float, 2>& v1,
220  const Vector<float, 2>& v2) {
221  return Vector<float, 2>(std::max(v1[0], v2[0]), std::max(v1[1], v2[1]));
222  }
223 
224  static inline Vector<float, 2> Min(const Vector<float, 2>& v1,
225  const Vector<float, 2>& v2) {
226  return Vector<float, 2>(std::min(v1[0], v2[0]), std::min(v1[1], v2[1]));
227  }
228 
230 
231 #if defined(__clang__)
232 #pragma clang diagnostic push
233 #pragma clang diagnostic ignored "-Wpedantic"
234 #endif // defined(__clang__)
235  union {
236  simd2f simd;
237  float data_[2];
238  struct {
239  float x;
240  float y;
241  };
242  };
243 #if defined(__clang__)
244 #pragma clang diagnostic pop
245 #endif // defined(__clang__)
246 };
247 /// @endcond
248 #endif // !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT) &&
249  // defined(__ARM_NEON__)
250 
251 } // namespace mathfu
252 
253 #endif // MATHFU_VECTOR_2_SIMD_H_
Vector< T, d > & operator*=(Vector< T, d > &lhs, const Vector< T, d > &rhs)
Multiply (in-place) a vector with another Vector.
Definition: vector.h:665
T LengthSquared() const
Calculate the squared length of this vector.
Definition: vector.h:380
static Vector< T, d > Min(const Vector< T, d > &v1, const Vector< T, d > &v2)
Compare each component and returns min values.
Definition: vector.h:487
T & operator[](const int i)
Access an element of the vector.
Definition: vector.h:306
Utility macros and functions.
T Length() const
Calculate the length of this vector.
Definition: vector.h:385
#define MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
Macro which defines the new and delete for MathFu classes.
Definition: utilities.h:600
static Vector< T, d > Max(const Vector< T, d > &v1, const Vector< T, d > &v2)
Compare each component and returns max values.
Definition: vector.h:477
Vector< T, d > & operator+=(Vector< T, d > &lhs, const Vector< T, d > &rhs)
Add (in-place) a vector with another Vector.
Definition: vector.h:688
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE T data_[d]
Elements of the vector.
Definition: vector.h:495
T Normalize()
Normalize this vector in-place.
Definition: vector.h:390
Vector< T, d > operator/(const Vector< T, d > &v, const T &s)
Divide a Vector by a scalar.
Definition: vector.h:556
Vector< T, d > & operator-=(Vector< T, d > &lhs, const Vector< T, d > &rhs)
Subtract (in-place) another Vector from a vector.
Definition: vector.h:699
static Vector< T, d > HadamardProduct(const Vector< T, d > &v1, const Vector< T, d > &v2)
Calculate the hadamard or componentwise product of two vectors.
Definition: vector.h:435
static CompatibleT ToType(const Vector< T, d > &v)
Load into any type that is some formulation of a length d array of type T.
Definition: vector.h:417
Vector< T, d > operator*(const T &s, const Vector< T, d > &v)
Multiply a Vector by a scalar.
Definition: vector.h:543
Vector< T, d > Normalized() const
Calculate the normalized version of this vector.
Definition: vector.h:395
static T DotProduct(const Vector< T, d > &v1, const Vector< T, d > &v2)
Calculate the dot product of two vectors.
Definition: vector.h:426
Vector< T, d > operator+(const T &s, const Vector< T, d > &v)
Add a scalar to each element of a Vector.
Definition: vector.h:567
void Pack(VectorPacked< T, d > *const vector) const
Pack a Vector to a packed "d" element vector structure.
Definition: vector.h:373
static Vector< T, d > RandomInRange(const Vector< T, d > &min, const Vector< T, d > &max)
Generates a random vector.
Definition: vector.h:467
T & operator()(const int i)
Access an element of the vector.
Definition: vector.h:293
static Vector< T, d > Lerp(const Vector< T, d > &v1, const Vector< T, d > &v2, const T percent)
Linearly interpolate two vectors.
Definition: vector.h:457
bool operator==(const Rect< T > &r1, const Rect< T > &r2)
Check if two rects are identical.
Definition: rect.h:67
Vector()
Create an uninitialized Vector.
Definition: vector.h:163
Vector< T, d > operator-(const T &s, const Vector< T, d > &v)
Subtract a scalar from each element of a Vector.
Definition: vector.h:578
Vector< T, d > & operator/=(Vector< T, d > &lhs, const Vector< T, d > &rhs)
Divide (in-place) a vector by another Vector.
Definition: vector.h:677
bool operator!=(const Rect< T > &r1, const Rect< T > &r2)
Check if two rects are not identical.
Definition: rect.h:76
static Vector< T, d > FromType(const CompatibleT &compatible)
Load from any type that is some formulation of a length d array of type T.
Definition: vector.h:405
T Scalar
Element type to enable reference by other classes.
Definition: vector.h:160