00001 #include "renderwindowinteractor.h"
00002
00003 #include "vtkMath.h"
00004 #include "vtkLightCollection.h"
00005 #include "vtkSphereSource.h"
00006 #include "vtkPolyDataMapper.h"
00007 #include "vtkMath.h"
00008
00079 RenderWindowInteractor::RenderWindowInteractor( QWidget *parent,
00080 const char *name )
00081 : RenderWindow( parent, name ) {
00082 this->InitRenderWindowInteractor();
00083 }
00084
00100 RenderWindowInteractor::RenderWindowInteractor(
00101 QGLFormat glf, QWidget *parent, const char *name )
00102 : RenderWindow( glf, parent, name ) {
00103 this->InitRenderWindowInteractor();
00104 }
00105
00106
00111 RenderWindowInteractor::~RenderWindowInteractor() {
00112 delete this->stepTimer;
00113 }
00114
00115
00121 void RenderWindowInteractor::InitRenderWindowInteractor() {
00122 this->SetLeftButtonFunction( SLOT(CameraRotate()) );
00123 this->SetMiddleButtonFunction( SLOT(CameraTranslate()) );
00124 this->SetRightButtonFunction( SLOT(CameraZoom()) );
00125 this->SetShiftLeftButtonFunction( SLOT(CameraRoll()) );
00126
00127 this->mouseEventActive = false;
00128 this->SetInteractionTime( 50 );
00129 this->SetSensitivity( 10.0 );
00130
00131 this->stepTimer = new QTimer();
00132 CHECK_PTR( this->stepTimer );
00133
00134 this->currentCamera = this->GetRenderer()->GetActiveCamera();
00135 CHECK_PTR( this->currentCamera );
00136
00137
00138 vtkLightCollection *lightCollection = this->GetRenderer()->GetLights();
00139 lightCollection->InitTraversal();
00140 this->currentLight = lightCollection->GetNextItem();
00141 CHECK_PTR( this->currentLight );
00142
00143 this->interactionActor = NULL;
00144 this->collisionActor = NULL;
00145 }
00146
00147
00151 const char *RenderWindowInteractor::GetClassName() {
00152 return( "RenderWindowInteractor" );
00153 }
00154
00155
00161 void RenderWindowInteractor::SetPlane(float *ebene) {
00162
00163 this->normale[0] = ebene[0];
00164 this->normale[1] = ebene[1];
00165 this->normale[2] = ebene[2];
00166 this->ebenekonstante = ebene[3];
00167
00168 }
00169
00176 void RenderWindowInteractor::SetSensitivity( float t ) {
00177 this->trackballFactor = t;
00178 }
00179
00185 float RenderWindowInteractor::GetSensitivity() {
00186 return this->trackballFactor;
00187 }
00188
00189
00209 void RenderWindowInteractor::SetLeftButtonFunction( const char* function ) {
00210 if( function == NULL ) {
00211 strncpy( this->leftButtonFunction, SLOT(DoNothing()), 100 );
00212 }
00213 else {
00214 strncpy( this->leftButtonFunction, function, 100 );
00215 }
00216 }
00217
00218
00238 void RenderWindowInteractor::SetMiddleButtonFunction( const char* function ) {
00239 if( function == NULL ) {
00240 strncpy( this->middleButtonFunction, SLOT(DoNothing()), 100 );
00241 }
00242 else {
00243 strncpy( this->middleButtonFunction, function, 100 );
00244 }
00245 }
00246
00247
00267 void RenderWindowInteractor::SetRightButtonFunction( const char* function ) {
00268 if( function == NULL ) {
00269 strncpy( this->rightButtonFunction, SLOT(DoNothing()), 100 );
00270 }
00271 else {
00272 strncpy( this->rightButtonFunction, function, 100 );
00273 }
00274 }
00275
00276
00296 void RenderWindowInteractor::SetShiftLeftButtonFunction(
00297 const char* function ) {
00298 if( function == NULL ) {
00299 strncpy( this->shiftLeftButtonFunction, SLOT(DoNothing()), 100 );
00300 }
00301 else {
00302 strncpy( this->shiftLeftButtonFunction, function, 100 );
00303 }
00304 }
00305
00306
00310 void RenderWindowInteractor::SetInteractionActor( vtkActor* actor ) {
00311 this->interactionActor = actor;
00312 }
00313
00314
00318 vtkActor *RenderWindowInteractor::GetInteractionActor( void ) {
00319 return this->interactionActor;
00320 }
00321
00332 void RenderWindowInteractor::SetActorRotation( float x, float y, float z ) {
00333 ASSERT( this->interactionActor != NULL );
00334
00335
00336 this->interactionActor->SetOrigin( x, y, z );
00337 }
00338
00339
00346 void RenderWindowInteractor::mousePressEvent( QMouseEvent *event ) {
00347 if( this->mouseEventActive ) {
00348 return;
00349 }
00350
00351 if( event->button() & LeftButton ) {
00352 if( event->state() & ShiftButton ) {
00353
00354 this->mouseEventActive = true;
00355 QObject::connect( this->stepTimer, SIGNAL(timeout()),
00356 this->shiftLeftButtonFunction );
00357 }
00358 else {
00359
00360 this->mouseEventActive = true;
00361 QObject::connect( this->stepTimer, SIGNAL(timeout()),
00362 this->leftButtonFunction );
00363 }
00364 }
00365 else if( event->button() & MidButton ) {
00366
00367 this->mouseEventActive = true;
00368 QObject::connect( this->stepTimer, SIGNAL(timeout()),
00369 this->middleButtonFunction );
00370 }
00371 else if( event->button() & RightButton ) {
00372
00373 this->mouseEventActive = true;
00374 QObject::connect( this->stepTimer, SIGNAL(timeout()),
00375 this, this->rightButtonFunction );
00376 }
00377
00378 if( this->mouseEventActive ) {
00379 this->currentMousePos[0] = event->x();
00380 this->currentMousePos[1] = event->y();
00381 this->lastMousePos[0] = event->x();
00382 this->lastMousePos[1] = event->y();
00383 this->firstCall = true;
00384 this->stepTimer->start( this->interactionTime );
00385 }
00386 }
00387
00388
00392 void RenderWindowInteractor::mouseReleaseEvent( QMouseEvent *event ) {
00393 if( this->mouseEventActive ) {
00394 this->stepTimer->stop();
00395 this->mouseEventActive = false;
00396 QObject::disconnect( this->stepTimer, 0, this, 0 );
00397 }
00398
00399 emit( Released(event->x(), this->height() - event->y()) );
00400
00401 }
00402
00403
00410 void RenderWindowInteractor::mouseMoveEvent( QMouseEvent *event ) {
00411 this->currentMousePos[0] = event->x();
00412 this->currentMousePos[1] = event->y();
00413 }
00414
00415
00426 void RenderWindowInteractor::SetInteractionTime( int time ) {
00427 this->interactionTime = time;
00428 }
00429
00433 int RenderWindowInteractor::GetInteractionTime( void ) {
00434 return this->interactionTime;
00435 }
00436
00437
00444 void RenderWindowInteractor::ActorRotate() {
00445 float xf;
00446 float yf;
00447
00448
00449 if( (this->currentMousePos[0] == this->lastMousePos[0]) &&
00450 (this->currentMousePos[1] == this->lastMousePos[1]) ) {
00451 return;
00452 }
00453
00454
00455
00456
00457
00458
00459 if( firstCall ) {
00460 int *size = this->GetRenderWindow()->GetSize();
00461 float *vp = this->GetRenderer()->GetViewport();
00462
00463 this->deltaAzimuth = -20.0/((vp[2] - vp[0])*size[0]);
00464 this->deltaElevation = -20.0/((vp[3] - vp[1])*size[1]);
00465
00466
00467 this->currentCamera->GetViewUp( this->viewUp );
00468 this->currentCamera->GetViewPlaneNormal( this->vpNormal );
00469 vtkMath::Cross( this->vpNormal, this->viewUp, this->rotateY );
00470
00471 this->firstCall = false;
00472 }
00473
00474
00475 xf = (this->currentMousePos[0] - this->lastMousePos[0])
00476 * this->trackballFactor * deltaAzimuth * (-1);
00477 yf = (this->currentMousePos[1] - this->lastMousePos[1])
00478 * this->trackballFactor * deltaElevation;
00479
00480 this->interactionActor->RotateWXYZ( xf, this->viewUp[0], this->viewUp[1],
00481 this->viewUp[2] );
00482 this->interactionActor->RotateWXYZ( yf, this->rotateY[0], this->rotateY[1],
00483 this->rotateY[2] );
00484
00485 emit ActorRotated( xf, yf );
00486
00487
00488 this->updateGL();
00489
00490
00491 this->lastMousePos[0] = this->currentMousePos[0];
00492 this->lastMousePos[1] = this->currentMousePos[1];
00493 }
00494
00495
00501 void RenderWindowInteractor::ActorTranslate() {
00502 float *center;
00503 float dispCenter[4];
00504 float newP[4];
00505 float oldP[4];
00506
00507
00508 if( (this->currentMousePos[0] == this->lastMousePos[0]) &&
00509 (this->currentMousePos[1] == this->lastMousePos[1]) ) {
00510 return;
00511 }
00512
00513 center = this->interactionActor->GetCenter();
00514 this->WorldToDisplay( center[0], center[1], center[2], dispCenter );
00515
00516 this->DisplayToWorld( float(this->currentMousePos[0]),
00517 float(this->height() - this->currentMousePos[1]),
00518 dispCenter[2],
00519 newP );
00520
00521 this->DisplayToWorld( float(this->lastMousePos[0]),
00522 float(this->height() - this->lastMousePos[1]),
00523 dispCenter[2],
00524 oldP);
00525
00526 this->interactionActor->AddPosition( newP[0]-oldP[0],
00527 newP[1]-oldP[1],
00528 newP[2]-oldP[2] );
00529
00530 this->updateGL();
00531
00532
00533 this->lastMousePos[0] = this->currentMousePos[0];
00534 this->lastMousePos[1] = this->currentMousePos[1];
00535 }
00536
00537
00543 void RenderWindowInteractor::ActorZoom() {
00544 float yf;
00545
00546
00547 if( (this->currentMousePos[0] == this->lastMousePos[0]) &&
00548 (this->currentMousePos[1] == this->lastMousePos[1]) ) {
00549 return;
00550 }
00551
00552
00553 if( firstCall ) {
00554 this->currentCamera->GetViewPlaneNormal( this->vpNormal );
00555 firstCall = false;
00556 }
00557
00558 yf = float(this->lastMousePos[1] - this->currentMousePos[1]) /
00559 float(this->height()) * this->trackballFactor * -10.0;
00560
00561 this->interactionActor->AddPosition( this->vpNormal[0] * yf,
00562 this->vpNormal[1] * yf,
00563 this->vpNormal[2] * yf );
00564
00565
00566 this->updateGL();
00567
00568
00569 this->lastMousePos[0] = this->currentMousePos[0];
00570 this->lastMousePos[1] = this->currentMousePos[1];
00571 }
00572
00573
00579 void RenderWindowInteractor::ActorRoll() {
00580 float angle;
00581
00582
00583 if( (this->currentMousePos[0] == this->lastMousePos[0]) &&
00584 (this->currentMousePos[1] == this->lastMousePos[1]) ) {
00585 return;
00586 }
00587
00588
00589 if( firstCall ) {
00590 this->currentCamera->GetViewPlaneNormal( this->vpNormal );
00591 this->renCenter[0] = this->GetRenderer()->GetCenter()[0];
00592 this->renCenter[1] = this->GetRenderer()->GetCenter()[1];
00593 this->renCenter[2] = this->GetRenderer()->GetCenter()[2];
00594 firstCall = false;
00595 }
00596
00597 int diffX1 = this->currentMousePos[0] - int(this->renCenter[0]);
00598 int diffY1 = this->currentMousePos[1] - int(this->renCenter[1]);
00599 int diffX2 = this->lastMousePos[0] - int(this->renCenter[0]);
00600 int diffY2 = this->lastMousePos[1] - int(this->renCenter[1]);
00601
00602 double a1 = atan2( double(diffY1), double(diffX1) );
00603 double a2 = atan2( double(diffY2), double(diffX2) );
00604 angle = (a2 - a1) / (2.0 * 3.1415926535) * 360.0 / 10.0 *
00605 this->trackballFactor;
00606 this->interactionActor->RotateWXYZ( angle, this->vpNormal[0],
00607 this->vpNormal[1],
00608 this->vpNormal[2] );
00609
00610 emit ActorRolled( angle );
00611
00612
00613 this->updateGL();
00614
00615
00616 this->lastMousePos[0] = this->currentMousePos[0];
00617 this->lastMousePos[1] = this->currentMousePos[1];
00618 }
00619
00620
00625 void RenderWindowInteractor::CameraRotate() {
00626 float xf;
00627 float yf;
00628
00629
00630 if( (this->currentMousePos[0] == this->lastMousePos[0]) &&
00631 (this->currentMousePos[1] == this->lastMousePos[1]) ) {
00632 return;
00633 }
00634
00635
00636 if( firstCall ) {
00637 int *size = this->GetRenderWindow()->GetSize();
00638 float *vp = this->GetRenderer()->GetViewport();
00639
00640 this->deltaAzimuth = -20.0/((vp[2] - vp[0])*size[0]);
00641 this->deltaElevation = -20.0/((vp[3] - vp[1])*size[1]);
00642 firstCall = false;
00643 }
00644
00645 xf = (this->currentMousePos[0] - this->lastMousePos[0]) * this->deltaAzimuth
00646 * this->trackballFactor;
00647 yf = (this->lastMousePos[1] - this->currentMousePos[1]) * this->deltaElevation
00648 * this->trackballFactor;
00649
00650 this->currentCamera->Azimuth( xf );
00651 this->currentCamera->Elevation( yf );
00652 this->currentCamera->OrthogonalizeViewUp();
00653 this->GetRenderer()->ResetCameraClippingRange();
00654
00655
00656 this->currentLight->SetPosition( this->currentCamera->GetPosition() );
00657 this->currentLight->SetFocalPoint( this->currentCamera->GetFocalPoint() );
00658
00659
00660 this->updateGL();
00661
00662
00663 this->lastMousePos[0] = this->currentMousePos[0];
00664 this->lastMousePos[1] = this->currentMousePos[1];
00665 }
00666
00667
00671 void RenderWindowInteractor::CameraTranslate() {
00672 float newP[4];
00673 float viewFocus[4];
00674 float viewPoint[3];
00675 double motionVector[3];
00676
00677
00678 if( (this->currentMousePos[0] == this->lastMousePos[0]) &&
00679 (this->currentMousePos[1] == this->lastMousePos[1]) ) {
00680 return;
00681 }
00682
00683 this->currentCamera->GetFocalPoint( viewFocus );
00684 this->WorldToDisplay( viewFocus[0], viewFocus[1], viewFocus[2],
00685 viewFocus );
00686 double focalDepth = viewFocus[2];
00687
00688 this->DisplayToWorld( float(this->width()/2.0 + (this->currentMousePos[0]
00689 - this->lastMousePos[0])),
00690 float(this->height()/2.0 - (this->currentMousePos[1]
00691 - this->lastMousePos[1])),
00692 focalDepth,
00693 newP );
00694
00695 this->currentCamera->GetFocalPoint( viewFocus );
00696 this->currentCamera->GetPosition( viewPoint );
00697
00698 motionVector[0] = this->trackballFactor / 10.0 * ( viewFocus[0] - newP[0] );
00699 motionVector[1] = this->trackballFactor / 10.0 * ( viewFocus[1] - newP[1] );
00700 motionVector[2] = this->trackballFactor / 10.0 * ( viewFocus[2] - newP[2] );
00701
00702 this->currentCamera->SetFocalPoint( motionVector[0] + viewFocus[0],
00703 motionVector[1] + viewFocus[1],
00704 motionVector[2] + viewFocus[2]);
00705 this->currentCamera->SetPosition( motionVector[0] + viewPoint[0],
00706 motionVector[1] + viewPoint[1],
00707 motionVector[2] + viewPoint[2]);
00708
00709
00710 this->currentLight->SetPosition( this->currentCamera->GetPosition() );
00711 this->currentLight->SetFocalPoint( this->currentCamera->GetFocalPoint() );
00712
00713
00714 this->updateGL();
00715
00716
00717 this->lastMousePos[0] = this->currentMousePos[0];
00718 this->lastMousePos[1] = this->currentMousePos[1];
00719 }
00720
00721
00726 void RenderWindowInteractor::CameraZoom() {
00727 float yf;
00728
00729
00730 if( this->currentMousePos[1] == this->lastMousePos[1] ) {
00731 return;
00732 }
00733
00734 yf = float(this->currentMousePos[1]-this->lastMousePos[1]) /
00735 float(this->height()) * this->trackballFactor;
00736
00737 yf = pow( 1.1, yf );
00738
00739 this->currentCamera->Dolly( yf );
00740 this->GetRenderer()->ResetCameraClippingRange();
00741
00742
00743 this->updateGL();
00744
00745
00746 this->lastMousePos[0] = this->currentMousePos[0];
00747 this->lastMousePos[1] = this->currentMousePos[1];
00748 }
00749
00750
00757 void RenderWindowInteractor::CameraRoll() {
00758 float angle;
00759
00760
00761 if( (this->currentMousePos[0] == this->lastMousePos[0]) &&
00762 (this->currentMousePos[1] == this->lastMousePos[1]) ) {
00763 return;
00764 }
00765
00766
00767 if( firstCall ) {
00768 this->renCenter[0] = this->GetRenderer()->GetCenter()[0];
00769 this->renCenter[1] = this->GetRenderer()->GetCenter()[1];
00770 this->renCenter[2] = this->GetRenderer()->GetCenter()[2];
00771 firstCall = false;
00772 }
00773
00774
00775 int diffX1 = this->currentMousePos[0] - int(this->renCenter[0]);
00776 int diffY1 = this->currentMousePos[1] - int(this->renCenter[1]);
00777 int diffX2 = this->lastMousePos[0] - int(this->renCenter[0]);
00778 int diffY2 = this->lastMousePos[1] - int(this->renCenter[1]);
00779
00780 double a1 = atan2( double(diffY1), double(diffX1) );
00781 double a2 = atan2( double(diffY2), double(diffX2) );
00782 angle = (a2 - a1) / (2.0 * 3.1415926535) * 360.0 / 10.0 *
00783 this->trackballFactor;
00784 this->currentCamera->Roll( angle );
00785
00786
00787 this->currentLight->SetPosition( this->currentCamera->GetPosition() );
00788 this->currentLight->SetFocalPoint( this->currentCamera->GetFocalPoint() );
00789
00790
00791 this->updateGL();
00792
00793
00794 this->lastMousePos[0] = this->currentMousePos[0];
00795 this->lastMousePos[1] = this->currentMousePos[1];
00796 }
00797
00798
00805 void RenderWindowInteractor::ActorPlaneMove() {
00806
00807 float *center;
00808 float dispCenter[4];
00809 float newP[4];
00810 float oldP[4];
00811 float p0[3],p1[3],t;
00812 float tkonstante = (this->normale[0])*(this->normale[0]) +
00813 (this->normale[1])*(this->normale[1]) +
00814 (this->normale[2])*(this->normale[2]) ;
00815
00816 if( (this->currentMousePos[0] == this->lastMousePos[0]) &&
00817 (this->currentMousePos[1] == this->lastMousePos[1]) ) {
00818 return;
00819 }
00820
00821 center = this->interactionActor->GetCenter();
00822 this->WorldToDisplay( center[0], center[1], center[2], dispCenter );
00823
00824 this->DisplayToWorld( float(this->currentMousePos[0]),
00825 float(this->height() - this->currentMousePos[1]),
00826 dispCenter[2],
00827 newP );
00828
00829 this->DisplayToWorld( float(this->lastMousePos[0]),
00830 float(this->height() - this->lastMousePos[1]),
00831 dispCenter[2],
00832 oldP);
00833
00834 oldP[3] = oldP[0]*(this->normale[0]) +
00835 oldP[1]*(this->normale[1]) +
00836 oldP[2]*(this->normale[2]) ;
00837
00838 t = (this->ebenekonstante - oldP[3])/tkonstante;
00839
00840 p0[0] = oldP[0] + t*(this->normale[0]);
00841 p0[1] = oldP[1] + t*(this->normale[1]);
00842 p0[2] = oldP[2] + t*(this->normale[2]);
00843
00844 newP[3] = newP[0]*(this->normale[0]) +
00845 newP[1]*(this->normale[1]) +
00846 newP[2]*(this->normale[2]);
00847
00848 t = (this->ebenekonstante - newP[3])/tkonstante;
00849
00850 p1[0] = newP[0] + t*(this->normale[0]);
00851 p1[1] = newP[1] + t*(this->normale[1]);
00852 p1[2] = newP[2] + t*(this->normale[2]);
00853
00854 this->interactionActor->AddPosition( p1[0]-p0[0],
00855 p1[1]-p0[1],
00856 p1[2]-p0[2] );
00857
00858 this->updateGL();
00859
00860
00861 this->lastMousePos[0] = this->currentMousePos[0];
00862 this->lastMousePos[1] = this->currentMousePos[1];
00863 }
00864
00865
00872 void RenderWindowInteractor::ActorPlaneRoll() {
00873
00874 float angle;
00875
00876
00877 if( (this->currentMousePos[0] == this->lastMousePos[0]) &&
00878 (this->currentMousePos[1] == this->lastMousePos[1]) ) {
00879 return;
00880 }
00881
00882
00883 if( firstCall ) {
00884 this->renCenter[0] = this->GetRenderer()->GetCenter()[0];
00885 this->renCenter[1] = this->GetRenderer()->GetCenter()[1];
00886 this->renCenter[2] = this->GetRenderer()->GetCenter()[2];
00887 firstCall = false;
00888 }
00889
00890 int diffX1 = this->currentMousePos[0] - int(this->renCenter[0]);
00891 int diffY1 = this->currentMousePos[1] - int(this->renCenter[1]);
00892 int diffX2 = this->lastMousePos[0] - int(this->renCenter[0]);
00893 int diffY2 = this->lastMousePos[1] - int(this->renCenter[1]);
00894
00895 double a1 = atan2( double(diffY1), double(diffX1) );
00896 double a2 = atan2( double(diffY2), double(diffX2) );
00897 angle = (a2 - a1) / (2.0 * 3.1415926535) * 360.0 / 10.0 *
00898 this->trackballFactor;
00899 this->interactionActor->RotateWXYZ( -angle, this->normale[0],
00900 this->normale[1],
00901 this->normale[2] );
00902
00903
00904 this->updateGL();
00905
00906
00907 this->lastMousePos[0] = this->currentMousePos[0];
00908 this->lastMousePos[1] = this->currentMousePos[1];
00909
00910 }
00911
00912
00918 void RenderWindowInteractor::DoNothing() {
00919 }
00920
00921
00930 void RenderWindowInteractor::DisplayToWorld( float x, float y, float z,
00931 float *worldPoint ) {
00932 this->GetRenderer()->SetDisplayPoint( x, y, z );
00933 this->GetRenderer()->DisplayToWorld();
00934 this->GetRenderer()->GetWorldPoint( worldPoint );
00935
00936
00937 if (worldPoint[3]) {
00938 worldPoint[0] = worldPoint[0] / worldPoint[3];
00939 worldPoint[1] = worldPoint[1] / worldPoint[3];
00940 worldPoint[2] = worldPoint[2] / worldPoint[3];
00941 worldPoint[3] = 1.0;
00942 }
00943 }
00944
00945
00954 void RenderWindowInteractor::WorldToDisplay( float x, float y, float z,
00955 float *displayPoint ) {
00956 this->GetRenderer()->SetWorldPoint(x, y, z, 1.0 );
00957 this->GetRenderer()->WorldToDisplay();
00958 this->GetRenderer()->GetDisplayPoint( displayPoint );
00959 }