Index: trunk/lib/FlairSimulator/src/Blade.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/Blade.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/Blade.cpp	(revision 286)
@@ -64,4 +64,32 @@
 }
 
+Blade::Blade(ISceneNode *parent, const vector3df &position, bool inverted, s32 id)
+    : ISceneNode(parent, getGui()->getSceneManager(), id,
+                 position) {
+  ISceneManager *mgr = getGui()->getSceneManager();
+
+  const IGeometryCreator *geo;
+  geo = mgr->getGeometryCreator();
+  pale = geo->createCubeMesh(vector3df(63.5, 0.5, 5));
+
+  float angle;
+  if (inverted == false) {
+    angle = 20;
+  } else {
+    angle = -20;
+  }
+
+  ITexture *texture = getGui()->getTexture("carbone.jpg");
+  pale_1 = new MeshSceneNode(parent, pale, vector3df(-30, 0, 0),
+                             vector3df(-angle + 90, 0, 0), texture);
+  pale_1->setParent(this);
+  pale_2 = new MeshSceneNode(parent, pale, vector3df(30, 0, 0),
+                             vector3df(angle + 90, 0, 0), texture);
+  pale_2->setParent(this);
+
+  anim = mgr->createRotationAnimator(vector3df(0.f, 0.f, 0.f));
+  addAnimator(anim);
+}
+
 void Blade::OnRegisterSceneNode() {
   if (IsVisible)
Index: trunk/lib/FlairSimulator/src/Blade.h
===================================================================
--- trunk/lib/FlairSimulator/src/Blade.h	(revision 245)
+++ trunk/lib/FlairSimulator/src/Blade.h	(revision 286)
@@ -36,4 +36,9 @@
         const irr::core::vector3df &position = irr::core::vector3df(0, 0, 0),
         bool inverted = false, irr::s32 id = -1);
+
+  Blade(irr::scene::ISceneNode *parent,
+        const irr::core::vector3df &position = irr::core::vector3df(0, 0, 0),
+        bool inverted = false, irr::s32 id = -1);
+  
   virtual void OnRegisterSceneNode(void);
   virtual void render(void);
Index: trunk/lib/FlairSimulator/src/FixedCamera.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/FixedCamera.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/FixedCamera.cpp	(revision 286)
@@ -27,4 +27,5 @@
 #include <Euler.h>
 
+
 using namespace irr;
 using namespace gui;
@@ -51,5 +52,5 @@
 void FixedCamera::animateNode(ISceneNode *node, u32 timeMs) {
   ICameraSceneNode *camera = static_cast<ICameraSceneNode *>(node);
-
+  
   if (LMouseKey == true) {
     if (!Rotating) {
Index: trunk/lib/FlairSimulator/src/FollowMeCamera.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/FollowMeCamera.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/FollowMeCamera.cpp	(revision 286)
@@ -63,5 +63,4 @@
 
 void FollowMeCamera::animateNode(ISceneNode *node, u32 timeMs) {
-
   float nRotY = RotY;
   float nRotZ = RotZ;
Index: trunk/lib/FlairSimulator/src/GenericObject.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/GenericObject.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/GenericObject.cpp	(revision 286)
@@ -40,8 +40,8 @@
 {
 	meshSceneNode=getGui()->getSceneManager()->addMeshSceneNode(mesh);
-	
+	/*
   selector = getGui()->getSceneManager()->createTriangleSelector(mesh, meshSceneNode);
   meshSceneNode->setTriangleSelector(selector);
-	
+	*/
   meshSceneNode->setMaterialFlag(EMF_LIGHTING, false);
 
@@ -53,4 +53,7 @@
 ITriangleSelector *GenericObject::TriangleSelector(void) { return selector; }
 
+void GenericObject::setVisible(bool isVisible) {
+  meshSceneNode->setVisible(isVisible);
+}
 void GenericObject::setScale(float value) {
   meshSceneNode->setScale(vector3df(value, value, value));
Index: trunk/lib/FlairSimulator/src/Gui_impl.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/Gui_impl.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/Gui_impl.cpp	(revision 286)
@@ -94,5 +94,4 @@
   device->setResizable(false);
 
-  // font = device->getGUIEnvironment()->getBuiltInFont();
   driver = device->getVideoDriver();
   smgr = device->getSceneManager();
@@ -179,4 +178,14 @@
   int lastFPS = -1;
   int cam_id = 0;
+  ITexture* texture=0;
+  IGUIFont* font =0;
+  
+  if (!driver->queryFeature(video::EVDF_RENDER_TO_TARGET)) {
+    self->Warn("rendering to texture is not possible, axis will not be displayed\n");
+  } else {
+    texture= getGui()->getSceneManager()->getVideoDriver()->addRenderTargetTexture(dimension2d<u32>(128,128));
+    device->getGUIEnvironment()->addImage(texture,position2d<s32>(0,scene_height-texture->getSize().Height));
+    font = getGui()->getDevice()->getGUIEnvironment()->getFont((media_path+"/font/simu_axis_font.xml").c_str());
+  }
 
   receiver->SetModel(models.at(0));
@@ -242,19 +251,5 @@
     driver->setViewPort(core::rect<s32>(0, 0, scene_width, scene_height));
     smgr->drawAll(); // commente voir plus bas
-                     /*
-                 env->drawAll();
-                 if (font)
-                 {
-                                     font->draw(L"This demo shows that Irrlicht is also capable
-                 of drawing 2D graphics.",
-                                             core::rect<s32>(130,10,300,50),
-                                             video::SColor(255,255,255,255));
-                 }
-                 else
-                 {
-                 printf("err\n");
-                 }
-                 device->setWindowCaption(L"toto");*/
-
+                    
     if (dbtFile_r == NULL) {// mode normal
       for (size_t i = 0; i < models.size(); i++) {
@@ -263,8 +258,15 @@
     }
 
+    //render to texture for axis if possible
+    if (texture) {
+      cameras.at(cam_id)->renderAxisToTexture(texture);
+    }
+    
+    //process update for sensors (cam, us...)
+    //also draws embedded cameras (see SimuCameraGL::UpdateFrom) 
     for (size_t i = 0; i < models.size(); i++) {
       models.at(i)->ProcessUpdate(NULL);
     }
-
+    
     // on fait ca ici, devrait etre un peu plus haut
     // mais a priori souci avec models.at(i)->pimpl_->CheckCollision();
@@ -274,7 +276,16 @@
     driver->setViewPort(core::rect<s32>(0, 0, scene_width, scene_height));
     smgr->drawAll();
-
+    
+    driver->setViewPort(core::rect<s32>(0, 0, smgr->getVideoDriver()->getScreenSize().Width, smgr->getVideoDriver()->getScreenSize().Height));
+    if(font) {
+      font->draw(L"VRPN:",rect<s32>(10,scene_height-30,100,50),SColor(128,255,255,255));
+      font->draw(L"X",rect<s32>(60,scene_height-30,100,50),SColor(255,255,0,0));
+      font->draw(L"Y",rect<s32>(70,scene_height-30,100,50),SColor(255,0,255,0));
+      font->draw(L"Z",rect<s32>(80,scene_height-30,100,50),SColor(255,0,0,255));
+      
+    }
+    device->getGUIEnvironment()->drawAll();
     driver->endScene();
-
+    
     int fps = driver->getFPS();
 
Index: trunk/lib/FlairSimulator/src/MeshSceneNode.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/MeshSceneNode.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/MeshSceneNode.cpp	(revision 286)
@@ -49,4 +49,22 @@
 }
 
+MeshSceneNode::MeshSceneNode(ISceneNode *parent, IMesh *mesh,
+                             const vector3df &position,
+                             const vector3df &rotation, ITexture *texture,
+                             s32 id)
+    : IMeshSceneNode(parent, getGui()->getSceneManager(), id,
+                     position, rotation) {
+  Material.Wireframe = false;
+  Material.Lighting = false;
+
+  setMesh(mesh);
+
+  if (texture != NULL) {
+    setMaterialTexture(0, texture);
+  }
+
+  //parent->getBoundingBox().addInternalBox(getTransformedBoundingBox());
+}
+
 void MeshSceneNode::OnRegisterSceneNode(void) {
   if (IsVisible)
Index: trunk/lib/FlairSimulator/src/MeshSceneNode.h
===================================================================
--- trunk/lib/FlairSimulator/src/MeshSceneNode.h	(revision 245)
+++ trunk/lib/FlairSimulator/src/MeshSceneNode.h	(revision 286)
@@ -31,4 +31,10 @@
       const irr::core::vector3df &rotation = irr::core::vector3df(0, 0, 0),
       irr::video::ITexture *texture = NULL, irr::s32 id = -1);
+  
+  MeshSceneNode(
+      irr::scene::ISceneNode *parent, irr::scene::IMesh *mesh,
+      const irr::core::vector3df &position = irr::core::vector3df(0, 0, 0),
+      const irr::core::vector3df &rotation = irr::core::vector3df(0, 0, 0),
+      irr::video::ITexture *texture = NULL, irr::s32 id = -1);
 
   virtual void OnRegisterSceneNode(void);
Index: trunk/lib/FlairSimulator/src/SimuBldc.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/SimuBldc.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/SimuBldc.cpp	(revision 286)
@@ -73,4 +73,4 @@
 }
 
-} // end namespace sensor
+} // end namespace actuator
 } // end namespace flair
Index: trunk/lib/FlairSimulator/src/Simulator.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/Simulator.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/Simulator.cpp	(revision 286)
@@ -36,10 +36,10 @@
 Simulator *getSimulator(void) { return simu; }
 
-Simulator::Simulator(string name, int optitrack_mstime, float yaw_deg)
+Simulator::Simulator(string name, int optitrack_mstime, float yaw_deg, int port)
     : FrameworkManager(name) {
   if (simu != NULL)
     Err("Simulator should be instanced only one time\n");
 
-  pimpl_ = new Simulator_impl(this, optitrack_mstime, yaw_deg);
+  pimpl_ = new Simulator_impl(this, optitrack_mstime, yaw_deg,port);
   simu = this;
 }
Index: trunk/lib/FlairSimulator/src/Simulator.h
===================================================================
--- trunk/lib/FlairSimulator/src/Simulator.h	(revision 245)
+++ trunk/lib/FlairSimulator/src/Simulator.h	(revision 286)
@@ -44,5 +44,5 @@
   // yaw_deg: rotation of the vrpn coordinate with respect to the earth
   // coordinate, around z axis
-  Simulator(std::string name, int optitrack_mstime = 10, float yaw_deg = 30);
+  Simulator(std::string name, int optitrack_mstime = 10, float yaw_deg = 30, int port=3883);
   ~Simulator();
   void RunSimu(void);
Index: trunk/lib/FlairSimulator/src/Simulator_impl.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/Simulator_impl.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/Simulator_impl.cpp	(revision 286)
@@ -31,6 +31,6 @@
 
 Simulator_impl::Simulator_impl(Simulator *self, int optitrack_mstime,
-                               float yaw_deg)
-    : vrpn_Connection_IP(), Thread(self, "simulator", 1) {
+                               float yaw_deg,int port)
+    : vrpn_Connection_IP(port), Thread(self, "simulator", 1) {
   this->self = self;
   this->optitrack_mstime = optitrack_mstime;
Index: trunk/lib/FlairSimulator/src/UavVrpnObject.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/UavVrpnObject.cpp	(revision 286)
+++ trunk/lib/FlairSimulator/src/UavVrpnObject.cpp	(revision 286)
@@ -0,0 +1,41 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+//  created:    2018/12/11
+//  filename:   UavVrpnObject.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    uav vrpn object, can display a real vrpn object in a simulated environment
+//
+/*********************************************************************/
+#ifdef GL
+
+#include "UavVrpnObject.h"
+#include "UavVrpnObject_impl.h"
+
+using namespace flair::sensor;
+  
+namespace flair {
+namespace simulator {
+
+UavVrpnObject::UavVrpnObject(std::string name,VrpnClient *client) 
+  : VrpnObject(name,client->GetTabWidget(),client){
+  
+  
+  pimpl_ = new UavVrpnObject_impl(this, name);
+  pimpl_->setPosition(irr::core::vector3df(4,4,100));
+}
+
+UavVrpnObject::~UavVrpnObject() {
+  delete pimpl_; 
+}
+
+} // end namespace simulator
+} // end namespace flair
+
+#endif // GL
Index: trunk/lib/FlairSimulator/src/UavVrpnObject.h
===================================================================
--- trunk/lib/FlairSimulator/src/UavVrpnObject.h	(revision 286)
+++ trunk/lib/FlairSimulator/src/UavVrpnObject.h	(revision 286)
@@ -0,0 +1,43 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+//  created:    2018/12/11
+//  filename:   UavVrpnObject.h
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    uav vrpn object, can display a real vrpn object in a simulated environment
+//
+/*********************************************************************/
+
+#ifndef UAVVRPNOBJECT_H
+#define UAVVRPNOBJECT_H
+
+#ifdef GL
+
+#include <VrpnObject.h>
+
+class UavVrpnObject_impl;
+
+namespace flair {
+namespace simulator {
+
+class UavVrpnObject :public sensor::VrpnObject {
+public:
+  UavVrpnObject(std::string name,sensor::VrpnClient *client=sensor::GetVrpnClient());
+  ~UavVrpnObject();
+
+private:
+  UavVrpnObject_impl *pimpl_;
+
+};
+} // end namespace simulator
+} // end namespace flair
+
+#endif // GL
+
+#endif // UAVVRPNOBJECT_H
Index: trunk/lib/FlairSimulator/src/UavVrpnObject_impl.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/UavVrpnObject_impl.cpp	(revision 286)
+++ trunk/lib/FlairSimulator/src/UavVrpnObject_impl.cpp	(revision 286)
@@ -0,0 +1,155 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+//  created:    2018/12/11
+//  filename:   UavVrpnObject_impl.cpp
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    uav vrpn object, can display a real vrpn object in a simulated environment
+//
+/*********************************************************************/
+#ifdef GL
+
+#include "UavVrpnObject_impl.h"
+#include "UavVrpnObject.h"
+#include <TabWidget.h>
+#include <Tab.h>
+#include <DoubleSpinBox.h>
+#include "Simulator.h"
+#include <ISceneManager.h>
+#include <IVideoDriver.h>
+#include "Blade.h"
+#include "MeshSceneNode.h"
+#include "Gui.h"
+#include "FollowMeCamera.h"
+#include <Matrix.h>
+#include <Quaternion.h>
+#include <Euler.h>
+
+#define MOTOR_SPEED 100
+
+using namespace irr::video;
+using namespace irr::scene;
+using namespace irr::core;
+using namespace flair::core;
+using namespace flair::simulator;
+using namespace flair::gui;
+  
+UavVrpnObject_impl::UavVrpnObject_impl(UavVrpnObject *self,std::string name) 
+  : IODevice(self,name),
+    ISceneNode(getGui()->getSceneManager()->getRootSceneNode(), getGui()->getSceneManager(), -1) {
+  this->self=self;
+  
+  // init user interface
+  Tab *tab = new Tab(getSimulator()->GetTabWidget(), ObjectName());
+  arm_length = new DoubleSpinBox(tab->LastRowLastCol(), "arm length (m):",0, 2, 0.1);
+
+  // camera
+  FollowMeCamera* camera = new FollowMeCamera(this,name);
+  
+  Draw();
+}
+
+UavVrpnObject_impl::~UavVrpnObject_impl() {
+  // les objets irrlicht seront automatiquement detruits (moteurs, helices,
+  // pales) par parenté
+}
+
+void UavVrpnObject_impl::UpdateFrom(const io_data *data) {
+  const Matrix* input = dynamic_cast<const Matrix*>(data);
+  if (!input) {
+      self->Warn("casting %s to Matrix failed\n",data->ObjectName().c_str());
+      return;
+  }
+  
+  Vector3Df vrpnPosition;
+  Quaternion vrpnQuaternion;
+  input->GetMutex();
+  vrpnQuaternion.q0=input->ValueNoMutex(0, 0);
+  vrpnQuaternion.q1=input->ValueNoMutex(1, 0);
+  vrpnQuaternion.q2=input->ValueNoMutex(2, 0);
+  vrpnQuaternion.q3=input->ValueNoMutex(3, 0);
+  vrpnPosition.x=input->ValueNoMutex(4, 0);
+  vrpnPosition.y=input->ValueNoMutex(5, 0);
+  vrpnPosition.z=input->ValueNoMutex(6, 0);
+  input->ReleaseMutex();
+  
+  vector3df nodePosition;
+  Quaternion nodeQuaternion;
+  Euler nodeEuler;
+
+  nodePosition = ToIrrlichtCoordinates(vrpnPosition);
+  setPosition(nodePosition);
+  nodeQuaternion = ToIrrlichtOrientation(vrpnQuaternion);
+  nodeQuaternion.ToEuler(nodeEuler);
+  setRotation(Euler::ToDegree(1) * vector3df(nodeEuler.roll,nodeEuler.pitch, nodeEuler.yaw));
+  
+  if (arm_length->ValueChanged() == true) {
+    setScale(vector3df(arm_length->Value(), arm_length->Value(), arm_length->Value()));
+  }
+}
+
+void UavVrpnObject_impl::render(void) {
+  IVideoDriver *driver = SceneManager->getVideoDriver();
+  driver->setTransform(ETS_WORLD, AbsoluteTransformation);
+}
+
+void UavVrpnObject_impl::OnRegisterSceneNode(void) {
+  if (IsVisible)
+    SceneManager->registerNodeForRendering(this);
+
+  ISceneNode::OnRegisterSceneNode();
+}
+
+void UavVrpnObject_impl::Draw(void) {
+  // create unite (1m=100cm) UAV; scale will be adapted according to arm_length
+  // parameter
+  // note that the frame used is irrlicht one:
+  // left handed, North East Up
+  const IGeometryCreator *geo;
+  geo = getGui()->getSceneManager()->getGeometryCreator();
+
+  // cylinders are aligned with y axis
+  IMesh *red_arm = geo->createCylinderMesh(2.5, 100, 16, SColor(0, 255, 0, 0));
+  IMesh *black_arm = geo->createCylinderMesh(2.5, 100, 16, SColor(0, 128, 128, 128));
+  IMesh *motor = geo->createCylinderMesh(7.5, 15, 16); //,SColor(0, 128, 128, 128));
+  // geo->drop();
+
+  ITexture *texture = getGui()->getTexture("carbone.jpg");
+  MeshSceneNode *fl_arm = new MeshSceneNode(this, red_arm, vector3df(0, 0, 0),
+                             vector3df(0, 0, -135));
+  MeshSceneNode *fr_arm = new MeshSceneNode(this, red_arm, vector3df(0, 0, 0),
+                             vector3df(0, 0, -45));
+  MeshSceneNode *rl_arm = new MeshSceneNode(this, black_arm, vector3df(0, 0, 0),
+                             vector3df(0, 0, 135), texture);
+  MeshSceneNode *rr_arm = new MeshSceneNode(this, black_arm, vector3df(0, 0, 0),
+                             vector3df(0, 0, 45), texture);
+
+  texture = getGui()->getTexture("metal047.jpg");
+  MeshSceneNode *fl_motor = new MeshSceneNode(this, motor, vector3df(70.71, -70.71, 2.5),
+                               vector3df(90, 0, 0), texture);
+  MeshSceneNode *fr_motor = new MeshSceneNode(this, motor, vector3df(70.71, 70.71, 2.5),
+                               vector3df(90, 0, 0), texture);
+  MeshSceneNode *rl_motor = new MeshSceneNode(this, motor, vector3df(-70.71, -70.71, 2.5),
+                               vector3df(90, 0, 0), texture);
+  MeshSceneNode *rr_motor = new MeshSceneNode(this, motor, vector3df(-70.71, 70.71, 2.5),
+                               vector3df(90, 0, 0), texture);
+
+  fl_blade = new Blade(this, vector3df(70.71, -70.71, 17.5));
+  fr_blade = new Blade(this, vector3df(70.71, 70.71, 17.5), true);
+  rl_blade = new Blade(this, vector3df(-70.71, -70.71, 17.5), true);
+  rr_blade = new Blade(this, vector3df(-70.71, 70.71, 17.5));
+  
+  fl_blade->SetRotationSpeed(MOTOR_SPEED);
+  fr_blade->SetRotationSpeed(-MOTOR_SPEED);
+  rl_blade->SetRotationSpeed(-MOTOR_SPEED);
+  rr_blade->SetRotationSpeed(MOTOR_SPEED);
+  
+  setScale(vector3df(arm_length->Value(), arm_length->Value(), arm_length->Value()));
+}
+#endif // GL
Index: trunk/lib/FlairSimulator/src/VisualizationCamera.cpp
===================================================================
--- trunk/lib/FlairSimulator/src/VisualizationCamera.cpp	(revision 245)
+++ trunk/lib/FlairSimulator/src/VisualizationCamera.cpp	(revision 286)
@@ -31,4 +31,5 @@
 using namespace core;
 using namespace scene;
+using namespace video;
 
 namespace flair {
@@ -40,5 +41,5 @@
   LMouseKey = false;
 
-   // camera
+  // camera for visualization
   camera = getGui()->getSceneManager()->addCameraSceneNode();
   camera->setAspectRatio(getGui()->getAspectRatio()); // on force a cause du view port
@@ -48,7 +49,49 @@
 
   getGui()->pimpl_->AddVisualizationCamera(this);
+  
+  // camera to draw axis, in a new dedicated scene manager
+  axis_scenemanager=getGui()->getSceneManager()->createNewSceneManager();
+  axis_camera = axis_scenemanager->addCameraSceneNode();
+  axis_camera->setAspectRatio(1);  // same as texture ratio, TODO: get it from texture in renderAxisToTexture
+  axis_camera->setUpVector(vector3df(0, 0, 1));
+  axis_camera->setFOV(PI / 2.5f);
+  axis_scenemanager->setActiveCamera(axis_camera);
+  prendre en compte le yaw monde/optitrack (rotation de axis_scenemanager?)
+  IAnimatedMesh* arrowMeshRed = axis_scenemanager->addArrowMesh( "x_axisArrow",video::SColor(255, 255, 0, 0),video::SColor(255, 255, 0, 0));
+  nodeX = axis_scenemanager->addMeshSceneNode(arrowMeshRed);
+  nodeX->setMaterialFlag(video::EMF_LIGHTING, false);
+  nodeX->setRotation(vector3df(0,0,-90));
+  nodeX->setScale(vector3df(1,3,1));
+  
+  IAnimatedMesh* arrowMeshGreen = axis_scenemanager->addArrowMesh( "y_axisArrow",video::SColor(255, 0, 255, 0),video::SColor(255, 0, 255, 0));
+  nodeY = axis_scenemanager->addMeshSceneNode(arrowMeshGreen);
+  nodeY->setMaterialFlag(video::EMF_LIGHTING, false);
+  nodeY->setScale(vector3df(1,3,1));
+  
+  IAnimatedMesh* arrowMeshBlue = axis_scenemanager->addArrowMesh( "z_axisArrow",video::SColor(255, 0, 0, 255),video::SColor(255, 0, 0, 255));
+  nodeZ = axis_scenemanager->addMeshSceneNode(arrowMeshBlue);
+  nodeZ->setMaterialFlag(video::EMF_LIGHTING, false);
+  nodeZ->setRotation(vector3df(-90,0,0));//irrlicht is left handed, draw a right handed axis
+  nodeZ->setScale(vector3df(1,3,1));
 }
 
 VisualizationCamera::~VisualizationCamera() {}
+
+void VisualizationCamera::renderAxisToTexture(ITexture* texture) {
+  //put axis at a "normalized" distance
+  vector3df direction=camera->getTarget()-camera->getPosition();
+  direction.normalize();
+  nodeX->setPosition(camera->getPosition()+direction*6);
+  nodeY->setPosition(camera->getPosition()+direction*6);
+  nodeZ->setPosition(camera->getPosition()+direction*6);
+
+  axis_camera->setPosition(camera->getPosition());
+  axis_camera->setRotation(camera->getRotation());
+  axis_camera->setTarget(camera->getTarget());
+  
+  axis_scenemanager->getVideoDriver()->setRenderTarget(texture, true, true, SColor(0,0,0,0));
+  axis_scenemanager->drawAll();
+  axis_scenemanager->getVideoDriver()->setRenderTarget(0, true, true, 0);
+}
 
 std::string VisualizationCamera::getName(void) {
Index: trunk/lib/FlairSimulator/src/VisualizationCamera.h
===================================================================
--- trunk/lib/FlairSimulator/src/VisualizationCamera.h	(revision 245)
+++ trunk/lib/FlairSimulator/src/VisualizationCamera.h	(revision 286)
@@ -27,4 +27,7 @@
     class ICameraSceneNode;
   }
+  namespace video {
+    class ITexture;
+  }
 }
 
@@ -42,11 +45,15 @@
   irr::scene::ICameraSceneNode *getCameraSceneNode(void);
   std::string getName(void);
+  void renderAxisToTexture(irr::video::ITexture* texture);
 
 private:
   virtual bool isEventReceiverEnabled(void) const { return true; }
-
+  irr::scene::ISceneNode *nodeX,*nodeY,*nodeZ;
+  irr::scene::ISceneManager *axis_scenemanager;
+  
 protected:
   bool LMouseKey;
   irr::scene::ICameraSceneNode *camera;
+  irr::scene::ICameraSceneNode *axis_camera;
   irr::core::position2df MousePos;
   float currentZoom;
Index: trunk/lib/FlairSimulator/src/X4.h
===================================================================
--- trunk/lib/FlairSimulator/src/X4.h	(revision 245)
+++ trunk/lib/FlairSimulator/src/X4.h	(revision 286)
@@ -43,10 +43,7 @@
 #ifdef GL
   virtual void Draw(void);
-  virtual void ExtraDraw(void){};
+  virtual void ExtraDraw(void){}; 
+#endif
 
-protected:
-  Blade *fl_blade, *fr_blade, *rl_blade, *rr_blade;
-  core::Mutex *motor_speed_mutex;
-#endif
 private:
   void CalcModel(void);
@@ -56,4 +53,6 @@
   void WritedbtBuf(char *dbtbuf);
   void ReaddbtBuf(char *dbtbuf);
+  Blade *fl_blade, *fr_blade, *rl_blade, *rr_blade;
+  core::Mutex *motor_speed_mutex;
 #endif
 
Index: trunk/lib/FlairSimulator/src/X8.h
===================================================================
--- trunk/lib/FlairSimulator/src/X8.h	(revision 245)
+++ trunk/lib/FlairSimulator/src/X8.h	(revision 286)
@@ -45,8 +45,5 @@
 
 protected:
-#ifdef GL
-  Blade *tfl_blade, *tfr_blade, *trl_blade, *trr_blade;
-  Blade *bfl_blade, *bfr_blade, *brl_blade, *brr_blade;
-#endif
+
 private:
   void CalcModel(void);
@@ -57,4 +54,6 @@
   void ReaddbtBuf(char *dbtbuf);
   core::Mutex *motor_speed_mutex;
+  Blade *tfl_blade, *tfr_blade, *trl_blade, *trr_blade;
+  Blade *bfl_blade, *bfr_blade, *brl_blade, *brr_blade;
 #endif
 
Index: trunk/lib/FlairSimulator/src/unexported/GenericObject.h
===================================================================
--- trunk/lib/FlairSimulator/src/unexported/GenericObject.h	(revision 245)
+++ trunk/lib/FlairSimulator/src/unexported/GenericObject.h	(revision 286)
@@ -47,4 +47,5 @@
 	void setPosition(const irr::core::vector3df& position);
   void setRotation(const irr::core::vector3df& rotation);
+  void setVisible(bool isVisible);//visible by default at construction
  
 private:
Index: trunk/lib/FlairSimulator/src/unexported/Model_impl.h
===================================================================
--- trunk/lib/FlairSimulator/src/unexported/Model_impl.h	(revision 245)
+++ trunk/lib/FlairSimulator/src/unexported/Model_impl.h	(revision 286)
@@ -72,9 +72,4 @@
   void OnRegisterSceneNode(void);
   void render(void);
-  void Draw(void) {
-    printf("CA MARCHE PAS PUNAISE\r\n");
-    ExtraDraw();
-  };
-  void ExtraDraw(void) { printf("nope\r\n"); };
 
   const irr::core::aabbox3d<irr::f32> &getBoundingBox(void) const {
Index: trunk/lib/FlairSimulator/src/unexported/Simulator_impl.h
===================================================================
--- trunk/lib/FlairSimulator/src/unexported/Simulator_impl.h	(revision 245)
+++ trunk/lib/FlairSimulator/src/unexported/Simulator_impl.h	(revision 286)
@@ -37,5 +37,5 @@
 public:
   Simulator_impl(flair::simulator::Simulator *self, int optitrack_mstime = 10,
-                 float yaw_deg = 30);
+                 float yaw_deg = 30, int port=3883);
   ~Simulator_impl();
 
Index: trunk/lib/FlairSimulator/src/unexported/UavVrpnObject_impl.h
===================================================================
--- trunk/lib/FlairSimulator/src/unexported/UavVrpnObject_impl.h	(revision 286)
+++ trunk/lib/FlairSimulator/src/unexported/UavVrpnObject_impl.h	(revision 286)
@@ -0,0 +1,73 @@
+// %flair:license{
+// This file is part of the Flair framework distributed under the
+// CECILL-C License, Version 1.0.
+// %flair:license}
+//  created:    2018/12/11
+//  filename:   UavVrpnObject_impl.h
+//
+//  author:     Guillaume Sanahuja
+//              Copyright Heudiasyc UMR UTC/CNRS 7253
+//
+//  version:    $Id: $
+//
+//  purpose:    uav vrpn object, can display a real vrpn object in a simulated environment
+//
+/*********************************************************************/
+
+#ifndef UAVVRPNOBJECT_IMPL_H
+#define UAVVRPNOBJECT_IMPL_H
+
+#ifdef GL
+
+#include <IODevice.h>
+#include <IMeshSceneNode.h>
+
+namespace flair {
+  namespace gui {
+    class DoubleSpinBox;
+  }
+}
+
+namespace flair {
+  namespace simulator {
+    class Blade;
+    class UavVrpnObject;
+  }
+}
+
+class UavVrpnObject_impl : private flair::core::IODevice,
+                      public irr::scene::ISceneNode {
+public:
+  UavVrpnObject_impl(flair::simulator::UavVrpnObject *self,std::string name);
+  ~UavVrpnObject_impl();
+
+  void Draw(void);
+  
+  const irr::core::aabbox3d<irr::f32> &getBoundingBox(void) const {
+    return box;
+  }
+  
+ void render(void);
+
+private:
+  flair::simulator::Blade *fl_blade, *fr_blade, *rl_blade, *rr_blade;
+  flair::gui::DoubleSpinBox *arm_length;
+  irr::core::aabbox3d<irr::f32> box;
+  void OnRegisterSceneNode(void);
+  flair::simulator::UavVrpnObject *self;
+  
+  /*!
+  * \brief Update using provided datas
+  *
+  * Reimplemented from IODevice.
+  *
+  * \param data data from the parent to process
+  */
+  void UpdateFrom(const flair::core::io_data *data);
+
+};
+
+
+#endif // GL
+
+#endif // UAVVRPNOBJECT_IMPL_H
