36 #include <boost/bind.hpp>
38 #include <OgreManualObject.h>
39 #include <OgreMaterialManager.h>
40 #include <OgreRectangle2D.h>
41 #include <OgreRenderSystem.h>
42 #include <OgreRenderWindow.h>
43 #include <OgreSceneManager.h>
44 #include <OgreSceneNode.h>
45 #include <OgreTextureManager.h>
46 #include <OgreViewport.h>
47 #include <OgreTechnique.h>
48 #include <OgreCamera.h>
49 #include <OgrePixelFormat.h>
50 #include <OGRE/OgreHardwarePixelBuffer.h>
51 #include <OGRE/OgreTechnique.h>
92 , caminfo_tf_filter_( 0 )
93 , new_caminfo_( false )
94 , force_render_( false )
97 image_position_property_ =
new EnumProperty(
"Image Rendering", BOTH,
98 "Render the image behind all other geometry or overlay it on top, or both.",
99 this, SLOT( forceRender() ));
100 image_position_property_->addOption( BACKGROUND );
101 image_position_property_->addOption( OVERLAY );
102 image_position_property_->addOption( BOTH );
105 "The amount of transparency to apply to the camera image when rendered as overlay.",
106 this, SLOT( updateAlpha() ));
107 alpha_property_->setMin( 0 );
108 alpha_property_->setMax( 1 );
112 "Set a zoom factor below 1 to see a larger part of the world, above 1 to magnify the image.",
113 this, SLOT( forceRender() ));
114 zoom_property_->setMin( 0.00001 );
115 zoom_property_->setMax( 100000 );
118 "width of overlay image",
119 this, SLOT(updateWidth()));
121 "height of overlay image",
122 this, SLOT(updateHeight()));
124 "left positoin of overlay image",
125 this, SLOT(updateLeft()));
127 "top positoin of overlay image",
128 this, SLOT(updateTop()));
129 texture_alpha_property_ =
new FloatProperty(
"texture alpha", 0.8,
131 this, SLOT(updateTextureAlpha()));
132 texture_alpha_property_->setMin(0.0);
133 texture_alpha_property_->setMax(1.0);
166 #if ROS_VERSION_MINIMUM(1, 15, 0) // noetic and greater
180 static int count = 0;
182 ss <<
"OverlayCameraDisplayObject" <<
count++;
189 bg_material_ = Ogre::MaterialManager::getSingleton().create( ss.str(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
195 bg_material_->getTechnique(0)->setLightingEnabled(
false);
196 Ogre::TextureUnitState* tu =
bg_material_->getTechnique(0)->getPass(0)->createTextureUnitState();
198 tu->setTextureFiltering( Ogre::TFO_NONE );
199 tu->setAlphaOperation( Ogre::LBX_SOURCE1, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, 0.0 );
204 Ogre::AxisAlignedBox aabInf;
205 aabInf.setInfinite();
209 #if ((OGRE_VERSION_MAJOR << 16) | (OGRE_VERSION_MINOR << 8) | OGRE_VERSION_PATCH) < ((1 << 16) | (10 << 8) | 0)
224 #if ((OGRE_VERSION_MAJOR << 16) | (OGRE_VERSION_MINOR << 8) | OGRE_VERSION_PATCH) < ((1 << 16) | (10 << 8) | 0)
230 fg_material_->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
267 "Changes the visibility of other Displays in the camera view.");
346 Ogre::Pass* pass =
fg_material_->getTechnique( 0 )->getPass( 0 );
347 if( pass->getNumTextureUnitStates() > 0 )
349 Ogre::TextureUnitState* tex_unit = pass->getTextureUnitState( 0 );
350 tex_unit->setAlphaOperation( Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT,
alpha );
384 "No CameraInfo received on [" + QString::fromStdString(
caminfo_sub_.
getTopic() ) +
"]. Topic may not exist.");
407 static int count = 0;
409 ss <<
"OverlayCameraImageDisplayObject" <<
count++;
423 int width = rt->getWidth();
424 int height = rt->getHeight();
426 Ogre::PixelBox pb(width, height, 1, Ogre::PF_BYTE_RGB, data);
427 rt->copyContentsToMemory(pb);
431 for (
int i = 0; i <
overlay_->getTextureWidth(); i++) {
432 for (
int j = 0; j <
overlay_->getTextureHeight(); j++) {
433 Ogre::ColourValue c = pb.getColourAt(i, j, 0);
434 QColor color(c.r * 255, c.g * 255, c.b * 255,
texture_alpha_ * 255);
435 Hud.setPixel(i, j, color.rgba());
444 sensor_msgs::CameraInfo::ConstPtr info;
445 sensor_msgs::Image::ConstPtr image;
453 if( !info || !image )
467 rviz_time != image->header.stamp )
469 std::ostringstream
s;
470 s <<
"Time-syncing active and no image at timestamp " << rviz_time.
toSec() <<
".";
475 Ogre::Vector3 position;
476 Ogre::Quaternion orientation;
482 orientation = orientation * Ogre::Quaternion( Ogre::Degree( 180 ), Ogre::Vector3::UNIT_X );
484 float img_width = info->width;
485 float img_height = info->height;
490 ROS_DEBUG(
"Malformed CameraInfo on camera [%s], width = 0", qPrintable(
getName() ));
496 ROS_DEBUG(
"Malformed CameraInfo on camera [%s], height = 0", qPrintable(
getName() ));
500 if( img_height == 0.0 || img_width == 0.0 )
503 "Could not determine width/height of image due to malformed CameraInfo (either width or height is 0)" );
507 double fx = info->P[0];
508 double fy = info->P[5];
513 float zoom_y = zoom_x;
516 if( win_width != 0 && win_height != 0 )
518 float img_aspect = (img_width/fx) / (img_height/fy);
519 float win_aspect = win_width / win_height;
521 if ( img_aspect > win_aspect )
523 zoom_y = zoom_y / img_aspect * win_aspect;
527 zoom_x = zoom_x / win_aspect * img_aspect;
532 double tx = -1 * (info->P[3] / fx);
533 Ogre::Vector3 right = orientation * Ogre::Vector3::UNIT_X;
534 position = position + (right * tx);
536 double ty = -1 * (info->P[7] / fy);
537 Ogre::Vector3 down = orientation * Ogre::Vector3::UNIT_Y;
538 position = position + (down * ty);
550 double cx = info->P[2];
551 double cy = info->P[6];
553 double far_plane = 100;
554 double near_plane = 0.01;
556 Ogre::Matrix4 proj_matrix;
557 proj_matrix = Ogre::Matrix4::ZERO;
559 proj_matrix[0][0]= 2.0 * fx/img_width * zoom_x;
560 proj_matrix[1][1]= 2.0 * fy/img_height * zoom_y;
562 proj_matrix[0][2]= 2.0 * (0.5 - cx/img_width) * zoom_x;
563 proj_matrix[1][2]= 2.0 * (cy/img_height - 0.5) * zoom_y;
565 proj_matrix[2][2]= -(far_plane+near_plane) / (far_plane-near_plane);
566 proj_matrix[2][3]= -2.0*far_plane*near_plane / (far_plane-near_plane);
568 proj_matrix[3][2]= -1;
581 bg_screen_rect_->setCorners( -1.0f*zoom_x, 1.0f*zoom_y, 1.0f*zoom_x, -1.0f*zoom_y );
582 fg_screen_rect_->setCorners( -1.0f*zoom_x, 1.0f*zoom_y, 1.0f*zoom_x, -1.0f*zoom_y );
584 Ogre::AxisAlignedBox aabInf;
585 aabInf.setInfinite();