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();
222 fg_material_->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
259 "Changes the visibility of other Displays in the camera view.");
338 Ogre::Pass* pass =
fg_material_->getTechnique( 0 )->getPass( 0 );
339 if( pass->getNumTextureUnitStates() > 0 )
341 Ogre::TextureUnitState* tex_unit = pass->getTextureUnitState( 0 );
342 tex_unit->setAlphaOperation( Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT,
alpha );
376 "No CameraInfo received on [" + QString::fromStdString(
caminfo_sub_.
getTopic() ) +
"]. Topic may not exist.");
399 static int count = 0;
401 ss <<
"OverlayCameraImageDisplayObject" <<
count++;
415 int width = rt->getWidth();
416 int height = rt->getHeight();
418 Ogre::PixelBox pb(width, height, 1, Ogre::PF_BYTE_RGB, data);
419 rt->copyContentsToMemory(pb);
423 for (
int i = 0; i <
overlay_->getTextureWidth(); i++) {
424 for (
int j = 0; j <
overlay_->getTextureHeight(); j++) {
425 Ogre::ColourValue c = pb.getColourAt(i, j, 0);
426 QColor color(c.r * 255, c.g * 255, c.b * 255,
texture_alpha_ * 255);
427 Hud.setPixel(i, j, color.rgba());
436 sensor_msgs::CameraInfo::ConstPtr info;
437 sensor_msgs::Image::ConstPtr image;
445 if( !info || !image )
459 rviz_time != image->header.stamp )
461 std::ostringstream
s;
462 s <<
"Time-syncing active and no image at timestamp " << rviz_time.
toSec() <<
".";
467 Ogre::Vector3 position;
468 Ogre::Quaternion orientation;
474 orientation = orientation * Ogre::Quaternion( Ogre::Degree( 180 ), Ogre::Vector3::UNIT_X );
476 float img_width = info->width;
477 float img_height = info->height;
482 ROS_DEBUG(
"Malformed CameraInfo on camera [%s], width = 0", qPrintable(
getName() ));
488 ROS_DEBUG(
"Malformed CameraInfo on camera [%s], height = 0", qPrintable(
getName() ));
492 if( img_height == 0.0 || img_width == 0.0 )
495 "Could not determine width/height of image due to malformed CameraInfo (either width or height is 0)" );
499 double fx = info->P[0];
500 double fy = info->P[5];
505 float zoom_y = zoom_x;
508 if( win_width != 0 && win_height != 0 )
510 float img_aspect = (img_width/fx) / (img_height/fy);
511 float win_aspect = win_width / win_height;
513 if ( img_aspect > win_aspect )
515 zoom_y = zoom_y / img_aspect * win_aspect;
519 zoom_x = zoom_x / win_aspect * img_aspect;
524 double tx = -1 * (info->P[3] / fx);
525 Ogre::Vector3 right = orientation * Ogre::Vector3::UNIT_X;
526 position = position + (right * tx);
528 double ty = -1 * (info->P[7] / fy);
529 Ogre::Vector3 down = orientation * Ogre::Vector3::UNIT_Y;
530 position = position + (down * ty);
542 double cx = info->P[2];
543 double cy = info->P[6];
545 double far_plane = 100;
546 double near_plane = 0.01;
548 Ogre::Matrix4 proj_matrix;
549 proj_matrix = Ogre::Matrix4::ZERO;
551 proj_matrix[0][0]= 2.0 * fx/img_width * zoom_x;
552 proj_matrix[1][1]= 2.0 * fy/img_height * zoom_y;
554 proj_matrix[0][2]= 2.0 * (0.5 - cx/img_width) * zoom_x;
555 proj_matrix[1][2]= 2.0 * (cy/img_height - 0.5) * zoom_y;
557 proj_matrix[2][2]= -(far_plane+near_plane) / (far_plane-near_plane);
558 proj_matrix[2][3]= -2.0*far_plane*near_plane / (far_plane-near_plane);
560 proj_matrix[3][2]= -1;
573 bg_screen_rect_->setCorners( -1.0f*zoom_x, 1.0f*zoom_y, 1.0f*zoom_x, -1.0f*zoom_y );
574 fg_screen_rect_->setCorners( -1.0f*zoom_x, 1.0f*zoom_y, 1.0f*zoom_x, -1.0f*zoom_y );
576 Ogre::AxisAlignedBox aabInf;
577 aabInf.setInfinite();