Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
FlatManipulator.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
34 
35 using namespace vl;
36 
38  mTranslationButton(MiddleButton), mZoomButton(RightButton),
39  mZoomSpeed(1.0f)
40  {
41  VL_DEBUG_SET_OBJECT_NAME()
42  }
43 
44 //-----------------------------------------------------------------------------
46 {
47  mCamera = camera;
48 }
49 //-----------------------------------------------------------------------------
51 {
52  if ( camera() == NULL )
53  return;
54 
55  // if already busy ignore the event, wadda heck!
56  if (mode() != NoMode)
57  return;
58 
59  //if the rodent is out of cage, kisses and bye-bye
60  int vx, vy;
61  if(mouseInViewport(x, y, vx, vy) == false)
62  return;
63  //store the rodent's position in the cage
64  mMouseStart = vec2(x,y);
65 
66  // enter new mode
67  if (btn == translationButton())
68  {//we need world pixel size only in translation mode
70  //now let's find the pixel size, assuming an orthographic projection
71  mPixelSize.x() = 2.0/camera()->projectionMatrix().e(0,0)/
72  camera()->viewport()->width();
73  mPixelSize.y() = 2.0/camera()->projectionMatrix().e(1,1)/
74  camera()->viewport()->height();
75  }
76  else
77  if (btn == zoomButton())
78  {
79  mMode = ZoomMode;
80  }
81 
82  VL_CHECK(openglContext()->framebuffer())
83 
84 }
85 //-----------------------------------------------------------------------------
87 {
88  if ( camera() == NULL )
89  return;
90 
91  // ignore the event if the manipulator is not in any mode
92  if (mode() == NoMode)
93  return;
94 
95  VL_CHECK(openglContext()->framebuffer())
96 
97  if (mode() == ZoomMode)
98  {
99  float scale = 1.0-(y - mMouseStart.y())*zoomSpeed()/100.0;
101  mat4::getScaling(scale, scale,1.0)*
102  camera()->viewMatrix());
103  mMouseStart = vec2(x,y);
104  }
105  else
106  if (mode() == TranslationMode)
107  {
108  vec2 shift = (vec2(x,y) - mMouseStart)*mPixelSize;
110  mat4::getTranslation(shift.x(), -shift.y(),0)*
111  camera()->viewMatrix());
112  mMouseStart = vec2(x,y);
113  }
114 
115  // update the view
116  openglContext()->update();
117 }
118 //-----------------------------------------------------------------------------
119 void FlatManipulator::mouseUpEvent(EMouseButton btn, int /*x*/, int /*y*/)
120 {
121  if ( camera() == NULL )
122  return;
123 
124  // if the manipulator is not doing anything ignore the event
125  if (mode() == NoMode)
126  return;
127 
128  // leave the mode
129  if (btn == translationButton() && mMode == TranslationMode)
130  mMode = NoMode;
131  else
132  if (btn == zoomButton() && mMode == ZoomMode)
133  mMode = NoMode;
134 }
135 //-----------------------------------------------------------------------------
137 {
138  if (enabled)
139  {
140  mMode = NoMode;
141  if ( openglContext() )
142  {
145  }
146  }
147 }
148 //-----------------------------------------------------------------------------
149 bool FlatManipulator::mouseInViewport(int mx, int my, int& vx, int& vy)
150 {
151  vx = mx - camera()->viewport()->x();
152  vy = openglContext()->height() - my - camera()->viewport()->y();
153 
154  //if outside camera's viewport, return false
155  if (vx<0 || vy<0 ||
156  vx >= camera()->viewport()->width() ||
157  vy >= camera()->viewport()->height())
158  {
159  return false;
160  }
161  return true;
162 }
163 //-----------------------------------------------------------------------------
164 vl::ref<vl::Geometry> makeScales(bool X, bool Y, bool Z, int numArmTicks, float mmStep, float mmTickSize)
165 {
166  vl::ref<vl::Geometry> scales = new vl::Geometry();
167  int numRulers = (X?1:0)+(Y?1:0)+(Z?1:0);
168  if(numRulers == 0) return scales;
169 
171  vl::ref<vl::ArrayFloat3> scalesPoints(new vl::ArrayFloat3());
172 
173  //the length of one arm of scales
174  const float mmArmLength = numArmTicks*mmStep;
175 
176  //calculate the number of points, having marks at every 10 mm
177  int numAxisPoints = ( 2*numArmTicks + 1)*2;
178 
179  //resize the array to accomodate a ruler
180  points->resize(numAxisPoints);
181  //room for up to three orthogonal rulers
182  scalesPoints->resize(numRulers*points->size());
183 
184  float xpos = mmStep;
185  int t;
186  //generate the X ruler
187  for(t = 0; t < numArmTicks; t++)
188  {
189  float height = mmTickSize;
190 
191  if((t+1)%10 == 0)//takes priority over '5'
192  height *= 2;
193  else
194  if((t+1)%5 == 0)
195  height *= 1.5;
196 
197  points->at(4*t) = vl::fvec3(-xpos, -height,0);
198  points->at(4*t+1) = vl::fvec3(-xpos, +height,0);
199  points->at(4*t+2) = vl::fvec3(xpos, -height,0);
200  points->at(4*t+3) = vl::fvec3(xpos, +height,0);
201 
202  xpos += mmStep;
203  }
204  //now add the axis line
205  points->at(4*t) = vl::fvec3(-mmArmLength, 0.0,0);
206  points->at(4*t+1) = vl::fvec3(mmArmLength, 0.0,0);
207 
208  int i=0;
209 
210  if(X)//transfer the X ruler into the main array
211  {
212  for(size_t p=0; p < points->size(); i++, p++)
213  {
214  scalesPoints->at(i) = points->at(p);
215  }
216  }
217  if(Y)//transfer the Y ruler into the main array
218  {
219  //rotate the generic ruler around Z axis to create the Y ruler
220  points->transform(vl::mat4::getRotation(90, 0, 0, 1));
221 
222  //copy the Y ruler into the scales array
223  for(size_t p=0; p < points->size(); i++, p++)
224  {
225  scalesPoints->at(i) = points->at(p);
226  }
227  }
228  if(Z)//transfer the Z ruler into the main array
229  {
230  //rotate the ruler based on the last rotation
231  vl::vec3 rotaxis = Y ? vl::vec3(1,0,0) : vl::vec3(0,1,0);
232  points->transform(vl::mat4::getRotation(90,rotaxis));
233 
234  //copy the Y ruler into the scales array
235  for(size_t p=0; p < points->size(); i++, p++)
236  {
237  scalesPoints->at(i) = points->at(p);
238  }
239  }
240  scales->setVertexArray(scalesPoints.get());
241  //every consecutive pair of points make a line
242  scales->drawCalls().push_back( new vl::DrawArrays( vl::PT_LINES, 0, numRulers*points->size() ) );
243  return scales;
244 }
int y() const
Definition: Viewport.hpp:67
bool mouseInViewport(int mx, int my, int &vx, int &vy)
const mat4 & viewMatrix() const
Returns the Camera&#39;s view matrix (inverse of the modeling matrix).
Definition: Camera.hpp:161
const T_Scalar & e(int i, int j) const
Definition: Matrix4.hpp:660
Vector3< float > fvec3
A 3 components vector with float precision.
Definition: Vector3.hpp:252
fvec2 vec2
Defined as: &#39;typedef fvec2 vec2&#39;. See also VL_PIPELINE_PRECISION.
Definition: Vector2.hpp:299
const T * get() const
Definition: Object.hpp:128
float zoomSpeed() const
Zoom speed multiplicative factor (default = 1).
virtual void mouseMoveEvent(int x, int y)
Event generated when the mouse moves.
void setVertexArray(ArrayAbstract *data)
Conventional vertex array.
Definition: Geometry.cpp:155
void resize(size_t dim)
Definition: Array.hpp:233
virtual void enableEvent(bool enabled)
Event generated whenever setEnabled() is called.
Camera * camera()
The camera through which the manipulator is used.
virtual void mouseUpEvent(EMouseButton, int x, int y)
Event generated when one of the mouse buttons is released.
void transform(const mat4 &m)
Transforms the vectors contained in the buffer.
Definition: Array.hpp:322
size_t size() const
Returns the number of elements of an array.
Definition: Array.hpp:235
The Geometry class is a Renderable that implements a polygonal mesh made of polygons, lines and points.
Definition: Geometry.hpp:66
Viewport * viewport()
The viewport bound to a camera.
Definition: Camera.hpp:141
void setCamera(Camera *camera)
The camera through which the manipulator is used.
Visualization Library main namespace.
int height() const
Definition: Viewport.hpp:71
int width() const
Definition: Viewport.hpp:69
virtual void setContinuousUpdate(bool continuous)
If the OpenGL context is a widget this function sets whether its area is continuously updated at each...
int height() const
Returns the height in pixels of an OpenGLContext.
FlatManipulator()
Constructor.
EMouseButton
int x() const
Definition: Viewport.hpp:65
#define NULL
Definition: OpenGLDefs.hpp:81
void setViewMatrix(const mat4 &mat)
Sets the Camera&#39;s view matrix (inverse of the modeling matrix).
Definition: Camera.hpp:157
static Matrix4 & getRotation(Matrix4 &out, float degrees, float x, float y, float z)
Definition: Matrix4.hpp:904
T_VectorType & at(size_t i)
Definition: Array.hpp:255
fvec3 vec3
Defined as: &#39;typedef fvec3 vec3&#39;. See also VL_PIPELINE_PRECISION.
Definition: Vector3.hpp:269
static Matrix4 & getTranslation(Matrix4 &out, const Vector3< float > &v)
Definition: Matrix4.hpp:548
virtual void mouseDownEvent(EMouseButton, int x, int y)
Event generated when one of the mouse buttons is pressed.
int zoomButton() const
Mouse button used to zoom.
static Matrix4 & getScaling(Matrix4 &out, const Vector3< float > &v)
Definition: Matrix4.hpp:584
const mat4 & projectionMatrix() const
The Camera&#39;s projection matrix.
Definition: Camera.hpp:175
vl::ref< vl::Geometry > makeScales(bool X=true, bool Y=true, bool Z=true, int numArmTicks=50, float mmStep=10, float mmTickSize=4, vl::fvec4 color=vl::fvec4(1, 1, 1, 1))
Makes an orthogonal cross-hair scales (reticle).
const T_Scalar & x() const
Definition: Vector2.hpp:132
OpenGLContext * openglContext()
Returns the OpenGLContext to which this UIEventListener is bound or NULL if no context is bound...
An array of vl::fvec3.
Definition: Array.hpp:414
EManipMode mode() const
Returns the current manipulator state.
Represents a virtual camera defining, among other things, the point of view from which scenes can be ...
Definition: Camera.hpp:50
virtual void setMouseVisible(bool)
If the OpenGL context is a widget this function sets whether the mouse is visible over it or not...
Wraps the OpenGL function glDrawArrays().
Definition: DrawArrays.hpp:57
const T_Scalar & y() const
Definition: Vector2.hpp:133
#define VL_CHECK(expr)
Definition: checks.hpp:73
int translationButton() const
Mouse button used to translate the view.
virtual void update()=0
If the OpenGLContext is a widget this function requests a redraw and generates an updateEvent()...
Collection< DrawCall > & drawCalls()
Returns the list of DrawCall objects bound to a Geometry.
Definition: Geometry.hpp:102