00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00060 osg::Matrixd m;
00061
00062 m = osg::computeWorldToLocal(nv->getNodePath());
00063 traverse(node, nv);
00064 osgcamera->setViewMatrix(m);
00065
00066
00067
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
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));
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;
00172 double Tx, Ty;
00173 std::string frameId;
00174 int paramsOn;
00175 int bw;
00176 int widget;
00177 float std;
00178
00179 osg::ref_ptr<osg::Image> renderTexture;
00180 osg::ref_ptr<osg::Image> depthTexture;
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
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
00206 osg::ref_ptr<osgWidget::Window> getWidgetWindow();
00207 };
00208
00209 #endif