From cdcb696c66685c52dca51359e33d6b1c698a703d Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Mon, 30 Nov 2020 21:40:13 -0800 Subject: [PATCH 1/6] Beginning of heightmap... it's not showing... Signed-off-by: Louise Poubel --- examples/worlds/heightmap.sdf | 113 ++++++++++++++++++++++++++++++++++ src/Conversions.cc | 67 ++++++++++++++++++++ src/Conversions_TEST.cc | 67 ++++++++++++++++++++ src/rendering/SceneManager.cc | 46 ++++++++++++++ 4 files changed, 293 insertions(+) create mode 100644 examples/worlds/heightmap.sdf diff --git a/examples/worlds/heightmap.sdf b/examples/worlds/heightmap.sdf new file mode 100644 index 0000000000..72d0bb68a0 --- /dev/null +++ b/examples/worlds/heightmap.sdf @@ -0,0 +1,113 @@ + + + + + + 0.001 + 1.0 + + + + + + + + + + + + + + + 3D View + false + docked + + + ogre + scene + 0.4 0.4 0.4 + 0.8 0.8 0.8 + -16.6 7.3 8.6 0.0 0.4 -0.45 + + + + + + World control + false + false + 72 + 121 + 1 + + floating + + + + + + + true + true + true + + + + + + + World stats + false + false + 110 + 290 + 1 + + floating + + + + + + + true + true + true + true + + + + + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + + https://fuel.ignitionrobotics.org/1.0/chapulina/models/Heightmap Bowl + + + + diff --git a/src/Conversions.cc b/src/Conversions.cc index b5cc4b1ca5..8152e1e150 100644 --- a/src/Conversions.cc +++ b/src/Conversions.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -181,6 +183,39 @@ msgs::Geometry ignition::gazebo::convert(const sdf::Geometry &_in) meshMsg->set_submesh(meshSdf->Submesh()); meshMsg->set_center_submesh(meshSdf->CenterSubmesh()); } + else if (_in.Type() == sdf::GeometryType::HEIGHTMAP && _in.HeightmapShape()) + { + auto heightmapSdf = _in.HeightmapShape(); + + out.set_type(msgs::Geometry::HEIGHTMAP); + auto heightmapMsg = out.mutable_heightmap(); + + heightmapMsg->set_filename(asFullPath(heightmapSdf->Uri(), + heightmapSdf->FilePath())); + msgs::Set(heightmapMsg->mutable_size(), heightmapSdf->Size()); + msgs::Set(heightmapMsg->mutable_origin(), heightmapSdf->Position()); + heightmapMsg->set_use_terrain_paging(heightmapSdf->UseTerrainPaging()); + heightmapMsg->set_sampling(heightmapSdf->Sampling()); + + for (auto i = 0u; i < heightmapSdf->TextureCount(); ++i) + { + auto textureSdf = heightmapSdf->TextureByIndex(i); + auto textureMsg = heightmapMsg->add_texture(); + textureMsg->set_size(textureSdf->Size()); + textureMsg->set_diffuse(asFullPath(textureSdf->Diffuse(), + heightmapSdf->FilePath())); + textureMsg->set_normal(asFullPath(textureSdf->Normal(), + heightmapSdf->FilePath())); + } + + for (auto i = 0u; i < heightmapSdf->BlendCount(); ++i) + { + auto blendSdf = heightmapSdf->BlendByIndex(i); + auto blendMsg = heightmapMsg->add_blend(); + blendMsg->set_min_height(blendSdf->MinHeight()); + blendMsg->set_fade_dist(blendSdf->FadeDistance()); + } + } else { ignerr << "Geometry type [" << static_cast(_in.Type()) @@ -244,6 +279,38 @@ sdf::Geometry ignition::gazebo::convert(const msgs::Geometry &_in) out.SetMeshShape(meshShape); } + else if (_in.type() == msgs::Geometry::HEIGHTMAP && _in.has_heightmap()) + { + out.SetType(sdf::GeometryType::HEIGHTMAP); + sdf::Heightmap heightmapShape; + + heightmapShape.SetUri(_in.heightmap().filename()); + heightmapShape.SetSize(msgs::Convert(_in.heightmap().size())); + heightmapShape.SetPosition(msgs::Convert(_in.heightmap().origin())); + heightmapShape.SetUseTerrainPaging(_in.heightmap().use_terrain_paging()); + heightmapShape.SetSampling(_in.heightmap().sampling()); + + for (int i = 0; i < _in.heightmap().texture_size(); ++i) + { + auto textureMsg = _in.heightmap().texture(i); + sdf::HeightmapTexture textureSdf; + textureSdf.SetSize(textureMsg.size()); + textureSdf.SetDiffuse(textureMsg.diffuse()); + textureSdf.SetNormal(textureMsg.normal()); + heightmapShape.AddTexture(textureSdf); + } + + for (int i = 0; i < _in.heightmap().blend_size(); ++i) + { + auto blendMsg = _in.heightmap().blend(i); + sdf::HeightmapBlend blendSdf; + blendSdf.SetMinHeight(blendMsg.min_height()); + blendSdf.SetFadeDistance(blendMsg.fade_dist()); + heightmapShape.AddBlend(blendSdf); + } + + out.SetHeightmapShape(heightmapShape); + } else { ignerr << "Geometry type [" << static_cast(_in.type()) diff --git a/src/Conversions_TEST.cc b/src/Conversions_TEST.cc index b25232fed2..be0d772e73 100644 --- a/src/Conversions_TEST.cc +++ b/src/Conversions_TEST.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -392,6 +393,72 @@ TEST(Conversions, GeometryPlane) EXPECT_EQ(math::Vector3d::UnitY, newGeometry.PlaneShape()->Normal()); } +///////////////////////////////////////////////// +TEST(Conversions, GeometryHeightmap) +{ + sdf::Geometry geometry; + geometry.SetType(sdf::GeometryType::HEIGHTMAP); + + sdf::Heightmap heightmap; + heightmap.SetUri("file://heights.png"); + heightmap.SetSize(ignition::math::Vector3d(1, 2, 3)); + heightmap.SetPosition(ignition::math::Vector3d(4, 5, 6)); + heightmap.SetUseTerrainPaging(true); + heightmap.SetSampling(16u); + + sdf::HeightmapTexture texture; + texture.SetDiffuse("file://diffuse.png"); + texture.SetNormal("file://normal.png"); + texture.SetSize(1.23); + heightmap.AddTexture(texture); + + sdf::HeightmapBlend blend; + blend.SetMinHeight(123.456); + blend.SetFadeDistance(456.789); + heightmap.AddBlend(blend); + + geometry.SetHeightmapShape(heightmap); + + auto geometryMsg = convert(geometry); + + EXPECT_EQ(msgs::Geometry::HEIGHTMAP, geometryMsg.type()); + EXPECT_TRUE(geometryMsg.has_heightmap()); + EXPECT_EQ(math::Vector3d(1, 2, 3), + msgs::Convert(geometryMsg.heightmap().size())); + EXPECT_EQ("file://heights.png", geometryMsg.heightmap().filename()); + EXPECT_TRUE(geometryMsg.heightmap().use_terrain_paging()); + EXPECT_EQ(16u, geometryMsg.heightmap().sampling()); + + ASSERT_EQ(1, geometryMsg.heightmap().texture().size()); + EXPECT_DOUBLE_EQ(1.23, geometryMsg.heightmap().texture(0).size()); + EXPECT_EQ("file://diffuse.png", geometryMsg.heightmap().texture(0).diffuse()); + EXPECT_EQ("file://normal.png", geometryMsg.heightmap().texture(0).normal()); + + ASSERT_EQ(1, geometryMsg.heightmap().blend().size()); + EXPECT_DOUBLE_EQ(123.456, geometryMsg.heightmap().blend(0).min_height()); + EXPECT_DOUBLE_EQ(456.789, geometryMsg.heightmap().blend(0).fade_dist()); + + auto newGeometry = convert(geometryMsg); + + EXPECT_EQ(sdf::GeometryType::HEIGHTMAP, newGeometry.Type()); + + auto newHeightmap = newGeometry.HeightmapShape(); + ASSERT_NE(nullptr, newHeightmap); + EXPECT_EQ(math::Vector3d(1, 2, 3), newHeightmap->Size()); + EXPECT_EQ("file://heights.png", newHeightmap->Uri()); + EXPECT_TRUE(newHeightmap->UseTerrainPaging()); + EXPECT_EQ(16u, newHeightmap->Sampling()); + + ASSERT_EQ(1u, newHeightmap->TextureCount()); + EXPECT_DOUBLE_EQ(1.23, newHeightmap->TextureByIndex(0)->Size()); + EXPECT_EQ("file://diffuse.png", newHeightmap->TextureByIndex(0)->Diffuse()); + EXPECT_EQ("file://normal.png", newHeightmap->TextureByIndex(0)->Normal()); + + ASSERT_EQ(1u, newHeightmap->BlendCount()); + EXPECT_DOUBLE_EQ(123.456, newHeightmap->BlendByIndex(0)->MinHeight()); + EXPECT_DOUBLE_EQ(456.789, newHeightmap->BlendByIndex(0)->FadeDistance()); +} + ///////////////////////////////////////////////// TEST(Conversions, Inertial) { diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index 20b4e8ab11..bdfdfec99f 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,8 @@ #include #include +#include +#include #include #include #include @@ -406,6 +409,49 @@ rendering::GeometryPtr SceneManager::LoadGeometry(const sdf::Geometry &_geom, geom = this->dataPtr->scene->CreateMesh(descriptor); scale = _geom.MeshShape()->Scale(); } + else if (_geom.Type() == sdf::GeometryType::HEIGHTMAP) + { + auto fullPath = asFullPath(_geom.HeightmapShape()->Uri(), + _geom.HeightmapShape()->FilePath()); + if (fullPath.empty()) + { + ignerr << "Heightmap geometry missing URI" << std::endl; + return geom; + } + + auto data = std::make_shared(); + if (data->Load(fullPath) < 0) + { + ignerr << "Failed to load heightmap image data from [" << fullPath << "]" + << std::endl; + return geom; + } + + rendering::HeightmapDescriptor descriptor; + descriptor.data = data; + descriptor.size = _geom.HeightmapShape()->Size(); + descriptor.sampling = _geom.HeightmapShape()->Sampling(); + + for (uint64_t i = 0; i < _geom.HeightmapShape()->TextureCount(); ++i) + { + auto textureSdf = _geom.HeightmapShape()->TextureByIndex(i); + rendering::HeightmapDescriptor::Texture textureDesc; + textureDesc.size = textureSdf->Size(); + textureDesc.diffuse = asFullPath(textureSdf->Diffuse(), _geom.FilePath()); + textureDesc.normal = asFullPath(textureSdf->Normal(), _geom.FilePath()); + descriptor.textures.push_back(textureDesc); + } + + // Heightmaps aren't geometries on ign-rendering. Instead of being attached + // to visuals, they're attached directly to the scene. So `geom` will + // be null and this is enough to attach it. + auto heightmap = this->dataPtr->scene->CreateHeightmap(descriptor); + if (nullptr == heightmap) + { + ignerr << "Failed to create heightmap [" << fullPath << "]" << std::endl; + } + scale = _geom.HeightmapShape()->Size(); + } else { ignerr << "Unsupported geometry type" << std::endl; From bdd6adb8af0d9aba52f82774e60ce84216ce2a55 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Mon, 30 Nov 2020 21:55:44 -0800 Subject: [PATCH 2/6] add blends Signed-off-by: Louise Poubel --- src/rendering/SceneManager.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index bdfdfec99f..8fd378d0af 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -437,11 +437,22 @@ rendering::GeometryPtr SceneManager::LoadGeometry(const sdf::Geometry &_geom, auto textureSdf = _geom.HeightmapShape()->TextureByIndex(i); rendering::HeightmapDescriptor::Texture textureDesc; textureDesc.size = textureSdf->Size(); - textureDesc.diffuse = asFullPath(textureSdf->Diffuse(), _geom.FilePath()); - textureDesc.normal = asFullPath(textureSdf->Normal(), _geom.FilePath()); + textureDesc.diffuse = asFullPath(textureSdf->Diffuse(), + _geom.HeightmapShape()->FilePath()); + textureDesc.normal = asFullPath(textureSdf->Normal(), + _geom.HeightmapShape()->FilePath()); descriptor.textures.push_back(textureDesc); } + for (uint64_t i = 0; i < _geom.HeightmapShape()->BlendCount(); ++i) + { + auto blendSdf = _geom.HeightmapShape()->BlendByIndex(i); + rendering::HeightmapDescriptor::Blend blendDesc; + blendDesc.minHeight = blendSdf->MinHeight(); + blendDesc.fadeDistance = blendSdf->FadeDistance(); + descriptor.blends.push_back(blendDesc); + } + // Heightmaps aren't geometries on ign-rendering. Instead of being attached // to visuals, they're attached directly to the scene. So `geom` will // be null and this is enough to attach it. From 57cbd404dc3a412b17fe2d7f1369eb1e01a6a843 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Mon, 14 Dec 2020 17:33:31 -0800 Subject: [PATCH 3/6] dummy visual Signed-off-by: Louise Poubel --- src/rendering/SceneManager.cc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index 8fd378d0af..a0d0f1ad36 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -277,7 +277,15 @@ rendering::VisualPtr SceneManager::CreateVisual(Entity _id, // set material rendering::MaterialPtr material{nullptr}; - if (_visual.Material()) + double transparency = _visual.Transparency(); + // Heightmap's material is loaded together with it. + // Just make the dummy geometry invisible here. + if (_visual.Geom()->Type() == sdf::GeometryType::HEIGHTMAP) + { + material = this->dataPtr->scene->CreateMaterial(); + transparency = 1; + } + else if (_visual.Material()) { material = this->LoadMaterial(*_visual.Material()); } @@ -320,7 +328,7 @@ rendering::VisualPtr SceneManager::CreateVisual(Entity _id, if (material) { // set transparency - material->SetTransparency(_visual.Transparency()); + material->SetTransparency(transparency); // cast shadows material->SetCastShadows(_visual.CastShadows()); @@ -461,7 +469,13 @@ rendering::GeometryPtr SceneManager::LoadGeometry(const sdf::Geometry &_geom, { ignerr << "Failed to create heightmap [" << fullPath << "]" << std::endl; } + geom = this->dataPtr->scene->CreateBox(); scale = _geom.HeightmapShape()->Size(); + + // Heightmap's origin is on its lowest point + auto position = _geom.HeightmapShape()->Position(); + position.Z() += scale.Z() * 0.5; + localPose.Set(position, math::Quaterniond::Identity); } else { From 4d86865e9c41bfaf23a4609b6b094816621b8307 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Wed, 16 Dec 2020 18:52:06 -0800 Subject: [PATCH 4/6] Heightmap is now a geometry Signed-off-by: Louise Poubel --- src/rendering/SceneManager.cc | 51 ++++++++++++++--------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index a0d0f1ad36..6d2165364b 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -36,6 +36,8 @@ #include #include +#include +#include #include #include #include @@ -277,13 +279,9 @@ rendering::VisualPtr SceneManager::CreateVisual(Entity _id, // set material rendering::MaterialPtr material{nullptr}; - double transparency = _visual.Transparency(); - // Heightmap's material is loaded together with it. - // Just make the dummy geometry invisible here. if (_visual.Geom()->Type() == sdf::GeometryType::HEIGHTMAP) { - material = this->dataPtr->scene->CreateMaterial(); - transparency = 1; + // Heightmap's material is loaded together with it. } else if (_visual.Material()) { @@ -328,7 +326,7 @@ rendering::VisualPtr SceneManager::CreateVisual(Entity _id, if (material) { // set transparency - material->SetTransparency(transparency); + material->SetTransparency(_visual.Transparency()); // cast shadows material->SetCastShadows(_visual.CastShadows()); @@ -436,46 +434,37 @@ rendering::GeometryPtr SceneManager::LoadGeometry(const sdf::Geometry &_geom, } rendering::HeightmapDescriptor descriptor; - descriptor.data = data; - descriptor.size = _geom.HeightmapShape()->Size(); - descriptor.sampling = _geom.HeightmapShape()->Sampling(); + descriptor.SetData(data); + descriptor.SetSize(_geom.HeightmapShape()->Size()); + descriptor.SetSampling(_geom.HeightmapShape()->Sampling()); for (uint64_t i = 0; i < _geom.HeightmapShape()->TextureCount(); ++i) { auto textureSdf = _geom.HeightmapShape()->TextureByIndex(i); - rendering::HeightmapDescriptor::Texture textureDesc; - textureDesc.size = textureSdf->Size(); - textureDesc.diffuse = asFullPath(textureSdf->Diffuse(), - _geom.HeightmapShape()->FilePath()); - textureDesc.normal = asFullPath(textureSdf->Normal(), - _geom.HeightmapShape()->FilePath()); - descriptor.textures.push_back(textureDesc); + rendering::HeightmapTexture textureDesc; + textureDesc.SetSize(textureSdf->Size()); + textureDesc.SetDiffuse(asFullPath(textureSdf->Diffuse(), + _geom.HeightmapShape()->FilePath())); + textureDesc.SetNormal(asFullPath(textureSdf->Normal(), + _geom.HeightmapShape()->FilePath())); + descriptor.AddTexture(textureDesc); } for (uint64_t i = 0; i < _geom.HeightmapShape()->BlendCount(); ++i) { auto blendSdf = _geom.HeightmapShape()->BlendByIndex(i); - rendering::HeightmapDescriptor::Blend blendDesc; - blendDesc.minHeight = blendSdf->MinHeight(); - blendDesc.fadeDistance = blendSdf->FadeDistance(); - descriptor.blends.push_back(blendDesc); + rendering::HeightmapBlend blendDesc; + blendDesc.SetMinHeight(blendSdf->MinHeight()); + blendDesc.SetFadeDistance(blendSdf->FadeDistance()); + descriptor.AddBlend(blendDesc); } - // Heightmaps aren't geometries on ign-rendering. Instead of being attached - // to visuals, they're attached directly to the scene. So `geom` will - // be null and this is enough to attach it. - auto heightmap = this->dataPtr->scene->CreateHeightmap(descriptor); - if (nullptr == heightmap) + geom = this->dataPtr->scene->CreateHeightmap(descriptor); + if (nullptr == geom) { ignerr << "Failed to create heightmap [" << fullPath << "]" << std::endl; } - geom = this->dataPtr->scene->CreateBox(); scale = _geom.HeightmapShape()->Size(); - - // Heightmap's origin is on its lowest point - auto position = _geom.HeightmapShape()->Position(); - position.Z() += scale.Z() * 0.5; - localPose.Set(position, math::Quaterniond::Identity); } else { From 68fd32ea5bb3c38f4b4f7d6353fbc59bfac553f7 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Thu, 17 Dec 2020 16:40:28 -0800 Subject: [PATCH 5/6] Add instructions to world Signed-off-by: Louise Poubel --- examples/worlds/heightmap.sdf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/worlds/heightmap.sdf b/examples/worlds/heightmap.sdf index 72d0bb68a0..43903b9681 100644 --- a/examples/worlds/heightmap.sdf +++ b/examples/worlds/heightmap.sdf @@ -1,6 +1,10 @@ From 8e84a423483bb1e65cc609b12d467ff8e76e4c2a Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Mon, 25 Jan 2021 12:38:54 -0800 Subject: [PATCH 6/6] simplify demo world Signed-off-by: Louise Poubel --- examples/worlds/heightmap.sdf | 66 ----------------------------------- 1 file changed, 66 deletions(-) diff --git a/examples/worlds/heightmap.sdf b/examples/worlds/heightmap.sdf index 43903b9681..69f354b513 100644 --- a/examples/worlds/heightmap.sdf +++ b/examples/worlds/heightmap.sdf @@ -9,26 +9,6 @@ --> - - 0.001 - 1.0 - - - - - - - - - @@ -46,52 +26,6 @@ -16.6 7.3 8.6 0.0 0.4 -0.45 - - - - World control - false - false - 72 - 121 - 1 - - floating - - - - - - - true - true - true - - - - - - - World stats - false - false - 110 - 290 - 1 - - floating - - - - - - - true - true - true - true - -