From cebe7ef57fa726c3f03d91bde0348593286f6acf Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Wed, 10 Oct 2007 14:08:48 +0000 Subject: [PATCH] From Matevz & Alja * base/inc/TVirtualViewer3D.h: Add function virtual void ObjectPaint(TObject*, Option_t*). /**************************************************************************/ * ged/src/TGedEditor.cxx: When adding top-level TGFrame for the extra tabs specify layout hints with kLHintsExpandX. /**************************************************************************/ * gl/inc/TGLScenePad.h: * gl/src/TGLScenePad.cxx: Implement virtual TVirtualViewer3D::ObjectPaint(). * gl/src/TGLCamera.cxx: * gl/inc/TGLCamera.h: * gl/src/TGLPerspectiveCamera.cxx: * gl/inc/TGLPerspectiveCamera.h: * gl/src/TGLOrthoCamera.cxx: * gl/inc/TGLOrthoCamera.h: Introduce two transformation matrices to clearly define movement of camera around the center point. The first transformation matrix fCamBase defines the coordinate system placed at the camera center point with camera up-vector as the third base vector. The second transformation matrix fCamTrans defines the camera transformation relative to fCamBase. Implement a common Truck(), Rotate() and Dolly() function for orthographic and perspective camera. Implement an option to define camera center point externally. Center can also be determined via picking. * gl/src/TGLUtil.cxx: * gl/inc/TGLUtil.h: TGLMatrix: add new functions to get/set the base vectors directly. TGLUtil: add member UInt_t fgDefaultDrawQuality. TGLRect: bugfix in Diagonal(), integer calculation overflowed. * gl/src/TGLViewer.cxx: * gl/inc/TGLViewer.h: Make interface to draw camera center point. Add option to disable/enable depth test when drawing axis guides. * gl/src/TGLViewerEditor.cxx: * gl/inc/TGLViewerEditor.h: Add GUI to manipulate camera center and to disable/enable depth test when drawing axis guides. * gl/src/TGLClipSetEditor.cxx: Change layout of labeled number entries. * gl/src/TGLLightSet.cxx: Fix positioning of front light. White-space consolidation. * gl/src/TGLLightSetEditor.cxx: * gl/inc/TGLLightSetEditor.h: Put GUI for the 6 lights in two columns. /**************************************************************************/ * tutorials/gl/glViewerExercise.C: Follow-up on changes in TGLCamera. Enable rotation on orthographic camera. * tutorials/gl/glViewerLOD.C: Workourond for cint bug with switch statements. git-svn-id: http://root.cern.ch/svn/root/trunk@20292 27541ba8-7e3a-0410-8455-c3a389f83636 --- base/inc/TVirtualViewer3D.h | 1 + ged/src/TGedEditor.cxx | 2 +- gl/inc/TGLCamera.h | 55 +++- gl/inc/TGLLightSetEditor.h | 4 +- gl/inc/TGLOrthoCamera.h | 37 ++- gl/inc/TGLPerspectiveCamera.h | 27 +- gl/inc/TGLScenePad.h | 1 + gl/inc/TGLUtil.h | 129 +++++++-- gl/inc/TGLViewer.h | 21 +- gl/inc/TGLViewerEditor.h | 21 +- gl/src/TGLCamera.cxx | 196 ++++++++++++- gl/src/TGLClipSetEditor.cxx | 32 +-- gl/src/TGLLightSet.cxx | 32 +-- gl/src/TGLLightSetEditor.cxx | 49 ++-- gl/src/TGLOrthoCamera.cxx | 470 ++++++++++++++------------------ gl/src/TGLPerspectiveCamera.cxx | 209 ++++---------- gl/src/TGLScenePad.cxx | 98 ++++--- gl/src/TGLUtil.cxx | 188 +++++++++++-- gl/src/TGLViewer.cxx | 134 ++++++--- gl/src/TGLViewerEditor.cxx | 252 ++++++++++++----- tutorials/gl/glViewerExercise.C | 167 +++++------- tutorials/gl/glViewerLOD.C | 54 ++-- 22 files changed, 1311 insertions(+), 868 deletions(-) diff --git a/base/inc/TVirtualViewer3D.h b/base/inc/TVirtualViewer3D.h index 6dd0148c015..93d04ff5850 100644 --- a/base/inc/TVirtualViewer3D.h +++ b/base/inc/TVirtualViewer3D.h @@ -56,6 +56,7 @@ public: // When they can, TPad::Paint() and TPad::PaintModified() simply // call the following function: virtual void PadPaint(TVirtualPad*) {} + virtual void ObjectPaint(TObject*, Option_t* = "") {} // Addition/removal of objects must occur between Begin/EndUpdate calls virtual void BeginScene() = 0; diff --git a/ged/src/TGedEditor.cxx b/ged/src/TGedEditor.cxx index bb60c004596..409b67abf26 100644 --- a/ged/src/TGedEditor.cxx +++ b/ged/src/TGedEditor.cxx @@ -538,7 +538,7 @@ void TGedEditor::ActivateEditor(TClass* cl, Bool_t recurse) while ((subf = (TGedFrame::TGedSubFrame*)next())) { // locate the composite frame on created tabs TGedTabInfo* ti = GetEditorTabInfo(subf->fName); - ti->fContainer->AddFrame(subf->fFrame); + ti->fContainer->AddFrame(subf->fFrame, new TGLayoutHints(kLHintsNormal | kLHintsExpandX)); if (fVisibleTabs.FindObject(ti) == 0) fVisibleTabs.Add(ti); } diff --git a/gl/inc/TGLCamera.h b/gl/inc/TGLCamera.h index 7321dc54798..a9ac83c1bf9 100644 --- a/gl/inc/TGLCamera.h +++ b/gl/inc/TGLCamera.h @@ -22,8 +22,8 @@ #include "TPoint.h" #endif -#include <assert.h> -#include <math.h> +#include <cassert> +#include <cmath> ////////////////////////////////////////////////////////////////////////// // // @@ -128,6 +128,20 @@ private: protected: // Fields + TGLMatrix fCamBase; //! tranformation to center and rotation from up to x vector + TGLMatrix fCamTrans; //! transformation relative to fCamTrans + Bool_t fExternalCenter; //! use external center insead of scene center + TGLVector3 fExtCenter; //! external camera center + TGLVector3 fDefCenter; //! deafult camera center + TGLVector3 *fCenter; //! current camera center + + mutable Double_t fNearClip; //! last applied near-clip + mutable Double_t fFarClip; //! last applied far-clip + + // Set in Setup() + Double_t fDollyDefault; //! default distnce from viewing centre + Double_t fDollyDistance; //! unit distance for camera movement in fwd/bck direction + Float_t fVAxisMinAngle; //! minimal allowed angle between up and fCamTrans Z vector // Internal cached matrices and frustum planes mutable Bool_t fCacheDirty; //! cached items dirty? @@ -147,12 +161,16 @@ protected: 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(Int_t screenShift, Double_t deltaFactor, + Bool_t mod1, Bool_t mod2) const; // Internal cache update - const as the actual camera configuration is unaffected void UpdateCache() const; + static UInt_t fgDollyDeltaSens; public: TGLCamera(); + TGLCamera(const TGLVector3 & hAxis, const TGLVector3 & vAxis); virtual ~TGLCamera(); Bool_t IsCacheDirty() const { return fCacheDirty; } @@ -165,20 +183,32 @@ public: // Camera manipulation interface (GL coord - origin bottom left) virtual void Setup(const TGLBoundingBox & box, Bool_t reset=kTRUE) = 0; virtual void Reset() = 0; - // virtual void Frame(const TGLBoundingBox & box) = 0; // TODO - // virtual void Frame(const TGLRec & rect) = 0; // TODO - virtual Bool_t Dolly(Int_t delta, Bool_t mod1, Bool_t mod2) = 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(Int_t x, Int_t y, Int_t xDelta, Int_t yDelta) = 0; - virtual Bool_t Rotate(Int_t xDelta, Int_t yDelta) = 0; + virtual Bool_t Truck(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2); + 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; virtual void Markup(TGLCameraMarkupStyle* /* ms */) const {} + void SetExternalCenter(Bool_t x); + Bool_t GetExternalCenter(){ return fExternalCenter; } + + void SetCenterVec( 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; } + // Current orientation and frustum - TGLVertex3 EyePoint() const; - TGLVector3 EyeDirection() const; - TGLVertex3 FrustumCenter() const; + TGLVertex3 EyePoint() const; + TGLVector3 EyeDirection() const; + TGLVertex3 FrustumCenter() const; const TGLPlane & FrustumPlane(EFrustumPlane plane) const; // Overlap / projection / intersection tests @@ -204,6 +234,11 @@ public: 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; // Cameras expanded-frustum interest box Bool_t OfInterest(const TGLBoundingBox & box, Bool_t ignoreSize) const; Bool_t UpdateInterest(Bool_t force); diff --git a/gl/inc/TGLLightSetEditor.h b/gl/inc/TGLLightSetEditor.h index c9fba2ad523..6c774a133d8 100644 --- a/gl/inc/TGLLightSetEditor.h +++ b/gl/inc/TGLLightSetEditor.h @@ -24,7 +24,7 @@ private: TGLLightSetSubEditor& operator=(const TGLLightSetSubEditor&); // Not implemented protected: - TGLLightSet *fM; + TGLLightSet *fM; TGGroupFrame *fLightFrame; TGButton *fTopLight; @@ -35,7 +35,7 @@ protected: TGButton *fSpecularLight; - TGButton* MakeLampButton(const Text_t* name, Int_t wid); + TGButton* MakeLampButton(const Text_t* name, Int_t wid, TGCompositeFrame* parent); public: TGLLightSetSubEditor(const TGWindow* p); diff --git a/gl/inc/TGLOrthoCamera.h b/gl/inc/TGLOrthoCamera.h index 4abe2ca81b6..2ba718b17c0 100644 --- a/gl/inc/TGLOrthoCamera.h +++ b/gl/inc/TGLOrthoCamera.h @@ -39,28 +39,27 @@ class TGLPaintDevice; class TGLOrthoCamera : public TGLCamera { public: - enum EType { kXOY, kXOZ, kZOY }; // pair of world axes aligned to h/v screen + enum EType { kZOY, kXOZ, kX0Y }; // pair of world axes aligned to h/v screen private: // Fields - EType fType; //! type (EType) - one of kXOY, kXOZ, kZOY + EType fType; //! camera type + Bool_t fEnableRotate; //! enable rotation // Limits - set in Setup() Double_t fZoomMin; //! minimum zoom factor Double_t fZoomDefault; //! default zoom factor Double_t fZoomMax; //! maximum zoom factor - TGLBoundingBox fVolume; //! + TGLBoundingBox fVolume; //! scene volume // Current interaction - Double_t fZoom; //! current zoom - TGLVector3 fTruck; //! current truck vector - TGLMatrix fMatrix; //! orthographic orientation matrix + Double_t fDefXSize, fDefYSize; //! x, y size of scene from camera view + Double_t fZoom; //! current zoom - static UInt_t fgZoomDeltaSens; - - //Stuff for TGLPlotPainter. + //Stuff for TGLPlotPainter. MT: This *must* go to a special subclass. Double_t fShift; Double_t fOrthoBox[4]; TGLVertex3 fCenter; + TGLVector3 fTruck; TArcBall fArcBall; TPoint fMousePos; Bool_t fVpChanged; @@ -68,26 +67,27 @@ private: // Methods void Init(); + static UInt_t fgZoomDeltaSens; public: - - // TODO: Convert this so define by pair of vectors as per perspective - // camera TGLOrthoCamera(); - TGLOrthoCamera(EType type); + TGLOrthoCamera(const TGLVector3 & hAxis, const TGLVector3 & vAxis); virtual ~TGLOrthoCamera(); virtual void Setup(const TGLBoundingBox & box, Bool_t reset=kTRUE); virtual void Reset(); - 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); - virtual Bool_t Truck(Int_t x, Int_t y, Int_t xDelta, Int_t yDelta); - virtual Bool_t Rotate(Int_t xDelta, Int_t yDelta); - + virtual Bool_t Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2); virtual void Apply(const TGLBoundingBox & sceneBox, const TGLRect * pickRect = 0) const; + virtual void Markup (TGLCameraMarkupStyle* ms) const; // External scripting control - void Configure(Double_t left, Double_t right, Double_t top, Double_t bottom); + // void Configure(Double_t left, Double_t right, Double_t top, Double_t bottom); + virtual void Configure(Double_t zoom, Double_t dolly, Double_t center[3], + Double_t hRotate, Double_t vRotate); + + void SetEnableRotate(Bool_t x){ fEnableRotate = x; } + Bool_t GetEnableRotate(){ return fEnableRotate; } //Stuff for TGLPlotPainter. void SetViewport(TGLPaintDevice *dev); @@ -100,7 +100,6 @@ public: void ZoomOut(); void SetCamera()const; void Apply()const; - Bool_t ViewportChanged()const{return fVpChanged;} Int_t GetX()const; Int_t GetY()const; diff --git a/gl/inc/TGLPerspectiveCamera.h b/gl/inc/TGLPerspectiveCamera.h index 0dc4179ab84..525cc669af8 100644 --- a/gl/inc/TGLPerspectiveCamera.h +++ b/gl/inc/TGLPerspectiveCamera.h @@ -31,43 +31,24 @@ class TGLPerspectiveCamera : public TGLCamera { - private: +private: // Fields - TGLVector3 fHAxis; //! - TGLVector3 fVAxis; //! - - // Set in Setup() - Double_t fDollyMin; //! - Double_t fDollyDefault; //! - Double_t fDollyMax; //! - Double_t fFOV; //! - Double_t fDolly; //! - Double_t fVRotate; //! - Double_t fHRotate; //! - TGLVertex3 fCenter; //! - TGLVector3 fTruck; //! - // These are fixed for any perspective camera static Double_t fgFOVMin, fgFOVDefault, fgFOVMax; - static UInt_t fgDollyDeltaSens, fgFOVDeltaSens; - + static UInt_t fgFOVDeltaSens; public: TGLPerspectiveCamera(const TGLVector3 & hAxis, const TGLVector3 & vAxis); virtual ~TGLPerspectiveCamera(); virtual void Setup(const TGLBoundingBox & box, Bool_t reset=kTRUE); virtual void Reset(); - 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); - virtual Bool_t Truck(Int_t x, Int_t y, Int_t xDelta, Int_t yDelta); - virtual Bool_t Rotate(Int_t xDelta, Int_t yDelta); - virtual void Apply(const TGLBoundingBox & box, const TGLRect * pickRect = 0) const; // External scripting control - void Configure(Double_t fov, Double_t dolly, Double_t center[3], - Double_t hRotate, Double_t vRotate); + virtual void Configure(Double_t fov, Double_t dolly, Double_t center[3], + Double_t hRotate, Double_t vRotate); ClassDef(TGLPerspectiveCamera,0) // a perspective view camera }; diff --git a/gl/inc/TGLScenePad.h b/gl/inc/TGLScenePad.h index 8ddd6d3438a..24601ea654d 100644 --- a/gl/inc/TGLScenePad.h +++ b/gl/inc/TGLScenePad.h @@ -79,6 +79,7 @@ public: virtual Bool_t CanLoopOnPrimitives() const { return kTRUE; } virtual void PadPaint(TVirtualPad* pad); + virtual void ObjectPaint(TObject* obj, Option_t* opt=""); // For now handled by viewer virtual Int_t DistancetoPrimitive(Int_t /*px*/, Int_t /*py*/) { return 9999; } diff --git a/gl/inc/TGLUtil.h b/gl/inc/TGLUtil.h index ff20af12dbc..a8ce107ef07 100644 --- a/gl/inc/TGLUtil.h +++ b/gl/inc/TGLUtil.h @@ -25,7 +25,7 @@ class TGLCamera; #include <cmath> #include <vector> -#include <assert.h> +#include <cassert> // TODO:Find a better place for these enums - TGLEnum.h? // Whole GL viewer should be moved into own namespace @@ -103,14 +103,16 @@ protected: public: TGLVertex3(); TGLVertex3(Double_t x, Double_t y, Double_t z); + TGLVertex3(Double_t* v); TGLVertex3(const TGLVertex3 & other); virtual ~TGLVertex3(); - Bool_t operator == (const TGLVertex3 & rhs) const; - TGLVertex3 & operator = (const TGLVertex3 & rhs); + Bool_t operator == (const TGLVertex3 & rhs) const; + TGLVertex3 & operator = (const TGLVertex3 & rhs); + TGLVertex3 & operator *= (Double_t f); + TGLVertex3 operator - () const; const TGLVertex3 & operator -= (const TGLVector3 & val); const TGLVertex3 & operator += (const TGLVector3 & val); - TGLVertex3 operator - () const; // Manipulators void Fill(Double_t val); @@ -141,6 +143,12 @@ public: ClassDef(TGLVertex3,0) // GL 3 component vertex helper/wrapper class }; +//______________________________________________________________________________ +inline TGLVertex3 operator*(Double_t f, const TGLVertex3& v) +{ + return TGLVertex3(f*v.X(), f*v.Y(), f*v.Z()); +} + //______________________________________________________________________________ inline void TGLVertex3::Negate() { @@ -173,6 +181,15 @@ inline TGLVertex3 TGLVertex3::operator - () const return TGLVertex3(-fVals[0], -fVals[1], -fVals[2]); } +//______________________________________________________________________________ +inline TGLVertex3& TGLVertex3::operator *= (Double_t f) +{ + fVals[0] *= f; + fVals[1] *= f; + fVals[2] *= f; + return *this; +} + //______________________________________________________________________________ inline Double_t & TGLVertex3::operator [] (Int_t index) { @@ -240,9 +257,11 @@ public: TGLVector3(const TGLVector3 & other); virtual ~TGLVector3(); - const TGLVector3 & operator /= (Double_t val); - const TGLVector3 & operator *= (Double_t val); - TGLVector3 operator - () const; + TGLVector3& operator = (const TGLVertex3& v) + { fVals[0] = v[0]; fVals[1] = v[1]; fVals[2] = v[2]; return *this; } + + TGLVector3 & operator /= (Double_t val); + TGLVector3 operator - () const; Double_t Mag() const; void Normalise(); @@ -267,7 +286,7 @@ inline const TGLVertex3 & TGLVertex3::operator += (const TGLVector3 & vec) } //______________________________________________________________________________ -inline const TGLVector3 & TGLVector3::operator /= (Double_t val) +inline TGLVector3 & TGLVector3::operator /= (Double_t val) { fVals[0] /= val; fVals[1] /= val; @@ -275,15 +294,6 @@ inline const TGLVector3 & TGLVector3::operator /= (Double_t val) return *this; } -//______________________________________________________________________________ -inline const TGLVector3 & TGLVector3::operator *= (Double_t val) -{ - fVals[0] *= val; - fVals[1] *= val; - fVals[2] *= val; - return *this; -} - //______________________________________________________________________________ inline TGLVector3 TGLVector3::operator - () const { @@ -363,6 +373,13 @@ inline TGLVector3 operator - (const TGLVector3 & vector1, const TGLVector3 & vec return TGLVector3(vector1[0] - vector2[0], vector1[1] - vector2[1], vector1[2] - vector2[2]); } +//______________________________________________________________________________ +// Dot-product +inline Double_t operator * (const TGLVector3 & a, const TGLVector3 & b) +{ + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; +} + ////////////////////////////////////////////////////////////////////////// // // // TGLLine3 // @@ -506,7 +523,9 @@ inline void TGLRect::Expand(Int_t x, Int_t y) //______________________________________________________________________________ inline Int_t TGLRect::Diagonal() const { - return static_cast<Int_t>(sqrt(static_cast<Double_t>(fWidth*fWidth + fHeight*fHeight))); + const Double_t w = static_cast<Double_t>(fWidth); + const Double_t h = static_cast<Double_t>(fHeight); + return static_cast<Int_t>(sqrt(w*w + h*h)); } //______________________________________________________________________________ @@ -709,22 +728,23 @@ public: TGLMatrix(); TGLMatrix(Double_t x, Double_t y, Double_t z); TGLMatrix(const TGLVertex3 & translation); - TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 * xAxis = 0); + TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 & xAxis); + TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis); TGLMatrix(const Double_t vals[16]); TGLMatrix(const TGLMatrix & other); virtual ~TGLMatrix(); // ClassDef introduces virtual fns // Operators TGLMatrix & operator =(const TGLMatrix & rhs); - Double_t & operator [] (Int_t index); - Double_t operator [] (Int_t index) const; + Double_t & operator [] (Int_t index); + Double_t operator [] (Int_t index) const; void MultRight(const TGLMatrix & rhs); void MultLeft (const TGLMatrix & lhs); TGLMatrix & operator*=(const TGLMatrix & rhs) { MultRight(rhs); return *this; } // Manipulators - void Set(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 * xAxis = 0); + void Set(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 & xAxis = 0); void Set(const Double_t vals[16]); void SetIdentity(); @@ -732,16 +752,30 @@ public: void SetTranslation(const TGLVertex3 & translation); void Translate(const TGLVector3 & vect); + void MoveLF(Int_t ai, Double_t amount); void Scale(const TGLVector3 & scale); void Rotate(const TGLVertex3 & pivot, const TGLVector3 & axis, Double_t angle); void RotateLF(Int_t i1, Int_t i2, Double_t amount); + void RotatePF(Int_t i1, Int_t i2, Double_t amount); void TransformVertex(TGLVertex3 & vertex) const; void Transpose3x3(); + Double_t Invert(); // Accesors - TGLVertex3 GetTranslation() const; + TGLVector3 GetTranslation() const; TGLVector3 GetScale() const; + void SetBaseVec(Int_t b, Double_t x, Double_t y, Double_t z); + void SetBaseVec(Int_t b, const TGLVector3& v); + void SetBaseVec(Int_t b, Double_t* x); + + TGLVector3 GetBaseVec(Int_t b) const; + void GetBaseVec(Int_t b, TGLVector3& v) const; + void GetBaseVec(Int_t b, Double_t* x) const; + + void MultiplyIP(TGLVector3& v, Double_t w=1) const; + void RotateIP(TGLVector3& v) const; + // Internal data accessors - for GL API const Double_t * CArr() const { return fVals; } Double_t * Arr() { return fVals; } @@ -811,6 +845,48 @@ inline TGLMatrix operator * (const TGLMatrix & lhs, const TGLMatrix & rhs) return res; } +//______________________________________________________________________________ +inline void TGLMatrix::SetBaseVec(Int_t b, Double_t x, Double_t y, Double_t z) +{ + Double_t* C = fVals + 4*--b; + C[0] = x; C[1] = y; C[2] = z; +} + +//______________________________________________________________________________ +inline void TGLMatrix::SetBaseVec(Int_t b, const TGLVector3& v) +{ + Double_t* C = fVals + 4*--b; + C[0] = v[0]; C[1] = v[1]; C[2] = v[2]; +} + +//______________________________________________________________________________ +inline void TGLMatrix::SetBaseVec(Int_t b, Double_t* x) +{ + Double_t* C = fVals + 4*--b; + C[0] = x[0]; C[1] = x[1]; C[2] = x[2]; +} + +//______________________________________________________________________________ +inline TGLVector3 TGLMatrix::GetBaseVec(Int_t b) const +{ + return TGLVector3(&fVals[4*--b]); +} + +//______________________________________________________________________________ +inline void TGLMatrix::GetBaseVec(Int_t b, TGLVector3& v) const +{ + const Double_t* C = fVals + 4*--b; + v[0] = C[0]; v[1] = C[1]; v[2] = C[2]; +} + +//______________________________________________________________________________ +inline void TGLMatrix::GetBaseVec(Int_t b, Double_t* x) const +{ + const Double_t* C = fVals + 4*--b; + x[0] = C[0], x[1] = C[1], x[2] = C[2]; +} + + ////////////////////////////////////////////////////////////////////////// // // // TGLUtil // @@ -823,6 +899,7 @@ inline TGLMatrix operator * (const TGLMatrix & lhs, const TGLMatrix & rhs) class TGLUtil { private: + static UInt_t fgDefaultDrawQuality; static UInt_t fgDrawQuality; protected: @@ -840,8 +917,10 @@ public: enum ELineHeadShape { kLineHeadNone, kLineHeadArrow, kLineHeadBox }; enum EAxesType { kAxesNone, kAxesEdge, kAxesOrigin }; - static void SetDrawQuality(UInt_t dq) { fgDrawQuality = dq; } - static void ResetDrawQuality() { fgDrawQuality = 60; } + static void SetDrawQuality(UInt_t dq) { fgDrawQuality = dq; } + static void ResetDrawQuality() { fgDrawQuality = fgDefaultDrawQuality; } + static UInt_t GetDefaultDrawQuality() { return fgDefaultDrawQuality; } + static void SetDefaultDrawQuality(UInt_t dq) { fgDefaultDrawQuality = dq; } // TODO: These draw routines should take LOD hints static void SetDrawColors(const Float_t rgba[4]); diff --git a/gl/inc/TGLViewer.h b/gl/inc/TGLViewer.h index 69d48a52f43..a66c8c31bff 100644 --- a/gl/inc/TGLViewer.h +++ b/gl/inc/TGLViewer.h @@ -91,10 +91,14 @@ protected: TGLOvlSelectRecord fOvlSelRec; //! select record from last overlay select // Mouse ineraction +public: + enum EPushAction { kPushStd, + kPushCamCenter }; enum EDragAction { kDragNone, kDragCameraRotate, kDragCameraTruck, kDragCameraDolly, kDragOverlay }; - +protected: + EPushAction fPushAction; EDragAction fAction; TPoint fLastPos; UInt_t fActiveButtonID; @@ -105,8 +109,10 @@ protected: TGLRect fViewport; //! viewport - drawn area Color_t fClearColor; //! clear-color Int_t fAxesType; //! axes type + Bool_t fAxesDepthTest; //! remove guides hidden-lines Bool_t fReferenceOn; //! reference marker on? TGLVertex3 fReferencePos; //! reference position + Bool_t fDrawCameraCenter; //! reference marker on? TGLCameraMarkupStyle * fCameraMarkup; //! markup size of viewport in scene units Bool_t fInitGL; //! has GL been initialised? @@ -184,14 +190,21 @@ public: // External GUI component interface TGLCamera & CurrentCamera() const { return *fCurrentCamera; } void SetCurrentCamera(ECameraType camera); - void SetOrthoCamera(ECameraType camera, Double_t left, Double_t right, Double_t top, Double_t bottom); + void SetOrthoCamera(ECameraType camera, Double_t zoom, Double_t dolly, + Double_t center[3], Double_t hRotate, Double_t vRotate); void SetPerspectiveCamera(ECameraType camera, Double_t fov, Double_t dolly, Double_t center[3], Double_t hRotate, Double_t vRotate); - void GetGuideState(Int_t & axesType, Bool_t & referenceOn, Double_t referencePos[3]) const; - void SetGuideState(Int_t axesType, Bool_t referenceOn, const Double_t referencePos[3]); + void GetGuideState(Int_t & axesType, Bool_t & axesDepthTest, Bool_t & referenceOn, Double_t* referencePos) const; + void SetGuideState(Int_t axesType, Bool_t axesDepthTest, Bool_t referenceOn, const Double_t* referencePos); + void SetDrawCameraCenter(Bool_t x); + Bool_t GetDrawCameraCenter() { return fDrawCameraCenter; } + void PickCameraCenter() { fPushAction = kPushCamCenter; RefreshPadEditor(this); } TGLCameraMarkupStyle* GetCameraMarkup() const { return fCameraMarkup; } void SetCameraMarkup(TGLCameraMarkupStyle* m) { fCameraMarkup = m; } + EPushAction GetPushAction() const { return fPushAction; } + EDragAction GetAction() const { return fAction; } + const TGLPhysicalShape * GetSelected() const; // Draw and selection diff --git a/gl/inc/TGLViewerEditor.h b/gl/inc/TGLViewerEditor.h index bd5ae06325a..ab97dfd37e0 100644 --- a/gl/inc/TGLViewerEditor.h +++ b/gl/inc/TGLViewerEditor.h @@ -42,10 +42,19 @@ private: TGTextButton *fCameraHome; //"Guides" tab's controls + TGCheckButton *fCameraCenterExt; + TGTextButton *fCaptureCenter; + TGCheckButton *fDrawCameraCenter; + TGNumberEntry *fCameraCenterX; + TGNumberEntry *fCameraCenterY; + TGNumberEntry *fCameraCenterZ; + + Int_t fAxesType; TGButtonGroup *fAxesContainer; TGRadioButton *fAxesNone; TGRadioButton *fAxesEdge; TGRadioButton *fAxesOrigin; + TGCheckButton *fAxesDepthTest; TGGroupFrame *fRefContainer; TGCheckButton *fReferenceOn; @@ -72,6 +81,8 @@ private: void CreateGuidesTab(); void CreateClippingTab(); + void UpdateReferencePosState(); + public: TGLViewerEditor(const TGWindow *p=0, Int_t width=140, Int_t height=30, UInt_t options=kChildFrame, Pixel_t back=GetDefaultFrameBackground()); @@ -88,13 +99,19 @@ public: void DoResetCameraOnDoubleClick(); void DoUpdateScene(); void DoCameraHome(); + void DoCameraCenterExt(); + void DoCaptureCenter(); + void DoDrawCameraCenter(); + void UpdateCameraCenter(); //Axis manipulation - void UpdateViewerGuides(); - void UpdateReferencePos(); + void UpdateViewerAxes(Int_t id); + void UpdateViewerReference(); void DoCameraMarkup(); void DetachFromPad(){fIsInPad = kFALSE;} + static TGNumberEntry* MakeLabeledNEntry(TGCompositeFrame* p, const char* name, Int_t labelw,Int_t nd=7, Int_t s=5); + ClassDef(TGLViewerEditor, 0) //GUI for editing TGLViewer attributes }; diff --git a/gl/src/TGLCamera.cxx b/gl/src/TGLCamera.cxx index 4e575a2828e..cc15051f38e 100644 --- a/gl/src/TGLCamera.cxx +++ b/gl/src/TGLCamera.cxx @@ -13,6 +13,7 @@ #include "TGLIncludes.h" #include "TGLBoundingBox.h" #include "TError.h" +#include "TMath.h" ////////////////////////////////////////////////////////////////////////// // // @@ -37,9 +38,15 @@ ClassImp(TGLCamera) const Double_t TGLCamera::fgInterestBoxExpansion = 1.3; +UInt_t TGLCamera::fgDollyDeltaSens = 500; //______________________________________________________________________________ TGLCamera::TGLCamera() : + fExternalCenter(kFALSE), + fCenter(&fDefCenter), + fNearClip(0), fFarClip(0), + fDollyDefault(1.0), fDollyDistance(1.0), + fVAxisMinAngle(0.01f), fCacheDirty(kTRUE), fTimeStamp (1), fProjM(), fModVM(), fClipM(), @@ -50,6 +57,29 @@ TGLCamera::TGLCamera() : for (UInt_t i = 0; i < kPlanesPerFrustum; i++ ) { fFrustumPlanes[i].Set(1.0, 0.0, 0.0, 0.0); } + TGLVertex3 origin; + fCamBase.Set(origin, TGLVector3(1, 0, 0), TGLVector3(0, 0, 1)); +} + +//______________________________________________________________________________ +TGLCamera::TGLCamera(const TGLVector3 & hAxis, const TGLVector3 & vAxis) : + fExternalCenter(kFALSE), + fCenter(&fDefCenter), + fNearClip(0), fFarClip(0), + fDollyDefault(1.0), fDollyDistance(1.0), + fVAxisMinAngle(0.01f), + fCacheDirty(kTRUE), + fTimeStamp (1), + fProjM(), fModVM(), fClipM(), + fViewport(0,0,100,100), + fLargestSeen(0.0) +{ + // Default base camera constructor + for (UInt_t i = 0; i < kPlanesPerFrustum; i++ ) { + fFrustumPlanes[i].Set(1.0, 0.0, 0.0, 0.0); + } + TGLVertex3 origin; + fCamBase.Set(origin, vAxis, hAxis); } //______________________________________________________________________________ @@ -690,14 +720,34 @@ Bool_t TGLCamera::AdjustAndClampVal(Double_t & val, Double_t min, Double_t max, val = max; } - if (val != oldVal) - { - return kTRUE; - } - else - { - return kFALSE; + return val != oldVal; +} + +//______________________________________________________________________________ +Double_t TGLCamera::AdjustDelta(Int_t screenShift, Double_t deltaFactor, + Bool_t mod1, Bool_t mod2) const +{ + // Adjust a passed screen value and apply modifiers. + // See AdjustAndClampVal() for details. + + if (screenShift == 0) + return 0; + + // Calculate a sensitivity based on passed modifiers + Double_t sens = 1.0; + + if (mod1) { + sens *= 0.1; + if (mod2) { + sens *= 0.1; + } + } else { + if (mod2) { + sens *= 10.0; + } } + + return sens * deltaFactor * screenShift; } //______________________________________________________________________________ @@ -736,3 +786,135 @@ void TGLCamera::DrawDebugAids() const glVertex3dv(end.CArr()); glEnd(); } + +//______________________________________________________________________________ +void TGLCamera::SetExternalCenter(Bool_t enable) +{ + // Set camera center diffrent than scene center, if enable is kTRUE. + + if (fExternalCenter == enable) + return; + + fExternalCenter = enable; + if (fExternalCenter) + fCenter = &fExtCenter; + else + fCenter = &fDefCenter; + + TGLMatrix bt = fCamBase * fCamTrans; + fCamBase.SetBaseVec(4, *fCenter); + TGLMatrix binv = fCamBase; binv.Invert(); + fCamTrans = binv * bt; + + IncTimeStamp(); +} + +//______________________________________________________________________________ +void TGLCamera::SetCenterVec(Double_t x, Double_t y, Double_t z) +{ + // Set camera center vector. + + if (fExternalCenter) + fExtCenter.Set(x, y, z); + else + fDefCenter.Set(x, y, z); + + TGLMatrix bt = fCamBase * fCamTrans; + fCamBase.SetBaseVec(4, *fCenter); + TGLMatrix binv = fCamBase; binv.Invert(); + fCamTrans = binv * bt; + + IncTimeStamp(); +} + +//______________________________________________________________________________ +Bool_t TGLCamera::Truck(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2) +{ + // Truck the camera - 'move camera parallel to film plane'. + // Returns kTRUE is redraw required (camera change), kFALSE otherwise. + + Double_t xstep = AdjustDelta(xDelta, 0.2*fDollyDistance, mod1, mod2); + fCamTrans.MoveLF(2, -xstep); + + Double_t ystep = AdjustDelta(yDelta, 0.2*fDollyDistance, mod1, mod2); + fCamTrans.MoveLF(3, -ystep); + + IncTimeStamp(); + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t TGLCamera::Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2) +{ + // Rotate the camera round view volume center established in Setup(). + // Arguments are: + // xDelta - horizontal delta (pixels) + // YDelta - vertical delta (pixels) + + Double_t vRotate = AdjustDelta(xDelta, TMath::TwoPi() / fViewport.Width(), mod1, mod2); + Double_t hRotate = AdjustDelta(yDelta, TMath::Pi() / fViewport.Height(), mod1, mod2); + + return RotateRad(hRotate, vRotate); +} + +//______________________________________________________________________________ +Bool_t TGLCamera::RotateRad(Double_t hRotate, Double_t vRotate) +{ + // Rotate camera around center. + + using namespace TMath; + if (hRotate != 0.0) + { + TGLVector3 fwd = fCamTrans.GetBaseVec(1); + TGLVector3 lft = fCamTrans.GetBaseVec(2); + TGLVector3 up = fCamTrans.GetBaseVec(3); + TGLVector3 pos = fCamTrans.GetTranslation(); + + TGLVector3 deltaT = pos - (pos*lft)*lft; + Double_t deltaF = deltaT * fwd; + Double_t deltaU = deltaT * up; + + // up vector lock + TGLVector3 zdir = fCamBase.GetBaseVec(3); + fCamBase.RotateIP(fwd); + Double_t theta = ACos(fwd*zdir); + if(theta+hRotate < fVAxisMinAngle) + hRotate = fVAxisMinAngle - theta; + else if(theta+hRotate > Pi() - fVAxisMinAngle) + hRotate = Pi() - fVAxisMinAngle - theta; + + fCamTrans.MoveLF(1, -deltaF); + fCamTrans.MoveLF(3, -deltaU); + fCamTrans.RotateLF(3, 1, hRotate); + fCamTrans.MoveLF(3, deltaU); + fCamTrans.MoveLF(1, deltaF); + } + if (vRotate != 0.0) + { + fCamTrans.RotatePF(1, 2, -vRotate); + } + + IncTimeStamp(); + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t TGLCamera::Dolly(Int_t delta, Bool_t mod1, Bool_t mod2) +{ + // Dolly the camera - 'move camera along eye line, retaining lens focal length'. + // Arguments are: + // + // 'delta' - mouse viewport delta (pixels) - +ive dolly in, -ive dolly out + // 'mod1' / 'mod2' - sensitivity modifiers - see TGLCamera::AdjustAndClampVal() + // + // Returns kTRUE is redraw required (camera change), kFALSE otherwise. + + Double_t step = AdjustDelta(delta, fDollyDistance, mod1, mod2); + if (step == 0) + return kFALSE; + + fCamTrans.MoveLF(1, -step); + + IncTimeStamp(); + return kTRUE; +} diff --git a/gl/src/TGLClipSetEditor.cxx b/gl/src/TGLClipSetEditor.cxx index abcecb716a9..eeb7a69bc08 100644 --- a/gl/src/TGLClipSetEditor.cxx +++ b/gl/src/TGLClipSetEditor.cxx @@ -18,6 +18,7 @@ #include "TGButtonGroup.h" #include "TGNumberEntry.h" +#include "TGLViewerEditor.h" //______________________________________________________________________________ // TGLClipSetSubEditor @@ -49,45 +50,36 @@ TGLClipSetSubEditor::TGLClipSetSubEditor(const TGWindow *p) : new TGRadioButton(fTypeButtons, "Plane"); new TGRadioButton(fTypeButtons, "Box"); - AddFrame(fTypeButtons, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + AddFrame(fTypeButtons, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 2, 2)); // Clip inside / edit fClipInside = new TGCheckButton(this, "Clip away inside"); - AddFrame(fClipInside, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + AddFrame(fClipInside, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 2, 2)); fClipEdit = new TGCheckButton(this, "Edit In Viewer"); - AddFrame(fClipEdit, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + AddFrame(fClipEdit, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 2, 2)); fClipShow = new TGCheckButton(this, "Show In Viewer"); - AddFrame(fClipShow, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + AddFrame(fClipShow, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 2, 2)); // Plane properties fPlanePropFrame = new TGCompositeFrame(this); - //fPlanePropFrame->SetCleanup(kDeepCleanup); - AddFrame(fPlanePropFrame, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + AddFrame(fPlanePropFrame, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 2, 2)); static const char * const planeStr[] = { "aX + ", "bY +", "cZ + ", "d = 0" }; - for (Int_t i = 0; i < 4; ++i) { - TGLabel *label = new TGLabel(fPlanePropFrame, planeStr[i]); - fPlanePropFrame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 3, 3, 3, 3)); - fPlaneProp[i] = new TGNumberEntry(fPlanePropFrame, 1., 8); - fPlanePropFrame->AddFrame(fPlaneProp[i], new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); - } + for (Int_t i = 0; i < 4; ++i) + fPlaneProp[i] = TGLViewerEditor::MakeLabeledNEntry(fPlanePropFrame, planeStr[i] , 40); // Box properties fBoxPropFrame = new TGCompositeFrame(this); - AddFrame(fBoxPropFrame, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + AddFrame(fBoxPropFrame, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 2, 2)); static const char * const boxStr[] = {"Center X", "Center Y", "Center Z", "Length X", "Length Y", "Length Z" }; - for (Int_t i = 0; i < 6; ++i) { - TGLabel *label = new TGLabel(fBoxPropFrame, boxStr[i]); - fBoxPropFrame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 3, 3, 3, 3)); - fBoxProp[i] = new TGNumberEntry(fBoxPropFrame, 1., 8); - fBoxPropFrame->AddFrame(fBoxProp[i], new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); - } + for (Int_t i = 0; i < 6; ++i) + fBoxProp[i] = TGLViewerEditor::MakeLabeledNEntry(fBoxPropFrame, boxStr[i] , 60); // Apply button fApplyButton = new TGTextButton(this, "Apply"); - AddFrame(fApplyButton, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + AddFrame(fApplyButton, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 2, 2)); fTypeButtons->Connect("Clicked(Int_t)", "TGLClipSetSubEditor", this, "ClipTypeChanged(Int_t)"); fClipInside->Connect("Clicked()", "TGLClipSetSubEditor", this, "UpdateViewerClip()"); diff --git a/gl/src/TGLLightSet.cxx b/gl/src/TGLLightSet.cxx index 283f9411c50..5d372322d4b 100644 --- a/gl/src/TGLLightSet.cxx +++ b/gl/src/TGLLightSet.cxx @@ -83,9 +83,6 @@ void TGLLightSet::StdSetupLights(const TGLBoundingBox& bbox, Double_t lightRadius = bbox.Extents().Mag() * 2.9; Double_t sideLightsZ, frontLightZ; - // Find Z depth (in eye coords) for front and side lights - // Has to be handlded differently due to ortho camera infinite - // viewpoint. TODO: Move into camera classes? const TGLOrthoCamera* orthoCamera = dynamic_cast<const TGLOrthoCamera*>(&camera); if (orthoCamera) { // Find distance from near clip plane to furstum center - i.e. vector of half @@ -95,14 +92,13 @@ void TGLLightSet::StdSetupLights(const TGLBoundingBox& bbox, frontLightZ = sideLightsZ; } else { // Perspective camera - - // Extract vector from camera eye point to center - // Camera must have been applied already + // Extract vector from camera eye point to center. + // Camera must have been applied already. TGLVector3 eyeVector = camera.EyePoint() - camera.FrustumCenter(); // Pull forward slightly (0.85) to avoid to sharp a cutoff sideLightsZ = eyeVector.Mag() * -0.85; - frontLightZ = 0.0; + frontLightZ = 0.2 * lightRadius; } // Reset the modelview so static lights are placed in fixed eye space @@ -111,26 +107,22 @@ void TGLLightSet::StdSetupLights(const TGLBoundingBox& bbox, // 0: Front, 1: Top, 2: Bottom, 3: Left, 4: Right TGLVertex3 center = bbox.Center(); - Float_t pos0[] = { center.X(), center.Y(), frontLightZ, 1.0 }; + // Float_t pos0[] = { center.X(), center.Y(), frontLightZ, 1.0 }; + Float_t pos0[] = { 0.0, 0.0, frontLightZ, 1.0 }; Float_t pos1[] = { center.X(), center.Y() + lightRadius, sideLightsZ, 1.0 }; Float_t pos2[] = { center.X(), center.Y() - lightRadius, sideLightsZ, 1.0 }; Float_t pos3[] = { center.X() - lightRadius, center.Y(), sideLightsZ, 1.0 }; Float_t pos4[] = { center.X() + lightRadius, center.Y(), sideLightsZ, 1.0 }; - Float_t frontLightColor[] = {0.35, 0.35, 0.35, 1.0}; - Float_t sideLightColor[] = {0.7, 0.7, 0.7, 1.0}; + const Float_t frontLightColor[] = { 0.4, 0.4, 0.4, 1.0 }; + const Float_t sideLightColor[] = { 0.7, 0.7, 0.7, 1.0 }; + const Float_t whiteSpec[] = { 0.8, 0.8, 0.8, 1.0 }; + const Float_t nullSpec[] = { 0.0, 0.0, 0.0, 1.0 }; + glLightfv(GL_LIGHT0, GL_POSITION, pos0); glLightfv(GL_LIGHT0, GL_DIFFUSE, frontLightColor); - if (fUseSpecular) - { - const Float_t whiteSpec[] = {1.f, 1.f, 1.f, 1.f}; - glLightfv(GL_LIGHT0, GL_SPECULAR, whiteSpec); - } - else - { - const Float_t nullSpec[] = {0.f, 0.f, 0.f, 1.f}; - glLightfv(GL_LIGHT0, GL_SPECULAR, nullSpec); - } + glLightfv(GL_LIGHT0, GL_SPECULAR, fUseSpecular ? whiteSpec : nullSpec); + glLightfv(GL_LIGHT1, GL_POSITION, pos1); glLightfv(GL_LIGHT1, GL_DIFFUSE, sideLightColor); glLightfv(GL_LIGHT2, GL_POSITION, pos2); diff --git a/gl/src/TGLLightSetEditor.cxx b/gl/src/TGLLightSetEditor.cxx index 3300b6c0fa2..a3eb025e7a9 100644 --- a/gl/src/TGLLightSetEditor.cxx +++ b/gl/src/TGLLightSetEditor.cxx @@ -28,6 +28,7 @@ ClassImp(TGLLightSetSubEditor) +//______________________________________________________________________________ TGLLightSetSubEditor::TGLLightSetSubEditor(const TGWindow *p) : TGVerticalFrame(p), fM (0), @@ -42,32 +43,41 @@ TGLLightSetSubEditor::TGLLightSetSubEditor(const TGWindow *p) : { // Constructor. - fLightFrame = new TGGroupFrame(this, "Light sources:", kLHintsTop | kLHintsCenterX); - + fLightFrame = new TGGroupFrame(this, "Light sources:", kVerticalFrame);//, kLHintsTop | kLHintsCenterX); fLightFrame->SetTitlePos(TGGroupFrame::kLeft); - AddFrame(fLightFrame, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3));//- + AddFrame(fLightFrame, new TGLayoutHints(kLHintsTop| kLHintsExpandX, 1, 1, 1, 1));//- + TGCompositeFrame* hf =0; + + hf = new TGHorizontalFrame(fLightFrame); + fTopLight = MakeLampButton("Top", TGLLightSet::kLightTop, hf); + fBottomLight = MakeLampButton("Bottom", TGLLightSet::kLightBottom, hf); + fLightFrame->AddFrame(hf, new TGLayoutHints(kLHintsTop|kLHintsExpandX, 0, 0, 2, 2)); + + hf = new TGHorizontalFrame(fLightFrame); + fLeftLight = MakeLampButton("Left", TGLLightSet::kLightLeft, hf); + fRightLight = MakeLampButton("Right", TGLLightSet::kLightRight, hf); + fLightFrame->AddFrame(hf, new TGLayoutHints(kLHintsTop|kLHintsExpandX , 0, 0, 0, 2)); - TGMatrixLayout *ml = new TGMatrixLayout(fLightFrame, 0, 1, 10); - fLightFrame->SetLayoutManager(ml); + hf = new TGHorizontalFrame(fLightFrame); + fFrontLight = MakeLampButton("Front", TGLLightSet::kLightFront, hf); + fSpecularLight = MakeLampButton("Specular", TGLLightSet::kLightSpecular, hf); - fTopLight = MakeLampButton("Top", TGLLightSet::kLightTop); - fRightLight = MakeLampButton("Right", TGLLightSet::kLightRight); - fBottomLight = MakeLampButton("Bottom", TGLLightSet::kLightBottom); - fLeftLight = MakeLampButton("Left", TGLLightSet::kLightLeft); - fFrontLight = MakeLampButton("Front", TGLLightSet::kLightFront); - fSpecularLight = MakeLampButton("Specular", TGLLightSet::kLightSpecular); + fLightFrame->AddFrame(hf, new TGLayoutHints(kLHintsTop|kLHintsExpandX, 0, 0, 0, 2)); } -TGButton* TGLLightSetSubEditor::MakeLampButton(const Text_t* name, Int_t wid) +//______________________________________________________________________________ +TGButton* TGLLightSetSubEditor::MakeLampButton(const Text_t* name, Int_t wid, + TGCompositeFrame* parent) { // Create a button for given lamp and set it up. - TGButton* b = new TGCheckButton(fLightFrame, name, wid); - fLightFrame->AddFrame(b); + TGButton* b = new TGCheckButton(parent, name, wid); + parent->AddFrame(b, new TGLayoutHints(kLHintsNormal|kLHintsExpandX, -2, 0, 0, 2)); b->Connect("Clicked()", "TGLLightSetSubEditor", this, "DoButton()"); return b; } +//______________________________________________________________________________ void TGLLightSetSubEditor::SetModel(TGLLightSet* m) { // New model was set, refresh data. @@ -84,6 +94,7 @@ void TGLLightSetSubEditor::SetModel(TGLLightSet* m) fSpecularLight->SetState(fM->GetUseSpecular() ? kButtonDown : kButtonUp); } +//______________________________________________________________________________ void TGLLightSetSubEditor::Changed() { // Data in sub-editor has been changed, emit "Changed()" signal. @@ -102,14 +113,16 @@ void TGLLightSetSubEditor::DoButton() } -//______________________________________________________________________ +//______________________________________________________________________________ // TGLLightSetEditor // // Editor for TGLLightSet. ClassImp(TGLLightSetEditor) -TGLLightSetEditor::TGLLightSetEditor(const TGWindow *p, Int_t width, Int_t height, +//______________________________________________________________________________ +TGLLightSetEditor::TGLLightSetEditor(const TGWindow *p, + Int_t width, Int_t height, UInt_t options, Pixel_t back) : TGedFrame(p, width, height, options | kVerticalFrame, back), fM (0), @@ -124,13 +137,13 @@ TGLLightSetEditor::TGLLightSetEditor(const TGWindow *p, Int_t width, Int_t heigh fSE->Connect("Changed()", "TGLLightSetEditor", this, "Update()"); } +//______________________________________________________________________________ TGLLightSetEditor::~TGLLightSetEditor() { // Destructor. } -/**************************************************************************/ - +//______________________________________________________________________________ void TGLLightSetEditor::SetModel(TObject* obj) { // SetModel ... forward to sub-editor. diff --git a/gl/src/TGLOrthoCamera.cxx b/gl/src/TGLOrthoCamera.cxx index 4eee3733233..dde467777e7 100644 --- a/gl/src/TGLOrthoCamera.cxx +++ b/gl/src/TGLOrthoCamera.cxx @@ -37,39 +37,33 @@ ClassImp(TGLOrthoCamera) UInt_t TGLOrthoCamera::fgZoomDeltaSens = 500; //______________________________________________________________________________ -TGLOrthoCamera::TGLOrthoCamera(EType type) : - fType(type), fZoomMin(0.01), fZoomDefault(0.78), fZoomMax(1000.0), +TGLOrthoCamera::TGLOrthoCamera(const TGLVector3 & hAxes, const TGLVector3 & vAxes) : + TGLCamera(hAxes, vAxes), + fType(kZOY), + fEnableRotate(kFALSE), 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), fTruck(0.0, 0.0, 0.0), fMatrix() + fZoom(1.0) { - // Construct orthographic camera with 'type' defining fixed view direction - // & orientation (in world frame): - // - // kXOY : X Horz. / Y Vert (looking towards +Z, Y up) - // kXOZ : X Horz. / Z Vert (looking towards +Y, Z up) - // kZOY : Z Horz. / Y Vert (looking towards +X, Y up) - // + // Construct orthographic camera. + Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100))); -} -//______________________________________________________________________________ -TGLOrthoCamera::TGLOrthoCamera() : - fType(kXOY), 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), fTruck(0.0, 0.0, 0.0), fShift(0.), fCenter(), - fVpChanged(kFALSE) -{ - // Construct orthographic camera. - fOrthoBox[0] = 1.; - fOrthoBox[1] = 1.; - fOrthoBox[2] = -1.; - fOrthoBox[3] = 1.; + // define camera type relative to horizontal vector + TGLVector3 v = fCamBase.GetBaseVec(1); + for(Int_t i=0; i<3; i++) + { + if(TMath::Abs(v[i]) == 1) + { + fType = (TGLOrthoCamera::EType)i; + break; + } + } } //______________________________________________________________________________ TGLOrthoCamera::~TGLOrthoCamera() { - // Destroy orthographic camera + // Destroy orthographic camera. } //______________________________________________________________________________ @@ -77,51 +71,13 @@ void TGLOrthoCamera::Setup(const TGLBoundingBox & box, Bool_t reset) { // Setup camera limits suitible to view the world volume defined by 'box' // and call Reset() to initialise camera. - static const Double_t rotMatrixXOY[] = { 1., 0., 0., 0., - 0., 1., 0., 0., - 0., 0., 1., 0., - 0., 0., 0., 1. }; - - static const Double_t rotMatrixXOZ[] = { 1., 0., 0., 0., - 0., 0., -1., 0., - 0., 1., 0., 0., - 0., 0., 0., 1. }; - static const Double_t rotMatrixZOY[] = { 0., 0., -1., 0., - 0., 1., 0., 0., - 1., 0., 0., 0., - 0., 0., 0., 1. }; + fVolume = box; - switch (fType) { - // Looking down Z axis, X horz, Y vert - case (kXOY): { - // X -> X - // Y -> Y - // Z -> Z - fVolume = box; - fMatrix.Set(rotMatrixXOY); - break; - } - // Looking down Y axis, X horz, Z vert - case (kXOZ): { - // X -> X - // Z -> Y - // Y -> Z - fVolume.SetAligned(TGLVertex3(box.XMin(), box.ZMin(), box.YMin()), - TGLVertex3(box.XMax(), box.ZMax(), box.YMax())); - fMatrix.Set(rotMatrixXOZ); - break; - } - // Looking down X axis, Z horz, Y vert - case (kZOY): { - // Z -> X - // Y -> Y - // X -> Z - fVolume.SetAligned(TGLVertex3(box.ZMin(), box.YMin(), box.XMin()), - TGLVertex3(box.ZMax(), box.YMax(), box.XMax())); - fMatrix.Set(rotMatrixZOY); - break; - } + if (fExternalCenter == kFALSE) + { + TGLVertex3 center = box.Center(); + SetCenterVec(center.X(), center.Y(), center.Z()); } if (reset) Reset(); @@ -132,29 +88,33 @@ void TGLOrthoCamera::Reset() { // Reset the camera to defaults - trucking, zooming to reframe the world volume // established in Setup(). Note: limits defined in Setup() are not adjusted. - fTruck.Set(0.0, 0.0, 0.0); - fZoom = fZoomDefault; - IncTimeStamp(); -} -//______________________________________________________________________________ -Bool_t TGLOrthoCamera::Dolly(Int_t delta, Bool_t mod1, Bool_t mod2) -{ - // Dolly the camera - 'move camera along eye line, retaining lens focal length'. - // Arguments are: - // - // 'delta' - mouse viewport delta (pixels) - +ive dolly in, -ive dolly out - // 'mod1' / 'mod2' - sensitivity modifiers - see TGLCamera::AdjustAndClampVal() - // - // For an orthographic camera dollying and zooming are identical and both equate - // logically to a rescaling of the viewport limits - without center shift. - // There is no perspective foreshortening or lens 'focal length'. - // - // Returns kTRUE is redraw required (camera change), kFALSE otherwise. + TGLVector3 e = fVolume.Extents(); + switch (fType) { + case kX0Y: { + // X -> X, Y -> Y, Z -> Z + fDefXSize = e.X(); fDefYSize = e.Y(); + break; + } + case kXOZ: { + // X -> X, Z -> Y, Y -> Z + fDefXSize = e.X(); fDefYSize = e.Z(); + break; + } + + case kZOY: { + // Z -> X, Y -> Y, X -> Z + fDefXSize = e.Z(); fDefYSize = e.Y(); + break; + } + } - // TODO: Bring all mouse handling into camera classes - would simplify interface and - // remove these non-generic cases. - return Zoom(delta, mod1, mod2); + fDollyDefault = 1.25*0.5*TMath::Sqrt(3)*fVolume.Extents().Mag(); + fDollyDistance = 0.002 * fDollyDefault; + fZoom = fZoomDefault; + fCamTrans.SetIdentity(); + fCamTrans.MoveLF(1, fDollyDefault); + IncTimeStamp(); } //______________________________________________________________________________ @@ -172,8 +132,6 @@ Bool_t TGLOrthoCamera::Zoom (Int_t delta, Bool_t mod1, Bool_t mod2) // // Returns kTRUE is redraw required (camera change), kFALSE otherwise. - // TODO: Bring all mouse handling into camera classes - would simplify interface and - // remove these non-generic cases. if (AdjustAndClampVal(fZoom, fZoomMin, fZoomMax, -delta*2, fgZoomDeltaSens, mod1, mod2)) { IncTimeStamp(); @@ -186,39 +144,15 @@ Bool_t TGLOrthoCamera::Zoom (Int_t delta, Bool_t mod1, Bool_t mod2) } //______________________________________________________________________________ -Bool_t TGLOrthoCamera::Truck(Int_t x, Int_t y, Int_t xDelta, Int_t yDelta) -{ - // Truck the camera - 'move camera parallel to film plane'. The film - // plane is defined by the EyePoint() / EyeDirection() pair. Define motion - // using center point (x/y) and delta (xDelta/yDelta) - the mouse motion. - // - // Returns kTRUE is redraw required (camera change), kFALSE otherwise. - // - // Note: Trucking is often mistakenly refered to as 'pan' or 'panning'. - // Panning is swivelling the camera on it's own axis - the eye point. - - //TODO: Convert TGLRect so this not required - GLint viewport[4] = { fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height() }; - TGLVertex3 start, end; - // Trucking done at near clipping plane - gluUnProject(x, y, 0.0, fModVM.CArr(), fProjM.CArr(), viewport, &start.X(), &start.Y(), &start.Z()); - gluUnProject(x + xDelta, y + yDelta, 0.0, fModVM.CArr(), fProjM.CArr(), viewport, &end.X(), &end.Y(), &end.Z()); - fTruck = fTruck + (end - start); - IncTimeStamp(); - return kTRUE; -} - -//______________________________________________________________________________ -Bool_t TGLOrthoCamera::Rotate(Int_t /*xDelta*/, Int_t /*yDelta*/) +Bool_t TGLOrthoCamera::Rotate(Int_t xDelta, Int_t yDelta, Bool_t mod1, Bool_t mod2) { // Rotate the camera - 'swivel round the view volume center'. - // Ignored at present for orthographic cameras - have a fixed direction. - // Could let the user or external code create non-axis - // ortho projects by adjusting H/V rotations in future. - // // Returns kTRUE is redraw required (camera change), kFALSE otherwise. - return kFALSE; + if (fEnableRotate) + return kFALSE; + else + return TGLCamera::Rotate(xDelta, yDelta, mod1, mod2); } //______________________________________________________________________________ @@ -235,8 +169,18 @@ void TGLOrthoCamera::Apply(const TGLBoundingBox & /*box*/, // as one passed to Setup(). // 'pickRect' - optional picking rect. If non-null, restrict drawing to this // viewport rect. + 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(); @@ -249,82 +193,161 @@ void TGLOrthoCamera::Apply(const TGLBoundingBox & /*box*/, (Int_t*) fViewport.CArr()); } - if(fViewport.Width() == 0 || fViewport.Height() == 0) { - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - return; - } - - TGLVector3 extents = fVolume.Extents(); - Double_t width = extents.X(); - Double_t height = extents.Y(); - Double_t halfRange; - if (width > height) { - halfRange = width / 2.0; + Double_t halfRangeX, halfRangeY; + if (fDefYSize*fViewport.Width()/fDefXSize > fViewport.Height()) { + halfRangeY = 0.5 *fDefYSize; + halfRangeX = halfRangeY*fViewport.Width()/fViewport.Height(); } else { - halfRange = height / 2.0; + halfRangeX = 0.5 *fDefXSize; + halfRangeY = halfRangeX*fViewport.Height()/fViewport.Width(); } - halfRange /= fZoom; - - // For near/far clipping half depth give extra slack so clip objects/manips - // are visible - Double_t halfDepth = extents.Mag(); - const TGLVertex3 & center = fVolume.Center(); - glOrtho(center.X() - halfRange, - center.X() + halfRange, - center.Y() - halfRange, - center.Y() + halfRange, - -center.Z() + halfDepth, - -center.Z() - halfDepth); + halfRangeX /= fZoom; + halfRangeY /= fZoom; + fNearClip = 0.05*fDollyDefault; + fFarClip = 2.0*fDollyDefault; + glOrtho(-halfRangeX, halfRangeX, + -halfRangeY, halfRangeY, + fNearClip, fFarClip); + // ii) setup modelview 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); - glScaled(1.0 / fViewport.Aspect(), 1.0, 1.0); + gluLookAt(pos[0], pos[1], pos[2], + center[0], center[1], center[2], + up[0], up[1], up[2]); - // Debug aid - show current volume - /*glDisable(GL_LIGHTING); - glColor3d(0.0, 0.0, 1.0); - fVolume.Draw(); - glEnable(GL_LIGHTING);*/ + if (fCacheDirty) UpdateCache(); +} - glMultMatrixd(fMatrix.CArr()); - glTranslated(fTruck.X(), fTruck.Y(), fTruck.Z()); - if (fCacheDirty) { - UpdateCache(); - } +//______________________________________________________________________________ +void TGLOrthoCamera::Configure(Double_t zoom, Double_t dolly, Double_t center[3], + Double_t hRotate, Double_t vRotate) +{ + // Configure the camera state. + + fZoom = zoom; + SetCenterVec(center[0], center[1], center[2]); + fCamTrans.MoveLF(1, dolly); + RotateRad(hRotate, vRotate); + + IncTimeStamp(); } //______________________________________________________________________________ -void TGLOrthoCamera::Configure(Double_t left, Double_t right, - Double_t top, Double_t bottom) +void TGLOrthoCamera::Markup(TGLCameraMarkupStyle* ms) const { - // Configure the camera state - Double_t width = right - left; - Double_t height = top - bottom; - - Double_t xZoom = width/fVolume.Extents().X(); - Double_t yZoom = height/fVolume.Extents().Y(); - - fZoom = (xZoom > yZoom) ? xZoom : yZoom; - - // kXOY : X Horz. / Y Vert (looking towards +Z, Y up) - // kXOZ : X Horz. / Z Vert (looking towards +Y, Z up) - // kZOY : Z Horz. / Y Vert (looking towards +X, Y up) - if (fType == kXOY) { - fTruck.X() = right - left; - fTruck.Y() = top - bottom; - } else if (fType == kXOZ) { - fTruck.X() = right - left; - fTruck.Z() = top - bottom; - } else if (fType == kZOY) { - fTruck.Z() = right - left; - fTruck.Y() = top - bottom; + // Write viewport dimensions on screen. + + Double_t width = fFrustumPlanes[kLeft].D() + fFrustumPlanes[kRight].D(); + Double_t maxbarw0 = ms->Barsize()*width; + + // get 10-exponent + Int_t exp = (Int_t) TMath::Floor(TMath::Log10(maxbarw0)); + + Double_t fact = maxbarw0/TMath::Power(10, exp); + Float_t barw; + + if (fact > 5) { + barw = 5*TMath::Power(10, exp); + glColor3d(1., 0., 1.0); } - IncTimeStamp(); + else if (fact > 2) { + barw = 2*TMath::Power(10, exp); + glColor3d(0., 1., 1.0); + } else { + barw = TMath::Power(10, exp); + glColor3d(0., 0., 1.0); + } + Double_t wproc = barw / width; + Int_t screenw = fViewport.Width(); + Int_t screenh = fViewport.Height(); + + Double_t sX, sY; + Double_t offX, offY, txtOffX, txtOffY; + ms->Offsets(offX, offY, txtOffX, txtOffY); + + switch (ms->Position()) + { + case TGLCameraMarkupStyle::kLUp: + sX = offX; + sY = screenh - offY - txtOffY - 8; + break; + case TGLCameraMarkupStyle::kLDn: + sX = offX; + sY = offY; + break; + case TGLCameraMarkupStyle::kRUp: + sX = screenw - ms->Barsize()*screenw - offX; + sY = screenh - offY - txtOffY - 8; + break; + case TGLCameraMarkupStyle::kRDn: + sX = screenw - ms->Barsize()*screenw - offX; + sY = offY; + break; + default: + sX = 0.5*screenw; + sY = 0.5*screenh; + break; + } + + glTranslatef(sX, sY, 0); + + glLineWidth(2.); + glColor3d(1., 1., 1.); + + Double_t mH = 2; + + glBegin(GL_LINES); + // horizontal static + glVertex3d(0, 0.,0.); + glVertex3d(ms->Barsize()*screenw, 0., 0.); + // corner bars + glVertex3d(ms->Barsize()*screenw, mH, 0.); + glVertex3d(ms->Barsize()*screenw, -mH, 0.); + // marker cormer bar + glColor3d(1., 0., 0.); + glVertex3d(0., mH, 0.); + glVertex3d(0., -mH, 0.); + // marker pointer + glVertex3d(screenw*wproc, 0., 0.); + glVertex3d(screenw*wproc, mH, 0.); + //marker line + glVertex3d(0, 0.,0.); + glVertex3d(screenw*wproc, 0., 0.); + glEnd(); + + glTranslated(-sX, -sY, 0); + + TString str = Form("%.*f", (exp < 0) ? -exp : 0, barw); + TGLUtil::DrawNumber(str, TGLVertex3(sX + txtOffX, sY + txtOffY, -1)); +} + +////////////////////////////////////////////////////////////////////////////// +// +// TGLPlotPainter +// +///////////////////////////////////////////////////////////////////////////// +//______________________________________________________________________________ +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) +{ + // Construct orthographic camera. + fOrthoBox[0] = 1.; + fOrthoBox[1] = 1.; + fOrthoBox[2] = -1.; + fOrthoBox[3] = 1.; } //______________________________________________________________________________ @@ -480,92 +503,3 @@ void TGLOrthoCamera::ZoomOut() fZoom *= 1.2; } -//______________________________________________________________________________ -void TGLOrthoCamera::Markup(TGLCameraMarkupStyle* ms) const -{ - // Write viewport dimensions on screen. - - TGLVector3 extents = fVolume.Extents(); - Double_t width = extents.X()/fZoom; - Double_t maxbarw0 = ms->Barsize()*width; - - // get 10-exponent - Int_t exp = (Int_t) TMath::Floor(TMath::Log10(maxbarw0)); - - Double_t fact = maxbarw0/TMath::Power(10, exp); - Float_t barw; - - if (fact > 5) { - barw = 5*TMath::Power(10, exp); - glColor3d(1., 0., 1.0); - } - else if (fact > 2) { - barw = 2*TMath::Power(10, exp); - glColor3d(0., 1., 1.0); - } else { - barw = TMath::Power(10, exp); - glColor3d(0., 0., 1.0); - } - Double_t wproc = barw / width; - Int_t screenw = fViewport.Width(); - Int_t screenh = fViewport.Height(); - - Double_t sX, sY; - Double_t offX, offY, txtOffX, txtOffY; - ms->Offsets(offX, offY, txtOffX, txtOffY); - - switch (ms->Position()) - { - case TGLCameraMarkupStyle::kLUp: - sX = offX; - sY = screenh - offY - txtOffY - 8; - break; - case TGLCameraMarkupStyle::kLDn: - sX = offX; - sY = offY; - break; - case TGLCameraMarkupStyle::kRUp: - sX = screenw - ms->Barsize()*screenw - offX; - sY = screenh - offY - txtOffY - 8; - break; - case TGLCameraMarkupStyle::kRDn: - sX = screenw - ms->Barsize()*screenw - offX; - sY = offY; - break; - default: - sX = 0.5*screenw; - sY = 0.5*screenh; - break; - } - - glTranslatef(sX, sY, 0); - - glLineWidth(2.); - glColor3d(1., 1., 1.); - - Double_t mH = 2; - - glBegin(GL_LINES); - // horizontal static - glVertex3d(0, 0.,0.); - glVertex3d(ms->Barsize()*screenw, 0., 0.); - // corner bars - glVertex3d(ms->Barsize()*screenw, mH, 0.); - glVertex3d(ms->Barsize()*screenw, -mH, 0.); - // marker cormer bar - glColor3d(1., 0., 0.); - glVertex3d(0., mH, 0.); - glVertex3d(0., -mH, 0.); - // marker pointer - glVertex3d(screenw*wproc, 0., 0.); - glVertex3d(screenw*wproc, mH, 0.); - //marker line - glVertex3d(0, 0.,0.); - glVertex3d(screenw*wproc, 0., 0.); - glEnd(); - - glTranslated(-sX, -sY, 0); - - TString str = Form("%.*f", (exp < 0) ? -exp : 0, barw); - TGLUtil::DrawNumber(str, TGLVertex3(sX + txtOffX, sY + txtOffY, -1)); -} diff --git a/gl/src/TGLPerspectiveCamera.cxx b/gl/src/TGLPerspectiveCamera.cxx index 5c8d9d2b58d..b525f79c6af 100644 --- a/gl/src/TGLPerspectiveCamera.cxx +++ b/gl/src/TGLPerspectiveCamera.cxx @@ -16,9 +16,6 @@ #include "TMath.h" #include "TError.h" -// TODO: Find somewhere else -#define PI 3.141592654 - ////////////////////////////////////////////////////////////////////////// // // // TGLPerspectiveCamera // @@ -37,20 +34,16 @@ ClassImp(TGLPerspectiveCamera) Double_t TGLPerspectiveCamera::fgFOVMin = 0.01; Double_t TGLPerspectiveCamera::fgFOVDefault = 30; Double_t TGLPerspectiveCamera::fgFOVMax = 120.0; - -UInt_t TGLPerspectiveCamera::fgDollyDeltaSens = 500; UInt_t TGLPerspectiveCamera::fgFOVDeltaSens = 500; //______________________________________________________________________________ -TGLPerspectiveCamera::TGLPerspectiveCamera(const TGLVector3 & hAxis, const TGLVector3 & vAxis) : - fHAxis(hAxis), fVAxis(vAxis), - fDollyMin(1.0), fDollyDefault(10.0), fDollyMax(100.0), - fFOV(fgFOVDefault), fDolly(fDollyDefault), - fVRotate(-90.0), fHRotate(90.0), - fCenter(0.0, 0.0, 0.0), fTruck(0.0, 0.0, 0.0) +TGLPerspectiveCamera::TGLPerspectiveCamera(const TGLVector3 & hAxes, const TGLVector3 & vAxes) : + TGLCamera(hAxes, vAxes), + fFOV(fgFOVDefault) { // Construct perspective camera Setup(TGLBoundingBox(TGLVertex3(-100,-100,-100), TGLVertex3(100,100,100))); + fCamTrans.MoveLF(1, fDollyDefault); } //______________________________________________________________________________ @@ -65,23 +58,23 @@ void TGLPerspectiveCamera::Setup(const TGLBoundingBox & box, Bool_t reset) // Setup camera limits suitible to view the world volume defined by 'box' // and call Reset() to initialise camera. - fCenter = box.Center(); + if (fExternalCenter == kFALSE) + { + TGLVertex3 center = box.Center(); + SetCenterVec(center.X(), center.Y(), center.Z()); + } // At default FOV, the maximum dolly should just encapsulate the longest side of box with // offset for next longetst side - - // Find two longest sides TGLVector3 extents = box.Extents(); Int_t sortInd[3]; TMath::Sort(3, extents.CArr(), sortInd); Double_t longest = extents[sortInd[0]]; Double_t nextLongest = extents[sortInd[1]]; - fDollyDefault = longest/(2.0*tan(fFOV*PI/360.0)); + fDollyDefault = longest/(2.0*tan(fgFOVDefault*TMath::Pi()/360)); fDollyDefault += nextLongest/2.0; - fDollyMin = -fDollyDefault; - fDollyDefault *= 1.2; - fDollyMax = fDollyDefault * 7.0; + fDollyDistance = 0.002 * fDollyDefault; if (reset) Reset(); @@ -92,30 +85,13 @@ void TGLPerspectiveCamera::Reset() { // Reset the camera to defaults - reframe the world volume established in Setup() // in default state. Note: limits defined in Setup() are not adjusted. + fFOV = fgFOVDefault; - fHRotate = 90.0; - fVRotate = 0.0; - fTruck.Set(-fCenter.X(), -fCenter.Y(), -fCenter.Z()); - fDolly = fDollyDefault; - IncTimeStamp(); -} -//______________________________________________________________________________ -Bool_t TGLPerspectiveCamera::Dolly(Int_t delta, Bool_t mod1, Bool_t mod2) -{ - // Dolly the camera - 'move camera along eye line, retaining lens focal length'. - // Arguments are: - // - // 'delta' - mouse viewport delta (pixels) - +ive dolly in, -ive dolly out - // 'mod1' / 'mod2' - sensitivity modifiers - see TGLCamera::AdjustAndClampVal() - // - // Returns kTRUE is redraw required (camera change), kFALSE otherwise. - if (AdjustAndClampVal(fDolly, fDollyMin, fDollyMax, delta, fgDollyDeltaSens, mod1, mod2)) { - IncTimeStamp(); - return kTRUE; - } else { - return kFALSE; - } + fCamTrans.SetIdentity(); + fCamTrans.MoveLF(1, fDollyDefault); + + IncTimeStamp(); } //______________________________________________________________________________ @@ -139,60 +115,6 @@ Bool_t TGLPerspectiveCamera::Zoom(Int_t delta, Bool_t mod1, Bool_t mod2) } } -//______________________________________________________________________________ -Bool_t TGLPerspectiveCamera::Truck(Int_t x, Int_t y, Int_t xDelta, Int_t yDelta) -{ - // Truck the camera - 'move camera parallel to film plane'. The film - // plane is defined by the EyePoint() / EyeDirection() pair. Define motion - // using center point (x/y) and delta (xDelta/yDelta) - the mouse motion. - // For an orthographic projection this means all objects (regardless of - // camera distance) track the mouse motion. - // - // Returns kTRUE is redraw required (camera change), kFALSE otherwise. - // - // Note: Trucking is often mistakenly refered to as 'pan' or 'panning'. - // Panning is swivelling the camera on it's own axis - the eye point. - - TGLVertex3 start, end; - - gluUnProject(x, y, 1.0, fModVM.CArr(), fProjM.CArr(), - fViewport.CArr(), &start.X(), &start.Y(), &start.Z()); - gluUnProject(x + xDelta, y + yDelta, 1.0, fModVM.CArr(), fProjM.CArr(), - fViewport.CArr(), &end.X(), &end.Y(), &end.Z()); - TGLVector3 truckDelta = end - start; - fTruck = fTruck + truckDelta/2.0; - IncTimeStamp(); - return kTRUE; -} - -//______________________________________________________________________________ -Bool_t TGLPerspectiveCamera::Rotate(Int_t xDelta, Int_t yDelta) -{ - // Rotate the camera round view volume center established in Setup(). - // Arguments are: - // - // xDelta - horizontal delta (pixels) - // YDelta - vertical delta (pixels) - // - // Deltas are divided by equivalent viewport dimension and scaled - // by full rotation - i.e. translates fraction of viewport to - // fractional rotation. - // - // TODO: Rotation center should be changeable from outside. - - fHRotate += static_cast<float>(xDelta)/fViewport.Width() * 360.0; - fVRotate -= static_cast<float>(yDelta)/fViewport.Height() * 180.0; - if ( fVRotate > 90.0 ) { - fVRotate = 90.0; - } - if ( fVRotate < -90.0 ) { - fVRotate = -90.0; - } - - IncTimeStamp(); - return kTRUE; -} - //______________________________________________________________________________ void TGLPerspectiveCamera::Apply(const TGLBoundingBox & sceneBox, const TGLRect * pickRect) const @@ -214,38 +136,42 @@ void TGLPerspectiveCamera::Apply(const TGLBoundingBox & sceneBox, // plane intersection. // Besides, this would give as a proper control over camera transforamtion // matrix. + // + // Much better since Oct 2007, the clipping planes stuff still + // needs to be cleaned. glViewport(fViewport.X(), fViewport.Y(), fViewport.Width(), fViewport.Height()); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - if(fViewport.Width() == 0 || fViewport.Height() == 0) { + if(fViewport.Width() == 0 || fViewport.Height() == 0) + { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); return; } + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // To find decent near/far clip plane distances we construct the // frustum thus: // i) first setup perspective with arbitary near/far planes gluPerspective(fFOV, fViewport.Aspect(), 1.0, 1000.0); + // printf("FIRST STEP FOV %f, aspect %f, nearClip %f, farClip %f \n", fFOV, fViewport.Aspect(), 1., 1000.); // ii) setup modelview 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); - glTranslated(0, 0, -fDolly); - - glRotated(fVRotate, 1.0, 0.0, 0.0); - glRotated(fHRotate, 0.0, 1.0, 0.0); - - // Rotate so vertical axis is just that.... - TGLVector3 zAxis = Cross(fHAxis, fVAxis); - TGLMatrix vertMatrix(TGLVertex3(0.0, 0.0, 0.0), zAxis, &fHAxis); - glMultMatrixd(vertMatrix.CArr()); - - glTranslated(fTruck[0], fTruck[1], fTruck[2]); + gluLookAt(pos[0], pos[1], pos[2], + center[0], center[1], center[2], + up[0], up[1], up[2]); // iii) update the cached frustum planes so we can get eye point/direction Bool_t modifiedCache = kFALSE; @@ -261,33 +187,29 @@ void TGLPerspectiveCamera::Apply(const TGLBoundingBox & sceneBox, // v) find the near/far distance which just encapsulate the passed bounding box vertexes // not ideal - should really find the nearest/further points on box surface // which intersect frustum - however this much more complicated - Double_t currentDist, nearClipDist=0, farClipDist=0; + Double_t currentDist; for (UInt_t i=0; i<8; i++) { currentDist = clipPlane.DistanceTo(sceneBox[i]); - if (i==0) { - nearClipDist = currentDist; - farClipDist = nearClipDist; - } - if (currentDist < nearClipDist) { - nearClipDist = currentDist; - } - if (currentDist > farClipDist) { - farClipDist = currentDist; + if (i==0) + { + fNearClip = currentDist; + fFarClip = fNearClip; } + if (currentDist < fNearClip) + fNearClip = currentDist; + if (currentDist > fFarClip) + fFarClip = currentDist; } // Add 1% each way to avoid any rounding conflicts with drawn objects - nearClipDist *= .49; //0.99; TODO Look at - avoid removing clipping + manip objs - farClipDist *= 2.01; // 1.01 - if (farClipDist < 2.0) { - farClipDist = 2.0; - } - if (nearClipDist < farClipDist/1000.0) { - nearClipDist = farClipDist/1000.0; - } + fNearClip *= 0.49; // 0.99; TODO Look at - avoid removing clipping + manip objs + fFarClip *= 2.01; // 1.01; + if (fFarClip < 2.0) + fFarClip = 2.0; + if (fNearClip < fFarClip/1000.0) + fNearClip = fFarClip/1000.0; glMatrixMode(GL_PROJECTION); glLoadIdentity(); - // Load up any picking rect if (pickRect) { @@ -298,19 +220,11 @@ void TGLPerspectiveCamera::Apply(const TGLBoundingBox & sceneBox, } // vi) reset the perspective using the correct near/far clips distances // and restore modelview mode - gluPerspective(fFOV, fViewport.Aspect(), nearClipDist, farClipDist); - glMatrixMode(GL_MODELVIEW); + gluPerspective(fFOV, fViewport.Aspect(), fNearClip, fFarClip); - if (fCacheDirty) { - UpdateCache(); + glMatrixMode(GL_MODELVIEW); - // Tracing - only show if camera changed - if (gDebug>3) { - Info("TGLPerspectiveCamera::Apply", "FOV %f Dolly %f fVRot %f fHRot", fFOV, fDolly, fVRotate, fHRotate); - Info("TGLPerspectiveCamera::Apply", "fTruck (%f,%f,%f)", fTruck[0], fTruck[1], fTruck[2]); - Info("TGLPerspectiveCamera::Apply", "Near %f Far %f", nearClipDist, farClipDist); - } - } + if (fCacheDirty) UpdateCache(); } //______________________________________________________________________________ @@ -318,26 +232,21 @@ void TGLPerspectiveCamera::Configure(Double_t fov, Double_t dolly, Double_t cent Double_t hRotate, Double_t vRotate) { // Configure the camera state - fFOV = fov; - fDolly = dolly; - fCenter.Set(center[0], center[1], center[2]); - fHRotate = hRotate; - fVRotate = vRotate; // Don't generally constrain external configuration // However exceeding the vRotate limits or silly FOV values will // cause very weird behaviour or projections so fix these - if (fVRotate > 90.0) { - fVRotate = 90.0; - } - if (fVRotate < -90.0) { - fVRotate = -90.0; - } + if (fFOV > 170.0) { fFOV = 170.0; } else if (fFOV < 0.1) { fFOV = 0.1; } + + SetCenterVec(center[0], center[1], center[2]); + fCamTrans.MoveLF(1, dolly); + RotateRad(hRotate, vRotate); + IncTimeStamp(); } diff --git a/gl/src/TGLScenePad.cxx b/gl/src/TGLScenePad.cxx index 412e45b6e65..c1cef8efc9d 100644 --- a/gl/src/TGLScenePad.cxx +++ b/gl/src/TGLScenePad.cxx @@ -115,51 +115,7 @@ void TGLScenePad::SubPadPaint(TVirtualPad* pad) TObjOptLink *lnk = (prims) ? (TObjOptLink*)prims->FirstLink() : 0; while (lnk) { - TObject *obj = lnk->GetObject(); - if (obj->InheritsFrom(TAtt3D::Class())) - { - //printf("normal-painting %s / %s\n", obj->GetName(), obj->ClassName()); - obj->Paint(lnk->GetOption()); - } - else if (obj->InheritsFrom(TH2::Class())) - { - // printf("histo 2d\n"); - TGLObject* log = new TH2GL(); - log->SetModel(obj, lnk->GetOption()); - log->SetBBox(); - AdoptLogical(*log); - AddHistoPhysical(log); - } - else if (obj->InheritsFrom(TF2::Class())) - { - // printf("func 2d\n"); - TGLObject* log = new TF2GL(); - log->SetModel(obj, lnk->GetOption()); - log->SetBBox(); - AdoptLogical(*log); - AddHistoPhysical(log); - } - else if (obj->InheritsFrom(TGLParametricEquation::Class())) - { - // printf("parametric\n"); - TGLObject* log = new TGLParametricEquationGL(); - log->SetModel(obj, lnk->GetOption()); - log->SetBBox(); - AdoptLogical(*log); - AddHistoPhysical(log); - } - - else if (obj->InheritsFrom(TVirtualPad::Class())) - { - SubPadPaint(dynamic_cast<TVirtualPad*>(obj)); - } - else - { - // Handle 2D primitives here. - // printf("TGLScenePad::PadPaint skipping %p, %s, %s.\n", - // obj, obj->GetName(), obj->ClassName()); - obj->Paint(lnk->GetOption()); - } + ObjectPaint(lnk->GetObject(), lnk->GetOption()); lnk = (TObjOptLink*)lnk->Next(); } @@ -167,6 +123,58 @@ void TGLScenePad::SubPadPaint(TVirtualPad* pad) gPad = padsav; } +//______________________________________________________________________________ +void TGLScenePad::ObjectPaint(TObject* obj, Option_t* opt) +{ + // Override of virtual TVirtualViewer3D::ObjectPaint(). + // Special handling of 2D/3D histograms to activate Timur's + // histo-painters. + + if (obj->InheritsFrom(TAtt3D::Class())) + { + //printf("normal-painting %s / %s\n", obj->GetName(), obj->ClassName()); + obj->Paint(opt); + } + else if (obj->InheritsFrom(TH2::Class())) + { + // printf("histo 2d\n"); + TGLObject* log = new TH2GL(); + log->SetModel(obj, opt); + log->SetBBox(); + AdoptLogical(*log); + AddHistoPhysical(log); + } + else if (obj->InheritsFrom(TF2::Class())) + { + // printf("func 2d\n"); + TGLObject* log = new TF2GL(); + log->SetModel(obj, opt); + log->SetBBox(); + AdoptLogical(*log); + AddHistoPhysical(log); + } + else if (obj->InheritsFrom(TGLParametricEquation::Class())) + { + // printf("parametric\n"); + TGLObject* log = new TGLParametricEquationGL(); + log->SetModel(obj, opt); + log->SetBBox(); + AdoptLogical(*log); + AddHistoPhysical(log); + } + else if (obj->InheritsFrom(TVirtualPad::Class())) + { + SubPadPaint(dynamic_cast<TVirtualPad*>(obj)); + } + else + { + // Handle 2D primitives here. + // printf("TGLScenePad::PadPaint skipping %p, %s, %s.\n", + // obj, obj->GetName(), obj->ClassName()); + obj->Paint(opt); + } +} + //______________________________________________________________________________ void TGLScenePad::PadPaintFromViewer(TGLViewer* viewer) { diff --git a/gl/src/TGLUtil.cxx b/gl/src/TGLUtil.cxx index 03db0904d6c..46aebc6d45a 100644 --- a/gl/src/TGLUtil.cxx +++ b/gl/src/TGLUtil.cxx @@ -63,6 +63,13 @@ TGLVertex3::TGLVertex3(Double_t x, Double_t y, Double_t z) Set(x,y,z); } +//______________________________________________________________________________ +TGLVertex3::TGLVertex3(Double_t* v) +{ + // Construct a vertex with components (v[0], v[1], v[2]) + Set(v[0], v[1], v[2]); +} + //______________________________________________________________________________ TGLVertex3::TGLVertex3(const TGLVertex3 & other) { @@ -201,6 +208,7 @@ TGLLine3::~TGLLine3() void TGLLine3::Set(const TGLVertex3 & start, const TGLVertex3 & end) { // Set 3D line running from 'start' to 'end' + fVertex = start; fVector = end - start; } @@ -486,7 +494,30 @@ TGLMatrix::TGLMatrix(const TGLVertex3 & translation) } //______________________________________________________________________________ -TGLMatrix::TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 * xAxis) +TGLMatrix::TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis) +{ + // Construct matrix which when applied puts local origin at + // 'origin' and the local Z axis in direction 'z'. Both + // 'origin' and 'zAxisVec' are expressed in the parent frame + SetIdentity(); + + TGLVector3 zAxisInt(zAxis); + zAxisInt.Normalise(); + TGLVector3 arbAxis; + + if (TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Y()) && TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Z())) { + arbAxis.Set(1.0, 0.0, 0.0); + } else if (TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.X()) && TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.Z())) { + arbAxis.Set(0.0, 1.0, 0.0); + } else { + arbAxis.Set(0.0, 0.0, 1.0); + } + + Set(origin, zAxis, Cross(zAxisInt, arbAxis)); +} + +//______________________________________________________________________________ +TGLMatrix::TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 & xAxis) { // Construct matrix which when applied puts local origin at // 'origin' and the local Z axis in direction 'z'. Both @@ -550,7 +581,7 @@ void TGLMatrix::MultLeft (const TGLMatrix & lhs) } //______________________________________________________________________________ -void TGLMatrix::Set(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 * xAxis) +void TGLMatrix::Set(const TGLVertex3 & origin, const TGLVector3 & zAxis, const TGLVector3 & xAxis) { // Set matrix which when applied puts local origin at // 'origin' and the local Z axis in direction 'z'. Both @@ -558,21 +589,7 @@ void TGLMatrix::Set(const TGLVertex3 & origin, const TGLVector3 & zAxis, const T TGLVector3 zAxisInt(zAxis); zAxisInt.Normalise(); - TGLVector3 xAxisInt; - if (xAxis) { - xAxisInt = *xAxis; - } else { - TGLVector3 arbAxis; - if (TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Y()) && TMath::Abs(zAxisInt.X()) <= TMath::Abs(zAxisInt.Z())) { - arbAxis.Set(1.0, 0.0, 0.0); - } else if (TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.X()) && TMath::Abs(zAxisInt.Y()) <= TMath::Abs(zAxisInt.Z())) { - arbAxis.Set(0.0, 1.0, 0.0); - } else { - arbAxis.Set(0.0, 0.0, 1.0); - } - xAxisInt = Cross(zAxisInt, arbAxis); - } - + TGLVector3 xAxisInt(xAxis); xAxisInt.Normalise(); TGLVector3 yAxisInt = Cross(zAxisInt, xAxisInt); @@ -639,7 +656,7 @@ void TGLMatrix::SetTranslation(const TGLVertex3 & translation) } //______________________________________________________________________________ -TGLVertex3 TGLMatrix::GetTranslation() const +TGLVector3 TGLMatrix::GetTranslation() const { // Return the translation component of matrix // @@ -648,7 +665,7 @@ TGLVertex3 TGLMatrix::GetTranslation() const // . . . Z() // . . . . - return TGLVertex3(fVals[12], fVals[13], fVals[14]); + return TGLVector3(fVals[12], fVals[13], fVals[14]); } //______________________________________________________________________________ @@ -667,6 +684,16 @@ void TGLMatrix::Translate(const TGLVector3 & vect) fVals[14] += vect[2]; } +//______________________________________________________________________________ +void TGLMatrix::MoveLF(Int_t ai, Double_t amount) +{ + // Translate in local frame. + // i1, i2 are axes indices: 1 ~ x, 2 ~ y, 3 ~ z. + + const Double_t *C = fVals + 4*--ai; + fVals[12] += amount*C[0]; fVals[13] += amount*C[1]; fVals[14] += amount*C[2]; +} + //______________________________________________________________________________ void TGLMatrix::Scale(const TGLVector3 & scale) { @@ -747,6 +774,25 @@ void TGLMatrix::RotateLF(Int_t i1, Int_t i2, Double_t amount) } } +//______________________________________________________________________________ +void TGLMatrix::RotatePF(Int_t i1, Int_t i2, Double_t amount) +{ + // Rotate in parent frame. Does optimised version of MultLeft. + + if(i1 == i2) return; + + // Optimized version: + const Double_t cos = TMath::Cos(amount), sin = TMath::Sin(amount); + Double_t b1, b2; + Double_t* C = fVals; + --i1; --i2; + for(int c=0; c<4; ++c, C+=4) { + b1 = cos*C[i1] - sin*C[i2]; + b2 = cos*C[i2] + sin*C[i1]; + C[i1] = b1; C[i2] = b2; + } +} + //______________________________________________________________________________ void TGLMatrix::TransformVertex(TGLVertex3 & vertex) const { @@ -783,6 +829,107 @@ void TGLMatrix::Transpose3x3() fVals[6] = temp; } +//______________________________________________________________________________ +Double_t TGLMatrix::Invert() +{ + // Invert the matrix, returns determinant. + // Copied from TMatrixFCramerInv. + + Double_t* M = fVals; + + const Double_t det2_12_01 = M[1]*M[6] - M[5]*M[2]; + const Double_t det2_12_02 = M[1]*M[10] - M[9]*M[2]; + const Double_t det2_12_03 = M[1]*M[14] - M[13]*M[2]; + const Double_t det2_12_13 = M[5]*M[14] - M[13]*M[6]; + const Double_t det2_12_23 = M[9]*M[14] - M[13]*M[10]; + const Double_t det2_12_12 = M[5]*M[10] - M[9]*M[6]; + const Double_t det2_13_01 = M[1]*M[7] - M[5]*M[3]; + const Double_t det2_13_02 = M[1]*M[11] - M[9]*M[3]; + const Double_t det2_13_03 = M[1]*M[15] - M[13]*M[3]; + const Double_t det2_13_12 = M[5]*M[11] - M[9]*M[7]; + const Double_t det2_13_13 = M[5]*M[15] - M[13]*M[7]; + const Double_t det2_13_23 = M[9]*M[15] - M[13]*M[11]; + const Double_t det2_23_01 = M[2]*M[7] - M[6]*M[3]; + const Double_t det2_23_02 = M[2]*M[11] - M[10]*M[3]; + const Double_t det2_23_03 = M[2]*M[15] - M[14]*M[3]; + const Double_t det2_23_12 = M[6]*M[11] - M[10]*M[7]; + const Double_t det2_23_13 = M[6]*M[15] - M[14]*M[7]; + const Double_t det2_23_23 = M[10]*M[15] - M[14]*M[11]; + + + const Double_t det3_012_012 = M[0]*det2_12_12 - M[4]*det2_12_02 + M[8]*det2_12_01; + const Double_t det3_012_013 = M[0]*det2_12_13 - M[4]*det2_12_03 + M[12]*det2_12_01; + const Double_t det3_012_023 = M[0]*det2_12_23 - M[8]*det2_12_03 + M[12]*det2_12_02; + const Double_t det3_012_123 = M[4]*det2_12_23 - M[8]*det2_12_13 + M[12]*det2_12_12; + const Double_t det3_013_012 = M[0]*det2_13_12 - M[4]*det2_13_02 + M[8]*det2_13_01; + const Double_t det3_013_013 = M[0]*det2_13_13 - M[4]*det2_13_03 + M[12]*det2_13_01; + const Double_t det3_013_023 = M[0]*det2_13_23 - M[8]*det2_13_03 + M[12]*det2_13_02; + const Double_t det3_013_123 = M[4]*det2_13_23 - M[8]*det2_13_13 + M[12]*det2_13_12; + const Double_t det3_023_012 = M[0]*det2_23_12 - M[4]*det2_23_02 + M[8]*det2_23_01; + const Double_t det3_023_013 = M[0]*det2_23_13 - M[4]*det2_23_03 + M[12]*det2_23_01; + const Double_t det3_023_023 = M[0]*det2_23_23 - M[8]*det2_23_03 + M[12]*det2_23_02; + const Double_t det3_023_123 = M[4]*det2_23_23 - M[8]*det2_23_13 + M[12]*det2_23_12; + const Double_t det3_123_012 = M[1]*det2_23_12 - M[5]*det2_23_02 + M[9]*det2_23_01; + const Double_t det3_123_013 = M[1]*det2_23_13 - M[5]*det2_23_03 + M[13]*det2_23_01; + const Double_t det3_123_023 = M[1]*det2_23_23 - M[9]*det2_23_03 + M[13]*det2_23_02; + const Double_t det3_123_123 = M[5]*det2_23_23 - M[9]*det2_23_13 + M[13]*det2_23_12; + + const Double_t det = M[0]*det3_123_123 - M[4]*det3_123_023 + + M[8]*det3_123_013 - M[12]*det3_123_012; + + if(det == 0) { + Warning("TGLMatrix::Invert", "matrix is singular."); + return 0; + } + + const Double_t oneOverDet = 1.0/det; + const Double_t mn1OverDet = - oneOverDet; + + M[0] = det3_123_123 * oneOverDet; + M[4] = det3_023_123 * mn1OverDet; + M[8] = det3_013_123 * oneOverDet; + M[12] = det3_012_123 * mn1OverDet; + + M[1] = det3_123_023 * mn1OverDet; + M[5] = det3_023_023 * oneOverDet; + M[9] = det3_013_023 * mn1OverDet; + M[13] = det3_012_023 * oneOverDet; + + M[2] = det3_123_013 * oneOverDet; + M[6] = det3_023_013 * mn1OverDet; + M[10] = det3_013_013 * oneOverDet; + M[14] = det3_012_013 * mn1OverDet; + + M[3] = det3_123_012 * mn1OverDet; + M[7] = det3_023_012 * oneOverDet; + M[11] = det3_013_012 * mn1OverDet; + M[15] = det3_012_012 * oneOverDet; + + return det; +} + +//______________________________________________________________________________ +void TGLMatrix::MultiplyIP(TGLVector3& v, Double_t w) const +{ + // Multiply vector in-place. + const Double_t* M = fVals; + Double_t r[3] = { v[0], v[1], v[2] }; + v.X() = M[0]*r[0] + M[4]*r[1] + M[8]*r[2] + M[12]*w; + v.Y() = M[1]*r[0] + M[5]*r[1] + M[9]*r[2] + M[13]*w; + v.Z() = M[2]*r[0] + M[6]*r[1] + M[10]*r[2] + M[14]*w; +} + +//______________________________________________________________________________ +void TGLMatrix::RotateIP(TGLVector3& v) const +{ + // Rotate vector in-place. Translation is not applied. + const Double_t* M = fVals; + Double_t r[3] = { v[0], v[1], v[2] }; + v.X() = M[0]*r[0] + M[4]*r[1] + M[8]*r[2]; + v.Y() = M[1]*r[0] + M[5]*r[1] + M[9]*r[2]; + v.Z() = M[2]*r[0] + M[6]*r[1] + M[10]*r[2]; +} + //______________________________________________________________________________ TGLVector3 TGLMatrix::GetScale() const { @@ -824,7 +971,8 @@ void TGLMatrix::Dump() const ClassImp(TGLUtil) -UInt_t TGLUtil::fgDrawQuality = 60; +UInt_t TGLUtil::fgDefaultDrawQuality = 60; +UInt_t TGLUtil::fgDrawQuality = fgDefaultDrawQuality; //______________________________________________________________________________ void TGLUtil::CheckError(const char * loc) diff --git a/gl/src/TGLViewer.cxx b/gl/src/TGLViewer.cxx index 28b4c23d5ce..9e8fab0452f 100644 --- a/gl/src/TGLViewer.cxx +++ b/gl/src/TGLViewer.cxx @@ -82,12 +82,12 @@ TGLViewer::TGLViewer(TVirtualPad * pad, Int_t x, Int_t y, Int_t width, Int_t height) : fPad(pad), fContextMenu(0), - fPerspectiveCameraXOZ(TGLVector3(1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)), // XOZ floor - fPerspectiveCameraYOZ(TGLVector3(0.0, 1.0, 0.0), TGLVector3(1.0, 0.0, 0.0)), // YOZ floor - fPerspectiveCameraXOY(TGLVector3(1.0, 0.0, 0.0), TGLVector3(0.0, 0.0,-1.0)), // XOY floor - fOrthoXOYCamera(TGLOrthoCamera::kXOY), - fOrthoXOZCamera(TGLOrthoCamera::kXOZ), - fOrthoZOYCamera(TGLOrthoCamera::kZOY), + fPerspectiveCameraXOZ(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)), // XOZ floor + fPerspectiveCameraYOZ(TGLVector3( 0.0,-1.0, 0.0), TGLVector3(1.0, 0.0, 0.0)), // YOZ floor + fPerspectiveCameraXOY(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 0.0, 1.0)), // XOY floor + fOrthoXOYCamera(TGLVector3( 0.0, 0.0, 1.0), TGLVector3(0.0, 1.0, 0.0)), // Looking down Z axis, X horz, Y vert + fOrthoXOZCamera(TGLVector3( 0.0,-1.0, 0.0), TGLVector3(0.0, 0.0, 1.0)), // Looking down Y axis, X horz, Z vert + fOrthoZOYCamera(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)), // Looking down X axis, Z horz, Y vert fCurrentCamera(&fPerspectiveCameraXOZ), fLightSet (0), @@ -95,12 +95,15 @@ TGLViewer::TGLViewer(TVirtualPad * pad, Int_t x, Int_t y, fSelectedPShapeRef (0), fCurrentOvlElm (0), - fAction(kDragNone), fLastPos(0,0), fActiveButtonID(0), + fPushAction(kPushStd), fAction(kDragNone), fLastPos(0,0), fActiveButtonID(0), fRedrawTimer(0), fClearColor(1), fAxesType(TGLUtil::kAxesNone), + fAxesDepthTest(kTRUE), fReferenceOn(kFALSE), fReferencePos(0.0, 0.0, 0.0), + fDrawCameraCenter(kFALSE), + fCameraMarkup(0), fInitGL(kFALSE), fSmartRefresh(kFALSE), fDebugMode(kFALSE), @@ -127,12 +130,12 @@ TGLViewer::TGLViewer(TVirtualPad * pad, Int_t x, Int_t y, TGLViewer::TGLViewer(TVirtualPad * pad) : fPad(pad), fContextMenu(0), - fPerspectiveCameraXOZ(TGLVector3(1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)), // XOZ floor - fPerspectiveCameraYOZ(TGLVector3(0.0, 1.0, 0.0), TGLVector3(1.0, 0.0, 0.0)), // YOZ floor - fPerspectiveCameraXOY(TGLVector3(1.0, 0.0, 0.0), TGLVector3(0.0, 0.0,-1.0)), // XOY floor - fOrthoXOYCamera(TGLOrthoCamera::kXOY), - fOrthoXOZCamera(TGLOrthoCamera::kXOZ), - fOrthoZOYCamera(TGLOrthoCamera::kZOY), + fPerspectiveCameraXOZ(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)), // XOZ floor + fPerspectiveCameraYOZ(TGLVector3( 0.0,-1.0, 0.0), TGLVector3(1.0, 0.0, 0.0)), // YOZ floor + fPerspectiveCameraXOY(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 0.0, 1.0)), // XOY floor + fOrthoXOYCamera(TGLVector3( 0.0, 0.0, 1.0), TGLVector3(0.0, 1.0, 0.0)), // Looking down Z axis, X horz, Y vert + fOrthoXOZCamera(TGLVector3( 0.0,-1.0, 0.0), TGLVector3(0.0, 0.0, 1.0)), // Looking down Y axis, X horz, Z vert + fOrthoZOYCamera(TGLVector3(-1.0, 0.0, 0.0), TGLVector3(0.0, 1.0, 0.0)), // Looking down X axis, Z horz, Y vert fCurrentCamera(&fPerspectiveCameraXOZ), fLightSet (0), @@ -140,12 +143,15 @@ TGLViewer::TGLViewer(TVirtualPad * pad) : fSelectedPShapeRef (0), fCurrentOvlElm (0), - fAction(kDragNone), fLastPos(0,0), fActiveButtonID(0), + fPushAction(kPushStd), fAction(kDragNone), fLastPos(0,0), fActiveButtonID(0), fRedrawTimer(0), fClearColor(1), fAxesType(TGLUtil::kAxesNone), + fAxesDepthTest(kTRUE), fReferenceOn(kFALSE), fReferencePos(0.0, 0.0, 0.0), + fDrawCameraCenter(kFALSE), + fCameraMarkup(0), fInitGL(kFALSE), fSmartRefresh(kFALSE), fDebugMode(kFALSE), @@ -309,6 +315,7 @@ void TGLViewer::PostSceneBuildSetup(Bool_t resetCameras) // Set default reference to center fReferencePos.Set(fOverallBoundingBox.Center()); + RefreshPadEditor(this); } @@ -474,17 +481,34 @@ void TGLViewer::DrawGuides() { // Draw reference marker and coordinate axes. - glDisable(GL_DEPTH_TEST); - + Bool_t disabled = kFALSE; if (fReferenceOn) + { + glDisable(GL_DEPTH_TEST); TGLUtil::DrawReferenceMarker(*fCamera, fReferencePos); - - if (fAxesType != TGLUtil::kAxesOrigin) + disabled = kTRUE; + } + if (fDrawCameraCenter) + { + glDisable(GL_DEPTH_TEST); + Float_t radius = fCamera->ViewportDeltaToWorld(TGLVertex3(fCamera->GetCenterVec()), 3, 3).Mag(); + const Float_t rgba[4] = { 0, 1, 1, 1.0 }; + TGLUtil::DrawSphere(fCamera->GetCenterVec(), radius, rgba); + disabled = kTRUE; + } + if(fAxesDepthTest && disabled) + { glEnable(GL_DEPTH_TEST); - + disabled = kFALSE; + } + else if (fAxesDepthTest == kFALSE && disabled == kFALSE) + { + glDisable(GL_DEPTH_TEST); + disabled = kTRUE; + } TGLUtil::DrawSimpleAxes(*fCamera, fOverallBoundingBox, fAxesType); - - glEnable(GL_DEPTH_TEST); + if(disabled) + glEnable(GL_DEPTH_TEST); } //______________________________________________________________________________ @@ -932,8 +956,9 @@ void TGLViewer::SetCurrentCamera(ECameraType cameraType) //______________________________________________________________________________ void TGLViewer::SetOrthoCamera(ECameraType camera, - Double_t left, Double_t right, - Double_t top, Double_t bottom) + Double_t zoom, Double_t dolly, + Double_t center[3], + Double_t hRotate, Double_t vRotate) { // Set an orthographic camera to supplied configuration - note this // does not need to be the current camera - though you will not see @@ -951,21 +976,21 @@ void TGLViewer::SetOrthoCamera(ECameraType camera, // TODO: Move these into a vector! switch(camera) { case(kCameraOrthoXOY): { - fOrthoXOYCamera.Configure(left, right, top, bottom); + fOrthoXOYCamera.Configure(zoom, dolly, center, hRotate, vRotate); if (fCurrentCamera == &fOrthoXOYCamera) { RequestDraw(TGLRnrCtx::kLODHigh); } break; } case(kCameraOrthoXOZ): { - fOrthoXOZCamera.Configure(left, right, top, bottom); + fOrthoXOZCamera.Configure(zoom, dolly, center, hRotate, vRotate); if (fCurrentCamera == &fOrthoXOZCamera) { RequestDraw(TGLRnrCtx::kLODHigh); } break; } case(kCameraOrthoZOY): { - fOrthoZOYCamera.Configure(left, right, top, bottom); + fOrthoZOYCamera.Configure(zoom, dolly, center, hRotate, vRotate); if (fCurrentCamera == &fOrthoZOYCamera) { RequestDraw(TGLRnrCtx::kLODHigh); } @@ -1032,11 +1057,13 @@ void TGLViewer::SetPerspectiveCamera(ECameraType camera, /**************************************************************************/ //______________________________________________________________________________ -void TGLViewer::GetGuideState(Int_t & axesType, Bool_t & referenceOn, Double_t referencePos[3]) const +void TGLViewer::GetGuideState(Int_t & axesType, Bool_t & axesDepthTest, Bool_t & referenceOn, Double_t referencePos[3]) const { - // Fetch the state of guides (axes & reference markers) into arguments. + // Fetch the state of guides (axes & reference markers) into arguments + + axesType = fAxesType; + axesDepthTest = fAxesDepthTest; - axesType = fAxesType; referenceOn = fReferenceOn; referencePos[0] = fReferencePos.X(); referencePos[1] = fReferencePos.Y(); @@ -1044,11 +1071,12 @@ void TGLViewer::GetGuideState(Int_t & axesType, Bool_t & referenceOn, Double_t r } //______________________________________________________________________________ -void TGLViewer::SetGuideState(Int_t axesType, Bool_t referenceOn, const Double_t referencePos[3]) +void TGLViewer::SetGuideState(Int_t axesType, Bool_t axesDepthTest, Bool_t referenceOn, const Double_t referencePos[3]) { // Set the state of guides (axes & reference markers) from arguments. fAxesType = axesType; + fAxesDepthTest = axesDepthTest; fReferenceOn = referenceOn; fReferencePos.Set(referencePos[0], referencePos[1], referencePos[2]); if (fGLDevice != -1) @@ -1056,6 +1084,14 @@ void TGLViewer::SetGuideState(Int_t axesType, Bool_t referenceOn, const Double_t RequestDraw(); } +//______________________________________________________________________________ +void TGLViewer::SetDrawCameraCenter(Bool_t x) +{ + // Draw camera look at and rotation point. + + fDrawCameraCenter = x; + RequestDraw(); +} // Selected physical //______________________________________________________________________________ @@ -1085,10 +1121,8 @@ void TGLViewer::OverlayDragFinished() Emit("OverlayDragFinished()"); } - /**************************************************************************/ /**************************************************************************/ - //______________________________________________________________________________ Int_t TGLViewer::DistancetoPrimitive(Int_t /*px*/, Int_t /*py*/) { @@ -1269,6 +1303,23 @@ Bool_t TGLViewer::HandleButton(Event_t * event) if (fAction != kNone) return kFALSE; + if (fPushAction == kPushCamCenter) + { + fPushAction = kPushStd; + RequestSelect(event->fX, event->fY); + if (fSelRec.GetN() > 0) + { + TGLVector3 v(event->fX, event->fY, 0.5*fSelRec.GetMinZ()); + fCurrentCamera->WindowToViewport(v); + v = fCurrentCamera->ViewportToWorld(v); + fCurrentCamera->SetExternalCenter(kTRUE); + fCurrentCamera->SetCenterVec(v.X(), v.Y(), v.Z()); + RequestDraw(); + } + RefreshPadEditor(this); + return kTRUE; + } + Bool_t grabPointer = kFALSE; Bool_t handled = kFALSE; @@ -1295,6 +1346,7 @@ Bool_t TGLViewer::HandleButton(Event_t * event) if (event->fState & kKeyShiftMask) { if (RequestSelect(event->fX, event->fY)) { ApplySelection(); + handled = kTRUE; } else { SelectionChanged(); // Just notify clients. } @@ -1304,8 +1356,10 @@ Bool_t TGLViewer::HandleButton(Event_t * event) TGLLogicalShape& lshape = const_cast<TGLLogicalShape&> (*fSecSelRec.GetPhysShape()->GetLogical()); lshape.ProcessSelection(*fRnrCtx, fSecSelRec); + handled = kTRUE; } - } else { + } + if ( ! handled) { fAction = kDragCameraRotate; grabPointer = kTRUE; } @@ -1558,8 +1612,10 @@ Bool_t TGLViewer::HandleMotion(Event_t * event) Short_t lod = TGLRnrCtx::kLODMed; // Camera interface requires GL coords - Y inverted - Int_t xDelta = event->fX - fLastPos.fX; - Int_t yDelta = event->fY - fLastPos.fY; + Int_t xDelta = event->fX - fLastPos.fX; + Int_t yDelta = event->fY - fLastPos.fY; + Bool_t mod1 = event->fState & kKeyControlMask; + Bool_t mod2 = event->fState & kKeyShiftMask; if (fAction == kDragNone) { @@ -1568,13 +1624,11 @@ Bool_t TGLViewer::HandleMotion(Event_t * event) processed = fCurrentOvlElm->Handle(*fRnrCtx, fOvlSelRec, event); lod = TGLRnrCtx::kLODHigh; } else if (fAction == kDragCameraRotate) { - processed = CurrentCamera().Rotate(xDelta, -yDelta); + processed = CurrentCamera().Rotate(xDelta, -yDelta, mod1, mod2); } else if (fAction == kDragCameraTruck) { - processed = CurrentCamera().Truck(event->fX, fViewport.Y() - event->fY, - xDelta, -yDelta); + processed = CurrentCamera().Truck(xDelta, -yDelta, mod1, mod2); } else if (fAction == kDragCameraDolly) { - processed = CurrentCamera().Dolly(xDelta, event->fState & kKeyControlMask, - event->fState & kKeyShiftMask); + processed = CurrentCamera().Dolly(xDelta, mod1, mod2); } else if (fAction == kDragOverlay) { processed = fCurrentOvlElm->Handle(*fRnrCtx, fOvlSelRec, event); } diff --git a/gl/src/TGLViewerEditor.cxx b/gl/src/TGLViewerEditor.cxx index 683298563df..da4e131af8b 100644 --- a/gl/src/TGLViewerEditor.cxx +++ b/gl/src/TGLViewerEditor.cxx @@ -37,10 +37,17 @@ TGLViewerEditor::TGLViewerEditor(const TGWindow *p, Int_t width, Int_t height, fResetCameraOnDoubleClick(0), fUpdateScene(0), fCameraHome(0), + fCameraCenterExt(0), + fCaptureCenter(0), + fCameraCenterX(0), + fCameraCenterY(0), + fCameraCenterZ(0), + fAxesType(0), fAxesContainer(0), fAxesNone(0), fAxesEdge(0), fAxesOrigin(0), + fAxesDepthTest(0), fRefContainer(0), fReferenceOn(0), fReferencePosX(0), @@ -78,12 +85,19 @@ void TGLViewerEditor::ConnectSignals2Slots() fResetCameraOnDoubleClick->Connect("Toggled(Bool_t)", "TGLViewerEditor", this, "DoResetCameraOnDoubleClick()"); fUpdateScene->Connect("Pressed()", "TGLViewerEditor", this, "DoUpdateScene()"); fCameraHome->Connect("Pressed()", "TGLViewerEditor", this, "DoCameraHome()"); + fCameraCenterExt->Connect("Clicked()", "TGLViewerEditor", this, "DoCameraCenterExt()"); + fCaptureCenter->Connect("Clicked()", "TGLViewerEditor", this, "DoCaptureCenter()"); + fDrawCameraCenter->Connect("Clicked()", "TGLViewerEditor", this, "DoDrawCameraCenter()"); + fCameraCenterX->Connect("ValueSet(Long_t)", "TGLViewerEditor", this, "UpdateCameraCenter()"); + fCameraCenterY->Connect("ValueSet(Long_t)", "TGLViewerEditor", this, "UpdateCameraCenter()"); + fCameraCenterZ->Connect("ValueSet(Long_t)", "TGLViewerEditor", this, "UpdateCameraCenter()"); - fAxesContainer->Connect("Clicked(Int_t)", "TGLViewerEditor", this, "UpdateViewerGuides()"); - fReferenceOn->Connect("Clicked()", "TGLViewerEditor", this, "UpdateViewerGuides()"); - fReferencePosX->Connect("ValueSet(Long_t)", "TGLViewerEditor", this, "UpdateViewerGuides()"); - fReferencePosY->Connect("ValueSet(Long_t)", "TGLViewerEditor", this, "UpdateViewerGuides()"); - fReferencePosZ->Connect("ValueSet(Long_t)", "TGLViewerEditor", this, "UpdateViewerGuides()"); + fAxesContainer->Connect("Clicked(Int_t)", "TGLViewerEditor", this, "UpdateViewerAxes(Int_t)"); + + fReferenceOn->Connect("Clicked()", "TGLViewerEditor", this, "UpdateViewerReference()"); + fReferencePosX->Connect("ValueSet(Long_t)", "TGLViewerEditor", this, "UpdateViewerReference()"); + fReferencePosY->Connect("ValueSet(Long_t)", "TGLViewerEditor", this, "UpdateViewerReference()"); + fReferencePosZ->Connect("ValueSet(Long_t)", "TGLViewerEditor", this, "UpdateViewerReference()"); fCamMode->Connect("Selected(Int_t)", "TGLViewerEditor", this, "DoCameraMarkup()"); fCamMarkupOn->Connect("Clicked()", "TGLViewerEditor", this, "DoCameraMarkup()"); @@ -119,10 +133,26 @@ void TGLViewerEditor::SetModel(TObject* obj) fLightSet->SetModel(fViewer->GetLightSet()); fClipSet->SetModel(fViewer->GetClipSet()); + // style tab fClearColor->SetColor(TColor::Number2Pixel(fViewer->GetClearColor()), kFALSE); fIgnoreSizesOnUpdate->SetState(fViewer->GetIgnoreSizesOnUpdate() ? kButtonDown : kButtonUp); fResetCamerasOnUpdate->SetState(fViewer->GetResetCamerasOnUpdate() ? kButtonDown : kButtonUp); fResetCameraOnDoubleClick->SetState(fViewer->GetResetCameraOnDoubleClick() ? kButtonDown : kButtonUp); + //camera look at + TGLCamera & cam = fViewer->CurrentCamera(); + fCameraCenterExt->SetDown(cam.GetExternalCenter()); + fDrawCameraCenter->SetDown(fViewer->GetDrawCameraCenter()); + Double_t* la = cam.GetCenterVec(); + fCameraCenterX->SetNumber(la[0]); + fCameraCenterY->SetNumber(la[1]); + fCameraCenterZ->SetNumber(la[2]); + fCameraCenterX->SetState(fCameraCenterExt->IsDown()); + fCameraCenterY->SetState(fCameraCenterExt->IsDown()); + fCameraCenterZ->SetState(fCameraCenterExt->IsDown()); + if (fViewer->GetPushAction() == TGLViewer::kPushCamCenter) + fCaptureCenter->SetTextColor(0xa03060); + else + fCaptureCenter->SetTextColor(0x000000); } //______________________________________________________________________________ @@ -191,42 +221,101 @@ void TGLViewerEditor::DoCameraMarkup() } //______________________________________________________________________________ -void TGLViewerEditor::UpdateViewerGuides() +void TGLViewerEditor::DoCameraCenterExt() +{ + // Set external camera center. + + TGLCamera& cam = fViewer->CurrentCamera(); + cam.SetExternalCenter(fCameraCenterExt->GetState()); + + fCameraCenterX->SetState(fCameraCenterExt->IsDown()); + fCameraCenterY->SetState(fCameraCenterExt->IsDown()); + fCameraCenterZ->SetState(fCameraCenterExt->IsDown()); + + ViewerRedraw(); +} + +//______________________________________________________________________________ +void TGLViewerEditor::DoCaptureCenter() +{ + // Capture camera-center via picking. + + fViewer->PickCameraCenter(); +} + +//______________________________________________________________________________ +void TGLViewerEditor::DoDrawCameraCenter() +{ + // Draw camera center. + + fViewer->SetDrawCameraCenter(fDrawCameraCenter->IsDown()); + ViewerRedraw(); +} + +//______________________________________________________________________________ +void TGLViewerEditor::UpdateCameraCenter() +{ + // Update current camera with GUI state. + + TGLCamera& cam = fViewer->CurrentCamera(); + cam.SetCenterVec(fCameraCenterX->GetNumber(), fCameraCenterY->GetNumber(), fCameraCenterZ->GetNumber()); + ViewerRedraw(); +} + +//______________________________________________________________________________ +void TGLViewerEditor::UpdateViewerAxes(Int_t id) { // Update viewer with GUI state. - Int_t axesType = TGLUtil::kAxesNone; - for (Int_t i = 1; i < 4; i++) { - TGButton * button = fAxesContainer->GetButton(i); - if (button && button->IsDown()) { - axesType = i-1; - break; + if(id < 4) + { + fAxesType = id -1; + for (Int_t i = 1; i < 4; i++) { + TGButton * button = fAxesContainer->GetButton(i); + if (i == id) + button->SetDown(kTRUE); + else + button->SetDown(kFALSE); } } + Bool_t axdt = fAxesContainer->GetButton(4)->IsDown(); + const Double_t refPos[] = {fReferencePosX->GetNumber(), fReferencePosY->GetNumber(), fReferencePosZ->GetNumber()}; + fViewer->SetGuideState(fAxesType, axdt, fReferenceOn->IsDown(), refPos); + UpdateReferencePosState(); +} + +//______________________________________________________________________________ +void TGLViewerEditor::UpdateViewerReference() +{ + // Update viewer with GUI state. const Double_t refPos[] = {fReferencePosX->GetNumber(), fReferencePosY->GetNumber(), fReferencePosZ->GetNumber()}; - fViewer->SetGuideState(axesType, fReferenceOn->IsDown(), refPos); - UpdateReferencePos(); + fViewer->SetGuideState(fAxesType, fAxesContainer->GetButton(4)->IsDown(), fReferenceOn->IsDown(), refPos); + UpdateReferencePosState(); } //______________________________________________________________________________ -void TGLViewerEditor::CreateStyleTab() +TGNumberEntry* TGLViewerEditor::MakeLabeledNEntry(TGCompositeFrame* p, const char* name, Int_t labelw,Int_t nd, Int_t style) { - // Creates "Style" tab. + // Helper function to create fixed width TGLabel and TGNumberEntry in same row. - // LightSet - fLightSet = new TGLLightSetSubEditor(this); - fLightSet->Connect("Changed", "TGLViewerEditor", this, "ViewerRedraw()"); - AddFrame(fLightSet, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 0, 0, 0)); + TGHorizontalFrame *rfr = new TGHorizontalFrame(p); + TGHorizontalFrame *labfr = new TGHorizontalFrame(rfr, labelw, 20, kFixedSize); + TGLabel* lab = new TGLabel(rfr,name); + labfr->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsBottom, 0, 0, 0) ); + rfr->AddFrame(labfr, new TGLayoutHints(kLHintsLeft | kLHintsBottom, 0, 0, 0)); - { - TGHorizontalFrame* hf = new TGHorizontalFrame(this); - TGLabel* lab = new TGLabel(hf, "Clear color"); - hf->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsBottom, 1, 12, 1, 3)); - fClearColor = new TGColorSelect(hf, 0, -1); - hf->AddFrame(fClearColor, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 1)); - AddFrame(hf, new TGLayoutHints(kLHintsLeft, 2, 1, 1, 1)); - } + TGNumberEntry* ne = new TGNumberEntry(rfr, 0.0f, nd, -1, (TGNumberFormat::EStyle)style); + rfr->AddFrame( ne, new TGLayoutHints(kLHintsLeft | kLHintsExpandX | kLHintsBottom, 2, 0, 0)); + + p->AddFrame(rfr, new TGLayoutHints(kLHintsLeft, 0, 0, 1, 0)); + return ne; +} + +//______________________________________________________________________________ +void TGLViewerEditor::CreateStyleTab() +{ + // Creates "Style" tab. MakeTitle("Update behaviour"); fIgnoreSizesOnUpdate = new TGCheckButton(this, "Ignore sizes"); @@ -238,10 +327,24 @@ void TGLViewerEditor::CreateStyleTab() fResetCameraOnDoubleClick = new TGCheckButton(this, "Reset on dbl-click"); fResetCameraOnDoubleClick->SetToolTipText("Reset cameras on double-click"); AddFrame(fResetCameraOnDoubleClick, new TGLayoutHints(kLHintsLeft, 4, 1, 1, 1)); - fUpdateScene = new TGTextButton(this, "Update Scene"); - AddFrame(fUpdateScene, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 4, 1, 1, 1)); - fCameraHome = new TGTextButton(this, "Camera Home"); - AddFrame(fCameraHome, new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 4, 1, 1, 1)); + + TGCompositeFrame* af = this; + fUpdateScene = new TGTextButton(af, "Update Scene", 130); + af->AddFrame(fUpdateScene, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 1, 1, 8, 1)); + fCameraHome = new TGTextButton(af, "Camera Home", 130); + af->AddFrame(fCameraHome, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 1, 1, 1, 1)); + + TGHorizontalFrame* hf = new TGHorizontalFrame(this); + TGLabel* lab = new TGLabel(hf, "Clear Color"); + hf->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsBottom, 1, 4, 8, 3)); + fClearColor = new TGColorSelect(hf, 0, -1); + hf->AddFrame(fClearColor, new TGLayoutHints(kLHintsLeft, 1, 1, 8, 1)); + AddFrame(hf, new TGLayoutHints(kLHintsLeft, 2, 1, 1, 1)); + + // LightSet + fLightSet = new TGLLightSetSubEditor(this); + fLightSet->Connect("Changed", "TGLViewerEditor", this, "ViewerRedraw()"); + AddFrame(fLightSet, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 0, 0, 0)); } //______________________________________________________________________________ @@ -250,45 +353,43 @@ void TGLViewerEditor::CreateGuidesTab() // Create "Guides" tab. fGuidesFrame = CreateEditorTabSubFrame("Guides"); - // axes - fAxesContainer = new TGButtonGroup(fGuidesFrame, "Axes"); - fAxesNone = new TGRadioButton(fAxesContainer, "None"); - fAxesEdge = new TGRadioButton(fAxesContainer, "Edge"); - fAxesOrigin = new TGRadioButton(fAxesContainer, "Origin"); - fGuidesFrame->AddFrame(fAxesContainer, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); - - //Reference container - fRefContainer = new TGGroupFrame(fGuidesFrame, "Reference Marker"); - fGuidesFrame->AddFrame(fRefContainer, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); - - //Reference options + // external camera look at point + TGGroupFrame* grf = new TGGroupFrame(fGuidesFrame, "Camera center:", kVerticalFrame); + fDrawCameraCenter = new TGCheckButton(grf, "Show", 50); + grf->AddFrame(fDrawCameraCenter, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 1, 1)); + fCameraCenterExt = new TGCheckButton(grf, "External", 50); + grf->AddFrame(fCameraCenterExt, new TGLayoutHints(kLHintsLeft, 0, 0, 1, 0)); + fGuidesFrame->AddFrame(grf, new TGLayoutHints(kLHintsTop| kLHintsLeft | kLHintsExpandX, 2, 3, 3, 0)); + Int_t labw = 20; + fCameraCenterX = MakeLabeledNEntry(grf, "X:", labw, 8, TGNumberFormat::kNESRealThree); + fCameraCenterY = MakeLabeledNEntry(grf, "Y:", labw, 8, TGNumberFormat::kNESRealThree); + fCameraCenterZ = MakeLabeledNEntry(grf, "Z:", labw, 8, TGNumberFormat::kNESRealThree); + fCaptureCenter = new TGTextButton(grf, " Pick center "); + grf->AddFrame(fCaptureCenter, new TGLayoutHints(kLHintsNormal, labw + 2, 0, 2, 0)); + + // reference container + fRefContainer = new TGGroupFrame(fGuidesFrame, "Reference marker"); + fGuidesFrame->AddFrame(fRefContainer, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 0, 0)); fReferenceOn = new TGCheckButton(fRefContainer, "Show"); - fRefContainer->AddFrame(fReferenceOn, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); - - TGLabel *label = new TGLabel(fRefContainer, "X"); - fRefContainer->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 3, 3)); - fReferencePosX = new TGNumberEntry(fRefContainer, 0.0, 8); - fRefContainer->AddFrame(fReferencePosX, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + fRefContainer->AddFrame(fReferenceOn, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX)); + fReferencePosX = MakeLabeledNEntry(fRefContainer, "X:", labw, 8, TGNumberFormat::kNESRealThree ); + fReferencePosY = MakeLabeledNEntry(fRefContainer, "Y:", labw, 8, TGNumberFormat::kNESRealThree ); + fReferencePosZ = MakeLabeledNEntry(fRefContainer, "Z:", labw, 8, TGNumberFormat::kNESRealThree ); - label = new TGLabel(fRefContainer, "Y"); - fRefContainer->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 3, 3)); - fReferencePosY = new TGNumberEntry(fRefContainer, 0.0, 8); - fRefContainer->AddFrame(fReferencePosY, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); - - label = new TGLabel(fRefContainer, "Z"); - fRefContainer->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 3, 3)); - fReferencePosZ = new TGNumberEntry(fRefContainer, 0.0, 8); - fRefContainer->AddFrame(fReferencePosZ, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); + // axes + fAxesContainer = new TGButtonGroup(fGuidesFrame, "Axes"); + fAxesNone = new TGRadioButton(fAxesContainer, "None", 1); + fAxesEdge = new TGRadioButton(fAxesContainer, "Edge", 2); + fAxesOrigin = new TGRadioButton(fAxesContainer, "Origin", 3); + fAxesDepthTest = new TGCheckButton(fAxesContainer, "DepthTest",4); + fGuidesFrame->AddFrame(fAxesContainer, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 0, 0)); // camera markup - fCamContainer = new TGGroupFrame(fGuidesFrame, "Camera Markup"); - fGuidesFrame->AddFrame(fCamContainer, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); - + fCamContainer = new TGGroupFrame(fGuidesFrame, "Camera markup"); + fGuidesFrame->AddFrame(fCamContainer, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 2, 3, 0, 0)); fCamMarkupOn = new TGCheckButton(fCamContainer, "Show"); fCamMarkupOn->SetToolTipText("Implemented for orthographic mode"); - - fCamContainer->AddFrame(fCamMarkupOn, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 3, 3, 3, 3)); - + fCamContainer->AddFrame(fCamMarkupOn, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX)); TGHorizontalFrame* chf = new TGHorizontalFrame(fCamContainer); TGLabel* lab = new TGLabel(chf, "Mode"); chf->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsBottom, 1, 4, 1, 2)); @@ -317,7 +418,7 @@ void TGLViewerEditor::CreateClippingTab() } //______________________________________________________________________________ -void TGLViewerEditor::UpdateReferencePos() +void TGLViewerEditor::UpdateReferencePosState() { // Enable/disable reference position (x/y/z) number edits based on // reference check box. @@ -330,22 +431,27 @@ void TGLViewerEditor::UpdateReferencePos() //______________________________________________________________________________ void TGLViewerEditor::SetGuides() { - // Set cintriks in "Guides" tab. + // Configuration of guides GUI called from SetModel(). - Int_t axesType = TGLUtil::kAxesNone; + Bool_t axesDepthTest = kFALSE; Bool_t referenceOn = kFALSE; Double_t referencePos[3] = {0.}; - fViewer->GetGuideState(axesType, referenceOn, referencePos); + fViewer->GetGuideState(fAxesType, axesDepthTest, referenceOn, referencePos); - // Button ids run from 1 - if (TGButton *btn = fAxesContainer->GetButton(axesType+1)) - btn->SetDown(); + for (Int_t i = 1; i < 4; i++) { + TGButton * btn = fAxesContainer->GetButton(i); + if (fAxesType+1 == i) + btn->SetDown(kTRUE); + else + btn->SetDown(kFALSE); + } + fAxesContainer->GetButton(4)->SetOn(axesDepthTest, kFALSE); fReferenceOn->SetDown(referenceOn); fReferencePosX->SetNumber(referencePos[0]); fReferencePosY->SetNumber(referencePos[1]); fReferencePosZ->SetNumber(referencePos[2]); - UpdateReferencePos(); + UpdateReferencePosState(); if (fViewer->CurrentCamera().IsA()->InheritsFrom("TGLOrthoCamera")) { fGuidesFrame->ShowFrame(fCamContainer); diff --git a/tutorials/gl/glViewerExercise.C b/tutorials/gl/glViewerExercise.C index 6edae7827af..3f2d43a5f8d 100644 --- a/tutorials/gl/glViewerExercise.C +++ b/tutorials/gl/glViewerExercise.C @@ -2,148 +2,121 @@ //Author: Richard maunder #include "TGLViewer.h" +#include "TGLPerspectiveCamera.h" #include "TTimer.h" #include "TRandom.h" #include "TVirtualPad.h" TGLViewer::ECameraType camera; -TTimer timer(50); +TTimer timer(25); TRandom randGen(0); -void AnimatePerspectiveCamera() +Int_t moveCount = 0; + +void AnimateCamera() { - static Double_t fov = 50.0; + // initialization + static Double_t fov = 30; + static Double_t zoom = 0.78; static Double_t dolly = 1500.0; static Double_t center[3] = {-164.0, -164.0, -180.0}; static Double_t hRotate = 0.0; static Double_t vRotate = 0.0; - - static Double_t fovStep = randGen.Rndm()*5.0 - 2.5; - static Double_t dollyStep = randGen.Rndm()*10.0 - 5.0; - static Double_t centerStep[3] = {randGen.Rndm()*20.0 - 10.0, - randGen.Rndm()*20.0 - 10.0, - randGen.Rndm()*20.0 - 10.0}; - static Double_t hRotateStep = randGen.Rndm()*10.0 - 5.0; - static Double_t vRotateStep = randGen.Rndm()*10.0 - 5.0; - - fov += fovStep; - dolly += dollyStep; + // steps + static Double_t fovStep = randGen.Rndm()*3.0 - 0.5; + static Double_t zoomStep = (20 - randGen.Rndm())/1000.; + static Double_t dollyStep = randGen.Rndm()*5.0 - 1.0; + static Double_t centerStep[3] = {randGen.Rndm()*4, randGen.Rndm()*4, randGen.Rndm()*4 }; + static Double_t hRotateStep = randGen.Rndm()*0.025; + static Double_t vRotateStep = randGen.Rndm()*0.05; + + // move center center[0] += centerStep[0]; center[1] += centerStep[1]; center[2] += centerStep[2]; + Double_t mag = TMath::Sqrt(center[0]*center[0] + center[1]*center[1] + center[2]*center[2]); + if(mag > 500) + { + centerStep[0] = -centerStep[0]; + centerStep[1] = -centerStep[1]; + centerStep[2] = -centerStep[2]; + } + + // rotate hRotate += hRotateStep; vRotate += vRotateStep; + if (vRotate >= TMath::TwoPi() || vRotate <= 0.0) + vRotateStep = -vRotateStep; - if (vRotate >= 90.0 || vRotate <= -90.0) - { - vRotateStep = -vRotateStep; - } - if (dolly >= 2000.0 || dolly <= 1000.0) { - dollyStep = -dollyStep; - } - if (fov > 170.0 || fov < 1.0) { - fovStep = - fovStep; - } - TGLViewer * v = (TGLViewer *)gPad->GetViewer3D(); + if (hRotate >= (TMath::PiOver2()- 0.02f)|| hRotate <= (0.07f -TMath::PiOver2())) + hRotateStep = -hRotateStep; - /* - void SetPerspectiveCamera(ECameraType camera, Double_t fov, Double_t dolly, - Double_t center[3], Double_t hRotate, Double_t vRotate);*/ - v->SetPerspectiveCamera(camera, fov, dolly, center, hRotate, vRotate); -} + // dolly + dolly += dollyStep; + if (dolly >= 2000.0 || dolly <= 1500.0) + dollyStep = -dollyStep; -void AnimateOrthographicCamera() -{ - static Double_t left = -100.0; - static Double_t right = 100.0; - static Double_t top = 100.0; - static Double_t bottom = -100.0; - - static Double_t leftStep = randGen.Rndm()*40.0 - 10.0; - static Double_t rightStep = randGen.Rndm()*20.0 - 10.0; - static Double_t topStep = randGen.Rndm()*40.0 - 10.0; - static Double_t bottomStep = randGen.Rndm()*20.0 -10.0; - - left += leftStep; - right += rightStep; - top += topStep; - bottom += bottomStep; - - if (left >= 0.0 || left <= -500.0) { - leftStep = -leftStep; - } - if (right >= 500.0 || right <= 0.0) { - rightStep = -rightStep; - } - if (top >= 500.0 || top <= 0.0) { - topStep = -topStep; - } - if (bottom >= 0.0 || bottom <= -500.0) { - bottomStep = -bottomStep; + // modify frustum + TGLViewer * v = (TGLViewer *)gPad->GetViewer3D(); + if(camera < 3) + { + fov += fovStep; + if (fov > 130.0 || fov < 5.0) + fovStep = - fovStep; } + else + { + zoom += zoomStep; + if (zoom > 4.0 || zoom < 0.25) + zoomStep = - zoomStep; } - TGLViewer * v = (TGLViewer *)gPad->GetViewer3D(); + // apply + if(camera < 3) + v->SetPerspectiveCamera(camera, fov, dollyStep, center, hRotateStep, vRotateStep); + else + v->SetOrthoCamera(camera, zoom, dollyStep, center, hRotateStep, vRotateStep); - /* - void SetOrthoCamera(ECameraType camera, Double_t left, Double_t right, Double_t top, Double_t bottom); */ - v->SetOrthoCamera(camera, left, right, top, bottom); + if (++moveCount % 10 == 0) + v->RefreshPadEditor(v); } void glViewerExercise() { gROOT->ProcessLine(".x nucleus.C"); TGLViewer * v = (TGLViewer *)gPad->GetViewer3D(); - - // Random draw style + + // Random draw style Int_t style = randGen.Integer(3); - switch (style) { + switch (style) + { case 0: v->SetStyle(TGLRnrCtx::kFill); break; case 1: v->SetStyle(TGLRnrCtx::kOutline); break; case 2: v->SetStyle(TGLRnrCtx::kWireFrame); break; - } - - // Clipping setup - something like this: - /* - Double_t planeEq[4] = { 0.5, 1.0, -1.0, 2.0 }; - v->SetClipState(TGLViewer::kClipPlane, planeEq); - v->SetCurrentClip(TGLViewer::kClipPlane, kTRUE); - */ - - // Guides - something like this: - /* - Double_t refPos[3] = { 50.0, 60.0, 100.0 }; - v->SetGuideState(TGLViewer::kAxesEdge, kTRUE, refPos); - */ + } // Lights - turn some off randomly TGLLightSet* ls = v->GetLightSet(); - if (randGen.Integer(2) == 0) { + if (randGen.Integer(2) == 0) ls->SetLight(TGLLightSet::kLightLeft, kFALSE); - } - if (randGen.Integer(2) == 0) { + if (randGen.Integer(2) == 0) ls->SetLight(TGLLightSet::kLightRight, kFALSE); - } - if (randGen.Integer(2) == 0) { + if (randGen.Integer(2) == 0) ls->SetLight(TGLLightSet::kLightTop, kFALSE); - } - if (randGen.Integer(2) == 0) { + if (randGen.Integer(2) == 0) ls->SetLight(TGLLightSet::kLightBottom, kFALSE); - } // Random camera type - /* - enum ECameraType { kCameraPerspXOZ, kCameraPerspYOZ, kCameraPerspXOY, - kCameraOrthoXOY, kCameraOrthoXOZ, kCameraOrthoZOY };*/ - Int_t cam = randGen.Integer(6); - camera = (TGLViewer::ECameraType)cam; + Int_t id = randGen.Integer(6); + camera = (TGLViewer::ECameraType)id; v->SetCurrentCamera(camera); + v->CurrentCamera().SetExternalCenter(kTRUE); + if (id > 2) { + TGLOrthoCamera& o = v->CurrentCamera(); + o.SetEnableRotate(kTRUE); + } // Now animate the camera - if (camera <3) { - timer.SetCommand("AnimatePerspectiveCamera()"); - } else { - timer.SetCommand("AnimateOrthographicCamera()"); - } + timer.SetCommand("AnimateCamera()"); timer.TurnOn(); } diff --git a/tutorials/gl/glViewerLOD.C b/tutorials/gl/glViewerLOD.C index dc534fb42de..b7e12e7304a 100644 --- a/tutorials/gl/glViewerLOD.C +++ b/tutorials/gl/glViewerLOD.C @@ -1,10 +1,10 @@ //To set the Level Of Details when rendering geometry shapes //Author: Richard Maunder - -void glViewerLOD(Int_t reqNodes = 1000, Bool_t randomDist = kTRUE, Bool_t reqSpheres = kTRUE, Bool_t reqTubes = kTRUE) + +void glViewerLOD(Int_t reqNodes = 1000, Bool_t randomDist = kTRUE, Bool_t reqSpheres = kTRUE, Bool_t reqTubes = kTRUE) { TGeoManager * geom = new TGeoManager("LODTest", "GL viewer LOD test"); - geom->SetNsegments(4); // Doesn't matter keep low + geom->SetNsegments(4); // Doesn't matter keep low TGeoMaterial *matEmptySpace = new TGeoMaterial("EmptySpace", 0, 0, 0); TGeoMaterial *matSolid = new TGeoMaterial("Solid" , .938, 1., 10000.); @@ -18,10 +18,10 @@ void glViewerLOD(Int_t reqNodes = 1000, Bool_t randomDist = kTRUE, Bool_t reqSph } else { worldRadius = pow(reqNodes,.3)*sizeBase; } - - TGeoVolume *top = geom->MakeBox("WORLD", medEmptySpace, worldRadius, worldRadius, worldRadius); + + TGeoVolume *top = geom->MakeBox("WORLD", medEmptySpace, worldRadius, worldRadius, worldRadius); geom->SetTopVolume(top); - + gRandom->SetSeed(); // Create random number of unique sphere shapes - up to 25% of total placed sphere requested @@ -36,13 +36,21 @@ void glViewerLOD(Int_t reqNodes = 1000, Bool_t randomDist = kTRUE, Bool_t reqSph sprintf(name, "Volume_%d", i); // Random volume shape - UInt_t type = gRandom->Integer((reqSpheres+reqTubes)*3); - if (!reqSpheres) type += 3; + Int_t type = -1; + if (reqSpheres && reqTubes) { + type = gRandom->Integer(2); + if (type == 1) + type += gRandom->Integer(3); + } + else if(reqSpheres) + type = 0; + else if(reqTubes) + type = 1 + gRandom->Integer(3); // Random dimensions Double_t rMin = gRandom->Rndm() * sizeBase; Double_t rMax = rMin + gRandom->Rndm() * sizeBase * 2.0; - Double_t dz = pow(gRandom->Rndm(),2.0) * sizeBase * 15.0; + Double_t dz = pow(gRandom->Rndm(),2.0) * sizeBase * 15.0; Double_t phi1 = gRandom->Rndm() * 90.0; Double_t phi2 = phi1 + gRandom->Rndm() * 270.0; @@ -51,32 +59,30 @@ void glViewerLOD(Int_t reqNodes = 1000, Bool_t randomDist = kTRUE, Bool_t reqSph if (color == kBlack) color += 1; switch (type) { - case 0: - case 1: - case 2: { + case (0): { // GL viewer only supports solid spheres (0. inner radius) - volumes[i] = geom->MakeSphere(name, medSolid, 0., rMax); + volumes[i] = geom->MakeSphere(name, medSolid, 0., rMax); printf("Volume %d : Color %d, Sphere, Radius %f\n", i, color, rMax); break; } - case 3: { - volumes[i] = geom->MakeTube(name, medSolid, rMin, rMax, dz); + case 1: { + volumes[i] = geom->MakeTube(name, medSolid, rMin, rMax, dz); printf("Volume %d : Color %d, Tube, Inner Radius %f, Outer Radius %f, Length %f\n", i, color, rMin, rMax, dz); break; } - case 4: { - volumes[i] = geom->MakeTubs(name, medSolid, rMin, rMax, dz, phi1, phi2); - printf("Volume %d : Color %d, Tube Seg, Inner Radius %f, Outer Radius %f, Length %f, Phi1 %f, Phi2 %f\n", + case 2: { + volumes[i] = geom->MakeTubs(name, medSolid, rMin, rMax, dz, phi1, phi2); + printf("Volume %d : Color %d, Tube Seg, Inner Radius %f, Outer Radius %f, Length %f, Phi1 %f, Phi2 %f\n", i, color, rMin, rMax, dz, phi1, phi2); break; } - case 5: { + case 3: { Double_t n1[3], n2[3]; - n1[0] = gRandom->Rndm()*.5; n1[1] = gRandom->Rndm()*.5; n1[2] = -1.0 + gRandom->Rndm()*.5; - n2[0] = gRandom->Rndm()*.5; n2[1] = gRandom->Rndm()*.5; n2[2] = 1.0 - gRandom->Rndm()*.5; + n1[0] = gRandom->Rndm()*.5; n1[1] = gRandom->Rndm()*.5; n1[2] = -1.0 + gRandom->Rndm()*.5; + n2[0] = gRandom->Rndm()*.5; n2[1] = gRandom->Rndm()*.5; n2[2] = 1.0 - gRandom->Rndm()*.5; - volumes[i] = geom->MakeCtub(name, medSolid, rMin, rMax, dz, phi1, phi2, n1[0], n1[1], n1[2], n2[0], n2[1], n2[2]); - printf("Volume %d : Color %d, Cut Tube, Inner Radius %f, Outer Radius %f, Length %f, Phi1 %f, Phi2 %f, n1 (%f,%f,%f), n2 (%f,%f,%f)\n", + volumes[i] = geom->MakeCtub(name, medSolid, rMin, rMax, dz, phi1, phi2, n1[0], n1[1], n1[2], n2[0], n2[1], n2[2]); + printf("Volume %d : Color %d, Cut Tube, Inner Radius %f, Outer Radius %f, Length %f, Phi1 %f, Phi2 %f, n1 (%f,%f,%f), n2 (%f,%f,%f)\n", i, color, rMin, rMax, dz, phi1, phi2, n1[0], n1[1], n1[2], n2[0], n2[1], n2[2]); break; } @@ -93,7 +99,7 @@ void glViewerLOD(Int_t reqNodes = 1000, Bool_t randomDist = kTRUE, Bool_t reqSph // Scatter reqSpheres placed sphere randomly in space Double_t x, y, z; for (i = 0; i < reqNodes; i++) { - // Pick random volume + // Pick random volume UInt_t useVolume = gRandom->Integer(volumeCount); TGeoTranslation * trans; -- GitLab