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;
1077 Qt::KeyboardModifier alt = Qt::AltModifier;
1079 for (i = 0; i < NumElements; i++)
1080 element_[i].over_ =
false;
1081 any_axis_over_ =
false;
1082 any_top_over_ =
false;
1083 outer_ring_over_ =
false;
1085 if (!(element_[Origin].clicked_ || any_top_clicked_ || any_axis_clicked_ || outer_ring_clicked_)) {
1087 if ((mode_ != LocalRotation) && (mode_ != Rotation))
1088 element_[Origin].over_ =
hitSphere(_state, newPoint2D);
1090 element_[Origin].over_ =
false;
1094 if (mode_ != Place) {
1099 if (mode_ != Place) {
1104 if (mode_ != Resize) {
1105 outer_ring_over_ =
mapToSphere(_state, newPoint2D, newPoint3D, Over);
1107 outer_ring_over_ =
false;
1111 if (element_[Origin].over_) {
1112 for (i = 1; i < NumElements; i++)
1113 element_[i].over_ =
false;
1114 any_axis_over_ =
false;
1115 any_top_over_ =
false;
1116 outer_ring_over_ =
false;
1117 }
else if (any_top_over_) {
1118 for (i = XAxis; i < NumElements; i++)
1119 element_[i].over_ =
false;
1120 any_axis_over_ =
false;
1121 outer_ring_over_ =
false;
1122 }
else if (any_axis_over_) {
1123 for (i = XRing; i < NumElements; i++)
1124 element_[i].over_ =
false;
1125 outer_ring_over_ =
false;
1126 }
else if (outer_ring_over_) {
1127 for (i = 0; i < XRing; i++)
1128 element_[i].over_ =
false;
1129 any_axis_over_ =
false;
1130 any_top_over_ =
false;
1135 bool rot[3], trans[3];
1138 for (i = 0; i < 3; i++) {
1139 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_;
1143 case TranslationRotation:
1144 for (i = 0; i < 3; i++) {
1145 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_;
1146 trans[i] = element_[XAxis + i].clicked_;
1150 for (i = 0; i < 3; i++) {
1151 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_ || element_[XAxis + i].clicked_;
1158 for (i = 0; i < 3; i++) {
1160 trans[i] = element_[XTop + i].clicked_ || element_[XAxis + i].clicked_;
1166 if (element_[Origin].clicked_) {
1175 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1176 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1177 && (_event->modifiers() & Qt::AltModifier) ) {
1178 newPoint2D = oldPoint2D_;
1180 if (mode_ != Resize) {
1188 Vec3d ntrans = newvec - oldvec;
1190 if (mode_ != Resize)
1194 scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1195 double positive = -1;
1196 if (newPoint2D[0] - oldPoint2D_[0] + oldPoint2D_[1] - newPoint2D[1] > 0)
1199 Vec2d div =
Vec2d(newPoint2D[0], newPoint2D[1]) -
Vec2d(oldPoint2D_[0], oldPoint2D_[1]);
1202 scaleValue *= positive;
1203 currentScale_ +=
Vec3d(scaleValue, scaleValue, scaleValue);
1205 scale(currentScale_);
1227 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1228 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1229 && (_event->modifiers() & Qt::AltModifier) ) {
1230 newPoint2D = oldPoint2D_;
1232 if (mode_ != Resize) {
1238 Vec3d ntrans = newvec - oldvec;
1243 if (mode_ == Resize) {
1245 double positive = -1;
1249 if (currentScale_[0] < 0)
1257 scaleValue *= positive;
1264 m.
scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1269 currentScale_ +=
Vec3d(scaleValue, 0.0, 0.0);
1271 m = localTransformation_;
1272 m.
scale(currentScale_);
1299 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1300 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1301 && (_event->modifiers() & Qt::AltModifier) ) {
1302 newPoint2D = oldPoint2D_;
1304 if (mode_ != Resize) {
1310 Vec3d ntrans = newvec - oldvec;
1315 if (mode_ == Resize) {
1317 double positive = -1;
1321 if (currentScale_[1] < 0)
1329 scaleValue *= positive;
1336 m.
scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1341 currentScale_ +=
Vec3d(0.0, scaleValue, 0.0);
1343 m = localTransformation_;
1344 m.
scale(currentScale_);
1372 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1373 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1374 && (_event->modifiers() & Qt::AltModifier) ) {
1375 newPoint2D = oldPoint2D_;
1377 if (mode_ != Resize) {
1383 Vec3d ntrans = newvec - oldvec;
1388 if (mode_ == Resize) {
1390 double positive = -1;
1394 if (currentScale_[2] < 0)
1402 scaleValue *= positive;
1409 m.
scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1414 currentScale_ +=
Vec3d(0.0, 0.0, scaleValue);
1416 m = localTransformation_;
1417 m.
scale(currentScale_);
1430 if (rot[0] && (activeRotations_ & X_AXIS)) {
1435 Vec2i dist = oldPoint2D_ - newPoint2D;
1439 if (_event->modifiers() == mods) {
1440 if (abs(dist[1]) <
static_cast<int>(_state.
viewport_height() / 16.f)) {
1442 lockOldPoint =
true;
1450 }
else if (_event->modifiers() == alt) {
1451 if (abs(dist[1]) <
static_cast<int>(_state.
viewport_height() / 16.f)) {
1453 lockOldPoint =
true;
1467 if (mode_ == LocalRotation) {
1488 if (rot[1] && (activeRotations_ & Y_AXIS)) {
1493 Vec2i dist = oldPoint2D_ - newPoint2D;
1497 if (_event->modifiers() == mods) {
1498 if (abs(dist[1]) <
static_cast<int>(_state.
viewport_width() / 16.f)) {
1500 lockOldPoint =
true;
1508 }
else if (_event->modifiers() == alt) {
1509 if (abs(dist[1]) <
static_cast<int>(_state.
viewport_width() / 16.f)) {
1511 lockOldPoint =
true;
1523 if (mode_ == LocalRotation) {
1541 if (rot[2] && (activeRotations_ & Z_AXIS)) {
1546 Vec2i dist = oldPoint2D_ - newPoint2D;
1551 if (_event->modifiers() == mods) {
1552 if (abs(dist[1]) <
static_cast<int>(_state.
viewport_width() / 16.f)) {
1554 lockOldPoint =
true;
1562 }
else if (_event->modifiers() == alt) {
1563 if (abs(dist[1]) <
static_cast<int>(_state.
viewport_width() / 16.f)) {
1565 lockOldPoint =
true;
1574 rotation = -dist[1];
1577 if (mode_ == LocalRotation) {
1605 oldPoint2D_ = newPoint2D;
1616 unsigned int x = _v2[0];
1621 Vec3d origin, direction;
1627 _state.
scale(2*manipulator_radius_);
1638 double a = direction.
sqrnorm(),
1639 b = 2.0 * (origin | direction),
1656 unsigned int x = _v2[0];
1661 Vec3d origin, direction;
1667 _state.
scale(manipulator_height_+4*manipulator_radius_);
1677 double a = direction.
sqrnorm(),
1678 b = 2.0 * (origin | direction),
1694 StateUpdates _updateStates )
1697 unsigned int x = _v1[0];
1715 _state.
rotate(-90, 1.0, 0.0, 0.0);
1719 _state.
rotate(90, 0.0, 1.0, 0.0);
1731 const Vec3d origin2(0,0,0),
1732 cylinderAxis(0.0, 0.0, 1.0);
1736 Vec3d normalX = (directionX % cylinderAxis).normalize();
1737 Vec3d vdX = ((origin2 - originX) % directionX);
1738 double axis_hitX = (normalX | vdX);
1739 double orthodistanceX = std::abs( ( origin2 - originX ) | normalX);
1742 Vec3d normalY = (directionY % cylinderAxis).normalize();
1743 Vec3d vdY = ((origin2 - originY) % directionY);
1744 double axis_hitY = (normalY | vdY);
1745 double orthodistanceY = std::abs( ( origin2 - originY ) | normalY);
1748 Vec3d normalZ = (directionZ % cylinderAxis).normalize();
1749 Vec3d vdZ = ((origin2 - originZ) % directionZ);
1750 double axis_hitZ = (normalZ | vdZ);
1751 double orthodistanceZ = std::abs( ( origin2 - originZ ) | normalZ);
1753 if ( _updateStates == None )
1756 if ( ( orthodistanceX < manipulator_radius_ ) &&
1757 ( axis_hitX >= 0 ) &&
1758 ( axis_hitX <= manipulator_height_ ) )
1762 if ( _updateStates == Click)
1763 element_[XAxis].clicked_ =
true;
1765 element_[XAxis].over_ =
true;
1767 }
else if ( ( orthodistanceY < manipulator_radius_ ) &&
1768 ( axis_hitY >= 0 ) &&
1769 ( axis_hitY <= manipulator_height_))
1773 if ( _updateStates == Click)
1774 element_[YAxis].clicked_ =
true;
1776 element_[YAxis].over_ =
true;
1778 }
else if ( ( orthodistanceZ < manipulator_radius_ ) &&
1779 ( axis_hitZ >= 0 ) &&
1780 ( axis_hitZ <= manipulator_height_ ) )
1783 if ( _updateStates == Click)
1784 element_[ZAxis].clicked_ =
true;
1786 element_[ZAxis].over_ =
true;
1790 if ( _updateStates == Click)
1791 return (element_[XAxis].clicked_ || element_[YAxis].clicked_ || element_[ZAxis].clicked_);
1793 return (element_[XAxis].over_ || element_[YAxis].over_ || element_[ZAxis].over_);
1805 StateUpdates _updateStates )
1808 unsigned int x = _v1[0];
1822 _state.
translate( 0.0, 0.0, manipulator_height_);
1824 _state.
translate( 0.0, 0.0, -manipulator_height_);
1827 _state.
rotate(-90, 1.0, 0.0, 0.0);
1828 _state.
translate(0.0, 0.0 , manipulator_height_ );
1830 _state.
translate(0.0, 0.0, -manipulator_height_);
1833 _state.
rotate(90, 0.0, 1.0, 0.0);
1834 _state.
translate(0.0, 0.0, manipulator_height_);
1836 _state.
translate(0.0, 0.0, -manipulator_height_);
1847 const Vec3d origin2(0,0,0),
1848 cylinderAxis(0.0, 0.0, 1.0);
1851 Vec3d normalX = (directionX % cylinderAxis).normalize();
1852 Vec3d vdX = ((origin2 - originX) % directionX );
1853 double axis_hitX = (normalX | vdX);
1854 double orthodistanceX = std::abs( ( origin2 - originX ) | normalX);
1857 Vec3d normalY = (directionY % cylinderAxis).normalize();
1858 Vec3d vdY = ((origin2 - originY) % directionY);
1859 double axis_hitY = (normalY | vdY);
1860 double orthodistanceY = std::abs( ( origin2 - originY ) | normalY);
1863 Vec3d normalZ = (directionZ % cylinderAxis).normalize();
1864 Vec3d vdZ = ((origin2 - originZ) % directionZ);
1865 double axis_hitZ = (normalZ | vdZ);
1866 double orthodistanceZ = std::abs( ( origin2 - originZ ) | normalZ);
1868 if ( _updateStates == None )
1873 if ( ( orthodistanceX < manipulator_radius_ * 2.0 ) &&
1874 ( axis_hitX >= 0.0 ) &&
1875 ( axis_hitX <= manipulator_height_ / 2.0 ) )
1879 if ( _updateStates == Click)
1880 element_[XTop].clicked_ =
true;
1882 element_[XTop].over_ =
true;
1884 }
else if ( ( orthodistanceY < manipulator_radius_ * 2.0 ) &&
1885 ( axis_hitY >= 0.0 ) &&
1886 ( axis_hitY <= manipulator_height_ / 2.0 ) )
1890 if ( _updateStates == Click)
1891 element_[YTop].clicked_ =
true;
1893 element_[YTop].over_ =
true;
1895 }
else if ( ( orthodistanceZ < manipulator_radius_ * 2.0 ) &&
1896 ( axis_hitZ >= 0.0 ) &&
1897 ( axis_hitZ <= manipulator_height_ / 2.0 ) )
1901 if ( _updateStates == Click)
1902 element_[ZTop].clicked_ =
true;
1904 element_[ZTop].over_ =
true;
1908 if ( _updateStates == Click)
1909 return (element_[XTop].clicked_ || element_[YTop].clicked_ || element_[ZTop].clicked_);
1910 return (element_[XTop].over_ || element_[YTop].over_ || element_[ZTop].over_);
1922 StateUpdates _updateStates)
1925 unsigned int x = _v2[0];
1929 Vec3d originXY, directionXY,
1930 originYZ, directionYZ,
1931 originZX, directionZX;
1939 _state.
rotate(90, 0.0, 1.0, 0.0);
1941 _state.
rotate(90, 1.0, 0.0, 0.0);
1949 double t1 = -originXY[2]/directionXY[2];
1950 Vec3d hitPointXY = originXY + directionXY*t1;
1952 double t2 = -originYZ[2]/directionYZ[2];
1953 Vec3d hitPointYZ = originYZ + directionYZ*t2;
1955 double t3 = -originZX[2]/directionZX[2];
1956 Vec3d hitPointZX = originZX + directionZX*t3;
1959 bool t1_near =
false, t2_near =
false, t3_near =
false;
1960 if( t1 <= t2 && t1 <= t3)
1962 if( t2 <= t1 && t2 <= t3)
1964 if( t3 <= t1 && t3 <= t2)
1967 bool xy_hit = hitPointXY.
length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
1968 hitPointXY.
length() < 2*manipulator_height_;
1970 bool yz_hit = hitPointYZ.
length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
1971 hitPointYZ.
length() < 2*manipulator_height_;
1973 bool zx_hit = hitPointZX.
length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
1974 hitPointZX.
length() < 2*manipulator_height_;
1977 bool more_than_one_hit = (xy_hit && yz_hit) || (xy_hit && zx_hit) || (yz_hit && zx_hit);
1989 if(xy_hit && (!more_than_one_hit || t1_near))
1992 if ( _updateStates == Click)
1993 element_[ZRing].clicked_ =
true;
1994 else if ( _updateStates == Over)
1995 element_[ZRing].over_ =
true;
2000 else if(yz_hit && (!more_than_one_hit || t2_near))
2003 if ( _updateStates == Click)
2004 element_[XRing].clicked_ =
true;
2005 else if ( _updateStates == Over)
2006 element_[XRing].over_ =
true;
2011 else if(zx_hit && (!more_than_one_hit || t3_near))
2014 if ( _updateStates == Click)
2015 element_[YRing].clicked_ =
true;
2016 else if ( _updateStates == Over)
2017 element_[YRing].over_ =
true;
2036 if (draw_manipulator_) {
2038 updateSize (_state);
2043 if(_state.compatibilityProfile())
2044 glPushAttrib(GL_DEPTH_BUFFER_BIT);
2045 GLboolean depthTest;
2046 glGetBooleanv(GL_DEPTH_TEST, &depthTest);
2062 axisBottom_->setBottomRadius(manipulator_radius_);
2063 axisBottom_->setTopRadius(manipulator_radius_);
2064 axisBottom_->draw(_state, manipulator_height_);
2067 _state.
translate(0.0, 0.0, manipulator_height_);
2068 axisTop_->setBottomRadius(manipulator_radius_*2.0);
2069 axisTop_->setTopRadius(manipulator_radius_*2.0);
2070 axisTop_->draw(_state, manipulator_height_/2.0);
2071 _state.
translate(0.0, 0.0, -manipulator_height_);
2077 _state.
rotate(-90, 1.0, 0.0, 0.0);
2078 axisBottom_->setBottomRadius(manipulator_radius_);
2079 axisBottom_->setTopRadius(manipulator_radius_);
2080 axisBottom_->draw(_state, manipulator_height_);
2083 _state.
translate(0.0, 0.0, manipulator_height_);
2084 axisTop_->setBottomRadius(manipulator_radius_*2.0);
2085 axisTop_->setTopRadius(manipulator_radius_*2.0);
2086 axisTop_->draw(_state, manipulator_height_/2.0);
2087 _state.
translate(0.0, 0.0, -manipulator_height_);
2094 _state.
rotate(90, 0.0, 1.0, 0.0);
2096 axisBottom_->setBottomRadius(manipulator_radius_);
2097 axisBottom_->setTopRadius(manipulator_radius_);
2098 axisBottom_->draw(_state, manipulator_height_);
2101 _state.
translate(0.0, 0.0, manipulator_height_);
2102 axisTop_->setBottomRadius(manipulator_radius_*2.0);
2103 axisTop_->setTopRadius(manipulator_radius_*2.0);
2104 axisTop_->draw(_state, manipulator_height_/2.0);
2106 _state.
translate(0.0, 0.0, -manipulator_height_);
2113 sphere_->draw(_state, manipulator_radius_*2);
2120 circle_->setInnerRadius(2.0f*manipulator_height_ - manipulator_height_/4.0f);
2121 circle_->setOuterRadius(2.0f*manipulator_height_);
2122 if ( activeRotations_ & X_AXIS)
2123 circle_->draw(_state);
2125 _state.
rotate(90, 0.0, 1.0, 0.0);
2126 if ( activeRotations_ & Y_AXIS)
2127 circle_->draw(_state);
2129 _state.
rotate(90, 1.0, 0.0, 0.0);
2130 if ( activeRotations_ & Z_AXIS)
2131 circle_->draw(_state);
2134 if(_state.compatibilityProfile())
2155 const Vec3d cross = _directionX % _directionY;
2157 localTransformation_(0,0) = _directionX[0];
2158 localTransformation_(1,0) = _directionX[1];
2159 localTransformation_(2,0) = _directionX[2];
2160 localTransformation_(3,0) = 0.0;
2162 localTransformation_(0,1) = _directionY[0];
2163 localTransformation_(1,1) = _directionY[1];
2164 localTransformation_(2,1) = _directionY[2];
2165 localTransformation_(3,1) = 0.0;
2167 localTransformation_(0,2) = cross[0];
2168 localTransformation_(1,2) = cross[1];
2169 localTransformation_(2,2) = cross[2];
2170 localTransformation_(3,2) = 0.0;
2187 direction =
Vec3d(0.0,0.0,0.0);
2203 direction =
Vec3d(0.0,0.0,0.0);
2219 direction =
Vec3d(0.0,0.0,0.0);
2226 double TranslationManipulatorNode::get_screen_length (
GLState& _state,
Vec3d& _point)
const 2237 void TranslationManipulatorNode::updateSize (
GLState& _state)
2239 if (auto_size_ != TranslationManipulatorNode::Never)
2243 int tmp, width, height;
2247 auto_size_length_ = get_screen_length (_state, point) * (width + height) * 0.02;
2249 if (auto_size_ == TranslationManipulatorNode::Once)
2250 auto_size_ = TranslationManipulatorNode::Never;
2253 manipulator_radius_ = set_manipulator_radius_ * auto_size_length_;
2254 manipulator_height_ = set_manipulator_height_ * auto_size_length_;
2262 if (!draw_manipulator_)
2265 float r = 2 * manipulator_height_;
Vec3d directionY() const
Get current direction of y-Axis in world coordinates.
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
void pop_modelview_matrix()
pop modelview matrix
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
const Vec4f & specular_color() const
get specular color
void set_diffuse_color(const Vec4f &_col)
set diffuse color
Vec3d directionZ() const
Get current direction of z-Axis in world coordinates.
picks faces (should be implemented for all nodes)
int viewport_width() const
get viewport width
Namespace providing different geometric functions concerning angles.
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax) override
bounding box of node
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
VectorT< float, 4 > Vec4f
void setDirty(bool _dirty=true)
mark node for redrawn
virtual void setIdentity() override
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
bool hitSphere(GLState &_state, const Vec2i &_v2)
Determine whether the origin sphere has been hit.
void clearTextures()
disables texture support and removes all texture types
void identity()
setup an identity matrix
void scale(double _s)
scale by (_s, _s, _s)
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
std::string name
Name for logging.
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
const Vec4f & diffuse_color() const
get diffuse color
void setTraverseMode(unsigned int _mode)
Set traverse mode for node.
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
void mult_matrix(const GLMatrixd &_m, const GLMatrixd &_inv_m, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply by a given transformation matrix
void set_updateGL(bool _b)
should GL matrices be updated after each matrix operation
void set_direction(const Vec3d &_directionX, const Vec3d &_directionY)
Set direction in world coordinates.
PickTarget
What target to use for picking.
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
bool invert()
matrix inversion (returns true on success)
void push_modelview_matrix()
push modelview matrix
void set_modelview(const GLMatrixd &_m)
set modelview
void setMode(ManipulatorMode _mode)
set current operation mode
GLMatrixd computeWorldMatrix()
computes world matrix, transforms from model to world space
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
bool mapToCylinderTop(GLState &_state, const Vec2i &_v2, StateUpdates _updateStates=None)
pick any of the prior targets (should be implemented for all nodes)
void set_ambient_color(const Vec4f &_col)
set ambient color
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
void pick(GLState &_state, PickTarget _target) override
leave node
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
int viewport_height() const
get viewport height
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
void set_specular_color(const Vec4f &_col)
set specular color
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat) override
create renderobjects for shaderpipeline renderer
TranslationManipulatorNode(BaseNode *_parent=0, const std::string &_name="<TranslationTranslationManipulatorNode>")
Default constructor.
bool mapToSphere(GLState &_state, const Vec2i &_v2, Vec3d &_v3, StateUpdates _updateStates=None)
void set_color(const Vec4f &_col)
set color
int priority
Priority to allow sorting of objects.
void viewing_ray(int _x, int _y, Vec3d &_origin, Vec3d &_direction) const
auto length() const -> decltype(std::declval< VectorT< S, DIM >>().norm())
compute squared euclidean norm
void update_rotation(GLState &_state)
update the internal rotation matrix ( internal rotation may be changed without modifiing children of ...
Vec3d directionX() const
Get current direction of x-Axis in world coordinates.
ManipulatorMode
enum to define the manipulator mode
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
bool mapToCylinder(GLState &_state, const Vec2i &_v2, StateUpdates _updateStates=None)
const GLMatrixd & modelview() const
get modelview matrix
decltype(std::declval< S >() *std::declval< S >()) sqrnorm() const
compute squared euclidean norm
virtual void mouseEvent(GLState &_state, QMouseEvent *_event) override
get mouse events
Execute action the children first and then on this node.
int context_height() const
get gl context height
unsigned int msSinceLastRedraw() const
time passed since last redraw in milliseconds
void update_manipulator_system(GLState &_state)
set the current state to follow manipulator transformation
bool touched_
stores if this manipulator was used in order to avoid emitting manipulatorMoved unnecessarily ...
~TranslationManipulatorNode()
Destructor.
GLenum blendDest
glBlendFunc: GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ONE_MINUS_SRC_ALPHA ...
VectorT< double, 2 > Vec2d
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
draw the cylinder (if enabled)
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Interface class between scenegraph and renderer.
bool is_zero(const T &_a, Real _eps)
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
VectorT< double, 3 > Vec3d
int context_width() const
get gl context width
GLMatrixd modelview
Modelview transform.
bool hitOuterSphere(GLState &_state, const Vec2i &_v2)
Determine whether the outer sphere has been hit by the cursor.