ViSP  2.10.0
vpSimulator.cpp
1 /****************************************************************************
2  *
3  * $Id: vpSimulator.cpp 5263 2015-02-04 13:43:25Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Simulator based on Coin3d.
36  *
37  * Authors:
38  * Eric Marchand
39  * Anthony Saunier
40  *
41  *****************************************************************************/
48 #include <visp/vpConfig.h>
49 
50 #ifdef VISP_HAVE_COIN_AND_GUI
51 
52 #include <visp/vpSimulator.h>
53 #include <visp/vpTime.h>
54 
55 #include <visp/vpImage.h>
56 #include <visp/vpImageIo.h>
57 
58 /* Objets OIV. */
59 #include <Inventor/nodes/SoCone.h> /* Objet cone. */
60 #include <Inventor/nodes/SoCylinder.h> /* Objet cylindre. */
61 #include <Inventor/nodes/SoPointLight.h> /* Objet lumiere ponctuelle. */
62 #include <Inventor/nodes/SoCoordinate3.h> /* Liste de points. */
63 #include <Inventor/nodes/SoIndexedFaceSet.h> /* Liste de face. */
64 #include <Inventor/nodes/SoTranslation.h> /* Trasnfo translation. */
65 #include <Inventor/nodes/SoScale.h> /* Trasnfo mise a l'echelle. */
66 #include <Inventor/nodes/SoRotationXYZ.h> /* Transfo rotation simple. */
67 
68 #include <Inventor/nodes/SoDirectionalLight.h> /* Objet lumiere directionnelle*/
69 #include <Inventor/nodes/SoMaterial.h> /* Matiere (couleur) des objets. */
70 #include <Inventor/nodes/SoDrawStyle.h> /* Style de rendu. */
71 #include <Inventor/nodes/SoEnvironment.h> /* Eclairage ambiant. */
72 #include <Inventor/nodes/SoGroup.h> /* Groupement de noeuds (sans separation)*/
73 #include <Inventor/actions/SoWriteAction.h>
74 
75 
76 
77 
78 // Positions of all of the vertices:
79 //
80 static float pyramidVertexes [5][3] =
81  {
82  {0.33f, 0.33f, 0.f},
83  {-0.33f, 0.33f, 0.f},
84  {-0.33f, -0.33f, 0.f},
85  {0.33f, -0.33f, 0.f},
86 
87  {0.f, 0.f, -1.0f}
88  };
89 
90 
91 static int32_t pyramidFaces[] =
92  {
93  0, 1, 2, 3, SO_END_FACE_INDEX, // top face
94 
95  0, 1, 4, SO_END_FACE_INDEX, // 4 faces about top
96  1, 2, 4, SO_END_FACE_INDEX,
97  2, 3, 4, SO_END_FACE_INDEX,
98  3, 0, 4, SO_END_FACE_INDEX,
99  };
100 
101 
102 // Routine to create a scene graph representing a dodecahedron
103 SoSeparator *
104 makePyramide()
105 {
106  SoSeparator *result = new SoSeparator;
107  result->ref();
108 
109  // Define coordinates for vertices
110  SoCoordinate3 *myCoords = new SoCoordinate3;
111  myCoords->point.setValues(0, 5, pyramidVertexes);
112  result->addChild(myCoords);
113 
114  // Define the IndexedFaceSet, with indices into the vertices:
115  SoIndexedFaceSet *myFaceSet = new SoIndexedFaceSet;
116  myFaceSet->coordIndex.setValues (0, 21, (const int32_t*)pyramidFaces);
117  result->addChild (myFaceSet);
118 
119  result->unrefNoDelete();
120  return result;
121 }
122 
123 /* Cree une fleche composee d'un cylindre et d'un cone.
124  * La fleche a une hauteur total de <longueur>, dont
125  * <proportionFleche>% pour la fleche. Le rayon du cylindre
126  * est <radius>, et celui de la fleche <radius> * 5.
127  * La fleche est oriente selon l'axe Y.
128  */
129 static SoSeparator *
130 createArrow (float longueur,
131  float proportionFleche,
132  float radius)
133 {
134  SoSeparator *fleche = new SoSeparator;
135  fleche->ref();
136 
137  SoTranslation *poseCylindre = new SoTranslation;
138  SoCylinder *line = new SoCylinder;
139  SoTranslation *posePointe = new SoTranslation;
140  SoCone *pointe = new SoCone;
141 
142  float l_cylindre = longueur * ( 1 - proportionFleche);
143  float l_cone = longueur * proportionFleche;
144  float radius_cylindre = radius;
145  float radius_cone = radius * 5;
146 
147  line->radius.setValue (radius_cylindre);
148  line->height.setValue (l_cylindre);
149 
150  poseCylindre->translation.setValue (0, l_cylindre / 2, 0);
151  posePointe->translation.setValue (0.0, l_cylindre / 2 + l_cone / 2, 0);
152 
153  pointe->bottomRadius.setValue (radius_cone);
154  pointe->height.setValue (l_cone);
155 
156 
157  fleche->addChild (poseCylindre);
158  fleche->addChild (line);
159  fleche->addChild (posePointe);
160  fleche->addChild (pointe);
161 
162  return fleche;
163 }
164 
165 
166 /*
167  Cree un objet repere dans un noeud separator, et le renvoie.
168  \return : code d'erreur, SIMU_CODE_OK si tout s'est bien passe.
169 */
170 #define LONGUEUR_FLECHE 1.0f
171 #define RAYON_FLECHE 0.002f
172 #define PROPORTION_FLECHE 0.1f
173 
174 SoSeparator *
175 createFrame (float longueurFleche = LONGUEUR_FLECHE ,
176  float proportionFleche = PROPORTION_FLECHE,
177  float radiusFleche = RAYON_FLECHE)
178 {
179  vpDEBUG_TRACE (15, "# Entree.");
180 
181  SoSeparator *frame = new SoSeparator;
182  frame-> ref ();
183 
184  SoRotationXYZ *rotationY_X = new SoRotationXYZ;
185  rotationY_X->axis = SoRotationXYZ::Z;
186  rotationY_X->angle.setValue ((float)(- M_PI / 2));
187 
188  SoRotationXYZ *rotationX_Y = new SoRotationXYZ;
189  rotationX_Y->axis = SoRotationXYZ::Z;
190  rotationX_Y->angle.setValue ((float)(M_PI / 2));
191 
192  SoRotationXYZ *rotationY_Z = new SoRotationXYZ;
193  rotationY_Z->axis = SoRotationXYZ::X;
194  rotationY_Z->angle.setValue ((float)(M_PI / 2));
195 
196  SoMaterial *rouge = new SoMaterial;
197  rouge->diffuseColor.setValue(1.0, 0.0, 0.0);
198  rouge->emissiveColor.setValue(0.5, 0.0, 0.0);
199 
200  SoMaterial *vert = new SoMaterial;
201  vert->diffuseColor.setValue(0.0, 1.0, 0.0);
202  vert->emissiveColor.setValue(0.0, 0.5, 0.0);
203 
204  SoMaterial *bleu = new SoMaterial;
205  bleu->diffuseColor.setValue(0.0, 0.0, 1.0);
206  bleu->emissiveColor.setValue(0.0, 0.0, 0.5);
207 
208  SoSeparator *fleche = createArrow(longueurFleche,
209  proportionFleche,
210  radiusFleche);
211 
212  frame->addChild (rouge);
213  frame->addChild (rotationY_X);
214  frame->addChild (fleche);
215  frame->addChild (vert);
216  frame->addChild (rotationX_Y);
217  frame->addChild (fleche);
218  frame->addChild (bleu);
219  frame->addChild (rotationY_Z);
220  frame->addChild (fleche);
221 
222  frame-> unrefNoDelete ();
223 
224  vpDEBUG_TRACE (15, "# Sortie.");
225  return frame;
226 }
227 
228 SoSeparator *
229 createCameraObject (const float zoomFactor = 1.0)
230 {
231  vpDEBUG_TRACE (15, "# Entree.");
232 
233  SoSeparator * cam = new SoSeparator;
234  cam->ref ();
235 
236  SoMaterial *myMaterial = new SoMaterial;
237  myMaterial->diffuseColor.setValue(1.0, 0.0, 0.0);
238  myMaterial->emissiveColor.setValue(0.5, 0.0, 0.0);
239 
240  SoScale *taille = new SoScale;
241  {
242  float zoom = 0.1f * zoomFactor;
243  taille->scaleFactor.setValue (zoom, zoom, zoom);
244  }
245 
246  SoMaterial *couleurBlanc = new SoMaterial;
247  couleurBlanc->diffuseColor.setValue(1.0, 1.0, 1.0);
248  couleurBlanc->emissiveColor.setValue(1.0, 1.0, 1.0);
249  SoDrawStyle * filDeFer = new SoDrawStyle;
250  filDeFer->style.setValue (SoDrawStyle::LINES);
251  filDeFer->lineWidth.setValue (1);
252 
253  SoSeparator * cone = new SoSeparator;
254  cone->ref();
255  cone->addChild (makePyramide());
256  cone->addChild (couleurBlanc);
257  cone->addChild (filDeFer);
258  cone->addChild (makePyramide());
259  cone->unrefNoDelete();
260 
261  cam->addChild(myMaterial);
262  cam->addChild(taille);
263  cam->addChild(cone);
264  cam->addChild(createFrame(2.0f,0.1f,0.01f));
265 
266  // cam->unref() ;
267  vpDEBUG_TRACE (15, "# Sortie.");
268  return cam;
269 }
270 
271 
272 //--------------------------------------------------------------
273 void
275 {
276  internal_width = 200;
277  internal_height= 200;
278  external_width = 200;
279  external_height= 200;
280 
281  mainWindowInitialized = false ;
282  internalView = NULL ;
283  externalView = NULL ;
284  image_background = NULL ;
285 
286  zoomFactor = 1 ;
287  cameraPositionInitialized = false ;
288 
289  // write image process
290  realtime=NULL ;
291  offScreenRenderer = NULL ;
292  bufferView = NULL;
293  get = 1 ;
295  mainThread = NULL;
296  scene = NULL;
297  internalRoot = NULL;
298  externalRoot = NULL;
299  internalCamera = NULL;
300  externalCamera = NULL;
301  internalCameraPosition = NULL;
302  extrenalCameraPosition = NULL;
303  internalCameraObject = NULL;
304 #if defined(VISP_HAVE_SOWIN)
305  // mainWindow = ?;
306 #elif defined(VISP_HAVE_SOQT)
307  mainWindow = NULL;
308 #elif defined(VISP_HAVE_SOXT)
309  // mainWindow = ?;
310 #endif
311 
312 }
313 void
315 {
316  if (internalView !=NULL) {delete internalView ; internalView = NULL;}
317  if (externalView !=NULL) {delete externalView ; externalView = NULL;}
318  if (bufferView!=NULL) {delete[] bufferView ; bufferView = NULL;}
319  if (image_background != NULL) {
320  free (image_background);
321  image_background = NULL;
322  }
323 
324 }
325 
327  :
328 #if defined(VISP_HAVE_SOWIN)
329  mainWindow(),
330 #elif defined(VISP_HAVE_SOQT)
331  mainWindow(NULL),
332 #elif defined(VISP_HAVE_SOXT)
333  mainWindow(),
334 #endif
335  mainWindowInitialized(false), typeImage(vpSimulator::grayImage),
336  image_background(NULL), internalView(NULL), externalView(NULL),
337  mainThread(NULL), internal_width(0), internal_height(0),
338  external_width(0), external_height(0), scene(NULL), internalRoot(NULL),
339  externalRoot(NULL), internalCamera(NULL), externalCamera(NULL),
340  internalCameraPosition(NULL), extrenalCameraPosition(NULL), internalCameraObject(NULL),
341  zoomFactor(0.), cameraPositionInitialized(false), cMf(), internalCameraParameters(),
342  externalCameraParameters(), realtime(NULL), offScreenRenderer(NULL), bufferView(NULL),
343  get(0)
344 {
346 }
347 
349 {
351 }
352 
353 void
355 {
356  mainWindow = vpViewer::init("");
357  mainWindowInitialized = true ;
358 }
359 
360 void
362 {
363  this->scene = new SoSeparator;
364  this->internalRoot = new SoSeparator;
365  this->externalRoot = new SoSeparator;
366 
367  this->scene->ref();
368  this->internalRoot->ref();
369  this->externalRoot->ref();
370 
371  // define the camera SoPerspectiveCamera
372  this->internalCamera = new SoPerspectiveCamera ;
373  this->externalCamera = new SoPerspectiveCamera ;
374 
375 
376  this->internalCameraPosition = new SoTransform;
377  this->internalCameraObject = createCameraObject(zoomFactor);
378 
379  internalCamera->farDistance.setValue(100);
380  internalCamera->nearDistance.setValue(0.0001f);
381 
382 
383 
384  // link between camera and internal root
385  this->internalRoot->addChild (this->internalCamera);
386  this->internalRoot->addChild (this->scene);
387 
388  this->externalRoot->addChild (this->externalCamera);
389  this->externalRoot->addChild (this->scene);
390 
391 
392  SoSeparator * camera = new SoSeparator;
393  camera->ref();
394  camera->addChild (this->internalCameraPosition);
395  camera->addChild (this->internalCameraObject);
396  this->externalRoot->addChild (camera);
397 
398 
399  //this->externalRoot->addChild (internalCameraPosition);
400  // this->externalRoot->addChild (internalCameraObject);
401  SoCube *cube = new SoCube ;
402  cube->width=0.01f ;
403  cube->depth=0.01f ;
404  cube->height=0.01f ;
405 
406  this->externalRoot->addChild (cube);
407 
408  if (realtime==NULL)
409  {
410 
411  SoDB::enableRealTimeSensor(FALSE);
412  SoSceneManager::enableRealTimeUpdate(FALSE);
413  realtime = (SbTime *) SoDB::getGlobalField("realTime");
414  realtime->setValue(0.0);
415 
416  }
417 
418 
419 }
420 
421 
422 
429 void
430 vpSimulator::setZoomFactor (const float zoom)
431 {
432  zoomFactor = zoom;
433  static bool firstTime = true;
434  if(firstTime){
435  SoScale *taille = new SoScale;
436  taille->scaleFactor.setValue (zoomFactor, zoomFactor, zoomFactor);
437  this->scene->addChild(taille);
438  firstTime = false;
439  }
440  else{
441  SoScale * taille = (SoScale*)this->scene->getChild(0);
442  taille->scaleFactor.setValue (zoomFactor, zoomFactor, zoomFactor);
443  }
444 }
445 
463 void
464 vpSimulator::changeZoomFactor(const float zoomFactor, const int index)
465 {
466  SoScale * taille = (SoScale*)this->scene->getChild(index);
467  taille->scaleFactor.setValue (zoomFactor, zoomFactor, zoomFactor);
468 // this->setZoomFactor(zoomFactor);
469 }
470 
471 void
472 vpSimulator::initInternalViewer(const unsigned int width, const unsigned int height)
473 {
474  internal_width = width;
475  internal_height = height;
476 
477  if (mainWindowInitialized==false)
478  {
480  initSceneGraph() ;
481  }
482 
484 
485  // set the scene to render from this view
486  internalView->setSceneGraph(internalRoot);
487 
488  // set the title
489  internalView->setTitle("Internal camera view") ;
490 
491  //If the view mode is on, user events will be caught and used to influence
492  //the camera position / orientation. in this viewer we do not want that,
493  //we set it to false
494  internalView->setViewing(false);
495 
496  // Turn the viewer decorations
497  internalView->setDecoration(false) ;
498 
499  internalView->resize((int)width, (int)height, true) ;
500 
501  // open the window
502  internalView->show();
503 
504  bufferView = new unsigned char[3*width*height] ;
505 
506 }
507 
508 void
509 vpSimulator::initExternalViewer(const unsigned int width, const unsigned int height)
510 {
511 
512  external_width = width;
513  external_height = height;
514 
515  if (mainWindowInitialized==false)
516  {
518  initSceneGraph() ;
519  }
520 
522 
523  // set the scene to render this view
524  externalView->setSceneGraph(externalRoot);
525 
526  // set the title
527  externalView->setTitle("External View") ;
528  externalView->resize((int)width, (int)height, false) ;
529  // the goal here is to see all the scene and not to determine
530  // a manual viewpoint
531  externalView->viewAll ();
532 
533  // open the window
534  externalView->show();
535 }
536 
537 void
539 {
540  internalCameraParameters = _cam ;
541 
542 
543  float px = (float)_cam.get_px();
544  float py = (float)_cam.get_py();
545  float v = internal_height/(2.f*py);
546 
547  internalCamera->ref() ;
548  internalCamera->heightAngle = 2*atan(v);
549  internalCamera->aspectRatio=(internal_width/internal_height)*(px/py);
550  internalCamera->nearDistance = 0.001f ;
551 
552  internalCamera->farDistance = 1000;
553  internalCamera->unrefNoDelete() ;
554 }
555 
556 void
558 {
559 // SoPerspectiveCamera *camera ;
560 // camera = (SoPerspectiveCamera *)this->externalView->getCamera() ;
561  externalCameraParameters = _cam ;
562 
563  float px = (float)_cam.get_px();
564  float py = (float)_cam.get_py();
565  float v = external_height/(2*py);
566 
567  externalCamera->ref() ;
568  externalCamera->heightAngle = 2*atan(v);
569  externalCamera->aspectRatio=(external_width/external_height)*(px/py);
570  externalCamera->nearDistance = 0.001f ;
571  externalCamera->farDistance = 1000;
572  externalCamera->unrefNoDelete() ;
573 
574 }
575 
576 void
578 {
579 /* SoCamera *camera ;
580  camera = this->externalView->getCamera() ;*/
581  SoSFVec3f position = externalCamera->position ;
582 
583  // get the rotation
584  SoSFRotation orientation = externalCamera->orientation;
585  SbVec3f axis ; float angle ;
586  orientation.getValue(axis,angle) ;
587  SbRotation rotation(axis,angle) ;
588 
589  // get the translation
590  SbVec3f t ;
591  t = position.getValue() ;
592 
593  SbMatrix matrix ;
594  matrix.setRotate(rotation) ;
595 
596  vpHomogeneousMatrix fMc ;
597  SbMatrix rotX;
598  rotX.setRotate (SbRotation (SbVec3f(1.0f, 0.0f, 0.0f), (float)M_PI));
599  matrix.multLeft (rotX);
600  for(unsigned int i=0;i<4;i++)
601  for(unsigned int j=0;j<4;j++)
602  fMc[j][i]=matrix[(int)i][(int)j];
603  fMc[0][3] = t[0] ;
604  fMc[1][3] = t[1] ;
605  fMc[2][3] = t[2] ;
606 
607  cMf = fMc.inverse() ;
608 }
609 
610 
611 void
613 {
615  cMf = _cMf ;
616 }
617 void
619 {
620 
621  SbMatrix matrix;
622  SbRotation rotCam;
623  SbMatrix rotX;
624  rotX.setRotate (SbRotation (SbVec3f(1.0f, 0.0f, 0.0f), (float)M_PI));
625  for(unsigned int i=0;i<4;i++)
626  for(unsigned int j=0;j<4;j++)
627  matrix[(int)j][(int)i]=(float)cMf[i][j];
628 
629  matrix= matrix.inverse();
630  matrix.multLeft (rotX);
631  rotCam.setValue(matrix);
632 
633 
634  internalCamera->ref() ;
635  internalCamera->orientation.setValue(rotCam);
636  internalCamera->position.setValue(matrix[3][0],matrix[3][1],matrix[3][2]);
637  internalCamera->unref() ;
638 
639  rotX.setRotate (SbRotation (SbVec3f(-1.0f, 0.0f, 0.0f), (float)M_PI));
640  matrix.multLeft (rotX);
641  rotCam.setValue(matrix);
642  internalCameraPosition->ref() ;
643  internalCameraPosition->rotation.setValue(rotCam);
644  internalCameraPosition->translation.setValue(matrix[3][0],matrix[3][1],matrix[3][2]);
645  internalCameraPosition->unref() ;
646 }
647 
648 
652 void
654 {
655 
656  // if (this->cameraPositionInitialized==true)
657  {
658  if (this->externalView != NULL)
659  {
660  this->externalView->render() ; //call actualRedraw()
661  // vpHomogeneousMatrix c ;
662  // getExternalCameraPosition(c) ;
663  }
664  if (this->internalView != NULL)
665  {
666  this->moveInternalCamera(this->cMf) ;
667  this->internalView->render() ; //call actualRedraw()
668  }
669  }
670 }
671 
672 // This function is called 20 times each second.
673 static void
674 timerSensorCallback(void *data , SoSensor *)
675 {
676  vpSimulator * simulator = (vpSimulator *)data ;
677 
678  simulator->redraw() ;
679 
680 }
681 
682 
683 void
685 {
686  if (mainWindowInitialized==false)
687  {
688  vpERROR_TRACE("main window is not opened ") ;
689  }
690 
691  vpTime::wait(1000) ;
692 
693  // Timer sensor
694  SoTimerSensor * timer = new SoTimerSensor(timerSensorCallback, (void *)this);
695  timer->setInterval(0.01);
696  timer->schedule();
697  vpViewer::mainLoop() ;
698 }
699 
700 
701 //-----------------------------------------------------------------
702 // scene stuff
703 //-----------------------------------------------------------------
704 
706 void
707 vpSimulator::load(const char *file_name)
708 {
709 
710  SoInput input;
711  if (!input.openFile(file_name))
712  {
713  vpERROR_TRACE("Erreur cannot open file %s",file_name);
714  }
715 
716  SoSeparator *newscene=SoDB::readAll(&input);
717  newscene->ref() ;
718  if (newscene==NULL)
719  {
720  vpERROR_TRACE("Error while reading %s",file_name);
721  }
722 
723  SoScale *taille = new SoScale;
724  taille->scaleFactor.setValue (zoomFactor, zoomFactor, zoomFactor);
725 
726 // newscene->addChild(taille);
727 
728 // std::cout << "this->scene->getNumChildren() = " << this->scene->getNumChildren() << std::endl;
729 
730  this->scene->addChild(taille);
731  this->scene->addChild(newscene);
732  newscene->unref() ;
733 
734 }
735 
736 
737 void
738 vpSimulator::save(const char *name,bool binary)
739 {
740  // get a pointer to the object "name"
741  SoOutput output ;
742  output.openFile(name) ;
743 
744  if (binary==true) output.setBinary(TRUE) ;
745 
746  SoWriteAction writeAction(&output) ;
747  writeAction.apply(scene) ;
748  output.closeFile() ;
749 
750 }
751 
757 void
759 {
760 
761  SoScale *taille = new SoScale;
762  taille->scaleFactor.setValue (zoom, zoom, zoom);
763 
764  SoSeparator * frame = new SoSeparator;
765  frame->ref();
766  frame->addChild(taille);
767  frame->addChild(createFrame (LONGUEUR_FLECHE*zoom, PROPORTION_FLECHE*zoom, RAYON_FLECHE*zoom));
768  this->addObject(frame, fMo, externalRoot) ;
769  // frame->unref();
770 }
771 
777 void
779 {
780  scene->addChild(createFrame (LONGUEUR_FLECHE*zoom, PROPORTION_FLECHE*zoom, RAYON_FLECHE*zoom)) ;
781 }
782 
788 void
789 vpSimulator::load(const char * iv_filename,const vpHomogeneousMatrix &fMo)
790 {
791 
792  SoInput in;
793  SoSeparator * newObject;
794 
795  if (! in.openFile (iv_filename))
796  {
797  vpERROR_TRACE ("Erreur lors de la lecture du fichier %s.", iv_filename);
798  }
799 
800  newObject = SoDB::readAll (&in);
801  if (NULL == newObject)
802  {
803  vpERROR_TRACE ("Problem reading data for file <%s>.", iv_filename);
804  }
805 
806  try
807  {
808  this->addObject (newObject, fMo) ;
809  }
810  catch(...)
811  {
812  vpERROR_TRACE("Error adding object from file <%s> ",iv_filename) ;
813  throw ;
814  }
815 
816 }
817 
818 
824 void
825 vpSimulator::addObject(SoSeparator * newObject, const vpHomogeneousMatrix &fMo)
826 {
827  try
828  {
829  this->addObject(newObject, fMo , scene);
830  }
831  catch(...)
832  {
833  vpERROR_TRACE("Error adding object in scene graph ") ;
834  throw ;
835  }
836 }
837 
838 
839 
840 
841 
849 void
850 vpSimulator::addObject(SoSeparator * object,
851  const vpHomogeneousMatrix &fMo,
852  SoSeparator * root)
853 {
854 
855  bool identity = true ;
856  for (unsigned int i=0 ; i <4 ;i++){
857  for (unsigned int j=0 ; j < 4 ; j++){
858  if (i==j){
859  if (fabs(fMo[i][j] -1) > 1e-6) identity=false ;
860  }
861  else{
862  if (fabs(fMo[i][j]) > 1e-6) identity=false ;
863  }
864  }
865  }
866 
867  if (identity==true)
868  {
869  root->addChild (object);
870  }
871  else
872  {
873  SbMatrix matrix;
874  SbRotation rotation;
875  for(unsigned int i=0;i<4;i++)
876  for(unsigned int j=0;j<4;j++)
877  matrix[(int)j][(int)i]=(float)fMo[i][j];
878 
879  // matrix= matrix.inverse();
880  rotation.setValue(matrix);
881 
882  SoTransform *displacement = new SoTransform;
883  SoSeparator *newNode = new SoSeparator;
884 
885  displacement->rotation.setValue(rotation);
886  displacement->translation.setValue(matrix[3][0],
887  matrix[3][1],
888  matrix[3][2]);
889 
890  root->addChild (newNode);
891  newNode->addChild (displacement);
892  newNode->addChild (object);
893 
894  }
895 }
896 
897 
899 void
900 vpSimulator::initApplication(void *(*start_routine)(void *))
901 {
902  //pthread_create (&mainThread, NULL, start_routine, (void *)this);
903  mainThread = SbThread::create (start_routine, (void *)this);
904 }
905 
915 void
916 vpSimulator::initApplication(void *(*start_routine)(void *), void* data)
917 {
918  mainThread = SbThread::create (start_routine, (void *)data);
919 }
920 
923 void
925 {
926  //pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL );
927  //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
928  vpTime::wait(1000) ;
929 }
932 void
934 {
935  vpViewer::exitMainLoop() ;
936  //pthread_exit (NULL);
937 }
938 
939 
940 
941 
942 
943 /* Initialise le SoOffScreenRenderer si necessaire, puis realise le rendu.
944  * Quand la fonction rend la main, le buffer est pret et n'a plus qu'a etre
945  * enregistre ou passe a l'utilisateur.
946  * INPUT:
947  * - vueInterne est vrai ssi il faut rendre la vue interne, faux ssi
948  * il faut rendre la vue externe.
949  * OUTPUT:
950  * - width : largeur de l'image dans le buffer.
951  * - height : hauteur de l'image dans le buffer.
952  */
953 void
954 vpSimulator::offScreenRendering(vpSimulatorViewType view, int * width, int * height)
955 {
956 
957  SbVec2s size(320,200);
958  SoNode * thisroot;
959 
960  {
961  if (view==vpSimulator::INTERNAL)
962  {
963  size = this ->internalView ->getViewportRegion().getWindowSize();
964  thisroot = this ->internalView->getSceneManager()->getSceneGraph() ;
965  }
966  else
967  {
968  size = this ->externalView ->getViewportRegion().getWindowSize();
969  thisroot = this ->externalView->getSceneManager()->getSceneGraph() ;
970  }
971  }
972  SbViewportRegion myViewPort(size);
973 
974  // Creation du rendu si necessaire.
975  if (NULL == this ->offScreenRenderer)
976  {
977  //Init du SoOffscreenRenderer
978  this ->offScreenRenderer = new SoOffscreenRenderer(myViewPort);
979  }
980  else
981  {
982  // Redefini le view port
983  this ->offScreenRenderer ->setViewportRegion (myViewPort);
984  }
985 
986  // Rendu offscreen
987  if (! this ->offScreenRenderer ->render(thisroot))
988  {
989  vpERROR_TRACE("La scene n'a pas pu etre rendue offscreen.");
990  delete this ->offScreenRenderer;
991  this ->offScreenRenderer = NULL;
992  }
993  else
994  {
995 
996 
997  /*
998  if (view==vpSimulator::INTERNAL)
999  {
1000  //Recopie du buffer contenant l'image, dans bufferView
1001  int length = 3*size [0]*size[1];
1002  delete [] bufferView;
1003  bufferView = new unsigned char [length];
1004  for(int i=0; i<length; i++)
1005  {
1006  bufferView[i] = this ->offScreenRenderer->getBuffer()[i];
1007  }
1008  }*/
1009 
1010  }
1011 
1012  // exit(1) ;
1013  if (NULL != width) { * width = size [0]; }
1014  if (NULL != height) { * height = size [1]; }
1015 
1016 
1017 }
1018 
1019 
1020 /* Enregistre l'image de vue interne ou externe dans un fichier RGB.
1021  * Effectue le rendu dans un buffer plutot qu'a l'ecran, puis sauvegarde
1022  * ce buffer au format PS (copie directe).
1023  * INPUT
1024  * - fileName: nom du fichier dans lequel placer le resultat.
1025  * OUTPUT
1026  * - RETURN : Code d'erreur CODE_OK si tout s'est bien passe.
1027  */
1028 
1029 void
1030 vpSimulator::write (const char * fileName)
1031 {
1032 
1033  while (get==0) { vpTRACE("%d ",get); }
1034  get =2 ;
1035  /* FILE *fp = fopen(fileName, "w");
1036  fprintf(fp,"P6 \n %d %d \n 255",internal_width,internal_height) ;
1037  fwrite(bufferView, sizeof(unsigned char), internal_width*internal_height*3, fp) ;*/
1039 
1040 
1041  for(unsigned int i=0 ; i < internal_height ; i++)
1042  for(unsigned int j=0 ; j < internal_width ; j++)
1043  {
1044  unsigned char r,g,b ;
1045  unsigned int index = 3*((internal_height-i-1)* internal_width + j );
1046  r = *(bufferView+index);
1047  g = *(bufferView+index+1);
1048  b = *(bufferView+index+2);
1049  I[i][j].R =r ;
1050  I[i][j].G =g ;
1051  I[i][j].B =b ;
1052  }
1053  vpImageIo::write(I,fileName) ;
1054  // fclose (fp);
1055  get =1 ;
1056 }
1057 
1058 void
1059 vpSimulator::getSizeInternalView(int& width, int& height)
1060 {
1061  SbVec2s size = this ->internalView ->getViewportRegion().getWindowSize();
1062  width = size [0];
1063  height = size[1];
1064 }
1065 
1071 void
1073 {
1074  //while (get==0) {;}
1075  get =2 ;
1078  get =1 ;
1079 }
1080 
1085 void
1087 {
1088  //while (get==0) {;}
1089  get =2 ;
1092  get =1 ;
1093 }
1094 
1095 #endif
1096 
1097 /*
1098  * Local variables:
1099  * c-basic-offset: 2
1100  * End:
1101  */
HWND mainWindow
main Widget
Definition: vpSimulator.h:118
SoSeparator * externalRoot
root node of the external view
Definition: vpSimulator.h:195
static void write(const vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:476
#define vpDEBUG_TRACE
Definition: vpDebug.h:482
virtual void initInternalViewer(const unsigned int nlig, const unsigned int ncol)
initialize the camera view
void resize(int x, int y, bool fixed=false)
Definition: vpViewer.cpp:148
void changeZoomFactor(const float zoom, const int index)
Change the zoom factor associated to the child given by index. In order to create multiple zoom facto...
SoPerspectiveCamera * internalCamera
internal camera
Definition: vpSimulator.h:198
bool cameraPositionInitialized
Definition: vpSimulator.h:244
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
void write(const char *fileName)
SoTransform * internalCameraPosition
internal camera position
Definition: vpSimulator.h:203
void kill()
perform some destruction
void setExternalCameraParameters(vpCameraParameters &cam)
set external camera parameters
void setCameraPosition(vpHomogeneousMatrix &cMf)
set the camera position (from an homogeneous matrix)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpERROR_TRACE
Definition: vpDebug.h:395
void addObject(SoSeparator *object, const vpHomogeneousMatrix &fMo, SoSeparator *root)
Add a new object in the scene graph ad a given location.
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
#define vpTRACE
Definition: vpDebug.h:418
Type * bitmap
points toward the bitmap
Definition: vpImage.h:120
Implementation of a simulator based on Coin3d (www.coin3d.org).
Definition: vpSimulator.h:102
vpCameraParameters internalCameraParameters
internal camera parameters
Definition: vpSimulator.h:248
void closeMainApplication()
void getSizeInternalView(int &width, int &height)
get the size of the internal view
void addAbsoluteFrame(float zoom=1)
Add the representation of the absolute frame.
unsigned int external_height
Definition: vpSimulator.h:172
void getExternalCameraPosition(vpHomogeneousMatrix &cMf)
get the external camera position
double get_py() const
void init()
perform some initialization
virtual void mainLoop()
activate the mainloop
static int wait(double t0, double t)
Definition: vpTime.cpp:149
bool mainWindowInitialized
Definition: vpSimulator.h:125
vpViewer * internalView
view from the camera
Definition: vpSimulator.h:143
void moveInternalCamera(vpHomogeneousMatrix &cMf)
modify the position of the camera in the scene graph
vpImageType typeImage
Definition: vpSimulator.h:135
SoSeparator * scene
Definition: vpSimulator.h:191
void getInternalImage(vpImage< unsigned char > &I)
get an Image of the internal view
SoSeparator * internalRoot
root node of the internal view
Definition: vpSimulator.h:193
vpCameraParameters externalCameraParameters
internal camera parameters
Definition: vpSimulator.h:250
SbTime * realtime
Definition: vpSimulator.h:277
void initApplication(void *(*start_routine)(void *))
begin the main program
SoTransform * extrenalCameraPosition
external camera position
Definition: vpSimulator.h:206
GLubyte * image_background
Definition: vpSimulator.h:137
void setInternalCameraParameters(vpCameraParameters &cam)
set internal camera parameters
Viewer used by the simulator.
Definition: vpViewer.h:120
Generic class defining intrinsic camera parameters.
void resize(const unsigned int h, const unsigned int w)
set the size of the image without initializing it.
Definition: vpImage.h:536
void initSceneGraph()
initialize the scene graph
void load(const char *file_name)
load an iv file
void offScreenRendering(vpSimulatorViewType view=vpSimulator::EXTERNAL, int *width=NULL, int *height=NULL)
double get_px() const
vpViewer * externalView
view from an external camera
Definition: vpSimulator.h:145
void initSoApplication()
open the SoGui application
SoPerspectiveCamera * externalCamera
external camera
Definition: vpSimulator.h:200
unsigned int external_width
Definition: vpSimulator.h:171
vpHomogeneousMatrix cMf
internal camera position
Definition: vpSimulator.h:246
void initMainApplication()
perform some initialization in the main program thread
void addFrame(const vpHomogeneousMatrix &fMo, float zoom=1)
Add the representation of a frame.
unsigned char * bufferView
image of the internal view
Definition: vpSimulator.h:284
unsigned int internal_width
Definition: vpSimulator.h:169
vpHomogeneousMatrix inverse() const
vpSimulator()
constructor
void redraw()
display the scene (handle with care)
void initExternalViewer(const unsigned int nlig, const unsigned int ncol)
initialize the external view
SoOffscreenRenderer * offScreenRenderer
Definition: vpSimulator.h:278
void setZoomFactor(const float zoom)
set the size of the camera/frame
virtual ~vpSimulator()
unsigned int internal_height
Definition: vpSimulator.h:170
void save(const char *name, bool binary=false)
save the scene in an iv file
float zoomFactor
Definition: vpSimulator.h:240
SoSeparator * internalCameraObject
representation of the camera in the external view
Definition: vpSimulator.h:209
SbThread * mainThread
thread with the main program
Definition: vpSimulator.h:155