Skip to content

Commit

Permalink
#5767: Flip Texture is now using the textool algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Oct 1, 2021
1 parent 5e8956b commit 2134f74
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 13 deletions.
23 changes: 19 additions & 4 deletions radiantcore/selection/algorithm/Shader.cpp
Expand Up @@ -17,6 +17,9 @@
#include "brush/TextureProjection.h"
#include "patch/PatchNode.h"
#include "selection/algorithm/Primitives.h"
#include "selection/algorithm/Texturing.h"
#include "selection/textool/FaceNode.h"
#include "selection/textool/PatchNode.h"
#include "selection/shaderclipboard/ShaderClipboard.h"
#include "selection/shaderclipboard/ClosestTexturableFinder.h"
#include "scene/Traverse.h"
Expand Down Expand Up @@ -460,14 +463,26 @@ void fitTextureCmd(const cmd::ArgumentList& args)
fitTexture(args[0].getDouble(), args[1].getDouble());
}

void flipTexture(unsigned int flipAxis)
void flipTexture(int flipAxis)
{
UndoableCommand undo("flipTexture");

GlobalSelectionSystem().foreachFace([&] (IFace& face) { face.flipTexture(flipAxis); });
GlobalSelectionSystem().foreachPatch([&] (IPatch& patch) { patch.flipTexture(flipAxis); });
// Create texture nodes around the selection and pass it on to the specialised flip algorithm
std::vector<textool::INode::Ptr> nodes;

SceneChangeNotify();
GlobalSelectionSystem().foreachFace([&](IFace& face) { nodes.emplace_back(std::make_shared<textool::FaceNode>(face)); });
GlobalSelectionSystem().foreachPatch([&] (IPatch& patch) { nodes.emplace_back(std::make_shared<textool::PatchNode>(patch)); });

// Flip every node about its own center point
for (const auto& node : nodes)
{
const auto& bounds = node->localAABB();
TextureFlipper flipper({ bounds.origin.x(), bounds.origin.y() }, flipAxis);

flipper.processNode(node);
}

radiant::TextureChangedMessage::Send();
}

void flipTextureS(const cmd::ArgumentList& args)
Expand Down
2 changes: 1 addition & 1 deletion radiantcore/selection/algorithm/Shader.h
Expand Up @@ -107,7 +107,7 @@ namespace selection
*
* @flipAxis: 0 = flip S, 1 = flip T
*/
void flipTexture(unsigned int flipAxis);
void flipTexture(int flipAxis);

/** greebo: The command Targets for flipping the textures about the
* S and T axes respectively.
Expand Down
12 changes: 10 additions & 2 deletions radiantcore/selection/algorithm/Texturing.cpp
Expand Up @@ -6,7 +6,15 @@ namespace selection
namespace algorithm
{

bool TextureBoundsAccumulator::operator()(const textool::INode::Ptr& node)
TextureNodeManipulator::operator std::function<bool(const textool::INode::Ptr& node)>()
{
return [this](const textool::INode::Ptr& node)
{
return processNode(node);
};
}

bool TextureBoundsAccumulator::processNode(const textool::INode::Ptr& node)
{
_bounds.includeAABB(node->localAABB());
return true;
Expand All @@ -30,7 +38,7 @@ TextureFlipper::TextureFlipper(const Vector2& flipCenter, int axis)
_transform.premultiplyBy(Matrix3::getTranslation(+flipCenter));
}

bool TextureFlipper::operator()(const textool::INode::Ptr& node)
bool TextureFlipper::processNode(const textool::INode::Ptr& node)
{
node->beginTransformation();
node->transform(_transform);
Expand Down
27 changes: 21 additions & 6 deletions radiantcore/selection/algorithm/Texturing.h
Expand Up @@ -10,14 +10,29 @@ namespace selection
namespace algorithm
{

class TextureBoundsAccumulator
class TextureNodeManipulator
{
protected:
TextureNodeManipulator()
{}

public:
// Conversion operator, to be able to pass an instance reference directly to
// ITextureToolSelectionSystem.foreachSelected() without having to set up the std::bind
operator std::function<bool(const textool::INode::Ptr& node)>();

// Required processor method to be implemented by subclasses
virtual bool processNode(const textool::INode::Ptr& node) = 0;
};

class TextureBoundsAccumulator :
public TextureNodeManipulator
{
private:
AABB _bounds;

public:
// Textool node visitor
bool operator()(const textool::INode::Ptr& node);
bool processNode(const textool::INode::Ptr& node) override;

const AABB& getBounds() const
{
Expand All @@ -26,16 +41,16 @@ class TextureBoundsAccumulator
};

// Flips all the visited node about the given axis and the given flip center point (in UV space)
class TextureFlipper
class TextureFlipper :
public TextureNodeManipulator
{
private:
Matrix3 _transform;

public:
TextureFlipper(const Vector2& flipCenter, int axis);

// Function operator, makes this class suitable to pass to e.g. ITextureToolSelectionSystem.foreachSelected()
bool operator()(const textool::INode::Ptr& node);
bool processNode(const textool::INode::Ptr& node) override;
};

}
Expand Down
Expand Up @@ -684,6 +684,7 @@ void TextureToolSelectionSystem::flipSelected(int axis)

// Calculate the center based on the selection
selection::algorithm::TextureBoundsAccumulator accumulator;
foreachSelectedNode(accumulator);

if (!accumulator.getBounds().isValid())
{
Expand Down

0 comments on commit 2134f74

Please sign in to comment.