blob: 269ecac53b9392e4a6fe29b34c8bda88ea9fb6b8 [file] [log] [blame]
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MATHFU_INTERNAL_VECTOR_4_H_
#define MATHFU_INTERNAL_VECTOR_4_H_
// Prefer including vector.h directly, since it includes specializations.
#include "mathfu/vector.h"
namespace mathfu {
template <class T>
class Vector<T, 4> {
public:
typedef T Scalar;
static const int d = 4;
inline Vector() {}
inline Vector(const Vector<T, 4>& v) {
MATHFU_VECTOR_OPERATION(data_[i] = v.data_[i]);
}
template <typename U>
explicit inline Vector(const Vector<U, 4>& v) {
MATHFU_VECTOR_OPERATION(data_[i] = static_cast<T>(v[i]));
}
explicit inline Vector(const T& s) { MATHFU_VECTOR_OPERATION(data_[i] = s); }
explicit inline Vector(const T* a) {
MATHFU_VECTOR_OPERATION(data_[i] = a[i]);
}
inline Vector(const T& s1, const T& s2, const T& s3, const T& s4) {
x = s1;
y = s2;
z = s3;
w = s4;
}
inline Vector(const Vector<T, 3>& vector3, const T& value) {
x = vector3[0];
y = vector3[1];
z = vector3[2];
w = value;
}
inline Vector(const Vector<T, 2>& v12, const Vector<T, 2>& v34) {
x = v12[0];
y = v12[1];
z = v34[0];
w = v34[1];
}
explicit inline Vector(const VectorPacked<T, 4>& vector) {
MATHFU_VECTOR_OPERATION(data_[i] = vector.data[i]);
}
inline T& operator()(const int i) { return data_[i]; }
inline const T& operator()(const int i) const { return data_[i]; }
inline T& operator[](const int i) { return data_[i]; }
inline const T& operator[](const int i) const { return data_[i]; }
inline Vector<T, 3> xyz() { return Vector<T, 3>(x, y, z); }
inline const Vector<T, 3> xyz() const { return Vector<T, 3>(x, y, z); }
inline Vector<T, 2> xy() { return Vector<T, 2>(x, y); }
inline const Vector<T, 2> xy() const { return Vector<T, 2>(x, y); }
inline Vector<T, 2> zw() { return Vector<T, 2>(z, w); }
inline const Vector<T, 2> zw() const { return Vector<T, 2>(z, w); }
inline void Pack(VectorPacked<T, 4>* const vector) const {
MATHFU_VECTOR_OPERATION(vector->data[i] = data_[i]);
}
inline T LengthSquared() const { return LengthSquaredHelper(*this); }
inline T Length() const { return LengthHelper(*this); }
inline T Normalize() { return NormalizeHelper(*this); }
inline Vector<T, 4> Normalized() const { return NormalizedHelper(*this); }
template <typename CompatibleT>
static inline Vector<T, 4> FromType(const CompatibleT& compatible) {
return FromTypeHelper<T, d, CompatibleT>(compatible);
}
template <typename CompatibleT>
static inline CompatibleT ToType(const Vector<T, 4>& v) {
return ToTypeHelper<T, d, CompatibleT>(v);
}
static inline T DotProduct(const Vector<T, 4>& v1, const Vector<T, 4>& v2) {
return DotProductHelper(v1, v2);
}
static inline Vector<T, 4> HadamardProduct(const Vector<T, 4>& v1,
const Vector<T, 4>& v2) {
return HadamardProductHelper(v1, v2);
}
static inline Vector<T, 4> Lerp(const Vector<T, 4>& v1,
const Vector<T, 4>& v2, const T percent) {
return LerpHelper(v1, v2, percent);
}
static inline Vector<T, 4> RandomInRange(const Vector<T, 4>& min,
const Vector<T, 4>& max) {
return RandomInRangeHelper(min, max);
}
static inline Vector<T, 4> Max(const Vector<T, 4>& v1,
const Vector<T, 4>& v2) {
return MaxHelper(v1, v2);
}
static inline Vector<T, 4> Min(const Vector<T, 4>& v1,
const Vector<T, 4>& v2) {
return MinHelper(v1, v2);
}
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
#include "mathfu/internal/disable_warnings_begin.h"
union {
T data_[4];
struct {
T x;
T y;
T z;
T w;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
template <class T>
struct VectorPacked<T, 4> {
/// Create an uninitialized VectorPacked.
VectorPacked() {}
/// Create a VectorPacked from a Vector.
///
/// Both VectorPacked and Vector must have the same number of dimensions.
/// @param vector Vector to create the VectorPacked from.
explicit VectorPacked(const Vector<T, 4>& vector) { vector.Pack(this); }
/// Copy a Vector to a VectorPacked.
///
/// Both VectorPacked and Vector must have the same number of dimensions.
/// @param vector Vector to copy to the VectorPacked.
/// @returns A reference to this VectorPacked.
VectorPacked& operator=(const Vector<T, 4>& vector) {
vector.Pack(this);
return *this;
}
#include "mathfu/internal/disable_warnings_begin.h"
/// Elements of the packed vector one per dimension.
union {
T data[4];
struct {
T x;
T y;
T z;
T w;
};
};
#include "mathfu/internal/disable_warnings_end.h"
};
} // namespace mathfu
#endif // MATHFU_INTERNAL_VECTOR_4_H_