Skip to content

Commit

Permalink
#5623: Add specialised Selector class for merge action mode
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed May 28, 2021
1 parent 0f31891 commit 130b1e9
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 25 deletions.
29 changes: 14 additions & 15 deletions radiantcore/selection/RadiantSelectionSystem.cpp
Expand Up @@ -91,10 +91,7 @@ void RadiantSelectionSystem::testSelectScene(SelectablesList& targetList, Select
EntitySelector entityTester(selector, test);
GlobalSceneGraph().foreachVisibleNodeInVolume(view, entityTester);

for (SelectionPool::const_iterator i = selector.begin(); i != selector.end(); ++i)
{
targetList.push_back(i->second);
}
std::for_each(selector.begin(), selector.end(), [&](const auto& p) { targetList.push_back(p.second); });
}
break;

Expand All @@ -121,9 +118,7 @@ void RadiantSelectionSystem::testSelectScene(SelectablesList& targetList, Select
}

// Add the first selection crop to the target vector
for (SelectionPool::const_iterator i = selector.begin(); i != selector.end(); ++i) {
targetList.push_back(i->second);
}
std::for_each(selector.begin(), selector.end(), [&](const auto& p) { targetList.push_back(p.second); });

// Add the secondary crop to the vector (if it has any entries)
for (SelectionPool::const_iterator i = sel2.begin(); i != sel2.end(); ++i) {
Expand All @@ -147,10 +142,7 @@ void RadiantSelectionSystem::testSelectScene(SelectablesList& targetList, Select
GlobalSceneGraph().foreachVisibleNodeInVolume(view, primitiveTester);

// Add the selection crop to the target vector
for (SelectionPool::const_iterator i = selector.begin(); i != selector.end(); ++i)
{
targetList.push_back(i->second);
}
std::for_each(selector.begin(), selector.end(), [&](const auto& p) { targetList.push_back(p.second); });
}
break;

Expand All @@ -159,10 +151,17 @@ void RadiantSelectionSystem::testSelectScene(SelectablesList& targetList, Select
ComponentSelector selectionTester(selector, test, componentMode);
foreachSelected(selectionTester);

for (SelectionPool::const_iterator i = selector.begin(); i != selector.end(); ++i)
{
targetList.push_back(i->second);
}
std::for_each(selector.begin(), selector.end(), [&](const auto& p) { targetList.push_back(p.second); });
}
break;

case eMergeAction:
{
MergeActionSelector tester(selector, test);
GlobalSceneGraph().foreachVisibleNodeInVolume(view, tester);

// Add the selection crop to the target vector
std::for_each(selector.begin(), selector.end(), [&](const auto& p) { targetList.push_back(p.second); });
}
break;
} // switch
Expand Down
31 changes: 28 additions & 3 deletions radiantcore/selection/SelectionTestWalkers.cpp
Expand Up @@ -43,14 +43,19 @@ bool SelectionTestWalker::entityIsWorldspawn(const scene::INodePtr& node)
void SelectionTestWalker::performSelectionTest(const scene::INodePtr& selectableNode,
const scene::INodePtr& nodeToBeTested)
{
ISelectablePtr selectable = Node_getSelectable(selectableNode);
if (!nodeIsEligibleForTesting(nodeToBeTested))
{
return;
}

if (selectable == NULL) return; // skip non-selectables
auto selectable = Node_getSelectable(selectableNode);

if (!selectable) return; // skip non-selectables

_selector.pushSelectable(*selectable);

// Test the entity for selection, this will add an intersection to the selector
SelectionTestablePtr selectionTestable = Node_getSelectionTestable(nodeToBeTested);
auto selectionTestable = Node_getSelectionTestable(nodeToBeTested);

if (selectionTestable)
{
Expand Down Expand Up @@ -185,5 +190,25 @@ void ComponentSelector::performComponentselectionTest(const scene::INodePtr& nod
}
}

MergeActionSelector::MergeActionSelector(Selector& selector, SelectionTest& test) :
SelectionTestWalker(selector, test)
{}

bool MergeActionSelector::visit(const scene::INodePtr& node)
{
if (node->getNodeType() != scene::INode::Type::MergeAction)
{
return true; // skip over every mismatching type
}

performSelectionTest(node, node);

return false;
}

bool MergeActionSelector::nodeIsEligibleForTesting(const scene::INodePtr& node)
{
return node->getNodeType() == scene::INode::Type::MergeAction;
}

}
35 changes: 28 additions & 7 deletions radiantcore/selection/SelectionTestWalkers.h
Expand Up @@ -32,11 +32,16 @@ class SelectionTestWalker :
// Returns true if the node is worldspawn
bool entityIsWorldspawn(const scene::INodePtr& node);

virtual bool nodeIsEligibleForTesting(const scene::INodePtr& node)
{
return node->getNodeType() != scene::INode::Type::MergeAction;
}

// Performs the actual selection test on the given node
// The nodeToBeTested is the node that is tested against, whereas
// the selectableNode is the one that gets pushed to the Selector
// These two might be the same node, but this is not mandatory.
void performSelectionTest(const scene::INodePtr& selectableNode, const scene::INodePtr& nodeToBeTested);
virtual void performSelectionTest(const scene::INodePtr& selectableNode, const scene::INodePtr& nodeToBeTested);
};

// A Selector which is testing for entities. This successfully
Expand All @@ -49,7 +54,7 @@ class EntitySelector :
SelectionTestWalker(selector, test)
{}

bool visit(const scene::INodePtr& node);
bool visit(const scene::INodePtr& node) override;
};

// A Selector looking for worldspawn primitives only.
Expand All @@ -61,7 +66,7 @@ class PrimitiveSelector :
SelectionTestWalker(selector, test)
{}

bool visit(const scene::INodePtr& node);
bool visit(const scene::INodePtr& node) override;
};

// A Selector looking for child primitives of group nodes only, non-worldspawn parent
Expand All @@ -73,7 +78,7 @@ class GroupChildPrimitiveSelector :
SelectionTestWalker(selector, test)
{}

bool visit(const scene::INodePtr& node);
bool visit(const scene::INodePtr& node) override;
};

// A selector testing for all kinds of selectable items, entities and primitives.
Expand All @@ -87,7 +92,7 @@ class AnySelector :
SelectionTestWalker(selector, test)
{}

bool visit(const scene::INodePtr& node);
bool visit(const scene::INodePtr& node) override;
};

// A class seeking for components, can be used either to traverse the
Expand All @@ -107,13 +112,29 @@ class ComponentSelector :
{}

// scene::Graph::Walker implementation
bool visit(const scene::INodePtr& node);
bool visit(const scene::INodePtr& node) override;

// SelectionSystem::Visitor implementation
void visit(const scene::INodePtr& node) const;
void visit(const scene::INodePtr& node) const override;

protected:
void performComponentselectionTest(const scene::INodePtr& node) const;
};

/**
* Selector class specifically testing merge actions only
*/
class MergeActionSelector :
public SelectionTestWalker
{
public:
MergeActionSelector(Selector& selector, SelectionTest& test);

bool visit(const scene::INodePtr& node) override;

protected:
// Invert the logic of the base class and only allow merge action nodes to be tested
bool nodeIsEligibleForTesting(const scene::INodePtr& node) override;
};

}

0 comments on commit 130b1e9

Please sign in to comment.