Browse Source

Trade: make MeshIndexData constexpr.

First step towards an ability to expose data compiled into an executable
through MeshData without having to allocate anything.
pull/371/head
Vladimír Vondruš 6 years ago
parent
commit
8cd75087ed
  1. 9
      src/Magnum/Trade/MeshData.cpp
  2. 19
      src/Magnum/Trade/MeshData.h
  3. 22
      src/Magnum/Trade/Test/MeshDataTest.cpp

9
src/Magnum/Trade/MeshData.cpp

@ -32,9 +32,10 @@
namespace Magnum { namespace Trade {
MeshIndexData::MeshIndexData(const MeshIndexType type, const Containers::ArrayView<const void> data) noexcept: type{type}, data{reinterpret_cast<const Containers::ArrayView<const char>&>(data)} {
CORRADE_ASSERT(!data.empty(),
"Trade::MeshIndexData: index array can't be empty, create a non-indexed mesh instead", );
MeshIndexData::MeshIndexData(const MeshIndexType type, const Containers::ArrayView<const void> data) noexcept: MeshIndexData{type, data, nullptr} {
/* Yes, this calls into a constexpr function defined in the header --
because I feel that makes more sense than duplicating the full assert
logic */
CORRADE_ASSERT(data.size()%meshIndexTypeSize(type) == 0,
"Trade::MeshIndexData: view size" << data.size() << "does not correspond to" << type, );
}
@ -63,7 +64,7 @@ Containers::Array<MeshAttributeData> meshAttributeDataNonOwningArray(const Conta
return Containers::Array<Trade::MeshAttributeData>{const_cast<Trade::MeshAttributeData*>(view.data()), view.size(), reinterpret_cast<void(*)(Trade::MeshAttributeData*, std::size_t)>(Trade::Implementation::nonOwnedArrayDeleter)};
}
MeshData::MeshData(const MeshPrimitive primitive, Containers::Array<char>&& indexData, const MeshIndexData& indices, Containers::Array<char>&& vertexData, Containers::Array<MeshAttributeData>&& attributes, const void* const importerState) noexcept: _indexType{indices.type}, _primitive{primitive}, _indexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _vertexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _importerState{importerState}, _indexData{std::move(indexData)}, _vertexData{std::move(vertexData)}, _attributes{std::move(attributes)}, _indices{indices.data} {
MeshData::MeshData(const MeshPrimitive primitive, Containers::Array<char>&& indexData, const MeshIndexData& indices, Containers::Array<char>&& vertexData, Containers::Array<MeshAttributeData>&& attributes, const void* const importerState) noexcept: _indexType{indices.type}, _primitive{primitive}, _indexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _vertexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _importerState{importerState}, _indexData{std::move(indexData)}, _vertexData{std::move(vertexData)}, _attributes{std::move(attributes)}, _indices{Containers::arrayCast<const char>(indices.data)} {
/* Save vertex count. It's a strided array view, so the size is not
depending on type. */
if(_attributes.empty()) {

19
src/Magnum/Trade/MeshData.h

@ -177,19 +177,27 @@ class MAGNUM_TRADE_EXPORT MeshIndexData {
explicit MeshIndexData(MeshIndexType type, Containers::ArrayView<const void> data) noexcept;
/** @brief Construct with unsigned byte indices */
explicit MeshIndexData(Containers::ArrayView<const UnsignedByte> data) noexcept: MeshIndexData{MeshIndexType::UnsignedByte, data} {}
constexpr explicit MeshIndexData(Containers::ArrayView<const UnsignedByte> data) noexcept: MeshIndexData{MeshIndexType::UnsignedByte, data, nullptr} {}
/** @brief Construct with unsigned short indices */
explicit MeshIndexData(Containers::ArrayView<const UnsignedShort> data) noexcept: MeshIndexData{MeshIndexType::UnsignedShort, data} {}
constexpr explicit MeshIndexData(Containers::ArrayView<const UnsignedShort> data) noexcept: MeshIndexData{MeshIndexType::UnsignedShort, data, nullptr} {}
/** @brief Construct with unsigned int indices */
explicit MeshIndexData(Containers::ArrayView<const UnsignedInt> data) noexcept: MeshIndexData{MeshIndexType::UnsignedInt, data} {}
constexpr explicit MeshIndexData(Containers::ArrayView<const UnsignedInt> data) noexcept: MeshIndexData{MeshIndexType::UnsignedInt, data, nullptr} {}
private:
/* Contains an assert common for all constexpr constructor, nullptr_t
to disambiguate from the public constructor of the same signature --
can't delegate into that one, because it checks against
meshIndexTypeSize() that's not constexpr, and since we come from a
template, we don't need that check anyway */
constexpr explicit MeshIndexData(MeshIndexType type, Containers::ArrayView<const void> data, std::nullptr_t);
/* Not prefixed with _ because we use them like public in MeshData */
friend MeshData;
MeshIndexType type;
Containers::ArrayView<const char> data;
/* Void so the constructors can be constexpr */
Containers::ArrayView<const void> data;
};
/**
@ -1016,6 +1024,9 @@ namespace Implementation {
}
#endif
constexpr MeshIndexData::MeshIndexData(MeshIndexType type, Containers::ArrayView<const void> data, std::nullptr_t):
type{type}, data{(CORRADE_CONSTEXPR_ASSERT(!data.empty(), "Trade::MeshIndexData: index array can't be empty, create a non-indexed mesh instead"), data)} {}
template<class T> MeshAttributeData::MeshAttributeData(MeshAttribute name, const Containers::StridedArrayView1D<T>& data) noexcept: MeshAttributeData{name, Implementation::vertexFormatFor<typename std::remove_const<T>::type>(), Containers::arrayCast<const char>(data)} {}
template<class T> Containers::ArrayView<const T> MeshData::indices() const {

22
src/Magnum/Trade/Test/MeshDataTest.cpp

@ -250,6 +250,10 @@ void MeshDataTest::debugAttributeName() {
using namespace Math::Literals;
constexpr UnsignedByte IndexBytes[]{25, 132, 3};
constexpr UnsignedShort IndexShorts[]{2575, 13224, 3};
constexpr UnsignedInt IndexInts[]{2110122, 132257, 3};
void MeshDataTest::constructIndex() {
{
Containers::Array<char> indexData{3*1};
@ -260,6 +264,12 @@ void MeshDataTest::constructIndex() {
CORRADE_COMPARE(data.indexType(), MeshIndexType::UnsignedByte);
CORRADE_COMPARE(static_cast<const void*>(data.indices<UnsignedByte>().data()), indexView.data());
CORRADE_COMPARE(data.indexCount(), 3);
constexpr MeshIndexData cindices{IndexBytes};
MeshData cdata{MeshPrimitive::Points, {}, IndexBytes, cindices};
CORRADE_COMPARE(cdata.indexType(), MeshIndexType::UnsignedByte);
CORRADE_COMPARE(static_cast<const void*>(cdata.indices<UnsignedByte>().data()), IndexBytes);
CORRADE_COMPARE(data.indexCount(), 3);
} {
Containers::Array<char> indexData{3*2};
auto indexView = Containers::arrayCast<UnsignedShort>(indexData);
@ -269,6 +279,12 @@ void MeshDataTest::constructIndex() {
CORRADE_COMPARE(data.indexType(), MeshIndexType::UnsignedShort);
CORRADE_COMPARE(static_cast<const void*>(data.indices<UnsignedShort>().data()), indexView.data());
CORRADE_COMPARE(data.indexCount(), 3);
constexpr MeshIndexData cindices{IndexShorts};
MeshData cdata{MeshPrimitive::Points, {}, IndexShorts, cindices};
CORRADE_COMPARE(cdata.indexType(), MeshIndexType::UnsignedShort);
CORRADE_COMPARE(static_cast<const void*>(cdata.indices<UnsignedShort>().data()), IndexShorts);
CORRADE_COMPARE(data.indexCount(), 3);
} {
Containers::Array<char> indexData{3*4};
auto indexView = Containers::arrayCast<UnsignedInt>(indexData);
@ -278,6 +294,12 @@ void MeshDataTest::constructIndex() {
CORRADE_COMPARE(data.indexType(), MeshIndexType::UnsignedInt);
CORRADE_COMPARE(static_cast<const void*>(data.indices<UnsignedInt>().data()), indexView.data());
CORRADE_COMPARE(data.indexCount(), 3);
constexpr MeshIndexData cindices{IndexInts};
MeshData cdata{MeshPrimitive::Points, {}, IndexInts, cindices};
CORRADE_COMPARE(cdata.indexType(), MeshIndexType::UnsignedInt);
CORRADE_COMPARE(static_cast<const void*>(cdata.indices<UnsignedInt>().data()), IndexInts);
CORRADE_COMPARE(data.indexCount(), 3);
}
}

Loading…
Cancel
Save