Add support for 4D vectors.
This commit is contained in:
parent
08378698b8
commit
a81c4c1077
2 changed files with 145 additions and 0 deletions
|
@ -104,9 +104,47 @@ namespace vwr {
|
|||
lower_vector_type yz ( void ) const;
|
||||
};
|
||||
|
||||
template <typename V, bool Enabled> struct Vec4Demotion;
|
||||
template <typename V> struct Vec4Demotion<V, false> {};
|
||||
template <typename V> struct Vec4Demotion<V, true> {
|
||||
typedef Vec<typename VectorWrapperInfo<V>::lower_vector_type> lower_vector_type;
|
||||
typedef typename VectorWrapperInfo<V>::scalar_type scalar_type;
|
||||
|
||||
static_assert(VectorWrapperInfo<typename VectorWrapperInfo<V>::lower_vector_type>::dimensions == 3, "Wrong demoted vector type");
|
||||
|
||||
lower_vector_type xyz ( void ) const;
|
||||
lower_vector_type xyw ( void ) const;
|
||||
lower_vector_type xzw ( void ) const;
|
||||
lower_vector_type yzw ( void ) const;
|
||||
};
|
||||
|
||||
template <typename V, size_type D>
|
||||
struct VecAccessors;
|
||||
|
||||
template <typename V>
|
||||
struct VecAccessors<V, 4> : Vec4Demotion<V, HasLowerVecTypedef<VectorWrapperInfo<V>>::value> {
|
||||
typedef typename VectorWrapperInfo<V>::scalar_type scalar_type;
|
||||
const Vec<V>& xyzw ( void ) const { return *static_cast<const Vec<V>*>(this); }
|
||||
const scalar_type& x ( void ) const;
|
||||
const scalar_type& y ( void ) const;
|
||||
const scalar_type& z ( void ) const;
|
||||
const scalar_type& w ( void ) const;
|
||||
scalar_type& x ( void );
|
||||
scalar_type& y ( void );
|
||||
scalar_type& z ( void );
|
||||
scalar_type& w ( void );
|
||||
|
||||
#if defined(VWR_EXTRA_ACCESSORS)
|
||||
Vec<V> xyz0 ( void ) const { return Vec<V>(x(), y(), z(), scalar_type(0)); }
|
||||
Vec<V> xyz1 ( void ) const { return Vec<V>(x(), y(), z(), scalar_type(1)); }
|
||||
Vec<V> x0zw ( void ) const { return Vec<V>(x(), scalar_type(0), z(), w()); }
|
||||
Vec<V> x1zw ( void ) const { return Vec<V>(x(), scalar_type(1), z(), w()); }
|
||||
Vec<V> _0yzw ( void ) const { return Vec<V>(scalar_type(0), y(), z(), w()); }
|
||||
Vec<V> _1yzw ( void ) const { return Vec<V>(scalar_type(1), y(), z(), w()); }
|
||||
Vec<V> wxyz ( void ) const { return Vec<V>(w(), x(), y(), z()); }
|
||||
#endif
|
||||
};
|
||||
|
||||
//Workaround for visual studio - VecAccessors<V, 3> should inherit from
|
||||
//both Vec3Promotion and Vec3Demotion, but when I do that, sizeof(Vec)
|
||||
//is wrong. I had to linearize the inheritance hierarchy so that the
|
||||
|
@ -260,6 +298,37 @@ namespace vwr {
|
|||
Vec& operator= ( const vector_type& parOther ) { this->data() = parOther; return *this; }
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
class Vec<V, 4> : public implem::VecBase<V>, public implem::VecAccessors<V, 4> {
|
||||
static_assert(std::is_standard_layout<implem::VecBase<V>>::value, "Base class must be a standard layout type");
|
||||
static_assert(std::is_standard_layout<implem::VecAccessors<V, 4>>::value, "Base class must be a standard layout type");
|
||||
public:
|
||||
typedef typename implem::VecBase<V>::scalar_type scalar_type;
|
||||
typedef typename implem::VecBase<V>::vector_type vector_type;
|
||||
enum {
|
||||
dimensions = 4
|
||||
};
|
||||
|
||||
static const Vec<V, 4> unit_x;
|
||||
static const Vec<V, 4> unit_y;
|
||||
static const Vec<V, 4> unit_z;
|
||||
static const Vec<V, 4> unit_w;
|
||||
|
||||
Vec ( void ) = default;
|
||||
Vec ( const Vec& ) = default;
|
||||
explicit Vec ( const vector_type& parIn ) : implem::VecBase<V>(parIn) { }
|
||||
explicit Vec ( const scalar_type parX ) : implem::VecBase<V>(parX) { }
|
||||
Vec ( scalar_type parX, scalar_type parY, scalar_type parZ, scalar_type parW ) : implem::VecBase<V>(parX, parY, parZ, parW) { }
|
||||
#if defined(VWR_WITH_IMPLICIT_CONVERSIONS)
|
||||
template <typename V2> Vec ( const Vec<V2, dimensions>& parOther ) { implem::assign(*this, parOther); }
|
||||
template <typename V2>
|
||||
Vec& operator= ( const Vec<V2, dimensions>& parOther ) { return implem::assign(*this, parOther); }
|
||||
#endif
|
||||
|
||||
Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); }
|
||||
Vec& operator= ( const vector_type& parOther ) { this->data() = parOther; return *this; }
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
Vec<V> mk_vec ( const V& parVec );
|
||||
|
||||
|
|
|
@ -72,6 +72,30 @@ namespace vwr {
|
|||
return lower_vector_type(this_vec[1], this_vec[2]);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto Vec4Demotion<V, true>::xyz() const -> lower_vector_type {
|
||||
auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||
return lower_vector_type(this_vec[0], this_vec[1], this_vec[2]);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto Vec4Demotion<V, true>::xyw() const -> lower_vector_type {
|
||||
auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||
return lower_vector_type(this_vec[0], this_vec[1], this_vec[3]);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto Vec4Demotion<V, true>::xzw() const -> lower_vector_type {
|
||||
auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||
return lower_vector_type(this_vec[0], this_vec[2], this_vec[3]);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto Vec4Demotion<V, true>::yzw() const -> lower_vector_type {
|
||||
auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||
return lower_vector_type(this_vec[1], this_vec[2], this_vec[3]);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto Vec1Promotion<V, true>::xn (const scalar_type& parN) const -> higher_vector_type {
|
||||
auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||
|
@ -168,6 +192,54 @@ namespace vwr {
|
|||
return this_vec[2];
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto VecAccessors<V, 4>::x() -> scalar_type& {
|
||||
auto& this_vec = *static_cast<Vec<V>*>(this);
|
||||
return this_vec[0];
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto VecAccessors<V, 4>::x() const -> const scalar_type& {
|
||||
const auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||
return this_vec[0];
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto VecAccessors<V, 4>::y() -> scalar_type& {
|
||||
auto& this_vec = *static_cast<Vec<V>*>(this);
|
||||
return this_vec[1];
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto VecAccessors<V, 4>::y() const -> const scalar_type& {
|
||||
const auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||
return this_vec[1];
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto VecAccessors<V, 4>::z() -> scalar_type& {
|
||||
auto& this_vec = *static_cast<Vec<V>*>(this);
|
||||
return this_vec[2];
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto VecAccessors<V, 4>::z() const -> const scalar_type& {
|
||||
const auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||
return this_vec[2];
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto VecAccessors<V, 4>::w() -> scalar_type& {
|
||||
auto& this_vec = *static_cast<Vec<V>*>(this);
|
||||
return this_vec[3];
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
auto VecAccessors<V, 4>::w() const -> const scalar_type& {
|
||||
const auto& this_vec = *static_cast<const Vec<V>*>(this);
|
||||
return this_vec[3];
|
||||
}
|
||||
|
||||
template <typename T, size_type S>
|
||||
template <size_type... I>
|
||||
offsets_array_wrapper<T, S>::offsets_array_wrapper (const bt::number_seq<size_type, I...>&) :
|
||||
|
@ -222,6 +294,10 @@ namespace vwr {
|
|||
template <typename V> const Vec<V, 3> Vec<V, 3>::unit_x(scalar_type(1), scalar_type(0), scalar_type(0));
|
||||
template <typename V> const Vec<V, 3> Vec<V, 3>::unit_y(scalar_type(0), scalar_type(1), scalar_type(0));
|
||||
template <typename V> const Vec<V, 3> Vec<V, 3>::unit_z(scalar_type(0), scalar_type(0), scalar_type(1));
|
||||
template <typename V> const Vec<V, 4> Vec<V, 4>::unit_x(scalar_type(1), scalar_type(0), scalar_type(0), scalar_type(0));
|
||||
template <typename V> const Vec<V, 4> Vec<V, 4>::unit_y(scalar_type(0), scalar_type(1), scalar_type(0), scalar_type(0));
|
||||
template <typename V> const Vec<V, 4> Vec<V, 4>::unit_z(scalar_type(0), scalar_type(0), scalar_type(1), scalar_type(0));
|
||||
template <typename V> const Vec<V, 4> Vec<V, 4>::unit_w(scalar_type(0), scalar_type(0), scalar_type(0), scalar_type(1));
|
||||
|
||||
template <typename V>
|
||||
Vec<V> mk_vec (const V& parVec) {
|
||||
|
|
Loading…
Reference in a new issue