#include "TGLPerspectiveCamera.h"
#include "TGLUtil.h"
#include "TGLIncludes.h"
#include "TMath.h"
#include "TError.h"
ClassImp(TGLPerspectiveCamera)
Double_t TGLPerspectiveCamera::fgFOVMin = 0.01;
Double_t TGLPerspectiveCamera::fgFOVDefault = 30;
Double_t TGLPerspectiveCamera::fgFOVMax = 120.0;
UInt_t TGLPerspectiveCamera::fgFOVDeltaSens = 500;
TGLPerspectiveCamera::TGLPerspectiveCamera(const TGLVector3 & hAxes, const TGLVector3 & vAxes) :
TGLCamera(hAxes, vAxes),
fFOV(fgFOVDefault)
{
Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100)));
fCamTrans.MoveLF(1, fDollyDefault);
}
TGLPerspectiveCamera::~TGLPerspectiveCamera()
{
}
void TGLPerspectiveCamera::Setup(const TGLBoundingBox & box, Bool_t reset)
{
if (fExternalCenter == kFALSE)
{
TGLVertex3 center = box.Center();
SetCenterVec(center.X(), center.Y(), center.Z());
}
TGLVector3 extents = box.Extents();
Int_t sortInd[3];
TMath::Sort(3, extents.CArr(), sortInd);
Double_t size = TMath::Hypot(extents[sortInd[0]], extents[sortInd[1]]);
Double_t fov = TMath::Min(fgFOVDefault, fgFOVDefault*fViewport.Aspect());
fDollyDefault = size / (2.0*TMath::Tan(fov*TMath::Pi()/360));
fDollyDistance = 0.002 * fDollyDefault;
if (reset)
{
Reset();
}
}
void TGLPerspectiveCamera::Reset()
{
fFOV = fgFOVDefault;
fCamTrans.SetIdentity();
fCamTrans.MoveLF(1, fDollyDefault);
IncTimeStamp();
}
Bool_t TGLPerspectiveCamera::Zoom(Int_t delta, Bool_t mod1, Bool_t mod2)
{
if (AdjustAndClampVal(fFOV, fgFOVMin, fgFOVMax, delta, fgFOVDeltaSens, mod1, mod2)) {
IncTimeStamp();
return kTRUE;
} else {
return kFALSE;
}
}
Bool_t TGLPerspectiveCamera::Truck(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
{
Double_t lenMidClip = 0.5 * (fFarClip + fNearClip) * TMath::Tan(0.5*fFOV*TMath::DegToRad());
Double_t xstep = xDelta * lenMidClip / fViewport.Height();
Double_t ystep = yDelta * lenMidClip / fViewport.Height();
xstep = AdjustDelta(xstep, 1.0, mod1, mod2);
ystep = AdjustDelta(ystep, 1.0, mod1, mod2);
fCamTrans.MoveLF(2, -xstep);
fCamTrans.MoveLF(3, -ystep);
IncTimeStamp();
return kTRUE;
}
void TGLPerspectiveCamera::Apply(const TGLBoundingBox & sceneBox,
const TGLRect * pickRect) const
{
glViewport(fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height());
if(fViewport.Width() == 0 || fViewport.Height() == 0)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return;
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fFOV, fViewport.Aspect(), 1.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
TGLMatrix mx = fCamBase*fCamTrans;
TGLVector3 pos = mx.GetTranslation();
TGLVector3 fwd = mx.GetBaseVec(1);
TGLVector3 center = pos - fwd;
TGLVector3 up = fCamBase.GetBaseVec(3);
gluLookAt(pos[0], pos[1], pos[2],
center[0], center[1], center[2],
up[0], up[1], up[2]);
Bool_t modifiedCache = kFALSE;
if (fCacheDirty) {
UpdateCache();
modifiedCache = kTRUE;
}
TGLPlane clipPlane(EyeDirection(), EyePoint());
fCacheDirty = modifiedCache;
Double_t currentDist;
for (UInt_t i=0; i<8; i++) {
currentDist = clipPlane.DistanceTo(sceneBox[i]);
if (i==0)
{
fNearClip = currentDist;
fFarClip = fNearClip;
}
if (currentDist < fNearClip)
fNearClip = currentDist;
if (currentDist > fFarClip)
fFarClip = currentDist;
}
fNearClip *= 0.49;
fFarClip *= 2.01;
if (fFarClip < 2.0)
fFarClip = 2.0;
if (fNearClip < fFarClip/1000.0)
fNearClip = fFarClip/1000.0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (pickRect)
{
TGLRect rect(*pickRect);
WindowToViewport(rect);
gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
(Int_t*) fViewport.CArr());
gluPerspective(fFOV, fViewport.Aspect(), fNearClip, fFarClip);
}
else
{
gluPerspective(fFOV, fViewport.Aspect(), fNearClip, fFarClip);
glGetDoublev(GL_PROJECTION_MATRIX, fLastNoPickProjM.Arr());
}
glMatrixMode(GL_MODELVIEW);
if (fCacheDirty) UpdateCache();
}
void TGLPerspectiveCamera::Configure(Double_t fov, Double_t dolly, Double_t center[3],
Double_t hRotate, Double_t vRotate)
{
fFOV = fov;
if (fFOV > 170.0) {
fFOV = 170.0;
} else if (fFOV < 0.1) {
fFOV = 0.1;
}
SetCenterVec(center[0], center[1], center[2]);
fCamTrans.MoveLF(1, dolly);
RotateRad(hRotate, vRotate);
IncTimeStamp();
}
Last change: Mon Oct 20 13:14:56 2008
Last generated: 2008-10-20 13:14
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.