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>
73static float pyramidVertexes[5][3] = { {0.33f, 0.33f, 0.f},
75 {-0.33f, -0.33f, 0.f},
80static int32_t pyramidFaces[] = {
106SoSeparator *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();
131static 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
171SoSeparator *createFrame(
float longueurFleche = LONGUEUR_FLECHE,
float proportionFleche = PROPORTION_FLECHE,
172 float radiusFleche = RAYON_FLECHE)
176 SoSeparator *frame =
new SoSeparator;
179 SoRotationXYZ *rotationY_X =
new SoRotationXYZ;
180 rotationY_X->axis = SoRotationXYZ::Z;
181 rotationY_X->angle.setValue(
static_cast<float>(-M_PI / 2));
183 SoRotationXYZ *rotationX_Y =
new SoRotationXYZ;
184 rotationX_Y->axis = SoRotationXYZ::Z;
185 rotationX_Y->angle.setValue(
static_cast<float>(M_PI / 2));
187 SoRotationXYZ *rotationY_Z =
new SoRotationXYZ;
188 rotationY_Z->axis = SoRotationXYZ::X;
189 rotationY_Z->angle.setValue(
static_cast<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();
221SoSeparator *createCameraObject(
float zoomFactor = 1.0)
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));
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)
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);
473 internalView->resize(
static_cast<int>(width),
static_cast<int>(height),
true);
478 bufferView =
new unsigned char[3 * width * height];
499 externalView->resize(
static_cast<int>(width),
static_cast<int>(height),
false);
512 float px =
static_cast<float>(_cam.
get_px());
513 float py =
static_cast<float>(_cam.
get_py());
531 float px =
static_cast<float>(_cam.
get_px());
532 float py =
static_cast<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),
static_cast<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[
static_cast<int>(i)][
static_cast<int>(j)];
590 rotX.setRotate(SbRotation(SbVec3f(1.0f, 0.0f, 0.0f),
static_cast<float>(M_PI)));
591 for (
unsigned int i = 0; i < 4; i++)
592 for (
unsigned int j = 0; j < 4; j++)
593 matrix[
static_cast<int>(j)][
static_cast<int>(i)] =
static_cast<float>(
cMf[i][j]);
595 matrix = matrix.inverse();
596 matrix.multLeft(rotX);
597 rotCam.setValue(matrix);
601 internalCamera->position.setValue(matrix[3][0], matrix[3][1], matrix[3][2]);
604 rotX.setRotate(SbRotation(SbVec3f(-1.0f, 0.0f, 0.0f),
static_cast<float>(M_PI)));
605 matrix.multLeft(rotX);
606 rotCam.setValue(matrix);
634static void timerSensorCallback(
void *data, SoSensor *)
650 SoTimerSensor *timer =
new SoTimerSensor(timerSensorCallback, (
void *)
this);
651 timer->setInterval(0.01);
653 vpViewer::mainLoop();
665 if (!input.openFile(file_name)) {
669 SoSeparator *newscene = SoDB::readAll(&input);
671 if (newscene ==
nullptr) {
675 SoScale *taille =
new SoScale;
683 this->
scene->addChild(taille);
684 this->
scene->addChild(newscene);
692 output.openFile(name);
695 output.setBinary(TRUE);
697 SoWriteAction writeAction(&output);
698 writeAction.apply(
scene);
710 SoScale *taille =
new SoScale;
711 taille->scaleFactor.setValue(zoom, zoom, zoom);
713 SoSeparator *frame =
new SoSeparator;
715 frame->addChild(taille);
716 frame->addChild(createFrame(LONGUEUR_FLECHE * zoom, PROPORTION_FLECHE * zoom, RAYON_FLECHE * zoom));
728 scene->addChild(createFrame(LONGUEUR_FLECHE * zoom, PROPORTION_FLECHE * zoom, RAYON_FLECHE * zoom));
740 SoSeparator *newObject;
742 if (!in.openFile(iv_filename)) {
743 vpERROR_TRACE(
"Erreur lors de la lecture du fichier %s.", iv_filename);
746 newObject = SoDB::readAll(&in);
747 if (
nullptr == newObject) {
748 vpERROR_TRACE(
"Problem reading data for file <%s>.", iv_filename);
755 vpERROR_TRACE(
"Error adding object from file <%s> ", iv_filename);
786 bool identity =
true;
787 for (
unsigned int i = 0; i < 4; i++) {
788 for (
unsigned int j = 0; j < 4; j++) {
790 if (fabs(fMo[i][j] - 1) > 1e-6)
794 if (fabs(fMo[i][j]) > 1e-6)
800 if (identity ==
true) {
801 root->addChild(
object);
806 for (
unsigned int i = 0; i < 4; i++)
807 for (
unsigned int j = 0; j < 4; j++)
808 matrix[
static_cast<int>(j)][
static_cast<int>(i)] =
static_cast<float>(fMo[i][j]);
811 rotation.setValue(matrix);
813 SoTransform *displacement =
new SoTransform;
814 SoSeparator *newNode =
new SoSeparator;
816 displacement->rotation.setValue(rotation);
817 displacement->translation.setValue(matrix[3][0], matrix[3][1], matrix[3][2]);
819 root->addChild(newNode);
820 newNode->addChild(displacement);
821 newNode->addChild(
object);
829 mainThread = SbThread::create(start_routine, (
void *)
this);
843 mainThread = SbThread::create(start_routine, (
void *)data);
858 vpViewer::exitMainLoop();
875 SbVec2s size(320, 200);
880 size = this->
internalView->getViewportRegion().getWindowSize();
881 thisroot = this->
internalView->getSceneManager()->getSceneGraph();
884 size = this->
externalView->getViewportRegion().getWindowSize();
885 thisroot = this->
externalView->getSceneManager()->getSceneGraph();
888 SbViewportRegion myViewPort(size);
923 if (
nullptr != width) {
926 if (
nullptr != height) {
940#ifdef VISP_HAVE_MODULE_IO
956 unsigned char r, g, b;
973 SbVec2s size = this->
internalView->getViewportRegion().getWindowSize();
1005#elif !defined(VISP_BUILD_SHARED_LIBS)
1007void 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)
Definition of the vpImage class member functions.
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
void write(const char *fileName)
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.
VISP_EXPORT int wait(double t0, double t)