Skip to content

Commit

Permalink
Showing 19 changed files with 584 additions and 112 deletions.
4 changes: 4 additions & 0 deletions Migration.md
Original file line number Diff line number Diff line change
@@ -67,6 +67,10 @@ in SDF by setting the `<visual><material><double_sided>` SDF element.
* **Deprecated**: `Entity EntityFromNode(const rendering::NodePtr &_node) const;`
* **Replacement**: `Entity entity = std::get<int>(visual->UserData("gazebo-entity"));`

## Ignition Gazebo 3.12.0 to 3.X.X

* Some sensors will only have the `SensorTopic` component after the 1st iteration.

## Ignition Gazebo 2.x to 3.x

* Use ign-rendering3, ign-sensors3 and ign-gui3.
2 changes: 1 addition & 1 deletion include/ignition/gazebo/components/CenterOfVolume.hh
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ namespace components
/// \brief A component for an entity's center of volume. Units are in meters.
/// The Vector3 value indicates center of volume of an entity. The
/// position of the center of volume is relative to the pose of the parent
/// entity.
/// entity, which is usually a link.
using CenterOfVolume = Component<math::Vector3d, class CenterOfVolumeTag>;
IGN_GAZEBO_REGISTER_COMPONENT("ign_gazebo_components.CenterOfVolume",
CenterOfVolume)
19 changes: 15 additions & 4 deletions src/gui/plugins/scene3d/GzScene3D.qml
Original file line number Diff line number Diff line change
@@ -14,16 +14,18 @@
* limitations under the License.
*
*/
import IgnGazebo 1.0 as IgnGazebo
import QtGraphicalEffects 1.0
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Dialogs 1.0
import QtQuick.Layouts 1.3
import RenderWindow 1.0
import QtGraphicalEffects 1.0
import IgnGazebo 1.0 as IgnGazebo

Rectangle {
width: 1000
height: 800
Layout.minimumWidth: 200
Layout.minimumHeight: 200
anchors.fill: parent

/**
* True to enable gamma correction
@@ -38,6 +40,7 @@ Rectangle {
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
visible: GzScene3D.loadingError.length == 0
onEntered: {
GzScene3D.OnFocusWindow()
}
@@ -50,6 +53,7 @@ Rectangle {
id: renderWindow
objectName: "renderWindow"
anchors.fill: parent
visible: GzScene3D.loadingError.length == 0

/**
* Message to be displayed over the render window
@@ -120,4 +124,11 @@ Rectangle {
standardButtons: Dialog.Ok
}

Label {
anchors.fill: parent
anchors.margins: 10
text: GzScene3D.loadingError
visible: (GzScene3D.loadingError.length > 0);
wrapMode: Text.WordWrap
}
}
81 changes: 66 additions & 15 deletions src/gui/plugins/scene3d/Scene3D.cc
Original file line number Diff line number Diff line change
@@ -1867,17 +1867,25 @@ void IgnRenderer::HandleMouseViewControl()
}

/////////////////////////////////////////////////
void IgnRenderer::Initialize()
std::string IgnRenderer::Initialize()
{
if (this->initialized)
return;
return std::string();

// Only one engine / scene / user camera is currently supported.
// Fail gracefully even before getting to renderUtil.
if (!rendering::loadedEngines().empty())
{
return "Currently only one plugin providing a 3D scene is supported at a "
"time.";
}

this->dataPtr->renderUtil.SetUseCurrentGLContext(true);
this->dataPtr->renderUtil.Init();

rendering::ScenePtr scene = this->dataPtr->renderUtil.Scene();
if (!scene)
return;
return "Failed to create a 3D scene.";

auto root = scene->RootVisual();

@@ -1899,6 +1907,7 @@ void IgnRenderer::Initialize()
this->dataPtr->rayQuery = this->dataPtr->camera->Scene()->CreateRayQuery();

this->initialized = true;
return std::string();
}

/////////////////////////////////////////////////
@@ -2295,6 +2304,12 @@ RenderThread::RenderThread()
qRegisterMetaType<RenderSync*>("RenderSync*");
}

/////////////////////////////////////////////////
void RenderThread::SetErrorCb(std::function<void(const QString&)> _cb)
{
this->errorCb = _cb;
}

/////////////////////////////////////////////////
void RenderThread::RenderNext(RenderSync *_renderSync)
{
@@ -2303,7 +2318,12 @@ void RenderThread::RenderNext(RenderSync *_renderSync)
if (!this->ignRenderer.initialized)
{
// Initialize renderer
this->ignRenderer.Initialize();
auto loadingError = this->ignRenderer.Initialize();
if (!loadingError.empty())
{
this->errorCb(QString::fromStdString(loadingError));
return;
}
}

// check if engine has been successfully initialized
@@ -2321,19 +2341,25 @@ void RenderThread::RenderNext(RenderSync *_renderSync)
/////////////////////////////////////////////////
void RenderThread::ShutDown()
{
this->context->makeCurrent(this->surface);
if (this->context && this->surface)
this->context->makeCurrent(this->surface);

this->ignRenderer.Destroy();

this->context->doneCurrent();
delete this->context;
if (this->context)
{
this->context->doneCurrent();
delete this->context;
}

// schedule this to be deleted only after we're done cleaning up
this->surface->deleteLater();
if (this->surface)
this->surface->deleteLater();

// Stop event processing, move the thread to GUI and make sure it is deleted.
this->exit();
this->moveToThread(QGuiApplication::instance()->thread());
if (this->ignRenderer.initialized)
this->moveToThread(QGuiApplication::instance()->thread());
}


@@ -2457,9 +2483,11 @@ void TextureNode::PrepareNode()
RenderWindowItem::RenderWindowItem(QQuickItem *_parent)
: QQuickItem(_parent), dataPtr(new RenderWindowItemPrivate)
{
// FIXME(anyone) Ogre 1/2 singletons crash when there's an attempt to load
// this plugin twice, so shortcut here. Ideally this would be caught at
// Ignition Rendering.
// TODO(chapulina) Forward-porting #1294 from ign-gazebo3 to ign-gazebo5
// is non-trivial since the plugin's internals have changed. Keeping this
// shortcut here for now, and revisiting later specifically for ign-gazebo5
// onwards.
// See https://github.com/ignitionrobotics/ign-gazebo/issues/1254
static bool done{false};
if (done)
{
@@ -2637,9 +2665,11 @@ Scene3D::~Scene3D() = default;
/////////////////////////////////////////////////
void Scene3D::LoadConfig(const tinyxml2::XMLElement *_pluginElem)
{
// FIXME(anyone) Ogre 1/2 singletons crash when there's an attempt to load
// this plugin twice, so shortcut here. Ideally this would be caught at
// Ignition Rendering.
// TODO(chapulina) Forward-porting #1294 from ign-gazebo3 to ign-gazebo5
// is non-trivial since the plugin's internals have changed. Keeping this
// shortcut here for now, and revisiting later specifically for ign-gazebo5
// onwards.
// See https://github.com/ignitionrobotics/ign-gazebo/issues/1254
static bool done{false};
if (done)
{
@@ -2656,6 +2686,8 @@ void Scene3D::LoadConfig(const tinyxml2::XMLElement *_pluginElem)
<< "Render window will not be created" << std::endl;
return;
}
renderWindow->SetErrorCb(std::bind(&Scene3D::SetLoadingError, this,
std::placeholders::_1));

if (this->title.empty())
this->title = "3D Scene";
@@ -3194,6 +3226,19 @@ void Scene3D::OnFocusWindow()
renderWindow->forceActiveFocus();
}

/////////////////////////////////////////////////
QString Scene3D::LoadingError() const
{
return this->loadingError;
}

/////////////////////////////////////////////////
void Scene3D::SetLoadingError(const QString &_loadingError)
{
this->loadingError = _loadingError;
this->LoadingErrorChanged();
}

/////////////////////////////////////////////////
void RenderWindowItem::SetXYZSnap(const math::Vector3d &_xyz)
{
@@ -3491,6 +3536,12 @@ void RenderWindowItem::OnHovered(const ignition::math::Vector2i &_hoverPos)
this->dataPtr->renderThread->ignRenderer.NewHoverEvent(_hoverPos);
}

/////////////////////////////////////////////////
void RenderWindowItem::SetErrorCb(std::function<void(const QString&)> _cb)
{
this->dataPtr->renderThread->SetErrorCb(_cb);
}

/////////////////////////////////////////////////
void RenderWindowItem::mousePressEvent(QMouseEvent *_e)
{
44 changes: 41 additions & 3 deletions src/gui/plugins/scene3d/Scene3D.hh
Original file line number Diff line number Diff line change
@@ -56,10 +56,13 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
class Scene3DPrivate;
class RenderUtil;

/// \brief Creates a new ignition rendering scene or adds a user-camera to an
/// existing scene. It is possible to orbit the camera around the scene with
/// \brief Creates an ignition rendering scene and user camera.
/// It is possible to orbit the camera around the scene with
/// the mouse. Use other plugins to manage objects in the scene.
///
/// Only one plugin displaying an Ignition Rendering scene can be used at a
/// time.
///
/// ## Configuration
///
/// * \<engine\> : Optional render engine name, defaults to 'ogre'.
@@ -88,6 +91,14 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
NOTIFY ErrorPopupTextChanged
)

/// \brief Loading error message
Q_PROPERTY(
QString loadingError
READ LoadingError
WRITE SetLoadingError
NOTIFY LoadingErrorChanged
)

/// \brief Constructor
public: Scene3D();

@@ -192,6 +203,20 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
/// the connection to work on the QML side
signals: void popupError();

/// \brief Get the loading error string.
/// \return String explaining the loading error. If empty, there's no error.
public: Q_INVOKABLE QString LoadingError() const;

/// \brief Set the loading error message.
/// \param[in] _loadingError Error message.
public: Q_INVOKABLE void SetLoadingError(const QString &_loadingError);

/// \brief Notify that loading error has changed
signals: void LoadingErrorChanged();

/// \brief Loading error message
public: QString loadingError;

/// \internal
/// \brief Pointer to private data.
private: std::unique_ptr<Scene3DPrivate> dataPtr;
@@ -221,7 +246,9 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
public: void Render(RenderSync *_renderSync);

/// \brief Initialize the render engine
public: void Initialize();
/// \return Error message if initialization failed. If empty, no errors
/// occurred.
public: std::string Initialize();

/// \brief Destroy camera associated with this renderer
public: void Destroy();
@@ -538,6 +565,13 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
/// \param[in] _size Size of the texture
signals: void TextureReady(uint _id, const QSize &_size);

/// \brief Set a callback to be called in case there are errors.
/// \param[in] _cb Error callback
public: void SetErrorCb(std::function<void(const QString &)> _cb);

/// \brief Function to be called if there are errors.
public: std::function<void(const QString &)> errorCb;

/// \brief Offscreen surface to render to
public: QOffscreenSurface *surface = nullptr;

@@ -749,6 +783,10 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
/// \param[in] _entity Scoped name of entity.
public slots: void OnContextMenuRequested(QString _entity);

/// \brief Set a callback to be called in case there are errors.
/// \param[in] _cb Error callback
public: void SetErrorCb(std::function<void(const QString &)> _cb);

/// \internal
/// \brief Pointer to private data.
private: std::unique_ptr<RenderWindowItemPrivate> dataPtr;
Loading
Oops, something went wrong.

0 comments on commit 37a3a46

Please sign in to comment.