#include "PupilInfo.h"
#include "PupilInfo.c7"
#include <Glasses/ZQueen.h>
#include <TMath.h>
#include <GL/glew.h>
ClassImp(PupilInfo);
Bool_t PupilInfo::sStereoDefault = false;
void PupilInfo::_init()
{
mCtorLibset = "GledCore";
mCtorName = "Pupil";
mMaxRnrDepth = 100;
bAutoRedraw = true;
mWidth = 640; mHeight = 480;
mClearColor.rgba(0,0,0);
mCameraBase = 0;
mLookAt = 0;
mLookAtMinDist = 0.1;
mUpReference = 0;
mUpRefAxis = 3;
bUpRefLockDir = true;
mUpRefMinAngle = 10;
mProjMode = P_Perspective;
mZFov = 90; mZSize = 20;
mYFac = 1; mXDist = 10;
mNearClip = 0.01; mFarClip = 100;
mZoomFac = 1.1;
mDefZFov = 90; mDefZSize = 20;
mMinZFov = 0;
mMaxZFov = 160;
mFrontMode = GL_FILL; mBackMode = GL_LINE;
bLiMo2Side = false;
bBlend = false;
mMSRotFac = 1; mMSMoveFac = 2; mMoveOM = -2; mAccelExp = 0.5;
mCHSize = 0.03;
mMPSize = 0;
mHomeAnimTime = 2;
bShowRPS = true; bShowView = true; bRnrNames = false;
bRnrFakeOverlayInCapture = false;
mBuffSize = 4096; mPickR = 5; mPickDisp = 0; mPickMaxN = 24;
mPopupDx = 200; mPopupDy = 0;
mPopupFx = 0; mPopupFy = -0.5;
bAllowHandlerSwitchInPupil = true;
bStereo = sStereoDefault;
mStereoZeroParallax = 0;
mStereoEyeOffsetFac = 1;
mStereoFrustumAsymFac = 1;
mRnrCamFix = 0;
}
void PupilInfo::SetCameraBase(ZNode* camerabase)
{
static const Exc_t _eh("PupilInfo::SetCameraBase ");
if(camerabase != 0) {
ZTrans* t = ToPupilFrame(camerabase);
if(t == 0)
throw(_eh + "camera not connected into pupil contents.");
delete t;
}
set_link_or_die(mCameraBase.ref_link(), camerabase, FID());
}
void PupilInfo::SetLookAt(ZNode* lookat)
{
static const Exc_t _eh("PupilInfo::SetLookAt ");
if(lookat != 0) {
ZTrans* t = ToPupilFrame(lookat);
if(t == 0)
throw(_eh + "camera not connected into pupil contents.");
delete t;
}
set_link_or_die(mLookAt.ref_link(), lookat, FID());
}
void PupilInfo::SetUpReference(ZNode* upreference)
{
static const Exc_t _eh("PupilInfo::SetUpReference ");
if(upreference != 0) {
ZTrans* t = ToPupilFrame(upreference);
if(t == 0)
throw("camera not connected into pupil contents.");
delete t;
}
set_link_or_die(mUpReference.ref_link(), upreference, FID());
}
void PupilInfo::ImportCameraInfo(CameraInfo* cam_info)
{
static const Exc_t _eh("PupilInfo::ImportCameraInfo ");
if(cam_info == 0) throw(_eh + "called with cam_info=0.");
if(cam_info->GetFixCameraBase()) {
SetCameraBase(cam_info->GetCameraBase());
}
if(cam_info->GetFixLookAt()) {
SetLookAt(cam_info->GetLookAt());
mLookAtMinDist = cam_info->GetLookAtMinDist();
}
if(cam_info->GetFixUpReference()) {
SetUpReference(cam_info->GetUpReference());
mUpRefAxis = cam_info->GetUpRefAxis();
bUpRefLockDir = cam_info->GetUpRefLockDir();
mUpRefMinAngle = cam_info->GetUpRefMinAngle();
}
mProjMode = (Projection_e) cam_info->GetProjMode();
mZFov = cam_info->GetZFov();
mZSize = cam_info->GetZSize();
mYFac = cam_info->GetYFac();
mXDist = cam_info->GetXDist();
mNearClip = cam_info->GetNearClip();
mFarClip = cam_info->GetFarClip();
mDefZFov = cam_info->GetDefZFov();
mDefZSize = cam_info->GetDefZSize();
Stamp(FID());
if(cam_info->GetFixCameraBase())
EmitCameraHomeRay();
}
void PupilInfo::SmoothCameraHome(ZNode* new_base)
{
if(new_base) {
SetCameraBase(new_base);
EmitRedrawRay();
}
EmitSmoothCameraHomeRay();
}
void PupilInfo::Zoom(Float_t delta)
{
switch(mProjMode) {
case P_Perspective: {
Float_t fov = mZFov + delta;
if (fov < mMinZFov) fov = mMinZFov;
if (fov > mMaxZFov) fov = mMaxZFov;
SetZFov (fov);
SetZSize(2*mXDist*TMath::Tan(0.5*TMath::DegToRad()*fov));
break;
}
case P_Orthographic: {
SetZSize(mZSize + delta);
SetZFov (2*TMath::RadToDeg()*TMath::ATan2(mZSize, mXDist));
}
}
}
void PupilInfo::ZoomFac(Float_t fac)
{
switch(mProjMode) {
case P_Perspective: {
Float_t fov = fac*mZFov;
if (fov < mMinZFov) fov = mMinZFov;
if (fov > mMaxZFov) fov = mMaxZFov;
SetZFov (fov);
SetZSize(2*mXDist*TMath::Tan(0.5*TMath::DegToRad()*mZFov));
break;
}
case P_Orthographic: {
SetZSize(fac*mZSize);
SetZFov (2*TMath::RadToDeg()*TMath::ATan2(mZSize, mXDist));
}
}
}
void PupilInfo::Home(Bool_t smooth)
{
switch(mProjMode)
{
case P_Perspective:
{
if (mDefZFov && mDefZFov != mZFov) {
SetZFov (mDefZFov);
SetZSize(2*mXDist*TMath::Tan(0.5*TMath::DegToRad()*mZFov));
}
}
case P_Orthographic: {
SetZSize(mDefZSize);
SetZFov (2*TMath::RadToDeg()*TMath::ATan2(mZSize, mXDist));
}
}
if (smooth)
EmitSmoothCameraHomeRay();
else
EmitCameraHomeRay();
}
void PupilInfo::SetupZFov(Float_t zfov)
{
SetZFov(zfov);
SetDefZFov(zfov);
}
void PupilInfo::SetupZSize(Float_t zsize)
{
SetZSize(zsize);
SetDefZSize(zsize);
}
ZTrans* PupilInfo::ToPupilFrame(ZNode* node)
{
if (node == 0) return 0;
ZTrans *ret;
{
GLensReadHolder rd_lck(node);
ret = new ZTrans(node->RefTrans());
}
set<ZGlass*> top_levels;
{
GMutexHolder lst_lck(mListMutex);
Stepper<ZNode> s(this);
while (s.step())
{
if (*s == node)
return ret;
top_levels.insert(*s);
}
}
node = node->GetParent();
while (node)
{
{
GLensReadHolder rd_lck(node);
ret->MultLeft(node->RefTrans());
}
if (top_levels.find(node) != top_levels.end())
return ret;
node = node->GetParent();
}
delete ret;
return 0;
}
ZTrans* PupilInfo::ToCameraFrame(ZNode* node)
{
ZTrans* n2p = ToPupilFrame(node);
if(n2p == 0) return 0;
ZNode* cam_base = mCameraBase.get();
if(cam_base) {
ZTrans* c2p = ToPupilFrame(cam_base);
if(c2p == 0) {
delete n2p;
return 0;
}
c2p->Invert();
*c2p *= *n2p;
delete n2p;
return c2p;
}
return n2p;
}
Bool_t PupilInfo::TransformMouseRayVectors(ZNode* ref, TVector3& pos, TVector3& dir)
{
pos = mMouseRayPos;
dir = mMouseRayDir;
ZNode *node = *mCameraBase;
while (node != ref)
{
if (!node)
return false;
GLensReadHolder rd_lck(node);
node->ref_trans().MultiplyIP(pos);
node->ref_trans().RotateIP (dir);
node = node->GetParent();
}
return true;
}
void PupilInfo::EmitResizeRay()
{
if(mQueen && mSaturn->AcceptsRays()) {
auto_ptr<Ray> ray
(Ray::PtrCtor(this, PRQN_resize_window, mTimeStamp, FID()));
mQueen->EmitRay(ray);
}
}
void PupilInfo::EmitCameraHomeRay()
{
if(mQueen && mSaturn->AcceptsRays()) {
auto_ptr<Ray> ray
(Ray::PtrCtor(this, PRQN_camera_home, mTimeStamp, FID()));
mQueen->EmitRay(ray);
}
}
void PupilInfo::EmitSmoothCameraHomeRay()
{
if(mQueen && mSaturn->AcceptsRays()) {
auto_ptr<Ray> ray
(Ray::PtrCtor(this, PRQN_smooth_camera_home, mTimeStamp, FID()));
mQueen->EmitRay(ray);
}
}
void PupilInfo::EmitRedrawRay(Bool_t signal_p)
{
if(mQueen && mSaturn->AcceptsRays()) {
auto_ptr<Ray> ray
(Ray::PtrCtor(this, PRQN_redraw, mTimeStamp, FID()));
TBufferFile cbuff(TBuffer::kWrite);
cbuff << signal_p;
ray->SetCustomBuffer(cbuff);
mQueen->EmitRay(ray);
}
}
void PupilInfo::EmitDumpImageRay(const TString& filename, Int_t n_tiles,
Bool_t copy_p, Bool_t signal_p)
{
if(mQueen && mSaturn->AcceptsRays()) {
auto_ptr<Ray> ray
(Ray::PtrCtor(this, PRQN_dump_image, mTimeStamp, FID()));
TBufferFile cbuff(TBuffer::kWrite);
cbuff << filename;
cbuff << n_tiles;
cbuff << copy_p;
cbuff << signal_p;
ray->SetCustomBuffer(cbuff);
mQueen->EmitRay(ray);
}
}
void PupilInfo::Redraw()
{
EmitRedrawRay();
}
void PupilInfo::RedrawWaitSignal()
{
mDirectDumpCond.Lock();
EmitRedrawRay(true);
mDirectDumpCond.Wait();
mDirectDumpCond.Unlock();
}
void PupilInfo::DumpImage(const TString& filename, Int_t n_tiles, Bool_t copy_p)
{
EmitDumpImageRay(filename, n_tiles, copy_p, false);
}
void PupilInfo::DumpImageWaitSignal(const TString& filename, Int_t n_tiles,
Bool_t copy_p)
{
mDirectDumpCond.Lock();
EmitDumpImageRay(filename, n_tiles, copy_p, true);
mDirectDumpCond.Wait();
mDirectDumpCond.Unlock();
}
void PupilInfo::ReceiveDumpFinishedSignal()
{
mDirectDumpCond.Lock();
mDirectDumpCond.Signal();
mDirectDumpCond.Unlock();
}