00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include "TranslationManipulatorNode.hh"
00057 #include "../Math/GLMatrixT.hh"
00058 #include "../GL/gl.hh"
00059
00060 #include <QMouseEvent>
00061 #include <QEvent>
00062 #include <float.h>
00063
00064 #include <Math_Tools/Math_Tools.hh>
00065 #include <OpenMesh/Core/Geometry/MathDefs.hh>
00066
00067
00068
00069
00070 namespace ACG {
00071 namespace SceneGraph {
00072
00073
00074
00075
00076
00077
00078 #define SNAP_PIXEL_TOLERANCE 30
00079
00080
00081
00082 const Vec4f colors[4][6] = {
00083
00084 {
00085
00086 Vec4f(0.2,0.2,0.2,1.0), Vec4f(0.5,0.5,0.5,1.0), Vec4f(0.8,0.8,0.8,1.0),
00087
00088 Vec4f(0.2,0.2,0.2,0.2), Vec4f(0.5,0.5,0.5,0.4), Vec4f(0.8,0.8,0.8,0.6)
00089 },
00090
00091 {
00092
00093 Vec4f(0.2,0.0,0.0,1.0), Vec4f(0.5,0.0,0.0,1.0), Vec4f(0.8,0.0,0.0,1.0),
00094
00095 Vec4f(0.3,0.1,0.1,0.2), Vec4f(0.5,0.2,0.2,0.4), Vec4f(0.8,0.4,0.4,0.6)
00096 },
00097
00098 {
00099
00100 Vec4f(0.0,0.2,0.0,1.0), Vec4f(0.0,0.5,0.0,1.0), Vec4f(0.0,0.8,0.0,1.0),
00101
00102 Vec4f(0.1,0.3,0.1,0.2), Vec4f(0.2,0.5,0.2,0.4), Vec4f(0.4,0.8,0.4,0.6)
00103 },
00104
00105 {
00106
00107 Vec4f(0.0,0.0,0.2,1.0), Vec4f(0.0,0.0,0.5,1.0), Vec4f(0.0,0.0,0.8,1.0),
00108
00109 Vec4f(0.1,0.1,0.3,0.2), Vec4f(0.2,0.2,0.5,0.4), Vec4f(0.4,0.4,0.8,0.6)
00110 }
00111 };
00112
00113
00114
00115
00116 TranslationManipulatorNode::Element::Element () :
00117 active_target_color_ (0.0, 0.0, 0.0, 1.0),
00118 active_current_color_ (0.0, 0.0, 0.0, 1.0),
00119 inactive_target_color_ (0.0, 0.0, 0.0, 1.0),
00120 inactive_current_color_ (0.0, 0.0, 0.0, 1.0),
00121 clicked_ (false),
00122 over_ (false)
00123 {
00124 }
00125
00126
00127
00128 TranslationManipulatorNode::
00129 TranslationManipulatorNode( BaseNode* _parent, const std::string& _name )
00130 : TransformNode(_parent, _name),
00131 draw_manipulator_(false),
00132 dirX_(1.0,0.0,0.0),
00133 dirY_(0.0,1.0,0.0),
00134 dirZ_(0.0,0.0,1.0),
00135 axis_(0),
00136 circle_(0),
00137 sphere_(0),
00138 manipulator_radius_(20.0),
00139 manipulator_height_(20),
00140 manipulator_slices_(10),
00141 manipulator_stacks_(10),
00142 any_axis_clicked_(false),
00143 any_top_clicked_(false),
00144 outer_ring_clicked_(false),
00145 any_axis_over_(false),
00146 any_top_over_(false),
00147 outer_ring_over_(false),
00148 resize_current_ (0.0),
00149 mode_ (TranslationRotation),
00150 ignoreTime_ (false),
00151 dragging_(false),
00152 auto_size_(TranslationManipulatorNode::Never),
00153 auto_size_length_(1.0)
00154 {
00155 localTransformation_.identity();
00156
00157
00158 axis_ = gluNewQuadric();
00159 circle_ = gluNewQuadric();
00160 sphere_ = gluNewQuadric();
00161
00162 setTraverseMode( BaseNode::ChildrenFirst );
00163
00164 updateTargetColors ();
00165 for (unsigned int i = 0; i < TranslationManipulatorNode::NumElements; i++)
00166 {
00167 element_[i].active_current_color_ = element_[i].active_target_color_;
00168 element_[i].inactive_current_color_ = element_[i].inactive_target_color_;
00169 }
00170
00171 }
00172
00173
00174
00175
00176 TranslationManipulatorNode::~TranslationManipulatorNode() {
00177
00178 if (axis_) {
00179 gluDeleteQuadric(axis_);
00180 }
00181
00182 if (circle_) {
00183 gluDeleteQuadric(circle_);
00184 }
00185
00186 if (sphere_) {
00187 gluDeleteQuadric(sphere_);
00188 }
00189 }
00190
00191
00192
00193
00194
00195 void
00196 TranslationManipulatorNode::
00197 setIdentity()
00198 {
00199 TransformNode::setIdentity();
00200 }
00201
00202
00203
00204 void
00205 TranslationManipulatorNode::
00206 update_manipulator_system(GLState& _state)
00207 {
00208 _state.translate(center()[0], center()[1], center()[2]);
00209 _state.mult_matrix(inverse_scale (), scale ());
00210
00211 update_rotation(_state);
00212 updateSize (_state);
00213 }
00214
00215
00216
00217 void
00218 TranslationManipulatorNode::update_rotation(GLState& _state){
00219
00220
00221 glMatrixMode(GL_MODELVIEW);
00222 GLMatrixd model = _state.modelview();
00223
00224
00225 model *= inverse_rotation();
00226
00227
00228 model *= localTransformation_;
00229
00230
00231 _state.set_modelview(model);
00232
00233 }
00234
00235
00236
00237 void TranslationManipulatorNode::updateTargetColors ()
00238 {
00239
00240 element_[Origin].active_target_color_ = colors[0][0];
00241 element_[XAxis].active_target_color_ = colors[1][0];
00242 element_[YAxis].active_target_color_ = colors[2][0];
00243 element_[ZAxis].active_target_color_ = colors[3][0];
00244 element_[XTop].active_target_color_ = colors[1][0];
00245 element_[YTop].active_target_color_ = colors[2][0];
00246 element_[ZTop].active_target_color_ = colors[3][0];
00247 element_[XRing].active_target_color_ = colors[1][0];
00248 element_[YRing].active_target_color_ = colors[2][0];
00249 element_[ZRing].active_target_color_ = colors[3][0];
00250
00251 element_[Origin].inactive_target_color_ = colors[0][3];
00252 element_[XAxis].inactive_target_color_ = colors[1][3];
00253 element_[YAxis].inactive_target_color_ = colors[2][3];
00254 element_[ZAxis].inactive_target_color_ = colors[3][3];
00255 element_[XTop].inactive_target_color_ = colors[1][3];
00256 element_[YTop].inactive_target_color_ = colors[2][3];
00257 element_[ZTop].inactive_target_color_ = colors[3][3];
00258 element_[XRing].inactive_target_color_ = colors[1][3];
00259 element_[YRing].inactive_target_color_ = colors[2][3];
00260 element_[ZRing].inactive_target_color_ = colors[3][3];
00261
00262
00263
00264 element_[XRing].active_target_color_[3] = 1.0;
00265 element_[YRing].active_target_color_[3] = 1.0;
00266 element_[ZRing].active_target_color_[3] = 1.0;
00267
00268
00269 if (mode_ == Resize || mode_ == Place)
00270 for (unsigned int i = 0; i < 3; i++)
00271 {
00272 element_[XRing + i].active_target_color_[3] = 0.0;
00273 element_[XRing + i].inactive_target_color_[3] = 0.0;
00274 }
00275
00276
00277 if(element_[Origin].clicked_){
00278 element_[Origin].active_target_color_ = colors[0][2];
00279 element_[Origin].inactive_target_color_ = colors[0][5];
00280 for (unsigned int i = 1; i < NumElements - 3; i++)
00281 {
00282 element_[i].active_target_color_ = (colors[0][2] * 0.5) + (colors[((i-1)%3) + 1][2] * 0.5);
00283 element_[i].inactive_target_color_ = (colors[0][5] * 0.5) + (colors[((i-1)%3) + 1][5] * 0.5);
00284 }
00285 return;
00286 } else if(element_[Origin].over_){
00287 element_[Origin].active_target_color_ = colors[0][1];
00288 element_[Origin].inactive_target_color_ = colors[0][4];
00289 for (unsigned int i = 1; i < NumElements - 3; i++)
00290 {
00291 element_[i].active_target_color_ = (colors[0][1] * 0.5) + (colors[((i-1)%3) + 1][1] * 0.5);
00292 element_[i].inactive_target_color_ = (colors[0][4] * 0.5) + (colors[((i-1)%3) + 1][4] * 0.5);
00293 }
00294 return;
00295 }
00296
00297 for (unsigned int i = 0; i < 3; i++)
00298 if (element_[i + XTop].clicked_)
00299 {
00300 element_[i + XTop].active_target_color_ = colors[i+1][2];
00301 element_[i + XTop].inactive_target_color_ = colors[i+1][5];
00302 if (mode_ != TranslationRotation)
00303 {
00304 element_[i + XAxis].active_target_color_ = colors[i+1][2];
00305 element_[i + XAxis].inactive_target_color_ = colors[i+1][5];
00306 }
00307 if (mode_ != Resize) {
00308 element_[i + XRing].active_target_color_ = colors[i+1][2];
00309 element_[i + XRing].inactive_target_color_ = colors[i+1][5];
00310 }
00311 return;
00312 } else if (element_[i + XTop].over_)
00313 {
00314 element_[i + XTop].active_target_color_ = colors[i+1][1];
00315 element_[i + XTop].inactive_target_color_ = colors[i+1][4];
00316 if (mode_ != TranslationRotation)
00317 {
00318 element_[i + XAxis].active_target_color_ = colors[i+1][1];
00319 element_[i + XAxis].inactive_target_color_ = colors[i+1][4];
00320 }
00321 if (mode_ != Resize) {
00322 element_[i + XRing].active_target_color_ = colors[i+1][1];
00323 element_[i + XRing].inactive_target_color_ = colors[i+1][4];
00324 }
00325 return;
00326 }
00327
00328 for (unsigned int i = 0; i < 3; i++)
00329 if (element_[i + XAxis].clicked_)
00330 {
00331 element_[i + XTop].active_target_color_ = colors[i+1][2];
00332 element_[i + XTop].inactive_target_color_ = colors[i+1][5];
00333 element_[i + XAxis].active_target_color_ = colors[i+1][2];
00334 element_[i + XAxis].inactive_target_color_ = colors[i+1][5];
00335 if (mode_ == LocalRotation) {
00336 element_[i + XRing].active_target_color_ = colors[i+1][2];
00337 element_[i + XRing].inactive_target_color_ = colors[i+1][5];
00338 }
00339 return;
00340 } else if (element_[i + XAxis].over_)
00341 {
00342 element_[i + XTop].active_target_color_ = colors[i+1][1];
00343 element_[i + XTop].inactive_target_color_ = colors[i+1][4];
00344 element_[i + XAxis].active_target_color_ = colors[i+1][1];
00345 element_[i + XAxis].inactive_target_color_ = colors[i+1][4];
00346 if (mode_ == LocalRotation) {
00347 element_[i + XRing].active_target_color_ = colors[i+1][1];
00348 element_[i + XRing].inactive_target_color_ = colors[i+1][4];
00349 }
00350 return;
00351 }
00352
00353 if (mode_ != Resize)
00354 for (unsigned int i = 0; i < 3; i++)
00355 if (element_[i + XRing].clicked_)
00356 {
00357 element_[i + XRing].active_target_color_ = colors[i+1][2];
00358 element_[i + XRing].inactive_target_color_ = colors[i+1][5];
00359 return;
00360 } else if (element_[i + XRing].over_)
00361 {
00362 element_[i + XRing].active_target_color_ = colors[i+1][1];
00363 element_[i + XRing].inactive_target_color_ = colors[i+1][4];
00364 return;
00365 }
00366
00367 }
00368
00369
00370
00371 bool TranslationManipulatorNode::updateCurrentColors (GLState& _state)
00372 {
00373 bool rv = false;
00374
00375 float value = (float)_state.msSinceLastRedraw () / 1000.0;
00376
00377 if (ignoreTime_)
00378 {
00379 value = 0;
00380 ignoreTime_ = false;
00381 }
00382
00383 for (unsigned int i = 0; i < NumElements; i++)
00384 {
00385 Vec4f diff = element_[i].active_target_color_ -
00386 element_[i].active_current_color_;
00387 for (unsigned int j = 0; j < 4; j++)
00388 if (diff[j] > value)
00389 diff[j] = value;
00390 else if (diff[j] < -value)
00391 diff[j] = -value;
00392 element_[i].active_current_color_ += diff;
00393 diff = element_[i].inactive_target_color_ -
00394 element_[i].inactive_current_color_;
00395 for (unsigned int j = 0; j < 4; j++)
00396 if (diff[j] > value)
00397 diff[j] = value;
00398 else if (diff[j] < -value)
00399 diff[j] = -value;
00400 element_[i].inactive_current_color_ += diff;
00401
00402 rv |= element_[i].active_target_color_ != element_[i].active_current_color_ ||
00403 element_[i].inactive_target_color_ != element_[i].inactive_current_color_;
00404 }
00405
00406 float diff = ((mode_ == Resize) ? 1.0 : 0.0) - resize_current_;
00407 if (diff > value)
00408 diff = value;
00409 else if (diff < -value)
00410 diff = -value;
00411 resize_current_ += diff;
00412 rv |= resize_current_ != ((mode_ == Resize) ? 1.0 : 0.0);
00413
00414 return rv;
00415 }
00416
00417
00418
00419 void TranslationManipulatorNode::drawManipulator (GLState& _state, bool _active)
00420 {
00421 glPushAttrib(GL_ENABLE_BIT );
00422 glDisable( GL_CULL_FACE );
00423
00424
00425 _state.push_modelview_matrix();
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 if (_active)
00453 {
00454 _state.set_diffuse_color(element_[ZAxis].active_current_color_);
00455 _state.set_specular_color(element_[ZAxis].active_current_color_);
00456 } else {
00457 _state.set_diffuse_color(element_[ZAxis].inactive_current_color_);
00458 _state.set_specular_color(element_[ZAxis].inactive_current_color_);
00459 }
00460
00461
00462 gluCylinder(axis_,
00463 (1.0 - resize_current_) * manipulator_radius_,
00464 (1.0 + resize_current_) * manipulator_radius_,
00465 manipulator_height_/2,
00466 manipulator_slices_,
00467 manipulator_stacks_);
00468
00469
00470 _state.translate(0.0, 0.0, manipulator_height_/2);
00471
00472 gluCylinder(axis_,
00473 manipulator_radius_,
00474 manipulator_radius_,
00475 manipulator_height_/2,
00476 manipulator_slices_,
00477 manipulator_stacks_);
00478
00479
00480
00481 if (_active)
00482 {
00483 _state.set_diffuse_color(element_[ZTop].active_current_color_);
00484 _state.set_specular_color(element_[ZTop].active_current_color_);
00485 } else {
00486 _state.set_diffuse_color(element_[ZTop].inactive_current_color_);
00487 _state.set_specular_color(element_[ZTop].inactive_current_color_);
00488 }
00489
00490 _state.translate(0.0, 0.0, manipulator_height_/2);
00491 gluCylinder(axis_,
00492 manipulator_radius_*2,
00493 0,
00494 manipulator_height_/2,
00495 manipulator_slices_,
00496 manipulator_stacks_);
00497 _state.translate(0.0, 0.0, -manipulator_height_);
00498
00499
00500
00501
00502 _state.rotate(-90, 1.0, 0.0, 0.0);
00503 if (_active)
00504 {
00505 _state.set_diffuse_color(element_[YAxis].active_current_color_);
00506 _state.set_specular_color(element_[YAxis].active_current_color_);
00507 } else {
00508 _state.set_diffuse_color(element_[YAxis].inactive_current_color_);
00509 _state.set_specular_color(element_[YAxis].inactive_current_color_);
00510 }
00511
00512
00513 gluCylinder(axis_,
00514 (1.0 - resize_current_) * manipulator_radius_,
00515 (1.0 + resize_current_) * manipulator_radius_,
00516 manipulator_height_/2,
00517 manipulator_slices_,
00518 manipulator_stacks_);
00519
00520
00521 _state.translate(0.0, 0.0, manipulator_height_/2);
00522
00523 gluCylinder(axis_,
00524 manipulator_radius_,
00525 manipulator_radius_,
00526 manipulator_height_/2,
00527 manipulator_slices_,
00528 manipulator_stacks_);
00529
00530
00531
00532 if (_active)
00533 {
00534 _state.set_diffuse_color(element_[YTop].active_current_color_);
00535 _state.set_specular_color(element_[YTop].active_current_color_);
00536 } else {
00537 _state.set_diffuse_color(element_[YTop].inactive_current_color_);
00538 _state.set_specular_color(element_[YTop].inactive_current_color_);
00539 }
00540
00541 _state.translate(0.0, 0.0, manipulator_height_/2);
00542 gluCylinder(axis_,
00543 manipulator_radius_*2,
00544 0,
00545 manipulator_height_/2,
00546 manipulator_slices_,
00547 manipulator_stacks_);
00548 _state.translate(0.0, 0.0, -manipulator_height_);
00549
00550
00551
00552
00553
00554 _state.rotate(90, 0.0, 1.0, 0.0);
00555 if (_active)
00556 {
00557 _state.set_diffuse_color(element_[XAxis].active_current_color_);
00558 _state.set_specular_color(element_[XAxis].active_current_color_);
00559 } else {
00560 _state.set_diffuse_color(element_[XAxis].inactive_current_color_);
00561 _state.set_specular_color(element_[XAxis].inactive_current_color_);
00562 }
00563
00564
00565 gluCylinder(axis_,
00566 (1.0 - resize_current_) * manipulator_radius_,
00567 (1.0 + resize_current_) * manipulator_radius_,
00568 manipulator_height_/2,
00569 manipulator_slices_,
00570 manipulator_stacks_);
00571
00572
00573 _state.translate(0.0, 0.0, manipulator_height_/2);
00574
00575 gluCylinder(axis_,
00576 manipulator_radius_,
00577 manipulator_radius_,
00578 manipulator_height_/2,
00579 manipulator_slices_,
00580 manipulator_stacks_);
00581
00582
00583
00584 if (_active)
00585 {
00586 _state.set_diffuse_color(element_[XTop].active_current_color_);
00587 _state.set_specular_color(element_[XTop].active_current_color_);
00588 } else {
00589 _state.set_diffuse_color(element_[XTop].inactive_current_color_);
00590 _state.set_specular_color(element_[XTop].inactive_current_color_);
00591 }
00592
00593 _state.translate(0.0, 0.0, manipulator_height_/2);
00594 gluCylinder(axis_,
00595 manipulator_radius_*2,
00596 0,
00597 manipulator_height_/2,
00598 manipulator_slices_,
00599 manipulator_stacks_);
00600 _state.translate(0.0, 0.0, -manipulator_height_);
00601
00602
00603
00604
00605 if (_active)
00606 {
00607 _state.set_diffuse_color(element_[Origin].active_current_color_);
00608 _state.set_specular_color(element_[Origin].active_current_color_);
00609 } else {
00610 _state.set_diffuse_color(element_[Origin].inactive_current_color_);
00611 _state.set_specular_color(element_[Origin].inactive_current_color_);
00612 }
00613
00614 gluSphere( sphere_, manipulator_radius_*2, manipulator_slices_, manipulator_stacks_ );
00615
00616
00617
00618
00619
00620 glEnable (GL_BLEND);
00621 glPushAttrib(GL_LIGHTING_BIT);
00622 glDisable(GL_LIGHTING);
00623
00624 if (_active)
00625 {
00626 glColor4f(element_[XRing].active_current_color_[0],
00627 element_[XRing].active_current_color_[1],
00628 element_[XRing].active_current_color_[2],
00629 element_[XRing].active_current_color_[3]);
00630 } else {
00631 glColor4f(element_[XRing].inactive_current_color_[0],
00632 element_[XRing].inactive_current_color_[1],
00633 element_[XRing].inactive_current_color_[2],
00634 element_[XRing].inactive_current_color_[3]);
00635 }
00636
00637 drawCircle(2*manipulator_height_, 2*manipulator_height_ - manipulator_height_/4.0);
00638
00639 if (_active)
00640 {
00641 glColor4f(element_[YRing].active_current_color_[0],
00642 element_[YRing].active_current_color_[1],
00643 element_[YRing].active_current_color_[2],
00644 element_[YRing].active_current_color_[3]);
00645 } else {
00646 glColor4f(element_[YRing].inactive_current_color_[0],
00647 element_[YRing].inactive_current_color_[1],
00648 element_[YRing].inactive_current_color_[2],
00649 element_[YRing].inactive_current_color_[3]);
00650 }
00651
00652 _state.rotate(90, 0.0, 1.0, 0.0);
00653 drawCircle(2*manipulator_height_, 2*manipulator_height_ - manipulator_height_/4.0);
00654
00655 if (_active)
00656 {
00657 glColor4f(element_[ZRing].active_current_color_[0],
00658 element_[ZRing].active_current_color_[1],
00659 element_[ZRing].active_current_color_[2],
00660 element_[ZRing].active_current_color_[3]);
00661 } else {
00662 glColor4f(element_[ZRing].inactive_current_color_[0],
00663 element_[ZRing].inactive_current_color_[1],
00664 element_[ZRing].inactive_current_color_[2],
00665 element_[ZRing].inactive_current_color_[3]);
00666 }
00667
00668 _state.rotate(90, 1.0, 0.0, 0.0);
00669 drawCircle(2*manipulator_height_, 2*manipulator_height_ - manipulator_height_/4.0);
00670
00671 glPopAttrib();
00672 glPopAttrib();
00673
00674
00675 _state.pop_modelview_matrix();
00676 }
00677
00678
00679
00680
00681 void
00682 TranslationManipulatorNode::draw(GLState& _state, unsigned int )
00683 {
00684 if (draw_manipulator_) {
00685
00686
00687 glPushAttrib(GL_LIGHTING_BIT);
00688 glEnable(GL_LIGHTING);
00689 glShadeModel(GL_SMOOTH);
00690
00691
00692 glPushAttrib(GL_DEPTH_BUFFER_BIT);
00693
00694
00695
00696 glPushAttrib(GL_COLOR_BUFFER_BIT);
00697
00698 glPushAttrib(GL_ENABLE_BIT);
00699
00700
00701 Vec4f backup_diffuse = _state.diffuse_color();
00702 Vec4f backup_specular = _state.specular_color();
00703
00704
00705
00706 update_manipulator_system(_state);
00707
00708 updateTargetColors ();
00709 if (updateCurrentColors (_state))
00710 setDirty ();
00711
00712 glEnable(GL_DEPTH_TEST);
00713 glDepthFunc(GL_GREATER);
00714 glDepthMask(GL_FALSE);
00715 glEnable (GL_BLEND);
00716 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00717 drawManipulator(_state, false);
00718 glDisable (GL_BLEND);
00719
00720 glDepthFunc(GL_LEQUAL);
00721 glDepthMask(GL_TRUE);
00722 drawManipulator(_state, true);
00723
00724
00725 glPopAttrib();
00726 glPopAttrib();
00727 glPopAttrib();
00728 glPopAttrib();
00729
00730
00731 _state.set_diffuse_color(backup_diffuse);
00732 _state.set_specular_color(backup_specular);
00733 }
00734 }
00735
00736
00737
00738
00740 void
00741 TranslationManipulatorNode::drawCircle(const float outerRadius, const float innerRadius)
00742 {
00743 gluDisk(circle_, innerRadius, outerRadius, 30, 30);
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 void
00757 TranslationManipulatorNode::mouseEvent(GLState& _state, QMouseEvent* _event)
00758 {
00759 if(!draw_manipulator_) return;
00760
00761 Vec3d oldPoint3D;
00762 Vec2i newPoint2D(_event->pos().x(), _event->pos().y());
00763 Vec3d newPoint3D;
00764 double old_axis_hit, new_axis_hit, new_axis_over;
00765 bool rot[3], trans[3];
00766 unsigned int i;
00767
00768 updateSize (_state);
00769
00770 switch (_event->type()) {
00771
00772
00773 case QEvent::MouseButtonPress:
00774 {
00775 for (i = 0; i < NumElements; i++)
00776 element_[i].clicked_ = false;
00777
00778
00779 if(!dragging_) {
00780 draggingOrigin3D_ = center();
00781 dragging_ = true;
00782 }
00783
00784
00785 if (mode_ != LocalRotation)
00786 element_[Origin].clicked_ = hitSphere(_state, newPoint2D);
00787 else
00788 element_[Origin].clicked_ = false;
00789
00790
00791 any_top_clicked_ = mapToCylinderTop(_state, newPoint2D, new_axis_hit, Click);
00792
00793
00794 any_axis_clicked_ = mapToCylinder(_state, newPoint2D, new_axis_hit, Click);
00795
00796
00797 if (mode_ != Resize)
00798 outer_ring_clicked_ = mapToSphere(_state, newPoint2D, newPoint3D, Click);
00799 else
00800 outer_ring_clicked_ = false;
00801
00802
00803 if (element_[Origin].clicked_) {
00804 for (i = 1; i < NumElements; i++)
00805 element_[i].clicked_ = false;
00806 any_axis_clicked_ = false;
00807 any_top_clicked_ = false;
00808 outer_ring_clicked_ = false;
00809 } else if ( any_top_clicked_ ) {
00810 for (i = XAxis; i < NumElements; i++)
00811 element_[i].clicked_ = false;
00812 any_axis_clicked_ = false;
00813 outer_ring_clicked_ = false;
00814 } else if ( any_axis_clicked_ ) {
00815 for (i = XRing; i < NumElements; i++)
00816 element_[i].clicked_ = false;
00817 outer_ring_clicked_ = false;
00818 } else if ( outer_ring_clicked_ ) {
00819 for (i = 0; i < XRing; i++)
00820 element_[i].clicked_ = false;
00821 any_axis_clicked_ = false;
00822 any_top_clicked_ = false;
00823 }
00824
00825
00826 if( _event->modifiers() & Qt::ControlModifier && _event->modifiers() & Qt::AltModifier) {
00827 localTransformation_.identity();
00828 }
00829
00830 oldPoint2D_ = newPoint2D;
00831 currentScale_ = Vec3d (1.0, 1.0, 1.0);
00832 ignoreTime_ = true;
00833 break;
00834 }
00835
00836
00837
00838 case QEvent::MouseButtonRelease:
00839 {
00840
00841 for (i = 0; i < NumElements; i++) {
00842 element_[i].clicked_ = false;
00843 }
00844 any_axis_clicked_ = false;
00845 any_top_clicked_ = false;
00846 outer_ring_clicked_ = false;
00847 ignoreTime_ = true;
00848 dragging_ = false;
00849 break;
00850 }
00851
00852
00853 case QEvent::MouseButtonDblClick:
00854 {
00855 draw_manipulator_ = !draw_manipulator_;
00856 break;
00857 }
00858
00859
00860
00861 case QEvent::MouseMove:
00862 {
00863 if(!draw_manipulator_) return;
00864
00865 for (i = 0; i < NumElements; i++)
00866 element_[i].over_ = false;
00867 any_axis_over_ = false;
00868 any_top_over_ = false;
00869 outer_ring_over_ = false;
00870
00871 if (!(element_[Origin].clicked_ || any_top_clicked_ || any_axis_clicked_ ||
00872 outer_ring_clicked_))
00873 {
00874
00875 if (mode_ != LocalRotation)
00876 element_[Origin].over_ = hitSphere(_state, newPoint2D);
00877 else
00878 element_[Origin].over_ = false;
00879
00880
00881 if(mode_ != Place) {
00882 any_top_over_ = mapToCylinderTop(_state, newPoint2D, new_axis_over, Over);
00883 }
00884
00885
00886 if(mode_ != Place) {
00887 any_axis_over_ = mapToCylinder(_state, newPoint2D, new_axis_over, Over);
00888 }
00889
00890
00891 if (mode_ != Resize) {
00892 outer_ring_over_ = mapToSphere(_state, newPoint2D, newPoint3D, Over);
00893 }
00894 else {
00895 outer_ring_over_ = false;
00896 }
00897
00898
00899 if (element_[Origin].over_) {
00900 for (i = 1; i < NumElements; i++)
00901 element_[i].over_ = false;
00902 any_axis_over_ = false;
00903 any_top_over_ = false;
00904 outer_ring_over_ = false;
00905 } else if ( any_top_over_ ) {
00906 for (i = XAxis; i < NumElements; i++)
00907 element_[i].over_ = false;
00908 any_axis_over_ = false;
00909 outer_ring_over_ = false;
00910 } else if ( any_axis_over_ ) {
00911 for (i = XRing; i < NumElements; i++)
00912 element_[i].over_ = false;
00913 outer_ring_over_ = false;
00914 } else if ( outer_ring_over_ ) {
00915 for (i = 0; i < XRing; i++)
00916 element_[i].over_ = false;
00917 any_axis_over_ = false;
00918 any_top_over_ = false;
00919 }
00920 }
00921
00922
00923 switch (mode_)
00924 {
00925 case TranslationRotation:
00926 for (i = 0; i < 3; i++)
00927 {
00928 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_;
00929 trans[i] = element_[XAxis + i].clicked_;
00930 }
00931 break;
00932 case LocalRotation:
00933 for (i = 0; i < 3; i++)
00934 {
00935 rot[i] = element_[XTop + i].clicked_ || element_[XRing + i].clicked_ || element_[XAxis + i].clicked_;
00936 trans[i] = false;
00937 }
00938 break;
00939 case Place:
00940 break;
00941 case Resize:
00942 for (i = 0; i < 3; i++)
00943 {
00944 rot[i] = false;
00945 trans[i] = element_[XTop + i].clicked_ || element_[XAxis + i].clicked_;
00946 }
00947 break;
00948 }
00949
00950
00951 if(element_[Origin].clicked_) {
00952
00953
00954
00955 Vec3d d = _state.project(center());
00956 Vec3d d_origin = _state.project(draggingOrigin3D_);
00957
00958
00959
00960 if (abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE &&
00961 abs(_state.context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
00962 && _event->modifiers() & Qt::AltModifier) {
00963 newPoint2D = oldPoint2D_;
00964 Vec3d backtrans = draggingOrigin3D_ - center();
00965 if (mode_ != Resize) {
00966 translate(backtrans);
00967 }
00968 }
00969
00970
00971 Vec3d oldvec = _state.unproject(Vec3d(oldPoint2D_[0], (_state.context_height() - oldPoint2D_[1]), d[2]));
00972 Vec3d newvec = _state.unproject(Vec3d(newPoint2D[0], (_state.context_height() - newPoint2D[1]), d[2]));
00973 Vec3d ntrans = newvec - oldvec;
00974
00975 if (mode_ != Resize)
00976 translate(ntrans);
00977 else
00978 {
00979
00980 scale(Vec3d (1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
00981 double positive = -1;
00982 if (newPoint2D[0] - oldPoint2D_[0] + oldPoint2D_[1] - newPoint2D[1] > 0)
00983 positive = 1;
00984
00985 Vec2d div = Vec2d (newPoint2D[0], newPoint2D[1]) - Vec2d (oldPoint2D_[0], oldPoint2D_[1]);
00986
00987 double scaleValue = div.norm () * 3.0 / qMin (_state.context_height(), _state.context_width());
00988 scaleValue *= positive;
00989 currentScale_ += Vec3d(scaleValue, scaleValue, scaleValue);
00990
00991 scale(currentScale_);
00992 }
00993 }
00994
00995
00996
00997 if (trans[0]) {
00998
00999 mapToCylinder(_state, oldPoint2D_, old_axis_hit);
01000 mapToCylinder(_state, newPoint2D, new_axis_hit);
01001
01002
01003
01004
01005
01006
01007 Vec3d d = _state.project(center());
01008 Vec3d d_origin = _state.project(draggingOrigin3D_);
01009
01010
01011
01012 if (abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE &&
01013 abs(_state.context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
01014 && _event->modifiers() & Qt::AltModifier) {
01015 newPoint2D = oldPoint2D_;
01016 Vec3d backtrans = draggingOrigin3D_ - center();
01017 if (mode_ != Resize) {
01018 translate(backtrans);
01019 }
01020 }
01021 Vec3d oldvec = _state.unproject(Vec3d(oldPoint2D_[0], (_state.context_height() - oldPoint2D_[1]), d[2]));
01022 Vec3d newvec = _state.unproject(Vec3d(newPoint2D[0], (_state.context_height() - newPoint2D[1]), d[2]));
01023 Vec3d ntrans = newvec - oldvec;
01024
01025
01026 ntrans = ( ntrans | directionX() ) * directionX();
01027
01028 if (mode_ == Resize){
01029
01030 double positive = -1;
01031 if ( (directionX() | ntrans) > 0 ) positive = 1;
01032
01033 if (currentScale_[0] < 0)
01034 positive *= -1;
01035
01036 Vec3d proj = _state.project(ntrans + oldvec);
01037
01038 Vec2d div = Vec2d (proj[0], proj[1]) - Vec2d (oldPoint2D_[0], (_state.context_height() - oldPoint2D_[1]));
01039
01040 double scaleValue = div.norm () * 3.0 / qMin (_state.context_height(), _state.context_width());
01041 scaleValue *= positive;
01042
01043
01044
01045 GLMatrixd m = localTransformation_;
01046 GLMatrixd mi = localTransformation_;
01047 mi.invert ();
01048
01049 m.scale(Vec3d (1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
01050 m *= mi;
01051
01052 scale (m);
01053
01054 currentScale_ += Vec3d(scaleValue, 0.0, 0.0);
01055
01056 m = localTransformation_;
01057 m.scale(currentScale_);
01058 m *= mi;
01059
01060 scale(m);
01061 }else
01062
01063 translate(ntrans);
01064 }
01065
01066
01067 if (trans[1]) {
01068
01069 mapToCylinder(_state, oldPoint2D_, old_axis_hit);
01070 mapToCylinder(_state, newPoint2D, new_axis_hit);
01071
01072
01073
01074
01075
01076
01077 Vec3d d = _state.project(center());
01078 Vec3d d_origin = _state.project(draggingOrigin3D_);
01079
01080
01081
01082 if (abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE &&
01083 abs(_state.context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
01084 && _event->modifiers() & Qt::AltModifier) {
01085 newPoint2D = oldPoint2D_;
01086 Vec3d backtrans = draggingOrigin3D_ - center();
01087 if (mode_ != Resize) {
01088 translate(backtrans);
01089 }
01090 }
01091 Vec3d oldvec = _state.unproject(Vec3d(oldPoint2D_[0], (_state.context_height() - oldPoint2D_[1]), d[2]));
01092 Vec3d newvec = _state.unproject(Vec3d(newPoint2D[0], (_state.context_height() - newPoint2D[1]), d[2]));
01093 Vec3d ntrans = newvec - oldvec;
01094
01095
01096 ntrans = ( ntrans | directionY() ) * directionY();
01097
01098 if (mode_ == Resize){
01099
01100 double positive = -1;
01101 if ( (directionY() | ntrans) > 0 ) positive = 1;
01102
01103 if (currentScale_[1] < 0)
01104 positive *= -1;
01105
01106 Vec3d proj = _state.project(ntrans + oldvec);
01107
01108 Vec2d div = Vec2d (proj[0], proj[1]) - Vec2d (oldPoint2D_[0], (_state.context_height() - oldPoint2D_[1]));
01109
01110 double scaleValue = div.norm () * 3.0 / qMin (_state.context_height(), _state.context_width());
01111 scaleValue *= positive;
01112
01113
01114 GLMatrixd m = localTransformation_;
01115 GLMatrixd mi = localTransformation_;
01116 mi.invert ();
01117
01118 m.scale(Vec3d (1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
01119 m *= mi;
01120
01121 scale (m);
01122
01123 currentScale_ += Vec3d(0.0, scaleValue, 0.0);
01124
01125 m = localTransformation_;
01126 m.scale(currentScale_);
01127 m *= mi;
01128
01129 scale(m);
01130
01131 }else
01132
01133 translate(ntrans);
01134 }
01135
01136
01137 if (trans[2]) {
01138
01139 mapToCylinder(_state, oldPoint2D_, old_axis_hit);
01140 mapToCylinder(_state, newPoint2D, new_axis_hit);
01141
01142
01143
01144
01145
01146
01147 Vec3d d = _state.project(center());
01148 Vec3d d_origin = _state.project(draggingOrigin3D_);
01149
01150
01151
01152 if (abs(d_origin[0] - newPoint2D[0]) < SNAP_PIXEL_TOLERANCE &&
01153 abs(_state.context_height() - d_origin[1] - newPoint2D[1]) < SNAP_PIXEL_TOLERANCE
01154 && _event->modifiers() & Qt::AltModifier) {
01155 newPoint2D = oldPoint2D_;
01156 Vec3d backtrans = draggingOrigin3D_ - center();
01157 if (mode_ != Resize) {
01158 translate(backtrans);
01159 }
01160 }
01161 Vec3d oldvec = _state.unproject(Vec3d(oldPoint2D_[0], (_state.context_height() - oldPoint2D_[1]), d[2]));
01162 Vec3d newvec = _state.unproject(Vec3d(newPoint2D[0], (_state.context_height() - newPoint2D[1]), d[2]));
01163 Vec3d ntrans = newvec - oldvec;
01164
01165
01166 ntrans = ( ntrans | directionZ() ) * directionZ();
01167
01168 if (mode_ == Resize) {
01169
01170 double positive = -1;
01171 if ( (directionZ() | ntrans) > 0 ) positive = 1;
01172
01173 if (currentScale_[2] < 0)
01174 positive *= -1;
01175
01176 Vec3d proj = _state.project(ntrans + oldvec);
01177
01178 Vec2d div = Vec2d (proj[0], proj[1]) - Vec2d (oldPoint2D_[0], (_state.context_height() - oldPoint2D_[1]));
01179
01180 double scaleValue = div.norm () * 3.0 / qMin (_state.context_height(), _state.context_width());
01181 scaleValue *= positive;
01182
01183
01184 GLMatrixd m = localTransformation_;
01185 GLMatrixd mi = localTransformation_;
01186 mi.invert ();
01187
01188 m.scale(Vec3d (1.0 / currentScale_[0], 1.0 / currentScale_[1], 1.0 / currentScale_[2]));
01189 m *= mi;
01190
01191 scale (m);
01192
01193 currentScale_ += Vec3d(0.0, 0.0, scaleValue);
01194
01195 m = localTransformation_;
01196 m.scale(currentScale_);
01197 m *= mi;
01198
01199 scale(m);
01200
01201 }else
01202
01203 translate(ntrans);
01204 }
01205
01206
01207 if (rot[0]) {
01208
01209 mapToCylinder(_state, oldPoint2D_, old_axis_hit);
01210 mapToCylinder(_state, newPoint2D, new_axis_hit);
01211
01212
01213 Vec2i dist = oldPoint2D_ - newPoint2D;
01214
01215
01216
01217 if (mode_ == LocalRotation) {
01218
01219
01220 localTransformation_.rotate( -dist[1], directionX(),ACG::MULT_FROM_LEFT);
01221
01222 } else {
01223
01224 _state.push_modelview_matrix();
01225 _state.translate(center()[0], center()[1], center()[2]);
01226 update_rotation(_state);
01227
01228 rotate(dist[1], directionX() );
01229
01230 _state.pop_modelview_matrix();
01231 }
01232
01233 }
01234
01235
01236
01237 if (rot[1]) {
01238
01239 mapToCylinder(_state, oldPoint2D_, old_axis_hit);
01240 mapToCylinder(_state, newPoint2D, new_axis_hit);
01241
01242 Vec2i dist = oldPoint2D_ - newPoint2D;
01243
01244
01245 if (mode_ == LocalRotation) {
01246
01247
01248 localTransformation_.rotate( -dist[0], directionY(),ACG::MULT_FROM_LEFT);
01249
01250 } else {
01251 _state.push_modelview_matrix();
01252 _state.translate(center()[0], center()[1], center()[2]);
01253
01254 rotate(dist[0], directionY() );
01255
01256 _state.pop_modelview_matrix();
01257 }
01258 }
01259
01260
01261 if (rot[2]) {
01262
01263 mapToCylinder(_state, oldPoint2D_, old_axis_hit);
01264 mapToCylinder(_state, newPoint2D, new_axis_hit);
01265
01266
01267 Vec2i dist = oldPoint2D_ - newPoint2D;
01268
01269 if (mode_ == LocalRotation) {
01270
01271
01272 localTransformation_.rotate( (dist[0]+dist[1])/2, directionZ(),ACG::MULT_FROM_LEFT);
01273
01274 } else {
01275 _state.push_modelview_matrix();
01276 _state.translate(center()[0], center()[1], center()[2]);
01277
01278 rotate((dist[0]+dist[1])/2, directionZ());
01279
01280 _state.pop_modelview_matrix();
01281 }
01282
01283 }
01284
01285 break;
01286 }
01287
01288 default:
01289 break;
01290 }
01291
01292 setDirty ();
01293
01294
01295 oldPoint2D_ = newPoint2D;
01296 }
01297
01298
01299
01300
01302 bool TranslationManipulatorNode::hitSphere( GLState& _state,
01303 const Vec2i& _v2)
01304 {
01305
01306 unsigned int x = _v2[0];
01307 unsigned int y = _state.context_height() - _v2[1];
01308
01309
01310
01311 Vec3d origin, direction;
01312
01313 _state.set_updateGL(false);
01314 _state.push_modelview_matrix();
01315
01316 update_manipulator_system(_state);
01317 _state.scale(2*manipulator_radius_);
01318
01319 _state.viewing_ray(x, y, origin, direction);
01320
01321 _state.pop_modelview_matrix();
01322 _state.set_updateGL(true);
01323
01324
01325
01326
01327
01328 double a = direction.sqrnorm(),
01329 b = 2.0 * (origin | direction),
01330 c = origin.sqrnorm() - 1.0,
01331 d = b*b - 4.0*a*c;
01332
01333 return (d >= 0.0);
01334 }
01335
01336
01337
01338
01339
01341
01342 bool TranslationManipulatorNode::hitOuterSphere( GLState& _state,
01343 const Vec2i& _v2)
01344 {
01345
01346 unsigned int x = _v2[0];
01347 unsigned int y = _state.context_height() - _v2[1];
01348
01349
01350
01351 Vec3d origin, direction;
01352
01353 _state.set_updateGL(false);
01354 _state.push_modelview_matrix();
01355
01356 update_manipulator_system(_state);
01357 _state.scale(manipulator_height_+4*manipulator_radius_);
01358
01359 _state.viewing_ray(x, y, origin, direction);
01360
01361 _state.pop_modelview_matrix();
01362 _state.set_updateGL(true);
01363
01364
01365
01366
01367 double a = direction.sqrnorm(),
01368 b = 2.0 * (origin | direction),
01369 c = origin.sqrnorm() - 1.0,
01370 d = b*b - 4.0*a*c;
01371
01372 return (d >= 0.0);
01373 }
01374
01375
01376
01377
01378
01381 bool
01382 TranslationManipulatorNode::mapToCylinder( GLState& _state,
01383 const Vec2i& _v1,
01384 double& _axis_hit,
01385 StateUpdates _updateStates )
01386 {
01387
01388 unsigned int x = _v1[0];
01389 unsigned int y = _state.context_height() - _v1[1];
01390
01391
01392
01393 Vec3d originX, directionX;
01394 Vec3d originY, directionY;
01395 Vec3d originZ, directionZ;
01396
01397 _state.set_updateGL(false);
01398 _state.push_modelview_matrix();
01399
01400
01401
01402 update_manipulator_system(_state);
01403 _state.viewing_ray(x, y, originZ, directionZ);
01404
01405
01406 _state.rotate(-90, 1.0, 0.0, 0.0);
01407 _state.viewing_ray(x, y, originY, directionY);
01408
01409
01410 _state.rotate(90, 0.0, 1.0, 0.0);
01411 _state.viewing_ray(x, y, originX, directionX);
01412
01413 _state.pop_modelview_matrix();
01414 _state.set_updateGL(true);
01415
01416
01417
01418
01419
01420
01421
01422 const Vec3d origin2(0,0,0),
01423 cylinderAxis(0.0, 0.0, 1.0);
01424
01425
01426
01427 Vec3d normalX = (directionX % cylinderAxis).normalize();
01428 Vec3d vdX = ((origin2 - originX) % directionX);
01429 double axis_hitX = (normalX | vdX);
01430 double orthodistanceX = fabsf( ( origin2 - originX ) | normalX);
01431
01432
01433 Vec3d normalY = (directionY % cylinderAxis).normalize();
01434 Vec3d vdY = ((origin2 - originY) % directionY);
01435 double axis_hitY = (normalY | vdY);
01436 double orthodistanceY = fabsf( ( origin2 - originY ) | normalY);
01437
01438
01439 Vec3d normalZ = (directionZ % cylinderAxis).normalize();
01440 Vec3d vdZ = ((origin2 - originZ) % directionZ);
01441 double axis_hitZ = (normalZ | vdZ);
01442 double orthodistanceZ = fabsf( ( origin2 - originZ ) | normalZ);
01443
01444 if ( _updateStates == None )
01445 return false;
01446
01447 if ( ( orthodistanceX < manipulator_radius_ ) &&
01448 ( axis_hitX >= 0 ) &&
01449 ( axis_hitX <= manipulator_height_ ) )
01450 {
01451
01452
01453 _axis_hit = axis_hitX;
01454 if ( _updateStates == Click)
01455 element_[XAxis].clicked_ = true;
01456 else
01457 element_[XAxis].over_ = true;
01458
01459 } else if ( ( orthodistanceY < manipulator_radius_ ) &&
01460 ( axis_hitY >= 0 ) &&
01461 ( axis_hitY <= manipulator_height_))
01462 {
01463
01464
01465 _axis_hit = axis_hitY;
01466 if ( _updateStates == Click)
01467 element_[YAxis].clicked_ = true;
01468 else
01469 element_[YAxis].over_ = true;
01470
01471 } else if ( ( orthodistanceZ < manipulator_radius_ ) &&
01472 ( axis_hitZ >= 0 ) &&
01473 ( axis_hitZ <= manipulator_height_ ) )
01474 {
01475
01476 _axis_hit = axis_hitZ;
01477 if ( _updateStates == Click)
01478 element_[ZAxis].clicked_ = true;
01479 else
01480 element_[ZAxis].over_ = true;
01481
01482 } else
01483 _axis_hit = 0.0;
01484
01485 if ( _updateStates == Click)
01486 return (element_[XAxis].clicked_ || element_[YAxis].clicked_ || element_[ZAxis].clicked_);
01487
01488 return (element_[XAxis].over_ || element_[YAxis].over_ || element_[ZAxis].over_);
01489 }
01490
01491
01492
01495
01496
01497 bool
01498 TranslationManipulatorNode::mapToCylinderTop( GLState& _state,
01499 const Vec2i& _v1,
01500 double& _axis_hit,
01501 StateUpdates _updateStates )
01502 {
01503
01504 unsigned int x = _v1[0];
01505 unsigned int y = _state.context_height() - _v1[1];
01506
01507
01508
01509 Vec3d originX, directionX;
01510 Vec3d originY, directionY;
01511 Vec3d originZ, directionZ;
01512
01513 _state.set_updateGL(false);
01514 _state.push_modelview_matrix();
01515
01516
01517 update_manipulator_system(_state);
01518 _state.translate( 0.0, 0.0, manipulator_height_);
01519 _state.viewing_ray(x, y, originZ, directionZ);
01520 _state.translate( 0.0, 0.0, -manipulator_height_);
01521
01522
01523 _state.rotate(-90, 1.0, 0.0, 0.0);
01524 _state.translate(0.0, 0.0 , manipulator_height_ );
01525 _state.viewing_ray(x, y, originY, directionY);
01526 _state.translate(0.0, 0.0, -manipulator_height_);
01527
01528
01529 _state.rotate(90, 0.0, 1.0, 0.0);
01530 _state.translate(0.0, 0.0, manipulator_height_);
01531 _state.viewing_ray(x, y, originX, directionX);
01532 _state.translate(0.0, 0.0, -manipulator_height_);
01533
01534 _state.pop_modelview_matrix();
01535 _state.set_updateGL(true);
01536
01537
01538
01539
01540
01541
01542
01543 const Vec3d origin2(0,0,0),
01544 cylinderAxis(0.0, 0.0, 1.0);
01545
01546
01547 Vec3d normalX = (directionX % cylinderAxis).normalize();
01548 Vec3d vdX = ((origin2 - originX) % directionX );
01549 double axis_hitX = (normalX | vdX);
01550 double orthodistanceX = fabsf( ( origin2 - originX ) | normalX);
01551
01552
01553 Vec3d normalY = (directionY % cylinderAxis).normalize();
01554 Vec3d vdY = ((origin2 - originY) % directionY);
01555 double axis_hitY = (normalY | vdY);
01556 double orthodistanceY = fabsf( ( origin2 - originY ) | normalY);
01557
01558
01559 Vec3d normalZ = (directionZ % cylinderAxis).normalize();
01560 Vec3d vdZ = ((origin2 - originZ) % directionZ);
01561 double axis_hitZ = (normalZ | vdZ);
01562 double orthodistanceZ = fabsf( ( origin2 - originZ ) | normalZ);
01563
01564 if ( _updateStates == None )
01565 return false;
01566
01567
01568
01569 if ( ( orthodistanceX < manipulator_radius_ * 2.0 ) &&
01570 ( axis_hitX >= 0.0 ) &&
01571 ( axis_hitX <= manipulator_height_ / 2.0 ) )
01572 {
01573
01574
01575 _axis_hit = axis_hitX;
01576 if ( _updateStates == Click)
01577 element_[XTop].clicked_ = true;
01578 else
01579 element_[XTop].over_ = true;
01580
01581 } else if ( ( orthodistanceY < manipulator_radius_ * 2.0 ) &&
01582 ( axis_hitY >= 0.0 ) &&
01583 ( axis_hitY <= manipulator_height_ / 2.0 ) )
01584 {
01585
01586
01587 _axis_hit = axis_hitY;
01588 if ( _updateStates == Click)
01589 element_[YTop].clicked_ = true;
01590 else
01591 element_[YTop].over_ = true;
01592
01593 } else if ( ( orthodistanceZ < manipulator_radius_ * 2.0 ) &&
01594 ( axis_hitZ >= 0.0 ) &&
01595 ( axis_hitZ <= manipulator_height_ / 2.0 ) )
01596 {
01597
01598
01599 _axis_hit = axis_hitZ;
01600 if ( _updateStates == Click)
01601 element_[ZTop].clicked_ = true;
01602 else
01603 element_[ZTop].over_ = true;
01604
01605 } else
01606 _axis_hit = 0.0;
01607
01608 if ( _updateStates == Click)
01609 return (element_[XTop].clicked_ || element_[YTop].clicked_ || element_[ZTop].clicked_);
01610 return (element_[XTop].over_ || element_[YTop].over_ || element_[ZTop].over_);
01611 }
01612
01613
01614
01618 bool
01619 TranslationManipulatorNode::mapToSphere( GLState& _state,
01620 const Vec2i& _v2,
01621 Vec3d& _v3,
01622 StateUpdates _updateStates)
01623 {
01624
01625 unsigned int x = _v2[0];
01626 unsigned int y = _state.context_height() - _v2[1];
01627
01628
01629 Vec3d originXY, directionXY,
01630 originYZ, directionYZ,
01631 originZX, directionZX;
01632
01633 _state.set_updateGL(false);
01634 _state.push_modelview_matrix();
01635
01636 update_manipulator_system(_state);
01637
01638 _state.viewing_ray(x, y, originXY, directionXY);
01639 _state.rotate(90, 0.0, 1.0, 0.0);
01640 _state.viewing_ray(x, y, originYZ, directionYZ);
01641 _state.rotate(90, 1.0, 0.0, 0.0);
01642 _state.viewing_ray(x, y, originZX, directionZX);
01643
01644 _state.pop_modelview_matrix();
01645 _state.set_updateGL(true);
01646
01647
01648
01649 double t1 = -originXY[2]/directionXY[2];
01650 Vec3d hitPointXY = originXY + directionXY*t1;
01651
01652 double t2 = -originYZ[2]/directionYZ[2];
01653 Vec3d hitPointYZ = originYZ + directionYZ*t2;
01654
01655 double t3 = -originZX[2]/directionZX[2];
01656 Vec3d hitPointZX = originZX + directionZX*t3;
01657
01658
01659 bool t1_near = false, t2_near = false, t3_near = false;
01660 if( t1 <= t2 && t1 <= t3)
01661 t1_near = true;
01662 if( t2 <= t1 && t2 <= t3)
01663 t2_near = true;
01664 if( t3 <= t1 && t3 <= t2)
01665 t3_near = true;
01666
01667 bool xy_hit = hitPointXY.length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
01668 hitPointXY.length() < 2*manipulator_height_;
01669
01670 bool yz_hit = hitPointYZ.length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
01671 hitPointYZ.length() < 2*manipulator_height_;
01672
01673 bool zx_hit = hitPointZX.length() > 2*manipulator_height_ - manipulator_height_/4.0 &&
01674 hitPointZX.length() < 2*manipulator_height_;
01675
01676
01677 bool more_than_one_hit = (xy_hit && yz_hit) || (xy_hit && zx_hit) || (yz_hit && zx_hit);
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689 if(xy_hit && (!more_than_one_hit || t1_near))
01690 {
01691
01692 if ( _updateStates == Click)
01693 element_[ZRing].clicked_ = true;
01694 else if ( _updateStates == Over)
01695 element_[ZRing].over_ = true;
01696 _v3 = hitPointXY;
01697 return true;
01698 }
01699
01700 else if(yz_hit && (!more_than_one_hit || t2_near))
01701 {
01702
01703 if ( _updateStates == Click)
01704 element_[XRing].clicked_ = true;
01705 else if ( _updateStates == Over)
01706 element_[XRing].over_ = true;
01707 _v3 = hitPointYZ;
01708 return true;
01709 }
01710
01711 else if(zx_hit && (!more_than_one_hit || t3_near))
01712 {
01713
01714 if ( _updateStates == Click)
01715 element_[YRing].clicked_ = true;
01716 else if ( _updateStates == Over)
01717 element_[YRing].over_ = true;
01718 _v3 = hitPointZX;
01719 return true;
01720 }
01721
01722 return false;
01723 }
01724
01725
01726
01727 void
01728 TranslationManipulatorNode::
01729 pick(GLState& _state, PickTarget _target)
01730 {
01731 if (_target == PICK_FACE ||
01732 _target == PICK_ANYTHING) {
01733
01734 if (draw_manipulator_) {
01735
01736 updateSize (_state);
01737
01738 _state.pick_set_maximum(5);
01739
01740
01741 glPushAttrib(GL_DEPTH_BUFFER_BIT);
01742 glEnable(GL_DEPTH_TEST);
01743 glDepthFunc(GL_LEQUAL);
01744
01745
01746 _state.push_modelview_matrix();
01747
01748
01749 update_manipulator_system(_state);
01750
01751 _state.pick_set_name(0);
01752
01753
01754
01755
01756
01757 gluCylinder(axis_,
01758 manipulator_radius_,
01759 manipulator_radius_,
01760 manipulator_height_,
01761 manipulator_slices_,
01762 manipulator_stacks_);
01763
01764
01765 _state.translate(0.0, 0.0, manipulator_height_);
01766 gluCylinder(axis_,
01767 manipulator_radius_*2,
01768 0,
01769 manipulator_height_/2,
01770 manipulator_slices_,
01771 manipulator_stacks_);
01772 _state.translate(0.0, 0.0, -manipulator_height_);
01773
01774 _state.pick_set_name(1);
01775
01776
01777
01778 _state.rotate(-90, 1.0, 0.0, 0.0);
01779 gluCylinder(axis_,
01780 manipulator_radius_,
01781 manipulator_radius_,
01782 manipulator_height_,
01783 manipulator_slices_,
01784 manipulator_stacks_);
01785
01786
01787 _state.translate(0.0, 0.0, manipulator_height_);
01788 gluCylinder(axis_,
01789 manipulator_radius_*2,
01790 0,
01791 manipulator_height_/2,
01792 manipulator_slices_,
01793 manipulator_stacks_);
01794 _state.translate(0.0, 0.0, -manipulator_height_);
01795
01796
01797 _state.pick_set_name(2);
01798
01799
01800
01801 _state.rotate(90, 0.0, 1.0, 0.0);
01802
01803 gluCylinder(axis_,
01804 manipulator_radius_,
01805 manipulator_radius_,
01806 manipulator_height_,
01807 manipulator_slices_,
01808 manipulator_stacks_);
01809
01810
01811 _state.translate(0.0, 0.0, manipulator_height_);
01812 gluCylinder(axis_,
01813 manipulator_radius_*2,
01814 0,
01815 manipulator_height_/2,
01816 manipulator_slices_,
01817 manipulator_stacks_);
01818 _state.translate(0.0, 0.0, -manipulator_height_);
01819
01820 _state.pick_set_name(3);
01821
01822
01823
01824
01825 gluSphere( sphere_, manipulator_radius_*2, manipulator_slices_, manipulator_stacks_ );
01826
01827
01828
01829
01830
01831 _state.pick_set_name(4);
01832 drawCircle(2*manipulator_height_, 2*manipulator_height_ - manipulator_height_/4.0);
01833
01834 _state.rotate(90, 0.0, 1.0, 0.0);
01835 drawCircle(2*manipulator_height_, 2*manipulator_height_ - manipulator_height_/4.0);
01836
01837 _state.rotate(90, 1.0, 0.0, 0.0);
01838 drawCircle(2*manipulator_height_, 2*manipulator_height_ - manipulator_height_/4.0);
01839
01840
01841
01842 glPopAttrib();
01843
01844 _state.pop_modelview_matrix();
01845 }
01846 }
01847 }
01848
01849
01850
01851
01852 void
01853 TranslationManipulatorNode::set_direction(const Vec3d& _directionX, const Vec3d& _directionY)
01854 {
01855
01856 localTransformation_.identity();
01857
01858 double angle;
01859
01860
01861
01862
01863
01864
01865 angle = OpenMesh::rad_to_deg(acos(OpenMesh::sane_aarg( MathTools::sane_normalized(_directionX) | MathTools::sane_normalized(dirX_) )));
01866
01867
01868
01869 Vec3d rotAxis = MathTools::sane_normalized( dirX_ % _directionX );
01870
01871 if ( rotAxis.sqrnorm() == 0.0 )
01872 rotAxis = MathTools::sane_normalized( dirZ_ );
01873
01874 localTransformation_.rotate( angle, rotAxis );
01875
01876 Vec3d newDirY = MathTools::sane_normalized( localTransformation_.transform_vector(dirY_) );
01877
01878 angle = OpenMesh::rad_to_deg(acos(OpenMesh::sane_aarg( MathTools::sane_normalized(_directionY) | MathTools::sane_normalized(newDirY) )));
01879
01880
01881 Vec3d rotAxis2 = MathTools::sane_normalized( newDirY % _directionY );
01882
01883 if ( rotAxis2.sqrnorm() == 0.0 )
01884 rotAxis2 = MathTools::sane_normalized( localTransformation_.transform_vector(dirX_) );
01885
01886 localTransformation_.rotate( angle, rotAxis2 );
01887 }
01888
01889
01890
01891
01892 Vec3d
01893 TranslationManipulatorNode::directionX() const
01894 {
01895 return MathTools::sane_normalized( localTransformation_.transform_vector(dirX_) );
01896 }
01897
01898
01899
01900
01901 Vec3d
01902 TranslationManipulatorNode::directionY() const
01903 {
01904 return MathTools::sane_normalized( localTransformation_.transform_vector(dirY_) );
01905 }
01906
01907
01908
01909
01910 Vec3d
01911 TranslationManipulatorNode::directionZ() const
01912 {
01913 return MathTools::sane_normalized(localTransformation_.transform_vector(dirZ_));
01914 }
01915
01916
01917
01918 double TranslationManipulatorNode::get_screen_length (GLState& _state, Vec3d& _point) const
01919 {
01920 Vec3d proj = _state.project (_point);
01921 proj[0] += 1.0;
01922 Vec3d uproj = _state.unproject (proj);
01923 uproj -= _point;
01924 return uproj.length ();
01925 }
01926
01927
01928
01929 void TranslationManipulatorNode::updateSize (GLState& _state)
01930 {
01931 if (auto_size_ != TranslationManipulatorNode::Never)
01932 {
01933 Vec3d point = localTransformation_.transform_point(Vec3d (0.0, 0.0, 0.0));
01934
01935 int tmp, width, height;
01936
01937 _state.get_viewport (tmp, tmp, width, height);
01938
01939 auto_size_length_ = get_screen_length (_state, point) * (width + height) * 0.02;
01940
01941 if (auto_size_ == TranslationManipulatorNode::Once)
01942 auto_size_ = TranslationManipulatorNode::Never;
01943 }
01944
01945 manipulator_radius_ = set_manipulator_radius_ * auto_size_length_;
01946 manipulator_height_ = set_manipulator_height_ * auto_size_length_;
01947 }
01948
01949
01950
01951
01952 void TranslationManipulatorNode::boundingBox( Vec3f & _bbMin, Vec3f & _bbMax )
01953 {
01954 if (!draw_manipulator_)
01955 return;
01956
01957 float r = 2 * manipulator_height_;
01958
01959 _bbMin.minimize(Vec3f(-r,-r,-r));
01960 _bbMax.maximize(Vec3f(r,r,r));
01961 }
01962
01963
01964
01965 void TranslationManipulatorNode::setMode (ManipulatorMode _mode)
01966 {
01967 if (mode_ != _mode)
01968 ignoreTime_ = true;
01969 mode_ = _mode;
01970 setDirty ();
01971 }
01972
01973
01974 }
01975 }
01976