Radium Engine  1.5.20
Loading...
Searching...
No Matches
VectorArray.hpp
1#pragma once
2
3#include <Core/Containers/AlignedStdVector.hpp>
4#include <Core/RaCore.hpp>
5#include <Core/Utils/ContainerIntrospectionInterface.hpp>
6
7#include <type_traits> // std::is_integral
8
9namespace Ra {
10namespace Core {
11
15template <typename V, bool isArithmetic, bool isEigen>
17
22template <typename V>
24 V,
25 std::is_arithmetic<V>::value || std::is_enum<V>::value,
26 std::is_base_of<typename Eigen::MatrixBase<V>, V>::value> {};
27
33template <typename V>
35{
36 private:
38
39 public:
40 static constexpr int NumberOfComponents = TypeHelper::NumberOfComponents;
46 using component_type = typename TypeHelper::component_type;
47 using Matrix = Eigen::Matrix<component_type, TypeHelper::NumberOfComponents, Eigen::Dynamic>;
48 using MatrixMap = Eigen::Map<Matrix>;
49 using ConstMatrixMap = Eigen::Map<const Matrix>;
50
53
56 size_t getSize() const override { return this->size(); }
57 size_t getNumberOfComponents() const override { return std::max( 0, NumberOfComponents ); }
58 size_t getBufferSize() const override { return getSize() * sizeof( V ); }
59 int getStride() const override { return sizeof( V ); }
60 const void* dataPtr() const override { return this->data(); }
62
68
69 template <int N = NumberOfComponents>
70 std::enable_if_t<( N > 0 ), MatrixMap> getMap() {
71 CORE_ASSERT( !this->empty(), "Cannot map an empty vector " );
72 return MatrixMap( TypeHelper::getData( this ),
73 TypeHelper::NumberOfComponents,
74 Eigen::Index( this->size() ) );
75 }
76
78 template <int N = NumberOfComponents>
79 std::enable_if_t<( N > 0 ), ConstMatrixMap> getMap() const {
80 CORE_ASSERT( !this->empty(), "Cannot map an empty vector " );
81 return ConstMatrixMap( TypeHelper::getConstData( this ),
82 TypeHelper::NumberOfComponents,
83 Eigen::Index( this->size() ) );
84 }
86};
87
88template <typename V>
89struct VectorArrayTypeHelperInternal<V, true, false> {
90 using component_type = V; // arithmetic types are component types
91 static constexpr int NumberOfComponents = 1;
92 static inline component_type* getData( VectorArray<V>* v ) { return v->data(); }
93 static inline const component_type* getConstData( const VectorArray<V>* v ) {
94 return v->data();
95 }
96};
97
98template <typename V>
99struct VectorArrayTypeHelperInternal<V, false, true> {
100 using component_type = typename V::Scalar; // use eigen scalar as component
101 static constexpr int NumberOfComponents = V::RowsAtCompileTime; // i.e. -1 for dynamic size
102 static inline component_type* getData( VectorArray<V>* v ) { return v->data()->data(); }
103 static inline const component_type* getConstData( const VectorArray<V>* v ) {
104 return v->data()->data();
105 }
106};
107
108template <typename V>
109struct VectorArrayTypeHelperInternal<V, false, false> {
110 using component_type = V;
111 static constexpr int NumberOfComponents = 0; // no component for other types, i.e. not mappable
112 static inline component_type* getData( VectorArray<V>* v ) { return v->data(); }
113 static inline const component_type* getConstData( const VectorArray<V>* v ) {
114 return v->data();
115 }
116};
117
118// Convenience aliases
119using Vector1Array = VectorArray<Scalar>;
120#define DEFINE_CONVENIENCE_MATRIX_ALIAS( NAME, TYPE, DIM ) \
121 using NAME = VectorArray<Eigen::Matrix<TYPE, DIM, 1>>;
122DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector2Array, Scalar, 2 )
123DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector3Array, Scalar, 3 )
124DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector4Array, Scalar, 4 )
125DEFINE_CONVENIENCE_MATRIX_ALIAS( VectorNArray, Scalar, Eigen::Dynamic )
126DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector1iArray, int, 1 )
127DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector2iArray, int, 2 )
128DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector3iArray, int, 3 )
129DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector4iArray, int, 4 )
130DEFINE_CONVENIENCE_MATRIX_ALIAS( VectorNiArray, int, Eigen::Dynamic )
131DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector1uArray, uint, 1 )
132DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector2uArray, uint, 2 )
133DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector3uArray, uint, 3 )
134DEFINE_CONVENIENCE_MATRIX_ALIAS( Vector4uArray, uint, 4 )
135DEFINE_CONVENIENCE_MATRIX_ALIAS( VectorNuArray, uint, Eigen::Dynamic )
136#undef DEFINE_CONVENIENCE_MATRIX_ALIAS
137
138// Notes :
139// Using a map for eigen integration was recommended by [1].
140// According to this document [2], it is necessary to use a special allocator to enforce
141// alignment...
142// But actually it is not necessary to do so in C++11 [3] (it is actually harmful
143// as it removes some vector features such as initializer lists).
144// Finally we use our own aligned allocator.
145
146// [1] https://forum.kde.org/viewtopic.php?f=74&t=126959
147// [2] http://eigen.tuxfamily.org/dox-devel/group__TopicStlContainers.html
148// [3] http://eigen.tuxfamily.org/bz/show_bug.cgi?id=829
149
150} // namespace Core
151} // namespace Ra
This class defines the introspection interface a container need to implement.
This class implements ContainerIntrospectionInterface for AlignedStdVector.
std::enable_if_t<(N > 0), MatrixMap > getMap()
const void * dataPtr() const override
typename TypeHelper::component_type component_type
size_t getNumberOfComponents() const override
int getStride() const override
size_t getSize() const override
size_t getBufferSize() const override
std::enable_if_t<(N > 0), ConstMatrixMap > getMap() const
T data(T... args)
T empty(T... args)
T max(T... args)
std::vector< T, Eigen::aligned_allocator< T > > AlignedStdVector
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3
T size(T... args)