#include "TGLAutoRotator.h"
#include "TGLViewer.h"
#include "TGLCamera.h"
#include "TMath.h"
#include "TTimer.h"
#include "TStopwatch.h"
ClassImp(TGLAutoRotator);
TGLAutoRotator::TGLAutoRotator(TGLViewer* v) :
fViewer(v), fCamera(0),
fTimer(new TTimer), fWatch(new TStopwatch),
fDt (0.01),
fWPhi (0.40),
fWTheta(0.15), fATheta(0.5),
fWDolly(0.30), fADolly(0.4),
fTimerRunning(kFALSE)
{
fTimer->Connect("Timeout()", "TGLAutoRotator", this, "Timeout()");
}
TGLAutoRotator::~TGLAutoRotator()
{
delete fWatch;
delete fTimer;
}
void TGLAutoRotator::SetDt(Double_t dt)
{
fDt = TMath::Range(0.01, 1.0, dt);
if (fTimerRunning)
{
fTimer->SetTime(TMath::Nint(1000*fDt));
fTimer->Reset();
}
}
void TGLAutoRotator::SetATheta(Double_t a)
{
a = TMath::Range(0.01, 1.0, a);
if (fTimerRunning)
{
fThetaA0 = fThetaA0 * a / fATheta;
}
fATheta = a;
}
void TGLAutoRotator::SetADolly(Double_t a)
{
a = TMath::Range(0.01, 1.0, a);
if (fTimerRunning)
{
fDollyA0 = fDollyA0 * a / fADolly;
}
fADolly = a;
}
void TGLAutoRotator::Start()
{
if (fTimerRunning)
{
Stop();
}
fCamera = & fViewer->CurrentCamera();
fThetaA0 = fATheta * TMath::PiOver2();
fDollyA0 = fADolly * fCamera->GetCamTrans().GetBaseVec(4).Mag();
fTimerRunning = kTRUE;
fTimer->SetTime(TMath::Nint(1000*fDt));
fTimer->Reset();
fTimer->TurnOn();
fWatch->Start();
}
void TGLAutoRotator::Stop()
{
if (fTimerRunning)
{
fWatch->Stop();
fTimer->TurnOff();
fTimerRunning = kFALSE;
}
}
void TGLAutoRotator::Timeout()
{
if (!fTimerRunning || gTQSender != fTimer)
{
Error("Timeout", "Not running or not called via timer.");
return;
}
using namespace TMath;
fWatch->Stop();
Double_t time = fWatch->RealTime();
fWatch->Continue();
Double_t delta_p = fWPhi*fDt;
Double_t delta_t = fThetaA0*fWTheta*Cos(fWTheta*time)*fDt;
Double_t delta_d = fDollyA0*fWDolly*Cos(fWDolly*time)*fDt;
Double_t th = fCamera->GetTheta();
if (th + delta_t > 3.0 || th + delta_t < 0.1416)
delta_t = 0;
fCamera->RotateRad(delta_t, delta_p);
fCamera->RefCamTrans().MoveLF(1, -delta_d);
fViewer->RequestDraw(TGLRnrCtx::kLODHigh);
}