TGLOrthoCamera.cxx

Go to the documentation of this file.
00001 // @(#)root/gl:$Id: TGLOrthoCamera.cxx 33864 2010-06-14 09:47:19Z matevz $
00002 // Author:  Richard Maunder  25/05/2005
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "TMath.h"
00013 
00014 #include "TGLOrthoCamera.h"
00015 #include "TGLIncludes.h"
00016 #include "TGLUtil.h"
00017 
00018 
00019 //////////////////////////////////////////////////////////////////////////
00020 //                                                                      //
00021 // TGLOrthoCamera                                                       //
00022 //                                                                      //
00023 // Orthographic projection camera. Currently limited to three types     //
00024 // defined at construction time - kXOY, kXOZ, kZOY - where this refers  //
00025 // to the viewport plane axis - e.g. kXOY has X axis horizontal, Y      //
00026 // vertical - i.e. looking down Z axis with Y vertical.                 //
00027 //
00028 // The plane types restriction could easily be removed to supported     //
00029 // arbitary ortho projections along any axis/orientation with free      //
00030 // rotations about them.                                                //
00031 //                                                                      //
00032 //////////////////////////////////////////////////////////////////////////
00033 
00034 ClassImp(TGLOrthoCamera)
00035 
00036 UInt_t   TGLOrthoCamera::fgZoomDeltaSens = 500;
00037 
00038 //______________________________________________________________________________
00039 TGLOrthoCamera::TGLOrthoCamera(EType type, const TGLVector3 & hAxis, const TGLVector3 & vAxis) :
00040    TGLCamera(hAxis, vAxis),
00041    fType(type),
00042    fEnableRotate(kFALSE), fDollyToZoom(kTRUE),
00043    fZoomMin(0.001), fZoomDefault(0.78), fZoomMax(1000.0),
00044    fVolume(TGLVertex3(-100.0, -100.0, -100.0), TGLVertex3(100.0, 100.0, 100.0)),
00045    fZoom(1.0)
00046 {
00047    // Construct orthographic camera.
00048 
00049    Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100)));
00050 }
00051 
00052 //______________________________________________________________________________
00053 TGLOrthoCamera::~TGLOrthoCamera()
00054 {
00055    // Destroy orthographic camera.
00056 }
00057 
00058 //______________________________________________________________________________
00059 void TGLOrthoCamera::Setup(const TGLBoundingBox & box, Bool_t reset)
00060 {
00061    // Setup camera limits suitible to view the world volume defined by 'box'
00062    // and call Reset() to initialise camera.
00063 
00064    fVolume = box;
00065 
00066    if (fExternalCenter == kFALSE)
00067    {
00068       if (fFixDefCenter)
00069       {
00070          SetCenterVec(fFDCenter.X(), fFDCenter.Y(), fFDCenter.Z());
00071       }
00072       else
00073       {
00074          TGLVertex3 center = box.Center();
00075          SetCenterVec(center.X(), center.Y(), center.Z());
00076       }
00077    }
00078    if (reset)
00079       Reset();
00080 }
00081 
00082 //______________________________________________________________________________
00083 void TGLOrthoCamera::Reset()
00084 {
00085    // Reset the camera to defaults - trucking, zooming to reframe the world volume
00086    // established in Setup(). Note: limits defined in Setup() are not adjusted.
00087 
00088    TGLVector3 e = fVolume.Extents();
00089    switch (fType) {
00090       case kXOY:
00091       case kXnOY:
00092       {
00093          // X -> X, Y -> Y, Z -> Z
00094          fDefXSize = e.X(); fDefYSize = e.Y();
00095          break;
00096       }
00097       case kXOZ:
00098       case kXnOZ:
00099       {
00100          // X -> X, Z -> Y, Y -> Z
00101          fDefXSize = e.X(); fDefYSize = e.Z();
00102          break;
00103       }
00104 
00105       case kZOY:
00106       case kZnOY:
00107       {
00108          // Z -> X, Y -> Y, X -> Z
00109          fDefXSize = e.Z(); fDefYSize = e.Y();
00110          break;
00111       }
00112    }
00113 
00114    fDollyDefault  = 1.25*0.5*TMath::Sqrt(3)*fVolume.Extents().Mag();
00115    fDollyDistance = 0.002 * fDollyDefault;
00116    fZoom   = fZoomDefault;
00117    fCamTrans.SetIdentity();
00118    fCamTrans.MoveLF(1, fDollyDefault);
00119    IncTimeStamp();
00120 }
00121 
00122 //______________________________________________________________________________
00123 Bool_t TGLOrthoCamera::Dolly(Int_t delta, Bool_t mod1, Bool_t mod2)
00124 {
00125    // Dolly the camera.
00126    // By default the dolly is reinterpreted to zoom, but it can be
00127    // changed by modifying the fDollyToZoom data-member.
00128 
00129    if (fDollyToZoom) {
00130       return Zoom(delta, mod1, mod2);
00131    } else {
00132       return TGLCamera::Dolly(delta, mod1, mod2);
00133    }
00134 }
00135 
00136 //______________________________________________________________________________
00137 Bool_t TGLOrthoCamera::Zoom(Int_t delta, Bool_t mod1, Bool_t mod2)
00138 {
00139    // Zoom the camera - 'adjust lens focal length, retaining camera position'.
00140    // Arguments are:
00141    //
00142    // 'delta' - mouse viewport delta (pixels) - +ive zoom in, -ive zoom out
00143    // 'mod1' / 'mod2' - sensitivity modifiers - see TGLCamera::AdjustAndClampVal()
00144    //
00145    // For an orthographic camera dollying and zooming are identical and both equate
00146    // logically to a rescaling of the viewport limits - without center shift.
00147    // There is no perspective foreshortening or lens 'focal length'.
00148    //
00149    // Returns kTRUE is redraw required (camera change), kFALSE otherwise.
00150 
00151    if (AdjustAndClampVal(fZoom, fZoomMin, fZoomMax, -delta*2, fgZoomDeltaSens, mod1, mod2))
00152    {
00153       IncTimeStamp();
00154       return kTRUE;
00155    }
00156    else
00157    {
00158       return kFALSE;
00159    }
00160 }
00161 
00162 //______________________________________________________________________________
00163 void TGLOrthoCamera::SetZoomMin(Double_t z)
00164 {
00165    // Set minimum zoom factor. If current zoom is less than z it is
00166    // set to z.
00167 
00168    fZoomMin = z;
00169    if (fZoom < fZoomMin) {
00170       fZoom = fZoomMin;
00171       IncTimeStamp();
00172    }
00173 }
00174 
00175 //______________________________________________________________________________
00176 void TGLOrthoCamera::SetZoomMax(Double_t z)
00177 {
00178    // Set maximum zoom factor. If current zoom is greater than z it
00179    // is set to z.
00180 
00181    fZoomMax = z;
00182    if (fZoom > fZoomMax) {
00183       fZoom = fZoomMax;
00184       IncTimeStamp();
00185    }
00186 }
00187 
00188 //______________________________________________________________________________
00189 Bool_t TGLOrthoCamera::Truck(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
00190 {
00191    // Truck the camera - 'move camera parallel to film plane'.
00192    // Returns kTRUE is redraw required (camera change), kFALSE otherwise.
00193 
00194    Double_t xstep = 2.0 * xDelta / fProjM[0] / fViewport.Width();
00195    Double_t ystep = 2.0 * yDelta / fProjM[5] / fViewport.Height();
00196 
00197    xstep = AdjustDelta(xstep, 1.0, mod1, mod2);
00198    ystep = AdjustDelta(ystep, 1.0, mod1, mod2);
00199 
00200    return Truck(-xstep, -ystep);
00201 }
00202 
00203 //______________________________________________________________________________
00204 Bool_t TGLOrthoCamera::Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
00205 {
00206    // Rotate the camera - 'swivel round the view volume center'.
00207    // Returns kTRUE is redraw required (camera change), kFALSE otherwise.
00208 
00209    if (fEnableRotate)
00210       return TGLCamera::Rotate(xDelta, yDelta, mod1, mod2);
00211    else
00212       return kFALSE;
00213 }
00214 
00215 //______________________________________________________________________________
00216 void TGLOrthoCamera::Apply(const TGLBoundingBox & /*box*/,
00217                            const TGLRect        * pickRect) const
00218 {
00219    // Apply the camera to the current GL context, setting the viewport, projection
00220    // and modelview matricies. After this verticies etc can be directly entered
00221    // in the world frame. This also updates the cached frustum values, enabling
00222    // all the projection, overlap tests etc defined in TGLCamera to be used.
00223    //
00224    // Arguments are:
00225    // 'box' - view volume box - ignored for ortho camera. Assumed to be same
00226    // as one passed to Setup().
00227    // 'pickRect' - optional picking rect. If non-null, restrict drawing to this
00228    // viewport rect.
00229 
00230    glViewport(fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height());
00231 
00232    if(fViewport.Width() == 0 || fViewport.Height() == 0)
00233    {
00234       glMatrixMode(GL_PROJECTION);
00235       glLoadIdentity();
00236       glMatrixMode(GL_MODELVIEW);
00237       glLoadIdentity();
00238       return;
00239    }
00240 
00241    glMatrixMode(GL_PROJECTION);
00242    glLoadIdentity();
00243 
00244    // Load up any picking rect
00245    if (pickRect)
00246    {
00247       TGLRect rect(*pickRect);
00248       WindowToViewport(rect);
00249       gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
00250                     (Int_t*) fViewport.CArr());
00251    }
00252 
00253    Double_t halfRangeX, halfRangeY;
00254    if (fDefYSize*fViewport.Width()/fDefXSize > fViewport.Height()) {
00255       halfRangeY = 0.5 *fDefYSize;
00256       halfRangeX = halfRangeY*fViewport.Width()/fViewport.Height();
00257    } else {
00258       halfRangeX = 0.5 *fDefXSize;
00259       halfRangeY = halfRangeX*fViewport.Height()/fViewport.Width();
00260    }
00261 
00262    halfRangeX /= fZoom;
00263    halfRangeY /= fZoom;
00264 
00265    fNearClip = 0.05*fDollyDefault;
00266    fFarClip  = 2.0*fDollyDefault;
00267    glOrtho(-halfRangeX, halfRangeX,
00268            -halfRangeY, halfRangeY,
00269             fNearClip,  fFarClip);
00270 
00271    if (!pickRect) glGetDoublev(GL_PROJECTION_MATRIX, fLastNoPickProjM.Arr());
00272 
00273    // ii) setup modelview
00274    glMatrixMode(GL_MODELVIEW);
00275    glLoadIdentity();
00276    TGLMatrix  mx     = fCamBase*fCamTrans;
00277    TGLVector3 pos    = mx.GetTranslation();
00278    TGLVector3 fwd    = mx.GetBaseVec(1);
00279    TGLVector3 center = pos - fwd;
00280    TGLVector3 up     = fCamBase.GetBaseVec(3);
00281 
00282    gluLookAt(pos[0],    pos[1],    pos[2],
00283              center[0], center[1], center[2],
00284              up[0],     up[1],     up[2]);
00285 
00286    if (fCacheDirty) UpdateCache();
00287 }
00288 
00289 //______________________________________________________________________________
00290 void TGLOrthoCamera::Configure(Double_t zoom, Double_t dolly, Double_t center[3],
00291                                Double_t hRotate, Double_t vRotate)
00292 {
00293    // Configure the camera state.
00294    //   zoom    - set directly (default = 0.78);
00295    //   dolly   - additional move along the camera forward direction;
00296    //   center  - new camera center (can be 0 for no change);
00297    //   hRotate - additional "up/down" rotation in radians;
00298    //   vRotate - additional "left/right" rotation in radians.
00299 
00300    fZoom = zoom;
00301 
00302    if (center)
00303       SetCenterVec(center[0], center[1], center[2]);
00304 
00305    fCamTrans.MoveLF(1, dolly);
00306    RotateRad(hRotate, vRotate);
00307 
00308    IncTimeStamp();
00309 }

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