24 ClassImp(TGLPerspectiveCamera);
26 Double_t TGLPerspectiveCamera::fgFOVMin = 0.01;
27 Double_t TGLPerspectiveCamera::fgFOVDefault = 30;
28 Double_t TGLPerspectiveCamera::fgFOVMax = 120.0;
29 UInt_t TGLPerspectiveCamera::fgFOVDeltaSens = 500;
34 TGLPerspectiveCamera::TGLPerspectiveCamera() :
35 TGLCamera(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)),
38 Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100)));
39 fCamTrans.MoveLF(1, fDollyDefault);
45 TGLPerspectiveCamera::TGLPerspectiveCamera(
const TGLVector3 & hAxes,
const TGLVector3 & vAxes) :
46 TGLCamera(hAxes, vAxes),
49 Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100)));
50 fCamTrans.MoveLF(1, fDollyDefault);
56 TGLPerspectiveCamera::~TGLPerspectiveCamera()
64 void TGLPerspectiveCamera::Setup(
const TGLBoundingBox & box, Bool_t reset)
66 if (fExternalCenter == kFALSE)
70 SetCenterVec(fFDCenter.X(), fFDCenter.Y(), fFDCenter.Z());
74 TGLVertex3 center = box.Center();
75 SetCenterVec(center.X(), center.Y(), center.Z());
80 TGLVector3 extents = box.Extents();
82 TMath::Sort(3, extents.CArr(), sortInd);
83 Double_t size = TMath::Hypot(extents[sortInd[0]], extents[sortInd[1]]);
84 Double_t fov = TMath::Min(fgFOVDefault, fgFOVDefault*fViewport.Aspect());
86 fDollyDefault = size / (2.0*TMath::Tan(fov*TMath::Pi()/360));
87 fDollyDistance = 0.002 * fDollyDefault;
99 void TGLPerspectiveCamera::Reset()
103 fCamTrans.SetIdentity();
104 fCamTrans.MoveLF(1, fDollyDefault);
118 Bool_t TGLPerspectiveCamera::Zoom(Int_t delta, Bool_t mod1, Bool_t mod2)
122 if (AdjustAndClampVal(fFOV, fgFOVMin, fgFOVMax, delta, fgFOVDeltaSens, mod1, mod2)) {
134 Bool_t TGLPerspectiveCamera::Truck(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
136 Double_t lenMidClip = 0.5 * (fFarClip + fNearClip) * TMath::Tan(0.5*fFOV*TMath::DegToRad());
138 Double_t xstep = xDelta * lenMidClip / fViewport.Height();
139 Double_t ystep = yDelta * lenMidClip / fViewport.Height();
141 xstep = AdjustDelta(xstep, 1.0, mod1, mod2);
142 ystep = AdjustDelta(ystep, 1.0, mod1, mod2);
144 return Truck(-xstep, -ystep);
158 void TGLPerspectiveCamera::Apply(
const TGLBoundingBox & sceneBox,
159 const TGLRect * pickRect)
const
172 glViewport(fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height());
174 if(fViewport.Width() == 0 || fViewport.Height() == 0)
176 glMatrixMode(GL_PROJECTION);
178 glMatrixMode(GL_MODELVIEW);
183 glMatrixMode(GL_PROJECTION);
189 gluPerspective(fFOV, fViewport.Aspect(), 1.0, 1000.0);
193 glMatrixMode(GL_MODELVIEW);
195 TGLMatrix mx = fCamBase*fCamTrans;
196 TGLVector3 pos = mx.GetTranslation();
197 TGLVector3 fwd = mx.GetBaseVec(1);
198 TGLVector3 center = pos - fwd;
199 TGLVector3 up = mx.GetBaseVec(3);
201 gluLookAt(pos[0], pos[1], pos[2],
202 center[0], center[1], center[2],
203 up[0], up[1], up[2]);
206 Bool_t modifiedCache = kFALSE;
209 modifiedCache = kTRUE;
213 TGLPlane clipPlane(EyeDirection(), EyePoint());
214 fCacheDirty = modifiedCache;
219 Double_t currentDist;
220 for (UInt_t i=0; i<8; i++) {
221 currentDist = clipPlane.DistanceTo(sceneBox[i]);
224 fNearClip = currentDist;
225 fFarClip = fNearClip;
227 if (currentDist < fNearClip)
228 fNearClip = currentDist;
229 if (currentDist > fFarClip)
230 fFarClip = currentDist;
237 if (fNearClip < fFarClip/1000.0)
238 fNearClip = fFarClip/1000.0;
240 glMatrixMode(GL_PROJECTION);
247 TGLRect rect(*pickRect);
248 WindowToViewport(rect);
249 gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
250 (Int_t*) fViewport.CArr());
251 gluPerspective(fFOV, fViewport.Aspect(), fNearClip, fFarClip);
255 gluPerspective(fFOV, fViewport.Aspect(), fNearClip, fFarClip);
256 glGetDoublev(GL_PROJECTION_MATRIX, fLastNoPickProjM.Arr());
259 glMatrixMode(GL_MODELVIEW);
261 if (fCacheDirty) UpdateCache();
272 void TGLPerspectiveCamera::Configure(Double_t fov, Double_t dolly, Double_t center[3],
273 Double_t hRotate, Double_t vRotate)
283 }
else if (fFOV < 0.1) {
288 SetCenterVec(center[0], center[1], center[2]);
290 fCamTrans.MoveLF(1, dolly);
291 RotateRad(hRotate, vRotate);