00001
00002
00003
00004
00005
00006
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
00033
00034
00035 ClassImp(TEveLegoEventHandler);
00036
00037
00038
00039
00040
00041
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
00055 }
00056
00057
00058 Bool_t TEveLegoEventHandler::HandleKey(Event_t *event)
00059 {
00060
00061
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
00073
00074
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
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();
00115 Double_t hR = -0.5 * TMath::Pi() + fTransTheta;
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
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
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 }