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