#include "TGLPerspectiveCamera.h"
#include "TGLUtil.h"
#include "TGLIncludes.h"
#include "TMath.h"
#include "TError.h"
#define PI 3.141592654
ClassImp(TGLPerspectiveCamera)
Double_t TGLPerspectiveCamera::fgFOVMin = 0.01;
Double_t TGLPerspectiveCamera::fgFOVDefault = 30;
Double_t TGLPerspectiveCamera::fgFOVMax = 120.0;
UInt_t TGLPerspectiveCamera::fgDollyDeltaSens = 500;
UInt_t TGLPerspectiveCamera::fgFOVDeltaSens = 500;
TGLPerspectiveCamera::TGLPerspectiveCamera(const TGLVector3 & hAxis, const TGLVector3 & vAxis) :
fHAxis(hAxis), fVAxis(vAxis),
fDollyMin(1.0), fDollyDefault(10.0), fDollyMax(100.0),
fFOV(fgFOVDefault), fDolly(fDollyDefault),
fVRotate(-90.0), fHRotate(90.0),
fCenter(0.0, 0.0, 0.0), fTruck(0.0, 0.0, 0.0)
{
Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100)));
}
TGLPerspectiveCamera::~TGLPerspectiveCamera()
{
}
void TGLPerspectiveCamera::Setup(const TGLBoundingBox & box)
{
fCenter = box.Center();
TGLVector3 extents = box.Extents();
Int_t sortInd[3];
TMath::Sort(3, extents.CArr(), sortInd);
Double_t longest = extents[sortInd[0]];
Double_t nextLongest = extents[sortInd[1]];
fDollyDefault = longest/(2.0*tan(fFOV*PI/360.0));
fDollyDefault += nextLongest/2.0;
fDollyMin = -fDollyDefault;
fDollyDefault *= 1.2;
fDollyMax = fDollyDefault * 7.0;
Reset();
}
void TGLPerspectiveCamera::Reset()
{
fFOV = fgFOVDefault;
fHRotate = 90.0;
fVRotate = 0.0;
fTruck.Set(-fCenter.X(), -fCenter.Y(), -fCenter.Z());
fDolly = fDollyDefault;
fCacheDirty = kTRUE;
}
Bool_t TGLPerspectiveCamera::Dolly(Int_t delta, Bool_t mod1, Bool_t mod2)
{
if (AdjustAndClampVal(fDolly, fDollyMin, fDollyMax, delta, fgDollyDeltaSens, mod1, mod2)) {
fCacheDirty = kTRUE;
return kTRUE;
} else {
return kFALSE;
}
}
Bool_t TGLPerspectiveCamera::Zoom(Int_t delta, Bool_t mod1, Bool_t mod2)
{
if (AdjustAndClampVal(fFOV, fgFOVMin, fgFOVMax, delta, fgFOVDeltaSens, mod1, mod2)) {
fCacheDirty = kTRUE;
return kTRUE;
} else {
return kFALSE;
}
}
Bool_t TGLPerspectiveCamera::Truck(Int_t x, Int_t y, Int_t xDelta, Int_t yDelta)
{
GLint viewport[4] = { fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height() };
TGLVertex3 start, end;
gluUnProject(x, y, 1.0, fModVM.CArr(), fProjM.CArr(), viewport, &start.X(), &start.Y(), &start.Z());
gluUnProject(x + xDelta, y + yDelta, 1.0, fModVM.CArr(), fProjM.CArr(), viewport, &end.X(), &end.Y(), &end.Z());
TGLVector3 truckDelta = end - start;
fTruck = fTruck + truckDelta/2.0;
fCacheDirty = kTRUE;
return kTRUE;
}
Bool_t TGLPerspectiveCamera::Rotate(Int_t xDelta, Int_t yDelta)
{
fHRotate += static_cast<float>(xDelta)/fViewport.Width() * 360.0;
fVRotate -= static_cast<float>(yDelta)/fViewport.Height() * 180.0;
if ( fVRotate > 90.0 ) {
fVRotate = 90.0;
}
if ( fVRotate < -90.0 ) {
fVRotate = -90.0;
}
fCacheDirty = kTRUE;
return kTRUE;
}
void TGLPerspectiveCamera::Apply(const TGLBoundingBox & sceneBox, const TGLRect * pickRect) const
{
glViewport(fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(fViewport.Width() == 0 || fViewport.Height() == 0) {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return;
}
gluPerspective(fFOV, fViewport.Aspect(), 1.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0, 0, -fDolly);
glRotated(fVRotate, 1.0, 0.0, 0.0);
glRotated(fHRotate, 0.0, 1.0, 0.0);
TGLVector3 zAxis = Cross(fHAxis, fVAxis);
TGLMatrix vertMatrix(TGLVertex3(0.0, 0.0, 0.0), zAxis, &fHAxis);
glMultMatrixd(vertMatrix.CArr());
glTranslated(fTruck[0], fTruck[1], fTruck[2]);
Bool_t modifiedCache = kFALSE;
if (fCacheDirty) {
UpdateCache();
modifiedCache = kTRUE;
}
TGLPlane clipPlane(EyeDirection(), EyePoint());
fCacheDirty = modifiedCache;
Double_t currentDist, nearClipDist=0, farClipDist=0;
for (UInt_t i=0; i<8; i++) {
currentDist = clipPlane.DistanceTo(sceneBox[i]);
if (i==0) {
nearClipDist = currentDist;
farClipDist = nearClipDist;
}
if (currentDist < nearClipDist) {
nearClipDist = currentDist;
}
if (currentDist > farClipDist) {
farClipDist = currentDist;
}
}
nearClipDist *= .49;
farClipDist *= 2.01;
if (farClipDist < 2.0) {
farClipDist = 2.0;
}
if (nearClipDist < farClipDist/1000.0) {
nearClipDist = farClipDist/1000.0;
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (pickRect) {
GLint viewport[4] = { fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height() };
gluPickMatrix(pickRect->X(), pickRect->Y(),
pickRect->Width(), pickRect->Height(),
viewport);
}
gluPerspective(fFOV, fViewport.Aspect(), nearClipDist, farClipDist);
glMatrixMode(GL_MODELVIEW);
if (fCacheDirty) {
UpdateCache();
if (gDebug>3) {
Info("TGLPerspectiveCamera::Apply", "FOV %f Dolly %f fVRot %f fHRot", fFOV, fDolly, fVRotate, fHRotate);
Info("TGLPerspectiveCamera::Apply", "fTruck (%f,%f,%f)", fTruck[0], fTruck[1], fTruck[2]);
Info("TGLPerspectiveCamera::Apply", "Near %f Far %f", nearClipDist, farClipDist);
}
}
}
void TGLPerspectiveCamera::Configure(Double_t fov, Double_t dolly, Double_t center[3],
Double_t hRotate, Double_t vRotate)
{
fFOV = fov;
fDolly = dolly;
fCenter.Set(center[0], center[1], center[2]);
fHRotate = hRotate;
fVRotate = vRotate;
if (fVRotate > 90.0) {
fVRotate = 90.0;
}
if (fVRotate < -90.0) {
fVRotate = -90.0;
}
if (fFOV > 170.0) {
fFOV = 170.0;
} else if (fFOV < 0.1) {
fFOV = 0.1;
}
fCacheDirty = kTRUE;
}
ROOT page - Class index - Class Hierarchy - Top of the page
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.