63 #include "TranslationManipulatorNode.hh" 65 #include <ACG/GL/IRenderer.hh> 67 #include <Math_Tools/Math_Tools.hh> 80 #define SNAP_PIXEL_TOLERANCE 30 84 const Vec4f colors[4][6] = {
88 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),
90 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)
95 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),
97 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)
102 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),
104 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)
109 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),
111 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)
118 TranslationManipulatorNode::Element::Element () :
119 active_target_color_ (0.0, 0.0, 0.0, 1.0),
120 active_current_color_ (0.0, 0.0, 0.0, 1.0),
121 inactive_target_color_ (0.0, 0.0, 0.0, 1.0),
122 inactive_current_color_ (0.0, 0.0, 0.0, 1.0),
134 draw_manipulator_(false),
143 manipulator_radius_(20.0),
144 manipulator_height_(20),
145 set_manipulator_radius_(1.0),
146 set_manipulator_height_(1.0),
147 manipulator_slices_(10),
148 manipulator_stacks_(10),
149 any_axis_clicked_(false),
150 any_top_clicked_(false),
151 outer_ring_clicked_(false),
152 any_axis_over_(false),
153 any_top_over_(false),
154 outer_ring_over_(false),
155 resize_current_ (0.0),
156 mode_ (TranslationRotation),
160 auto_size_length_(1.0),
161 activeRotations_(ALL_AXIS)
166 axisBottom_ =
new ACG::GLCone(manipulator_slices_, manipulator_stacks_,
167 (1.0 - resize_current_) * manipulator_radius_,
168 (1.0 + resize_current_) * manipulator_radius_,
false,
true);
169 axisCenter_ =
new ACG::GLCone(manipulator_slices_, manipulator_stacks_,
170 (1.0 - resize_current_) * manipulator_radius_,
171 (1.0 + resize_current_) * manipulator_radius_,
false,
true);
172 axisTop_ =
new ACG::GLCone(manipulator_slices_, manipulator_stacks_,
173 (1.0 - resize_current_) * manipulator_radius_,
174 (1.0 + resize_current_) * manipulator_radius_,
false,
true);
176 sphere_ =
new ACG::GLSphere(manipulator_slices_, manipulator_stacks_);
177 circle_ =
new ACG::GLDisk(30, 30, 2.0f*manipulator_height_ - manipulator_height_/4.0f, 2.0f*manipulator_height_);
181 updateTargetColors ();
182 for (
unsigned int i = 0; i < TranslationManipulatorNode::NumElements; i++)
184 element_[i].active_current_color_ = element_[i].active_target_color_;
185 element_[i].inactive_current_color_ = element_[i].inactive_target_color_;
241 glMatrixMode(GL_MODELVIEW);
248 model *= localTransformation_;
257 void TranslationManipulatorNode::updateTargetColors ()
260 element_[Origin].active_target_color_ = colors[0][0];
261 element_[XAxis].active_target_color_ = colors[1][0];
262 element_[YAxis].active_target_color_ = colors[2][0];
263 element_[ZAxis].active_target_color_ = colors[3][0];
264 element_[XTop].active_target_color_ = colors[1][0];
265 element_[YTop].active_target_color_ = colors[2][0];
266 element_[ZTop].active_target_color_ = colors[3][0];
267 element_[XRing].active_target_color_ = colors[1][0];
268 element_[YRing].active_target_color_ = colors[2][0];
269 element_[ZRing].active_target_color_ = colors[3][0];
271 element_[Origin].inactive_target_color_ = colors[0][3];
272 element_[XAxis].inactive_target_color_ = colors[1][3];
273 element_[YAxis].inactive_target_color_ = colors[2][3];
274 element_[ZAxis].inactive_target_color_ = colors[3][3];
275 element_[XTop].inactive_target_color_ = colors[1][3];
276 element_[YTop].inactive_target_color_ = colors[2][3];
277 element_[ZTop].inactive_target_color_ = colors[3][3];
278 element_[XRing].inactive_target_color_ = colors[1][3];
279 element_[YRing].inactive_target_color_ = colors[2][3];
280 element_[ZRing].inactive_target_color_ = colors[3][3];
284 element_[XRing].active_target_color_[3] = 1.0;
285 element_[YRing].active_target_color_[3] = 1.0;
286 element_[ZRing].active_target_color_[3] = 1.0;
289 if (mode_ == Resize || mode_ == Place)
290 for (
unsigned int i = 0; i < 3; i++)
292 element_[XRing + i].active_target_color_[3] = 0.0;
293 element_[XRing + i].inactive_target_color_[3] = 0.0;
297 if(element_[Origin].clicked_){
298 element_[Origin].active_target_color_ = colors[0][2];
299 element_[Origin].inactive_target_color_ = colors[0][5];
300 for (
unsigned int i = 1; i < NumElements - 3; i++)
302 element_[i].active_target_color_ = (colors[0][2] * 0.5) + (colors[((i-1)%3) + 1][2] * 0.5);
303 element_[i].inactive_target_color_ = (colors[0][5] * 0.5) + (colors[((i-1)%3) + 1][5] * 0.5);
306 }
else if(element_[Origin].over_){
307 element_[Origin].active_target_color_ = colors[0][1];
308 element_[Origin].inactive_target_color_ = colors[0][4];
309 for (
unsigned int i = 1; i < NumElements - 3; i++)
311 element_[i].active_target_color_ = (colors[0][1] * 0.5) + (colors[((i-1)%3) + 1][1] * 0.5);
312 element_[i].inactive_target_color_ = (colors[0][4] * 0.5) + (colors[((i-1)%3) + 1][4] * 0.5);
317 for (
unsigned int i = 0; i < 3; i++)
318 if (element_[i + XTop].clicked_)
320 element_[i + XTop].active_target_color_ = colors[i+1][2];
321 element_[i + XTop].inactive_target_color_ = colors[i+1][5];
322 if (mode_ != TranslationRotation)
324 element_[i + XAxis].active_target_color_ = colors[i+1][2];
325 element_[i + XAxis].inactive_target_color_ = colors[i+1][5];
327 if (mode_ != Resize) {
328 element_[i + XRing].active_target_color_ = colors[i+1][2];
329 element_[i + XRing].inactive_target_color_ = colors[i+1][5];
332 }
else if (element_[i + XTop].over_)
334 element_[i + XTop].active_target_color_ = colors[i+1][1];
335 element_[i + XTop].inactive_target_color_ = colors[i+1][4];
336 if (mode_ != TranslationRotation)
338 element_[i + XAxis].active_target_color_ = colors[i+1][1];
339 element_[i + XAxis].inactive_target_color_ = colors[i+1][4];
341 if (mode_ != Resize) {
342 element_[i + XRing].active_target_color_ = colors[i+1][1];
343 element_[i + XRing].inactive_target_color_ = colors[i+1][4];
348 for (
unsigned int i = 0; i < 3; i++)
349 if (element_[i + XAxis].clicked_)
351 element_[i + XTop].active_target_color_ = colors[i+1][2];
352 element_[i + XTop].inactive_target_color_ = colors[i+1][5];
353 element_[i + XAxis].active_target_color_ = colors[i+1][2];
354 element_[i + XAxis].inactive_target_color_ = colors[i+1][5];
355 if (mode_ == LocalRotation) {
356 element_[i + XRing].active_target_color_ = colors[i+1][2];
357 element_[i + XRing].inactive_target_color_ = colors[i+1][5];
360 }
else if (element_[i + XAxis].over_)
362 element_[i + XTop].active_target_color_ = colors[i+1][1];
363 element_[i + XTop].inactive_target_color_ = colors[i+1][4];
364 element_[i + XAxis].active_target_color_ = colors[i+1][1];
365 element_[i + XAxis].inactive_target_color_ = colors[i+1][4];
366 if (mode_ == LocalRotation) {
367 element_[i + XRing].active_target_color_ = colors[i+1][1];
368 element_[i + XRing].inactive_target_color_ = colors[i+1][4];
373 if (mode_ != Resize) {
374 for (
unsigned int i = 0; i < 3; i++) {
375 if (element_[i + XRing].clicked_)
377 element_[i + XRing].active_target_color_ = colors[i+1][2];
378 element_[i + XRing].inactive_target_color_ = colors[i+1][5];
380 }
else if (element_[i + XRing].over_)
382 element_[i + XRing].active_target_color_ = colors[i+1][1];
383 element_[i + XRing].inactive_target_color_ = colors[i+1][4];
393 bool TranslationManipulatorNode::updateCurrentColors (
GLState& _state)
405 for (
unsigned int i = 0; i < NumElements; i++)
407 Vec4f diff = element_[i].active_target_color_ -
408 element_[i].active_current_color_;
410 for (
unsigned int j = 0; j < 4; j++)
413 else if (diff[j] < -value)
416 element_[i].active_current_color_ += diff;
418 diff = element_[i].inactive_target_color_ -
419 element_[i].inactive_current_color_;
421 for (
unsigned int j = 0; j < 4; j++)
424 else if (diff[j] < -value)
427 element_[i].inactive_current_color_ += diff;
429 rv |= element_[i].active_target_color_ != element_[i].active_current_color_ ||
430 element_[i].inactive_target_color_ != element_[i].inactive_current_color_;
433 float diff = ((mode_ == Resize) ? 1.0 : 0.0) - resize_current_;
437 else if (diff < -value)
440 resize_current_ += diff;
441 rv |= resize_current_ != ((mode_ == Resize) ? 1.0 : 0.0);
448 void TranslationManipulatorNode::drawManipulator (
GLState& _state,
bool _active)
450 glPushAttrib(GL_ENABLE_BIT );
491 axisBottom_->setBottomRadius((1.0 - resize_current_) * manipulator_radius_);
492 axisBottom_->setTopRadius((1.0 + resize_current_) * manipulator_radius_);
493 axisBottom_->draw(_state, manipulator_height_/2.0);
496 _state.
translate(0.0, 0.0, manipulator_height_/2);
498 axisCenter_->setBottomRadius(manipulator_radius_);
499 axisCenter_->setTopRadius(manipulator_radius_);
500 axisCenter_->draw(_state, manipulator_height_/2.0);
513 _state.
translate(0.0, 0.0, manipulator_height_/2);
514 axisTop_->setBottomRadius(manipulator_radius_*2.0);
515 axisTop_->setTopRadius(0.0);
516 axisTop_->draw(_state, manipulator_height_/2.0);
517 _state.
translate(0.0, 0.0, -manipulator_height_);
522 _state.
rotate(-90, 1.0, 0.0, 0.0);
533 axisBottom_->setBottomRadius((1.0 - resize_current_) * manipulator_radius_);
534 axisBottom_->setTopRadius((1.0 + resize_current_) * manipulator_radius_);
535 axisBottom_->draw(_state, manipulator_height_/2.0);
538 _state.
translate(0.0, 0.0, manipulator_height_/2);
540 axisCenter_->setBottomRadius(manipulator_radius_);
541 axisCenter_->setTopRadius(manipulator_radius_);
542 axisCenter_->draw(_state, manipulator_height_/2.0);
555 _state.
translate(0.0, 0.0, manipulator_height_/2);
556 axisTop_->setBottomRadius(manipulator_radius_*2.0);
557 axisTop_->setTopRadius(0.0);
558 axisTop_->draw(_state, manipulator_height_/2.0);
559 _state.
translate(0.0, 0.0, -manipulator_height_);
565 _state.
rotate(90, 0.0, 1.0, 0.0);
576 axisBottom_->setBottomRadius((1.0 - resize_current_) * manipulator_radius_);
577 axisBottom_->setTopRadius((1.0 + resize_current_) * manipulator_radius_);
578 axisBottom_->draw(_state, manipulator_height_/2.0);
581 _state.
translate(0.0, 0.0, manipulator_height_/2);
583 axisCenter_->setBottomRadius(manipulator_radius_);
584 axisCenter_->setTopRadius(manipulator_radius_);
585 axisCenter_->draw(_state, manipulator_height_/2.0);
598 _state.
translate(0.0, 0.0, manipulator_height_/2);
599 axisTop_->setBottomRadius(manipulator_radius_*2.0);
600 axisTop_->setTopRadius(0.0);
601 axisTop_->draw(_state, manipulator_height_/2.0);
602 _state.
translate(0.0, 0.0, -manipulator_height_);
616 sphere_->draw(_state, manipulator_radius_*2);
623 glPushAttrib(GL_LIGHTING_BIT);
627 circle_->setInnerRadius(2.0f*manipulator_height_ - manipulator_height_/4.0f);
628 circle_->setOuterRadius(2.0f*manipulator_height_);
630 if ( activeRotations_ & X_AXIS) {
635 _state.
set_color(element_[XRing].active_current_color_);
640 _state.
set_color(element_[XRing].inactive_current_color_);
644 circle_->draw(_state);
648 _state.
rotate(90, 0.0, 1.0, 0.0);
649 if ( activeRotations_ & Y_AXIS) {
654 _state.
set_color(element_[YRing].active_current_color_);
659 _state.
set_color(element_[YRing].inactive_current_color_);
663 circle_->draw(_state);
666 _state.
rotate(90, 1.0, 0.0, 0.0);
667 if ( activeRotations_ & Z_AXIS) {
672 _state.
set_color(element_[ZRing].active_current_color_);
677 _state.
set_color(element_[ZRing].inactive_current_color_);
681 circle_->draw(_state);
699 if (draw_manipulator_) {
702 glPushAttrib(GL_LIGHTING_BIT);
707 glPushAttrib(GL_DEPTH_BUFFER_BIT);
711 glPushAttrib(GL_COLOR_BUFFER_BIT);
713 glPushAttrib(GL_ENABLE_BIT);
723 updateTargetColors ();
724 if (updateCurrentColors (_state))
729 glDepthMask(GL_FALSE);
732 drawManipulator(_state,
false);
736 glDepthMask(GL_TRUE);
737 drawManipulator(_state,
true);
767 world *= localTransformation_;
779 if (draw_manipulator_)
788 updateTargetColors ();
789 if (updateCurrentColors (_state))
806 ro.depthWrite =
false;
809 ro.blendSrc = GL_SRC_ALPHA;
813 addManipulatorToRenderer(_renderer, &ro,
false);
820 ro.depthWrite =
true;
821 addManipulatorToRenderer(_renderer, &ro,
true);
827 void TranslationManipulatorNode::addAxisToRenderer (
IRenderer* _renderer,
RenderObject* _baseRO,
bool _active,
int _axis)
829 assert(_axis >= XAxis && _axis - 3 >= 0 && _axis <= ZAxis);
831 for (
int i = 0; i < 3; ++i)
832 _baseRO->emissive[i] = _active ? element_[_axis].active_current_color_[i] : element_[_axis].inactive_current_color_[i];
835 axisBottom_->setBottomRadius((1.0 - resize_current_) * manipulator_radius_);
836 axisBottom_->setTopRadius((1.0 + resize_current_) * manipulator_radius_);
837 axisBottom_->addToRenderer(_renderer, _baseRO, manipulator_height_/2.0f);
842 axisCenter_->setBottomRadius(manipulator_radius_);
843 axisCenter_->setTopRadius(manipulator_radius_);
844 axisCenter_->addToRenderer(_renderer, _baseRO, manipulator_height_/2.0f);
850 for (
int i = 0; i < 3; ++i)
851 _baseRO->emissive[i] = _active ? (element_[_axis-3].active_current_color_[i]) : (element_[_axis-3].inactive_current_color_[i]);
854 axisTop_->setBottomRadius(manipulator_radius_*2.0);
855 axisTop_->setTopRadius(0.0);
856 axisTop_->addToRenderer(_renderer, _baseRO, manipulator_height_/2.0f);
863 void TranslationManipulatorNode::addManipulatorToRenderer (
IRenderer* _renderer,
RenderObject* _baseRO,
bool _active)
865 _baseRO->culling =
false;
874 addAxisToRenderer(_renderer, _baseRO, _active, ZAxis);
881 addAxisToRenderer(_renderer, _baseRO, _active, YAxis);
888 addAxisToRenderer(_renderer, _baseRO, _active, XAxis);
894 for (
int i = 0; i < 3; ++i)
895 _baseRO->emissive[i] = _active ? (element_[Origin].active_current_color_[i]) : (element_[Origin].inactive_current_color_[i]);
897 sphere_->addToRenderer(_renderer, _baseRO, manipulator_radius_ * 2.0f);
906 circle_->setInnerRadius(2.0f*manipulator_height_ - manipulator_height_/4.0f);
907 circle_->setOuterRadius(2.0f*manipulator_height_);
909 if ( activeRotations_ & X_AXIS)
911 for (
int i = 0; i < 3; ++i)
912 _baseRO->emissive[i] = _active ? (element_[XRing].active_current_color_[i]) : (element_[XRing].inactive_current_color_[i]);
914 circle_->addToRenderer_primitive(_renderer, _baseRO);
919 if ( activeRotations_ & Y_AXIS)
921 for (
int i = 0; i < 3; ++i)
922 _baseRO->emissive[i] = _active ? (element_[YRing].active_current_color_[i]) : (element_[YRing].inactive_current_color_[i]);
923 circle_->addToRenderer_primitive(_renderer, _baseRO);
927 if ( activeRotations_ & Z_AXIS)
929 for (
int i = 0; i < 3; ++i)
930 _baseRO->emissive[i] = _active ? (element_[ZRing].active_current_color_[i]) : (element_[ZRing].inactive_current_color_[i]);
931 circle_->addToRenderer_primitive(_renderer, _baseRO);
950 if (!draw_manipulator_)
954 Vec2i newPoint2D(_event->pos().x(), _event->pos().y());
956 bool rot[3], trans[3];
958 bool lockOldPoint =
false;
962 switch (_event->type()) {
965 case QEvent::MouseButtonPress: {
966 for (i = 0; i < NumElements; i++)
967 element_[i].clicked_ =
false;
971 draggingOrigin3D_ =
center();
976 if ((mode_ != LocalRotation) && (mode_ != Rotation))
977 element_[Origin].clicked_ =
hitSphere(_state, newPoint2D);
979 element_[Origin].clicked_ =
false;
985 any_axis_clicked_ =
mapToCylinder(_state, newPoint2D, Click);
989 outer_ring_clicked_ =
mapToSphere(_state, newPoint2D, newPoint3D, Click);
991 outer_ring_clicked_ =
false;
994 if (element_[Origin].clicked_) {
995 for (i = 1; i < NumElements; i++)
996 element_[i].clicked_ =
false;
997 any_axis_clicked_ =
false;
998 any_top_clicked_ =
false;
999 outer_ring_clicked_ =
false;
1000 }
else if (any_top_clicked_) {
1001 for (i = XAxis; i < NumElements; i++)
1002 element_[i].clicked_ =
false;
1003 any_axis_clicked_ =
false;
1004 outer_ring_clicked_ =
false;
1005 }
else if (any_axis_clicked_) {
1006 for (i = XRing; i < NumElements; i++)
1007 element_[i].clicked_ =
false;
1008 outer_ring_clicked_ =
false;
1009 }
else if (outer_ring_clicked_) {
1010 for (i = 0; i < XRing; i++)
1011 element_[i].clicked_ =
false;
1012 any_axis_clicked_ =
false;
1013 any_top_clicked_ =
false;
1017 if ( (_event->modifiers() & Qt::ControlModifier) && (_event->modifiers() & Qt::AltModifier) ) {
1021 oldPoint2D_ = newPoint2D;
1022 currentScale_ =
Vec3d(1.0, 1.0, 1.0);
1025 touched_ = element_[Origin].clicked_
1027 || any_axis_clicked_
1028 || outer_ring_clicked_;
1033 case QEvent::MouseButtonRelease: {
1035 for (i = 0; i < NumElements; i++) {
1036 if (element_[i].clicked_)
1038 element_[i].clicked_ =
false;
1043 || any_axis_clicked_
1044 || outer_ring_clicked_;
1046 any_axis_clicked_ =
false;
1047 any_top_clicked_ =
false;
1048 outer_ring_clicked_ =
false;
1054 case QEvent::MouseButtonDblClick: {
1055 draw_manipulator_ = !draw_manipulator_;
1060 case QEvent::MouseMove: {
1061 if (!draw_manipulator_) {
1067 Qt::KeyboardModifiers mods = Qt::ShiftModifier | Qt::ControlModifier;
1069 for (i = 0; i < NumElements; i++)
1070 element_[i].over_ =
false;
1071 any_axis_over_ =
false;
1072 any_top_over_ =
false;
1073 outer_ring_over_ =
false;
1075 if (!(element_[Origin].clicked_ || any_top_clicked_ || any_axis_clicked_ || outer_ring_clicked_)) {
1077 if ((mode_ != LocalRotation) && (mode_ != Rotation))
1078 element_[Origin].over_ =
hitSphere(_state, newPoint2D);
1080 element_[Origin].over_ =
false;
1084 if (mode_ != Place) {
1089 if (mode_ != Place) {
1094 if (mode_ != Resize) {
1095 outer_ring_over_ =
mapToSphere(_state, newPoint2D, newPoint3D, Over);
1097 outer_ring_over_ =
false;
1101 if (element_[Origin].over_) {
1102 for (i = 1; i < NumElements; i++)
1103 element_[i].over_ =
false;
1104 any_axis_over_ =
false;
1105 any_top_over_ =
false;
1106 outer_ring_over_ =
false;
1107 }
else if (any_top_over_) {
1108 for (i = XAxis; i < NumElements; i++)
1109 element_[i].over_ =
false;
1110 any_axis_over_ =
false;
1111 outer_ring_over_ =
false;
1112 }
else if (any_axis_over_) {
1113 for (i = XRing; i < NumElements; i++)
1114 element_[i].over_ =
false;
1115 outer_ring_over_ =
false;
1116 }
else if (outer_ring_over_) {
1117 for (i = 0; i < XRing; i++)
1118 element_[i].over_ =
false;
1119 any_axis_over_ =
false;
1120 any_top_over_ =
false;
1127 for (i = 0; i < 3; i++) {
1128 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_;
1132 case TranslationRotation:
1133 for (i = 0; i < 3; i++) {
1134 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_;
1135 trans[i] = element_[XAxis + i].clicked_;
1139 for (i = 0; i < 3; i++) {
1140 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_ || element_[XAxis + i].clicked_;
1147 for (i = 0; i < 3; i++) {
1149 trans[i] = element_[XTop + i].clicked_ || element_[XAxis + i].clicked_;
1155 if (element_[Origin].clicked_) {
1164 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1165 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1166 && (_event->modifiers() & Qt::AltModifier) ) {
1167 newPoint2D = oldPoint2D_;
1169 if (mode_ != Resize) {
1177 Vec3d ntrans = newvec - oldvec;
1179 if (mode_ != Resize)
1183 scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1184 double positive = -1;
1185 if (newPoint2D[0] - oldPoint2D_[0] + oldPoint2D_[1] - newPoint2D[1] > 0)
1188 Vec2d div =
Vec2d(newPoint2D[0], newPoint2D[1]) -
Vec2d(oldPoint2D_[0], oldPoint2D_[1]);
1191 scaleValue *= positive;
1192 currentScale_ +=
Vec3d(scaleValue, scaleValue, scaleValue);
1194 scale(currentScale_);
1216 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1217 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1218 && (_event->modifiers() & Qt::AltModifier) ) {
1219 newPoint2D = oldPoint2D_;
1221 if (mode_ != Resize) {
1227 Vec3d ntrans = newvec - oldvec;
1232 if (mode_ == Resize) {
1234 double positive = -1;
1238 if (currentScale_[0] < 0)
1246 scaleValue *= positive;
1253 m.
scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1258 currentScale_ +=
Vec3d(scaleValue, 0.0, 0.0);
1260 m = localTransformation_;
1261 m.
scale(currentScale_);
1288 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1289 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1290 && (_event->modifiers() & Qt::AltModifier) ) {
1291 newPoint2D = oldPoint2D_;
1293 if (mode_ != Resize) {
1299 Vec3d ntrans = newvec - oldvec;
1304 if (mode_ == Resize) {
1306 double positive = -1;
1310 if (currentScale_[1] < 0)
1318 scaleValue *= positive;
1325 m.
scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1330 currentScale_ +=
Vec3d(0.0, scaleValue, 0.0);
1332 m = localTransformation_;
1333 m.
scale(currentScale_);
1361 if (std::abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE
1362 && std::abs(_state.
context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
1363 && (_event->modifiers() & Qt::AltModifier) ) {
1364 newPoint2D = oldPoint2D_;
1366 if (mode_ != Resize) {
1372 Vec3d ntrans = newvec - oldvec;
1377 if (mode_ == Resize) {
1379 double positive = -1;
1383 if (currentScale_[2] < 0)
1391 scaleValue *= positive;
1398 m.
scale(
Vec3d(1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
1403 currentScale_ +=
Vec3d(0.0, 0.0, scaleValue);
1405 m = localTransformation_;
1406 m.
scale(currentScale_);
1419 if (rot[0] && (activeRotations_ & X_AXIS)) {
1424 Vec2i dist = oldPoint2D_ - newPoint2D;
1428 if (_event->modifiers() == mods) {
1431 lockOldPoint =
true;
1446 if (mode_ == LocalRotation) {
1467 if (rot[1] && (activeRotations_ & Y_AXIS)) {
1472 Vec2i dist = oldPoint2D_ - newPoint2D;
1476 if (_event->modifiers() == mods) {
1479 lockOldPoint =
true;
1492 if (mode_ == LocalRotation) {
1510 if (rot[2] && (activeRotations_ & Z_AXIS)) {
1515 Vec2i dist = oldPoint2D_ - newPoint2D;
1520 if (_event->modifiers() == mods) {
1523 lockOldPoint =
true;
1533 rotation = -dist[1];
1536 if (mode_ == LocalRotation) {
1564 oldPoint2D_ = newPoint2D;
1575 unsigned int x = _v2[0];
1580 Vec3d origin, direction;
1586 _state.
scale(2*manipulator_radius_);
1597 double a = direction.
sqrnorm(),
1598 b = 2.0 * (origin | direction),
1615 unsigned int x = _v2[0];
1620 Vec3d origin, direction;
1626 _state.
scale(manipulator_height_+4*manipulator_radius_);
1636 double a = direction.
sqrnorm(),
1637 b = 2.0 * (origin | direction),
1653 StateUpdates _updateStates )
1656 unsigned int x = _v1[0];
1674 _state.
rotate(-90, 1.0, 0.0, 0.0);
1678 _state.
rotate(90, 0.0, 1.0, 0.0);
1690 const Vec3d origin2(0,0,0),
1691 cylinderAxis(0.0, 0.0, 1.0);
1695 Vec3d normalX = (directionX % cylinderAxis).normalize();
1696 Vec3d vdX = ((origin2 - originX) % directionX);
1697 double axis_hitX = (normalX | vdX);
1698 double orthodistanceX = std::abs( ( origin2 - originX ) | normalX);
1701 Vec3d normalY = (directionY % cylinderAxis).normalize();
1702 Vec3d vdY = ((origin2 - originY) % directionY);
1703 double axis_hitY = (normalY | vdY);
1704 double orthodistanceY = std::abs( ( origin2 - originY ) | normalY);
1707 Vec3d normalZ = (directionZ % cylinderAxis).normalize();
1708 Vec3d vdZ = ((origin2 - originZ) % directionZ);
1709 double axis_hitZ = (normalZ | vdZ);
1710 double orthodistanceZ = std::abs( ( origin2 - originZ ) | normalZ);
1712 if ( _updateStates == None )
1715 if ( ( orthodistanceX < manipulator_radius_ ) &&
1716 ( axis_hitX >= 0 ) &&
1717 ( axis_hitX <= manipulator_height_ ) )
1721 if ( _updateStates == Click)
1722 element_[XAxis].clicked_ =
true;
1724 element_[XAxis].over_ =
true;
1726 }
else if ( ( orthodistanceY < manipulator_radius_ ) &&
1727 ( axis_hitY >= 0 ) &&
1728 ( axis_hitY <= manipulator_height_))
1732 if ( _updateStates == Click)
1733 element_[YAxis].clicked_ =
true;
1735 element_[YAxis].over_ =
true;
1737 }
else if ( ( orthodistanceZ < manipulator_radius_ ) &&
1738 ( axis_hitZ >= 0 ) &&
1739 ( axis_hitZ <= manipulator_height_ ) )
1742 if ( _updateStates == Click)
1743 element_[ZAxis].clicked_ =
true;
1745 element_[ZAxis].over_ =
true;
1749 if ( _updateStates == Click)
1750 return (element_[XAxis].clicked_ || element_[YAxis].clicked_ || element_[ZAxis].clicked_);
1752 return (element_[XAxis].over_ || element_[YAxis].over_ || element_[ZAxis].over_);
1764 StateUpdates _updateStates )
1767 unsigned int x = _v1[0];
1781 _state.
translate( 0.0, 0.0, manipulator_height_);
1783 _state.
translate( 0.0, 0.0, -manipulator_height_);
1786 _state.
rotate(-90, 1.0, 0.0, 0.0);
1787 _state.
translate(0.0, 0.0 , manipulator_height_ );
1789 _state.
translate(0.0, 0.0, -manipulator_height_);
1792 _state.
rotate(90, 0.0, 1.0, 0.0);
1793 _state.
translate(0.0, 0.0, manipulator_height_);
1795 _state.
translate(0.0, 0.0, -manipulator_height_);
1806 const Vec3d origin2(0,0,0),
1807 cylinderAxis(0.0, 0.0, 1.0);
1810 Vec3d normalX = (directionX % cylinderAxis).normalize();
1811 Vec3d vdX = ((origin2 - originX) % directionX );
1812 double axis_hitX = (normalX | vdX);
1813 double orthodistanceX = std::abs( ( origin2 - originX ) | normalX);
1816 Vec3d normalY = (directionY % cylinderAxis).normalize();
1817 Vec3d vdY = ((origin2 - originY) % directionY);
1818 double axis_hitY = (normalY | vdY);
1819 double orthodistanceY = std::abs( ( origin2 - originY ) | normalY);
1822 Vec3d normalZ = (directionZ % cylinderAxis).normalize();
1823 Vec3d vdZ = ((origin2 - originZ) % directionZ);
1824 double axis_hitZ = (normalZ | vdZ);
1825 double orthodistanceZ = std::abs( ( origin2 - originZ ) | normalZ);
1827 if ( _updateStates == None )
1832 if ( ( orthodistanceX < manipulator_radius_ * 2.0 ) &&
1833 ( axis_hitX >= 0.0 ) &&
1834 ( axis_hitX <= manipulator_height_ / 2.0 ) )
1838 if ( _updateStates == Click)
1839 element_[XTop].clicked_ =
true;
1841 element_[XTop].over_ =
true;
1843 }
else if ( ( orthodistanceY < manipulator_radius_ * 2.0 ) &&
1844 ( axis_hitY >= 0.0 ) &&
1845 ( axis_hitY <= manipulator_height_ / 2.0 ) )
1849 if ( _updateStates == Click)
1850 element_[YTop].clicked_ =
true;
1852 element_[YTop].over_ =
true;
1854 }
else if ( ( orthodistanceZ < manipulator_radius_ * 2.0 ) &&
1855 ( axis_hitZ >= 0.0 ) &&
1856 ( axis_hitZ <= manipulator_height_ / 2.0 ) )
1860 if ( _updateStates == Click)
1861 element_[ZTop].clicked_ =
true;
1863 element_[ZTop].over_ =
true;
1867 if ( _updateStates == Click)
1868 return (element_[XTop].clicked_ || element_[YTop].clicked_ || element_[ZTop].clicked_);
1869 return (element_[XTop].over_ || element_[YTop].over_ || element_[ZTop].over_);
1881 StateUpdates _updateStates)
1884 unsigned int x = _v2[0];
1888 Vec3d originXY, directionXY,
1889 originYZ, directionYZ,
1890 originZX, directionZX;
1898 _state.
rotate(90, 0.0, 1.0, 0.0);
1900 _state.
rotate(90, 1.0, 0.0, 0.0);
1908 double t1 = -originXY[2]/directionXY[2];
1909 Vec3d hitPointXY = originXY + directionXY*t1;
1911 double t2 = -originYZ[2]/directionYZ[2];
1912 Vec3d hitPointYZ = originYZ + directionYZ*t2;
1914 double t3 = -originZX[2]/directionZX[2];
1915 Vec3d hitPointZX = originZX + directionZX*t3;
1918 bool t1_near =
false, t2_near =
false, t3_near =
false;
1919 if( t1 <= t2 && t1 <= t3)
1921 if( t2 <= t1 && t2 <= t3)
1923 if( t3 <= t1 && t3 <= t2)
1926 bool xy_hit = hitPointXY.
length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
1927 hitPointXY.
length() < 2*manipulator_height_;
1929 bool yz_hit = hitPointYZ.
length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
1930 hitPointYZ.
length() < 2*manipulator_height_;
1932 bool zx_hit = hitPointZX.
length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
1933 hitPointZX.
length() < 2*manipulator_height_;
1936 bool more_than_one_hit = (xy_hit && yz_hit) || (xy_hit && zx_hit) || (yz_hit && zx_hit);
1948 if(xy_hit && (!more_than_one_hit || t1_near))
1951 if ( _updateStates == Click)
1952 element_[ZRing].clicked_ =
true;
1953 else if ( _updateStates == Over)
1954 element_[ZRing].over_ =
true;
1959 else if(yz_hit && (!more_than_one_hit || t2_near))
1962 if ( _updateStates == Click)
1963 element_[XRing].clicked_ =
true;
1964 else if ( _updateStates == Over)
1965 element_[XRing].over_ =
true;
1970 else if(zx_hit && (!more_than_one_hit || t3_near))
1973 if ( _updateStates == Click)
1974 element_[YRing].clicked_ =
true;
1975 else if ( _updateStates == Over)
1976 element_[YRing].over_ =
true;
1995 if (draw_manipulator_) {
1997 updateSize (_state);
2002 glPushAttrib(GL_DEPTH_BUFFER_BIT);
2018 axisBottom_->setBottomRadius(manipulator_radius_);
2019 axisBottom_->setTopRadius(manipulator_radius_);
2020 axisBottom_->draw(_state, manipulator_height_);
2023 _state.
translate(0.0, 0.0, manipulator_height_);
2024 axisTop_->setBottomRadius(manipulator_radius_*2.0);
2025 axisTop_->setTopRadius(manipulator_radius_*2.0);
2026 axisTop_->draw(_state, manipulator_height_/2.0);
2027 _state.
translate(0.0, 0.0, -manipulator_height_);
2033 _state.
rotate(-90, 1.0, 0.0, 0.0);
2034 axisBottom_->setBottomRadius(manipulator_radius_);
2035 axisBottom_->setTopRadius(manipulator_radius_);
2036 axisBottom_->draw(_state, manipulator_height_);
2039 _state.
translate(0.0, 0.0, manipulator_height_);
2040 axisTop_->setBottomRadius(manipulator_radius_*2.0);
2041 axisTop_->setTopRadius(manipulator_radius_*2.0);
2042 axisTop_->draw(_state, manipulator_height_/2.0);
2043 _state.
translate(0.0, 0.0, -manipulator_height_);
2050 _state.
rotate(90, 0.0, 1.0, 0.0);
2052 axisBottom_->setBottomRadius(manipulator_radius_);
2053 axisBottom_->setTopRadius(manipulator_radius_);
2054 axisBottom_->draw(_state, manipulator_height_);
2057 _state.
translate(0.0, 0.0, manipulator_height_);
2058 axisTop_->setBottomRadius(manipulator_radius_*2.0);
2059 axisTop_->setTopRadius(manipulator_radius_*2.0);
2060 axisTop_->draw(_state, manipulator_height_/2.0);
2062 _state.
translate(0.0, 0.0, -manipulator_height_);
2069 sphere_->draw(_state, manipulator_radius_*2);
2076 circle_->setInnerRadius(2.0f*manipulator_height_ - manipulator_height_/4.0f);
2077 circle_->setOuterRadius(2.0f*manipulator_height_);
2078 if ( activeRotations_ & X_AXIS)
2079 circle_->draw(_state);
2081 _state.
rotate(90, 0.0, 1.0, 0.0);
2082 if ( activeRotations_ & Y_AXIS)
2083 circle_->draw(_state);
2085 _state.
rotate(90, 1.0, 0.0, 0.0);
2086 if ( activeRotations_ & Z_AXIS)
2087 circle_->draw(_state);
2108 const Vec3d cross = _directionX % _directionY;
2110 localTransformation_(0,0) = _directionX[0];
2111 localTransformation_(1,0) = _directionX[1];
2112 localTransformation_(2,0) = _directionX[2];
2113 localTransformation_(3,0) = 0.0;
2115 localTransformation_(0,1) = _directionY[0];
2116 localTransformation_(1,1) = _directionY[1];
2117 localTransformation_(2,1) = _directionY[2];
2118 localTransformation_(3,1) = 0.0;
2120 localTransformation_(0,2) = cross[0];
2121 localTransformation_(1,2) = cross[1];
2122 localTransformation_(2,2) = cross[2];
2123 localTransformation_(3,2) = 0.0;
2133 return MathTools::sane_normalized( localTransformation_.
transform_vector(dirX_) );
2142 return MathTools::sane_normalized( localTransformation_.
transform_vector(dirY_) );
2151 return MathTools::sane_normalized(localTransformation_.
transform_vector(dirZ_));
2156 double TranslationManipulatorNode::get_screen_length (
GLState& _state,
Vec3d& _point)
const 2167 void TranslationManipulatorNode::updateSize (
GLState& _state)
2169 if (auto_size_ != TranslationManipulatorNode::Never)
2173 int tmp, width, height;
2177 auto_size_length_ = get_screen_length (_state, point) * (width + height) * 0.02;
2179 if (auto_size_ == TranslationManipulatorNode::Once)
2180 auto_size_ = TranslationManipulatorNode::Never;
2183 manipulator_radius_ = set_manipulator_radius_ * auto_size_length_;
2184 manipulator_height_ = set_manipulator_height_ * auto_size_length_;
2192 if (!draw_manipulator_)
2195 float r = 2 * manipulator_height_;
VectorT< double, 2 > Vec2d
const GLMatrixd & inverse_scale() const
return inverse scale matrix
bool mapToSphere(GLState &_state, const Vec2i &_v2, Vec3d &_v3, StateUpdates _updateStates=None)
auto length() const -> decltype(std::declval< VectorT< S, DIM >>().norm())
compute squared euclidean norm
void clearTextures()
disables texture support and removes all texture types
const GLMatrixd & rotation() const
return rotation matrix
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
VectorT< float, 4 > Vec4f
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
virtual void mouseEvent(GLState &_state, QMouseEvent *_event)
get mouse events
int context_height() const
get gl context height
void set_ambient_color(const Vec4f &_col)
set ambient color
void viewing_ray(int _x, int _y, Vec3d &_origin, Vec3d &_direction) const
void push_modelview_matrix()
push modelview matrix
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
bounding box of node
void set_direction(const Vec3d &_directionX, const Vec3d &_directionY)
Set direction in world coordinates.
void update_rotation(GLState &_state)
update the internal rotation matrix ( internal rotation may be changed without modifiing children of ...
int priority
Priority to allow sorting of objects.
void pick(GLState &_state, PickTarget _target)
leave node
int viewport_width() const
get viewport width
const Vec4f & specular_color() const
get specular color
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
PickTarget
What target to use for picking.
bool hitOuterSphere(GLState &_state, const Vec2i &_v2)
Determine whether the outer sphere has been hit by the cursor.
void set_diffuse_color(const Vec4f &_col)
set diffuse color
void setMode(ManipulatorMode _mode)
set current operation mode
GLMatrixd modelview
Modelview transform.
void identity()
setup an identity matrix
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
draw the cylinder (if enabled)
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
GLMatrixd computeWorldMatrix()
computes world matrix, transforms from model to world space
static void enable(GLenum _cap)
replaces glEnable, but supports locking
GLenum blendDest
glBlendFunc: GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ONE_MINUS_SRC_ALPHA ...
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
void mult_matrix(const GLMatrixd &_m, const GLMatrixd &_inv_m, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply by a given transformation matrix
bool pick_set_maximum(unsigned int _idx)
Set the maximal number of primitives/components of your object.
void set_specular_color(const Vec4f &_col)
set specular color
void setTraverseMode(unsigned int _mode)
Set traverse mode for node.
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
ManipulatorMode
enum to define the manipulator mode
void set_modelview(const GLMatrixd &_m)
set modelview
const Vec3d & center() const
get center
bool hitSphere(GLState &_state, const Vec2i &_v2)
Determine whether the origin sphere has been hit.
int context_width() const
get gl context width
const GLMatrixd & scale() const
return scale matrix
static void disable(GLenum _cap)
replaces glDisable, but supports locking
virtual void setIdentity()
bool touched_
stores if this manipulator was used in order to avoid emitting manipulatorMoved unnecessarily ...
Namespace providing different geometric functions concerning angles.
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat)
create renderobjects for shaderpipeline renderer
TranslationManipulatorNode(BaseNode *_parent=0, const std::string &_name="<TranslationTranslationManipulatorNode>")
Default constructor.
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
void update_manipulator_system(GLState &_state)
set the current state to follow manipulator transformation
void scale(double _s)
scale by (_s, _s, _s)
Vec3d directionZ() const
Get current direction of z-Axis in world coordinates.
~TranslationManipulatorNode()
Destructor.
void pop_modelview_matrix()
pop modelview matrix
void pick_set_name(unsigned int _idx)
sets the current name/color (like glLoadName(_idx))
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
bool mapToCylinderTop(GLState &_state, const Vec2i &_v2, StateUpdates _updateStates=None)
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
bool invert()
matrix inversion (returns true on success)
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
decltype(std::declval< S >()*std::declval< S >()) sqrnorm() const
compute squared euclidean norm
unsigned int msSinceLastRedraw() const
time passed since last redraw in milliseconds
Vec3d directionY() const
Get current direction of y-Axis in world coordinates.
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
const Vec4f & diffuse_color() const
get diffuse color
const GLMatrixd & modelview() const
get modelview matrix
Vec3d directionX() const
Get current direction of x-Axis in world coordinates.
Execute action the children first and then on this node.
const GLMatrixd & inverse_rotation() const
return inverse rotation matrix
void translate(const Vec3d &_v)
Add a translation to the current Transformation.
pick any of the prior targets (should be implemented for all nodes)
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
int viewport_height() const
get viewport height
void set_color(const Vec4f &_col)
set color
void setDirty(bool _dirty=true)
mark node for redrawn
Interface class between scenegraph and renderer.
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
VectorT< double, 3 > Vec3d
picks faces (should be implemented for all nodes)
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void set_updateGL(bool _b)
should GL matrices be updated after each matrix operation
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
virtual void setIdentity()
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
bool mapToCylinder(GLState &_state, const Vec2i &_v2, StateUpdates _updateStates=None)