Skip to content

Commit

Permalink
#5567: Implement frob stage removal
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Apr 2, 2021
1 parent 33fcbc4 commit 19ca94a
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 49 deletions.
131 changes: 84 additions & 47 deletions libs/materials/FrobStageSetup.h
Expand Up @@ -39,9 +39,83 @@ class FrobStageSetup
{
public:
static bool HasWhiteBlendStage(const MaterialPtr& material)
{
return FindWhiteBlendStage(material).first != nullptr;
}

static bool HasAdditiveDiffuseStage(const MaterialPtr& material)
{
return FindAdditiveDiffuseStage(material).first != nullptr;
}

// Checks whether the default frob stages are present on this material
static bool IsPresent(const MaterialPtr& material)
{
if (!material) return false;

auto diffuse = GetDiffuseMap(material);

return !diffuse.empty() && HasWhiteBlendStage(material) && HasAdditiveDiffuseStage(material);
}

// Add the needed frob stages to this material
static void AddToMaterial(const MaterialPtr& material)
{
if (!material) return;

if (!HasAdditiveDiffuseStage(material))
{
AddAdditiveDiffuseStage(material);
}

if (!HasWhiteBlendStage(material))
{
AddWhiteBlendStage(material);
}
}

// Removes the two frob stages from this material
static void RemoveFromMaterial(const MaterialPtr& material)
{
if (!material) return;

auto additiveStage = FindAdditiveDiffuseStage(material);

if (additiveStage.second > 0)
{
material->removeLayer(static_cast<std::size_t>(additiveStage.second));
}

auto whiteBlendStage = FindWhiteBlendStage(material);

if (whiteBlendStage.second > 0)
{
material->removeLayer(static_cast<std::size_t>(whiteBlendStage.second));
}
}

static std::string GetDiffuseMap(const MaterialPtr& material)
{
for (const auto& layer : material->getAllLayers())
{
if (layer->getType() == IShaderLayer::DIFFUSE && layer->getMapExpression())
{
return layer->getMapExpression()->getExpressionString();
}
}

return std::string();
}

private:
static std::pair<IShaderLayer::Ptr, int> FindWhiteBlendStage(const MaterialPtr& material)
{
const auto& layers = material->getAllLayers();

for (int index = 0; index < layers.size(); ++index)
{
const auto& layer = layers[index];

// if ( parm11 > 0 )
if (!layer->getConditionExpression() || layer->getConditionExpression()->getExpressionString() != FrobCondition)
{
Expand All @@ -65,21 +139,24 @@ class FrobStageSetup

if (rgb && rgb->getExpressionString() == WhiteBlendRgbExpression)
{
return true;
return std::make_pair(layer, index);
}
}

return false;
return std::make_pair(IShaderLayer::Ptr(), -1);
}

static bool HasAdditiveDiffuseStage(const MaterialPtr& material)
static std::pair<IShaderLayer::Ptr, int> FindAdditiveDiffuseStage(const MaterialPtr& material)
{
auto diffuse = GetDiffuseMap(material);

if (diffuse.empty()) return false;
if (diffuse.empty()) return std::make_pair(IShaderLayer::Ptr(), -1);

for (const auto& layer : material->getAllLayers())
const auto& layers = material->getAllLayers();
for (int index = 0; index < layers.size(); ++index)
{
const auto& layer = layers[index];

// if ( parm11 > 0 )
if (!layer->getConditionExpression() || layer->getConditionExpression()->getExpressionString() != FrobCondition)
{
Expand All @@ -103,53 +180,13 @@ class FrobStageSetup

if (rgb && rgb->getExpressionString() == AdditiveRgbExpression)
{
return true;
return std::make_pair(layer, index);
}
}

return false;
}

// Checks whether the default frob stages are present on this material
static bool IsPresent(const MaterialPtr& material)
{
if (!material) return false;

auto diffuse = GetDiffuseMap(material);

return !diffuse.empty() && HasWhiteBlendStage(material) && HasAdditiveDiffuseStage(material);
return std::make_pair(IShaderLayer::Ptr(), -1);
}

// Add the needed frob stages to this material
static void AddToMaterial(const MaterialPtr& material)
{
if (!material) return;

if (!HasAdditiveDiffuseStage(material))
{
AddAdditiveDiffuseStage(material);
}

if (!HasWhiteBlendStage(material))
{
AddWhiteBlendStage(material);
}
}

static std::string GetDiffuseMap(const MaterialPtr& material)
{
for (const auto& layer : material->getAllLayers())
{
if (layer->getType() == IShaderLayer::DIFFUSE && layer->getMapExpression())
{
return layer->getMapExpression()->getExpressionString();
}
}

return std::string();
}

private:
static void AddAdditiveDiffuseStage(const MaterialPtr& material)
{
auto index = material->addLayer(IShaderLayer::BLEND);
Expand Down
3 changes: 1 addition & 2 deletions radiant/ui/materials/editor/MaterialEditor.cpp
Expand Up @@ -2617,8 +2617,7 @@ void MaterialEditor::_onBasicRemoveFrobStages(wxCommandEvent& ev)

try
{
// TODO
//shaders::FrobStageSetup::RemoveFromMaterial(_material);
shaders::FrobStageSetup::RemoveFromMaterial(_material);
}
catch (const std::runtime_error& ex)
{
Expand Down
19 changes: 19 additions & 0 deletions test/Materials.cpp
Expand Up @@ -1474,4 +1474,23 @@ TEST_F(MaterialsTest, MaterialFrobStageAddition)
EXPECT_TRUE(shaders::FrobStageSetup::HasWhiteBlendStage(material));
}

void checkFrobStageRemoval(const std::string& materialName)
{
auto material = GlobalMaterialManager().getMaterial(materialName);

shaders::FrobStageSetup::RemoveFromMaterial(material);
EXPECT_FALSE(shaders::FrobStageSetup::HasAdditiveDiffuseStage(material));
EXPECT_FALSE(shaders::FrobStageSetup::HasWhiteBlendStage(material));
}

TEST_F(MaterialsTest, MaterialFrobStageRemoval)
{
checkFrobStageRemoval("textures/parsertest/frobstage_present1");
checkFrobStageRemoval("textures/parsertest/frobstage_missing1");
checkFrobStageRemoval("textures/parsertest/frobstage_missing2");
checkFrobStageRemoval("textures/parsertest/frobstage_missing3");
checkFrobStageRemoval("textures/parsertest/frobstage_missing4");
checkFrobStageRemoval("textures/parsertest/frobstage_missing5");
}

}

0 comments on commit 19ca94a

Please sign in to comment.