/
MergeActionNode.h
149 lines (119 loc) · 4.02 KB
/
MergeActionNode.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#pragma once
#include "imergeaction.h"
#include "iselectiontest.h"
#include "math/AABB.h"
#include "scene/SelectableNode.h"
#include "scene/merge/MergeAction.h"
namespace map
{
class MergeActionNode final :
public scene::IMergeActionNode,
public scene::SelectableNode,
public SelectionTestable
{
private:
scene::merge::MergeAction::Ptr _action;
scene::INodePtr _affectedNode;
public:
using Ptr = std::shared_ptr<MergeActionNode>;
MergeActionNode(const scene::merge::MergeAction::Ptr& action) :
_action(action)
{
_affectedNode = _action->getAffectedNode();
auto addNodeAction = std::dynamic_pointer_cast<scene::merge::AddCloneToParentAction>(_action);
if (addNodeAction)
{
// Get the clone and add it to the target scene, it needs to be renderable here
scene::addNodeToContainer(_affectedNode, addNodeAction->getParent());
}
// Hide the affected node itself, we're doing the rendering ourselves, recursively
_affectedNode->enable(Node::eHidden);
_affectedNode->foreachNode([&](const scene::INodePtr& child)
{
child->enable(Node::eHidden);
return true;
});
}
void onInsertIntoScene(scene::IMapRootNode& rootNode) override
{
SelectableNode::onInsertIntoScene(rootNode);
_action->activate();
}
void onRemoveFromScene(scene::IMapRootNode& rootNode) override
{
auto addNodeAction = std::dynamic_pointer_cast<scene::merge::AddCloneToParentAction>(_action);
if (addNodeAction)
{
scene::removeNodeFromParent(_affectedNode);
}
// Release the hidden state of the contained nodes
_affectedNode->disable(Node::eHidden);
_affectedNode->foreachNode([&](const scene::INodePtr& child)
{
child->disable(Node::eHidden);
return true;
});
_action->deactivate();
SelectableNode::onRemoveFromScene(rootNode);
}
scene::merge::ActionType getActionType() const override
{
return _action->getType();
}
scene::INode::Type getNodeType() const override
{
return scene::INode::Type::MergeAction;
}
const AABB& localAABB() const override
{
return _affectedNode->localAABB();
}
void renderSolid(RenderableCollector& collector, const VolumeTest& volume) const override
{
_affectedNode->viewChanged();
_affectedNode->renderSolid(collector, volume);
_affectedNode->foreachNode([&](const scene::INodePtr& child)
{
child->viewChanged();
child->renderSolid(collector, volume);
return true;
});
}
void renderWireframe(RenderableCollector& collector, const VolumeTest& volume) const override
{
_affectedNode->viewChanged();
_affectedNode->renderWireframe(collector, volume);
_affectedNode->foreachNode([&](const scene::INodePtr& child)
{
child->viewChanged();
child->renderWireframe(collector, volume);
return true;
});
}
std::size_t getHighlightFlags() override
{
return isSelected() ? Highlight::Selected : Highlight::NoHighlight;
}
void testSelect(Selector& selector, SelectionTest& test) override
{
testSelectNode(_affectedNode, selector, test);
_affectedNode->foreachNode([&](const scene::INodePtr& child)
{
testSelectNode(child, selector, test);
return true;
});
}
private:
void testSelectNode(const scene::INodePtr& node, Selector& selector, SelectionTest& test)
{
auto selectionTestable = std::dynamic_pointer_cast<SelectionTestable>(node);
// Regardless of what node we test, it will always be the MergeActionNode that will be selected
selector.pushSelectable(*this);
if (selectionTestable)
{
selectionTestable->testSelect(selector, test);
}
selector.popSelectable();
}
};
}