Browse Source

MaterialTools: add a possibility to filter also the types enum.

I thought it wasn't needed and people could do it manually after only to
realize it'd be actually very convenient if present.
pull/601/head
Vladimír Vondruš 3 years ago
parent
commit
177c59289e
  1. 16
      src/Magnum/MaterialTools/Filter.cpp
  2. 12
      src/Magnum/MaterialTools/Filter.h
  3. 20
      src/Magnum/MaterialTools/Test/FilterTest.cpp

16
src/Magnum/MaterialTools/Filter.cpp

@ -41,7 +41,7 @@ namespace {
- if neither is nullptr then inputAttributesToKeep is patched to have zero
bits for all attributes in filtered-out layers,
- both can't be nullptr */
Trade::MaterialData filterAttributesLayersImplementation(const Trade::MaterialData& material, const Containers::BitArrayView inputAttributesToKeep, const Containers::BitArrayView inputLayersToKeep) {
Trade::MaterialData filterAttributesLayersImplementation(const Trade::MaterialData& material, const Containers::BitArrayView inputAttributesToKeep, const Containers::BitArrayView inputLayersToKeep, const Trade::MaterialTypes typesToKeep) {
const std::size_t totalAttributeCount = material.attributeDataOffset(material.layerCount());
/* Generate the input attribute bit array or make a mutable copy. Using an
@ -106,32 +106,32 @@ Trade::MaterialData filterAttributesLayersImplementation(const Trade::MaterialDa
}
CORRADE_INTERNAL_ASSERT(attributeOffset == attributes.size());
return Trade::MaterialData{material.types(), std::move(attributes), std::move(layers)};
return Trade::MaterialData{material.types() & typesToKeep, std::move(attributes), std::move(layers)};
}
}
Trade::MaterialData filterAttributes(const Trade::MaterialData& material, const Containers::BitArrayView attributesToKeep) {
Trade::MaterialData filterAttributes(const Trade::MaterialData& material, const Containers::BitArrayView attributesToKeep, const Trade::MaterialTypes typesToKeep) {
CORRADE_ASSERT(attributesToKeep.size() == material.attributeData().size(),
"MaterialTools::filterAttributes(): expected" << material.attributeData().size() << "bits but got" << attributesToKeep.size(), (Trade::MaterialData{{}, {}}));
return filterAttributesLayersImplementation(material, attributesToKeep, nullptr);
return filterAttributesLayersImplementation(material, attributesToKeep, nullptr, typesToKeep);
}
Trade::MaterialData filterLayers(const Trade::MaterialData& material, const Containers::BitArrayView layersToKeep) {
Trade::MaterialData filterLayers(const Trade::MaterialData& material, const Containers::BitArrayView layersToKeep, const Trade::MaterialTypes typesToKeep) {
CORRADE_ASSERT(layersToKeep.size() == material.layerCount(),
"MaterialTools::filterLayers(): expected" << material.layerCount() << "bits but got" << layersToKeep.size(), (Trade::MaterialData{{}, {}}));
return filterAttributesLayersImplementation(material, nullptr, layersToKeep);
return filterAttributesLayersImplementation(material, nullptr, layersToKeep, typesToKeep);
}
Trade::MaterialData filterAttributesLayers(const Trade::MaterialData& material, const Containers::BitArrayView attributesToKeep, const Containers::BitArrayView layersToKeep) {
Trade::MaterialData filterAttributesLayers(const Trade::MaterialData& material, const Containers::BitArrayView attributesToKeep, const Containers::BitArrayView layersToKeep, const Trade::MaterialTypes typesToKeep) {
CORRADE_ASSERT(attributesToKeep.size() == material.attributeData().size(),
"MaterialTools::filterAttributesLayers(): expected" << material.attributeData().size() << "attribute bits but got" << attributesToKeep.size(), (Trade::MaterialData{{}, {}}));
CORRADE_ASSERT(layersToKeep.size() == material.layerCount(),
"MaterialTools::filterAttributesLayers(): expected" << material.layerCount() << "layer bits but got" << layersToKeep.size(), (Trade::MaterialData{{}, {}}));
return filterAttributesLayersImplementation(material, attributesToKeep, layersToKeep);
return filterAttributesLayersImplementation(material, attributesToKeep, layersToKeep, typesToKeep);
}
}}

12
src/Magnum/MaterialTools/Filter.h

@ -30,6 +30,8 @@
* @m_since_latest
*/
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/MaterialTools/visibility.h"
#include "Magnum/Trade/Trade.h"
@ -44,14 +46,14 @@ Returns a material with only the attributes for which the corresponding bit in
bit ranges corresponding to @ref Trade::MaterialData::attributeDataOffset() for
a particular layer. The output layer ranges are then recalculated based on how
many attributes are left in those. Empty layers are kept,
@ref Trade::MaterialData::types() are transferred unchanged.
@ref Trade::MaterialData::types() are ANDed with @p typesToKeep.
The size of @p attributesToKeep is expected to be equal to the number of
attributes in all layers (i.e., size of the
@ref Trade::MaterialData::attributeData() array).
@see @ref filterLayers(), @ref filterAttributesLayers()
*/
MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributes(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep);
MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributes(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{});
/**
@brief Filter material layers
@ -60,13 +62,13 @@ MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributes(const Trade::Ma
Returns a material with only the layers for which the corresponding bit in
@p layersToKeep was set. The only exception is the base layer, which is left
empty if removed. Attributes in other layers are kept untouched,
@ref Trade::MaterialData::types() are transferred unchanged.
@ref Trade::MaterialData::types() are ANDed with @p typesToKeep.
The size of @p layerCount is expected to be equal to
@ref Trade::MaterialData::layerCount().
@see @ref filterAttributes(), @ref filterAttributesLayers()
*/
MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterLayers(const Trade::MaterialData& material, Containers::BitArrayView layersToKeep);
MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterLayers(const Trade::MaterialData& material, Containers::BitArrayView layersToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{});
/**
@brief Filter material attributes and layers
@ -76,7 +78,7 @@ Performs what @ref filterAttributes() and @ref filterLayers() do, but in a
single step. Bits in @p attributesToKeep that correspond to layers that are
removed are ignored.
*/
MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributesLayers(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Containers::BitArrayView layersToKeep);
MAGNUM_MATERIALTOOLS_EXPORT Trade::MaterialData filterAttributesLayers(const Trade::MaterialData& material, Containers::BitArrayView attributesToKeep, Containers::BitArrayView layersToKeep, Trade::MaterialTypes typesToKeep = ~Trade::MaterialTypes{});
}}

20
src/Magnum/MaterialTools/Test/FilterTest.cpp

@ -82,7 +82,7 @@ void FilterTest::attributes() {
{Trade::MaterialAttribute::TextureCoordinates, 11u}, /* 3 */
{Trade::MaterialAttribute::TextureLayer, 0u}, /* 4 */
};
Trade::MaterialData material{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Flat, Trade::DataFlags{}, attributes};
Trade::MaterialData material{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Flat|Trade::MaterialType::Phong, Trade::DataFlags{}, attributes};
Containers::BitArray attributesToKeep{DirectInit, 5, true};
attributesToKeep.reset(1);
@ -92,13 +92,13 @@ void FilterTest::attributes() {
/* The types are kept intact even if they don't make sense, that's a job
for some higher-level utility that understands their relations to
present attributes */
CORRADE_COMPARE_AS(filterAttributes(material, attributesToKeep), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Flat, {
CORRADE_COMPARE_AS(filterAttributes(material, attributesToKeep, Trade::MaterialType::PbrClearCoat|Trade::MaterialType::PbrMetallicRoughness), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, {
{Trade::MaterialAttribute::AlphaBlend, true},
{Trade::MaterialAttribute::BaseColorTexture, 7u},
}}), DebugTools::CompareMaterial);
/* Removing all shouldn't do anything unexpected */
CORRADE_COMPARE_AS(filterAttributes(material, Containers::BitArray{ValueInit, 5}), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::Flat, {
CORRADE_COMPARE_AS(filterAttributes(material, Containers::BitArray{ValueInit, 5}, {}), (Trade::MaterialData{{}, {
}}), DebugTools::CompareMaterial);
}
@ -170,14 +170,14 @@ void FilterTest::layers() {
{"againSomething", false}, /* 6 #9 */
};
const UnsignedInt layers[]{3, 3, 6, 8, 8, 9, 10};
Trade::MaterialData material{Trade::MaterialType::PbrClearCoat, Trade::DataFlags{}, attributes, Trade::DataFlags{}, layers};
Trade::MaterialData material{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::PbrMetallicRoughness, Trade::DataFlags{}, attributes, Trade::DataFlags{}, layers};
Containers::BitArray layersToKeep{DirectInit, 7, true};
layersToKeep.reset(1);
layersToKeep.reset(2);
layersToKeep.reset(5);
CORRADE_COMPARE_AS(filterLayers(material, layersToKeep), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, {
CORRADE_COMPARE_AS(filterLayers(material, layersToKeep, Trade::MaterialType::PbrMetallicRoughness|Trade::MaterialType::PbrSpecularGlossiness), (Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::AlphaBlend, true},
{Trade::MaterialAttribute::BaseColor, 0xffcc66ff_rgbaf},
{Trade::MaterialAttribute::BaseColorTexture, 7u},
@ -188,7 +188,7 @@ void FilterTest::layers() {
}, {3, 5, 5, 6}}), DebugTools::CompareMaterial);
/* Removing all shouldn't do anything unexpected */
CORRADE_COMPARE_AS(filterLayers(material, Containers::BitArray{ValueInit, 7}), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, {
CORRADE_COMPARE_AS(filterLayers(material, Containers::BitArray{ValueInit, 7}, {}), (Trade::MaterialData{{}, {
}}), DebugTools::CompareMaterial);
}
@ -247,7 +247,7 @@ void FilterTest::attributesLayers() {
{"againSomething", false}, /* 6 #9 */
};
const UnsignedInt layers[]{3, 3, 6, 8, 8, 9, 10};
Trade::MaterialData material{Trade::MaterialType::PbrClearCoat, Trade::DataFlags{}, attributes, Trade::DataFlags{}, layers};
Trade::MaterialData material{Trade::MaterialType::PbrClearCoat|Trade::MaterialType::PbrMetallicRoughness, Trade::DataFlags{}, attributes, Trade::DataFlags{}, layers};
Containers::BitArray attributesToKeep{DirectInit, 10, true};
attributesToKeep.reset(1);
@ -259,7 +259,7 @@ void FilterTest::attributesLayers() {
layersToKeep.reset(1);
layersToKeep.reset(2);
CORRADE_COMPARE_AS(filterAttributesLayers(material, attributesToKeep, layersToKeep), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, {
CORRADE_COMPARE_AS(filterAttributesLayers(material, attributesToKeep, layersToKeep, Trade::MaterialType::PbrMetallicRoughness|Trade::MaterialType::PbrSpecularGlossiness), (Trade::MaterialData{Trade::MaterialType::PbrMetallicRoughness, {
{Trade::MaterialAttribute::AlphaBlend, true},
{Trade::MaterialAttribute::BaseColorTexture, 7u},
{"texturePointer", nullptr},
@ -269,11 +269,11 @@ void FilterTest::attributesLayers() {
}, {2, 3, 3, 3, 4}}), DebugTools::CompareMaterial);
/* Removing all attributes should keep all layers but make them empty */
CORRADE_COMPARE_AS(filterAttributesLayers(material, Containers::BitArray{ValueInit, 10}, Containers::BitArray{DirectInit, 7, true}), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, {
CORRADE_COMPARE_AS(filterAttributesLayers(material, Containers::BitArray{ValueInit, 10}, Containers::BitArray{DirectInit, 7, true}, {}), (Trade::MaterialData{{}, {
}, {0, 0, 0, 0, 0, 0, 0}}), DebugTools::CompareMaterial);
/* Removing all layers should make the material completely empty */
CORRADE_COMPARE_AS(filterLayers(material, Containers::BitArray{ValueInit, 7}), (Trade::MaterialData{Trade::MaterialType::PbrClearCoat, {
CORRADE_COMPARE_AS(filterAttributesLayers(material, Containers::BitArray{ValueInit, 10}, Containers::BitArray{ValueInit, 7}, {}), (Trade::MaterialData{{}, {
}}), DebugTools::CompareMaterial);
}

Loading…
Cancel
Save