Add support for 4D vectors.

This commit is contained in:
King_DuckZ 2018-07-27 23:41:23 +01:00
parent 08378698b8
commit a81c4c1077
2 changed files with 145 additions and 0 deletions

View File

@ -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 );

View File

@ -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) {