Browse Source

MeshTools: make interleave() work with Corrade containers too.

pull/338/head
Vladimír Vondruš 7 years ago
parent
commit
de1e1fa4d5
  1. 3
      doc/changelog.dox
  2. 31
      src/Magnum/MeshTools/Interleave.h

3
doc/changelog.dox

@ -195,6 +195,9 @@ See also:
- @ref MeshTools::fullScreenTriangle() was updated to work on ES3 SwiftShader - @ref MeshTools::fullScreenTriangle() was updated to work on ES3 SwiftShader
contexts (which have broken @glsl gl_VertexID @ce) contexts (which have broken @glsl gl_VertexID @ce)
- @ref MeshTools::interleave() and @ref MeshTools::interleaveInto() now works
also with @ref Corrade::Containers::ArrayView,
@ref Corrade::Containers::StridedArrayView and friends
@subsubsection changelog-latest-changes-texturetools TextureTools library @subsubsection changelog-latest-changes-texturetools TextureTools library

31
src/Magnum/MeshTools/Interleave.h

@ -32,6 +32,7 @@
#include <cstring> #include <cstring>
#include <Corrade/Containers/Array.h> #include <Corrade/Containers/Array.h>
#include <Corrade/Utility/Assert.h> #include <Corrade/Utility/Assert.h>
#include <Corrade/Utility/TypeTraits.h>
#include "Magnum/Magnum.h" #include "Magnum/Magnum.h"
@ -67,11 +68,25 @@ struct AttributeCount {
constexpr std::size_t operator()() const { return 0; } constexpr std::size_t operator()() const { return 0; }
}; };
/* If anybody has an idea how to do this better and not require C++17 if
constexpr, please tell me. This is horrendous. */
CORRADE_HAS_TYPE(HasType, typename T::Type);
template<bool hasType> struct TypeSizeImpl;
template<> struct TypeSizeImpl<true> {
template<class T> constexpr static std::size_t get() { return sizeof(typename T::Type); }
};
template<> struct TypeSizeImpl<false> {
template<class T> constexpr static std::size_t get() { return sizeof(typename T::value_type); }
};
template<class T> constexpr std::size_t typeSize() {
return TypeSizeImpl<HasType<T>::value>::template get<T>();
}
/* Stride, taking gaps into account. It must be in the structure, same reason /* Stride, taking gaps into account. It must be in the structure, same reason
as above */ as above */
struct Stride { struct Stride {
template<class T, class ...U> typename std::enable_if<!std::is_convertible<T, std::size_t>::value, std::size_t>::type operator()(const T&, const U&... next) const { template<class T, class ...U> typename std::enable_if<!std::is_convertible<T, std::size_t>::value, std::size_t>::type operator()(const T&, const U&... next) const {
return sizeof(typename T::value_type) + Stride{}(next...); return typeSize<T>() + Stride{}(next...);
} }
template<class... T> std::size_t operator()(std::size_t gap, const T&... next) const { template<class... T> std::size_t operator()(std::size_t gap, const T&... next) const {
return gap + Stride{}(next...); return gap + Stride{}(next...);
@ -83,9 +98,9 @@ struct Stride {
template<class T> typename std::enable_if<!std::is_convertible<T, std::size_t>::value, std::size_t>::type writeOneInterleaved(std::size_t stride, char* startingOffset, const T& attributeList) { template<class T> typename std::enable_if<!std::is_convertible<T, std::size_t>::value, std::size_t>::type writeOneInterleaved(std::size_t stride, char* startingOffset, const T& attributeList) {
auto it = attributeList.begin(); auto it = attributeList.begin();
for(std::size_t i = 0; i != attributeList.size(); ++i, ++it) for(std::size_t i = 0; i != attributeList.size(); ++i, ++it)
std::memcpy(startingOffset + i*stride, reinterpret_cast<const char*>(&*it), sizeof(typename T::value_type)); std::memcpy(startingOffset + i*stride, reinterpret_cast<const char*>(&*it), typeSize<T>());
return sizeof(typename T::value_type); return typeSize<T>();
} }
/* Skip gap */ /* Skip gap */
@ -119,10 +134,12 @@ would be 21 bytes, causing possible performance loss.
@attention The function expects that all arrays have the same size. @attention The function expects that all arrays have the same size.
@note The only requirements to attribute array type is that it must have @note The only requirements to attribute array type is that it must have either
typedef `T::value_type`, forward iterator (to be used with range-based a typedef `T::Type` (in case of Corrade types such as
for) and function `size()` returning count of elements. In most cases it @ref Corrade::Containers::ArrayView) or a typedef `T::value_type` (in case
will be @ref std::vector or @ref std::array. of STL types such as @ref std::vector or @ref std::array) or a, a forward
iterator (to be used with range-based for) and a function `size()`
returning count of elements.
@see @ref interleaveInto() @see @ref interleaveInto()
*/ */

Loading…
Cancel
Save