diff --git a/examples/lidar_visual/Main.cc b/examples/lidar_visual/Main.cc index e1c1a30a7..71e3eebff 100644 --- a/examples/lidar_visual/Main.cc +++ b/examples/lidar_visual/Main.cc @@ -213,6 +213,7 @@ LidarVisualPtr createLidar(ScenePtr _scene) lidar->SetMaxVerticalAngle(vMaxAngle); lidar->SetMaxRange(maxRange); lidar->SetMinRange(minRange); + lidar->SetSize(5.0); // the types can be set as follows:- // LVT_POINTS -> Lidar Points at the range value diff --git a/examples/lidar_visual/README.md b/examples/lidar_visual/README.md index 3e0155035..b0e9b8793 100644 --- a/examples/lidar_visual/README.md +++ b/examples/lidar_visual/README.md @@ -20,7 +20,7 @@ By default, the demo uses the Ogre 1 engine: ./lidar_visual -It's also possible to use Ogre 2, i.e. (Currently disabled) +It's also possible to use Ogre 2: ./lidar_visual ogre2 diff --git a/include/ignition/rendering/LidarVisual.hh b/include/ignition/rendering/LidarVisual.hh index 417826c1c..1d2314f30 100644 --- a/include/ignition/rendering/LidarVisual.hh +++ b/include/ignition/rendering/LidarVisual.hh @@ -171,6 +171,16 @@ namespace ignition /// \return The type for lidar visual public: virtual LidarVisualType Type() const = 0; + /// \brief Set size of the lidar visualization, + /// e.g. size of rasterized lidar points in pixels + /// \param[in] _size Size of the lidar visualization. + public: virtual void SetSize(double _size) = 0; + + /// \brief Get size of the lidar visualization + /// \return Size of the lidar visualization. + /// \sa SetSize + public: virtual double Size() const = 0; + /// \brief Set if non-hitting rays will be displayed /// (this does not work for TRIANGLE_STRIPS visual) /// \param[in] _display Boolean value to display non hitting visuals diff --git a/include/ignition/rendering/Marker.hh b/include/ignition/rendering/Marker.hh index 9b4844bdd..85b4795d7 100644 --- a/include/ignition/rendering/Marker.hh +++ b/include/ignition/rendering/Marker.hh @@ -108,6 +108,16 @@ namespace ignition /// \return The render type of the marker public: virtual ignition::rendering::MarkerType Type() const = 0; + /// \brief Set size of the marker. Only affects MT_POINTS. + /// e.g. size of rasterized points in pixels + /// \param[in] _size Size of the marker + public: virtual void SetSize(double _size) = 0; + + /// \brief Get the size of the marker. + /// \return The size of the marker + /// \sa SetSize + public: virtual double Size() const = 0; + /// \brief Clear the points of the marker, if applicable public: virtual void ClearPoints() = 0; diff --git a/include/ignition/rendering/base/BaseLidarVisual.hh b/include/ignition/rendering/base/BaseLidarVisual.hh index c2cf9a1df..4e0edb24d 100644 --- a/include/ignition/rendering/base/BaseLidarVisual.hh +++ b/include/ignition/rendering/base/BaseLidarVisual.hh @@ -138,6 +138,12 @@ namespace ignition // Documentation inherited public: virtual LidarVisualType Type() const override; + // Documentation inherited + public: virtual void SetSize(double _size) override; + + // Documentation inherited + public: virtual double Size() const override; + /// \brief Create predefined materials for lidar visual public: virtual void CreateMaterials(); @@ -186,6 +192,9 @@ namespace ignition /// \brief Type of lidar visualisation protected: LidarVisualType lidarVisualType = LidarVisualType::LVT_TRIANGLE_STRIPS; + + /// \brief Size of lidar visualisation + protected: double size = 1.0; }; ///////////////////////////////////////////////// @@ -432,6 +441,20 @@ namespace ignition return this->lidarVisualType; } + ///////////////////////////////////////////////// + template + void BaseLidarVisual::SetSize(double _size) + { + this->size = _size; + } + + ///////////////////////////////////////////////// + template + double BaseLidarVisual::Size() const + { + return this->size; + } + ///////////////////////////////////////////////// template void BaseLidarVisual::SetDisplayNonHitting(bool _display) diff --git a/include/ignition/rendering/base/BaseMarker.hh b/include/ignition/rendering/base/BaseMarker.hh index 7f5f83d2a..4de3193ba 100644 --- a/include/ignition/rendering/base/BaseMarker.hh +++ b/include/ignition/rendering/base/BaseMarker.hh @@ -60,6 +60,12 @@ namespace ignition // Documentation inherited public: virtual MarkerType Type() const override; + // Documentation inherited + public: virtual void SetSize(double _size) override; + + // Documentation inherited + public: virtual double Size() const override; + // Documentation inherited public: virtual void SetLayer(int32_t _layer) override; @@ -97,6 +103,9 @@ namespace ignition /// \brief Marker type protected: MarkerType markerType = ignition::rendering::MarkerType::MT_NONE; + + /// \brief Marker size + protected: double size = 1.0; }; ///////////////////////////////////////////////// @@ -159,6 +168,21 @@ namespace ignition return this->markerType; } + ///////////////////////////////////////////////// + template + void BaseMarker::SetSize(double _size) + { + this->size = _size; + this->markerDirty = true; + } + + ///////////////////////////////////////////////// + template + double BaseMarker::Size() const + { + return this->size; + } + ///////////////////////////////////////////////// template void BaseMarker::PreRender() diff --git a/ogre/src/OgreLidarVisual.cc b/ogre/src/OgreLidarVisual.cc index 9b8f66af1..62c6b3800 100644 --- a/ogre/src/OgreLidarVisual.cc +++ b/ogre/src/OgreLidarVisual.cc @@ -12,7 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * */ #include @@ -486,6 +486,16 @@ void OgreLidarVisual::Update() verticalAngle += this->verticalAngleStep; } + if (this->dataPtr->lidarVisType == LidarVisualType::LVT_POINTS && + !this->dataPtr->points.empty()) + { + // get the PointCloudPoint material + Ogre::MaterialPtr mat = this->dataPtr->points[0]->getMaterial(); + auto pass = mat->getTechnique(0)->getPass(0); + auto params = pass->getVertexProgramParameters(); + params->setNamedConstant("size", static_cast(this->size)); + } + // The newly created dynamic lines are having default visibility as true. // The visibility needs to be set as per the current value after the new // renderables are created. diff --git a/ogre/src/OgreMarker.cc b/ogre/src/OgreMarker.cc index 21874d7f1..e08f22952 100644 --- a/ogre/src/OgreMarker.cc +++ b/ogre/src/OgreMarker.cc @@ -54,6 +54,30 @@ OgreMarker::~OgreMarker() ////////////////////////////////////////////////// void OgreMarker::PreRender() { + if (this->markerType == MarkerType::MT_POINTS && + this->dataPtr->dynamicRenderable && + this->dataPtr->dynamicRenderable->PointCount() > 0u) + { + std::string pointsMatName = "PointCloudPoint"; + if (this->dataPtr->dynamicRenderable->getMaterial().isNull() || + this->dataPtr->dynamicRenderable->getMaterial()->getName() + != pointsMatName) + { +#if (OGRE_VERSION <= ((1 << 16) | (10 << 8) | 7)) + this->dataPtr->dynamicRenderable->setMaterial(pointsMatName); +#else + Ogre::MaterialPtr pointsMat = + Ogre::MaterialManager::getSingleton().getByName( + pointsMatName); + this->dataPtr->dynamicRenderable->setMaterial(pointsMat); +#endif + } + auto pass = this->dataPtr->dynamicRenderable->getMaterial()->getTechnique( + 0)->getPass(0); + auto vertParams = pass->getVertexProgramParameters(); + vertParams->setNamedConstant("size", static_cast(this->size)); + } + this->dataPtr->dynamicRenderable->Update(); } diff --git a/ogre/src/media/materials/programs/point_vs.glsl b/ogre/src/media/materials/programs/point_vs.glsl index 97db65be4..016ae026a 100644 --- a/ogre/src/media/materials/programs/point_vs.glsl +++ b/ogre/src/media/materials/programs/point_vs.glsl @@ -5,10 +5,11 @@ // Works for perspective and orthographic projection. uniform mat4 worldviewproj_matrix; +uniform float size; void main() { gl_Position = worldviewproj_matrix * gl_Vertex; gl_FrontColor = gl_Color; - gl_PointSize = 10 / gl_Position.w; -} \ No newline at end of file + gl_PointSize = size; +} diff --git a/ogre/src/media/materials/scripts/point_cloud_point.material b/ogre/src/media/materials/scripts/point_cloud_point.material index 0e2d515a4..c708329f0 100644 --- a/ogre/src/media/materials/scripts/point_cloud_point.material +++ b/ogre/src/media/materials/scripts/point_cloud_point.material @@ -6,13 +6,13 @@ vertex_program PointCloudVS glsl default_params { param_named_auto worldviewproj_matrix worldviewproj_matrix + param_named size float 1.0 } } fragment_program PointCloudFS glsl { source point_fs.glsl - } material PointCloudPoint @@ -27,4 +27,4 @@ material PointCloudPoint fragment_program_ref PointCloudFS {} } } -} \ No newline at end of file +} diff --git a/ogre2/src/Ogre2DynamicRenderable.cc b/ogre2/src/Ogre2DynamicRenderable.cc index 52be0b32f..46c7a358a 100644 --- a/ogre2/src/Ogre2DynamicRenderable.cc +++ b/ogre2/src/Ogre2DynamicRenderable.cc @@ -342,6 +342,9 @@ void Ogre2DynamicRenderable::UpdateBuffer() // update item aabb if (this->dataPtr->ogreItem) { + bool castShadows = this->dataPtr->ogreItem->getCastShadows(); + auto lowLevelMat = this->dataPtr->ogreItem->getSubItem(0)->getMaterial(); + // need to rebuild ogre [sub]item because the vao was destroyed // this updates the item's bounding box and fixes occasional crashes // from invalid access to old vao @@ -356,6 +359,13 @@ void Ogre2DynamicRenderable::UpdateBuffer() this->dataPtr->ogreItem->setCastShadows( this->dataPtr->material->CastShadows()); } + else if (lowLevelMat) + { + // the _initialise call above resets the ogre item properties so set + // them again + this->dataPtr->ogreItem->getSubItem(0)->setMaterial(lowLevelMat); + this->dataPtr->ogreItem->setCastShadows(castShadows); + } } this->dataPtr->dirty = false; diff --git a/ogre2/src/Ogre2LidarVisual.cc b/ogre2/src/Ogre2LidarVisual.cc index f7f458557..98a604a39 100644 --- a/ogre2/src/Ogre2LidarVisual.cc +++ b/ogre2/src/Ogre2LidarVisual.cc @@ -15,8 +15,19 @@ * */ +#ifdef __APPLE__ + #define GL_SILENCE_DEPRECATION + #include + #include +#else +#ifndef _WIN32 + #include +#endif +#endif #include + +#include "ignition/rendering/ogre2/Ogre2Conversions.hh" #include "ignition/rendering/ogre2/Ogre2DynamicRenderable.hh" #include "ignition/rendering/ogre2/Ogre2LidarVisual.hh" #include "ignition/rendering/ogre2/Ogre2Scene.hh" @@ -26,7 +37,10 @@ #ifdef _MSC_VER #pragma warning(push, 0) #endif +#include +#include #include +#include #ifdef _MSC_VER #pragma warning(pop) #endif @@ -63,6 +77,10 @@ class ignition::rendering::Ogre2LidarVisualPrivate /// \brief The visibility of the visual public: bool visible = true; + + /// \brief Pointer to point cloud material. + /// Used when LidarVisualType = LVT_POINTS. + public: Ogre::MaterialPtr pointsMat; }; using namespace ignition; @@ -121,6 +139,7 @@ void Ogre2LidarVisual::Destroy() } this->dataPtr->lidarPoints.clear(); + this->dataPtr->pointsMat.setNull(); } ////////////////////////////////////////////////// @@ -133,6 +152,18 @@ void Ogre2LidarVisual::Init() ////////////////////////////////////////////////// void Ogre2LidarVisual::Create() { + // enable GL_PROGRAM_POINT_SIZE so we can set gl_PointSize in vertex shader +#ifdef __APPLE__ + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); +#else +#ifndef _WIN32 + glEnable(GL_PROGRAM_POINT_SIZE); +#endif +#endif + this->dataPtr->pointsMat = + Ogre::MaterialManager::getSingleton().getByName( + "PointCloudPoint"); + this->ClearPoints(); this->dataPtr->receivedData = false; } @@ -300,8 +331,11 @@ void Ogre2LidarVisual::Update() new Ogre2DynamicRenderable(this->Scene())); renderable->SetOperationType(MT_POINTS); - MaterialPtr mat = this->Scene()->Material("Lidar/BlueRay"); - renderable->SetMaterial(mat, false); + + // use low level programmable material so we can customize point size + Ogre::Item *item = dynamic_cast(renderable->OgreObject()); + item->setCastShadows(false); + item->getSubItem(0)->setMaterial(this->dataPtr->pointsMat); this->ogreNode->attachObject(renderable->OgreObject()); this->dataPtr->points.push_back(renderable); @@ -441,6 +475,22 @@ void Ogre2LidarVisual::Update() verticalAngle += this->verticalAngleStep; } + if (this->dataPtr->lidarVisType == LidarVisualType::LVT_POINTS && + !this->dataPtr->points.empty()) + { + // point renderables use low level materials + // get the material and set size uniform variable + auto pass = this->dataPtr->pointsMat->getTechnique(0)->getPass(0); + auto vertParams = pass->getVertexProgramParameters(); + vertParams->setNamedConstant("size", static_cast(this->size)); + + // support setting color only from diffuse for now + MaterialPtr mat = this->Scene()->Material("Lidar/BlueRay"); + auto fragParams = pass->getFragmentProgramParameters(); + fragParams->setNamedConstant("color", + Ogre2Conversions::Convert(mat->Diffuse())); + } + // The newly created dynamic lines are having default visibility as true. // The visibility needs to be set as per the current value after the new // renderables are created. diff --git a/ogre2/src/Ogre2Marker.cc b/ogre2/src/Ogre2Marker.cc index 01a1a5b57..3fa3c5151 100644 --- a/ogre2/src/Ogre2Marker.cc +++ b/ogre2/src/Ogre2Marker.cc @@ -15,12 +15,23 @@ * */ +#ifdef __APPLE__ + #define GL_SILENCE_DEPRECATION + #include + #include +#else +#ifndef _WIN32 + #include +#endif +#endif + #include #include #include #include "ignition/rendering/ogre2/Ogre2Capsule.hh" +#include "ignition/rendering/ogre2/Ogre2Conversions.hh" #include "ignition/rendering/ogre2/Ogre2DynamicRenderable.hh" #include "ignition/rendering/ogre2/Ogre2Marker.hh" #include "ignition/rendering/ogre2/Ogre2Material.hh" @@ -28,6 +39,16 @@ #include "ignition/rendering/ogre2/Ogre2Scene.hh" #include "ignition/rendering/ogre2/Ogre2Visual.hh" +#ifdef _MSC_VER + #pragma warning(push, 0) +#endif +#include +#include +#include +#ifdef _MSC_VER + #pragma warning(pop) +#endif + class ignition::rendering::Ogre2MarkerPrivate { /// \brief Marker material @@ -62,6 +83,45 @@ Ogre2Marker::~Ogre2Marker() ////////////////////////////////////////////////// void Ogre2Marker::PreRender() { + if (this->markerType == MarkerType::MT_POINTS && + this->dataPtr->dynamicRenderable && + this->dataPtr->dynamicRenderable->PointCount() > 0u) + { + Ogre::Item *item = dynamic_cast( + this->dataPtr->dynamicRenderable->OgreObject()); + if (!item->getSubItem(0)->getMaterial() || + item->getSubItem(0)->getMaterial()->getName() != "PointCloudPoint") + { + // enable GL_PROGRAM_POINT_SIZE so we can set gl_PointSize in vertex + // shader + #ifdef __APPLE__ + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + #else + #ifndef _WIN32 + glEnable(GL_PROGRAM_POINT_SIZE); + #endif + #endif + Ogre::MaterialPtr pointsMat = + Ogre::MaterialManager::getSingleton().getByName( + "PointCloudPoint"); + item->getSubItem(0)->setMaterial(pointsMat); + } + + // point renderables use low level materials + // get the material and set size uniform variable + auto pass = item->getSubItem(0)->getMaterial()->getTechnique(0)->getPass(0); + auto vertParams = pass->getVertexProgramParameters(); + vertParams->setNamedConstant("size", static_cast(this->size)); + + // support setting color only from diffuse for now + if (this->dataPtr->material) + { + auto fragParams = pass->getFragmentProgramParameters(); + fragParams->setNamedConstant("color", + Ogre2Conversions::Convert(this->dataPtr->material->Diffuse())); + } + } + this->dataPtr->dynamicRenderable->Update(); } diff --git a/ogre2/src/media/materials/programs/point_fs.glsl b/ogre2/src/media/materials/programs/point_fs.glsl new file mode 100644 index 000000000..a08d2c2ed --- /dev/null +++ b/ogre2/src/media/materials/programs/point_fs.glsl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#version 330 + +uniform vec4 color; + +out vec4 fragColor; + +void main() +{ + // todo(anyone) update Ogre2DynamicRenderable to support vertex coloring + // so we can set color using the line below + // fragColor = gl_Color; + fragColor = color; +} diff --git a/ogre2/src/media/materials/programs/point_vs.glsl b/ogre2/src/media/materials/programs/point_vs.glsl new file mode 100644 index 000000000..139e9f7b3 --- /dev/null +++ b/ogre2/src/media/materials/programs/point_vs.glsl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#version 330 + +in vec4 vertex; +uniform mat4 worldViewProj; +uniform float size; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + // Calculate output position + gl_Position = worldViewProj * vertex; + gl_PointSize = size; +} diff --git a/ogre2/src/media/materials/scripts/point_cloud_point.material b/ogre2/src/media/materials/scripts/point_cloud_point.material new file mode 100644 index 000000000..00221692e --- /dev/null +++ b/ogre2/src/media/materials/scripts/point_cloud_point.material @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +vertex_program PointCloudVS glsl +{ + source point_vs.glsl + + default_params + { + param_named_auto worldViewProj worldviewproj_matrix + param_named size float 1.0 + } +} + +fragment_program PointCloudFS glsl +{ + source point_fs.glsl + default_params + { + param_named color vec4 1.0 1.0 1.0 1.0 + } +} + +material PointCloudPoint +{ + technique + { + pass + { + point_size_attenuation on + point_sprites on + vertex_program_ref PointCloudVS {} + fragment_program_ref PointCloudFS {} + } + } +} diff --git a/src/LidarVisual_TEST.cc b/src/LidarVisual_TEST.cc index a205b76a8..5cc600e7b 100644 --- a/src/LidarVisual_TEST.cc +++ b/src/LidarVisual_TEST.cc @@ -107,6 +107,9 @@ void LidarVisualTest::LidarVisual(const std::string &_renderEngine) lidar->SetType(LVT_TRIANGLE_STRIPS); EXPECT_EQ(lidar->Type(), LVT_TRIANGLE_STRIPS); + EXPECT_DOUBLE_EQ(1.0, lidar->Size()); + lidar->SetSize(12.0); + EXPECT_DOUBLE_EQ(12.0, lidar->Size()); ignition::math::Pose3d p(0.5, 2.56, 3.67, 1.4, 2, 4.5); lidar->SetOffset(p); diff --git a/src/Marker_TEST.cc b/src/Marker_TEST.cc index 9a6861020..7510df123 100644 --- a/src/Marker_TEST.cc +++ b/src/Marker_TEST.cc @@ -109,6 +109,10 @@ void MarkerTest::Marker(const std::string &_renderEngine) EXPECT_NO_THROW(marker->SetPoint(0, math::Vector3d(3, 1, 2))); EXPECT_NO_THROW(marker->ClearPoints()); + EXPECT_DOUBLE_EQ(1.0, marker->Size()); + marker->SetSize(3.0); + EXPECT_DOUBLE_EQ(3.0, marker->Size()); + // Clean up engine->DestroyScene(scene); rendering::unloadEngine(engine->Name());