Browse Source

Trade: add getters for offset and stride in MeshAttributeData.

Less code and complexity than first creating a StridedArrayView in
data() and then extracting offset/stride from there.
pull/371/head
Vladimír Vondruš 6 years ago
parent
commit
8c4a2b1c6f
  1. 8
      src/Magnum/MeshTools/Interleave.cpp
  2. 24
      src/Magnum/Trade/MeshData.h
  3. 8
      src/Magnum/Trade/Test/MeshDataTest.cpp

8
src/Magnum/MeshTools/Interleave.cpp

@ -80,9 +80,9 @@ Trade::MeshData interleavedLayout(const Trade::MeshData& data, const UnsignedInt
std::size_t extraAttributeCount = 0;
for(std::size_t i = 0; i != extra.size(); ++i) {
if(extra[i].format() == VertexFormat{}) {
CORRADE_ASSERT(extra[i].data().stride() > 0 || stride >= std::size_t(-extra[i].data().stride()),
"MeshTools::interleavedLayout(): negative padding" << extra[i].data().stride() << "in extra attribute" << i << "too large for stride" << stride, (Trade::MeshData{MeshPrimitive::Points, 0}));
stride += extra[i].data().stride();
CORRADE_ASSERT(extra[i].stride() > 0 || stride >= std::size_t(-extra[i].stride()),
"MeshTools::interleavedLayout(): negative padding" << extra[i].stride() << "in extra attribute" << i << "too large for stride" << stride, (Trade::MeshData{MeshPrimitive::Points, 0}));
stride += extra[i].stride();
} else {
stride += vertexFormatSize(extra[i].format());
++extraAttributeCount;
@ -118,7 +118,7 @@ Trade::MeshData interleavedLayout(const Trade::MeshData& data, const UnsignedInt
for(UnsignedInt i = 0; i != extra.size(); ++i) {
/* Padding, only adjust the offset for next attribute */
if(extra[i].format() == VertexFormat{}) {
offset += extra[i].data().stride();
offset += extra[i].stride();
continue;
}

24
src/Magnum/Trade/MeshData.h

@ -430,6 +430,7 @@ class MAGNUM_TRADE_EXPORT MeshAttributeData {
* between interleaved attributes. Negative values can be used to alias
* multiple different attributes onto each other. Not meant to be
* passed to @ref MeshData.
* @see @ref stride()
*/
constexpr explicit MeshAttributeData(Int padding): _data{nullptr}, _vertexCount{0}, _format{}, _stride{
(CORRADE_CONSTEXPR_ASSERT(padding >= -32768 && padding <= 32767,
@ -452,6 +453,25 @@ class MAGNUM_TRADE_EXPORT MeshAttributeData {
/** @brief Attribute format */
constexpr VertexFormat format() const { return _format; }
/**
* @brief Attribute offset
*
* If the attribute is offset-only, returns the offset directly,
* otherwise uses the @p vertexData parameter to calculate the offset.
* @see @ref isOffsetOnly()
*/
std::size_t offset(Containers::ArrayView<const void> vertexData) const {
return _isOffsetOnly ? _data.offset : reinterpret_cast<const char*>(_data.pointer) - reinterpret_cast<const char*>(vertexData.data());
}
/**
* @brief Attribute stride
*
* Can be negative for pad values, never negative for real attributes.
* @see @ref MeshAttributeData(Int)
*/
constexpr Short stride() const { return _stride; }
/** @brief Attribute array size */
constexpr UnsignedShort arraySize() const { return _arraySize; }
@ -474,8 +494,8 @@ class MAGNUM_TRADE_EXPORT MeshAttributeData {
/**
* @brief Type-erased attribute data for an offset-only attribute
*
* If the attribute is not offset-only, the @ref vertexData parameter
* is ignored.
* If the attribute is not offset-only, the @p vertexData parameter is
* ignored.
* @see @ref isOffsetOnly(), @ref data() const
*/
Containers::StridedArrayView1D<const void> data(Containers::ArrayView<const void> vertexData) const {

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

@ -492,6 +492,8 @@ void MeshDataTest::constructAttribute() {
CORRADE_COMPARE(positions.arraySize(), 0);
CORRADE_COMPARE(positions.name(), MeshAttribute::Position);
CORRADE_COMPARE(positions.format(), VertexFormat::Vector2);
CORRADE_COMPARE(positions.offset(positionData), 0);
CORRADE_COMPARE(positions.stride(), sizeof(Vector2));
CORRADE_VERIFY(positions.data().data() == positionData);
/* This is allowed too for simplicity, it just ignores the parameter */
CORRADE_VERIFY(positions.data(positionData).data() == positionData);
@ -501,11 +503,13 @@ void MeshDataTest::constructAttribute() {
constexpr UnsignedShort arraySize = cpositions.arraySize();
constexpr MeshAttribute name = cpositions.name();
constexpr VertexFormat format = cpositions.format();
constexpr Short stride = cpositions.stride();
constexpr Containers::StridedArrayView1D<const void> data = cpositions.data();
CORRADE_VERIFY(!isOffsetOnly);
CORRADE_COMPARE(arraySize, 0);
CORRADE_COMPARE(name, MeshAttribute::Position);
CORRADE_COMPARE(format, VertexFormat::Vector2);
CORRADE_COMPARE(stride, sizeof(Vector2));
CORRADE_COMPARE(data.data(), Positions);
}
@ -603,6 +607,8 @@ void MeshDataTest::constructAttributeOffsetOnly() {
CORRADE_COMPARE(a.arraySize(), 0);
CORRADE_COMPARE(a.name(), MeshAttribute::TextureCoordinates);
CORRADE_COMPARE(a.format(), VertexFormat::Vector2);
CORRADE_COMPARE(a.offset(vertexData), sizeof(Vector2));
CORRADE_COMPARE(a.stride(), 2*sizeof(Vector2));
CORRADE_COMPARE_AS(Containers::arrayCast<const Vector2>(a.data(vertexData)),
Containers::arrayView<Vector2>({{1.0f, 0.3f}, {0.5f, 0.7f}}),
TestSuite::Compare::Container);
@ -612,6 +618,8 @@ void MeshDataTest::constructAttributeOffsetOnly() {
CORRADE_COMPARE(ca.arraySize(), 0);
CORRADE_COMPARE(ca.name(), MeshAttribute::TextureCoordinates);
CORRADE_COMPARE(ca.format(), VertexFormat::Vector2);
CORRADE_COMPARE(ca.offset(vertexData), sizeof(Vector2));
CORRADE_COMPARE(ca.stride(), 2*sizeof(Vector2));
CORRADE_COMPARE_AS(Containers::arrayCast<const Vector2>(a.data(vertexData)),
Containers::arrayView<Vector2>({{1.0f, 0.3f}, {0.5f, 0.7f}}),
TestSuite::Compare::Container);

Loading…
Cancel
Save