#include "TVirtualGL.h"
#include "TMath.h"
#include "TGLOrthoCamera.h"
#include "TGLIncludes.h"
#include "TGLUtil.h"
ClassImp(TGLOrthoCamera)
UInt_t TGLOrthoCamera::fgZoomDeltaSens = 500;
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)
{
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);
fCamTrans.MoveLF(2, -xstep);
fCamTrans.MoveLF(3, -ystep);
IncTimeStamp();
return kTRUE;
}
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 = fCamBase.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;
SetCenterVec(center[0], center[1], center[2]);
fCamTrans.MoveLF(1, dolly);
RotateRad(hRotate, vRotate);
IncTimeStamp();
}
TGLOrthoCamera::TGLOrthoCamera() :
fZoomMin(0.01), fZoomDefault(0.78), fZoomMax(1000.0),
fVolume(TGLVertex3(-100.0, -100.0, -100.0), TGLVertex3(100.0, 100.0, 100.0)),
fZoom(1.0), fShift(0.), fCenter(),
fVpChanged(kFALSE)
{
fOrthoBox[0] = 1.;
fOrthoBox[1] = 1.;
fOrthoBox[2] = -1.;
fOrthoBox[3] = 1.;
}
void TGLOrthoCamera::SetViewport(TGLPaintDevice *dev)
{
Int_t vp[4] = {0};
dev->ExtractViewport(vp);
if (vp[2] != Int_t(fViewport.Width()) || vp[3] != Int_t(fViewport.Height()) ||
vp[0] != fViewport.X() || vp[1] != fViewport.Y())
{
fVpChanged = kTRUE;
fArcBall.SetBounds(vp[2], vp[3]);
fViewport.Set(vp[0], vp[1], vp[2], vp[3]);
} else
fVpChanged = kFALSE;
}
void TGLOrthoCamera::SetViewVolume(const TGLVertex3 *box)
{
fCenter[0] = (box[0].X() + box[1].X()) / 2;
fCenter[1] = (box[0].Y() + box[2].Y()) / 2;
fCenter[2] = (box[0].Z() + box[4].Z()) / 2;
const Double_t maxDim = box[1].X() - box[0].X();
fOrthoBox[0] = maxDim;
fOrthoBox[1] = maxDim;
fOrthoBox[2] = -100 * maxDim;
fOrthoBox[3] = 100 * maxDim;
fShift = maxDim * 1.5;
}
void TGLOrthoCamera::StartRotation(Int_t px, Int_t py)
{
fArcBall.Click(TPoint(px, py));
}
void TGLOrthoCamera::RotateCamera(Int_t px, Int_t py)
{
fArcBall.Drag(TPoint(px, py));
}
void TGLOrthoCamera::StartPan(Int_t px, Int_t py)
{
fMousePos.fX = px;
fMousePos.fY = fViewport.Height() - py;
}
void TGLOrthoCamera::Pan(Int_t px, Int_t py)
{
py = fViewport.Height() - py;
Double_t mv[16] = {0.};
glGetDoublev(GL_MODELVIEW_MATRIX, mv);
Double_t pr[16] = {0.};
glGetDoublev(GL_PROJECTION_MATRIX, pr);
Int_t vp[] = {0, 0, fViewport.Width(), fViewport.Height()};
TGLVertex3 start, end;
gluUnProject(fMousePos.fX, fMousePos.fY, 1., mv, pr, vp, &start.X(), &start.Y(), &start.Z());
gluUnProject(px, py, 1., mv, pr, vp, &end.X(), &end.Y(), &end.Z());
fTruck += (start - end) /= 2.;
fMousePos.fX = px;
fMousePos.fY = py;
}
void TGLOrthoCamera::SetCamera()const
{
glViewport(0, 0, fViewport.Width(), fViewport.Height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(
-fOrthoBox[0] * fZoom,
fOrthoBox[0] * fZoom,
-fOrthoBox[1] * fZoom,
fOrthoBox[1] * fZoom,
fOrthoBox[2],
fOrthoBox[3]
);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void TGLOrthoCamera::Apply(Double_t phi, Double_t theta)const
{
glTranslated(0., 0., -fShift);
glMultMatrixd(fArcBall.GetRotMatrix());
glRotated(theta - 90., 1., 0., 0.);
glRotated(phi, 0., 0., 1.);
glTranslated(-fTruck[0], -fTruck[1], -fTruck[2]);
glTranslated(-fCenter[0], -fCenter[1], -fCenter[2]);
}
Int_t TGLOrthoCamera::GetX()const
{
return fViewport.X();
}
Int_t TGLOrthoCamera::GetY()const
{
return fViewport.Y();
}
Int_t TGLOrthoCamera::GetWidth()const
{
return Int_t(fViewport.Width());
}
Int_t TGLOrthoCamera::GetHeight()const
{
return Int_t(fViewport.Height());
}
void TGLOrthoCamera::ZoomIn()
{
fZoom /= 1.2;
}
void TGLOrthoCamera::ZoomOut()
{
fZoom *= 1.2;
}
Last change: Wed Sep 17 12:20:25 2008
Last generated: 2008-09-17 12:20
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.