From 9f2e0c02dcacf073164ee3e8689c0aac7b092abf Mon Sep 17 00:00:00 2001 From: Imanol Fernandez Date: Tue, 6 Aug 2019 21:12:12 +0200 Subject: [PATCH] Capture pointer input during move gestures. Improve curved keyboard move. (#1500) --- .../mozilla/vrbrowser/ui/widgets/Windows.java | 1 - app/src/main/cpp/BrowserWorld.cpp | 22 ++++++--- app/src/main/cpp/Controller.cpp | 8 ++++ app/src/main/cpp/Controller.h | 3 ++ app/src/main/cpp/WidgetMover.cpp | 47 +++++++++++++++---- app/src/main/cpp/WidgetMover.h | 4 +- 6 files changed, 66 insertions(+), 19 deletions(-) diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/Windows.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/Windows.java index cbbcb7066..557cbea2e 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/Windows.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/Windows.java @@ -510,7 +510,6 @@ private void placeWindow(@NonNull WindowWidget aWindow, WindowPlacement aPositio WidgetPlacement placement = aWindow.getPlacement(); aWindow.setWindowPlacement(aPosition); boolean curved = SettingsStore.getInstance(mContext).getCylinderDensity() > 0; - Log.e("VRB", "mortimer curved: " + curved); switch (aPosition) { case FRONT: placement.anchorX = 0.5f; diff --git a/app/src/main/cpp/BrowserWorld.cpp b/app/src/main/cpp/BrowserWorld.cpp index ed3a89a43..56ca9ce2e 100644 --- a/app/src/main/cpp/BrowserWorld.cpp +++ b/app/src/main/cpp/BrowserWorld.cpp @@ -360,8 +360,8 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) { continue; } - vrb::Vector start = controller.transformMatrix.MultiplyPosition(controller.beamTransformMatrix.MultiplyPosition(vrb::Vector())); - vrb::Vector direction = controller.transformMatrix.MultiplyDirection(controller.beamTransformMatrix.MultiplyDirection(vrb::Vector(0.0f, 0.0f, -1.0f))); + const vrb::Vector start = controller.StartPoint(); + const vrb::Vector direction = controller.Direction(); WidgetPtr hitWidget; float hitDistance = farClip; @@ -373,11 +373,15 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) { // Don't interact with other widgets when resizing gesture is active. continue; } + if (movingWidget && movingWidget->GetWidget() != widget) { + // Don't interact with other widgets when moving gesture is active. + continue; + } vrb::Vector result; vrb::Vector normal; float distance = 0.0f; bool isInWidget = false; - const bool clamp = !widget->IsResizing(); + const bool clamp = !widget->IsResizing() && !movingWidget; if (widget->TestControllerIntersection(start, direction, result, normal, clamp, isInWidget, distance)) { if (isInWidget && (distance < hitDistance)) { hitWidget = widget; @@ -954,8 +958,9 @@ BrowserWorld::StartWidgetMove(int32_t aHandle, int32_t aMoveBehavour) { return; } - vrb::Vector initialPoint; vrb::Vector anchorPoint; + vrb::Vector start; + vrb::Vector direction; int controllerIndex = -1; for (Controller& controller: m.controllers->GetControllers()) { @@ -965,7 +970,8 @@ BrowserWorld::StartWidgetMove(int32_t aHandle, int32_t aMoveBehavour) { if (controller.pointer && controller.pointer->GetHitWidget() == widget) { controllerIndex = controller.index; - initialPoint = controller.pointerWorldPoint; + start = controller.StartPoint(); + direction = controller.Direction(); int32_t w, h; widget->GetSurfaceTextureSize(w, h); anchorPoint.x() = controller.pointerX / (float)w; @@ -979,7 +985,11 @@ BrowserWorld::StartWidgetMove(int32_t aHandle, int32_t aMoveBehavour) { } m.movingWidget = WidgetMover::Create(); - m.movingWidget->StartMoving(widget, aMoveBehavour, controllerIndex, initialPoint, anchorPoint); + WidgetPtr parent; + if (widget->GetPlacement()->parentHandle) { + parent = m.GetWidget(widget->GetPlacement()->parentHandle); + } + m.movingWidget->StartMoving(widget, parent, aMoveBehavour, controllerIndex, start, direction, anchorPoint); } void diff --git a/app/src/main/cpp/Controller.cpp b/app/src/main/cpp/Controller.cpp index 654e51d72..2c6e581ab 100644 --- a/app/src/main/cpp/Controller.cpp +++ b/app/src/main/cpp/Controller.cpp @@ -96,6 +96,14 @@ Controller::Reset() { lastHoverEvent = 0.0; } +vrb::Vector Controller::StartPoint() const { + return transformMatrix.MultiplyPosition(beamTransformMatrix.MultiplyPosition(vrb::Vector())); +} + +vrb::Vector Controller::Direction() const { + return transformMatrix.MultiplyDirection(beamTransformMatrix.MultiplyDirection(vrb::Vector(0.0f, 0.0f, -1.0f))); +} + void Controller::DetachRoot() { if (transform) { diff --git a/app/src/main/cpp/Controller.h b/app/src/main/cpp/Controller.h index ffcae5699..dafecd757 100644 --- a/app/src/main/cpp/Controller.h +++ b/app/src/main/cpp/Controller.h @@ -56,6 +56,9 @@ struct Controller { double lastHoverEvent; device::CapabilityFlags deviceCapabilities; + vrb::Vector StartPoint() const; + vrb::Vector Direction() const; + Controller(); Controller(const Controller& aController); ~Controller(); diff --git a/app/src/main/cpp/WidgetMover.cpp b/app/src/main/cpp/WidgetMover.cpp index cb24e7a6d..3a9b8756e 100644 --- a/app/src/main/cpp/WidgetMover.cpp +++ b/app/src/main/cpp/WidgetMover.cpp @@ -22,6 +22,7 @@ enum class WidgetMoveBehaviour { struct WidgetMover::State { WidgetPtr widget; + WidgetPtr parentWidget; int attachedController; vrb::Vector initialPoint; vrb::Vector anchorPoint; @@ -39,17 +40,41 @@ struct WidgetMover::State { , endRotation(0) {} - vrb::Vector ProjectPoint(const vrb::Vector& aWorldPoint) const { - if (widget->GetCylinder()) { + + vrb::Vector ProjectPoint(const WidgetPtr& aWidget, const vrb::Vector& aWorldPoint) const { + if (aWidget->GetCylinder()) { + // For a cylinder project the point to the virtual quad. vrb::Vector min, max; - widget->GetWidgetMinAndMax(min, max); - vrb::Vector point = widget->GetCylinder()->ProjectPointToQuad(aWorldPoint, 0.5f, widget->GetCylinderDensity(), min, max); - return widget->GetTransformNode()->GetWorldTransform().MultiplyPosition(point); + aWidget->GetWidgetMinAndMax(min, max); + vrb::Vector point = aWidget->GetCylinder()->ProjectPointToQuad(aWorldPoint, 0.5f, aWidget->GetCylinderDensity(), min, max); + return aWidget->GetTransformNode()->GetWorldTransform().MultiplyPosition(point); } else { return aWorldPoint; } } + vrb::Vector GetMovePoint(const vrb::Vector& aStart, const vrb::Vector& aDirection) const { + float hitDistance = -1; + vrb::Vector hitPoint; + vrb::Vector hitNormal; + bool isInWidget = false; + widget->TestControllerIntersection(aStart, aDirection, hitPoint, hitNormal, false, isInWidget, hitDistance); + + vrb::Vector result = ProjectPoint(widget, hitPoint); + + if (parentWidget && moveBehaviour == WidgetMoveBehaviour::KEYBOARD && widget->GetCylinder()) { + // For Cylindrical keyboard move we want to use the x translation from the parent widget (the window) + parentWidget->TestControllerIntersection(aStart, aDirection, hitPoint, hitNormal, false, isInWidget, hitDistance); + if (hitDistance >= 0) { + vrb::Vector point = ProjectPoint(parentWidget, hitPoint); + result.x() = point.x(); + result.z() = point.z(); + } + } + + return result; + } + WidgetPlacementPtr& HandleKeyboardMove(const vrb::Vector& aDelta) { float x = initialPlacement->translation.x() * WidgetPlacement::kWorldDPIRatio; float y = initialPlacement->translation.y() * WidgetPlacement::kWorldDPIRatio; @@ -85,7 +110,7 @@ struct WidgetMover::State { angle = t * maxAngle; } - float t = 0.0f; + float t; if (y > 1.45f) { t = 1.0f; } else { @@ -121,7 +146,7 @@ WidgetMover::HandleMove(const vrb::Vector& aStart, const vrb::Vector& aDirection if (hitDistance < 0) { return nullptr; }; - hitPoint = m.ProjectPoint(hitPoint); + hitPoint = m.GetMovePoint(aStart, aDirection); vrb::Vector delta = hitPoint - m.initialPoint; delta.y() = hitPoint.y() - m.initialPoint.y(); @@ -145,16 +170,17 @@ WidgetMover::HandleMove(const vrb::Vector& aStart, const vrb::Vector& aDirection } void -WidgetMover::StartMoving(const WidgetPtr& aWidget, const int32_t aMoveBehaviour, const int32_t aControllerIndex, - const vrb::Vector& aHitPoint, const vrb::Vector& aAnchorPoint) { +WidgetMover::StartMoving(const WidgetPtr& aWidget, const WidgetPtr& aParentWidget, const int32_t aMoveBehaviour, const int32_t aControllerIndex, + const vrb::Vector& aStart, const vrb::Vector& aDirection, const vrb::Vector& aAnchorPoint) { m.widget = aWidget; + m.parentWidget = aParentWidget; m.attachedController = aControllerIndex; m.initialTransform = aWidget->GetTransform(); - m.initialPoint = m.ProjectPoint(aHitPoint); m.anchorPoint = aAnchorPoint; m.initialPlacement = aWidget->GetPlacement(); m.movePlacement = WidgetPlacement::Create(*m.initialPlacement); m.moveBehaviour = (WidgetMoveBehaviour) aMoveBehaviour; + m.initialPoint = m.GetMovePoint(aStart, aDirection); } void @@ -164,6 +190,7 @@ WidgetMover::EndMoving() { VRBrowser::HandleMoveEnd(m.widget->GetHandle(), m.endDelta.x(), m.endDelta.y(), m.endDelta.z(), m.endRotation); } m.widget = nullptr; + m.parentWidget = nullptr; } WidgetPtr diff --git a/app/src/main/cpp/WidgetMover.h b/app/src/main/cpp/WidgetMover.h index 95fd252c1..2fd521ada 100644 --- a/app/src/main/cpp/WidgetMover.h +++ b/app/src/main/cpp/WidgetMover.h @@ -28,8 +28,8 @@ class WidgetMover { static WidgetMoverPtr Create(); bool IsMoving(const int aControllerIndex) const; WidgetPlacementPtr HandleMove(const vrb::Vector& aStart, const vrb::Vector& aDirection); - void StartMoving(const WidgetPtr& aWidget, const int32_t aMoveBehavour, const int32_t aControllerIndex, - const vrb::Vector& aHitPoint, const vrb::Vector& aAnchorPoint); + void StartMoving(const WidgetPtr& aWidget, const WidgetPtr& aParentWidget, const int32_t aMoveBehavour, const int32_t aControllerIndex, + const vrb::Vector& aStart, const vrb::Vector& aDirection, const vrb::Vector& aAnchorPoint); void EndMoving(); WidgetPtr GetWidget() const; protected: