Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
biasGLviewerGLUT.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include "biasGLviewerGLUT.hh"
26 #include <algorithm>
27 #include <iostream>
28 #include <Utils/IOUtils.hh>
29 
30 #ifdef BIAS_HAVE_OPENSCENEGRAPH
31 #include <osg/ShapeDrawable>
32 #include <osg/Group>
33 #endif //BIAS_HAVE_OPENSCENEGRAPH
34 
35 using namespace std;
36 using namespace BIAS;
37 
38 void AnimFuncWrapper();
39 biasGLviewerGLUT* viewerObjPointer = NULL;
40 
41 biasGLviewerGLUT::
42 biasGLviewerGLUT(int argc, char* argv[])
43 {
44  initialized_ = false;
45  animate_ = false;
46  storeToDisc_ = false;
47  renderBoundingBoxes_ = false;
48 
49  slotCounter_ = 0;
50  viewingSlot_ = 0;
51  contextPointer_ = NULL;
52 
53  // Animation / Control Params
54  int groupID = GetFreeGroupID();
55  //animationFile_ = AddParamString(
56  // "anim", "animation file", "", 'a', groupID);
57  //fixedFPS_ = AddParamDouble(
58  // "fps", "set a fixed fps for animation", 25, 1, 1000, 'f', groupID);
59  useFlyMode_ = AddParamBool(
60  "fly", "set mouse control to fly mode", false, 0 ,groupID);
61  useRotMode_ = AddParamBool(
62  "onlyRot", "turn only rotation for mouse control on", false, 0, groupID);
63  SetGroupName(groupID, "Animation / Control");
64 
65  // View Params
66  groupID = GetFreeGroupID();
67  zNear_ = AddParamDouble(
68  "zNear", "set near clipping plane distance, overrides autoClipping", 0.001, 0.000001, DBL_MAX, 0 ,groupID);
69  zFar_ = AddParamDouble(
70  "zFar", "set near clipping plane distance, overrides autoClipping", 10000, 0.00001, DBL_MAX, 0, groupID);
71  fov_ = AddParamDouble(
72  "fov", "field of view in degree", 0, 0, 359.9, 0, groupID);
73  autoClipping_ = AddParamBool(
74  "autoClipping", "turns auto clipping on/off", true, 0 , groupID);
75  backfaceCulling_ = AddParamBool(
76  "backfaceCulling", "do not draw back faces of triangles?", false, 0, groupID);
77  teapot_ = AddParamBool(
78  "teapot", "Add a glut teapot to scene", false, 0, groupID);
79  cube_ = AddParamBool(
80  "cube", "Add a glut cube to scene", false, 0, groupID);
81  tetrahedron_ = AddParamBool(
82  "tetrahedron", "Add a glut tetrahedron to scene", false, 0, groupID);
83  icosahedron_ = AddParamBool(
84  "icosahedron", "Add a glut icosahedron to scene", false, 0, groupID);
85 
86  SetGroupName(groupID, "View");
87 
88  // Camera Params
89  groupID = GetFreeGroupID();
90  projectionFile_ = AddParamString(
91  "projection", "load camera parameters from this file, sets findSceneCenter to false if useJustIntrinsics is false (default)",
92  "", 'p', groupID);
93  useSceneCenter_ = AddParamBool(
94  "findSceneCenter", "sets camera to center of scene",
95  true, 0, groupID);
96  useJustIntrinsics_ = AddParamBool(
97  "useJustIntrinsics", "uses only intrinsics from loaded projection",
98  false, 0, groupID);
99 
100  // create values for reshape behaviour
101  std::vector<std::string> reshapeBehaviour;
102  reshapeBehaviour.push_back("Deny");
103  reshapeBehaviour.push_back("AutoRescaleParams");
104  reshapeBehaviour.push_back("AutoCutImage");
105  reshapeBehaviour.push_back("AutoSimplePerspectiveCam");
106 
107  autoReshapeBehaviour_ = AddParamEnum(
108  "reshapeBehaviour", "sets the automatic reshape behaviour of the camera",
109  reshapeBehaviour, 1,NULL, 0, groupID);
110  SetGroupName(groupID, "Camera");
111 
112  // Misc Params
113  groupID = GetFreeGroupID();
114  winwidth_ = AddParamInt(
115  "winwidth", "window width", 640, 0, INT_MAX, 'w', groupID);
116  winheight_ = AddParamInt(
117  "winheight", "window width", 480, 0, INT_MAX, 'h', groupID);
118  screenShotName_ = AddParamString(
119  "screenShotName", "name for screenshots default is 'screenShot'", "screenShot", 0, groupID);
120  backGroundColor_ = AddParamVecDbl(
121  "bgColor", "set background clear color", "200.0 230.0 230.0", 0, groupID);
122 
123  bool ret = IOUtils::ParseCommandLineEvalHelp(*this,argc, argv,firstUnkownParam_);
124  if(!ret) BIASWARN("Parsing command line arguments failed. Please check them!");
125  argc_ = argc;
126  argv_ = argv;
127 }
128 
129 
130 void biasGLviewerGLUT::
131 Init()
132 {
133  // init projection and window size
134  unsigned int winwidth = *winwidth_, winheight = *winheight_;
135  if(*projectionFile_ == "") {
136  Vector3<double> C(0.0,0.0,0.0);
137  Quaternion<double> Q(0.0,0.0,0.0,1.0);
139  ppp->SetSimplePerspectiveCam(65.0,winwidth,winheight);
140  cout<<"Setting simple perspective camera with: 65 degrees fov and:"
141  <<winwidth<<"x"<<winheight<<" pixel."<<endl;
142  ppp->SetExtrinsics(C,Q);
143  camera_.Assign(*ppp);
144  }
145  else {
146  // when projection with extrinsics is loaded no scene center is used
147  if (!(*useJustIntrinsics_)) {
148  *useSceneCenter_ = false;
149  }
150  Projection proj;
151 
152 #ifdef BIAS_HAVE_XML2
153  if (proj.XMLRead(*projectionFile_) != 0) {
154 #else
155  if (proj.Load(*projectionFile_) != 0) {
156 #endif
157  BIASERR("could not read projection file!\n");
158  exit(0);
159  }
160  else
161  camera_.Assign(*proj.GetParameters());
162  }
163  unsigned int width, height;
164  camera_.GetMyselfAsProjectionParameterBase()->GetImageSize(width, height);
165 
166  if(winwidth == 0)
167  winwidth = width;
168  if(winheight == 0)
169  winheight = height;
170 
171  // init Glut Context
172  contextPointer_ =
173  new ContextGLUT(0,0, winwidth, winheight,
174  "BIASOpenGLViewerGlut", NULL, &argc_, argv_);
175 
176  //check if a value was entered for clipping planes and set auto to false
177  if(*zFar_ != 10000 || *zNear_ != 0.001)
178  contextPointer_->SetAutoClipping(false);
179  else
180  contextPointer_->SetAutoClipping(*autoClipping_);
181 
182  // set background color
183  Vector4<float> clearColor((float)((*backGroundColor_)[0]),
184  (float)((*backGroundColor_)[1]),
185  (float)((*backGroundColor_)[2]),
186  0.0);
187  contextPointer_->SetClearColor(clearColor);
188 
189  // init Clipping Planes
190  camera_.SetZClippingPlanes(*zNear_, *zFar_);
191 
192  // init screen shor control
193  screenShotControl_.Init(contextPointer_, *screenShotName_, "ppm", "", true);
194 
195  sceneLight_.SetLightAsHeadLight(false);
196  sceneLight_.SetDrawLightPosition(false);
197  sceneLight_.SetAmbient(Vector4<double>(0.3,0.3,0.3,1.0));
198  sceneLight_.SetDiffuse(Vector4<double>(1.0,1.0,1.0,1.0));
199  sceneLight_.SetSpecular(Vector4<double>(1.0,1.0,1.0,1.0));
200  contextPointer_->AppendScene(&sceneLight_);
201 
202 #ifdef BIAS_HAVE_OPENSCENEGRAPH
203  // init and load scene
204  scene_.Init();
205  bool hasModel = false;
206 
207  if(argc_ - firstUnkownParam_ >= 1 && firstUnkownParam_ > 0) {
208  for(int i=0;i< (argc_ - firstUnkownParam_);i++){
209  cout<<"loading "<<argv_[firstUnkownParam_+i]<< "... \n"; cout.flush();
210  if(scene_.AppendSubTreeFromFile(argv_[firstUnkownParam_+i])!=0)
211  cout<<" failed\n";
212  else{
213  cout<<" success\n";
214  hasModel = true;
215  }
216  }
217  }
218 
219  if(!hasModel && ! (*teapot_) && ! (*cube_)
220  && ! (*icosahedron_) && ! (*tetrahedron_)) {
221  osg::ShapeDrawable *sphere =
222  new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0., 0., 0.), 2.0));
223  const osg::Vec4 color(139.0/255.0,248.0/255.0,244.0/255.0,0);
224  sphere->setColor(color);
225  osg::Geode *n = new osg::Geode;
226  n->addDrawable(sphere);
227  scene_.AppendNode(n);
228  }
229 
230  contextPointer_->AppendScene(&scene_);
231 
232 #endif
233 
234  //append glut Scene
235  sceneGlut_.SetDrawTeapot(*teapot_,0.4);
236  sceneGlut_.SetDrawCube(*cube_,0.4);
237  sceneGlut_.SetDrawIcosahedron(*icosahedron_);
238  sceneGlut_.SetDrawTetrahedron(*tetrahedron_);
239  contextPointer_->AppendScene(&sceneGlut_);
240 
241 
242 
243  // set auto reshape behaviour of camera, default is AutoRescaleParams
244  switch(*autoReshapeBehaviour_)
245  {
246  case 0:
247  camera_.SetAutoReshapeBehaviour(GLProjectionParametersInterface::Deny);
248  break;
249  case 2:
250  camera_.SetAutoReshapeBehaviour(GLProjectionParametersInterface::AutoCutImage);
251  break;
252  case 3:
253  camera_.SetAutoReshapeBehaviour(GLProjectionParametersInterface::AutoSimplePerspectiveCam);
254  break;
255  default:
256  camera_.SetAutoReshapeBehaviour(GLProjectionParametersInterface::AutoRescaleParams);
257  break;
258  }
259 
260 
261  // init camera control
262  contextPointer_->SetGLProjectionParametersInterface(&camera_);
263 
264  if(*useFlyMode_ && ! *useRotMode_) {
265  contextPointer_->SetControl(&flyControl_);
266  }
267  else if (!*useFlyMode_ && ! *useRotMode_ ) {
268  contextPointer_->SetControl(&control_);
269  //DistanceMeaseureControl is also derived from Scenebase and draws itself
270  contextPointer_->AppendScene(&control_);
271  }
272  else {
273  contextPointer_->SetControl(&rotControl_);
274  }
275 
276  // add listeners
277  contextPointer_->AppendAdditionalListener(&screenShotControl_);
278  contextPointer_->AppendAdditionalListener(this); //key listener
279 
280  // set camera center
281  if(*useSceneCenter_) {
282  BIAS::Vector3<double> CameraCenter, radius, SceneCenter;
283  if (!contextPointer_->GetSceneCenter(SceneCenter, radius))
284  BIASERR("could not retrieve bounding box from scene");
285  // move 10% outwards
286  CameraCenter = SceneCenter + 1.1 * radius;
287  cout<<"using scene center "<<SceneCenter<<" and new camera center "
288  <<CameraCenter <<endl;
289  // set point of interest only if not equal to camera center
290  if ((CameraCenter-SceneCenter).NormL2()>0.001) {
291  camera_.GetMyselfAsProjectionParameterBase()->SetC(CameraCenter);
292  control_.SetPointOfInterest(SceneCenter);
293  } else {
294  cerr<<"could not set poi, empty scene ?"<<endl;
295  }
296  }
297 
298  // backface culling
299  if (*backfaceCulling_)
300  glEnable(GL_CULL_FACE);
301  else
302  glDisable(GL_CULL_FACE);
303 
304  initialized_ = true;
305 }
306 
307 void biasGLviewerGLUT::
308 Run()
309 {
310  if (initialized_) glutMainLoop();
311  else cout << "Run Init() first!" << endl;
312 }
313 
314 
315 bool biasGLviewerGLUT::
316 StandardKeyPressed(unsigned char key, int, int)
317 {
318  static int pointSizeG = 1;
319  static bool twosided = false;
320  switch(key) {
321  case 'b':
322  renderBoundingBoxes_ = !renderBoundingBoxes_;
323  cout<<"switched bounding box rendering "
324  << (renderBoundingBoxes_? "on" : "off")<<endl;
325  contextPointer_->GlobalBoundingBoxSwitch(renderBoundingBoxes_);
326  break;
327  case 'q':
328  exit(0);
329  break;
330  case '0' :
331  viewingSlot_ = 0;
332  cout<<"camera->SetActiveSlot(0)"<<endl;
333  break;
334  case 'z': glPolygonMode( GL_FRONT_AND_BACK, GL_POINT);
335  cout << "PolygonMode: Point." << endl;
336  break;
337  case 'x': glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
338  cout << "PolygonMode: Line." << endl;
339  break;
340  case 'c': glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
341  cout << "PolygonMode: Fill." << endl;
342  break;
343  case 'Z': glShadeModel(GL_SMOOTH);
344  cout << "Shading Smooth." << endl;
345  break;
346  case 'X': glShadeModel(GL_FLAT);
347  cout << "Shading Flat." << endl;
348  break;
349  case 'T':
350  if(!twosided) {
351  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
352  twosided = true;
353  } else {
354  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
355  twosided = false;
356  }
357  cout << "Two-sided lighting is " << (twosided ? "on" : "off")
358  << "." << endl;
359  break;
360 
361  case ']':
362  pointSizeG++;
363  cout<<"Point/Line Size increasing:"<<pointSizeG<<endl;
364  glPointSize(pointSizeG);
365  glLineWidth(pointSizeG);
366  break;
367  case '[':
368  pointSizeG--;
369  if (pointSizeG<1) pointSizeG=1;
370  cout<<"Point/Line Size decreasing:"<<pointSizeG<<endl;
371  glPointSize(pointSizeG);
372  glLineWidth(pointSizeG);
373  break;
374  case 'G':SceneBase::SetAnimationSpeed(1.0);
375  cout<<"Enabling Animation/Collision in SceneBase. Speed = 1"<<endl;
376  break;
377  case 'g':SceneBase::SetAnimationSpeed(0.0);
378  cout<<"Disabling Animation/Collision in SceneBase."<<endl;
379  break;
380  case 'a':
381  animate_ = true;
382  glutIdleFunc(AnimFuncWrapper);
383  break;
384  case 's':
385  animate_ = false;
386  glutIdleFunc(NULL);
387  break;
388  case 'S':
389  toggleStoreToDisc_();
390  break;
391  case 'h' :
392  cout<<"\n Application specific controls: \n\n";
393  cout<<"\t + : Increase TimeStep\n";
394  cout<<"\t - : Decrease TimeStep\n";
395  cout<<"\t n : switch view to next slot\n";
396  cout<<"\t 0 : switch view to slot 0\n";
397  cout<<"\t a : start/resume animation\n";
398  cout<<"\t s : stop animation\n";
399  cout<<"\t g/G : enable/disable SceneBase animation/collision"<<endl;
400  cout<<"\t S : store images to disc, resume with next slot when done\n";
401  cout<<"\t T : toggle two-sided lighting\n";
402  cout<<"\t m : toggle the distance measurement control\n";
403  cout<<"\t P : Print current camera info \n";
404  cout<<"\t q : quit \n";
405  cout<<"\t b : toggle bounding box rendering\n";
406  cout<<"\t [] : increase/decrease point/line size\n";
407  cout<<"\t zxc : toggle polygon mode\n";
408  cout<<"\t </> : decrerase/increase zFar \n";
409  cout<<"\t ,/. : decrerase/increase zNear \n";
410  cout<<"\t F5 : screenshot + depth\n";
411  cout<<"\t F6 : camera params\n";
412  break;
413  case 'm':
414  control_.SetDistanceMeasure(! control_.GetDistanceMeasure());
415  break;
416  case 'P' :
417  cout<<"Current Camera:"<<camera_<<endl;
418  break;
419  case '>' :
420  *zFar_ *= (12.0)/(10.0);
421  camera_.SetZClippingPlanes(*zNear_, *zFar_);
422  cout<<"zFar = "<<*zFar_<<endl;
423  break;
424  case '<' :
425  *zFar_ *= (10.0)/(12.0);
426  cout<<"zFar = "<<*zFar_<<endl;
427  camera_.SetZClippingPlanes(*zNear_, *zFar_);
428  break;
429  case ',':
430  *zNear_ *= (10.0)/(12.0);
431  cout<<"zNear = "<<*zNear_<<endl;
432  camera_.SetZClippingPlanes(*zNear_, *zFar_);
433  break;
434  case '.':
435  *zNear_ *= (12.0)/(10.0);
436  cout<<"zNear = "<<*zNear_<<endl;
437  camera_.SetZClippingPlanes(*zNear_, *zFar_);
438  break;
439  default:
440  return false;
441  break;
442  }
443  glutPostRedisplay();
444  return true;
445 }
446 
447 void biasGLviewerGLUT::
448 AnimationFunc() {
449  /* if (!animate_) return;
450 
451  if(animator_.Animate()!=1) {
452  if(storeToDisc_) {
453  screenShotControl_.StoreScreenShot();
454  }
455  BIAS::RMatrix rmat;Vector3<double> C;
456  camera_.GetAbsoluteExtrinsics(C,rmat);
457  double PhiX, PhiY, PhiZ;
458  rmat.GetRotationAnglesXYZ(PhiX, PhiY, PhiZ);
459 
460  } else {
461  if(storeToDisc_) {
462  if(slotCounter_ < camera_.GetNumSlots()-1) {
463  slotCounter_++;
464 
465  animator_.Start();
466  } else {
467  toggleStoreToDisc_();
468  slotCounter_ = 0;
469 
470 
471  }
472  }
473  }
474  */
475 }
476 
477 void AnimFuncWrapper() {
478  (*viewerObjPointer).AnimationFunc();
479  glutPostRedisplay();
480 }
481 
482 
483 void biasGLviewerGLUT::
484 toggleStoreToDisc_() {
485  storeToDisc_ = !storeToDisc_;
486  if(storeToDisc_)
487  cout<<"WRITING to disc ENABLED!\n";
488  else
489  cout<<"WRITING to disc DISABLED!\n";
490 }
491 
492 int main(int argc, char* argv[])
493 {
494  biasGLviewerGLUT viewer(argc,argv);
495  viewerObjPointer = &viewer;
496  viewer.Init();
497  viewer.Run();
498  return 0;
499 }
500 
int SetSimplePerspectiveCam(double fovyDEG, int imageWidth=-1, int imageHeight=-1)
int XMLRead(const std::string &Filename)
derived classes must implement the function XMLIn which is called by this function XMLRead to read ev...
Definition: XMLBase.cpp:78
virtual int Load(const std::string &filename)
convenience wrapper which tries to read different formats
Definition: Projection.cpp:62
const ProjectionParametersBase * GetParameters(unsigned int cam=0) const
const parameter access function
Definition: Projection.hh:194
This class hides the underlying projection model, like projection matrix, spherical camera...
Definition: Projection.hh:70
class Vec3f Vec3
Wrapper to glut-library.
Definition: ContextGLUT.hh:38
class for rendering with projection parameters of ProjectionParametersPerspective ...
virtual int SetExtrinsics(const BIAS::HomgPoint3D &C, const BIAS::RMatrix &R)