diff --git a/app/src/main/cpp/BrowserWorld.cpp b/app/src/main/cpp/BrowserWorld.cpp index d4426dc40..abc5acca2 100644 --- a/app/src/main/cpp/BrowserWorld.cpp +++ b/app/src/main/cpp/BrowserWorld.cpp @@ -871,11 +871,21 @@ BrowserWorld::DrawWorld() { m.externalVR->SetCompositorEnabled(true); m.device->SetRenderMode(device::RenderMode::StandAlone); vrb::Vector headPosition = m.device->GetHeadTransform().GetTranslation(); + vrb::Vector headDirection = m.device->GetHeadTransform().MultiplyDirection(vrb::Vector(0.0f, 0.0f, -1.0f)); if (m.skybox) { m.skybox->SetTransform(vrb::Matrix::Translation(headPosition)); } m.rootTransparent->SortNodes([=](const NodePtr& a, const NodePtr& b) { - return DistanceToNode(a, headPosition) < DistanceToNode(b, headPosition); + const float kMaxFloat = 9999999.0f; + float da = DistanceToPlane(GetWidgetFromNode(a), headPosition, headDirection); + float db = DistanceToPlane(GetWidgetFromNode(b), headPosition, headDirection); + if (da < 0.0f) { + da = std::numeric_limits::max(); + } + if (db < 0.0f) { + db = std::numeric_limits::max(); + } + return da < db; }); m.device->StartFrame(); @@ -1109,6 +1119,28 @@ BrowserWorld::DistanceToNode(const vrb::NodePtr& aTargetNode, const vrb::Vector& return result; } +WidgetPtr +BrowserWorld::GetWidgetFromNode(const vrb::NodePtr& aNode) const { + for (const auto & widget: m.widgets) { + if (widget->GetRoot() == aNode) { + return widget; + } + } + return nullptr; +} + +float +BrowserWorld::DistanceToPlane(const WidgetPtr& aWidget, const vrb::Vector& aPosition, const vrb::Vector& aDirection) const { + if (!aWidget) { + return -1.0f; + } + vrb::Vector result; + bool inside = false; + float distance = -1.0f; + aWidget->GetQuad()->TestIntersection(aPosition, aDirection, result, false, inside, distance); + return distance; +} + } // namespace crow diff --git a/app/src/main/cpp/BrowserWorld.h b/app/src/main/cpp/BrowserWorld.h index c0656577e..3ee8a0cba 100644 --- a/app/src/main/cpp/BrowserWorld.h +++ b/app/src/main/cpp/BrowserWorld.h @@ -21,6 +21,8 @@ typedef std::shared_ptr BrowserWorldPtr; typedef std::weak_ptr BrowserWorldWeakPtr; class WidgetPlacement; typedef std::shared_ptr WidgetPlacementPtr; +class Widget; +typedef std::shared_ptr WidgetPtr; class BrowserWorld { public: @@ -64,6 +66,8 @@ class BrowserWorld { void LoadSkybox(const vrb::TransformPtr transform, const std::string& basePath); void CreateFloor(); float DistanceToNode(const vrb::NodePtr& aNode, const vrb::Vector& aPosition) const; + WidgetPtr GetWidgetFromNode(const vrb::NodePtr& aNode) const; + float DistanceToPlane(const WidgetPtr& aNode, const vrb::Vector& aPosition, const vrb::Vector& aDirection) const; private: State& m; BrowserWorld() = delete; diff --git a/app/src/main/cpp/Widget.cpp b/app/src/main/cpp/Widget.cpp index da126a45a..82944e635 100644 --- a/app/src/main/cpp/Widget.cpp +++ b/app/src/main/cpp/Widget.cpp @@ -288,6 +288,11 @@ Widget::GetRoot() const { return m.root; } +QuadPtr +Widget::GetQuad() const { + return m.quad; +} + vrb::TransformPtr Widget::GetTransformNode() const { return m.transform; diff --git a/app/src/main/cpp/Widget.h b/app/src/main/cpp/Widget.h index 1dff1381b..25dc0c29c 100644 --- a/app/src/main/cpp/Widget.h +++ b/app/src/main/cpp/Widget.h @@ -17,6 +17,9 @@ namespace crow { +class Quad; +typedef std::shared_ptr QuadPtr; + class Widget; typedef std::shared_ptr WidgetPtr; @@ -44,6 +47,7 @@ class Widget { void TogglePointer(const bool aEnabled); bool IsVisible() const; vrb::NodePtr GetRoot() const; + QuadPtr GetQuad() const; vrb::TransformPtr GetTransformNode() const; vrb::NodePtr GetPointerGeometry() const; void SetPointerGeometry(vrb::NodePtr& aNode);