00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TGLPerspectiveCamera.h"
00013 #include "TGLUtil.h"
00014 #include "TGLIncludes.h"
00015
00016 #include "TMath.h"
00017 #include "TError.h"
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 ClassImp(TGLPerspectiveCamera)
00033
00034 Double_t TGLPerspectiveCamera::fgFOVMin = 0.01;
00035 Double_t TGLPerspectiveCamera::fgFOVDefault = 30;
00036 Double_t TGLPerspectiveCamera::fgFOVMax = 120.0;
00037 UInt_t TGLPerspectiveCamera::fgFOVDeltaSens = 500;
00038
00039
00040 TGLPerspectiveCamera::TGLPerspectiveCamera(const TGLVector3 & hAxes, const TGLVector3 & vAxes) :
00041 TGLCamera(hAxes, vAxes),
00042 fFOV(fgFOVDefault)
00043 {
00044
00045 Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100)));
00046 fCamTrans.MoveLF(1, fDollyDefault);
00047 }
00048
00049
00050 TGLPerspectiveCamera::~TGLPerspectiveCamera()
00051 {
00052
00053 }
00054
00055
00056 void TGLPerspectiveCamera::Setup(const TGLBoundingBox & box, Bool_t reset)
00057 {
00058
00059
00060
00061 if (fExternalCenter == kFALSE)
00062 {
00063 if (fFixDefCenter)
00064 {
00065 SetCenterVec(fFDCenter.X(), fFDCenter.Y(), fFDCenter.Z());
00066 }
00067 else
00068 {
00069 TGLVertex3 center = box.Center();
00070 SetCenterVec(center.X(), center.Y(), center.Z());
00071 }
00072 }
00073
00074
00075 TGLVector3 extents = box.Extents();
00076 Int_t sortInd[3];
00077 TMath::Sort(3, extents.CArr(), sortInd);
00078 Double_t size = TMath::Hypot(extents[sortInd[0]], extents[sortInd[1]]);
00079 Double_t fov = TMath::Min(fgFOVDefault, fgFOVDefault*fViewport.Aspect());
00080
00081 fDollyDefault = size / (2.0*TMath::Tan(fov*TMath::Pi()/360));
00082 fDollyDistance = 0.002 * fDollyDefault;
00083
00084 if (reset)
00085 {
00086 Reset();
00087 }
00088 }
00089
00090
00091 void TGLPerspectiveCamera::Reset()
00092 {
00093
00094
00095
00096 fFOV = fgFOVDefault;
00097
00098 fCamTrans.SetIdentity();
00099 fCamTrans.MoveLF(1, fDollyDefault);
00100
00101 IncTimeStamp();
00102 }
00103
00104
00105 Bool_t TGLPerspectiveCamera::Zoom(Int_t delta, Bool_t mod1, Bool_t mod2)
00106 {
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 if (AdjustAndClampVal(fFOV, fgFOVMin, fgFOVMax, delta, fgFOVDeltaSens, mod1, mod2)) {
00118 IncTimeStamp();
00119 return kTRUE;
00120 } else {
00121 return kFALSE;
00122 }
00123 }
00124
00125
00126 Bool_t TGLPerspectiveCamera::Truck(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2)
00127 {
00128
00129
00130
00131 Double_t lenMidClip = 0.5 * (fFarClip + fNearClip) * TMath::Tan(0.5*fFOV*TMath::DegToRad());
00132
00133 Double_t xstep = xDelta * lenMidClip / fViewport.Height();
00134 Double_t ystep = yDelta * lenMidClip / fViewport.Height();
00135
00136 xstep = AdjustDelta(xstep, 1.0, mod1, mod2);
00137 ystep = AdjustDelta(ystep, 1.0, mod1, mod2);
00138
00139 return Truck(-xstep, -ystep);
00140 }
00141
00142
00143 void TGLPerspectiveCamera::Apply(const TGLBoundingBox & sceneBox,
00144 const TGLRect * pickRect) const
00145 {
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 glViewport(fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height());
00168
00169 if(fViewport.Width() == 0 || fViewport.Height() == 0)
00170 {
00171 glMatrixMode(GL_PROJECTION);
00172 glLoadIdentity();
00173 glMatrixMode(GL_MODELVIEW);
00174 glLoadIdentity();
00175 return;
00176 }
00177
00178 glMatrixMode(GL_PROJECTION);
00179 glLoadIdentity();
00180
00181
00182
00183
00184 gluPerspective(fFOV, fViewport.Aspect(), 1.0, 1000.0);
00185
00186
00187
00188 glMatrixMode(GL_MODELVIEW);
00189 glLoadIdentity();
00190 TGLMatrix mx = fCamBase*fCamTrans;
00191 TGLVector3 pos = mx.GetTranslation();
00192 TGLVector3 fwd = mx.GetBaseVec(1);
00193 TGLVector3 center = pos - fwd;
00194 TGLVector3 up = fCamBase.GetBaseVec(3);
00195
00196 gluLookAt(pos[0], pos[1], pos[2],
00197 center[0], center[1], center[2],
00198 up[0], up[1], up[2]);
00199
00200
00201 Bool_t modifiedCache = kFALSE;
00202 if (fCacheDirty) {
00203 UpdateCache();
00204 modifiedCache = kTRUE;
00205 }
00206
00207
00208 TGLPlane clipPlane(EyeDirection(), EyePoint());
00209 fCacheDirty = modifiedCache;
00210
00211
00212
00213
00214 Double_t currentDist;
00215 for (UInt_t i=0; i<8; i++) {
00216 currentDist = clipPlane.DistanceTo(sceneBox[i]);
00217 if (i==0)
00218 {
00219 fNearClip = currentDist;
00220 fFarClip = fNearClip;
00221 }
00222 if (currentDist < fNearClip)
00223 fNearClip = currentDist;
00224 if (currentDist > fFarClip)
00225 fFarClip = currentDist;
00226 }
00227
00228 fNearClip *= 0.49;
00229 fFarClip *= 2.01;
00230 if (fFarClip < 2.0)
00231 fFarClip = 2.0;
00232 if (fNearClip < fFarClip/1000.0)
00233 fNearClip = fFarClip/1000.0;
00234
00235 glMatrixMode(GL_PROJECTION);
00236 glLoadIdentity();
00237
00238
00239
00240 if (pickRect)
00241 {
00242 TGLRect rect(*pickRect);
00243 WindowToViewport(rect);
00244 gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
00245 (Int_t*) fViewport.CArr());
00246 gluPerspective(fFOV, fViewport.Aspect(), fNearClip, fFarClip);
00247 }
00248 else
00249 {
00250 gluPerspective(fFOV, fViewport.Aspect(), fNearClip, fFarClip);
00251 glGetDoublev(GL_PROJECTION_MATRIX, fLastNoPickProjM.Arr());
00252 }
00253
00254 glMatrixMode(GL_MODELVIEW);
00255
00256 if (fCacheDirty) UpdateCache();
00257 }
00258
00259
00260 void TGLPerspectiveCamera::Configure(Double_t fov, Double_t dolly, Double_t center[3],
00261 Double_t hRotate, Double_t vRotate)
00262 {
00263
00264
00265
00266
00267
00268
00269
00270 fFOV = fov;
00271
00272
00273
00274
00275
00276 if (fFOV > 170.0) {
00277 fFOV = 170.0;
00278 } else if (fFOV < 0.1) {
00279 fFOV = 0.1;
00280 }
00281
00282 if (center)
00283 SetCenterVec(center[0], center[1], center[2]);
00284
00285 fCamTrans.MoveLF(1, dolly);
00286 RotateRad(hRotate, vRotate);
00287
00288 IncTimeStamp();
00289 }