TGLScaleManip.cxx

Go to the documentation of this file.
00001 // @(#)root/gl:$Id: TGLScaleManip.cxx 34006 2010-06-21 10:36:05Z matevz $
00002 // Author:  Richard Maunder  16/09/2005
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "TGLScaleManip.h"
00013 #include "TGLPhysicalShape.h"
00014 #include "TGLCamera.h"
00015 #include "TGLIncludes.h"
00016 
00017 //////////////////////////////////////////////////////////////////////////
00018 //                                                                      //
00019 // TGLScaleManip                                                        //
00020 //                                                                      //
00021 // Scale manipulator - attaches to physical shape and draws local axes  //
00022 // widgets with box heads. User can mouse over (turns yellow) and L     //
00023 // click/drag to scale along this axis.                                 //
00024 // Widgets use standard 3D package axes colours: X red, Y green, Z blue.//
00025 //////////////////////////////////////////////////////////////////////////
00026 
00027 ClassImp(TGLScaleManip)
00028 
00029 //______________________________________________________________________________
00030 TGLScaleManip::TGLScaleManip()
00031 {
00032    // Construct scale manipulator not bound to any physical shape.
00033 }
00034 
00035 //______________________________________________________________________________
00036 TGLScaleManip::TGLScaleManip(TGLPhysicalShape * shape) :
00037    TGLManip(shape)
00038 {
00039    // Construct scale manipulator bound to TGLPhysicalShape 'shape'.
00040 }
00041 
00042 //______________________________________________________________________________
00043 TGLScaleManip::~TGLScaleManip()
00044 {
00045    // Destory the scale manipulator
00046 }
00047 
00048 //______________________________________________________________________________
00049 void TGLScaleManip::Draw(const TGLCamera & camera) const
00050 {
00051    // Draw scale manipulator - tubes with box heads, in local axes of
00052    // attached shape, in red(X), green(Y) and blue(Z), with white center sphere.
00053    // If selected widget (mouse over) this is drawn in active colour (yellow).
00054 
00055    if (!fShape) {
00056       return;
00057    }
00058 
00059    // Get draw scales
00060    const TGLBoundingBox & box = fShape->BoundingBox();
00061    Double_t baseScale;
00062    TGLVector3 axisScale[3];
00063    CalcDrawScale(box, camera, baseScale, axisScale);
00064 
00065    // Get permitted manipulations on shape
00066    TGLPhysicalShape::EManip manip = fShape->GetManip();
00067 
00068    glEnable(GL_BLEND);
00069    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00070    glDisable(GL_CULL_FACE);
00071 
00072    // Draw three axis widgets out of bounding box where permitted
00073    // Not drawing will prevent interaction
00074    // GL name loading for hit testing - 0 reserved for no selection
00075    if (manip & TGLPhysicalShape::kScaleX) {
00076       glPushName(1);
00077       TGLUtil::DrawLine(box.Center(), axisScale[0], TGLUtil::kLineHeadBox,
00078                         baseScale, ColorFor(1));
00079       glPopName();
00080    } else {
00081       TGLUtil::DrawLine(box.Center(), axisScale[0], TGLUtil::kLineHeadBox,
00082                         baseScale, TGLUtil::fgGrey);
00083    }
00084    if (manip & TGLPhysicalShape::kScaleY) {
00085       glPushName(2);
00086       TGLUtil::DrawLine(box.Center(), axisScale[1], TGLUtil::kLineHeadBox,
00087                         baseScale, ColorFor(2));
00088       glPopName();
00089    } else {
00090       TGLUtil::DrawLine(box.Center(), axisScale[1], TGLUtil::kLineHeadBox,
00091                         baseScale, TGLUtil::fgGrey);
00092    }
00093    if (manip & TGLPhysicalShape::kScaleZ) {
00094       glPushName(3);
00095       TGLUtil::DrawLine(box.Center(), axisScale[2], TGLUtil::kLineHeadBox,
00096                         baseScale, ColorFor(3));
00097       glPopName();
00098    } else {
00099       TGLUtil::DrawLine(box.Center(), axisScale[2], TGLUtil::kLineHeadBox,
00100                         baseScale, TGLUtil::fgGrey);
00101    }
00102    // Draw white center sphere
00103    TGLUtil::DrawSphere(box.Center(), baseScale/2.0, TGLUtil::fgWhite);
00104 
00105    glEnable(GL_CULL_FACE);
00106    glDisable(GL_BLEND);
00107 }
00108 
00109 //______________________________________________________________________________
00110 Bool_t TGLScaleManip::HandleButton(const Event_t   & event,
00111                                    const TGLCamera & camera)
00112 {
00113    // Handle mouse button event over manipulator - returns kTRUE if
00114    // redraw required kFALSE otherwise.
00115 
00116    if (event.fType == kButtonPress && fSelectedWidget != 0) {
00117       fStartScale = fShape->GetScale();
00118    }
00119 
00120    return TGLManip::HandleButton(event, camera);
00121 }
00122 
00123 //______________________________________________________________________________
00124 Bool_t TGLScaleManip::HandleMotion(const Event_t & event,
00125                                    const TGLCamera & camera)
00126 {
00127    // Handle mouse motion over manipulator - if active (selected
00128    // widget) scale physical along selected widget (axis) of the
00129    // manipulator, so it tracks mouse action. Returns kTRUE if redraw
00130    // required kFALSE otherwise.
00131 
00132    if (fActive) {
00133       // Find mouse delta projected into world at attached object center
00134       TGLVector3 shift = camera.ViewportDeltaToWorld(fShape->BoundingBox().Center(),
00135                                                      event.fX - fFirstMouse.GetX(),
00136                                                      -event.fY + fFirstMouse.GetY()); // Y inverted
00137 
00138       UInt_t axisIndex = fSelectedWidget - 1; // Ugg sort out axis / widget id mapping
00139       TGLVector3 widgetAxis = fShape->BoundingBox().Axis(axisIndex, kTRUE);
00140 
00141       // Scale by projected screen factor
00142       TGLVector3 screenScale = camera.ViewportDeltaToWorld(fShape->BoundingBox().Center(), 500, 500);
00143       Double_t factor = -5.0*Dot(shift, widgetAxis) / screenScale.Mag();
00144 
00145       TGLVector3 newScale = fStartScale;
00146       newScale[axisIndex] += factor;
00147       LimitScale(newScale[axisIndex]);
00148       fShape->Scale(newScale);
00149 
00150       fLastMouse.SetX(event.fX);
00151       fLastMouse.SetY(event.fY);
00152 
00153       return kTRUE;
00154    }
00155    return kFALSE;
00156 }
00157 
00158 //______________________________________________________________________________
00159 void TGLScaleManip::LimitScale(Double_t & factor) const
00160 {
00161    // Clamp scale to sizable values: 1000 - 1/1000
00162    // Guards against div by zero problems.
00163    if (factor < 1e-4) {
00164       factor = 1e-4;
00165    }
00166    if (factor > 1e+4) {
00167       factor = 1e+4;
00168    }
00169 }

Generated on Tue Jul 5 14:18:08 2011 for ROOT_528-00b_version by  doxygen 1.5.1