diff --git a/examples/worlds/minimal_scene.sdf b/examples/worlds/minimal_scene.sdf
new file mode 100644
index 0000000000..8dc69f2bbf
--- /dev/null
+++ b/examples/worlds/minimal_scene.sdf
@@ -0,0 +1,452 @@
+
+
+
+
+
+
+
+
+
+
+ 3D View
+ false
+ docked
+
+
+ ogre2
+ scene
+ 0.4 0.4 0.4
+ 0.8 0.8 0.8
+ -6 0 6 0 0.5 0
+
+
+
+
+
+
+
+
+
+ false
+ 5
+ 5
+ floating
+ false
+
+
+
+
+
+
+
+
+ false
+ 5
+ 5
+ floating
+ false
+
+
+
+
+
+
+
+
+ false
+ 5
+ 5
+ floating
+ false
+
+
+
+
+
+
+
+
+ false
+ 5
+ 5
+ floating
+ false
+
+
+
+
+
+
+ World control
+ false
+ false
+ 72
+ 121
+ 1
+
+ floating
+
+
+
+
+
+
+ true
+ true
+ true
+ /world/buoyancy/control
+ /world/buoyancy/stats
+
+
+
+
+
+
+ World stats
+ false
+ false
+ 110
+ 290
+ 1
+
+ floating
+
+
+
+
+
+
+ true
+ true
+ true
+ true
+ /world/buoyancy/stats
+
+
+
+
+
+ false
+ 0
+ 0
+ 250
+ 50
+ floating
+ false
+ #666666
+
+
+
+
+
+
+ false
+ 250
+ 0
+ 150
+ 50
+ floating
+ false
+ #666666
+
+
+
+
+
+
+ false
+ 0
+ 50
+ 250
+ 50
+ floating
+ false
+ #777777
+
+
+
+
+
+
+ false
+ 250
+ 50
+ 50
+ 50
+ floating
+ false
+ #777777
+
+
+
+
+
+
+ false
+ docked
+
+
+
+
+
+
+ false
+ docked
+
+
+
+
+
+
+ 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
+
+
+
+ true
+
+
+
+
+ 0 0 1
+ 100 100
+
+
+
+
+
+
+ 0 0 1
+ 100 100
+
+
+
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+ 0.8 0.8 0.8 1
+
+
+
+
+
+
+ 0 0 0.5 0 0 0
+
+
+
+ 0.16666
+ 0
+ 0
+ 0.16666
+ 0
+ 0.16666
+
+ 1.0
+
+
+
+
+ 1 1 1
+
+
+
+
+
+
+
+ 1 1 1
+
+
+
+ 1 0 0 1
+ 1 0 0 1
+ 1 0 0 1
+
+
+
+
+
+
+ 0 -1.5 0.5 0 0 0
+
+
+
+ 0.1458
+ 0
+ 0
+ 0.1458
+ 0
+ 0.125
+
+ 1.0
+
+
+
+
+ 0.5
+ 1.0
+
+
+
+
+
+
+
+ 0.5
+ 1.0
+
+
+
+ 0 1 0 1
+ 0 1 0 1
+ 0 1 0 1
+
+
+
+
+
+
+ 0 1.5 0.5 0 0 0
+
+
+
+ 0.1
+ 0
+ 0
+ 0.1
+ 0
+ 0.1
+
+ 1.0
+
+
+
+
+ 0.5
+
+
+
+
+
+
+
+ 0.5
+
+
+
+ 0 0 1 1
+ 0 0 1 1
+ 0 0 1 1
+
+
+
+
+
+
+ 0 -3.0 0.5 0 0 0
+
+
+
+ 0.074154
+ 0
+ 0
+ 0.074154
+ 0
+ 0.018769
+
+ 1.0
+
+
+
+
+ 0.2
+ 0.6
+
+
+
+
+
+
+ 0.2
+ 0.6
+
+
+
+ 1 1 0 1
+ 1 1 0 1
+ 1 1 0 1
+
+
+
+
+
+
+ 0 3.0 0.5 0 0 0
+
+
+
+ 0.068
+ 0
+ 0
+ 0.058
+ 0
+ 0.026
+
+ 1.0
+
+
+
+
+ 0.2 0.3 0.5
+
+
+
+
+
+
+ 0.2 0.3 0.5
+
+
+
+ 1 0 1 1
+ 1 0 1 1
+ 1 0 1 1
+
+
+
+
+
+
diff --git a/include/ignition/gazebo/rendering/RenderUtil.hh b/include/ignition/gazebo/rendering/RenderUtil.hh
index b02837a5cc..4bd8fb0039 100644
--- a/include/ignition/gazebo/rendering/RenderUtil.hh
+++ b/include/ignition/gazebo/rendering/RenderUtil.hh
@@ -92,6 +92,10 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
/// \return Name of the rendering scene.
public: std::string SceneName() const;
+ /// \brief Set the scene to use.
+ /// \param[in] _scene Pointer to the scene.
+ public: void SetScene(const rendering::ScenePtr &_scene);
+
/// \brief Set background color of render window
/// \param[in] _color Color of render window background
public: void SetBackgroundColor(const math::Color &_color);
diff --git a/src/gui/plugins/CMakeLists.txt b/src/gui/plugins/CMakeLists.txt
index d754fc4f49..c8d7ab74f4 100644
--- a/src/gui/plugins/CMakeLists.txt
+++ b/src/gui/plugins/CMakeLists.txt
@@ -129,6 +129,7 @@ add_subdirectory(plot_3d)
add_subdirectory(plotting)
add_subdirectory(resource_spawner)
add_subdirectory(scene3d)
+add_subdirectory(scene_manager)
add_subdirectory(shapes)
add_subdirectory(transform_control)
add_subdirectory(video_recorder)
diff --git a/src/gui/plugins/scene_manager/CMakeLists.txt b/src/gui/plugins/scene_manager/CMakeLists.txt
new file mode 100644
index 0000000000..6e5e884b94
--- /dev/null
+++ b/src/gui/plugins/scene_manager/CMakeLists.txt
@@ -0,0 +1,7 @@
+gz_add_gui_plugin(GzSceneManager
+ SOURCES GzSceneManager.cc
+ QT_HEADERS GzSceneManager.hh
+ PRIVATE_LINK_LIBS
+ ${PROJECT_LIBRARY_TARGET_NAME}-rendering
+ ignition-utils${IGN_UTILS_VER}::ignition-utils${IGN_UTILS_VER}
+)
diff --git a/src/gui/plugins/scene_manager/GzSceneManager.cc b/src/gui/plugins/scene_manager/GzSceneManager.cc
new file mode 100644
index 0000000000..f7ec59fbac
--- /dev/null
+++ b/src/gui/plugins/scene_manager/GzSceneManager.cc
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ *
+*/
+
+#include "GzSceneManager.hh"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "ignition/gazebo/EntityComponentManager.hh"
+#include "ignition/gazebo/components/Name.hh"
+#include "ignition/gazebo/components/World.hh"
+#include "ignition/gazebo/rendering/RenderUtil.hh"
+
+namespace ignition
+{
+namespace gazebo
+{
+inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
+ /// \brief Private data class for GzSceneManager
+ class GzSceneManagerPrivate
+ {
+ /// \brief Update the 3D scene based on the latest state of the ECM.
+ public: void OnRender();
+
+ //// \brief Pointer to the rendering scene
+ public: rendering::ScenePtr scene;
+
+ /// \brief Rendering utility
+ public: RenderUtil renderUtil;
+ };
+}
+}
+}
+
+using namespace ignition;
+using namespace gazebo;
+
+/////////////////////////////////////////////////
+GzSceneManager::GzSceneManager()
+ : GuiSystem(), dataPtr(std::make_unique())
+{
+}
+
+/////////////////////////////////////////////////
+GzSceneManager::~GzSceneManager() = default;
+
+/////////////////////////////////////////////////
+void GzSceneManager::LoadConfig(const tinyxml2::XMLElement *)
+{
+ if (this->title.empty())
+ this->title = "Scene Manager";
+
+ ignition::gui::App()->findChild<
+ ignition::gui::MainWindow *>()->installEventFilter(this);
+}
+
+//////////////////////////////////////////////////
+void GzSceneManager::Update(const UpdateInfo &_info,
+ EntityComponentManager &_ecm)
+{
+ IGN_PROFILE("GzSceneManager::Update");
+
+ this->dataPtr->renderUtil.UpdateECM(_info, _ecm);
+ this->dataPtr->renderUtil.UpdateFromECM(_info, _ecm);
+}
+
+/////////////////////////////////////////////////
+bool GzSceneManager::eventFilter(QObject *_obj, QEvent *_event)
+{
+ if (_event->type() == gui::events::Render::kType)
+ {
+ this->dataPtr->OnRender();
+ }
+
+ // Standard event processing
+ return QObject::eventFilter(_obj, _event);
+}
+
+/////////////////////////////////////////////////
+void GzSceneManagerPrivate::OnRender()
+{
+ if (nullptr == this->scene)
+ {
+ this->scene = rendering::sceneFromFirstRenderEngine();
+ if (nullptr == this->scene)
+ return;
+
+ this->renderUtil.SetScene(this->scene);
+ }
+
+ this->renderUtil.Update();
+}
+
+// Register this plugin
+IGNITION_ADD_PLUGIN(ignition::gazebo::GzSceneManager,
+ ignition::gui::Plugin)
diff --git a/src/gui/plugins/scene_manager/GzSceneManager.hh b/src/gui/plugins/scene_manager/GzSceneManager.hh
new file mode 100644
index 0000000000..ab0d5f1be0
--- /dev/null
+++ b/src/gui/plugins/scene_manager/GzSceneManager.hh
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ *
+*/
+
+#ifndef IGNITION_GAZEBO_GUI_GZSCENEMANAGER_HH_
+#define IGNITION_GAZEBO_GUI_GZSCENEMANAGER_HH_
+
+#include
+
+#include
+
+namespace ignition
+{
+namespace gazebo
+{
+// Inline bracket to help doxygen filtering.
+inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
+ class GzSceneManagerPrivate;
+
+ /// \brief Updates a 3D scene based on information coming from the ECM.
+ /// This plugin doesn't instantiate a new 3D scene. Instead, it relies on
+ /// another plugin being loaded alongside it that will create and paint the
+ /// scene to the window, such as `ignition::gui::plugins::Scene3D`.
+ class GzSceneManager : public GuiSystem
+ {
+ Q_OBJECT
+
+ /// \brief Constructor
+ public: GzSceneManager();
+
+ /// \brief Destructor
+ public: ~GzSceneManager() override;
+
+ // Documentation inherited
+ public: void LoadConfig(const tinyxml2::XMLElement *_pluginElem)
+ override;
+
+ // Documentation inherited
+ public: void Update(const UpdateInfo &_info,
+ EntityComponentManager &_ecm) override;
+
+ // Documentation inherited
+ private: bool eventFilter(QObject *_obj, QEvent *_event) override;
+
+ /// \internal
+ /// \brief Pointer to private data.
+ private: std::unique_ptr dataPtr;
+ };
+}
+}
+}
+
+#endif
diff --git a/src/gui/plugins/scene_manager/GzSceneManager.qml b/src/gui/plugins/scene_manager/GzSceneManager.qml
new file mode 100644
index 0000000000..873da30014
--- /dev/null
+++ b/src/gui/plugins/scene_manager/GzSceneManager.qml
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+*/
+
+import QtQuick 2.0
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+// TODO: remove invisible rectangle, see
+// https://github.com/ignitionrobotics/ign-gui/issues/220
+Rectangle {
+ visible: false
+ Layout.minimumWidth: 100
+ Layout.minimumHeight: 100
+}
diff --git a/src/gui/plugins/scene_manager/GzSceneManager.qrc b/src/gui/plugins/scene_manager/GzSceneManager.qrc
new file mode 100644
index 0000000000..b28c13c3b4
--- /dev/null
+++ b/src/gui/plugins/scene_manager/GzSceneManager.qrc
@@ -0,0 +1,5 @@
+
+
+ GzSceneManager.qml
+
+
diff --git a/src/rendering/RenderUtil.cc b/src/rendering/RenderUtil.cc
index f9aed5c294..e941bc986f 100644
--- a/src/rendering/RenderUtil.cc
+++ b/src/rendering/RenderUtil.cc
@@ -2001,6 +2001,10 @@ void RenderUtilPrivate::RemoveRenderingEntities(
/////////////////////////////////////////////////
void RenderUtil::Init()
{
+ // Already initialized
+ if (nullptr != this->dataPtr->scene)
+ return;
+
ignition::common::SystemPaths pluginPath;
pluginPath.SetPluginPathEnv(kRenderPluginPathEnv);
rendering::setPluginPaths(pluginPath.PluginPaths());
@@ -2101,6 +2105,14 @@ void RenderUtil::SetSceneName(const std::string &_name)
this->dataPtr->sceneName = _name;
}
+/////////////////////////////////////////////////
+void RenderUtil::SetScene(const rendering::ScenePtr &_scene)
+{
+ this->dataPtr->scene = _scene;
+ this->dataPtr->sceneManager.SetScene(_scene);
+ this->dataPtr->engine = _scene == nullptr ? nullptr : _scene->Engine();
+}
+
/////////////////////////////////////////////////
std::string RenderUtil::SceneName() const
{