MathFu
An open source project by FPL.
 All Classes Namespaces Files Functions Variables Typedefs Friends Groups Pages
vector_4_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_4_SIMD_H_
17 #define MATHFU_VECTOR_4_SIMD_H_
18 
19 #include "mathfu/internal/vector_4.h"
20 #include "mathfu/utilities.h"
21 
22 #include <math.h>
23 
24 #ifdef MATHFU_COMPILE_WITH_SIMD
25 #include "vectorial/simd4f.h"
26 #endif
27 
28 /// @file mathfu/internal/vector_4_simd.h MathFu Vector<T, 4> Specialization
29 /// @brief 4-dimensional specialization of mathfu::Vector for SIMD optimized
30 /// builds.
31 /// @see mathfu::Vector
32 
33 namespace mathfu {
34 
35 #ifdef MATHFU_COMPILE_WITH_SIMD
36 
37 template <>
38 class Vector<float, 4> {
39  public:
40  typedef float Scalar;
41 
42  inline Vector() {}
43 
44  inline Vector(const Vector<float, 4>& v) { simd = v.simd; }
45 
46  explicit inline Vector(const Vector<int, 4>& v) {
47  data_[0] = static_cast<float>(v[0]);
48  data_[1] = static_cast<float>(v[1]);
49  data_[2] = static_cast<float>(v[2]);
50  data_[3] = static_cast<float>(v[3]);
51  }
52 
53  explicit inline Vector(const simd4f& v) { simd = v; }
54 
55  explicit inline Vector(const float& s) { simd = simd4f_splat(s); }
56 
57  inline Vector(const float& s1, const float& s2, const float& s3,
58  const float& s4) {
59  simd = simd4f_create(s1, s2, s3, s4);
60  }
61 
62  explicit inline Vector(const float* v) { simd = simd4f_uload4(v); }
63 
64  inline Vector(const Vector<float, 3>& vector3, const float& value) {
65 #ifdef MATHFU_COMPILE_WITH_PADDING
66  simd = vector3.simd;
67  (*this)[3] = value;
68 #else
69  simd = simd4f_create(vector3[0], vector3[1], vector3[2], value);
70 #endif // MATHFU_COMPILE_WITH_PADDING
71  }
72 
73  inline Vector(const Vector<float, 2>& vector12,
74  const Vector<float, 2>& vector34) {
75  simd = simd4f_create(vector12[0], vector12[1], vector34[0], vector34[1]);
76  }
77 
78  explicit inline Vector(const VectorPacked<float, 4>& vector) {
79  simd = simd4f_uload4(vector.data);
80  }
81 
82  inline float& operator()(const int i) { return data_[i]; }
83 
84  inline const float& operator()(const int i) const { return data_[i]; }
85 
86  inline float& operator[](const int i) { return data_[i]; }
87 
88  inline const float& operator[](const int i) const { return data_[i]; }
89 
90  /// GLSL style multi-component accessors.
91  inline Vector<float, 3> xyz() { return Vector<float, 3>(x, y, z); }
92  inline const Vector<float, 3> xyz() const {
93  return Vector<float, 3>(x, y, z);
94  }
95 
96  inline Vector<float, 2> xy() { return Vector<float, 2>(x, y); }
97  inline const Vector<float, 2> xy() const { return Vector<float, 2>(x, y); }
98 
99  inline Vector<float, 2> zw() { return Vector<float, 2>(z, w); }
100  inline const Vector<float, 2> zw() const { return Vector<float, 2>(z, w); }
101 
102  inline void Pack(VectorPacked<float, 4>* const vector) const {
103  simd4f_ustore4(simd, vector->data);
104  }
105 
106  inline Vector<float, 4> operator-() const {
107  return Vector<float, 4>(simd4f_sub(simd4f_zero(), simd));
108  }
109 
110  inline Vector<float, 4> operator*(const Vector<float, 4>& v) const {
111  return Vector<float, 4>(simd4f_mul(simd, v.simd));
112  }
113 
114  inline Vector<float, 4> operator/(const Vector<float, 4>& v) const {
115  return Vector<float, 4>(simd4f_div(simd, v.simd));
116  }
117 
118  inline Vector<float, 4> operator+(const Vector<float, 4>& v) const {
119  return Vector<float, 4>(simd4f_add(simd, v.simd));
120  }
121 
122  inline Vector<float, 4> operator-(const Vector<float, 4>& v) const {
123  return Vector<float, 4>(simd4f_sub(simd, v.simd));
124  }
125 
126  inline Vector<float, 4> operator*(const float& s) const {
127  return Vector<float, 4>(simd4f_mul(simd, simd4f_splat(s)));
128  }
129 
130  inline Vector<float, 4> operator/(const float& s) const {
131  return Vector<float, 4>(simd4f_div(simd, simd4f_splat(s)));
132  }
133 
134  inline Vector<float, 4> operator+(const float& s) const {
135  return Vector<float, 4>(simd4f_add(simd, simd4f_splat(s)));
136  }
137 
138  inline Vector<float, 4> operator-(const float& s) const {
139  return Vector<float, 4>(simd4f_sub(simd, simd4f_splat(s)));
140  }
141 
142  inline Vector<float, 4>& operator*=(const Vector<float, 4>& v) {
143  simd = simd4f_mul(simd, v.simd);
144  return *this;
145  }
146 
147  inline Vector<float, 4>& operator/=(const Vector<float, 4>& v) {
148  simd = simd4f_div(simd, v.simd);
149  return *this;
150  }
151 
152  inline Vector<float, 4>& operator+=(const Vector<float, 4>& v) {
153  simd = simd4f_add(simd, v.simd);
154  return *this;
155  }
156 
157  inline Vector<float, 4>& operator-=(const Vector<float, 4>& v) {
158  simd = simd4f_sub(simd, v.simd);
159  return *this;
160  }
161 
162  inline Vector<float, 4>& operator*=(const float& s) {
163  simd = simd4f_mul(simd, simd4f_splat(s));
164  return *this;
165  }
166 
167  inline Vector<float, 4>& operator/=(const float& s) {
168  simd = simd4f_div(simd, simd4f_splat(s));
169  return *this;
170  }
171 
172  inline Vector<float, 4>& operator+=(const float& s) {
173  simd = simd4f_add(simd, simd4f_splat(s));
174  return *this;
175  }
176 
177  inline Vector<float, 4>& operator-=(const float& s) {
178  simd = simd4f_sub(simd, simd4f_splat(s));
179  return *this;
180  }
181 
182  inline bool operator==(const Vector<float, 4>& v) const {
183  for (int i = 0; i < 4; ++i) {
184  if ((*this)[i] != v[i]) return false;
185  }
186  return true;
187  }
188 
189  inline bool operator!=(const Vector<float, 4>& v) const {
190  return !operator==(v);
191  }
192 
193  inline float LengthSquared() const {
194  return simd4f_get_x(simd4f_dot4(simd, simd));
195  }
196 
197  inline float Length() const { return simd4f_get_x(simd4f_length4(simd)); }
198 
199  inline float Normalize() {
200  const float length = Length();
201  simd = simd4f_mul(simd, simd4f_splat(1 / length));
202  return length;
203  }
204 
205  inline Vector<float, 4> Normalized() const {
206  return Vector<float, 4>(simd4f_normalize4(simd));
207  }
208 
209  template <typename CompatibleT>
210  static inline Vector<float, 4> FromType(const CompatibleT& compatible) {
211  return FromTypeHelper<float, 4, CompatibleT>(compatible);
212  }
213 
214  template <typename CompatibleT>
215  static inline CompatibleT ToType(const Vector<float, 4>& v) {
216  return ToTypeHelper<float, 4, CompatibleT>(v);
217  }
218 
219  static inline float DotProduct(const Vector<float, 4>& v1,
220  const Vector<float, 4>& v2) {
221  return simd4f_get_x(simd4f_dot4(v1.simd, v2.simd));
222  }
223 
224  static inline Vector<float, 4> HadamardProduct(const Vector<float, 4>& v1,
225  const Vector<float, 4>& v2) {
226  return Vector<float, 4>(simd4f_mul(v1.simd, v2.simd));
227  }
228 
229  static inline Vector<float, 4> Lerp(const Vector<float, 4>& v1,
230  const Vector<float, 4>& v2,
231  float percent) {
232  const Vector<float, 4> percentv(percent);
233  const Vector<float, 4> one(1.0f);
234  const Vector<float, 4> one_minus_percent = one - percentv;
235  return Vector<float, 4>(
236  simd4f_add(simd4f_mul(one_minus_percent.simd, v1.simd),
237  simd4f_mul(percentv.simd, v2.simd)));
238  }
239 
240  /// Generates a random vector, where the range for each component is
241  /// bounded by min and max.
243  const Vector<float, 4>& max) {
244  return Vector<float, 4>(mathfu::RandomInRange<float>(min[0], max[0]),
245  mathfu::RandomInRange<float>(min[1], max[1]),
246  mathfu::RandomInRange<float>(min[2], max[2]),
247  mathfu::RandomInRange<float>(min[3], max[3]));
248  }
249 
250  static inline Vector<float, 4> Max(const Vector<float, 4>& v1,
251  const Vector<float, 4>& v2) {
252  return Vector<float, 4>(simd4f_max(v1.simd, v2.simd));
253  }
254 
255  static inline Vector<float, 4> Min(const Vector<float, 4>& v1,
256  const Vector<float, 4>& v2) {
257  return Vector<float, 4>(simd4f_min(v1.simd, v2.simd));
258  }
259 
260  template <class T, int rows, int cols>
261  friend class Matrix;
262 
264 
265 #include "mathfu/internal/disable_warnings_begin.h"
266  union {
267  simd4f simd;
268  float data_[4];
269  struct {
270  float x;
271  float y;
272  float z;
273  float w;
274  };
275  };
276 #include "mathfu/internal/disable_warnings_end.h"
277 };
278 /// @endcond
279 #endif // MATHFU_COMPILE_WITH_SIMD
280 
281 } // namespace mathfu
282 
283 #endif // MATHFU_VECTOR_4_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
Vector of d elements with type T.
Definition: vector.h:63
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, 2 > zw()
GLSL style 2 element accessor.
Definition: vector.h:356
Vector< T, d > operator*(const T &s, const Vector< T, d > &v)
Multiply a Vector by a scalar.
Definition: vector.h:543
Vector< T, 2 > xy()
GLSL style 2 element accessor.
Definition: vector.h:338
T data[d]
Elements of the packed vector one per dimension.
Definition: vector.h:142
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
Packed N-dimensional vector.
Definition: vector.h:121
Definition: vector_4_simd.h:38
void Pack(VectorPacked< T, d > *const vector) const
Pack a Vector to a packed "d" element vector structure.
Definition: vector.h:373
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
Vector< T, 3 > xyz()
GLSL style 3 element accessor.
Definition: vector.h:319
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
static Vector< float, 4 > RandomInRange(const Vector< float, 4 > &min, const Vector< float, 4 > &max)
Definition: vector_4_simd.h:242
Vector< float, 3 > xyz()
GLSL style multi-component accessors.
Definition: vector_4_simd.h:91