ViSP  2.9.0
vpSimulator.cpp
1 /****************************************************************************
2  *
3  * $Id: vpSimulator.cpp 4574 2014-01-09 08:48:51Z 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 {
329 }
330 
332 {
334 }
335 
336 void
338 {
339  mainWindow = vpViewer::init("");
340  mainWindowInitialized = true ;
341 }
342 
343 void
345 {
346  this->scene = new SoSeparator;
347  this->internalRoot = new SoSeparator;
348  this->externalRoot = new SoSeparator;
349 
350  this->scene->ref();
351  this->internalRoot->ref();
352  this->externalRoot->ref();
353 
354  // define the camera SoPerspectiveCamera
355  this->internalCamera = new SoPerspectiveCamera ;
356  this->externalCamera = new SoPerspectiveCamera ;
357 
358 
359  this->internalCameraPosition = new SoTransform;
360  this->internalCameraObject = createCameraObject(zoomFactor);
361 
362  internalCamera->farDistance.setValue(100);
363  internalCamera->nearDistance.setValue(0.0001f);
364 
365 
366 
367  // link between camera and internal root
368  this->internalRoot->addChild (this->internalCamera);
369  this->internalRoot->addChild (this->scene);
370 
371  this->externalRoot->addChild (this->externalCamera);
372  this->externalRoot->addChild (this->scene);
373 
374 
375  SoSeparator * camera = new SoSeparator;
376  camera->ref();
377  camera->addChild (this->internalCameraPosition);
378  camera->addChild (this->internalCameraObject);
379  this->externalRoot->addChild (camera);
380 
381 
382  //this->externalRoot->addChild (internalCameraPosition);
383  // this->externalRoot->addChild (internalCameraObject);
384  SoCube *cube = new SoCube ;
385  cube->width=0.01f ;
386  cube->depth=0.01f ;
387  cube->height=0.01f ;
388 
389  this->externalRoot->addChild (cube);
390 
391  if (realtime==NULL)
392  {
393 
394  SoDB::enableRealTimeSensor(FALSE);
395  SoSceneManager::enableRealTimeUpdate(FALSE);
396  realtime = (SbTime *) SoDB::getGlobalField("realTime");
397  realtime->setValue(0.0);
398 
399  }
400 
401 
402 }
403 
404 
405 
412 void
413 vpSimulator::setZoomFactor (const float zoom)
414 {
415  zoomFactor = zoom;
416  static bool firstTime = true;
417  if(firstTime){
418  SoScale *taille = new SoScale;
419  taille->scaleFactor.setValue (zoomFactor, zoomFactor, zoomFactor);
420  this->scene->addChild(taille);
421  firstTime = false;
422  }
423  else{
424  SoScale * taille = (SoScale*)this->scene->getChild(0);
425  taille->scaleFactor.setValue (zoomFactor, zoomFactor, zoomFactor);
426  }
427 }
428 
446 void
447 vpSimulator::changeZoomFactor(const float zoomFactor, const int index)
448 {
449  SoScale * taille = (SoScale*)this->scene->getChild(index);
450  taille->scaleFactor.setValue (zoomFactor, zoomFactor, zoomFactor);
451 // this->setZoomFactor(zoomFactor);
452 }
453 
454 void
455 vpSimulator::initInternalViewer(const unsigned int width, const unsigned int height)
456 {
457  internal_width = width;
458  internal_height = height;
459 
460  if (mainWindowInitialized==false)
461  {
463  initSceneGraph() ;
464  }
465 
467 
468  // set the scene to render from this view
469  internalView->setSceneGraph(internalRoot);
470 
471  // set the title
472  internalView->setTitle("Internal camera view") ;
473 
474  //If the view mode is on, user events will be caught and used to influence
475  //the camera position / orientation. in this viewer we do not want that,
476  //we set it to false
477  internalView->setViewing(false);
478 
479  // Turn the viewer decorations
480  internalView->setDecoration(false) ;
481 
482  internalView->resize((int)width, (int)height, true) ;
483 
484  // open the window
485  internalView->show();
486 
487  bufferView = new unsigned char[3*width*height] ;
488 
489 }
490 
491 void
492 vpSimulator::initExternalViewer(const unsigned int width, const unsigned int height)
493 {
494 
495  external_width = width;
496  external_height = height;
497 
498  if (mainWindowInitialized==false)
499  {
501  initSceneGraph() ;
502  }
503 
505 
506  // set the scene to render this view
507  externalView->setSceneGraph(externalRoot);
508 
509  // set the title
510  externalView->setTitle("External View") ;
511  externalView->resize((int)width, (int)height, false) ;
512  // the goal here is to see all the scene and not to determine
513  // a manual viewpoint
514  externalView->viewAll ();
515 
516  // open the window
517  externalView->show();
518 }
519 
520 void
522 {
523  internalCameraParameters = _cam ;
524 
525 
526  float px = (float)_cam.get_px();
527  float py = (float)_cam.get_py();
528  float v = internal_height/(2.f*py);
529 
530  internalCamera->ref() ;
531  internalCamera->heightAngle = 2*atan(v);
532  internalCamera->aspectRatio=(internal_width/internal_height)*(px/py);
533  internalCamera->nearDistance = 0.001f ;
534 
535  internalCamera->farDistance = 1000;
536  internalCamera->unrefNoDelete() ;
537 }
538 
539 void
541 {
542 // SoPerspectiveCamera *camera ;
543 // camera = (SoPerspectiveCamera *)this->externalView->getCamera() ;
544  externalCameraParameters = _cam ;
545 
546  float px = (float)_cam.get_px();
547  float py = (float)_cam.get_py();
548  float v = external_height/(2*py);
549 
550  externalCamera->ref() ;
551  externalCamera->heightAngle = 2*atan(v);
552  externalCamera->aspectRatio=(external_width/external_height)*(px/py);
553  externalCamera->nearDistance = 0.001f ;
554  externalCamera->farDistance = 1000;
555  externalCamera->unrefNoDelete() ;
556 
557 }
558 
559 void
561 {
562 /* SoCamera *camera ;
563  camera = this->externalView->getCamera() ;*/
564  SoSFVec3f position = externalCamera->position ;
565 
566  // get the rotation
567  SoSFRotation orientation = externalCamera->orientation;
568  SbVec3f axis ; float angle ;
569  orientation.getValue(axis,angle) ;
570  SbRotation rotation(axis,angle) ;
571 
572  // get the translation
573  SbVec3f t ;
574  t = position.getValue() ;
575 
576  SbMatrix matrix ;
577  matrix.setRotate(rotation) ;
578 
579  vpHomogeneousMatrix fMc ;
580  SbMatrix rotX;
581  rotX.setRotate (SbRotation (SbVec3f(1.0f, 0.0f, 0.0f), (float)M_PI));
582  matrix.multLeft (rotX);
583  for(unsigned int i=0;i<4;i++)
584  for(unsigned int j=0;j<4;j++)
585  fMc[j][i]=matrix[(int)i][(int)j];
586  fMc[0][3] = t[0] ;
587  fMc[1][3] = t[1] ;
588  fMc[2][3] = t[2] ;
589 
590  cMf = fMc.inverse() ;
591 }
592 
593 
594 void
596 {
598  cMf = _cMf ;
599 }
600 void
602 {
603 
604  SbMatrix matrix;
605  SbRotation rotCam;
606  SbMatrix rotX;
607  rotX.setRotate (SbRotation (SbVec3f(1.0f, 0.0f, 0.0f), (float)M_PI));
608  for(unsigned int i=0;i<4;i++)
609  for(unsigned int j=0;j<4;j++)
610  matrix[(int)j][(int)i]=(float)cMf[i][j];
611 
612  matrix= matrix.inverse();
613  matrix.multLeft (rotX);
614  rotCam.setValue(matrix);
615 
616 
617  internalCamera->ref() ;
618  internalCamera->orientation.setValue(rotCam);
619  internalCamera->position.setValue(matrix[3][0],matrix[3][1],matrix[3][2]);
620  internalCamera->unref() ;
621 
622  rotX.setRotate (SbRotation (SbVec3f(-1.0f, 0.0f, 0.0f), (float)M_PI));
623  matrix.multLeft (rotX);
624  rotCam.setValue(matrix);
625  internalCameraPosition->ref() ;
626  internalCameraPosition->rotation.setValue(rotCam);
627  internalCameraPosition->translation.setValue(matrix[3][0],matrix[3][1],matrix[3][2]);
628  internalCameraPosition->unref() ;
629 }
630 
631 
635 void
637 {
638 
639  // if (this->cameraPositionInitialized==true)
640  {
641  if (this->externalView != NULL)
642  {
643  this->externalView->render() ; //call actualRedraw()
644  // vpHomogeneousMatrix c ;
645  // getExternalCameraPosition(c) ;
646  }
647  if (this->internalView != NULL)
648  {
649  this->moveInternalCamera(this->cMf) ;
650  this->internalView->render() ; //call actualRedraw()
651  }
652  }
653 }
654 
655 // This function is called 20 times each second.
656 static void
657 timerSensorCallback(void *data , SoSensor *)
658 {
659  vpSimulator * simulator = (vpSimulator *)data ;
660 
661  simulator->redraw() ;
662 
663 }
664 
665 
666 void
668 {
669  if (mainWindowInitialized==false)
670  {
671  vpERROR_TRACE("main window is not opened ") ;
672  }
673 
674  vpTime::wait(1000) ;
675 
676  // Timer sensor
677  SoTimerSensor * timer = new SoTimerSensor(timerSensorCallback, (void *)this);
678  timer->setInterval(0.01);
679  timer->schedule();
680  vpViewer::mainLoop() ;
681 }
682 
683 
684 //-----------------------------------------------------------------
685 // scene stuff
686 //-----------------------------------------------------------------
687 
689 void
690 vpSimulator::load(const char *file_name)
691 {
692 
693  SoInput input;
694  if (!input.openFile(file_name))
695  {
696  vpERROR_TRACE("Erreur cannot open file %s",file_name);
697  }
698 
699  SoSeparator *newscene=SoDB::readAll(&input);
700  newscene->ref() ;
701  if (newscene==NULL)
702  {
703  vpERROR_TRACE("Error while reading %s",file_name);
704  }
705 
706  SoScale *taille = new SoScale;
707  taille->scaleFactor.setValue (zoomFactor, zoomFactor, zoomFactor);
708 
709 // newscene->addChild(taille);
710 
711 // std::cout << "this->scene->getNumChildren() = " << this->scene->getNumChildren() << std::endl;
712 
713  this->scene->addChild(taille);
714  this->scene->addChild(newscene);
715  newscene->unref() ;
716 
717 }
718 
719 
720 void
721 vpSimulator::save(const char *name,bool binary)
722 {
723  // get a pointer to the object "name"
724  SoOutput output ;
725  output.openFile(name) ;
726 
727  if (binary==true) output.setBinary(TRUE) ;
728 
729  SoWriteAction writeAction(&output) ;
730  writeAction.apply(scene) ;
731  output.closeFile() ;
732 
733 }
734 
740 void
742 {
743 
744  SoScale *taille = new SoScale;
745  taille->scaleFactor.setValue (zoom, zoom, zoom);
746 
747  SoSeparator * frame = new SoSeparator;
748  frame->ref();
749  frame->addChild(taille);
750  frame->addChild(createFrame (LONGUEUR_FLECHE*zoom, PROPORTION_FLECHE*zoom, RAYON_FLECHE*zoom));
751  this->addObject(frame, fMo, externalRoot) ;
752  // frame->unref();
753 }
754 
760 void
762 {
763  scene->addChild(createFrame (LONGUEUR_FLECHE*zoom, PROPORTION_FLECHE*zoom, RAYON_FLECHE*zoom)) ;
764 }
765 
771 void
772 vpSimulator::load(const char * iv_filename,const vpHomogeneousMatrix &fMo)
773 {
774 
775  SoInput in;
776  SoSeparator * newObject;
777 
778  if (! in.openFile (iv_filename))
779  {
780  vpERROR_TRACE ("Erreur lors de la lecture du fichier %s.", iv_filename);
781  }
782 
783  newObject = SoDB::readAll (&in);
784  if (NULL == newObject)
785  {
786  vpERROR_TRACE ("Problem reading data for file <%s>.", iv_filename);
787  }
788 
789  try
790  {
791  this->addObject (newObject, fMo) ;
792  }
793  catch(...)
794  {
795  vpERROR_TRACE("Error adding object from file <%s> ",iv_filename) ;
796  throw ;
797  }
798 
799 }
800 
801 
807 void
808 vpSimulator::addObject(SoSeparator * newObject, const vpHomogeneousMatrix &fMo)
809 {
810  try
811  {
812  this->addObject(newObject, fMo , scene);
813  }
814  catch(...)
815  {
816  vpERROR_TRACE("Error adding object in scene graph ") ;
817  throw ;
818  }
819 }
820 
821 
822 
823 
824 
832 void
833 vpSimulator::addObject(SoSeparator * object,
834  const vpHomogeneousMatrix &fMo,
835  SoSeparator * root)
836 {
837 
838  bool identity = true ;
839  for (unsigned int i=0 ; i <4 ;i++){
840  for (unsigned int j=0 ; j < 4 ; j++){
841  if (i==j){
842  if (fabs(fMo[i][j] -1) > 1e-6) identity=false ;
843  }
844  else{
845  if (fabs(fMo[i][j]) > 1e-6) identity=false ;
846  }
847  }
848  }
849 
850  if (identity==true)
851  {
852  vpTRACE("identity ") ;
853  root->addChild (object);
854  }
855  else
856  {
857  SbMatrix matrix;
858  SbRotation rotation;
859  for(unsigned int i=0;i<4;i++)
860  for(unsigned int j=0;j<4;j++)
861  matrix[(int)j][(int)i]=(float)fMo[i][j];
862 
863  // matrix= matrix.inverse();
864  rotation.setValue(matrix);
865 
866  SoTransform *displacement = new SoTransform;
867  SoSeparator *newNode = new SoSeparator;
868 
869  displacement->rotation.setValue(rotation);
870  displacement->translation.setValue(matrix[3][0],
871  matrix[3][1],
872  matrix[3][2]);
873 
874  root->addChild (newNode);
875  newNode->addChild (displacement);
876  newNode->addChild (object);
877 
878  }
879 }
880 
881 
883 void
884 vpSimulator::initApplication(void *(*start_routine)(void *))
885 {
886  //pthread_create (&mainThread, NULL, start_routine, (void *)this);
887  mainThread = SbThread::create (start_routine, (void *)this);
888 }
889 
899 void
900 vpSimulator::initApplication(void *(*start_routine)(void *), void* data)
901 {
902  mainThread = SbThread::create (start_routine, (void *)data);
903 }
904 
907 void
909 {
910  //pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL );
911  //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
912  vpTime::wait(1000) ;
913 }
916 void
918 {
919  vpViewer::exitMainLoop() ;
920  //pthread_exit (NULL);
921 }
922 
923 
924 
925 
926 
927 /* Initialise le SoOffScreenRenderer si necessaire, puis realise le rendu.
928  * Quand la fonction rend la main, le buffer est pret et n'a plus qu'a etre
929  * enregistre ou passe a l'utilisateur.
930  * INPUT:
931  * - vueInterne est vrai ssi il faut rendre la vue interne, faux ssi
932  * il faut rendre la vue externe.
933  * OUTPUT:
934  * - width : largeur de l'image dans le buffer.
935  * - height : hauteur de l'image dans le buffer.
936  */
937 void
938 vpSimulator::offScreenRendering(vpSimulatorViewType view, int * width, int * height)
939 {
940 
941  SbVec2s size(320,200);
942  SoNode * thisroot;
943 
944  {
945  if (view==vpSimulator::INTERNAL)
946  {
947  size = this ->internalView ->getViewportRegion().getWindowSize();
948  thisroot = this ->internalView->getSceneManager()->getSceneGraph() ;
949  }
950  else
951  {
952  size = this ->externalView ->getViewportRegion().getWindowSize();
953  thisroot = this ->externalView->getSceneManager()->getSceneGraph() ;
954  }
955  }
956  SbViewportRegion myViewPort(size);
957 
958  // Creation du rendu si necessaire.
959  if (NULL == this ->offScreenRenderer)
960  {
961  //Init du SoOffscreenRenderer
962  this ->offScreenRenderer = new SoOffscreenRenderer(myViewPort);
963  }
964  else
965  {
966  // Redefini le view port
967  this ->offScreenRenderer ->setViewportRegion (myViewPort);
968  }
969 
970  // Rendu offscreen
971  if (! this ->offScreenRenderer ->render(thisroot))
972  {
973  vpERROR_TRACE("La scene n'a pas pu etre rendue offscreen.");
974  delete this ->offScreenRenderer;
975  this ->offScreenRenderer = NULL;
976  }
977  else
978  {
979 
980 
981  /*
982  if (view==vpSimulator::INTERNAL)
983  {
984  //Recopie du buffer contenant l'image, dans bufferView
985  int length = 3*size [0]*size[1];
986  delete [] bufferView;
987  bufferView = new unsigned char [length];
988  for(int i=0; i<length; i++)
989  {
990  bufferView[i] = this ->offScreenRenderer->getBuffer()[i];
991  }
992  }*/
993 
994  }
995 
996  // exit(1) ;
997  if (NULL != width) { * width = size [0]; }
998  if (NULL != height) { * height = size [1]; }
999 
1000 
1001 }
1002 
1003 
1004 /* Enregistre l'image de vue interne ou externe dans un fichier RGB.
1005  * Effectue le rendu dans un buffer plutot qu'a l'ecran, puis sauvegarde
1006  * ce buffer au format PS (copie directe).
1007  * INPUT
1008  * - fileName: nom du fichier dans lequel placer le resultat.
1009  * OUTPUT
1010  * - RETURN : Code d'erreur CODE_OK si tout s'est bien passe.
1011  */
1012 
1013 void
1014 vpSimulator::write (const char * fileName)
1015 {
1016 
1017  while (get==0) { vpTRACE("%d ",get); }
1018  get =2 ;
1019  /* FILE *fp = fopen(fileName, "w");
1020  fprintf(fp,"P6 \n %d %d \n 255",internal_width,internal_height) ;
1021  fwrite(bufferView, sizeof(unsigned char), internal_width*internal_height*3, fp) ;*/
1023 
1024 
1025  for(unsigned int i=0 ; i < internal_height ; i++)
1026  for(unsigned int j=0 ; j < internal_width ; j++)
1027  {
1028  unsigned char r,g,b ;
1029  unsigned int index = 3*((internal_height-i-1)* internal_width + j );
1030  r = *(bufferView+index);
1031  g = *(bufferView+index+1);
1032  b = *(bufferView+index+2);
1033  I[i][j].R =r ;
1034  I[i][j].G =g ;
1035  I[i][j].B =b ;
1036  }
1037  vpImageIo::write(I,fileName) ;
1038  // fclose (fp);
1039  get =1 ;
1040 }
1041 
1042 void
1043 vpSimulator::getSizeInternalView(int& width, int& height)
1044 {
1045  SbVec2s size = this ->internalView ->getViewportRegion().getWindowSize();
1046  width = size [0];
1047  height = size[1];
1048 }
1049 
1055 void
1057 {
1058  //while (get==0) {;}
1059  get =2 ;
1062  get =1 ;
1063 }
1064 
1069 void
1071 {
1072  //while (get==0) {;}
1073  get =2 ;
1076  get =1 ;
1077 }
1078 
1079 #endif
1080 
1081 /*
1082  * Local variables:
1083  * c-basic-offset: 2
1084  * End:
1085  */
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:452
#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
Definition: vpImage.h:532
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