void PointCloud2Display::processMessage( const sensor_msgs::PointCloud2ConstPtr& cloud ) { // Filter any nan values out of the cloud. Any nan values that make it through to PointCloudBase // will get their points put off in lala land, but it means they still do get processed/rendered // which can be a big performance hit sensor_msgs::PointCloud2Ptr filtered(new sensor_msgs::PointCloud2); int32_t xi = findChannelIndex(cloud, "x"); int32_t yi = findChannelIndex(cloud, "y"); int32_t zi = findChannelIndex(cloud, "z"); if (xi == -1 || yi == -1 || zi == -1) { return; } const uint32_t xoff = cloud->fields[xi].offset; const uint32_t yoff = cloud->fields[yi].offset; const uint32_t zoff = cloud->fields[zi].offset; const uint32_t point_step = cloud->point_step; const size_t point_count = cloud->width * cloud->height; filtered->data.resize(cloud->data.size()); if (point_count == 0) { return; } uint32_t output_count = 0; const uint8_t* ptr = &cloud->data.front(); for (size_t i = 0; i < point_count; ++i) { float x = *reinterpret_cast<const float*>(ptr + xoff); float y = *reinterpret_cast<const float*>(ptr + yoff); float z = *reinterpret_cast<const float*>(ptr + zoff); if (validateFloats(Ogre::Vector3(x, y, z))) { memcpy(&filtered->data.front() + (output_count * point_step), ptr, point_step); ++output_count; } ptr += point_step; } filtered->header = cloud->header; filtered->fields = cloud->fields; filtered->data.resize(output_count * point_step); filtered->height = 1; filtered->width = output_count; filtered->is_bigendian = cloud->is_bigendian; filtered->point_step = point_step; filtered->row_step = output_count; point_cloud_common_->addMessage( filtered ); }
Ogre::Vector3 pointFromCloud(const sensor_msgs::PointCloud2ConstPtr& cloud, uint32_t index) { int32_t xi = findChannelIndex(cloud, "x"); int32_t yi = findChannelIndex(cloud, "y"); int32_t zi = findChannelIndex(cloud, "z"); const uint32_t xoff = cloud->fields[xi].offset; const uint32_t yoff = cloud->fields[yi].offset; const uint32_t zoff = cloud->fields[zi].offset; const uint8_t type = cloud->fields[xi].datatype; const uint32_t point_step = cloud->point_step; float x = valueFromCloud<float>(cloud, xoff, type, point_step, index); float y = valueFromCloud<float>(cloud, yoff, type, point_step, index); float z = valueFromCloud<float>(cloud, zoff, type, point_step, index); return Ogre::Vector3(x, y, z); }