aboutsummaryrefslogtreecommitdiffstats
path: root/support/magicleap/Servo2D
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2018-10-30 03:41:52 -0400
committerGitHub <noreply@github.com>2018-10-30 03:41:52 -0400
commitb5b8550fb206cf7159feed3ea14418b5c0358ee2 (patch)
tree953628bf45801bb71495f7556a8bd0b39418a8c0 /support/magicleap/Servo2D
parent662fd0afa49ff48888e7f6fe42e23470117b2ddd (diff)
parentfc38c04313f377daaaa378172b940b971e220d5c (diff)
downloadservo-b5b8550fb206cf7159feed3ea14418b5c0358ee2.tar.gz
servo-b5b8550fb206cf7159feed3ea14418b5c0358ee2.zip
Auto merge of #22045 - asajeffrey:magicleap-follow-hyperlinks, r=paulrouget
Get the ML port to follow hyperlinks <!-- Please describe your changes on the following line: --> This PR adds some basic mouse support to the magic leap touchpad. Moves are mapped to mouse moves (for hover style) and trigger pulls are mapped to mouse clicks (for following hyperlinks). --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes do not require tests because we can't test on ML <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22045) <!-- Reviewable:end -->
Diffstat (limited to 'support/magicleap/Servo2D')
-rw-r--r--support/magicleap/Servo2D/.vscode/settings.json1
-rw-r--r--support/magicleap/Servo2D/code/inc/Servo2D.h12
-rw-r--r--support/magicleap/Servo2D/code/src/Servo2D.cpp82
3 files changed, 86 insertions, 9 deletions
diff --git a/support/magicleap/Servo2D/.vscode/settings.json b/support/magicleap/Servo2D/.vscode/settings.json
index b367781dc14..e15dd9c895b 100644
--- a/support/magicleap/Servo2D/.vscode/settings.json
+++ b/support/magicleap/Servo2D/.vscode/settings.json
@@ -5,6 +5,7 @@
"C_Cpp.default.includePath": [
"${workspaceFolder}/code/**",
"${config.lumin_sdk}/lumin/usr/include/",
+ "${config.lumin_sdk}/lumin/stl/libc++-lumin/include",
"${config.lumin_sdk}/include/runtime/app",
"${config.lumin_sdk}/include/runtime/core",
"${config.lumin_sdk}/include/runtime/external",
diff --git a/support/magicleap/Servo2D/code/inc/Servo2D.h b/support/magicleap/Servo2D/code/inc/Servo2D.h
index 866f2e09e6c..2f76c306e7c 100644
--- a/support/magicleap/Servo2D/code/inc/Servo2D.h
+++ b/support/magicleap/Servo2D/code/inc/Servo2D.h
@@ -5,6 +5,9 @@
#include <lumin/LandscapeApp.h>
#include <lumin/Prism.h>
#include <lumin/event/ServerEvent.h>
+#include <lumin/event/KeyInputEventData.h>
+#include <lumin/event/ControlTouchPadInputEventData.h>
+#include <lumin/node/QuadNode.h>
#include <lumin/resource/PlanarResource.h>
#include <SceneDescriptor.h>
@@ -88,9 +91,18 @@ protected:
* Handle events from the server
*/
virtual bool eventListener(lumin::ServerEvent* event) override;
+ bool touchpadEventListener(lumin::ControlTouchPadInputEventData* event);
+ bool keyEventListener(lumin::KeyInputEventData* event);
+
+ /**
+ * Get the current cursor position, with respect to the viewport.
+ */
+ glm::vec2 viewportCursorPosition();
+ bool pointInsideViewport(glm::vec2 pt);
private:
lumin::Prism* prism_ = nullptr; // represents the bounded space where the App renders.
lumin::PlanarResource* plane_ = nullptr; // the plane we're rendering into
+ lumin::QuadNode* content_node_ = nullptr; // the node containing the plane
ServoInstance servo_ = nullptr; // the servo instance we're embedding
};
diff --git a/support/magicleap/Servo2D/code/src/Servo2D.cpp b/support/magicleap/Servo2D/code/src/Servo2D.cpp
index 3d6c0ca905e..8704478e210 100644
--- a/support/magicleap/Servo2D/code/src/Servo2D.cpp
+++ b/support/magicleap/Servo2D/code/src/Servo2D.cpp
@@ -11,11 +11,12 @@
#include <SceneDescriptor.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
+#include <glm/gtc/matrix_transform.hpp>
#include <string.h>
// The viewport dimensions (in px).
-const unsigned int VIEWPORT_W = 500;
-const unsigned int VIEWPORT_H = 500;
+const int VIEWPORT_W = 500;
+const int VIEWPORT_H = 500;
// The hidpi factor.
const float HIDPI = 1.0;
@@ -38,6 +39,7 @@ void logger(MLLogLevel lvl, char* msg) {
extern "C" ServoInstance init_servo(EGLContext, EGLSurface, EGLDisplay, MLLogger,
const char* url, int width, int height, float hidpi);
extern "C" void heartbeat_servo(ServoInstance);
+extern "C" void cursor_servo(ServoInstance, float x, float y, bool triggered);
extern "C" void discard_servo(ServoInstance);
// Create a Servo2D instance
@@ -86,12 +88,13 @@ int Servo2D::init() {
}
std::string content_node_id = Servo2D_exportedNodes::content;
- lumin::QuadNode* content_node = lumin::QuadNode::CastFrom(prism_->findNode(content_node_id, root_node));
- if (!content_node) {
+ content_node_ = lumin::QuadNode::CastFrom(prism_->findNode(content_node_id, root_node));
+ if (!content_node_) {
ML_LOG(Error, "Servo2D Failed to get content node");
abort();
return 1;
}
+ content_node_->setTriggerable(true);
lumin::ResourceIDType plane_id = prism_->createPlanarEGLResourceId();
if (!plane_id) {
@@ -107,7 +110,7 @@ int Servo2D::init() {
return 1;
}
- content_node->setRenderResource(plane_id);
+ content_node_->setRenderResource(plane_id);
// Get the EGL context, surface and display.
EGLContext ctx = plane_->getEGLContext();
@@ -117,7 +120,7 @@ int Servo2D::init() {
glViewport(0, 0, VIEWPORT_W, VIEWPORT_H);
// Hook into servo
- servo_ = init_servo(ctx, surf, dpy, logger, "https://servo.org", VIEWPORT_H, VIEWPORT_W, HIDPI);
+ servo_ = init_servo(ctx, surf, dpy, logger, "https://servo.org/", VIEWPORT_H, VIEWPORT_W, HIDPI);
if (!servo_) {
ML_LOG(Error, "Servo2D Failed to init servo instance");
abort();
@@ -192,9 +195,70 @@ bool Servo2D::updateLoop(float fDelta) {
}
bool Servo2D::eventListener(lumin::ServerEvent* event) {
+ // Dispatch based on event type
+ switch (event->getServerEventType()) {
+ case lumin::ServerEventType::kControlTouchPadInputEvent:
+ return touchpadEventListener(static_cast<lumin::ControlTouchPadInputEventData*>(event));
+ case lumin::ServerEventType::kKeyInputEvent:
+ return keyEventListener(static_cast<lumin::KeyInputEventData*>(event));
+ default:
+ return false;
+ }
+}
+
+glm::vec2 Servo2D::viewportCursorPosition() {
+ // Get the cursor position relative to the origin of the content node (in m)
+ glm::vec3 pos = lumin::ui::Cursor::GetPosition(prism_) - content_node_->getPrismPosition();
+
+ // Get the size of the content node (in m)
+ glm::vec2 sz = content_node_->getSize();
+
+ // Convert to a position in viewport px
+ float x = (pos.x / sz.x) * (float)VIEWPORT_W;
+ float y = (1 - pos.y / sz.y) * (float)VIEWPORT_H; // Sigh, invert the y coordinate
+
+ return glm::vec2(x, y);
+}
+
+bool Servo2D::pointInsideViewport(glm::vec2 pt) {
+ return (0 <= pt.x && 0 <= pt.y && pt.x <= VIEWPORT_W && pt.y <= VIEWPORT_H);
+}
+
+bool Servo2D::touchpadEventListener(lumin::ControlTouchPadInputEventData* event) {
+ // Only respond when the cursor is enabled
+ if (!lumin::ui::Cursor::IsEnabled(prism_)) {
+ return false;
+ }
- // Place your event handling here.
+ // Only respond when the cursor is inside the viewport
+ glm::vec2 pos = viewportCursorPosition();
+ if (!pointInsideViewport(pos)) {
+ return false;
+ }
+
+ // Inform Servo of the trigger
+ cursor_servo(servo_, pos.x, pos.y, false);
+ return true;
+}
+
+bool Servo2D::keyEventListener(lumin::KeyInputEventData* event) {
+ // Only respond to trigger keys
+ if (event->keyCode() != lumin::input::KeyCodes::AKEYCODE_EX_TRIGGER) {
+ return false;
+ }
- // Return true if the event is consumed.
- return false;
+ // Only respond when the cursor is enabled
+ if (!lumin::ui::Cursor::IsEnabled(prism_)) {
+ return false;
+ }
+
+ // Only respond when the cursor is inside the viewport
+ glm::vec2 pos = viewportCursorPosition();
+ if (!pointInsideViewport(pos)) {
+ return false;
+ }
+
+ // Inform Servo of the trigger
+ cursor_servo(servo_, pos.x, pos.y, true);
+ return true;
}