/
RadiantSelectionSystem.h
215 lines (150 loc) · 7.13 KB
/
RadiantSelectionSystem.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#pragma once
#include "irenderable.h"
#include "iselection.h"
#include "iselectiontest.h"
#include "icommandsystem.h"
#include "imap.h"
#include "selectionlib.h"
#include "SelectedNodeList.h"
#include "SceneManipulationPivot.h"
namespace selection
{
class RadiantSelectionSystem final :
public SelectionSystem,
public Renderable,
public ISceneSelectionTesterFactory
{
private:
SceneManipulationPivot _pivot;
std::set<Observer*> _observers;
// The 3D volume surrounding the most recent selection.
WorkZone _workZone;
// When this is set to TRUE, the idle callback will emit a scenegraph change call
// This is to avoid massive calls to GlobalSceneGraph().sceneChanged() on each
// and every selection change.
mutable bool _requestWorkZoneRecalculation;
// A simple set that gets filled after the SelectableSortedSet is populated.
// greebo: I used this to merge two SelectionPools (entities and primitives)
// with a preferred sorting (see RadiantSelectionSystem::testSelectScene)
typedef std::list<ISelectable*> SelectablesList;
SelectionInfo _selectionInfo;
sigc::signal<void, const ISelectable&> _sigSelectionChanged;
std::map<std::size_t, ISceneManipulator::Ptr> _manipulators;
// The currently active manipulator
ISceneManipulator::Ptr _activeManipulator;
IManipulator::Type _defaultManipulatorType;
// state
SelectionMode _mode;
ComponentSelectionMode _componentMode;
std::size_t _countPrimitive;
std::size_t _countComponent;
// The internal list to keep track of the selected instances (components and primitives)
SelectedNodeList _selection;
SelectedNodeList _componentSelection;
// The coordinates of the mouse pointer when the manipulation starts
Vector2 _deviceStart;
bool nothingSelected() const;
sigc::signal<void, IManipulator::Type> _sigActiveManipulatorChanged;
sigc::signal<void, SelectionMode> _sigSelectionModeChanged;
sigc::signal<void, ComponentSelectionMode> _sigComponentModeChanged;
bool _selectionFocusActive;
std::set<std::shared_ptr<ISelectable>> _selectionFocusPool;
public:
RadiantSelectionSystem();
/** greebo: Returns a structure with all the related
* information about the current selection (brush count,
* entity count, etc.)
*/
const SelectionInfo& getSelectionInfo() override;
void onSceneBoundsChanged();
void pivotChanged() override;
void pivotChangedSelection(const ISelectable& selectable);
void addObserver(Observer* observer) override;
void removeObserver(Observer* observer) override;
void setSelectionMode(SelectionMode mode) override;
SelectionMode getSelectionMode() const override;
void SetComponentMode(ComponentSelectionMode mode) override;
ComponentSelectionMode ComponentMode() const override;
sigc::signal<void, SelectionMode>& signal_selectionModeChanged() override;
sigc::signal<void, ComponentSelectionMode>& signal_componentModeChanged() override;
// Returns the ID of the registered manipulator
std::size_t registerManipulator(const ISceneManipulator::Ptr& manipulator) override;
void unregisterManipulator(const ISceneManipulator::Ptr& manipulator) override;
IManipulator::Type getActiveManipulatorType() override;
const ISceneManipulator::Ptr& getActiveManipulator() override;
void setActiveManipulator(std::size_t manipulatorId) override;
void setActiveManipulator(IManipulator::Type manipulatorType) override;
sigc::signal<void, IManipulator::Type>& signal_activeManipulatorChanged() override;
std::size_t countSelected() const override;
std::size_t countSelectedComponents() const override;
void onSelectedChanged(const scene::INodePtr& node, const ISelectable& selectable) override;
void onComponentSelection(const scene::INodePtr& node, const ISelectable& selectable) override;
SelectionChangedSignal signal_selectionChanged() const override
{
return _sigSelectionChanged;
}
scene::INodePtr ultimateSelected() override;
scene::INodePtr penultimateSelected() override;
void setSelectedAll(bool selected) override;
void setSelectedAllComponents(bool selected) override;
void foreachSelected(const std::function<void(const scene::INodePtr&)>& functor) override;
void foreachSelectedComponent(const Visitor& visitor) override;
void foreachSelectedComponent(const std::function<void(const scene::INodePtr&)>& functor) override;
void foreachBrush(const std::function<void(Brush&)>& functor) override;
void foreachFace(const std::function<void(IFace&)>& functor) override;
void foreachPatch(const std::function<void(IPatch&)>& functor) override;
std::size_t getSelectedFaceCount() override;
IFace& getSingleSelectedFace() override;
void deselectAll();
void selectPoint(SelectionTest& test, EModifier modifier, bool face) override;
void selectArea(SelectionTest& test, EModifier modifier, bool face) override;
void onManipulationStart() override;
void onManipulationChanged() override;
void onManipulationEnd() override;
void onManipulationCancelled() override;
const WorkZone& getWorkZone() override;
Vector3 getCurrentSelectionCenter() override;
void toggleSelectionFocus();
void onPreRender(const VolumeTest& volume) override;
void renderHighlights(IRenderableCollector& collector, const VolumeTest& volume) override
{}
void setRenderSystem(const RenderSystemPtr& renderSystem) override
{}
std::size_t getHighlightFlags() override
{
return Highlight::NoHighlight; // never highlighted
}
const Matrix4& getPivot2World() override;
// RegisterableModule implementation
const std::string& getName() const override;
const StringSet& getDependencies() const override;
void initialiseModule(const IApplicationContext& ctx) override;
void shutdownModule() override;
ISceneSelectionTester::Ptr createSceneSelectionTester(SelectionMode mode) override;
private:
// Traverses the scene and adds any selectable nodes matching the given SelectionTest to the "targetList".
void testSelectScene(SelectablesList& targetList, SelectionTest& test,
const VolumeTest& view, SelectionMode mode, ComponentSelectionMode componentMode);
bool higherEntitySelectionPriority() const;
void notifyObservers(const scene::INodePtr& node, bool isComponent);
std::size_t getManipulatorIdForType(IManipulator::Type type);
// Command targets used to connect to the event system
void toggleManipulatorModeCmd(const cmd::ArgumentList& args);
void toggleManipulatorMode(IManipulator::Type type);
void toggleManipulatorModeById(std::size_t manipId);
void activateDefaultMode();
void toggleEntityMode(const cmd::ArgumentList& args);
void toggleGroupPartMode(const cmd::ArgumentList& args);
void toggleMergeActionMode(const cmd::ArgumentList& args);
void toggleSelectionFocus(const cmd::ArgumentList& args);
void toggleComponentMode(ComponentSelectionMode mode);
void toggleComponentModeCmd(const cmd::ArgumentList& args);
void onManipulatorModeChanged();
void onComponentModeChanged();
void checkComponentModeSelectionMode(const ISelectable& selectable); // connects to the selection change signal
void performPointSelection(const SelectablesList& candidates, EModifier modifier);
void onSelectionPerformed();
void deselectCmd(const cmd::ArgumentList& args);
void onMapEvent(IMap::MapEvent ev);
};
}