1 #include "Manipulators.h"
2 #include "Remap.h"
3 #include "Selectors.h"
4 #include "BestPoint.h"
5 #include "TransformationVisitors.h"
6 #include "SelectionTest.h"
7 #include "Planes.h"
8 #include "../renderer.h"
9
10 // ------------ Helper functions ---------------------------
11
12 const Colour4b g_colour_sphere(0, 0, 0, 255);
13 const Colour4b g_colour_screen(0, 255, 255, 255);
14 const Colour4b g_colour_selected(255, 255, 0, 255);
15
colourSelected(const Colour4b & colour,bool selected)16 inline const Colour4b& colourSelected (const Colour4b& colour, bool selected)
17 {
18 return (selected) ? g_colour_selected : colour;
19 }
20
21 template<typename remap_policy>
draw_semicircle(const std::size_t segments,const float radius,PointVertex * vertices,remap_policy remap)22 inline void draw_semicircle (const std::size_t segments, const float radius, PointVertex* vertices, remap_policy remap)
23 {
24 const double increment = c_pi / double(segments << 2);
25
26 std::size_t count = 0;
27 float x = radius;
28 float y = 0;
29 remap_policy::set(vertices[segments << 2].vertex, -radius, 0, 0);
30 while (count < segments) {
31 PointVertex* i = vertices + count;
32 PointVertex* j = vertices + ((segments << 1) - (count + 1));
33
34 PointVertex* k = i + (segments << 1);
35 PointVertex* l = j + (segments << 1);
36
37 remap_policy::set(i->vertex, x, -y, 0);
38 remap_policy::set(k->vertex, -y, -x, 0);
39
40 ++count;
41
42 {
43 const double theta = increment * count;
44 x = static_cast<float> (radius * cos(theta));
45 y = static_cast<float> (radius * sin(theta));
46 }
47
48 remap_policy::set(j->vertex, y, -x, 0);
49 remap_policy::set(l->vertex, -x, -y, 0);
50 #if 0
51 remap_policy::set(n->vertex,-y, x, 0);
52 remap_policy::set(p->vertex, x, y, 0);
53 #endif
54 }
55 }
56
~Manipulator()57 Manipulator::~Manipulator()
58 {
59 }
60
61 // ------------ RotateManipulator methods ------------------
62
63 // Constructor
RotateManipulator(Rotatable & rotatable,std::size_t segments,float radius)64 RotateManipulator::RotateManipulator (Rotatable& rotatable, std::size_t segments, float radius) :
65 m_free(rotatable), m_axis(rotatable), m_circle_x((segments << 2) + 1), m_circle_y((segments << 2) + 1), m_circle_z(
66 (segments << 2) + 1), m_circle_screen(segments << 3), m_circle_sphere(segments << 3)
67 {
68 draw_semicircle(segments, radius, m_circle_x.m_vertices.data(), RemapYZX());
69 draw_semicircle(segments, radius, m_circle_y.m_vertices.data(), RemapZXY());
70 draw_semicircle(segments, radius, m_circle_z.m_vertices.data(), RemapXYZ());
71
72 draw_circle(segments, radius * 1.15f, m_circle_screen.m_vertices.data(), RemapXYZ());
73 draw_circle(segments, radius, m_circle_sphere.m_vertices.data(), RemapXYZ());
74 }
75
UpdateColours()76 void RotateManipulator::UpdateColours ()
77 {
78 m_circle_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected()));
79 m_circle_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected()));
80 m_circle_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected()));
81 m_circle_screen.setColour(colourSelected(g_colour_screen, m_selectable_screen.isSelected()));
82 m_circle_sphere.setColour(colourSelected(g_colour_sphere, false));
83 }
84
updateCircleTransforms()85 void RotateManipulator::updateCircleTransforms ()
86 {
87 Vector3 localViewpoint(matrix4_transformed_direction(m_pivot.m_worldSpace.getTransposed(),
88 m_pivot.m_viewpointSpace.z().getVector3()));
89
90 m_circle_x_visible = !vector3_equal_epsilon(g_vector3_axis_x, localViewpoint, 1e-6f);
91 if (m_circle_x_visible) {
92 m_local2world_x = Matrix4::getIdentity();
93 m_local2world_x.y().getVector3() = g_vector3_axis_x.crossProduct(localViewpoint).getNormalised();
94 m_local2world_x.z().getVector3() = m_local2world_x.x().getVector3().crossProduct(
95 m_local2world_x.y().getVector3()).getNormalised();
96 matrix4_premultiply_by_matrix4(m_local2world_x, m_pivot.m_worldSpace);
97 }
98
99 m_circle_y_visible = !vector3_equal_epsilon(g_vector3_axis_y, localViewpoint, 1e-6f);
100 if (m_circle_y_visible) {
101 m_local2world_y = Matrix4::getIdentity();
102 m_local2world_y.z().getVector3() = g_vector3_axis_y.crossProduct(localViewpoint).getNormalised();
103 m_local2world_y.x().getVector3() = m_local2world_y.y().getVector3().crossProduct(
104 m_local2world_y.z().getVector3()).getNormalised();
105 matrix4_premultiply_by_matrix4(m_local2world_y, m_pivot.m_worldSpace);
106 }
107
108 m_circle_z_visible = !vector3_equal_epsilon(g_vector3_axis_z, localViewpoint, 1e-6f);
109 if (m_circle_z_visible) {
110 m_local2world_z = Matrix4::getIdentity();
111 m_local2world_z.x().getVector3() = g_vector3_axis_z.crossProduct(localViewpoint).getNormalised();
112 m_local2world_z.y().getVector3() = m_local2world_z.z().getVector3().crossProduct(
113 m_local2world_z.x().getVector3()).getNormalised();
114 matrix4_premultiply_by_matrix4(m_local2world_z, m_pivot.m_worldSpace);
115 }
116 }
117
render(Renderer & renderer,const VolumeTest & volume,const Matrix4 & pivot2world)118 void RotateManipulator::render (Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world)
119 {
120 m_pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport());
121 updateCircleTransforms();
122
123 // temp hack
124 UpdateColours();
125
126 renderer.SetState(m_state_outer, Renderer::eWireframeOnly);
127 renderer.SetState(m_state_outer, Renderer::eFullMaterials);
128
129 renderer.addRenderable(m_circle_screen, m_pivot.m_viewpointSpace);
130 renderer.addRenderable(m_circle_sphere, m_pivot.m_viewpointSpace);
131
132 if (m_circle_x_visible) {
133 renderer.addRenderable(m_circle_x, m_local2world_x);
134 }
135 if (m_circle_y_visible) {
136 renderer.addRenderable(m_circle_y, m_local2world_y);
137 }
138 if (m_circle_z_visible) {
139 renderer.addRenderable(m_circle_z, m_local2world_z);
140 }
141 }
142
testSelect(const View & view,const Matrix4 & pivot2world)143 void RotateManipulator::testSelect (const View& view, const Matrix4& pivot2world)
144 {
145 m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport());
146 updateCircleTransforms();
147
148 SelectionPool selector;
149
150 {
151 {
152 Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_x));
153
154 SelectionIntersection best;
155 LineStrip_BestPoint(local2view, m_circle_x.m_vertices.data(), m_circle_x.m_vertices.size(), best);
156 selector.addSelectable(best, &m_selectable_x);
157 }
158
159 {
160 Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_y));
161
162 SelectionIntersection best;
163 LineStrip_BestPoint(local2view, m_circle_y.m_vertices.data(), m_circle_y.m_vertices.size(), best);
164 selector.addSelectable(best, &m_selectable_y);
165 }
166
167 {
168 Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_local2world_z));
169
170 SelectionIntersection best;
171 LineStrip_BestPoint(local2view, m_circle_z.m_vertices.data(), m_circle_z.m_vertices.size(), best);
172 selector.addSelectable(best, &m_selectable_z);
173 }
174 }
175
176 {
177 Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace));
178
179 {
180 SelectionIntersection best;
181 LineLoop_BestPoint(local2view, m_circle_screen.m_vertices.data(), m_circle_screen.m_vertices.size(), best);
182 selector.addSelectable(best, &m_selectable_screen);
183 }
184
185 {
186 SelectionIntersection best;
187 Circle_BestPoint(local2view, eClipCullCW, m_circle_sphere.m_vertices.data(),
188 m_circle_sphere.m_vertices.size(), best);
189 selector.addSelectable(best, &m_selectable_sphere);
190 }
191 }
192
193 m_axis_screen = m_pivot.m_axis_screen;
194
195 if (!selector.failed()) {
196 (*selector.begin()).second->setSelected(true);
197 }
198 }
199
GetManipulatable()200 Manipulatable* RotateManipulator::GetManipulatable ()
201 {
202 if (m_selectable_x.isSelected()) {
203 m_axis.SetAxis(g_vector3_axis_x);
204 return &m_axis;
205 } else if (m_selectable_y.isSelected()) {
206 m_axis.SetAxis(g_vector3_axis_y);
207 return &m_axis;
208 } else if (m_selectable_z.isSelected()) {
209 m_axis.SetAxis(g_vector3_axis_z);
210 return &m_axis;
211 } else if (m_selectable_screen.isSelected()) {
212 m_axis.SetAxis(m_axis_screen);
213 return &m_axis;
214 } else
215 return &m_free;
216 }
217
setSelected(bool select)218 void RotateManipulator::setSelected (bool select)
219 {
220 m_selectable_x.setSelected(select);
221 m_selectable_y.setSelected(select);
222 m_selectable_z.setSelected(select);
223 m_selectable_screen.setSelected(select);
224 }
225
isSelected() const226 bool RotateManipulator::isSelected () const
227 {
228 return m_selectable_x.isSelected() | m_selectable_y.isSelected() | m_selectable_z.isSelected()
229 | m_selectable_screen.isSelected() | m_selectable_sphere.isSelected();
230 }
231
232 // Initialise the shader of the RotateManipulator class
233 Shader* RotateManipulator::m_state_outer;
234
235 // ------------ TranslateManipulator methods ------------------
236
237 // Constructor
TranslateManipulator(Translatable & translatable,std::size_t segments,float length)238 TranslateManipulator::TranslateManipulator (Translatable& translatable, std::size_t segments, float length) :
239 m_free(translatable), m_axis(translatable), m_arrow_head_x(3 * 2 * (segments << 3)), m_arrow_head_y(3 * 2
240 * (segments << 3)), m_arrow_head_z(3 * 2 * (segments << 3))
241 {
242 draw_arrowline(length, m_arrow_x.m_line, 0);
243 draw_arrowhead(segments, length, m_arrow_head_x.m_vertices.data(), TripleRemapXYZ<Vertex3f> (), TripleRemapXYZ<
244 Normal3f> ());
245 draw_arrowline(length, m_arrow_y.m_line, 1);
246 draw_arrowhead(segments, length, m_arrow_head_y.m_vertices.data(), TripleRemapYZX<Vertex3f> (), TripleRemapYZX<
247 Normal3f> ());
248 draw_arrowline(length, m_arrow_z.m_line, 2);
249 draw_arrowhead(segments, length, m_arrow_head_z.m_vertices.data(), TripleRemapZXY<Vertex3f> (), TripleRemapZXY<
250 Normal3f> ());
251
252 draw_quad(16, m_quad_screen.m_quad);
253 }
254
UpdateColours()255 void TranslateManipulator::UpdateColours ()
256 {
257 m_arrow_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected()));
258 m_arrow_head_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected()));
259 m_arrow_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected()));
260 m_arrow_head_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected()));
261 m_arrow_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected()));
262 m_arrow_head_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected()));
263 m_quad_screen.setColour(colourSelected(g_colour_screen, m_selectable_screen.isSelected()));
264 }
265
manipulator_show_axis(const Pivot2World & pivot,const Vector3 & axis)266 bool TranslateManipulator::manipulator_show_axis (const Pivot2World& pivot, const Vector3& axis)
267 {
268 return fabs(pivot.m_axis_screen.dot(axis)) < 0.95;
269 }
270
render(Renderer & renderer,const VolumeTest & volume,const Matrix4 & pivot2world)271 void TranslateManipulator::render (Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world)
272 {
273 m_pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport());
274
275 // temp hack
276 UpdateColours();
277
278 Vector3 x = m_pivot.m_worldSpace.x().getVector3().getNormalised();
279 bool show_x = manipulator_show_axis(m_pivot, x);
280
281 Vector3 y = m_pivot.m_worldSpace.y().getVector3().getNormalised();
282 bool show_y = manipulator_show_axis(m_pivot, y);
283
284 Vector3 z = m_pivot.m_worldSpace.z().getVector3().getNormalised();
285 bool show_z = manipulator_show_axis(m_pivot, z);
286
287 renderer.SetState(m_state_wire, Renderer::eWireframeOnly);
288 renderer.SetState(m_state_wire, Renderer::eFullMaterials);
289
290 if (show_x) {
291 renderer.addRenderable(m_arrow_x, m_pivot.m_worldSpace);
292 }
293 if (show_y) {
294 renderer.addRenderable(m_arrow_y, m_pivot.m_worldSpace);
295 }
296 if (show_z) {
297 renderer.addRenderable(m_arrow_z, m_pivot.m_worldSpace);
298 }
299
300 renderer.addRenderable(m_quad_screen, m_pivot.m_viewplaneSpace);
301
302 renderer.SetState(m_state_fill, Renderer::eWireframeOnly);
303 renderer.SetState(m_state_fill, Renderer::eFullMaterials);
304
305 if (show_x) {
306 renderer.addRenderable(m_arrow_head_x, m_pivot.m_worldSpace);
307 }
308 if (show_y) {
309 renderer.addRenderable(m_arrow_head_y, m_pivot.m_worldSpace);
310 }
311 if (show_z) {
312 renderer.addRenderable(m_arrow_head_z, m_pivot.m_worldSpace);
313 }
314 }
315
testSelect(const View & view,const Matrix4 & pivot2world)316 void TranslateManipulator::testSelect (const View& view, const Matrix4& pivot2world)
317 {
318 m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport());
319
320 SelectionPool selector;
321
322 Vector3 x = m_pivot.m_worldSpace.x().getVector3().getNormalised();
323 bool show_x = manipulator_show_axis(m_pivot, x);
324
325 Vector3 y = m_pivot.m_worldSpace.y().getVector3().getNormalised();
326 bool show_y = manipulator_show_axis(m_pivot, y);
327
328 Vector3 z = m_pivot.m_worldSpace.z().getVector3().getNormalised();
329 bool show_z = manipulator_show_axis(m_pivot, z);
330
331 {
332 Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace));
333
334 {
335 SelectionIntersection best;
336 Quad_BestPoint(local2view, eClipCullCW, m_quad_screen.m_quad, best);
337 if (best.valid()) {
338 best = SelectionIntersection(0, 0);
339 selector.addSelectable(best, &m_selectable_screen);
340 }
341 }
342 }
343
344 {
345 Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_worldSpace));
346
347 #if defined(DEBUG_SELECTION)
348 g_render_clipped.construct(view.GetViewMatrix());
349 #endif
350
351 if (show_x) {
352 SelectionIntersection best;
353 Line_BestPoint(local2view, m_arrow_x.m_line, best);
354 Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_x.m_vertices.begin(),
355 m_arrow_head_x.m_vertices.end(), best);
356 selector.addSelectable(best, &m_selectable_x);
357 }
358
359 if (show_y) {
360 SelectionIntersection best;
361 Line_BestPoint(local2view, m_arrow_y.m_line, best);
362 Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_y.m_vertices.begin(),
363 m_arrow_head_y.m_vertices.end(), best);
364 selector.addSelectable(best, &m_selectable_y);
365 }
366
367 if (show_z) {
368 SelectionIntersection best;
369 Line_BestPoint(local2view, m_arrow_z.m_line, best);
370 Triangles_BestPoint(local2view, eClipCullCW, m_arrow_head_z.m_vertices.begin(),
371 m_arrow_head_z.m_vertices.end(), best);
372 selector.addSelectable(best, &m_selectable_z);
373 }
374 }
375
376 if (!selector.failed()) {
377 (*selector.begin()).second->setSelected(true);
378 }
379 }
380
GetManipulatable()381 Manipulatable* TranslateManipulator::GetManipulatable ()
382 {
383 if (m_selectable_x.isSelected()) {
384 m_axis.SetAxis(g_vector3_axis_x);
385 return &m_axis;
386 } else if (m_selectable_y.isSelected()) {
387 m_axis.SetAxis(g_vector3_axis_y);
388 return &m_axis;
389 } else if (m_selectable_z.isSelected()) {
390 m_axis.SetAxis(g_vector3_axis_z);
391 return &m_axis;
392 } else {
393 return &m_free;
394 }
395 }
396
setSelected(bool select)397 void TranslateManipulator::setSelected (bool select)
398 {
399 m_selectable_x.setSelected(select);
400 m_selectable_y.setSelected(select);
401 m_selectable_z.setSelected(select);
402 m_selectable_screen.setSelected(select);
403 }
404
isSelected() const405 bool TranslateManipulator::isSelected () const
406 {
407 return m_selectable_x.isSelected() | m_selectable_y.isSelected() | m_selectable_z.isSelected()
408 | m_selectable_screen.isSelected();
409 }
410
411 // Initialise the shaders of this class
412 Shader* TranslateManipulator::m_state_wire;
413 Shader* TranslateManipulator::m_state_fill;
414
415 // ------------ ScaleManipulator methods ------------------
416
417 // Constructor
ScaleManipulator(Scalable & scalable,std::size_t segments,float length)418 ScaleManipulator::ScaleManipulator (Scalable& scalable, std::size_t segments, float length) :
419 m_free(scalable), m_axis(scalable)
420 {
421 draw_arrowline(length, m_arrow_x.m_line, 0);
422 draw_arrowline(length, m_arrow_y.m_line, 1);
423 draw_arrowline(length, m_arrow_z.m_line, 2);
424
425 draw_quad(16, m_quad_screen.m_quad);
426 }
427
UpdateColours()428 void ScaleManipulator::UpdateColours ()
429 {
430 m_arrow_x.setColour(colourSelected(g_colour_x, m_selectable_x.isSelected()));
431 m_arrow_y.setColour(colourSelected(g_colour_y, m_selectable_y.isSelected()));
432 m_arrow_z.setColour(colourSelected(g_colour_z, m_selectable_z.isSelected()));
433 m_quad_screen.setColour(colourSelected(g_colour_screen, m_selectable_screen.isSelected()));
434 }
435
render(Renderer & renderer,const VolumeTest & volume,const Matrix4 & pivot2world)436 void ScaleManipulator::render (Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world)
437 {
438 m_pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport());
439
440 // temp hack
441 UpdateColours();
442
443 renderer.addRenderable(m_arrow_x, m_pivot.m_worldSpace);
444 renderer.addRenderable(m_arrow_y, m_pivot.m_worldSpace);
445 renderer.addRenderable(m_arrow_z, m_pivot.m_worldSpace);
446
447 renderer.addRenderable(m_quad_screen, m_pivot.m_viewpointSpace);
448 }
449
testSelect(const View & view,const Matrix4 & pivot2world)450 void ScaleManipulator::testSelect (const View& view, const Matrix4& pivot2world)
451 {
452 m_pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport());
453
454 SelectionPool selector;
455
456 {
457 Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_worldSpace));
458
459 {
460 SelectionIntersection best;
461 Line_BestPoint(local2view, m_arrow_x.m_line, best);
462 selector.addSelectable(best, &m_selectable_x);
463 }
464
465 {
466 SelectionIntersection best;
467 Line_BestPoint(local2view, m_arrow_y.m_line, best);
468 selector.addSelectable(best, &m_selectable_y);
469 }
470
471 {
472 SelectionIntersection best;
473 Line_BestPoint(local2view, m_arrow_z.m_line, best);
474 selector.addSelectable(best, &m_selectable_z);
475 }
476 }
477
478 {
479 Matrix4 local2view(matrix4_multiplied_by_matrix4(view.GetViewMatrix(), m_pivot.m_viewpointSpace));
480
481 {
482 SelectionIntersection best;
483 Quad_BestPoint(local2view, eClipCullCW, m_quad_screen.m_quad, best);
484 selector.addSelectable(best, &m_selectable_screen);
485 }
486 }
487
488 if (!selector.failed()) {
489 (*selector.begin()).second->setSelected(true);
490 }
491 }
492
GetManipulatable()493 Manipulatable* ScaleManipulator::GetManipulatable ()
494 {
495 if (m_selectable_x.isSelected()) {
496 m_axis.SetAxis(g_vector3_axis_x);
497 return &m_axis;
498 } else if (m_selectable_y.isSelected()) {
499 m_axis.SetAxis(g_vector3_axis_y);
500 return &m_axis;
501 } else if (m_selectable_z.isSelected()) {
502 m_axis.SetAxis(g_vector3_axis_z);
503 return &m_axis;
504 } else
505 return &m_free;
506 }
507
setSelected(bool select)508 void ScaleManipulator::setSelected (bool select)
509 {
510 m_selectable_x.setSelected(select);
511 m_selectable_y.setSelected(select);
512 m_selectable_z.setSelected(select);
513 m_selectable_screen.setSelected(select);
514 }
515
isSelected() const516 bool ScaleManipulator::isSelected () const
517 {
518 return m_selectable_x.isSelected() | m_selectable_y.isSelected() | m_selectable_z.isSelected()
519 | m_selectable_screen.isSelected();
520 }
521
522 // ------------ DragManipulator methods ------------------
523
GetManipulatable()524 Manipulatable* DragManipulator::GetManipulatable() {
525 return _dragSelectable.isSelected() ? &_freeDrag : &_freeResize;
526 }
527
testSelect(const View & view,const Matrix4 & pivot2world)528 void DragManipulator::testSelect(const View& view, const Matrix4& pivot2world) {
529 SelectionPool selector;
530
531 SelectionVolume test(view);
532
533 if (GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) {
534 BooleanSelector booleanSelector;
535
536 Scene_TestSelect_Primitive(booleanSelector, test, view);
537
538 if (booleanSelector.isSelected()) {
539 selector.addSelectable(SelectionIntersection(0, 0), &_dragSelectable);
540 _selected = false;
541 } else {
542 _selected = Scene_forEachPlaneSelectable_selectPlanes(GlobalSceneGraph(), selector, test);
543 }
544 }
545 // Check for entities that can be selected
546 else if (GlobalSelectionSystem().Mode() == SelectionSystem::eEntity) {
547 // Create a boolean selection pool (can have exactly one selectable or none)
548 BooleanSelector booleanSelector;
549
550 // Find the visible entities
551 Scene_forEachVisible(GlobalSceneGraph(), view, testselect_entity_visible(booleanSelector, test));
552
553 // Check, if an entity could be found
554 if (booleanSelector.isSelected()) {
555 selector.addSelectable(SelectionIntersection(0, 0), &_dragSelectable);
556 _selected = false;
557 }
558 } else {
559 BestSelector bestSelector;
560 Scene_TestSelect_Component_Selected(bestSelector, test, view, GlobalSelectionSystem().ComponentMode());
561 for (std::list<Selectable*>::iterator i = bestSelector.best().begin(); i != bestSelector.best().end(); ++i) {
562 if (!(*i)->isSelected()) {
563 GlobalSelectionSystem().setSelectedAllComponents(false);
564 }
565 _selected = false;
566 selector.addSelectable(SelectionIntersection(0, 0), (*i));
567 _dragSelectable.setSelected(true);
568 }
569 }
570
571 for (SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i) {
572 (*i).second->setSelected(true);
573 }
574 }
575
setSelected(bool select)576 void DragManipulator::setSelected(bool select) {
577 _selected = select;
578 _dragSelectable.setSelected(select);
579 }
580
isSelected() const581 bool DragManipulator::isSelected() const {
582 return _selected || _dragSelectable.isSelected();
583 }
584