#include "TMath.h"
#include "TGLOrthoCamera.h"
#include "TGLIncludes.h"
#include "TGLUtil.h"
ClassImp(TGLOrthoCamera)
UInt_t TGLOrthoCamera::fgZoomDeltaSens = 500;
TGLOrthoCamera::TGLOrthoCamera() :
TGLCamera(TGLVector3( 0.0, 0.0, 1.0), TGLVector3(0.0, 1.0, 0.0)),
fType(kXOY),
fEnableRotate(kFALSE), fDollyToZoom(kTRUE),
fZoomMin(0.001), fZoomDefault(0.78), fZoomMax(1000.0),
fVolume(TGLVertex3(-100.0, -100.0, -100.0), TGLVertex3(100.0, 100.0, 100.0)),
fZoom(1.0)
{
Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100)));
}
TGLOrthoCamera::TGLOrthoCamera(EType type, const TGLVector3 & hAxis, const TGLVector3 & vAxis) :
TGLCamera(hAxis, vAxis),
fType(type),
fEnableRotate(kFALSE), fDollyToZoom(kTRUE),
fZoomMin(0.001), fZoomDefault(0.78), fZoomMax(1000.0),
fVolume(TGLVertex3(-100.0, -100.0, -100.0), TGLVertex3(100.0, 100.0, 100.0)),
fZoom(1.0)
{
Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100)));
}
TGLOrthoCamera::~TGLOrthoCamera()
{
}
void TGLOrthoCamera::Setup(const TGLBoundingBox & box, Bool_t reset)
{
fVolume = box;
if (fExternalCenter == kFALSE)
{
if (fFixDefCenter)
{
SetCenterVec(fFDCenter.X(), fFDCenter.Y(), fFDCenter.Z());
}
else
{
TGLVertex3 center = box.Center();
SetCenterVec(center.X(), center.Y(), center.Z());
}
}
if (reset)
Reset();
}
void TGLOrthoCamera::Reset()
{
TGLVector3 e = fVolume.Extents();
switch (fType) {
case kXOY:
case kXnOY:
{
fDefXSize = e.X(); fDefYSize = e.Y();
break;
}
case kXOZ:
case kXnOZ:
{
fDefXSize = e.X(); fDefYSize = e.Z();
break;
}
case kZOY:
case kZnOY:
{
fDefXSize = e.Z(); fDefYSize = e.Y();
break;
}
}
fDollyDefault = 1.25*0.5*TMath::Sqrt(3)*fVolume.Extents().Mag();
fDollyDistance = 0.002 * fDollyDefault;
fZoom = fZoomDefault;
fCamTrans.SetIdentity();
fCamTrans.MoveLF(1, fDollyDefault);
IncTimeStamp();
}
Bool_t TGLOrthoCamera::Dolly(Int_t delta, Bool_t mod1, Bool_t mod2)
{
if (fDollyToZoom) {
return Zoom(delta, mod1, mod2);
} else {
return TGLCamera::Dolly(delta, mod1, mod2);
}
}
Bool_t TGLOrthoCamera::Zoom(Int_t delta, Bool_t mod1, Bool_t mod2)
{
if (AdjustAndClampVal(fZoom, fZoomMin, fZoomMax, -delta*2, fgZoomDeltaSens, mod1, mod2))
{
IncTimeStamp();
return kTRUE;
}
else
{
return kFALSE;
}
}
void TGLOrthoCamera::SetZoomMin(Double_t z)
{
fZoomMin = z;
if (fZoom < fZoomMin) {
fZoom = fZoomMin;
IncTimeStamp();
}
}
void TGLOrthoCamera::SetZoomMax(Double_t z)
{
fZoomMax = z;
if (fZoom > fZoomMax) {
fZoom = fZoomMax;
IncTimeStamp();
}
}
Bool_t TGLOrthoCamera::Truck(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
{
Double_t xstep = 2.0 * xDelta / fProjM[0] / fViewport.Width();
Double_t ystep = 2.0 * yDelta / fProjM[5] / fViewport.Height();
xstep = AdjustDelta(xstep, 1.0, mod1, mod2);
ystep = AdjustDelta(ystep, 1.0, mod1, mod2);
return Truck(-xstep, -ystep);
}
Bool_t TGLOrthoCamera::Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
{
if (fEnableRotate)
return TGLCamera::Rotate(xDelta, yDelta, mod1, mod2);
else
return kFALSE;
}
void TGLOrthoCamera::Apply(const TGLBoundingBox & ,
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();
if (pickRect)
{
TGLRect rect(*pickRect);
WindowToViewport(rect);
gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
(Int_t*) fViewport.CArr());
}
Double_t halfRangeX, halfRangeY;
if (fDefYSize*fViewport.Width()/fDefXSize > fViewport.Height()) {
halfRangeY = 0.5 *fDefYSize;
halfRangeX = halfRangeY*fViewport.Width()/fViewport.Height();
} else {
halfRangeX = 0.5 *fDefXSize;
halfRangeY = halfRangeX*fViewport.Height()/fViewport.Width();
}
halfRangeX /= fZoom;
halfRangeY /= fZoom;
fNearClip = 0.05*fDollyDefault;
fFarClip = 2.0*fDollyDefault;
glOrtho(-halfRangeX, halfRangeX,
-halfRangeY, halfRangeY,
fNearClip, fFarClip);
if (!pickRect) glGetDoublev(GL_PROJECTION_MATRIX, fLastNoPickProjM.Arr());
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
TGLMatrix mx = fCamBase*fCamTrans;
TGLVector3 pos = mx.GetTranslation();
TGLVector3 fwd = mx.GetBaseVec(1);
TGLVector3 center = pos - fwd;
TGLVector3 up = mx.GetBaseVec(3);
gluLookAt(pos[0], pos[1], pos[2],
center[0], center[1], center[2],
up[0], up[1], up[2]);
if (fCacheDirty) UpdateCache();
}
void TGLOrthoCamera::Configure(Double_t zoom, Double_t dolly, Double_t center[3],
Double_t hRotate, Double_t vRotate)
{
fZoom = zoom;
if (center)
SetCenterVec(center[0], center[1], center[2]);
fCamTrans.MoveLF(1, dolly);
RotateRad(hRotate, vRotate);
IncTimeStamp();
}