11 #include <OGRE/OgreManualObject.h> 12 #include <OGRE/OgreMaterialManager.h> 13 #include <OGRE/OgreSceneManager.h> 14 #include <OGRE/OgreSceneNode.h> 15 #include <OGRE/OgreTechnique.h> 16 #include <OGRE/OgreTextureManager.h> 17 #include <OGRE/OgreVector3.h> 29 frameNode_ = parentNode->createChildSceneNode();
39 Ogre::MaterialManager::getSingleton().remove(
material_->getName());
52 bool noColor, Ogre::ColourValue meshColor,
bool mapLayerColor, std::string colorLayer,
53 bool useRainbow,
bool invertRainbow, Ogre::ColourValue minColor, Ogre::ColourValue maxColor,
54 bool autocomputeIntensity,
float minIntensity,
float maxIntensity) {
55 const auto startTime = std::chrono::high_resolution_clock::now();
57 ROS_DEBUG(
"Unable to visualize grid map, no map data. Use setMessage() first!");
63 if (layerNames.size() < 1) {
64 ROS_DEBUG(
"Unable to visualize grid map, map must contain at least one layer.");
67 if ((!flatTerrain && !
map_.
exists(heightLayer)) || (!noColor && !flatColor && !
map_.
exists(colorLayer))) {
68 ROS_DEBUG(
"Unable to visualize grid map, requested layer(s) not available.");
78 if (rows < 2 || cols < 2) {
79 ROS_DEBUG(
"GridMap has not enough cells.");
88 const size_t nVertices = cols * rows;
99 if (std::find(basicLayers.begin(), basicLayers.end(), heightLayer) == basicLayers.end()) {
100 basicLayers.emplace_back(heightLayer);
105 Eigen::ArrayXXf heightOrFlatData;
107 heightOrFlatData = Eigen::ArrayXXf::Zero(heightData.rows(), heightData.cols());
109 heightOrFlatData = heightData.array();
116 }
else if(mapLayerColor) {
118 }
else if (!useRainbow) {
120 }
else if (!invertRainbow) {
126 const auto colorValues =
computeColorValues(heightData, colorData, coloringMethod, meshColor, minIntensity, maxIntensity,
127 autocomputeIntensity, minColor, maxColor);
133 Eigen::ArrayXXi indexToOgreIndex;
134 indexToOgreIndex.setConstant(rows, cols, -1);
139 for (
size_t i = 0; i < rows; ++i) {
140 for (
size_t j = 0; j < cols; ++j) {
141 std::vector<int> vertices;
142 std::vector<Ogre::ColourValue> colors;
146 if (!isValid(index(0), index(1))) {
150 manualObject_->position(position(0), position(1), heightOrFlatData(index(0), index(1)));
152 const Ogre::ColourValue& color = colorValues(index(0), index(1));
155 indexToOgreIndex(index(0), index(1)) = ogreIndex;
159 if (i == 0 || j == 0) {
164 std::vector<int> vertexIndices;
165 std::vector<Ogre::Vector3> vertexPositions;
166 for (
size_t k = 0; k < 2; k++) {
167 for (
size_t l = 0; l < 2; l++) {
169 if (!isValid(index(0), index(1))) {
172 const grid_map::Position position = topLeft.array() - index.cast<
double>() * resolution;
173 vertexIndices.emplace_back(indexToOgreIndex(index(0), index(1)));
174 vertexPositions.emplace_back(position(0), position(1), heightOrFlatData(index(0), index(1)));
179 if (vertexIndices.size() > 2) {
182 if (vertexIndices.size() == 3) {
183 manualObject_->triangle(vertexIndices[0], vertexIndices[1], vertexIndices[2]);
185 manualObject_->quad(vertexIndices[0], vertexIndices[2], vertexIndices[3], vertexIndices[1]);
195 if (vertexIndices.size() == 3) {
218 material_->getTechnique(0)->setLightingEnabled(
false);
220 if (alpha < 0.9998) {
221 material_->getTechnique(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
222 material_->getTechnique(0)->setDepthWriteEnabled(
false);
224 material_->getTechnique(0)->setSceneBlending(Ogre::SBT_REPLACE);
225 material_->getTechnique(0)->setDepthWriteEnabled(
true);
228 const auto stopTime = std::chrono::high_resolution_clock::now();
229 const auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(stopTime - startTime);
230 ROS_DEBUG_STREAM(
"Visualization of grid_map took: " << elapsedTime.count() <<
" ms.");
235 static uint32_t count = 0;
237 ss <<
"Mesh" << count++;
244 material_ = Ogre::MaterialManager::getSingleton().create(
materialName_, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
246 material_->getTechnique(0)->setLightingEnabled(
true);
247 material_->setCullingMode(Ogre::CULL_NONE);
256 Eigen::Ref<const grid_map::Matrix> colorData,
258 double minIntensity,
double maxIntensity,
bool autocomputeIntensity,
259 Ogre::ColourValue minColor, Ogre::ColourValue maxColor) {
264 if (autocomputeIntensity && isIntensityColoringMethod) {
265 minIntensity = colorData.minCoeffOfFinites();
266 maxIntensity = minIntensity + std::max(colorData.maxCoeffOfFinites() - minIntensity, 0.2);
269 switch (coloringMethod) {
271 return ColorArray::Constant(heightData.rows(), heightData.cols(), flatColor);
273 return colorData.unaryExpr([](
float color) {
274 Eigen::Vector3f colorVectorRGB;
276 return Ogre::ColourValue(colorVectorRGB(0), colorVectorRGB(1), colorVectorRGB(2));
279 return colorData.unaryExpr([&](
float color) {
284 return colorData.unaryExpr([&](
float color) {
289 return colorData.unaryExpr([&](
float color) {
294 throw std::invalid_argument(std::string(
"An unknown coloring method was provided: ") +
295 std::to_string(static_cast<int>(coloringMethod)));
304 const size_t nLines = 2 * (rows * (cols - 1) + cols * (rows - 1));
310 for (
const std::string& layer : basicLayers) {
311 isValid = isValid &&
map_.
get(layer).array().unaryExpr([](
float v) {
return std::isfinite(v); });
329 intensity = std::min(intensity, max_intensity);
330 intensity = std::max(intensity, min_intensity);
331 intensity = (intensity - min_intensity) / (max_intensity - min_intensity);
335 intensity = std::min(intensity, 1.0
f);
336 intensity = std::max(intensity, 0.0
f);
338 float h = intensity * 5.0f + 1.0f;
341 if (!(i & 1)) f = 1 - f;
344 Ogre::ColourValue color;
346 color[0] = n, color[1] = 0, color[2] = 1;
348 color[0] = 0, color[1] = n, color[2] = 1;
350 color[0] = 0, color[1] = 1, color[2] = n;
352 color[0] = n, color[1] = 1, color[2] = 0;
354 color[0] = 1, color[1] = n, color[2] = 0;
361 intensity = std::min(intensity, 1.0
f);
362 intensity = std::max(intensity, 0.0
f);
364 Ogre::ColourValue color;
365 color.r = intensity * (max_color.r - min_color.r) + min_color.r;
366 color.g = intensity * (max_color.g - min_color.g) + min_color.g;
367 color.b = intensity * (max_color.b - min_color.b) + min_color.b;
boost::shared_ptr< rviz::BillboardLine > meshLines_
Ogre::SceneManager * sceneManager_
bool getPosition(const Index &index, Position &position) const
ColorArray computeColorValues(Eigen::Ref< const grid_map::Matrix > heightData, Eigen::Ref< const grid_map::Matrix > colorData, GridMapVisual::ColoringMethod coloringMethod, Ogre::ColourValue flatColor, double minIntensity, double maxIntensity, bool autocomputeIntensity, Ogre::ColourValue minColor, Ogre::ColourValue maxColor)
void setFramePosition(const Ogre::Vector3 &position)
void computeVisualization(float alpha, bool showGridLines, bool flatTerrain, std::string heightLayer, bool flatColor, bool noColor, Ogre::ColourValue meshColor, bool mapLayerColor, std::string colorLayer, bool useRainbow, bool invertRainbow, Ogre::ColourValue minColor, Ogre::ColourValue maxColor, bool autocomputeIntensity, float minIntensity, float maxIntensity)
static void normalizeIntensity(float &intensity, float minIntensity, float maxIntensity)
Ogre::MaterialPtr material_
static Ogre::ColourValue getRainbowColor(float intensity)
void convertToDefaultStartIndex()
bool exists(const std::string &layer) const
Ogre::ManualObject * manualObject_
Ogre::ColourValue getInterpolatedColor(float intensity, Ogre::ColourValue minColor, Ogre::ColourValue maxColor)
static bool fromMessage(const grid_map_msgs::GridMap &message, grid_map::GridMap &gridMap, const std::vector< std::string > &layers, bool copyBasicLayers=true, bool copyAllNonBasicLayers=true)
double getResolution() const
const std::vector< std::string > & getLayers() const
std::vector< std::string > getLayerNames()
const Matrix & get(const std::string &layer) const
GridMapVisual(Ogre::SceneManager *sceneManager, Ogre::SceneNode *parentNode)
void initializeMeshLines(size_t cols, size_t rows, double resolution, double alpha)
std::string materialName_
#define ROS_DEBUG_STREAM(args)
void initializeAndBeginManualObject(size_t nVertices)
void setFrameOrientation(const Ogre::Quaternion &orientation)
MaskArray computeIsValidMask(std::vector< std::string > basicLayers)
bool colorValueToVector(const unsigned long &colorValue, Eigen::Vector3i &colorVector)
Eigen::Array< bool, Eigen::Dynamic, Eigen::Dynamic > MaskArray
Ogre::SceneNode * frameNode_
const std::vector< std::string > & getBasicLayers() const
const Size & getSize() const
Eigen::Array< Ogre::ColourValue, Eigen::Dynamic, Eigen::Dynamic > ColorArray
void setMessage(const grid_map_msgs::GridMap::ConstPtr &msg)