Skip to content

Commit

Permalink
Emit more events from Scene3D (#213)
Browse files Browse the repository at this point in the history
* Start porting events from ign-gazebo

Signed-off-by: Louise Poubel <[email protected]>

* Remove test that fails due to #216

Signed-off-by: Louise Poubel <[email protected]>

* Move Scene3d_TEST.cc to test/integration

There seems to be a problem with loading the ignition-rendering-ogre
plugin from the Scene3D test if it links to that plugin. Making
Scene3D_TEST.cc into an integration test works because it doesn't
directly call any plugin methods.

This also changes the linking for the Grid3D plugin to only link
to the ignition-rendering core library target instead of the
IGNITION-RENDERING_LIBRARIES variable which includes the ogre
component library plugins.

Signed-off-by: Steve Peters <[email protected]>

* process qt events to allow scene to initialize

Signed-off-by: Steve Peters <[email protected]>

* Add test helper to check event

Signed-off-by: Louise Poubel <[email protected]>

* added more tests

Signed-off-by: ahcorde <[email protected]>

* make linters happy

Signed-off-by: ahcorde <[email protected]>

* Move TestHelper code to .cc file, fix windows?

Signed-off-by: Steve Peters <[email protected]>

* Fix windows?

Signed-off-by: ahcorde <[email protected]>

* Fix windows?

Signed-off-by: Alejandro Hernández <[email protected]>

* Expect values of Vector3 point in click events

Signed-off-by: Steve Peters <[email protected]>

* Remove debug message

Signed-off-by: Steve Peters <[email protected]>

* Remove unused variable

Signed-off-by: Steve Peters <[email protected]>

Co-authored-by: Steve Peters <[email protected]>
Co-authored-by: ahcorde <[email protected]>
  • Loading branch information
3 people authored May 27, 2021
1 parent a7e659e commit 4a0159b
Show file tree
Hide file tree
Showing 12 changed files with 600 additions and 146 deletions.
2 changes: 1 addition & 1 deletion src/plugins/grid_3d/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ ign_gui_add_plugin(Grid3D
TEST_SOURCES
# Grid3D_TEST.cc
PUBLIC_LINK_LIBS
${IGNITION-RENDERING_LIBRARIES}
ignition-rendering${IGN_RENDERING_VER}::ignition-rendering${IGN_RENDERING_VER}
)

4 changes: 1 addition & 3 deletions src/plugins/scene3d/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ ign_gui_add_plugin(Scene3D
Scene3D.cc
QT_HEADERS
Scene3D.hh
TEST_SOURCES
# Scene3D_TEST.cc
PUBLIC_LINK_LIBS
${IGNITION-RENDERING_LIBRARIES}
ignition-rendering${IGN_RENDERING_VER}::ignition-rendering${IGN_RENDERING_VER}
)

201 changes: 184 additions & 17 deletions src/plugins/scene3d/Scene3D.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <vector>

#include <ignition/common/Console.hh>
#include <ignition/common/KeyEvent.hh>
#include <ignition/common/MouseEvent.hh>
#include <ignition/plugin/Register.hh>
#include <ignition/common/MeshManager.hh>
Expand Down Expand Up @@ -207,9 +208,15 @@ namespace plugins
/// \brief Flag to indicate if mouse event is dirty
public: bool mouseDirty = false;

/// \brief Flag to indicate if hover event is dirty
public: bool hoverDirty = false;

/// \brief Mouse event
public: common::MouseEvent mouseEvent;

/// \brief Key event
public: common::KeyEvent keyEvent;

/// \brief Mouse move distance since last event.
public: math::Vector2d drag;

Expand All @@ -222,6 +229,9 @@ namespace plugins
/// \brief Camera orbit controller
public: rendering::OrbitViewController viewControl;

/// \brief The currently hovered mouse position in screen coordinates
public: math::Vector2i mouseHoverPos{math::Vector2i::Zero};

/// \brief Ray query for mouse clicks
public: rendering::RayQueryPtr rayQuery;

Expand Down Expand Up @@ -885,6 +895,15 @@ void IgnRenderer::Render()
void IgnRenderer::HandleMouseEvent()
{
std::lock_guard<std::mutex> lock(this->dataPtr->mutex);
this->BroadcastHoverPos();
this->BroadcastLeftClick();
this->BroadcastRightClick();
this->HandleMouseViewControl();
}

/////////////////////////////////////////////////
void IgnRenderer::HandleMouseViewControl()
{
if (!this->dataPtr->mouseDirty)
return;

Expand Down Expand Up @@ -939,6 +958,106 @@ void IgnRenderer::HandleMouseEvent()
this->dataPtr->mouseDirty = false;
}

////////////////////////////////////////////////
void IgnRenderer::HandleKeyPress(QKeyEvent *_e)
{
if (_e->isAutoRepeat())
return;

std::lock_guard<std::mutex> lock(this->dataPtr->mutex);

this->dataPtr->keyEvent.SetKey(_e->key());
this->dataPtr->keyEvent.SetText(_e->text().toStdString());

this->dataPtr->keyEvent.SetControl(
(_e->modifiers() & Qt::ControlModifier));
this->dataPtr->keyEvent.SetShift(
(_e->modifiers() & Qt::ShiftModifier));
this->dataPtr->keyEvent.SetAlt(
(_e->modifiers() & Qt::AltModifier));

this->dataPtr->mouseEvent.SetControl(this->dataPtr->keyEvent.Control());
this->dataPtr->mouseEvent.SetShift(this->dataPtr->keyEvent.Shift());
this->dataPtr->mouseEvent.SetAlt(this->dataPtr->keyEvent.Alt());
this->dataPtr->keyEvent.SetType(common::KeyEvent::PRESS);
}

////////////////////////////////////////////////
void IgnRenderer::HandleKeyRelease(QKeyEvent *_e)
{
if (_e->isAutoRepeat())
return;

std::lock_guard<std::mutex> lock(this->dataPtr->mutex);

this->dataPtr->keyEvent.SetKey(0);

this->dataPtr->keyEvent.SetControl(
(_e->modifiers() & Qt::ControlModifier)
&& (_e->key() != Qt::Key_Control));
this->dataPtr->keyEvent.SetShift(
(_e->modifiers() & Qt::ShiftModifier)
&& (_e->key() != Qt::Key_Shift));
this->dataPtr->keyEvent.SetAlt(
(_e->modifiers() & Qt::AltModifier)
&& (_e->key() != Qt::Key_Alt));

this->dataPtr->mouseEvent.SetControl(this->dataPtr->keyEvent.Control());
this->dataPtr->mouseEvent.SetShift(this->dataPtr->keyEvent.Shift());
this->dataPtr->mouseEvent.SetAlt(this->dataPtr->keyEvent.Alt());
this->dataPtr->keyEvent.SetType(common::KeyEvent::RELEASE);
}

/////////////////////////////////////////////////
void IgnRenderer::BroadcastHoverPos()
{
if (!this->dataPtr->hoverDirty)
return;

auto pos = this->ScreenToScene(this->dataPtr->mouseHoverPos);

events::HoverToScene hoverToSceneEvent(pos);
App()->sendEvent(App()->findChild<MainWindow *>(), &hoverToSceneEvent);
}

/////////////////////////////////////////////////
void IgnRenderer::BroadcastLeftClick()
{
if (!this->dataPtr->mouseDirty)
return;

if (this->dataPtr->mouseEvent.Dragging())
return;

if (this->dataPtr->mouseEvent.Button() != common::MouseEvent::LEFT ||
this->dataPtr->mouseEvent.Type() != common::MouseEvent::RELEASE)
return;

auto pos = this->ScreenToScene(this->dataPtr->mouseEvent.Pos());

events::LeftClickToScene leftClickToSceneEvent(pos);
App()->sendEvent(App()->findChild<MainWindow *>(), &leftClickToSceneEvent);
}

/////////////////////////////////////////////////
void IgnRenderer::BroadcastRightClick()
{
if (!this->dataPtr->mouseDirty)
return;

if (this->dataPtr->mouseEvent.Dragging())
return;

if (this->dataPtr->mouseEvent.Button() != common::MouseEvent::RIGHT ||
this->dataPtr->mouseEvent.Type() != common::MouseEvent::RELEASE)
return;

auto pos = this->ScreenToScene(this->dataPtr->mouseEvent.Pos());

events::RightClickToScene rightClickToSceneEvent(pos);
App()->sendEvent(App()->findChild<MainWindow *>(), &rightClickToSceneEvent);
}

/////////////////////////////////////////////////
void IgnRenderer::Initialize()
{
Expand Down Expand Up @@ -1016,6 +1135,14 @@ void IgnRenderer::Destroy()
}
}

/////////////////////////////////////////////////
void IgnRenderer::NewHoverEvent(const math::Vector2i &_hoverPos)
{
std::lock_guard<std::mutex> lock(this->dataPtr->mutex);
this->dataPtr->mouseHoverPos = _hoverPos;
this->dataPtr->hoverDirty = true;
}

/////////////////////////////////////////////////
void IgnRenderer::NewMouseEvent(const common::MouseEvent &_e,
const math::Vector2d &_drag)
Expand Down Expand Up @@ -1455,6 +1582,12 @@ void Scene3D::LoadConfig(const tinyxml2::XMLElement *_pluginElem)
}
}

/////////////////////////////////////////////////
void RenderWindowItem::OnHovered(const ignition::math::Vector2i &_hoverPos)
{
this->dataPtr->renderThread->ignRenderer.NewHoverEvent(_hoverPos);
}

/////////////////////////////////////////////////
void RenderWindowItem::mousePressEvent(QMouseEvent *_e)
{
Expand Down Expand Up @@ -1505,23 +1638,57 @@ void RenderWindowItem::wheelEvent(QWheelEvent *_e)
this->dataPtr->mouseEvent, math::Vector2d(scroll, scroll));
}

///////////////////////////////////////////////////
// void Scene3D::resizeEvent(QResizeEvent *_e)
// {
// if (this->dataPtr->renderWindow)
// {
// this->dataPtr->renderWindow->OnResize(_e->size().width(),
// _e->size().height());
// }
//
// if (this->dataPtr->camera)
// {
// this->dataPtr->camera->SetAspectRatio(
// static_cast<double>(this->width()) / this->height());
// this->dataPtr->camera->SetHFOV(M_PI * 0.5);
// }
// }
//
////////////////////////////////////////////////
void RenderWindowItem::HandleKeyPress(QKeyEvent *_e)
{
this->dataPtr->renderThread->ignRenderer.HandleKeyPress(_e);
}

////////////////////////////////////////////////
void RenderWindowItem::HandleKeyRelease(QKeyEvent *_e)
{
this->dataPtr->renderThread->ignRenderer.HandleKeyRelease(_e);
}

/////////////////////////////////////////////////
bool Scene3D::eventFilter(QObject *_obj, QEvent *_event)
{
if (_event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(_event);
if (keyEvent)
{
auto renderWindow = this->PluginItem()->findChild<RenderWindowItem *>();
renderWindow->HandleKeyPress(keyEvent);
}
}
else if (_event->type() == QEvent::KeyRelease)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(_event);
if (keyEvent)
{
auto renderWindow = this->PluginItem()->findChild<RenderWindowItem *>();
renderWindow->HandleKeyRelease(keyEvent);
}
}

// Standard event processing
return QObject::eventFilter(_obj, _event);
}

/////////////////////////////////////////////////
void Scene3D::OnHovered(int _mouseX, int _mouseY)
{
auto renderWindow = this->PluginItem()->findChild<RenderWindowItem *>();
renderWindow->OnHovered({_mouseX, _mouseY});
}

/////////////////////////////////////////////////
void Scene3D::OnFocusWindow()
{
auto renderWindow = this->PluginItem()->findChild<RenderWindowItem *>();
renderWindow->forceActiveFocus();
}

// Register this plugin
IGNITION_ADD_PLUGIN(ignition::gui::plugins::Scene3D,
Expand Down
51 changes: 50 additions & 1 deletion src/plugins/scene3d/Scene3D.hh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ namespace plugins
/// \brief Destructor
public: virtual ~Scene3D();

/// \brief Callback when the mouse hovers to a new position.
/// \param[in] _mouseX x coordinate of the hovered mouse position.
/// \param[in] _mouseY y coordinate of the hovered mouse position.
public slots: void OnHovered(int _mouseX, int _mouseY);

/// \brief Callback when the mouse enters the render window to
/// focus the window for mouse/key events
public slots: void OnFocusWindow();

// Documentation inherited
protected: bool eventFilter(QObject *_obj, QEvent *_event) override;

// Documentation inherited
public: virtual void LoadConfig(const tinyxml2::XMLElement *_pluginElem)
override;
Expand Down Expand Up @@ -106,9 +118,33 @@ namespace plugins
public: void NewMouseEvent(const common::MouseEvent &_e,
const math::Vector2d &_drag = math::Vector2d::Zero);

/// \brief New hover event triggered.
/// \param[in] _hoverPos Mouse hover screen position
public: void NewHoverEvent(const math::Vector2i &_hoverPos);

/// \brief Handle key press event for snapping
/// \param[in] _e The key event to process.
public: void HandleKeyPress(QKeyEvent *_e);

/// \brief Handle key release event for snapping
/// \param[in] _e The key event to process.
public: void HandleKeyRelease(QKeyEvent *_e);

/// \brief Handle mouse event for view control
private: void HandleMouseEvent();

/// \brief Handle mouse event for view control
private: void HandleMouseViewControl();

/// \brief Broadcasts the currently hovered 3d scene location.
private: void BroadcastHoverPos();

/// \brief Broadcasts a left click within the scene
private: void BroadcastLeftClick();

/// \brief Broadcasts a right click within the scene
private: void BroadcastRightClick();

/// \brief Retrieve the first point on a surface in the 3D scene hit by a
/// ray cast from the given 2D screen coordinates.
/// \param[in] _screenPos 2D coordinates on the screen, in pixels.
Expand Down Expand Up @@ -254,9 +290,22 @@ namespace plugins
/// \param[in] _topic Scene topic
public: void SetSceneTopic(const std::string &_topic);

/// \brief Called when the mouse hovers to a new position.
/// \param[in] _hoverPos 2D coordinates of the hovered mouse position on
/// the render window.
public: void OnHovered(const ignition::math::Vector2i &_hoverPos);

/// \brief Slot called when thread is ready to be started
public Q_SLOTS: void Ready();

/// \brief Handle key press event for snapping
/// \param[in] _e The key event to process.
public: void HandleKeyPress(QKeyEvent *_e);

/// \brief Handle key release event for snapping
/// \param[in] _e The key event to process.
public: void HandleKeyRelease(QKeyEvent *_e);

// Documentation inherited
protected: virtual void mousePressEvent(QMouseEvent *_e) override;

Expand All @@ -276,7 +325,7 @@ namespace plugins
/// \param[in] _data The node transformation data.
/// \return Updated node.
private: QSGNode *updatePaintNode(QSGNode *_oldNode,
QQuickItem::UpdatePaintNodeData *_data) override;
QQuickItem::UpdatePaintNodeData *_data) override;

/// \internal
/// \brief Pointer to private data.
Expand Down
17 changes: 16 additions & 1 deletion src/plugins/scene3d/Scene3D.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*
*/
import QtQuick 2.0
import QtQuick 2.9
import QtQuick.Controls 2.0
import RenderWindow 1.0
import QtGraphicalEffects 1.0
Expand All @@ -28,6 +28,21 @@ Rectangle {
*/
property bool gammaCorrect: false

/**
* Get mouse position on 3D widget
*/
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
onEntered: {
Scene3D.OnFocusWindow()
}
onPositionChanged: {
Scene3D.OnHovered(mouseArea.mouseX, mouseArea.mouseY);
}
}

RenderWindow {
id: renderWindow
Expand Down
Loading

0 comments on commit 4a0159b

Please sign in to comment.