Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGLCamera.h
Go to the documentation of this file.
1 // @(#)root/gl:$Id$
2 // Author: Richard Maunder 25/05/2005
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TGLCamera
13 #define ROOT_TGLCamera
14 
15 #include "TGLUtil.h"
16 #include "TGLBoundingBox.h"
17 #include "TPoint.h"
18 #include "TObject.h"
19 
20 #include <cassert>
21 #include <cmath>
22 
23 //////////////////////////////////////////////////////////////////////////
24 // //
25 // TGLCamera //
26 // //
27 // Abstract base camera class - concrete classes for orthographic and //
28 // persepctive cameras derive from it. This class maintains values for //
29 // the current: //
30 // i) Viewport //
31 // ii) Projection, modelview and clip matricies - extracted from GL //
32 // iii) The 6 frustum planes //
33 // iv) Expanded frustum interest box //
34 // //
35 // It provides methods for various projection, overlap and intersection //
36 // tests for viewport and world locations, against the true frustum and //
37 // expanded interest box, and for extracting eye position and direction.//
38 // //
39 // It also defines the pure virtual manipulation interface methods the //
40 // concrete ortho and prespective classes must implement. //
41 //////////////////////////////////////////////////////////////////////////
42 
43 class TGLCamera : public TObject
44 {
45 public:
46  enum EFrustumPlane
47  {
48  kNear = 0,
49  kLeft = 1,
50  kRight = 2,
51  kTop = 3,
52  kBottom = 4,
53  kFar = 5,
54  kPlanesPerFrustum = 6
55  };
56 
57 private:
58  // Fields
59 
60  // Debuging visual aids
61  TGLBoundingBox fPreviousInterestBox; //! previous interest box (DEBUG)
62  TGLBoundingBox fInterestFrustum; //! frustum basis of current interest box - NOT a true BB! (DEBUG)
63  TGLBoundingBox fInterestFrustumAsBox; //! frustum basis (as box) of current interest box (DEBUG)
64 
65  static const Double_t fgInterestBoxExpansion; //! expansion c.f. aligned current frustum box
66 
67  // Methods
68  TGLBoundingBox Frustum(Bool_t asBox = kTRUE) const; // current frustum
69 
70  // Non-copyable class
71  TGLCamera(const TGLCamera &);
72  TGLCamera & operator=(const TGLCamera &);
73 
74 protected:
75  // Fields
76  TGLMatrix fCamBase; // tranformation to center and rotation from up to x vector
77  TGLMatrix fCamTrans; // transformation relative to fCamTrans
78  Bool_t fExternalCenter; // use external center insead of scene center
79  Bool_t fFixDefCenter; // use fixed default center
80  Bool_t fWasArcBalled; // set when arc-ball rotation is used
81  TGLVector3 fExtCenter; // external camera center
82  TGLVector3 fDefCenter; // default camera center
83  TGLVector3 fFDCenter; // fixed default camera center
84  TGLVector3 *fCenter; //! current camera center
85 
86  mutable Double_t fNearClip; //! last applied near-clip
87  mutable Double_t fFarClip; //! last applied far-clip
88 
89  // Set in Setup()
90  Double_t fDollyDefault; // default distnce from viewing centre
91  Double_t fDollyDistance; // unit distance for camera movement in fwd/bck direction
92  Float_t fVAxisMinAngle; // minimal allowed angle between up and fCamTrans Z vector
93 
94  // Internal cached matrices and frustum planes
95  mutable Bool_t fCacheDirty; //! cached items dirty?
96  mutable UInt_t fTimeStamp; //! timestamp
97  mutable TGLMatrix fLastNoPickProjM; //! no-pick projection matrix (cached)
98  mutable TGLMatrix fProjM; //! projection matrix (cached)
99  mutable TGLMatrix fModVM; //! modelView matrix (cached)
100  mutable TGLMatrix fClipM; //! object space clip matrix (cached)
101  mutable TGLPlane fFrustumPlanes[kPlanesPerFrustum]; //! frustum planes (cached)
102 
103  TGLRect fViewport; //! viewport (GL coords - origin bottom left)
104 
105  TGLBoundingBox fInterestBox; //! the interest box - created in UpdateInterest()
106  mutable Double_t fLargestSeen; //! largest box diagonal seen in OfInterest() - used when
107  //! bootstrapping interest box
108 
109  // Internal cache update - const as the actual camera configuration is unaffected
110  void UpdateCache() const;
111 
112  static UInt_t fgDollyDeltaSens;
113 public:
114  TGLCamera();
115  TGLCamera(const TGLVector3 & hAxis, const TGLVector3 & vAxis);
116  virtual ~TGLCamera();
117 
118  virtual Bool_t IsOrthographic() const { return kFALSE; }
119  virtual Bool_t IsPerspective() const { return kFALSE; }
120 
121  const TGLMatrix& RefModelViewMatrix() const { return fModVM; }
122 
123  Bool_t IsCacheDirty() const { return fCacheDirty; }
124  void IncTimeStamp() { fCacheDirty = kTRUE; ++fTimeStamp; }
125  UInt_t TimeStamp() const { return fTimeStamp; }
126 
127  void SetViewport(const TGLRect & viewport);
128  TGLRect& RefViewport() { return fViewport; }
129  const TGLRect& RefViewport() const { return fViewport; }
130 
131  // Camera manipulation interface (GL coord - origin bottom left)
132  virtual void Setup(const TGLBoundingBox & box, Bool_t reset=kTRUE) = 0;
133  virtual void Reset() = 0;
134 
135  virtual Bool_t Dolly(Int_t delta, Bool_t mod1, Bool_t mod2);
136  virtual Bool_t Zoom (Int_t delta, Bool_t mod1, Bool_t mod2) = 0;
137  virtual Bool_t Truck(Double_t xDelta, Double_t yDelta);
138  virtual Bool_t Truck(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2) = 0;
139  virtual Bool_t Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2);
140  virtual Bool_t RotateRad(Double_t hRotate, Double_t vRotate);
141  virtual Bool_t RotateArcBall(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2);
142  virtual Bool_t RotateArcBallRad(Double_t hRotate, Double_t vRotate);
143 
144  virtual void Apply(const TGLBoundingBox & sceneBox, const TGLRect * pickRect = 0) const = 0;
145 
146  Bool_t AdjustAndClampVal(Double_t & val, Double_t min, Double_t max,
147  Int_t screenShift, Int_t screenShiftRange,
148  Bool_t mod1, Bool_t mod2) const;
149  Double_t AdjustDelta(Double_t screenShift, Double_t deltaFactor,
150  Bool_t mod1, Bool_t mod2) const;
151 
152  void SetExternalCenter(Bool_t x);
153  Bool_t GetExternalCenter(){ return fExternalCenter; }
154 
155  void SetCenterVec(Double_t x, Double_t y, Double_t z);
156  void SetCenterVecWarp(Double_t x, Double_t y, Double_t z);
157  Double_t* GetCenterVec() { return fCenter->Arr(); }
158 
159  void SetFixDefCenter(Bool_t x) { fFixDefCenter = x; }
160  void SetFixDefCenterVec(Double_t x, Double_t y, Double_t z) { fFDCenter.Set(x, y, z); }
161  Double_t* GetFixDefCenterVec() { return fFDCenter.Arr(); }
162 
163  Double_t GetNearClip() const { return fNearClip; }
164  Double_t GetFarClip() const { return fFarClip; }
165 
166  const TGLMatrix& GetCamBase() const { return fCamBase; }
167  const TGLMatrix& GetCamTrans() const { return fCamTrans; }
168  // If you manipulate camera ... also call IncTimeStamp() before redraw.
169  TGLMatrix& RefCamBase() { return fCamBase; }
170  TGLMatrix& RefCamTrans() { return fCamTrans; }
171 
172  Double_t GetTheta() const;
173 
174  TGLMatrix& RefLastNoPickProjM() const { return fLastNoPickProjM; }
175 
176  // Current orientation and frustum
177  TGLVertex3 EyePoint() const;
178  TGLVector3 EyeDirection() const;
179  TGLVertex3 FrustumCenter() const;
180  const TGLPlane & FrustumPlane(EFrustumPlane plane) const;
181 
182  // Overlap / projection / intersection tests
183  // Viewport is GL coorinate system - origin bottom/left
184  Rgl::EOverlap FrustumOverlap (const TGLBoundingBox & box) const; // box/frustum overlap test
185  Rgl::EOverlap ViewportOverlap(const TGLBoundingBox & box) const; // box/viewport overlap test
186  TGLRect ViewportRect (const TGLBoundingBox & box, TGLBoundingBox::EFace face) const;
187  TGLRect ViewportRect (const TGLBoundingBox & box, const TGLBoundingBox::EFace * face = 0) const;
188  TGLVertex3 WorldToViewport(const TGLVertex3 & worldVertex, TGLMatrix* modviewMat=0) const;
189  TGLVector3 WorldDeltaToViewport(const TGLVertex3 & worldRef, const TGLVector3 & worldDelta) const;
190  TGLVertex3 ViewportToWorld(const TGLVertex3 & viewportVertex, TGLMatrix* modviewMat=0) const;
191  TGLLine3 ViewportToWorld(Double_t viewportX, Double_t viewportY) const;
192  TGLLine3 ViewportToWorld(const TPoint & viewport) const;
193  TGLVector3 ViewportDeltaToWorld(const TGLVertex3 & worldRef, Double_t viewportXDelta, Double_t viewportYDelta, TGLMatrix* modviewMat=0) const;
194  std::pair<Bool_t, TGLVertex3> ViewportPlaneIntersection(Double_t viewportX, Double_t viewportY, const TGLPlane & worldPlane) const;
195  std::pair<Bool_t, TGLVertex3> ViewportPlaneIntersection(const TPoint & viewport, const TGLPlane & worldPlane) const;
196 
197  // Window to GL viewport conversion - invert Y
198  void WindowToViewport(Int_t & /* x */, Int_t & y) const { y = fViewport.Height() - y; }
199  void WindowToViewport(TPoint & point) const { point.SetY(fViewport.Height() - point.GetY()); }
200  void WindowToViewport(TGLRect & rect) const { rect.Y() = fViewport.Height() - rect.Y(); }
201  void WindowToViewport(TGLVertex3 & vertex) const { vertex.Y() = fViewport.Height() - vertex.Y(); }
202 
203  Float_t GetVAxisMinAngle(){return fVAxisMinAngle;}
204  void SetVAxisMinAngle(Float_t x){fVAxisMinAngle = x;}
205 
206  virtual void Configure(Double_t zoom, Double_t dolly, Double_t center[3],
207  Double_t hRotate, Double_t vRotate) = 0;
208  // Cameras expanded-frustum interest box
209  Bool_t OfInterest(const TGLBoundingBox & box, Bool_t ignoreSize) const;
210  Bool_t UpdateInterest(Bool_t force);
211  void ResetInterest();
212 
213  // Debuging - draw frustum and interest boxes
214  void DrawDebugAids() const;
215 
216  ClassDef(TGLCamera,1); // Camera abstract base class.
217 };
218 
219 inline const TGLPlane & TGLCamera::FrustumPlane(EFrustumPlane plane) const
220 {
221  // Return one of the planes forming the camera frustum
222  if (fCacheDirty) {
223  Error("TGLCamera::FrustumBox()", "cache dirty");
224  }
225  return fFrustumPlanes[plane];
226 }
227 
228 
229 #endif // ROOT_TGLCamera