Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGLManip.cxx
Go to the documentation of this file.
1 // @(#)root/gl:$Id$
2 // Author: Richard Maunder 16/09/2005
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TGLManip.h"
13 #include "TGLUtil.h"
14 #include "TGLCamera.h"
15 #include "TGLPhysicalShape.h"
16 #include "TGLIncludes.h"
17 #include "TROOT.h"
18 
19 #include "TVirtualX.h"
20 
21 /** \class TGLManip
22 \ingroup opengl
23 Abstract base class for viewer manipulators, which allow direct in
24 viewer manipulation of a (TGlPhysicalShape) object - currently
25 translation, scaling and rotation along/round objects local axes.
26 See derived classes for these implementations.
27 
28 This class provides binding to the zero or one manipulated physical,
29 hit testing (selection) for manipulator sub component (widget), and
30 some common mouse action handling/tracking.
31 */
32 
33 ClassImp(TGLManip);
34 
35 ////////////////////////////////////////////////////////////////////////////////
36 /// Construct a manipulator object, bound to supplied viewer, and no
37 /// physical shape.
38 
39 TGLManip::TGLManip() :
40  fShape(0),
41  fSelectedWidget(0), fActive(kFALSE),
42  fFirstMouse(0, 0),
43  fLastMouse(0, 0)
44 {
45 }
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// Construct a manipulator object, bound to supplied physical shape.
49 
50 TGLManip::TGLManip(TGLPhysicalShape* shape) :
51  fShape(shape),
52  fSelectedWidget(0), fActive(kFALSE),
53  fFirstMouse(0, 0),
54  fLastMouse(0, 0)
55 {
56 }
57 
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Copy constructor.
60 
61 TGLManip::TGLManip(const TGLManip& gm) :
62  TVirtualGLManip(gm),
63  fShape(gm.fShape),
64  fSelectedWidget(gm.fSelectedWidget),
65  fActive(gm.fActive),
66  fFirstMouse(gm.fFirstMouse),
67  fLastMouse(gm.fLastMouse)
68 {
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 /// Assignment operator.
73 
74 TGLManip& TGLManip::operator=(const TGLManip& gm)
75 {
76  if(this!=&gm) {
77  TVirtualGLManip::operator=(gm);
78  fShape=gm.fShape;
79  fSelectedWidget=gm.fSelectedWidget;
80  fActive=gm.fActive;
81  fFirstMouse=gm.fFirstMouse;
82  fLastMouse=gm.fLastMouse;
83  }
84  return *this;
85 }
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// Destroy manipulator object.
89 
90 TGLManip::~TGLManip()
91 {
92 }
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 /// Returns color to be used for given widget.
96 
97 const UChar_t* TGLManip::ColorFor(UInt_t widget) const
98 {
99  if (widget == fSelectedWidget)
100  {
101  return TGLUtil::fgYellow;
102  }
103  else
104  {
105  switch (widget)
106  {
107  case 1: return TGLUtil::fgRed;
108  case 2: return TGLUtil::fgGreen;
109  case 3: return TGLUtil::fgBlue;
110  default: return TGLUtil::fgGrey;
111  }
112  }
113 }
114 
115 ////////////////////////////////////////////////////////////////////////////////
116 /// Handle a mouse button event - return kTRUE if processed, kFALSE otherwise
117 
118 Bool_t TGLManip::HandleButton(const Event_t& event, const TGLCamera& /*camera*/)
119 {
120  // Only interested in Left mouse button actions
121  if (event.fCode != kButton1) {
122  return kFALSE;
123  }
124 
125  // Mouse down on selected widget?
126  if (event.fType == kButtonPress && fSelectedWidget != 0) {
127  fFirstMouse.SetX(event.fX);
128  fFirstMouse.SetY(event.fY);
129  fLastMouse.SetX(event.fX);
130  fLastMouse.SetY(event.fY);
131  fActive = kTRUE;
132  return kTRUE;
133  } else if (event.fType == kButtonRelease && fActive) {
134  fActive = kFALSE;
135  return kTRUE;
136  } else {
137  return kFALSE;
138  }
139 }
140 
141 ////////////////////////////////////////////////////////////////////////////////
142 /// Handle a mouse button event - return kTRUE if widget selection change
143 /// kFALSE otherwise
144 
145 Bool_t TGLManip::HandleMotion(const Event_t& /*event*/,
146  const TGLCamera& /*camera*/)
147 {
148  return kFALSE;
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// Calculates base and axis scale factor (in world units) for
153 /// drawing manipulators with reasonable size range in current
154 /// camera.
155 
156 void TGLManip::CalcDrawScale(const TGLBoundingBox& box,
157  const TGLCamera& camera,
158  Double_t& base,
159  TGLVector3 axis[3]) const
160 {
161  // Calculate a base scale
162  base = box.Extents().Mag() / 100.0;
163 
164  // Clamp this base scale to a viewport pixel range
165  // Allow some variation so zooming is noticeable
166  TGLVector3 pixelInWorld = camera.ViewportDeltaToWorld(box.Center(), 1, 1);
167  Double_t pixelScale = pixelInWorld.Mag();
168  if (base < pixelScale * 3.0) {
169  base = pixelScale * 3.0;
170  } else if (base > pixelScale * 6.0) {
171  base = pixelScale * 6.0;
172  }
173 
174  // Calculate some axis scales
175  for (UInt_t i = 0; i<3; i++) {
176  if (box.IsEmpty()) {
177  axis[i] = box.Axis(i, kTRUE)*base*-10.0;
178  } else {
179  axis[i] = box.Axis(i, kFALSE)*-0.51;
180  if (axis[i].Mag() < base*10.0) {
181  axis[i] = box.Axis(i, kTRUE)*base*-10.0;
182  }
183  }
184  }
185 }