39 #include <visp3/core/vpConfig.h>
41 #ifdef VISP_HAVE_COIN3D_AND_GUI
43 #include <visp3/ar/vpSimulator.h>
44 #include <visp3/core/vpDebug.h>
45 #include <visp3/core/vpTime.h>
47 #include <visp3/core/vpImage.h>
49 #ifdef VISP_HAVE_MODULE_IO
50 #include <visp3/io/vpImageIo.h>
54 #include <Inventor/nodes/SoCone.h>
55 #include <Inventor/nodes/SoCoordinate3.h>
56 #include <Inventor/nodes/SoCylinder.h>
57 #include <Inventor/nodes/SoIndexedFaceSet.h>
58 #include <Inventor/nodes/SoPointLight.h>
59 #include <Inventor/nodes/SoRotationXYZ.h>
60 #include <Inventor/nodes/SoScale.h>
61 #include <Inventor/nodes/SoTranslation.h>
63 #include <Inventor/actions/SoWriteAction.h>
64 #include <Inventor/nodes/SoDirectionalLight.h>
65 #include <Inventor/nodes/SoDrawStyle.h>
66 #include <Inventor/nodes/SoEnvironment.h>
67 #include <Inventor/nodes/SoGroup.h>
68 #include <Inventor/nodes/SoMaterial.h>
73 static float pyramidVertexes[5][3] = { {0.33f, 0.33f, 0.f},
75 {-0.33f, -0.33f, 0.f},
80 static int32_t pyramidFaces[] = {
106 SoSeparator *makePyramide()
108 SoSeparator *result =
new SoSeparator;
112 SoCoordinate3 *myCoords =
new SoCoordinate3;
113 myCoords->point.setValues(0, 5, pyramidVertexes);
114 result->addChild(myCoords);
117 SoIndexedFaceSet *myFaceSet =
new SoIndexedFaceSet;
118 myFaceSet->coordIndex.setValues(0, 21, (
const int32_t *)pyramidFaces);
119 result->addChild(myFaceSet);
121 result->unrefNoDelete();
131 static SoSeparator *createArrow(
float longueur,
float proportionFleche,
float radius)
133 SoSeparator *fleche =
new SoSeparator;
136 SoTranslation *poseCylindre =
new SoTranslation;
137 SoCylinder *line =
new SoCylinder;
138 SoTranslation *posePointe =
new SoTranslation;
139 SoCone *pointe =
new SoCone;
141 float l_cylindre = longueur * (1 - proportionFleche);
142 float l_cone = longueur * proportionFleche;
143 float radius_cylindre = radius;
144 float radius_cone = radius * 5;
146 line->radius.setValue(radius_cylindre);
147 line->height.setValue(l_cylindre);
149 poseCylindre->translation.setValue(0, l_cylindre / 2, 0);
150 posePointe->translation.setValue(0.0, l_cylindre / 2 + l_cone / 2, 0);
152 pointe->bottomRadius.setValue(radius_cone);
153 pointe->height.setValue(l_cone);
155 fleche->addChild(poseCylindre);
156 fleche->addChild(line);
157 fleche->addChild(posePointe);
158 fleche->addChild(pointe);
167 #define LONGUEUR_FLECHE 1.0f
168 #define RAYON_FLECHE 0.002f
169 #define PROPORTION_FLECHE 0.1f
171 SoSeparator *createFrame(
float longueurFleche = LONGUEUR_FLECHE,
float proportionFleche = PROPORTION_FLECHE,
172 float radiusFleche = RAYON_FLECHE)
174 vpDEBUG_TRACE(15,
"# Entree.");
176 SoSeparator *frame =
new SoSeparator;
179 SoRotationXYZ *rotationY_X =
new SoRotationXYZ;
180 rotationY_X->axis = SoRotationXYZ::Z;
181 rotationY_X->angle.setValue((
float)(-M_PI / 2));
183 SoRotationXYZ *rotationX_Y =
new SoRotationXYZ;
184 rotationX_Y->axis = SoRotationXYZ::Z;
185 rotationX_Y->angle.setValue((
float)(M_PI / 2));
187 SoRotationXYZ *rotationY_Z =
new SoRotationXYZ;
188 rotationY_Z->axis = SoRotationXYZ::X;
189 rotationY_Z->angle.setValue((
float)(M_PI / 2));
191 SoMaterial *rouge =
new SoMaterial;
192 rouge->diffuseColor.setValue(1.0, 0.0, 0.0);
193 rouge->emissiveColor.setValue(0.5, 0.0, 0.0);
195 SoMaterial *vert =
new SoMaterial;
196 vert->diffuseColor.setValue(0.0, 1.0, 0.0);
197 vert->emissiveColor.setValue(0.0, 0.5, 0.0);
199 SoMaterial *bleu =
new SoMaterial;
200 bleu->diffuseColor.setValue(0.0, 0.0, 1.0);
201 bleu->emissiveColor.setValue(0.0, 0.0, 0.5);
203 SoSeparator *fleche = createArrow(longueurFleche, proportionFleche, radiusFleche);
205 frame->addChild(rouge);
206 frame->addChild(rotationY_X);
207 frame->addChild(fleche);
208 frame->addChild(vert);
209 frame->addChild(rotationX_Y);
210 frame->addChild(fleche);
211 frame->addChild(bleu);
212 frame->addChild(rotationY_Z);
213 frame->addChild(fleche);
215 frame->unrefNoDelete();
217 vpDEBUG_TRACE(15,
"# Sortie.");
221 SoSeparator *createCameraObject(
float zoomFactor = 1.0)
223 vpDEBUG_TRACE(15,
"# Entree.");
225 SoSeparator *cam =
new SoSeparator;
228 SoMaterial *myMaterial =
new SoMaterial;
229 myMaterial->diffuseColor.setValue(1.0, 0.0, 0.0);
230 myMaterial->emissiveColor.setValue(0.5, 0.0, 0.0);
232 SoScale *taille =
new SoScale;
234 float zoom = 0.1f * zoomFactor;
235 taille->scaleFactor.setValue(zoom, zoom, zoom);
238 SoMaterial *couleurBlanc =
new SoMaterial;
239 couleurBlanc->diffuseColor.setValue(1.0, 1.0, 1.0);
240 couleurBlanc->emissiveColor.setValue(1.0, 1.0, 1.0);
241 SoDrawStyle *filDeFer =
new SoDrawStyle;
242 filDeFer->style.setValue(SoDrawStyle::LINES);
243 filDeFer->lineWidth.setValue(1);
245 SoSeparator *cone =
new SoSeparator;
247 cone->addChild(makePyramide());
248 cone->addChild(couleurBlanc);
249 cone->addChild(filDeFer);
250 cone->addChild(makePyramide());
251 cone->unrefNoDelete();
253 cam->addChild(myMaterial);
254 cam->addChild(taille);
256 cam->addChild(createFrame(2.0f, 0.1f, 0.01f));
259 vpDEBUG_TRACE(15,
"# Sortie.");
294 #if defined(VISP_HAVE_SOWIN)
296 #elif defined(VISP_HAVE_SOQT)
298 #elif defined(VISP_HAVE_SOXT)
324 #if defined(VISP_HAVE_SOWIN)
326 #elif defined(VISP_HAVE_SOQT)
328 #elif defined(VISP_HAVE_SOXT)
331 mainWindowInitialized(false), typeImage(
vpSimulator::grayImage), image_background(nullptr), internalView(nullptr),
332 externalView(nullptr), mainThread(nullptr), internal_width(0), internal_height(0), external_width(0), external_height(0),
333 scene(nullptr), internalRoot(nullptr), externalRoot(nullptr), internalCamera(nullptr), externalCamera(nullptr),
334 internalCameraPosition(nullptr), extrenalCameraPosition(nullptr), internalCameraObject(nullptr), zoomFactor(0.),
335 cameraPositionInitialized(false), cMf(), internalCameraParameters(), externalCameraParameters(), realtime(nullptr),
336 offScreenRenderer(nullptr), bufferView(nullptr), get(0)
351 this->
scene =
new SoSeparator;
376 SoSeparator *camera =
new SoSeparator;
384 SoCube *cube =
new SoCube;
387 cube->height = 0.01f;
393 SoDB::enableRealTimeSensor(FALSE);
394 SoSceneManager::enableRealTimeUpdate(FALSE);
395 realtime = (SbTime *)SoDB::getGlobalField(
"realTime");
409 static bool firstTime =
true;
411 SoScale *taille =
new SoScale;
413 this->
scene->addChild(taille);
417 SoScale *taille = (SoScale *)this->
scene->getChild(0);
442 SoScale *taille = (SoScale *)this->
scene->getChild(index);
478 bufferView =
new unsigned char[3 * width * height];
512 float px = (float)_cam.
get_px();
513 float py = (float)_cam.
get_py();
531 float px = (float)_cam.
get_px();
532 float py = (float)_cam.
get_py();
553 orientation.getValue(axis, angle);
554 SbRotation rotation(axis, angle);
558 t = position.getValue();
561 matrix.setRotate(rotation);
565 rotX.setRotate(SbRotation(SbVec3f(1.0f, 0.0f, 0.0f), (
float)M_PI));
566 matrix.multLeft(rotX);
567 for (
unsigned int i = 0; i < 4; i++)
568 for (
unsigned int j = 0; j < 4; j++)
569 fMc[j][i] = matrix[(
int)i][(int)j];
588 rotX.setRotate(SbRotation(SbVec3f(1.0f, 0.0f, 0.0f), (
float)M_PI));
589 for (
unsigned int i = 0; i < 4; i++)
590 for (
unsigned int j = 0; j < 4; j++)
591 matrix[(
int)j][(int)i] = (
float)
cMf[i][j];
594 matrix.multLeft(rotX);
595 rotCam.setValue(matrix);
599 internalCamera->position.setValue(matrix[3][0], matrix[3][1], matrix[3][2]);
602 rotX.setRotate(SbRotation(SbVec3f(-1.0f, 0.0f, 0.0f), (
float)M_PI));
603 matrix.multLeft(rotX);
604 rotCam.setValue(matrix);
632 static void timerSensorCallback(
void *data, SoSensor *)
642 vpERROR_TRACE(
"main window is not opened ");
648 SoTimerSensor *timer =
new SoTimerSensor(timerSensorCallback, (
void *)
this);
649 timer->setInterval(0.01);
651 vpViewer::mainLoop();
663 if (!input.openFile(file_name)) {
664 vpERROR_TRACE(
"Erreur cannot open file %s", file_name);
667 SoSeparator *newscene = SoDB::readAll(&input);
669 if (newscene ==
nullptr) {
670 vpERROR_TRACE(
"Error while reading %s", file_name);
673 SoScale *taille =
new SoScale;
681 this->
scene->addChild(taille);
682 this->
scene->addChild(newscene);
690 output.openFile(name);
693 output.setBinary(TRUE);
695 SoWriteAction writeAction(&output);
696 writeAction.apply(
scene);
708 SoScale *taille =
new SoScale;
709 taille->scaleFactor.setValue(zoom, zoom, zoom);
711 SoSeparator *frame =
new SoSeparator;
713 frame->addChild(taille);
714 frame->addChild(createFrame(LONGUEUR_FLECHE * zoom, PROPORTION_FLECHE * zoom, RAYON_FLECHE * zoom));
726 scene->addChild(createFrame(LONGUEUR_FLECHE * zoom, PROPORTION_FLECHE * zoom, RAYON_FLECHE * zoom));
738 SoSeparator *newObject;
740 if (!in.openFile(iv_filename)) {
741 vpERROR_TRACE(
"Erreur lors de la lecture du fichier %s.", iv_filename);
744 newObject = SoDB::readAll(&in);
745 if (
nullptr == newObject) {
746 vpERROR_TRACE(
"Problem reading data for file <%s>.", iv_filename);
753 vpERROR_TRACE(
"Error adding object from file <%s> ", iv_filename);
769 vpERROR_TRACE(
"Error adding object in scene graph ");
784 bool identity =
true;
785 for (
unsigned int i = 0; i < 4; i++) {
786 for (
unsigned int j = 0; j < 4; j++) {
788 if (fabs(fMo[i][j] - 1) > 1e-6)
792 if (fabs(fMo[i][j]) > 1e-6)
798 if (identity ==
true) {
799 root->addChild(
object);
804 for (
unsigned int i = 0; i < 4; i++)
805 for (
unsigned int j = 0; j < 4; j++)
806 matrix[(
int)j][(int)i] = (
float)fMo[i][j];
809 rotation.setValue(matrix);
811 SoTransform *displacement =
new SoTransform;
812 SoSeparator *newNode =
new SoSeparator;
814 displacement->rotation.setValue(rotation);
815 displacement->translation.setValue(matrix[3][0], matrix[3][1], matrix[3][2]);
817 root->addChild(newNode);
818 newNode->addChild(displacement);
819 newNode->addChild(
object);
827 mainThread = SbThread::create(start_routine, (
void *)
this);
841 mainThread = SbThread::create(start_routine, (
void *)data);
856 vpViewer::exitMainLoop();
873 SbVec2s size(320, 200);
878 size = this->
internalView->getViewportRegion().getWindowSize();
879 thisroot = this->
internalView->getSceneManager()->getSceneGraph();
882 size = this->
externalView->getViewportRegion().getWindowSize();
883 thisroot = this->
externalView->getSceneManager()->getSceneGraph();
886 SbViewportRegion myViewPort(size);
900 vpERROR_TRACE(
"La scene n'a pas pu etre rendue offscreen.");
921 if (
nullptr != width) {
924 if (
nullptr != height) {
938 #ifdef VISP_HAVE_MODULE_IO
939 void vpSimulator::write(
const char *fileName)
954 unsigned char r, g, b;
971 SbVec2s size = this->
internalView->getViewportRegion().getWindowSize();
1003 #elif !defined(VISP_BUILD_SHARED_LIBS)
1005 void dummy_vpSimulator() { };
Generic class defining intrinsic camera parameters.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Type * bitmap
points toward the bitmap
Implementation of a simulator based on Coin3d (www.coin3d.org).
SoPerspectiveCamera * internalCamera
internal camera
void save(const char *name, bool binary=false)
save the scene in an iv file
unsigned int internal_height
GLubyte * image_background
vpCameraParameters internalCameraParameters
internal camera parameters
void load(const char *file_name)
load an iv file
unsigned char * bufferView
image of the internal view
SoTransform * extrenalCameraPosition
external camera position
void addFrame(const vpHomogeneousMatrix &fMo, float zoom=1)
Add the representation of a frame.
void setInternalCameraParameters(vpCameraParameters &cam)
set internal camera parameters
void changeZoomFactor(float zoom, int index)
Change the zoom factor associated to the child given by index. In order to create multiple zoom facto...
void kill()
perform some destruction
virtual void mainLoop()
activate the mainloop
unsigned int external_height
void setExternalCameraParameters(vpCameraParameters &cam)
set external camera parameters
unsigned int internal_width
void getInternalImage(vpImage< unsigned char > &I)
get an Image of the internal view
void initMainApplication()
perform some initialization in the main program thread
bool cameraPositionInitialized
void getSizeInternalView(int &width, int &height)
get the size of the internal view
void moveInternalCamera(vpHomogeneousMatrix &cMf)
modify the position of the camera in the scene graph
void initSoApplication()
open the SoGui application
void getExternalCameraPosition(vpHomogeneousMatrix &cMf)
get the external camera position
void redraw()
display the scene (handle with care)
void initApplication(void *(*start_routine)(void *))
begin the main program
vpViewer * internalView
view from the camera
void init()
perform some initialization
vpHomogeneousMatrix cMf
internal camera position
SoSeparator * internalCameraObject
representation of the camera in the external view
SbThread * mainThread
thread with the main program
vpViewer * externalView
view from an external camera
void setZoomFactor(float zoom)
set the size of the camera/frame
SoPerspectiveCamera * externalCamera
external camera
void setCameraPosition(vpHomogeneousMatrix &cMf)
set the camera position (from an homogeneous matrix)
HWND mainWindow
main Widget
void offScreenRendering(vpSimulatorViewType view=vpSimulator::EXTERNAL, int *width=nullptr, int *height=nullptr)
void initExternalViewer(unsigned int nlig, unsigned int ncol)
initialize the external view
SoSeparator * externalRoot
root node of the external view
virtual void initInternalViewer(unsigned int nlig, unsigned int ncol)
initialize the camera view
bool mainWindowInitialized
void addObject(SoSeparator *object, const vpHomogeneousMatrix &fMo, SoSeparator *root)
Add a new object in the scene graph ad a given location.
vpCameraParameters externalCameraParameters
internal camera parameters
void initSceneGraph()
initialize the scene graph
SoOffscreenRenderer * offScreenRenderer
SoTransform * internalCameraPosition
internal camera position
SoSeparator * internalRoot
root node of the internal view
void closeMainApplication()
void addAbsoluteFrame(float zoom=1)
Add the representation of the absolute frame.
unsigned int external_width
Viewer used by the simulator.
void resize(int x, int y, bool fixed=false)
VISP_EXPORT int wait(double t0, double t)