Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TrackballControl.cpp
1 #include "TrackballControl.hh"
2 
3 #include <Base/Math/Vector3.hh>
4 #include <Gui/biasgl.h>
5 
6 using namespace BIAS;
7 using namespace BIAS;
8 using namespace std;
9 
10 
13 {
14  PointOfInterest_ = Vector3<double>(0.0,0.0,0.0);
15  controlledObject_=NULL;
16  Stepsize_ = 0.2;
17  UseLeftDouble_ = true;
18 }
19 
21 RightMouseMoved(int , int , int y1, int y2) {
22 
23  // Zoom out
24  if (y1 - y2 > 0)
25  {
26  MoveInViewingDirection(-Stepsize_);
27  }
28  // Zoom in
29  else if(y1 - y2 < 0)
30  {
31  MoveInViewingDirection(Stepsize_);
32  }
33  else
34  {
35  return false;
36  }
37  return true;
38 }
39 
40 
42 MouseWheelUsed(double stepsize)
43 {
44  MoveInViewingDirection(stepsize);
45  return true;
46 }
47 
49 MoveInViewingDirection(double stepsize)
50 {
52  Vector3<double> C(0,0,0);
53  controlledObject_->GetExtrinsics(C,R);
54  Vector3<double> direction;
55  double distance;
56 
57  // Compute new position of camera.
58  PointOfInterest_.Sub(C, direction);
59  distance = direction.NormL2();
60  if (Equal(distance, 0.0)){
61  distance = 1.0;
62  direction = Vector3<double>(0., 0., 1.0);
63  } else {
64  direction.Normalize();
65  }
66  double nearClippingPlane = 0;
67  nearClippingPlane = controlledObject_->GetNearClippingPlane();
68  if(distance > (nearClippingPlane+stepsize) ) {
69  direction.Multiply(stepsize, direction);
70  } else {
71  direction.Multiply(nearClippingPlane-distance, direction);
72  }
73  C.Add(direction, C);
74 
75  controlledObject_->SetExtrinsics(HomgPoint3D(C),R);
76 }
77 
79 RotateAroundPOI(BIAS::Vector3<double> axis, double angleRAD)
80 {
81  Vector3<double> C,up(0,1,0);
82  controlledObject_->GetExtrinsics(C, up);
84  rotation.SetValueAsAxisRad(axis, angleRAD);
85 
86  // Derive direction vector and rotate direction and up vector.
87  Vector3<double> direction;
88  C.Sub(PointOfInterest_, direction);
89  rotation.MultVec(direction, direction);
90  rotation.MultVec(up, up);
91  direction.Add(PointOfInterest_, C);
92 
93  controlledObject_->SetExtrinsics(C, PointOfInterest_, up);
94  return;
95 }
96 
98 LeftMouseMoved(int x1, int x2, int y1, int y2)
99 {
100  //left hand image coordinate system if extended by viewing direction
101 
102  int viewport[4];
103  glGetIntegerv(GL_VIEWPORT, viewport);
104  x1-=viewport[0];
105  x2-=viewport[0];
106  y1-=viewport[1];
107  y2-=viewport[1];
108 
109  double width = viewport[2];
110  double height = viewport[3];
111 
112  Vector3<double> C, up(0,1,0);
114  controlledObject_->GetExtrinsics(C, up);
115  R = controlledObject_->GetMyselfAsProjectionParameterBase()->GetR();
116 
117  // Calculate first vector
118  // The trackball contains the whole scene.
119  double x = x1 / width * 2.0;
120  double y = y1 / height * 2.0;
121  x = x - 1.0;
122  y = 1.0 - y;
123  x *=-1.0;
124  // calculate clicked point on trackball. Trackball has radius 1
125  double z = sqrt(2.0) - x * x - y * y;
126  if (z > 0)
127  {
128  z = sqrt(z);
129  }
130  else
131  {
132  return false;
133  }
134  Vector3<double> v1 = Vector3<double>(x, y, z);
135  v1.Normalize();
136  v1 = R*v1;
137 
138  // calculate second vector.
139  x = x2 / width * 2.0;
140  y = y2 / height * 2.0;
141  x = x - 1.0;
142  y = 1.0 - y;
143  x *=-1.0;
144 
145  z = sqrt(2.0) - x * x - y * y;
146  if (z > 0)
147  {
148  z = sqrt(z);
149  }
150  else
151  {
152  return false;
153  }
154 
155  Vector3<double> v2 = Vector3<double>(x, y, z);
156  v2.Normalize();
157  v2 = R*v2;
158 
159  // Calculate axis and angle for quaternion
160  Vector3<double> axis;
161 
162  v2.CrossProduct(v1, axis);
163  double angleRAD = acos(v1.ScalarProduct(v2));
164 
165  RotateAroundPOI(axis, angleRAD);
166  return true;
167 }
168 
170 LeftMouseDoubleClicked(int x, int y, int m)
171 {
172  if (! UseLeftDouble_) {
173  return false;
174  }
175 
176  // Get from 2D mouse position 3D point in scene.
177  if(!controlledObject_->GetViewportCoordinates(x, y)) {
178  BIASERR("outside used viewport!");
179  return false;
180  }
181 
182  BIAS::HomgPoint3D homgPoint=controlledObject_->UnProject(x, y);
183 
184  if (homgPoint[3] != 0.0)
185  {
186  Vector3<double> poi(homgPoint[0],homgPoint[1], homgPoint[2]);
187  SetPointOfInterest(poi);
188 
189  //cout << "TrackballControl::LeftMouseDoubleClicked("<<x<<","<<y<<") : "
190  // << "Set point of interest to ("
191  // << homgPoint[0] << ", "<< homgPoint[1] << ", " << homgPoint[2]
192  // << ")." << endl;
193  //Vector3<double> C;
194  // C = controlledObject_->GetMyselfAsProjectionParameterBase()->GetC();
195  // cout<<"And Camera Center:"<<C<<endl;
196 
197  }
198  else
199  {
200  ;//BIASERR("Error: Point of interest / 3D point could not be set.");
201  }
202  return true;
203 }
204 
206 MiddleMouseMoved(int x1, int x2, int y1, int y2)
207 {
208  // get current extrinsics
209  Vector3<double> C(0,0,0), up(0,0,1);
210  controlledObject_->GetExtrinsics(C, up);
211 
212  // compute vector of camera center to poi
213  Vector3<double> localPOI(0,0,0);
214  PointOfInterest_.Sub(C, localPOI);
215 
216  // compute distance of camera center to poi
217  double poiDepth = localPOI.Length();
218 
219  // project point of interest
220  HomgPoint3D tmp(PointOfInterest_);
221  HomgPoint2D projectedPOI = controlledObject_->Project(tmp);
222 
223  // move projected point of interest
224  projectedPOI[0] += (x1 - x2);
225  projectedPOI[1] += (y1 - y2);
226  projectedPOI[2] = 1.;
227 
228  // set new poi at old depth
229  tmp = controlledObject_->UnProject(projectedPOI, poiDepth);
230  tmp.Homogenize();
231  PointOfInterest_[0] = tmp[0]; PointOfInterest_[1] = tmp[1]; PointOfInterest_[2] = tmp[2];
232  // adjust center of camera
233  PointOfInterest_.Sub(localPOI, C);
234 
235  controlledObject_->SetExtrinsics(C, PointOfInterest_, up);
236  return true;
237 
238  /*
239  Vector3<double> directionRight, directionUp, up(0,1,0), C, view;
240  if (controlledObject_->PoseValid()){
241  controlledObject_->GetCurrentExtrinsics(C, up);
242  } else {
243  BIASERR("TrackballControl: PoseInvalid");
244  }
245  // Derive vector for moving right / left
246  PointOfInterest_.Sub(C, view);
247  view.CrossProduct(up, directionRight);
248  directionRight.Normalize();
249  directionUp = up;
250 
251  if (x1-x2 != 0)
252  {
253  if (x1 > x2)
254  {
255  // Move left
256  directionRight.MultIP(Stepsize_);
257  C.AddIP(directionRight);
258  PointOfInterest_.AddIP(directionRight);
259  }
260  else
261  {
262  // Move right
263  directionRight.MultIP(-Stepsize_);
264  C.AddIP(directionRight);
265  PointOfInterest_.AddIP(directionRight);
266  }
267  }
268 
269  if (y1-y2 != 0)
270  {
271  if (y1 > y2)
272  {
273  // Move up
274  directionUp.MultIP(-Stepsize_);
275  C.AddIP(directionUp);
276  PointOfInterest_.AddIP(directionUp);
277  }
278  else
279  {
280  // Move down
281  directionUp.MultIP(Stepsize_);
282  C.AddIP(directionUp);
283  PointOfInterest_.AddIP(directionUp);
284  }
285  }
286 
287  controlledObject_->SetExtrinsics(C, PointOfInterest_, up);
288  return true;
289  */
290 }
291 
292 
294 RotateAroundViewingDirection(double rotationAngleRAD)
295 {
296  Vector3<double> C, up(0,1,0), rotationAxis;
297  controlledObject_->GetExtrinsics(C, up);
298 
299  rotationAxis = PointOfInterest_ - C;
300  if(rotationAxis.NormL2() == 0.0){
301  BIASERR("point of interest equals camera center\n");
303  R = controlledObject_->GetMyselfAsProjectionParameterBase()->GetR();
304  for(unsigned int i=0; i<3; i++)
305  rotationAxis[i] = R[i][2];
306  }
307 
308  // Create quaternion and derive new up vector
310  delta.SetValueAsAxisRad(rotationAxis, rotationAngleRAD);
311  delta.MultVec(up, up);
312 
313  controlledObject_->SetExtrinsics(C,
314  PointOfInterest_,
315  up);
316 }
317 
319 LeftAndRightMouseMoved(int x1, int x2, int y1, int y2)
320 {
321  //left hand image coordinate system if extended by viewing direction
322  // int temp = y2;
323  // y2 = y1;
324  // y1 = temp;
325 
326  int viewport[4];
327  glGetIntegerv(GL_VIEWPORT, viewport);
328  int width = viewport[2];
329  int height = viewport[3];
330 
331  Vector3<double> C, up(0,1,0), viewingDirection;
332  controlledObject_->GetExtrinsics(C, up);
333 
334  viewingDirection = PointOfInterest_ - C;
335 
336  Vector3<double> rotationAxis;
337  // Compute rotation axis and angle
338  Vector3<double> v1 = Vector3<double>((x1 - (width/2.0)),
339  (y1 - (height/2.0)),
340  0);
341 
342  Vector3<double> v2 = Vector3<double>(x2 - (width/2.0),
343  y2 - (height/2.0),
344  0);
345 
346  v1.Normalize();
347  v2.Normalize();
348 
349  v1.CrossProduct(v2, rotationAxis);
350  double rotationAngle = acos(v1.ScalarProduct(v2));
351 
352  if(viewingDirection.ScalarProduct(rotationAxis) > 0 )
353  rotationAngle *= -1.0;
354 
355  RotateAroundViewingDirection(rotationAngle);
356 
357  return true;
358 }
359 
362 {
363  PointOfInterest_ = poi;
364 
365  if(controlledObject_==NULL) return;
366  // Calculate new camera parameters.
367  Vector3<double> C, up(0, 1, 0);
368  if (controlledObject_->PoseValid()){
369  controlledObject_->GetExtrinsics(C,up);
370  } else {
371  BIASERR("TrackballControl: PoseInvalid");
372  }
373 
374  //automaticly set stepsize to a 5 percent of distance to point of interest
375  Vector3<double> dist = PointOfInterest_ - C;
376  Stepsize_ = 0.05*dist.NormL2();
377  //cout<<"[Trackball] stepsize = "<<Stepsize_<<endl;
378  controlledObject_->SetExtrinsics(C,poi,up);
379 }
380 
381 
384 {
385  // extract old distance of
386  double dist = 10.0;
387  if (controlledObject_){
388  RMatrix oldR;
389  Vector3<double> oldC;
390  controlledObject_->GetExtrinsics(oldC, oldR);
391  Vector3<double> oldPOI = GetPoI();
392  dist = (oldC-oldPOI).NormL2();
393  }
397  if (controlledObject_->PoseValid()){
398  controlledObject_->GetExtrinsics(C,R);
399  } else {
400  BIASERR("TrackballControl: PoseInvalid, using identity!");
401  C[0]=0;C[1]=0;C[2]=0;
402  R.SetIdentity();
403  }
405  A[0] = R[0][2]; A[1] = R[1][2]; A[2] = R[2][2];
406  A *= dist;
407  SetPointOfInterest(C+A);
408 }
void Sub(const T &scalar, Vector4< T > &dest) const
Substraction with a scalar, storing results in destionation vector.
Definition: Vector4.hh:591
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
double Length() const
returns the Euclidean Length of the Vector
Definition: Vector3.hh:193
virtual bool LeftMouseDoubleClicked(int x, int y, int m)
Computes from the coordinates x,y a 3D point in the scene and tries to set it to the point of interes...
void Add(const T &scalar, Vector3< T > &dest) const
Addition with a scalar, storing results in destionation vector.
Definition: Vector3.hh:684
void SetGLProjectionParametersInterface(BIAS::GLProjectionParametersInterface *projInterface)
Set the ProjectionParametersInterface (camera)
void ScalarProduct(const Vector3< T > &argvec, T &result) const
scalar product (=inner product) of two vectors, storing the result in result
Definition: Vector3.hh:603
void Multiply(const T &scalar, Vector3< T > &dest) const
Multiplication with a scalar, storing results in destination vector.
Definition: Vector3.hh:698
void Homogenize()
homogenize class data member elements to W==1 by divison by W
Definition: HomgPoint3D.hh:308
bool LeftMouseMoved(int x1, int x2, int y1, int y2)
Rotates the camera around the point of interest.
bool MouseWheelUsed(double stepsize)
Handles Mouse Wheel events and zooms in or out.
bool MiddleMouseMoved(int x1, int x2, int y1, int y2)
Moves the camera left/right/up/down and sets new point of interest.
int MultVec(const Vector3< QUAT_TYPE > &vec, Vector3< QUAT_TYPE > &res) const
rotates the given Vector qith the quaternion ( q v q* ) the resulting vector is given in res ...
Definition: Quaternion.hh:136
3D rotation matrix
Definition: RMatrix.hh:49
void RotateAroundViewingDirection(double rotationAngleRAD)
Rotate around viewing direction.
Abstract interface class to handle changes in rendering parameters by controllers and in rendering co...
void CrossProduct(const Vector3< T > &argvec, Vector3< T > &destvec) const
cross product of two vectors destvec = this x argvec
Definition: Vector3.hh:594
bool LeftAndRightMouseMoved(int x1, int x2, int y1, int y2)
react to mouse move if left and right button is pressed.
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
void Sub(const T &scalar, Vector3< T > &dest) const
Substraction with a scalar, storing results in destination vector.
Definition: Vector3.hh:705
bool RightMouseMoved(int x1, int x2, int y1, int y2)
Moves the camera forward to point of interest if y2-y1 is positive else the camera is moved away from...
virtual void SetGLProjectionParametersInterface(BIAS::GLProjectionParametersInterface *interface_)
Set the camera projection parameters.
class for rotation with axis and angle
void RotateAroundPOI(BIAS::Vector3< double > axis, double angleRAD)
Rotate around the point of interest.
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663
void SetPointOfInterest(const BIAS::Vector3< double > &poi)
Set point of interest the controller will circle around.
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
class BIASGeometryBase_EXPORT HomgPoint3D
void SetValueAsAxisRad(const Vector3< QUAT_TYPE > &axis, QUAT_TYPE angle)
sets the quaternion with given rotation axis and angle (in rad)
Definition: Quaternion.hh:183
void MoveInViewingDirection(double stepSize)
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429