#ifndef ROOT_TGLCamera
#define ROOT_TGLCamera
#include "TGLUtil.h"
#include "TGLBoundingBox.h"
#include "TPoint.h"
#include <cassert>
#include <cmath>
class TGLCamera
{
public:
enum EFrustumPlane
{
kNear = 0,
kLeft = 1,
kRight = 2,
kTop = 3,
kBottom = 4,
kFar = 5,
kPlanesPerFrustum = 6
};
private:
TGLBoundingBox fPreviousInterestBox;
TGLBoundingBox fInterestFrustum;
TGLBoundingBox fInterestFrustumAsBox;
static const Double_t fgInterestBoxExpansion;
TGLBoundingBox Frustum(Bool_t asBox = kTRUE) const;
TGLCamera(const TGLCamera &);
TGLCamera & operator=(const TGLCamera &);
protected:
TGLMatrix fCamBase;
TGLMatrix fCamTrans;
Bool_t fExternalCenter;
TGLVector3 fExtCenter;
TGLVector3 fDefCenter;
TGLVector3 *fCenter;
mutable Double_t fNearClip;
mutable Double_t fFarClip;
Double_t fDollyDefault;
Double_t fDollyDistance;
Float_t fVAxisMinAngle;
mutable Bool_t fCacheDirty;
mutable UInt_t fTimeStamp;
mutable TGLMatrix fLastNoPickProjM;
mutable TGLMatrix fProjM;
mutable TGLMatrix fModVM;
mutable TGLMatrix fClipM;
mutable TGLPlane fFrustumPlanes[kPlanesPerFrustum];
TGLRect fViewport;
TGLBoundingBox fInterestBox;
mutable Double_t fLargestSeen;
void UpdateCache() const;
static UInt_t fgDollyDeltaSens;
public:
TGLCamera();
TGLCamera(const TGLVector3 & hAxis, const TGLVector3 & vAxis);
virtual ~TGLCamera();
virtual Bool_t IsOrthographic() const { return kFALSE; }
virtual Bool_t IsPerspective() const { return kFALSE; }
const TGLMatrix& RefModelViewMatrix() const { return fModVM; }
Bool_t IsCacheDirty() const { return fCacheDirty; }
void IncTimeStamp() { fCacheDirty = kTRUE; ++fTimeStamp; }
UInt_t TimeStamp() const { return fTimeStamp; }
void SetViewport(const TGLRect & viewport);
TGLRect& RefViewport() { return fViewport; }
virtual void Setup(const TGLBoundingBox & box, Bool_t reset=kTRUE) = 0;
virtual void Reset() = 0;
virtual Bool_t Dolly(Int_t delta, Bool_t mod1, Bool_t mod2);
virtual Bool_t Zoom (Int_t delta, Bool_t mod1, Bool_t mod2) = 0;
virtual Bool_t Truck(Double_t xDelta, Double_t yDelta);
virtual Bool_t Truck(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2) = 0;
virtual Bool_t Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2);
virtual Bool_t RotateRad(Double_t hRotate, Double_t vRotate);
virtual void Apply(const TGLBoundingBox & sceneBox, const TGLRect * pickRect = 0) const = 0;
Bool_t AdjustAndClampVal(Double_t & val, Double_t min, Double_t max,
Int_t screenShift, Int_t screenShiftRange,
Bool_t mod1, Bool_t mod2) const;
Double_t AdjustDelta(Double_t screenShift, Double_t deltaFactor,
Bool_t mod1, Bool_t mod2) const;
void SetExternalCenter(Bool_t x);
Bool_t GetExternalCenter(){ return fExternalCenter; }
void SetCenterVec(Double_t x, Double_t y, Double_t z);
void SetCenterVecWarp(Double_t x, Double_t y, Double_t z);
Double_t* GetCenterVec() { return fCenter->Arr(); }
Double_t GetNearClip() const { return fNearClip; }
Double_t GetFarClip() const { return fFarClip; }
const TGLMatrix& GetCamBase() const { return fCamBase; }
const TGLMatrix& GetCamTrans() const { return fCamTrans; }
TGLMatrix& RefCamBase() { return fCamBase; }
TGLMatrix& RefCamTrans() { return fCamTrans; }
Double_t GetTheta() const;
TGLMatrix& RefLastNoPickProjM() const { return fLastNoPickProjM; }
TGLVertex3 EyePoint() const;
TGLVector3 EyeDirection() const;
TGLVertex3 FrustumCenter() const;
const TGLPlane & FrustumPlane(EFrustumPlane plane) const;
EOverlap FrustumOverlap (const TGLBoundingBox & box) const;
EOverlap ViewportOverlap(const TGLBoundingBox & box) const;
TGLRect ViewportRect (const TGLBoundingBox & box, TGLBoundingBox::EFace face) const;
TGLRect ViewportRect (const TGLBoundingBox & box, const TGLBoundingBox::EFace * face = 0) const;
TGLVertex3 WorldToViewport(const TGLVertex3 & worldVertex, TGLMatrix* modviewMat=0) const;
TGLVector3 WorldDeltaToViewport(const TGLVertex3 & worldRef, const TGLVector3 & worldDelta) const;
TGLVertex3 ViewportToWorld(const TGLVertex3 & viewportVertex, TGLMatrix* modviewMat=0) const;
TGLLine3 ViewportToWorld(Double_t viewportX, Double_t viewportY) const;
TGLLine3 ViewportToWorld(const TPoint & viewport) const;
TGLVector3 ViewportDeltaToWorld(const TGLVertex3 & worldRef, Double_t viewportXDelta, Double_t viewportYDelta, TGLMatrix* modviewMat=0) const;
std::pair<Bool_t, TGLVertex3> ViewportPlaneIntersection(Double_t viewportX, Double_t viewportY, const TGLPlane & worldPlane) const;
std::pair<Bool_t, TGLVertex3> ViewportPlaneIntersection(const TPoint & viewport, const TGLPlane & worldPlane) const;
void WindowToViewport(Int_t & , Int_t & y) const { y = fViewport.Height() - y; }
void WindowToViewport(TPoint & point) const { point.SetY(fViewport.Height() - point.GetY()); }
void WindowToViewport(TGLRect & rect) const { rect.Y() = fViewport.Height() - rect.Y(); }
void WindowToViewport(TGLVertex3 & vertex) const { vertex.Y() = fViewport.Height() - vertex.Y(); }
const TGLRect& RefViewport() const { return fViewport; }
Float_t GetVAxisMinAngle(){return fVAxisMinAngle;}
void SetVAxisMinAngle(Float_t x){fVAxisMinAngle = x;}
virtual void Configure(Double_t zoom, Double_t dolly, Double_t center[3],
Double_t hRotate, Double_t vRotate) = 0;
Bool_t OfInterest(const TGLBoundingBox & box, Bool_t ignoreSize) const;
Bool_t UpdateInterest(Bool_t force);
void ResetInterest();
void DrawDebugAids() const;
ClassDef(TGLCamera,0);
};
inline const TGLPlane & TGLCamera::FrustumPlane(EFrustumPlane plane) const
{
if (fCacheDirty) {
Error("TGLCamera::FrustumBox()", "cache dirty");
}
return fFrustumPlanes[plane];
}
#endif // ROOT_TGLCamera