VirtualCamera.h
Go to the documentation of this file.
00001 /* 
00002  * Copyright (c) 2013 University of Jaume-I.
00003  * All rights reserved. This program and the accompanying materials
00004  * are made available under the terms of the GNU Public License v3.0
00005  * which accompanies this distribution, and is available at
00006  * http://www.gnu.org/licenses/gpl.html
00007  * 
00008  * Contributors:
00009  *     Mario Prats
00010  *     Javier Perez
00011  */
00012 
00013 #ifndef VIRTUALCAMERA_H_
00014 #define VIRTUALCAMERA_H_
00015 
00016 #include "SimulatorConfig.h"
00017 #include "CustomWidget.h"
00018 #include "ConfigXMLParser.h"
00019 #include "UWSimUtils.h"
00020 
00021 #include <osgViewer/Viewer>
00022 #include <osgGA/NodeTrackerManipulator>
00023 #include <osg/Camera>
00024 #include <osg/Texture2D>
00025 #include <osgGA/GUIEventHandler>
00026 #include <osg/Geometry>
00027 #include <osg/NodeTrackerCallback>
00028 #include <osg/Switch>
00029 #include <osg/Geode>
00030 #include <osg/Geometry>
00031 #include <osg/Vec3>
00032 #include <osg/Drawable>
00033 #include <osg/LineWidth>
00034 #include <osg/io_utils>
00035 
00036 #include <GL/glu.h>
00037 
00038 #include <ros/ros.h>
00039 
00040 #include <tf/transform_datatypes.h>
00041 
00043 class VirtualCamera : public CustomWidget, public osg::Referenced
00044 {
00045 
00046   //Custom node tracking
00047   class MyNodeTrackerCallback : public osg::NodeTrackerCallback
00048   {
00049     osg::ref_ptr<osg::Camera> osgcamera;
00050     osg::ref_ptr<osg::Image> zbuffer;
00051     osg::Matrixd previous_wMc;
00052 
00053     double show_path_;
00054 
00055     ros::Time previous, current;
00056 
00057     void operator()(osg::Node *node, osg::NodeVisitor *nv)
00058     {
00059       //std::cerr << "Node Tracker callback" << std::endl;
00060       osg::Matrixd m;
00061       //((osg::Transform*)node)->computeWorldToLocalMatrix(m,nv);
00062       m = osg::computeWorldToLocal(nv->getNodePath());
00063       traverse(node, nv);
00064       osgcamera->setViewMatrix(m);
00065 
00066       //Check for the time ellapsed since the last time. If greater than showfov rate (if defined),
00067       //and displacement greater than min_displacement, attach the current FOV to the root
00068       current = ros::Time::now();
00069       if (show_path_ > 0 && (current - previous).toSec() > show_path_)
00070       {
00071         previous = current;
00072 
00073         osg::Matrixd wMc = osgcamera->getViewMatrix();
00074         if ((wMc.getTrans() - previous_wMc.getTrans()).length() > 0.15)
00075         {
00076           previous_wMc = wMc;
00077 
00078           osg::Matrixd projm = osgcamera->getProjectionMatrix();
00079 
00080           GLint viewport[4];
00081           viewport[0] = osgcamera->getViewport()->x();
00082           viewport[1] = osgcamera->getViewport()->y();
00083           viewport[2] = osgcamera->getViewport()->width();
00084           viewport[3] = osgcamera->getViewport()->height();
00085 
00086           double z_b[4];
00087           z_b[0] = ((float*)zbuffer->data())[0];
00088           z_b[1] = ((float*)zbuffer->data())[viewport[2] - 1];
00089           z_b[2] = ((float*)zbuffer->data())[viewport[2] * viewport[3] - 1];
00090           z_b[3] = ((float*)zbuffer->data())[viewport[2] * viewport[3] - viewport[2]];
00091 
00092           if (z_b[0] > 0 || z_b[1] > 0 || z_b[2] > 0 || z_b[3] > 0)
00093           {
00094             double X[4], Y[4], Z[4];
00095             gluUnProject(0, 0, z_b[0] * 0.9999, wMc.ptr(), projm.ptr(), viewport, &X[0], &Y[0], &Z[0]);
00096             gluUnProject(viewport[2], 0, z_b[1] * 0.9999, wMc.ptr(), projm.ptr(), viewport, &X[1], &Y[1], &Z[1]);
00097             gluUnProject(viewport[2], viewport[3], z_b[2] * 0.9999, wMc.ptr(), projm.ptr(), viewport, &X[2], &Y[2],
00098                          &Z[2]);
00099             gluUnProject(0, viewport[3], z_b[3] * 0.9999, wMc.ptr(), projm.ptr(), viewport, &X[3], &Y[3], &Z[3]);
00100 
00101             cameraPathVertices->push_back(osg::Vec3d(X[0], Y[0], Z[0]));
00102             cameraPathVertices->push_back(osg::Vec3d(X[1], Y[1], Z[1]));
00103             cameraPathVertices->push_back(osg::Vec3d(X[2], Y[2], Z[2]));
00104             cameraPathVertices->push_back(osg::Vec3d(X[3], Y[3], Z[3]));
00105 
00106             cameraPathVertices->push_back(osg::Vec3d(X[0], Y[0], Z[0]));
00107             cameraPathGeometry->setVertexArray(cameraPathVertices);
00108             ((osg::DrawArrays*)cameraPathPrset.get())->setFirst(0);
00109             ((osg::DrawArrays*)cameraPathPrset.get())->setCount(cameraPathVertices->size());
00110           }
00111         }
00112       }
00113     }
00114   public:
00115     //Attributes that store the camera path projected on the terrain
00116     osg::ref_ptr<osg::Switch> cameraPathSwitch;
00117     osg::ref_ptr<osg::Geode> cameraPathGeode;
00118     osg::ref_ptr<osg::Geometry> cameraPathGeometry;
00119     osg::ref_ptr<osg::Vec3Array> cameraPathVertices;
00120     osg::ref_ptr<osg::Vec4Array> cameraPathColors;
00121     osg::ref_ptr<osg::PrimitiveSet> cameraPathPrset;
00122 
00123     MyNodeTrackerCallback(osg::Group *uwsim_root, osg::Image *zbuffer, osg::Camera *cam)
00124     {
00125       this->zbuffer = zbuffer;
00126       this->osgcamera = cam;
00127       show_path_ = 0;
00128 
00129       previous = ros::Time::now();
00130 
00131       cameraPathSwitch = new osg::Switch();
00132       uwsim_root->addChild(cameraPathSwitch);
00133       cameraPathSwitch->setAllChildrenOn();
00134 
00135       cameraPathGeode = new osg::Geode();
00136       cameraPathGeometry = new osg::Geometry();
00137       cameraPathVertices = new osg::Vec3Array;
00138       cameraPathGeometry->setVertexArray(cameraPathVertices);
00139       cameraPathColors = new osg::Vec4Array;
00140       cameraPathColors->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); //TODO: Allow user set color
00141       cameraPathGeometry->setColorArray(cameraPathColors);
00142       cameraPathGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
00143       cameraPathPrset = new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, 0);
00144       cameraPathGeometry->addPrimitiveSet(cameraPathPrset);
00145       cameraPathGeode->addDrawable(cameraPathGeometry);
00146 
00147       osg::LineWidth* linewidth = new osg::LineWidth();
00148       linewidth->setWidth(3.0f);
00149       cameraPathGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON);
00150 
00151       cameraPathSwitch->addChild(cameraPathGeode);
00152 
00153     }
00154 
00155     void showPath(double rate)
00156     {
00157       show_path_ = rate;
00158     }
00159   };
00160 
00161 public:
00162   std::string name, parentLinkName;
00163   osg::ref_ptr<osg::Group> uwsim_root;
00164   osg::ref_ptr<osg::Camera> textureCamera;
00165   osg::Node *trackNode;
00166   osg::ref_ptr<MyNodeTrackerCallback> node_tracker;
00167 
00168   int width, height, range;
00169   double fx, fy, cx, cy; 
00170   double aspectRatio, fov, far, near, k;
00171   double baseline; //Only for stereo. Default=0
00172   double Tx, Ty; //Only for stereo.
00173   std::string frameId; //Default=""
00174   int paramsOn;
00175   int bw; //BlackWhite camera
00176   int widget; //Widget available or not
00177   float std;//Camera noise
00178 
00179   osg::ref_ptr<osg::Image> renderTexture; //RGB image
00180   osg::ref_ptr<osg::Image> depthTexture; //Range image
00181 
00182   VirtualCamera(osg::Group *uwsim_root, std::string name,std::string parentName, osg::Node *trackNode, int width, double fov, double range);
00183   VirtualCamera(osg::Group *uwsim_root, std::string name,std::string parentName, osg::Node *trackNode, int width, int height, double fov,
00184                 double aspectRatio);
00185   VirtualCamera(osg::Group *uwsim_root, std::string name,std::string parentName, osg::Node *trackNode, int width, int height, double baseline,
00186                 std::string frameId,double fov,SceneBuilder *oscene,float std, Parameters *params, int range, int bw);
00187   VirtualCamera();
00188 
00189   void init(osg::Group *uwsim_root, std::string name,std::string parentName, osg::Node *trackNode, int width, int height, double baseline,
00190             std::string frameId, Parameters *params, int range, double fov, double aspectRatio, double near, double far,
00191             int bw, int widget,SceneBuilder *oscene, float std);
00192 
00193   //Creates the uniforms and loads the shader for the camera.
00194   void loadShaders(SceneBuilder *oscene);
00195 
00196   int getTFTransform(tf::Pose & pose, std::string & parent);
00197 
00198   void createCamera();
00199 
00200   void showPath(double rate)
00201   {
00202     node_tracker->showPath(rate);
00203   }
00204 
00205   //Interface to be implemented by widgets. Build a widget window with the data to be displayed
00206   osg::ref_ptr<osgWidget::Window> getWidgetWindow();
00207 };
00208 
00209 #endif /* VIRTUALCAMERA_H_ */


uwsim
Author(s): Mario Prats , Javier Perez
autogenerated on Fri Aug 28 2015 13:28:58