57 #include "TranslationManipulatorNode.hh" 59 #include <ACG/GL/IRenderer.hh> 61 #include <OpenMesh/Core/Geometry/MathDefs.hh> 63 #include <ACG/GL/GLPrimitives.hh> 76 #define SNAP_PIXEL_TOLERANCE 30 80 const Vec4f colors[4][6] = {
84 Vec4f(0.2f,0.2f,0.2f,1.0f),
Vec4f(0.5f,0.5f,0.5f,1.0f),
Vec4f(0.8f,0.8f,0.8f,1.0f),
86 Vec4f(0.2f,0.2f,0.2f,0.2f),
Vec4f(0.5f,0.5f,0.5f,0.4f),
Vec4f(0.8f,0.8f,0.8f,0.6f)
91 Vec4f(0.2f,0.0f,0.0f,1.0f),
Vec4f(0.5f,0.0f,0.0f,1.0f),
Vec4f(0.8f,0.0f,0.0f,1.0f),
93 Vec4f(0.3f,0.1f,0.1f,0.2f),
Vec4f(0.5f,0.2f,0.2f,0.4f),
Vec4f(0.8f,0.4f,0.4f,0.6f)
98 Vec4f(0.0f,0.2f,0.0f,1.0f),
Vec4f(0.0f,0.5f,0.0f,1.0f),
Vec4f(0.0f,0.8f,0.0f,1.0f),
100 Vec4f(0.1f,0.3f,0.1f,0.2f),
Vec4f(0.2f,0.5f,0.2f,0.4f),
Vec4f(0.4f,0.8f,0.4f,0.6f)
105 Vec4f(0.0f,0.0f,0.2f,1.0f),
Vec4f(0.0f,0.0f,0.5f,1.0f),
Vec4f(0.0f,0.0f,0.8f,1.0f),
107 Vec4f(0.1f,0.1f,0.3f,0.2f),
Vec4f(0.2f,0.2f,0.5f,0.4f),
Vec4f(0.4f,0.4f,0.8f,0.6f)
114 TranslationManipulatorNode::Element::Element () :
115 active_target_color_ (0.0, 0.0, 0.0, 1.0),
116 active_current_color_ (0.0, 0.0, 0.0, 1.0),
117 inactive_target_color_ (0.0, 0.0, 0.0, 1.0),
118 inactive_current_color_ (0.0, 0.0, 0.0, 1.0),
130 draw_manipulator_(false),
139 manipulator_radius_(20.0),
140 manipulator_height_(20),
141 set_manipulator_radius_(1.0),
142 set_manipulator_height_(1.0),
143 manipulator_slices_(10),
144 manipulator_stacks_(10),
145 any_axis_clicked_(false),
146 any_top_clicked_(false),
147 outer_ring_clicked_(false),
148 any_axis_over_(false),
149 any_top_over_(false),
150 outer_ring_over_(false),
151 resize_current_ (0.0),
152 mode_ (TranslationRotation),
156 auto_size_length_(1.0),
157 activeRotations_(ALL_AXIS)
162 axisBottom_ =
new ACG::GLCone(manipulator_slices_, manipulator_stacks_,
163 (1.0 - resize_current_) * manipulator_radius_,
164 (1.0 + resize_current_) * manipulator_radius_,
false,
true);
165 axisCenter_ =
new ACG::GLCone(manipulator_slices_, manipulator_stacks_,
166 (1.0 - resize_current_) * manipulator_radius_,
167 (1.0 + resize_current_) * manipulator_radius_,
false,
true);
168 axisTop_ =
new ACG::GLCone(manipulator_slices_, manipulator_stacks_,
169 (1.0 - resize_current_) * manipulator_radius_,
170 (1.0 + resize_current_) * manipulator_radius_,
false,
true);
172 sphere_ =
new ACG::GLSphere(manipulator_slices_, manipulator_stacks_);
173 circle_ =
new ACG::GLDisk(30, 30, 2.0f*manipulator_height_ - manipulator_height_/4.0f, 2.0f*manipulator_height_);
177 updateTargetColors ();
178 for (
unsigned int i = 0; i < TranslationManipulatorNode::NumElements; i++)
180 element_[i].active_current_color_ = element_[i].active_target_color_;
181 element_[i].inactive_current_color_ = element_[i].inactive_target_color_;
237 if(_state.compatibilityProfile())
238 glMatrixMode(GL_MODELVIEW);
245 model *= localTransformation_;
254 void TranslationManipulatorNode::updateTargetColors ()
257 element_[Origin].active_target_color_ = colors[0][0];
258 element_[XAxis].active_target_color_ = colors[1][0];
259 element_[YAxis].active_target_color_ = colors[2][0];
260 element_[ZAxis].active_target_color_ = colors[3][0];
261 element_[XTop].active_target_color_ = colors[1][0];
262 element_[YTop].active_target_color_ = colors[2][0];
263 element_[ZTop].active_target_color_ = colors[3][0];
264 element_[XRing].active_target_color_ = colors[1][0];
265 element_[YRing].active_target_color_ = colors[2][0];
266 element_[ZRing].active_target_color_ = colors[3][0];
268 element_[Origin].inactive_target_color_ = colors[0][3];
269 element_[XAxis].inactive_target_color_ = colors[1][3];
270 element_[YAxis].inactive_target_color_ = colors[2][3];
271 element_[ZAxis].inactive_target_color_ = colors[3][3];
272 element_[XTop].inactive_target_color_ = colors[1][3];
273 element_[YTop].inactive_target_color_ = colors[2][3];
274 element_[ZTop].inactive_target_color_ = colors[3][3];
275 element_[XRing].inactive_target_color_ = colors[1][3];
276 element_[YRing].inactive_target_color_ = colors[2][3];
277 element_[ZRing].inactive_target_color_ = colors[3][3];
281 element_[XRing].active_target_color_[3] = 1.0;
282 element_[YRing].active_target_color_[3] = 1.0;
283 element_[ZRing].active_target_color_[3] = 1.0;
286 if (mode_ == Resize || mode_ == Place)
287 for (
unsigned int i = 0; i < 3; i++)
289 element_[XRing + i].active_target_color_[3] = 0.0;
290 element_[XRing + i].inactive_target_color_[3] = 0.0;
294 if(element_[Origin].clicked_){
295 element_[Origin].active_target_color_ = colors[0][2];
296 element_[Origin].inactive_target_color_ = colors[0][5];
297 for (
unsigned int i = 1; i < NumElements - 3; i++)
299 element_[i].active_target_color_ = (colors[0][2] *
static_cast<float>(0.5) ) + (colors[((i-1)%3) + 1][2] * static_cast<float>(0.5));
300 element_[i].inactive_target_color_ = (colors[0][5] *
static_cast<float>(0.5)) + (colors[((i-1)%3) + 1][5] * static_cast<float>(0.5) );
303 }
else if(element_[Origin].over_){
304 element_[Origin].active_target_color_ = colors[0][1];
305 element_[Origin].inactive_target_color_ = colors[0][4];
306 for (
unsigned int i = 1; i < NumElements - 3; i++)
308 element_[i].active_target_color_ = (colors[0][1] *
static_cast<float>(0.5)) + (colors[((i-1)%3) + 1][1] * static_cast<float>(0.5));
309 element_[i].inactive_target_color_ = (colors[0][4] *
static_cast<float>(0.5)) + (colors[((i-1)%3) + 1][4] * static_cast<float>(0.5));
314 for (
unsigned int i = 0; i < 3; i++)
315 if (element_[i + XTop].clicked_)
317 element_[i + XTop].active_target_color_ = colors[i+1][2];
318 element_[i + XTop].inactive_target_color_ = colors[i+1][5];
319 if (mode_ != TranslationRotation)
321 element_[i + XAxis].active_target_color_ = colors[i+1][2];
322 element_[i + XAxis].inactive_target_color_ = colors[i+1][5];
324 if (mode_ != Resize) {
325 element_[i + XRing].active_target_color_ = colors[i+1][2];
326 element_[i + XRing].inactive_target_color_ = colors[i+1][5];
329 }
else if (element_[i + XTop].over_)
331 element_[i + XTop].active_target_color_ = colors[i+1][1];
332 element_[i + XTop].inactive_target_color_ = colors[i+1][4];
333 if (mode_ != TranslationRotation)
335 element_[i + XAxis].active_target_color_ = colors[i+1][1];
336 element_[i + XAxis].inactive_target_color_ = colors[i+1][4];
338 if (mode_ != Resize) {
339 element_[i + XRing].active_target_color_ = colors[i+1][1];
340 element_[i + XRing].inactive_target_color_ = colors[i+1][4];
345 for (
unsigned int i = 0; i < 3; i++)
346 if (element_[i + XAxis].clicked_)
348 element_[i + XTop].active_target_color_ = colors[i+1][2];
349 element_[i + XTop].inactive_target_color_ = colors[i+1][5];
350 element_[i + XAxis].active_target_color_ = colors[i+1][2];
351 element_[i + XAxis].inactive_target_color_ = colors[i+1][5];
352 if (mode_ == LocalRotation) {
353 element_[i + XRing].active_target_color_ = colors[i+1][2];
354 element_[i + XRing].inactive_target_color_ = colors[i+1][5];
357 }
else if (element_[i + XAxis].over_)
359 element_[i + XTop].active_target_color_ = colors[i+1][1];
360 element_[i + XTop].inactive_target_color_ = colors[i+1][4];
361 element_[i + XAxis].active_target_color_ = colors[i+1][1];
362 element_[i + XAxis].inactive_target_color_ = colors[i+1][4];
363 if (mode_ == LocalRotation) {
364 element_[i + XRing].active_target_color_ = colors[i+1][1];
365 element_[i + XRing].inactive_target_color_ = colors[i+1][4];
370 if (mode_ != Resize) {
371 for (
unsigned int i = 0; i < 3; i++) {
372 if (element_[i + XRing].clicked_)
374 element_[i + XRing].active_target_color_ = colors[i+1][2];
375 element_[i + XRing].inactive_target_color_ = colors[i+1][5];
377 }
else if (element_[i + XRing].over_)
379 element_[i + XRing].active_target_color_ = colors[i+1][1];
380 element_[i + XRing].inactive_target_color_ = colors[i+1][4];
390 bool TranslationManipulatorNode::updateCurrentColors (
GLState& _state)
402 for (
unsigned int i = 0; i < NumElements; i++)
404 Vec4f diff = element_[i].active_target_color_ -
405 element_[i].active_current_color_;
407 for (
unsigned int j = 0; j < 4; j++)
410 else if (diff[j] < -value)
413 element_[i].active_current_color_ += diff;
415 diff = element_[i].inactive_target_color_ -
416 element_[i].inactive_current_color_;
418 for (
unsigned int j = 0; j < 4; j++)
421 else if (diff[j] < -value)
424 element_[i].inactive_current_color_ += diff;
426 rv |= element_[i].active_target_color_ != element_[i].active_current_color_ ||
427 element_[i].inactive_target_color_ != element_[i].inactive_current_color_;
430 float diff = ((mode_ == Resize) ? 1.0 : 0.0) - resize_current_;
434 else if (diff < -value)
437 resize_current_ += diff;
438 rv |= resize_current_ != ((mode_ == Resize) ? 1.0 : 0.0);
445 void TranslationManipulatorNode::drawManipulator (
GLState& _state,
bool _active)
447 glPushAttrib(GL_ENABLE_BIT );
488 axisBottom_->setBottomRadius((1.0 - resize_current_) * manipulator_radius_);
489 axisBottom_->setTopRadius((1.0 + resize_current_) * manipulator_radius_);
490 axisBottom_->draw(_state, manipulator_height_/2.0);
493 _state.
translate(0.0, 0.0, manipulator_height_/2);
495 axisCenter_->setBottomRadius(manipulator_radius_);
496 axisCenter_->setTopRadius(manipulator_radius_);
497 axisCenter_->draw(_state, manipulator_height_/2.0);
510 _state.
translate(0.0, 0.0, manipulator_height_/2);
511 axisTop_->setBottomRadius(manipulator_radius_*2.0);
512 axisTop_->setTopRadius(0.0);
513 axisTop_->draw(_state, manipulator_height_/2.0);
514 _state.
translate(0.0, 0.0, -manipulator_height_);
519 _state.
rotate(-90, 1.0, 0.0, 0.0);
530 axisBottom_->setBottomRadius((1.0 - resize_current_) * manipulator_radius_);
531 axisBottom_->setTopRadius((1.0 + resize_current_) * manipulator_radius_);
532 axisBottom_->draw(_state, manipulator_height_/2.0);
535 _state.
translate(0.0, 0.0, manipulator_height_/2);
537 axisCenter_->setBottomRadius(manipulator_radius_);
538 axisCenter_->setTopRadius(manipulator_radius_);
539 axisCenter_->draw(_state, manipulator_height_/2.0);
552 _state.
translate(0.0, 0.0, manipulator_height_/2);
553 axisTop_->setBottomRadius(manipulator_radius_*2.0);
554 axisTop_->setTopRadius(0.0);
555 axisTop_->draw(_state, manipulator_height_/2.0);
556 _state.
translate(0.0, 0.0, -manipulator_height_);
562 _state.
rotate(90, 0.0, 1.0, 0.0);
573 axisBottom_->setBottomRadius((1.0 - resize_current_) * manipulator_radius_);
574 axisBottom_->setTopRadius((1.0 + resize_current_) * manipulator_radius_);
575 axisBottom_->draw(_state, manipulator_height_/2.0);
578 _state.
translate(0.0, 0.0, manipulator_height_/2);
580 axisCenter_->setBottomRadius(manipulator_radius_);
581 axisCenter_->setTopRadius(manipulator_radius_);
582 axisCenter_->draw(_state, manipulator_height_/2.0);
595 _state.
translate(0.0, 0.0, manipulator_height_/2);
596 axisTop_->setBottomRadius(manipulator_radius_*2.0);
597 axisTop_->setTopRadius(0.0);
598 axisTop_->draw(_state, manipulator_height_/2.0);
599 _state.
translate(0.0, 0.0, -manipulator_height_);
613 sphere_->draw(_state, manipulator_radius_*2);
620 glPushAttrib(GL_LIGHTING_BIT);
624 circle_->setInnerRadius(2.0f*manipulator_height_ - manipulator_height_/4.0f);
625 circle_->setOuterRadius(2.0f*manipulator_height_);
627 if ( activeRotations_ & X_AXIS) {
632 _state.
set_color(element_[XRing].active_current_color_);
637 _state.
set_color(element_[XRing].inactive_current_color_);
641 circle_->draw(_state);
645 _state.
rotate(90, 0.0, 1.0, 0.0);
646 if ( activeRotations_ & Y_AXIS) {
651 _state.
set_color(element_[YRing].active_current_color_);
656 _state.
set_color(element_[YRing].inactive_current_color_);
660 circle_->draw(_state);
663 _state.
rotate(90, 1.0, 0.0, 0.0);
664 if ( activeRotations_ & Z_AXIS) {
669 _state.
set_color(element_[ZRing].active_current_color_);
674 _state.
set_color(element_[ZRing].inactive_current_color_);
678 circle_->draw(_state);
696 if (draw_manipulator_) {
699 glPushAttrib(GL_LIGHTING_BIT);
704 glPushAttrib(GL_DEPTH_BUFFER_BIT);
708 glPushAttrib(GL_COLOR_BUFFER_BIT);
710 glPushAttrib(GL_ENABLE_BIT);
720 updateTargetColors ();
721 if (updateCurrentColors (_state))
726 glDepthMask(GL_FALSE);
729 drawManipulator(_state,
false);
733 glDepthMask(GL_TRUE);
734 drawManipulator(_state,
true);
764 world *= localTransformation_;
776 if (draw_manipulator_)
785 updateTargetColors ();
786 if (updateCurrentColors (_state))
803 ro.depthWrite =
false;
806 ro.blendSrc = GL_SRC_ALPHA;
810 addManipulatorToRenderer(_renderer, &ro,
false);
817 ro.depthWrite =
true;
820 addManipulatorToRenderer(_renderer, &ro,
true);
826 void TranslationManipulatorNode::addAxisToRenderer (
IRenderer* _renderer,
RenderObject* _baseRO,
bool _active,
int _axis)
828 assert(_axis >= XAxis && _axis - 3 >= 0 && _axis <= ZAxis);
830 for (
int i = 0; i < 3; ++i)
831 _baseRO->emissive[i] = _active ? element_[_axis].active_current_color_[i] : element_[_axis].inactive_current_color_[i];
834 axisBottom_->setBottomRadius((1.0 - resize_current_) * manipulator_radius_);
835 axisBottom_->setTopRadius((1.0 + resize_current_) * manipulator_radius_);
836 axisBottom_->addToRenderer(_renderer, _baseRO, manipulator_height_/2.0f);
841 axisCenter_->setBottomRadius(manipulator_radius_);
842 axisCenter_->setTopRadius(manipulator_radius_);
843 axisCenter_->addToRenderer(_renderer, _baseRO, manipulator_height_/2.0f);
849 for (
int i = 0; i < 3; ++i)
850 _baseRO->emissive[i] = _active ? (element_[_axis-3].active_current_color_[i]) : (element_[_axis-3].inactive_current_color_[i]);
853 axisTop_->setBottomRadius(manipulator_radius_*2.0);
854 axisTop_->setTopRadius(0.0);
855 axisTop_->addToRenderer(_renderer, _baseRO, manipulator_height_/2.0f);
862 void TranslationManipulatorNode::addManipulatorToRenderer (
IRenderer* _renderer,
RenderObject* _baseRO,
bool _active)
864 _baseRO->culling =
false;
873 _baseRO->debugName =
"TranslationManipulatorNode.z";
874 addAxisToRenderer(_renderer, _baseRO, _active, ZAxis);
880 _baseRO->debugName =
"TranslationManipulatorNode.y";
882 addAxisToRenderer(_renderer, _baseRO, _active, YAxis);
888 _baseRO->debugName =
"TranslationManipulatorNode.x";
890 addAxisToRenderer(_renderer, _baseRO, _active, XAxis);
896 _baseRO->debugName =
"TranslationManipulatorNode.sphere";
898 for (
int i = 0; i < 3; ++i)
899 _baseRO->emissive[i] = _active ? (element_[Origin].active_current_color_[i]) : (element_[Origin].inactive_current_color_[i]);
901 sphere_->addToRenderer(_renderer, _baseRO, manipulator_radius_ * 2.0f);
910 circle_->setInnerRadius(2.0f*manipulator_height_ - manipulator_height_/4.0f);
911 circle_->setOuterRadius(2.0f*manipulator_height_);
913 if ( activeRotations_ & X_AXIS)
915 _baseRO->
name =
"TranslationManipulatorNode.x_ring";
917 for (
int i = 0; i < 3; ++i)
918 _baseRO->emissive[i] = _active ? (element_[XRing].active_current_color_[i]) : (element_[XRing].inactive_current_color_[i]);
920 circle_->addToRenderer_primitive(_renderer, _baseRO);
925 if ( activeRotations_ & Y_AXIS)
927 _baseRO->debugName =
"TranslationManipulatorNode.y_ring";
929 for (
int i = 0; i < 3; ++i)
930 _baseRO->emissive[i] = _active ? (element_[YRing].active_current_color_[i]) : (element_[YRing].inactive_current_color_[i]);
931 circle_->addToRenderer_primitive(_renderer, _baseRO);
935 if ( activeRotations_ & Z_AXIS)
937 _baseRO->debugName =
"TranslationManipulatorNode.z_ring";
939 for (
int i = 0; i < 3; ++i)
940 _baseRO->emissive[i] = _active ? (element_[ZRing].active_current_color_[i]) : (element_[ZRing].inactive_current_color_[i]);
941 circle_->addToRenderer_primitive(_renderer, _baseRO);
960 if (!draw_manipulator_)
964 Vec2i newPoint2D(_event->pos().x(), _event->pos().y());
967 bool lockOldPoint =
false;
971 switch (_event->type()) {
974 case QEvent::MouseButtonPress: {
975 for (i = 0; i < NumElements; i++)
976 element_[i].clicked_ =
false;
980 draggingOrigin3D_ =
center();
985 if ((mode_ != LocalRotation) && (mode_ != Rotation))
986 element_[Origin].clicked_ =
hitSphere(_state, newPoint2D);
988 element_[Origin].clicked_ =
false;
994 any_axis_clicked_ =
mapToCylinder(_state, newPoint2D, Click);
998 outer_ring_clicked_ =
mapToSphere(_state, newPoint2D, newPoint3D, Click);
1000 outer_ring_clicked_ =
false;
1003 if (element_[Origin].clicked_) {
1004 for (i = 1; i < NumElements; i++)
1005 element_[i].clicked_ =
false;
1006 any_axis_clicked_ =
false;
1007 any_top_clicked_ =
false;
1008 outer_ring_clicked_ =
false;
1009 }
else if (any_top_clicked_) {
1010 for (i = XAxis; i < NumElements; i++)
1011 element_[i].clicked_ =
false;
1012 any_axis_clicked_ =
false;
1013 outer_ring_clicked_ =
false;
1014 }
else if (any_axis_clicked_) {
1015 for (i = XRing; i < NumElements; i++)
1016 element_[i].clicked_ =
false;
1017 outer_ring_clicked_ =
false;
1018 }
else if (outer_ring_clicked_) {
1019 for (i = 0; i < XRing; i++)
1020 element_[i].clicked_ =
false;
1021 any_axis_clicked_ =
false;
1022 any_top_clicked_ =
false;
1026 if ( (_event->modifiers() & Qt::ControlModifier) && (_event->modifiers() & Qt::AltModifier) ) {
1030 oldPoint2D_ = newPoint2D;
1031 currentScale_ =
Vec3d(1.0, 1.0, 1.0);
1034 touched_ = element_[Origin].clicked_
1036 || any_axis_clicked_
1037 || outer_ring_clicked_;
1042 case QEvent::MouseButtonRelease: {
1044 for (i = 0; i < NumElements; i++) {
1045 if (element_[i].clicked_)
1047 element_[i].clicked_ =
false;
1052 || any_axis_clicked_
1053 || outer_ring_clicked_;
1055 any_axis_clicked_ =
false;
1056 any_top_clicked_ =
false;
1057 outer_ring_clicked_ =
false;
1063 case QEvent::MouseButtonDblClick: {
1064 draw_manipulator_ = !draw_manipulator_;
1069 case QEvent::MouseMove: {
1070 if (!draw_manipulator_) {
1076 Qt::KeyboardModifiers mods = Qt::ShiftModifier | Qt::ControlModifier;
1078 for (i = 0; i < NumElements; i++)
1079 element_[i].over_ =
false;
1080 any_axis_over_ =
false;
1081 any_top_over_ =
false;
1082 outer_ring_over_ =
false;
1084 if (!(element_[Origin].clicked_ || any_top_clicked_ || any_axis_clicked_ || outer_ring_clicked_)) {
1086 if ((mode_ != LocalRotation) && (mode_ != Rotation))
1087 element_[Origin].over_ =
hitSphere(_state, newPoint2D);
1089 element_[Origin].over_ =
false;
1093 if (mode_ != Place) {
1098 if (mode_ != Place) {
1103 if (mode_ != Resize) {
1104 outer_ring_over_ =
mapToSphere(_state, newPoint2D, newPoint3D, Over);
1106 outer_ring_over_ =
false;
1110 if (element_[Origin].over_) {
1111 for (i = 1; i < NumElements; i++)
1112 element_[i].over_ =
false;
1113 any_axis_over_ =
false;
1114 any_top_over_ =
false;
1115 outer_ring_over_ =
false;
1116 }
else if (any_top_over_) {
1117 for (i = XAxis; i < NumElements; i++)
1118 element_[i].over_ =
false;
1119 any_axis_over_ =
false;
1120 outer_ring_over_ =
false;
1121 }
else if (any_axis_over_) {
1122 for (i = XRing; i < NumElements; i++)
1123 element_[i].over_ =
false;
1124 outer_ring_over_ =
false;
1125 }
else if (outer_ring_over_) {
1126 for (i = 0; i < XRing; i++)
1127 element_[i].over_ =
false;
1128 any_axis_over_ =
false;
1129 any_top_over_ =
false;
1134 bool rot[3], trans[3];
1137 for (i = 0; i < 3; i++) {
1138 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_;
1142 case TranslationRotation:
1143 for (i = 0; i < 3; i++) {
1144 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_;
1145 trans[i] = element_[XAxis + i].clicked_;
1149 for (i = 0; i < 3; i++) {
1150 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_ || element_[XAxis + i].clicked_;
1157 for (i = 0; i < 3; i++) {
1159 trans[i] = element_[XTop + i].clicked_ || element_[XAxis + i].clicked_;
1165 if (element_[Origin].clicked_) {
1174 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1175 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1176 && (_event->modifiers() & Qt::AltModifier) ) {
1177 newPoint2D = oldPoint2D_;
1179 if (mode_ != Resize) {
1187 Vec3d ntrans = newvec - oldvec;
1189 if (mode_ != Resize)
1193 scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1194 double positive = -1;
1195 if (newPoint2D[0] - oldPoint2D_[0] + oldPoint2D_[1] - newPoint2D[1] > 0)
1198 Vec2d div =
Vec2d(newPoint2D[0], newPoint2D[1]) -
Vec2d(oldPoint2D_[0], oldPoint2D_[1]);
1201 scaleValue *= positive;
1202 currentScale_ +=
Vec3d(scaleValue, scaleValue, scaleValue);
1204 scale(currentScale_);
1226 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1227 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1228 && (_event->modifiers() & Qt::AltModifier) ) {
1229 newPoint2D = oldPoint2D_;
1231 if (mode_ != Resize) {
1237 Vec3d ntrans = newvec - oldvec;
1242 if (mode_ == Resize) {
1244 double positive = -1;
1248 if (currentScale_[0] < 0)
1256 scaleValue *= positive;
1263 m.
scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1268 currentScale_ +=
Vec3d(scaleValue, 0.0, 0.0);
1270 m = localTransformation_;
1271 m.
scale(currentScale_);
1298 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1299 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1300 && (_event->modifiers() & Qt::AltModifier) ) {
1301 newPoint2D = oldPoint2D_;
1303 if (mode_ != Resize) {
1309 Vec3d ntrans = newvec - oldvec;
1314 if (mode_ == Resize) {
1316 double positive = -1;
1320 if (currentScale_[1] < 0)
1328 scaleValue *= positive;
1335 m.
scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1340 currentScale_ +=
Vec3d(0.0, scaleValue, 0.0);
1342 m = localTransformation_;
1343 m.
scale(currentScale_);
1371 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1372 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1373 && (_event->modifiers() & Qt::AltModifier) ) {
1374 newPoint2D = oldPoint2D_;
1376 if (mode_ != Resize) {
1382 Vec3d ntrans = newvec - oldvec;
1387 if (mode_ == Resize) {
1389 double positive = -1;
1393 if (currentScale_[2] < 0)
1401 scaleValue *= positive;
1408 m.
scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1413 currentScale_ +=
Vec3d(0.0, 0.0, scaleValue);
1415 m = localTransformation_;
1416 m.
scale(currentScale_);
1429 if (rot[0] && (activeRotations_ & X_AXIS)) {
1434 Vec2i dist = oldPoint2D_ - newPoint2D;
1438 if (_event->modifiers() == mods) {
1441 lockOldPoint =
true;
1456 if (mode_ == LocalRotation) {
1477 if (rot[1] && (activeRotations_ & Y_AXIS)) {
1482 Vec2i dist = oldPoint2D_ - newPoint2D;
1486 if (_event->modifiers() == mods) {
1489 lockOldPoint =
true;
1502 if (mode_ == LocalRotation) {
1520 if (rot[2] && (activeRotations_ & Z_AXIS)) {
1525 Vec2i dist = oldPoint2D_ - newPoint2D;
1530 if (_event->modifiers() == mods) {
1533 lockOldPoint =
true;
1543 rotation = -dist[1];
1546 if (mode_ == LocalRotation) {
1574 oldPoint2D_ = newPoint2D;
1585 unsigned int x = _v2[0];
1590 Vec3d origin, direction;
1596 _state.
scale(2*manipulator_radius_);
1607 double a = direction.
sqrnorm(),
1608 b = 2.0 * (origin | direction),
1625 unsigned int x = _v2[0];
1630 Vec3d origin, direction;
1636 _state.
scale(manipulator_height_+4*manipulator_radius_);
1646 double a = direction.
sqrnorm(),
1647 b = 2.0 * (origin | direction),
1663 StateUpdates _updateStates )
1666 unsigned int x = _v1[0];
1684 _state.
rotate(-90, 1.0, 0.0, 0.0);
1688 _state.
rotate(90, 0.0, 1.0, 0.0);
1700 const Vec3d origin2(0,0,0),
1701 cylinderAxis(0.0, 0.0, 1.0);
1705 Vec3d normalX = (directionX % cylinderAxis).normalize();
1706 Vec3d vdX = ((origin2 - originX) % directionX);
1707 double axis_hitX = (normalX | vdX);
1708 double orthodistanceX = std::abs( ( origin2 - originX ) | normalX);
1711 Vec3d normalY = (directionY % cylinderAxis).normalize();
1712 Vec3d vdY = ((origin2 - originY) % directionY);
1713 double axis_hitY = (normalY | vdY);
1714 double orthodistanceY = std::abs( ( origin2 - originY ) | normalY);
1717 Vec3d normalZ = (directionZ % cylinderAxis).normalize();
1718 Vec3d vdZ = ((origin2 - originZ) % directionZ);
1719 double axis_hitZ = (normalZ | vdZ);
1720 double orthodistanceZ = std::abs( ( origin2 - originZ ) | normalZ);
1722 if ( _updateStates == None )
1725 if ( ( orthodistanceX < manipulator_radius_ ) &&
1726 ( axis_hitX >= 0 ) &&
1727 ( axis_hitX <= manipulator_height_ ) )
1731 if ( _updateStates == Click)
1732 element_[XAxis].clicked_ =
true;
1734 element_[XAxis].over_ =
true;
1736 }
else if ( ( orthodistanceY < manipulator_radius_ ) &&
1737 ( axis_hitY >= 0 ) &&
1738 ( axis_hitY <= manipulator_height_))
1742 if ( _updateStates == Click)
1743 element_[YAxis].clicked_ =
true;
1745 element_[YAxis].over_ =
true;
1747 }
else if ( ( orthodistanceZ < manipulator_radius_ ) &&
1748 ( axis_hitZ >= 0 ) &&
1749 ( axis_hitZ <= manipulator_height_ ) )
1752 if ( _updateStates == Click)
1753 element_[ZAxis].clicked_ =
true;
1755 element_[ZAxis].over_ =
true;
1759 if ( _updateStates == Click)
1760 return (element_[XAxis].clicked_ || element_[YAxis].clicked_ || element_[ZAxis].clicked_);
1762 return (element_[XAxis].over_ || element_[YAxis].over_ || element_[ZAxis].over_);
1774 StateUpdates _updateStates )
1777 unsigned int x = _v1[0];
1791 _state.
translate( 0.0, 0.0, manipulator_height_);
1793 _state.
translate( 0.0, 0.0, -manipulator_height_);
1796 _state.
rotate(-90, 1.0, 0.0, 0.0);
1797 _state.
translate(0.0, 0.0 , manipulator_height_ );
1799 _state.
translate(0.0, 0.0, -manipulator_height_);
1802 _state.
rotate(90, 0.0, 1.0, 0.0);
1803 _state.
translate(0.0, 0.0, manipulator_height_);
1805 _state.
translate(0.0, 0.0, -manipulator_height_);
1816 const Vec3d origin2(0,0,0),
1817 cylinderAxis(0.0, 0.0, 1.0);
1820 Vec3d normalX = (directionX % cylinderAxis).normalize();
1821 Vec3d vdX = ((origin2 - originX) % directionX );
1822 double axis_hitX = (normalX | vdX);
1823 double orthodistanceX = std::abs( ( origin2 - originX ) | normalX);
1826 Vec3d normalY = (directionY % cylinderAxis).normalize();
1827 Vec3d vdY = ((origin2 - originY) % directionY);
1828 double axis_hitY = (normalY | vdY);
1829 double orthodistanceY = std::abs( ( origin2 - originY ) | normalY);
1832 Vec3d normalZ = (directionZ % cylinderAxis).normalize();
1833 Vec3d vdZ = ((origin2 - originZ) % directionZ);
1834 double axis_hitZ = (normalZ | vdZ);
1835 double orthodistanceZ = std::abs( ( origin2 - originZ ) | normalZ);
1837 if ( _updateStates == None )
1842 if ( ( orthodistanceX < manipulator_radius_ * 2.0 ) &&
1843 ( axis_hitX >= 0.0 ) &&
1844 ( axis_hitX <= manipulator_height_ / 2.0 ) )
1848 if ( _updateStates == Click)
1849 element_[XTop].clicked_ =
true;
1851 element_[XTop].over_ =
true;
1853 }
else if ( ( orthodistanceY < manipulator_radius_ * 2.0 ) &&
1854 ( axis_hitY >= 0.0 ) &&
1855 ( axis_hitY <= manipulator_height_ / 2.0 ) )
1859 if ( _updateStates == Click)
1860 element_[YTop].clicked_ =
true;
1862 element_[YTop].over_ =
true;
1864 }
else if ( ( orthodistanceZ < manipulator_radius_ * 2.0 ) &&
1865 ( axis_hitZ >= 0.0 ) &&
1866 ( axis_hitZ <= manipulator_height_ / 2.0 ) )
1870 if ( _updateStates == Click)
1871 element_[ZTop].clicked_ =
true;
1873 element_[ZTop].over_ =
true;
1877 if ( _updateStates == Click)
1878 return (element_[XTop].clicked_ || element_[YTop].clicked_ || element_[ZTop].clicked_);
1879 return (element_[XTop].over_ || element_[YTop].over_ || element_[ZTop].over_);
1891 StateUpdates _updateStates)
1894 unsigned int x = _v2[0];
1898 Vec3d originXY, directionXY,
1899 originYZ, directionYZ,
1900 originZX, directionZX;
1908 _state.
rotate(90, 0.0, 1.0, 0.0);
1910 _state.
rotate(90, 1.0, 0.0, 0.0);
1918 double t1 = -originXY[2]/directionXY[2];
1919 Vec3d hitPointXY = originXY + directionXY*t1;
1921 double t2 = -originYZ[2]/directionYZ[2];
1922 Vec3d hitPointYZ = originYZ + directionYZ*t2;
1924 double t3 = -originZX[2]/directionZX[2];
1925 Vec3d hitPointZX = originZX + directionZX*t3;
1928 bool t1_near =
false, t2_near =
false, t3_near =
false;
1929 if( t1 <= t2 && t1 <= t3)
1931 if( t2 <= t1 && t2 <= t3)
1933 if( t3 <= t1 && t3 <= t2)
1936 bool xy_hit = hitPointXY.
length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
1937 hitPointXY.
length() < 2*manipulator_height_;
1939 bool yz_hit = hitPointYZ.
length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
1940 hitPointYZ.
length() < 2*manipulator_height_;
1942 bool zx_hit = hitPointZX.
length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
1943 hitPointZX.
length() < 2*manipulator_height_;
1946 bool more_than_one_hit = (xy_hit && yz_hit) || (xy_hit && zx_hit) || (yz_hit && zx_hit);
1958 if(xy_hit && (!more_than_one_hit || t1_near))
1961 if ( _updateStates == Click)
1962 element_[ZRing].clicked_ =
true;
1963 else if ( _updateStates == Over)
1964 element_[ZRing].over_ =
true;
1969 else if(yz_hit && (!more_than_one_hit || t2_near))
1972 if ( _updateStates == Click)
1973 element_[XRing].clicked_ =
true;
1974 else if ( _updateStates == Over)
1975 element_[XRing].over_ =
true;
1980 else if(zx_hit && (!more_than_one_hit || t3_near))
1983 if ( _updateStates == Click)
1984 element_[YRing].clicked_ =
true;
1985 else if ( _updateStates == Over)
1986 element_[YRing].over_ =
true;
2005 if (draw_manipulator_) {
2007 updateSize (_state);
2012 if(_state.compatibilityProfile())
2013 glPushAttrib(GL_DEPTH_BUFFER_BIT);
2014 GLboolean depthTest;
2015 glGetBooleanv(GL_DEPTH_TEST, &depthTest);
2031 axisBottom_->setBottomRadius(manipulator_radius_);
2032 axisBottom_->setTopRadius(manipulator_radius_);
2033 axisBottom_->draw(_state, manipulator_height_);
2036 _state.
translate(0.0, 0.0, manipulator_height_);
2037 axisTop_->setBottomRadius(manipulator_radius_*2.0);
2038 axisTop_->setTopRadius(manipulator_radius_*2.0);
2039 axisTop_->draw(_state, manipulator_height_/2.0);
2040 _state.
translate(0.0, 0.0, -manipulator_height_);
2046 _state.
rotate(-90, 1.0, 0.0, 0.0);
2047 axisBottom_->setBottomRadius(manipulator_radius_);
2048 axisBottom_->setTopRadius(manipulator_radius_);
2049 axisBottom_->draw(_state, manipulator_height_);
2052 _state.
translate(0.0, 0.0, manipulator_height_);
2053 axisTop_->setBottomRadius(manipulator_radius_*2.0);
2054 axisTop_->setTopRadius(manipulator_radius_*2.0);
2055 axisTop_->draw(_state, manipulator_height_/2.0);
2056 _state.
translate(0.0, 0.0, -manipulator_height_);
2063 _state.
rotate(90, 0.0, 1.0, 0.0);
2065 axisBottom_->setBottomRadius(manipulator_radius_);
2066 axisBottom_->setTopRadius(manipulator_radius_);
2067 axisBottom_->draw(_state, manipulator_height_);
2070 _state.
translate(0.0, 0.0, manipulator_height_);
2071 axisTop_->setBottomRadius(manipulator_radius_*2.0);
2072 axisTop_->setTopRadius(manipulator_radius_*2.0);
2073 axisTop_->draw(_state, manipulator_height_/2.0);
2075 _state.
translate(0.0, 0.0, -manipulator_height_);
2082 sphere_->draw(_state, manipulator_radius_*2);
2089 circle_->setInnerRadius(2.0f*manipulator_height_ - manipulator_height_/4.0f);
2090 circle_->setOuterRadius(2.0f*manipulator_height_);
2091 if ( activeRotations_ & X_AXIS)
2092 circle_->draw(_state);
2094 _state.
rotate(90, 0.0, 1.0, 0.0);
2095 if ( activeRotations_ & Y_AXIS)
2096 circle_->draw(_state);
2098 _state.
rotate(90, 1.0, 0.0, 0.0);
2099 if ( activeRotations_ & Z_AXIS)
2100 circle_->draw(_state);
2103 if(_state.compatibilityProfile())
2124 const Vec3d cross = _directionX % _directionY;
2126 localTransformation_(0,0) = _directionX[0];
2127 localTransformation_(1,0) = _directionX[1];
2128 localTransformation_(2,0) = _directionX[2];
2129 localTransformation_(3,0) = 0.0;
2131 localTransformation_(0,1) = _directionY[0];
2132 localTransformation_(1,1) = _directionY[1];
2133 localTransformation_(2,1) = _directionY[2];
2134 localTransformation_(3,1) = 0.0;
2136 localTransformation_(0,2) = cross[0];
2137 localTransformation_(1,2) = cross[1];
2138 localTransformation_(2,2) = cross[2];
2139 localTransformation_(3,2) = 0.0;
2156 direction =
Vec3d(0.0,0.0,0.0);
2172 direction =
Vec3d(0.0,0.0,0.0);
2188 direction =
Vec3d(0.0,0.0,0.0);
2195 double TranslationManipulatorNode::get_screen_length (
GLState& _state,
Vec3d& _point)
const 2206 void TranslationManipulatorNode::updateSize (
GLState& _state)
2208 if (auto_size_ != TranslationManipulatorNode::Never)
2212 int tmp, width, height;
2216 auto_size_length_ = get_screen_length (_state, point) * (width + height) * 0.02;
2218 if (auto_size_ == TranslationManipulatorNode::Once)
2219 auto_size_ = TranslationManipulatorNode::Never;
2222 manipulator_radius_ = set_manipulator_radius_ * auto_size_length_;
2223 manipulator_height_ = set_manipulator_height_ * auto_size_length_;
2231 if (!draw_manipulator_)
2234 float r = 2 * manipulator_height_;
bool mapToCylinder(GLState &_state, const Vec2i &_v2, StateUpdates _updateStates=None)
Vec3d directionZ() const
Get current direction of z-Axis in world coordinates.
bool invert()
matrix inversion (returns true on success)
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
const Vec4f & specular_color() const
get specular color
Namespace providing different geometric functions concerning angles.
void clearTextures()
disables texture support and removes all texture types
const GLMatrixd & inverse_scale() const
return inverse scale matrix
void pick(GLState &_state, PickTarget _target)
leave node
void translate(const Vec3d &_v)
Add a translation to the current Transformation.
void update_rotation(GLState &_state)
update the internal rotation matrix ( internal rotation may be changed without modifiing children of ...
void set_specular_color(const Vec4f &_col)
set specular color
void set_ambient_color(const Vec4f &_col)
set ambient color
pick any of the prior targets (should be implemented for all nodes)
int context_width() const
get gl context width
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
void set_diffuse_color(const Vec4f &_col)
set diffuse color
decltype(std::declval< S >() *std::declval< S >()) sqrnorm() const
compute squared euclidean norm
void push_modelview_matrix()
push modelview matrix
void set_updateGL(bool _b)
should GL matrices be updated after each matrix operation
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
int context_height() const
get gl context height
const GLMatrixd & scale() const
return scale matrix
virtual void mouseEvent(GLState &_state, QMouseEvent *_event)
get mouse events
ManipulatorMode
enum to define the manipulator mode
VectorT< float, 4 > Vec4f
void set_color(const Vec4f &_col)
set color
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
int viewport_width() const
get viewport width
void setMode(ManipulatorMode _mode)
set current operation mode
GLMatrixd modelview
Modelview transform.
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
Interface class between scenegraph and renderer.
~TranslationManipulatorNode()
Destructor.
GLMatrixd computeWorldMatrix()
computes world matrix, transforms from model to world space
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
VectorT< double, 2 > Vec2d
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
bounding box of node
const GLMatrixd & inverse_rotation() const
return inverse rotation matrix
void set_direction(const Vec3d &_directionX, const Vec3d &_directionY)
Set direction in world coordinates.
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
void mult_matrix(const GLMatrixd &_m, const GLMatrixd &_inv_m, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply by a given transformation matrix
void setDirty(bool _dirty=true)
mark node for redrawn
VectorT< double, 3 > Vec3d
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
virtual void setIdentity()
void setTraverseMode(unsigned int _mode)
Set traverse mode for node.
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Vec3d directionY() const
Get current direction of y-Axis in world coordinates.
int viewport_height() const
get viewport height
Execute action the children first and then on this node.
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
TranslationManipulatorNode(BaseNode *_parent=0, const std::string &_name="<TranslationTranslationManipulatorNode>")
Default constructor.
bool touched_
stores if this manipulator was used in order to avoid emitting manipulatorMoved unnecessarily ...
bool hitSphere(GLState &_state, const Vec2i &_v2)
Determine whether the origin sphere has been hit.
void viewing_ray(int _x, int _y, Vec3d &_origin, Vec3d &_direction) const
const GLMatrixd & rotation() const
return rotation matrix
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat)
create renderobjects for shaderpipeline renderer
auto length() const -> decltype(std::declval< VectorT< S, DIM >>().norm())
compute squared euclidean norm
const GLMatrixd & modelview() const
get modelview matrix
ShaderGenDesc shaderDesc
Drawmode and other shader params.
bool is_zero(const T &_a, Real _eps)
PickTarget
What target to use for picking.
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
std::string name
Name for logging.
void pop_modelview_matrix()
pop modelview matrix
void identity()
setup an identity matrix
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
draw the cylinder (if enabled)
void scale(double _s)
scale by (_s, _s, _s)
picks faces (should be implemented for all nodes)
void update_manipulator_system(GLState &_state)
set the current state to follow manipulator transformation
bool mapToSphere(GLState &_state, const Vec2i &_v2, Vec3d &_v3, StateUpdates _updateStates=None)
void set_modelview(const GLMatrixd &_m)
set modelview
virtual void setIdentity()
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
const Vec4f & diffuse_color() const
get diffuse color
GLenum blendDest
glBlendFunc: GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ONE_MINUS_SRC_ALPHA ...
bool mapToCylinderTop(GLState &_state, const Vec2i &_v2, StateUpdates _updateStates=None)
unsigned int msSinceLastRedraw() const
time passed since last redraw in milliseconds
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
const Vec3d & center() const
get center
bool hitOuterSphere(GLState &_state, const Vec2i &_v2)
Determine whether the outer sphere has been hit by the cursor.
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
int priority
Priority to allow sorting of objects.
Vec3d directionX() const
Get current direction of x-Axis in world coordinates.