TEveLegoEventHandler.cxx

Go to the documentation of this file.
00001 /*************************************************************************
00002  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
00003  * All rights reserved.                                                  *
00004  *                                                                       *
00005  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00006  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00007  *************************************************************************/
00008 
00009 
00010 #include "TEveLegoEventHandler.h"
00011 #include "TEveCaloLegoGL.h"
00012 
00013 #include "TGLViewer.h"
00014 #include "TGLWidget.h"
00015 #include "TGLOverlay.h"
00016 #include "TGLLogicalShape.h"
00017 #include "TGLPhysicalShape.h"
00018 #include "TGLCamera.h"
00019 #include "TGLPerspectiveCamera.h"
00020 #include "TGLOrthoCamera.h"
00021 #include "KeySymbols.h"
00022 
00023 #include "TMath.h"
00024 #include "TGLUtil.h"
00025 #include "TEveTrans.h"
00026 
00027 #include "TEveCalo.h"
00028 
00029 
00030 //==============================================================================
00031 //==============================================================================
00032 // TEveLegoEventHandler
00033 //==============================================================================
00034 
00035 ClassImp(TEveLegoEventHandler);
00036 
00037 //______________________________________________________________________________
00038 //
00039 // A base class of TGLEventHandler. Switches current camera from perspective
00040 // to orthographic bird-view, if camera theta is less than given threshold. It sets back
00041 // perspective camera when accumulated angle is more than transition theta.
00042 //
00043 
00044 //______________________________________________________________________________
00045 TEveLegoEventHandler::TEveLegoEventHandler(TGWindow *w, TObject *obj, TEveCaloLego *lego):
00046    TGLEventHandler(w, obj),
00047 
00048    fMode(kFree),
00049    fTransTheta(0.5f),
00050    fTheta(0.f),
00051 
00052    fLego(lego)
00053 {
00054    // Constructor.
00055 }
00056 
00057 //______________________________________________________________________________
00058 Bool_t TEveLegoEventHandler::HandleKey(Event_t *event)
00059 {
00060    // Virtual from TGLEventHandler.
00061    // Free the camera when home is pressed.
00062 
00063    if (event->fCode == kKey_Home)
00064       fMode = kFree;
00065 
00066    return TGLEventHandler::HandleKey(event);
00067 }
00068 
00069 //______________________________________________________________________________
00070 Bool_t TEveLegoEventHandler::Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
00071 {
00072    // Method to handle action TGLViewer::kDragCameraRotate. It switches from standard perspective
00073    // view to bird-view bellow angle fTransTheta and restores view when accumulated theta is larger
00074    // than transition angle.
00075 
00076    if ( !fLego ) return TGLEventHandler::Rotate(xDelta, yDelta, mod1, mod2);
00077 
00078    TGLCamera &cam =  fGLViewer->GetRnrCtx()->RefCamera();
00079    Double_t hRotate = cam.AdjustDelta(-yDelta, TMath::Pi()/cam.RefViewport().Height(), mod1, mod2);
00080 
00081    // get lego bounding box
00082    Float_t *bb = fLego->AssertBBox();
00083    TGLBoundingBox box;
00084    box.SetAligned(TGLVertex3(bb[0], bb[2], bb[4]), TGLVertex3(bb[1], bb[3], bb[5]));
00085    box.Transform(fLego->RefMainTrans().Array());
00086 
00087    Bool_t camChanged = kFALSE;
00088 
00089    if (cam.IsOrthographic())
00090    {
00091       fTheta += hRotate;
00092       if (fTheta < 0) fTheta = 0;
00093       if (fTheta > fTransTheta)
00094       {
00095          TGLCamera* ortho = &cam;
00096          Double_t l = -ortho->FrustumPlane(TGLCamera::kLeft).D();
00097          Double_t r =  ortho->FrustumPlane(TGLCamera::kRight).D();
00098          Double_t t =  ortho->FrustumPlane(TGLCamera::kTop).D();
00099          Double_t b = -ortho->FrustumPlane(TGLCamera::kBottom).D();
00100 
00101          fGLViewer->SetCurrentCamera(TGLViewer::kCameraPerspXOY);
00102          TGLPerspectiveCamera* persp = dynamic_cast<TGLPerspectiveCamera*>(&fGLViewer->GetRnrCtx()->RefCamera());
00103          persp->Setup(box, kTRUE);
00104 
00105          TGLVector3 extents = box.Extents();
00106          Int_t sortInd[3];
00107          TMath::Sort(3, extents.CArr(), sortInd);
00108          Double_t size = TMath::Hypot(extents[sortInd[0]], extents[sortInd[1]]);
00109          Double_t dolly  = size / (2.0*TMath::Tan(30*TMath::Pi()/360));
00110          Double_t fov = TMath::ATan(TMath::Hypot(t-b, r-l)/(2*dolly));
00111 
00112          persp->SetCenterVecWarp(0.5*(l+r), 0.5*(t+b), 0);
00113 
00114          Double_t vR =  -0.5 * TMath::Pi(); // switch XY
00115          Double_t hR =  -0.5 * TMath::Pi() + fTransTheta; // fix top view angle
00116          persp->Configure(fov*TMath::RadToDeg(), 0, 0, hR, vR);
00117 
00118          fMode = kFree;
00119          camChanged = kTRUE;
00120       }
00121    }
00122    else
00123    {
00124       Double_t theta  = cam.GetTheta();
00125       Double_t thetaN = theta + hRotate;
00126       if (thetaN > TMath::Pi() - cam.GetVAxisMinAngle()) thetaN = TMath::Pi() - cam.GetVAxisMinAngle();
00127       else if (thetaN < cam.GetVAxisMinAngle())   thetaN = cam.GetVAxisMinAngle();
00128 
00129       fTheta = thetaN;
00130 
00131       if (thetaN < fTransTheta)
00132       {
00133          TGLPerspectiveCamera* persp =  (TGLPerspectiveCamera*)(&cam);
00134          fGLViewer->SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
00135          TGLOrthoCamera* ortho = dynamic_cast<TGLOrthoCamera*>(& fGLViewer->GetRnrCtx()->RefCamera());
00136          ortho->Setup(box,  kTRUE);
00137 
00138          // translation to the plane intersect
00139          const TGLMatrix& mx =  cam.GetCamBase() * cam.GetCamTrans();
00140          TGLVertex3 d   = mx.GetTranslation();
00141          TGLVertex3 p = d + mx.GetBaseVec(1);
00142          TGLLine3  line(d, p);
00143          const TGLPlane rp = TGLPlane(cam.GetCamBase().GetBaseVec(3), TGLVertex3());
00144          std::pair<Bool_t, TGLVertex3> intersection;
00145          intersection = Intersection(rp, line, kTRUE);
00146          TGLVertex3 v = intersection.second;
00147          ortho->Truck( v.X() - box.Center().X(), v.Y() - box.Center().Y());
00148 
00149          // zoom
00150          Double_t t =  persp->FrustumPlane(TGLCamera::kTop).D();
00151          Double_t b = -persp->FrustumPlane(TGLCamera::kBottom).D();
00152          Double_t zoom = box.Extents().Y()/(t-b);
00153          ortho->Configure(zoom, 0, 0, 0, 0);
00154 
00155          fMode = kLocked;
00156          camChanged = kTRUE;
00157       }
00158       else
00159       {
00160          camChanged = fGLViewer->CurrentCamera().Rotate(xDelta, -yDelta, mod1, mod2);
00161       }
00162    }
00163    return camChanged;
00164 }

Generated on Tue Jul 5 14:16:12 2011 for ROOT_528-00b_version by  doxygen 1.5.1