Sfoglia il codice sorgente

Hide UIElement3D from public API, clean up UIElement3D and UIComponent.

`UIElement3D` is no longer in public API. This prompted addition of `UIComponent::SetViewportIndex(unsigned index)` API for controlling which viewport is used for UI input mapping. If component does not belong to a node then index will be cached and used when component is added to a node. Not setting viewport index or setting invalid index will result in use of viewport at index 0.

`UIElement3D` no longer holds `UIComponent` pointer. Instead it holds `Node` pointer and obtains `Scene` and `StaticModel` directly from the model. This allows model to be removed and re-added without breaking. Note that after re-adding (likely new) `StaticModel` it is user's responsibility to set material returned by `UIComponent` to a new `StaticModel`.

`UIElement3D` no longer caches model pointer if component does not own the model. As a result of that flag `isStaticModelOwned_` was removed.

Swapped protected members and methods in `UIComponent` to fit style guidelines.
Rokas Kupstys 8 anni fa
parent
commit
4571e9ba20
3 ha cambiato i file con 134 aggiunte e 154 eliminazioni
  1. 0 1
      Source/Urho3D/UI/UI.cpp
  2. 122 113
      Source/Urho3D/UI/UIComponent.cpp
  3. 12 40
      Source/Urho3D/UI/UIComponent.h

+ 0 - 1
Source/Urho3D/UI/UI.cpp

@@ -2131,7 +2131,6 @@ void RegisterUILibrary(Context* context)
     ProgressBar::RegisterObject(context);
     ToolTip::RegisterObject(context);
     UIComponent::RegisterObject(context);
-    UIElement3D::RegisterObject(context);
 }
 
 }

+ 122 - 113
Source/Urho3D/UI/UIComponent.cpp

@@ -19,7 +19,6 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 //
-#include "UIComponent.h"
 #include "../Core/Context.h"
 #include "../Graphics/BillboardSet.h"
 #include "../Graphics/Graphics.h"
@@ -32,9 +31,11 @@
 #include "../Graphics/Camera.h"
 #include "../Graphics/VertexBuffer.h"
 #include "../Scene/Scene.h"
+#include "../Scene/SceneEvents.h"
 #include "../Resource/ResourceCache.h"
 #include "../IO/Log.h"
 #include "../UI/UI.h"
+#include "../UI/UIComponent.h"
 #include "../UI/UIEvents.h"
 
 
@@ -46,9 +47,106 @@ static int const UICOMPONENT_MIN_TEXTURE_SIZE = 64;
 static int const UICOMPONENT_MAX_TEXTURE_SIZE = 4096;
 
 
-UIComponent::UIComponent(Context* context) : 
-    Component(context),
-    isStaticModelOwned_(false)
+class UIElement3D : public UIElement
+{
+    URHO3D_OBJECT(UIElement3D, UIElement);
+public:
+    /// Construct.
+    UIElement3D(Context* context) : UIElement(context) { }
+    /// Destruct.
+    virtual ~UIElement3D() override = default;
+    /// Set UIComponent which is using this element as root element.
+    void SetNode(Node* node) { node_ = node; }
+    /// Set active viewport through which this element is rendered. If viewport is not set, it defaults to first viewport.
+    void SetViewport(Viewport* viewport) { viewport_ = viewport; }
+    /// Convert element coordinates to screen coordinates.
+    IntVector2 ElementToScreen(const IntVector2& position) override
+    {
+        URHO3D_LOGERROR("UIElement3D::ElementToScreen is not implemented.");
+        return {-1, -1};
+    }
+    /// Convert screen coordinates to element coordinates.
+    IntVector2 ScreenToElement(const IntVector2& screenPos) override
+    {
+        IntVector2 result(-1, -1);
+
+        if (node_.Expired())
+            return result;
+
+        Scene* scene = node_->GetScene();
+        StaticModel* model = node_->GetComponent<StaticModel>();
+        if (scene == nullptr || model == nullptr)
+            return result;
+
+        Renderer* renderer = GetSubsystem<Renderer>();
+        if (renderer == nullptr)
+            return result;
+
+        // \todo Always uses the first viewport, in case there are multiple
+        Octree* octree = scene->GetComponent<Octree>();
+        if (viewport_ == nullptr)
+            viewport_ = renderer->GetViewportForScene(scene, 0);
+
+        if (viewport_.Expired() || octree == nullptr)
+            return result;
+
+        if (viewport_->GetScene() != scene)
+        {
+            URHO3D_LOGERROR("UIComponent and Viewport set to component's root element belong to different scenes.");
+            return result;
+        }
+
+        Camera* camera = viewport_->GetCamera();
+
+        if (camera == nullptr)
+            return result;
+
+        IntRect rect = viewport_->GetRect();
+        if (rect == IntRect::ZERO)
+        {
+            Graphics* graphics = GetSubsystem<Graphics>();
+            rect.right_ = graphics->GetWidth();
+            rect.bottom_ = graphics->GetHeight();
+        }
+
+        Ray ray(camera->GetScreenRay((float)screenPos.x_ / rect.Width(), (float)screenPos.y_ / rect.Height()));
+        PODVector<RayQueryResult> queryResultVector;
+        RayOctreeQuery query(queryResultVector, ray, RAY_TRIANGLE_UV, M_INFINITY, DRAWABLE_GEOMETRY, DEFAULT_VIEWMASK);
+
+        octree->Raycast(query);
+
+        if (queryResultVector.Empty())
+            return result;
+
+        for (unsigned i = 0; i < queryResultVector.Size(); i++)
+        {
+            RayQueryResult& queryResult = queryResultVector[i];
+            if (queryResult.drawable_ != model)
+            {
+                // ignore billboard sets by default
+                if (queryResult.drawable_->GetTypeInfo()->IsTypeOf(BillboardSet::GetTypeStatic()))
+                    continue;
+                return result;
+            }
+
+            Vector2& uv = queryResult.textureUV_;
+            result = IntVector2(static_cast<int>(uv.x_ * GetWidth()),
+                static_cast<int>(uv.y_ * GetHeight()));
+            return result;
+        }
+        return result;
+    }
+
+protected:
+    /// A UIComponent which owns this element.
+    WeakPtr<Node> node_;
+    /// Viewport which renders this element.
+    WeakPtr<Viewport> viewport_;
+};
+
+UIComponent::UIComponent(Context* context)
+    : Component(context)
+    , viewportIndex_(0)
 {
     texture_ = context_->CreateObject<Texture2D>();
     texture_->SetFilterMode(FILTER_BILINEAR);
@@ -57,7 +155,6 @@ UIComponent::UIComponent(Context* context) :
     texture_->SetNumLevels(1);                                        // No mipmaps
 
     rootElement_ = context_->CreateObject<UIElement3D>();
-    rootElement_->SetUIComponent(this);
     rootElement_->SetTraversalMode(TM_BREADTH_FIRST);
     rootElement_->SetEnabled(true);
 
@@ -79,6 +176,7 @@ UIComponent::~UIComponent()
 void UIComponent::RegisterObject(Context* context)
 {
     context->RegisterFactory<UIComponent>();
+    context->RegisterFactory<UIElement3D>();
 }
 
 UIElement* UIComponent::GetRoot() const
@@ -96,34 +194,28 @@ Texture2D* UIComponent::GetTexture() const
     return texture_;
 }
 
-StaticModel* UIComponent::GetModel() const
-{
-    return model_;
-}
-
 void UIComponent::OnNodeSet(Node* node)
 {
+    UIElement3D* rootElement = static_cast<UIElement3D*>(rootElement_.Get());
+    rootElement->SetNode(node);
     if (node)
     {
-        model_ = node->GetComponent<StaticModel>();
-        if (model_.Null())
-        {
-            isStaticModelOwned_ = true;
-            model_ = node->CreateComponent<StaticModel>();
-        }
-        model_->SetMaterial(material_);
-        rootElement_->SetRenderTexture(texture_);
+        Renderer* renderer = GetSubsystem<Renderer>();
+        StaticModel* model = node->GetComponent<StaticModel>();
+        rootElement->SetViewport(renderer->GetViewportForScene(GetScene(), viewportIndex_));
+        if (model == nullptr)
+            model_ = model = node->CreateComponent<StaticModel>();
+        model->SetMaterial(material_);
+        rootElement->SetRenderTexture(texture_);
     }
     else
     {
-        rootElement_->SetRenderTexture(nullptr);
-        model_->SetMaterial(nullptr);
-        if (isStaticModelOwned_)
+        rootElement->SetRenderTexture(nullptr);
+        if (model_.NotNull())
         {
-            model_->GetNode()->RemoveComponent<StaticModel>();
-            isStaticModelOwned_ = false;
+            model_->Remove();
+            model_ = nullptr;
         }
-        model_ = nullptr;
     }
 }
 
@@ -146,98 +238,15 @@ void UIComponent::OnElementResized(StringHash eventType, VariantMap& args)
         URHO3D_LOGERROR("UIComponent: resizing texture failed.");
 }
 
-IntVector2 UIElement3D::ScreenToElement(const IntVector2& screenPos)
+void UIComponent::SetViewportIndex(unsigned int index)
 {
-    IntVector2 result(-1, -1);
-
-    Scene* scene = component_->GetScene();
-    if (!scene)
-        return result;
-
-    Renderer* renderer = GetSubsystem<Renderer>();
-    if (!renderer)
-        return result;
-
-    // \todo Always uses the first viewport, in case there are multiple
-    Octree* octree = scene->GetComponent<Octree>();
-    Viewport* viewport = viewport_;
-    if (viewport == nullptr)
-        viewport = renderer->GetViewportForScene(scene, 0);
-
-    if (!viewport || !octree)
-        return result;
-
-    if (viewport->GetScene() != scene)
+    viewportIndex_ = index;
+    if (Scene* scene = GetScene())
     {
-        URHO3D_LOGERROR("UIComponent and Viewport set to component's root element belong to different scenes.");
-        return result;
+        Renderer* renderer = GetSubsystem<Renderer>();
+        Viewport* viewport = renderer->GetViewportForScene(scene, index);
+        static_cast<UIElement3D*>(rootElement_.Get())->SetViewport(viewport);
     }
-
-    Camera* camera = viewport->GetCamera();
-
-    if (!camera)
-        return result;
-
-    IntRect rect = viewport->GetRect();
-    if (rect == IntRect::ZERO)
-    {
-        Graphics* graphics = GetSubsystem<Graphics>();
-        rect.right_ = graphics->GetWidth();
-        rect.bottom_ = graphics->GetHeight();
-    }
-
-    Ray ray(camera->GetScreenRay((float)screenPos.x_ / rect.Width(), (float)screenPos.y_ / rect.Height()));
-    PODVector<RayQueryResult> queryResultVector;
-    RayOctreeQuery query(queryResultVector, ray, RAY_TRIANGLE_UV, M_INFINITY, DRAWABLE_GEOMETRY, DEFAULT_VIEWMASK);
-
-    octree->Raycast(query);
-
-    if (queryResultVector.Empty())
-        return result;
-
-    for (unsigned i = 0; i < queryResultVector.Size(); i++)
-    {
-        RayQueryResult& queryResult = queryResultVector[i];
-        if (queryResult.drawable_ != component_->GetModel())
-        {
-            // ignore billboard sets by default
-            if (queryResult.drawable_->GetTypeInfo()->IsTypeOf(BillboardSet::GetTypeStatic()))
-                continue;
-            return result;
-        }
-
-        Vector2& uv = queryResult.textureUV_;
-        result = IntVector2(static_cast<int>(uv.x_ * component_->GetRoot()->GetWidth()),
-            static_cast<int>(uv.y_ * component_->GetRoot()->GetHeight()));
-        return result;
-    }
-    return result;
-}
-
-IntVector2 UIElement3D::ElementToScreen(const IntVector2& position)
-{
-    URHO3D_LOGERROR("UIElement3D::ElementToScreen is not implemented.");
-    return {-1, -1};
-}
-
-void UIElement3D::RegisterObject(Context* context)
-{
-    context->RegisterFactory<UIElement3D>();
-}
-
-UIElement3D::UIElement3D(Context* context)
-    : UIElement(context)
-{
-}
-
-void UIElement3D::SetUIComponent(UIComponent* component)
-{
-    component_ = component;
-}
-
-void UIElement3D::SetViewport(Viewport* viewport)
-{
-    viewport_ = viewport;
 }
 
 }

+ 12 - 40
Source/Urho3D/UI/UIComponent.h

@@ -34,7 +34,6 @@ class Viewport;
 class UIElement;
 class UIBatch;
 class VertexBuffer;
-class UIElement3D;
 
 class URHO3D_API UIComponent : public Component
 {
@@ -54,52 +53,25 @@ public:
     Material* GetMaterial() const;
     /// Return texture which will be used for rendering UI to.
     Texture2D* GetTexture() const;
-    /// Return static model on to which UI will be rendered.
-    StaticModel* GetModel() const;
+    /// Set index of viewport to be used for screen coordinate translation.
+    void SetViewportIndex(unsigned int index);
 
 protected:
-    /// Material that is set to the model.
-    SharedPtr<Material> material_;
-    /// Texture that UIElement will be rendered into.
-    SharedPtr<Texture2D> texture_;
-    /// Model that texture will be applied to.
-    SharedPtr<StaticModel> model_;
-    /// UIElement to be rendered into texture.
-    SharedPtr<UIElement3D> rootElement_;
-    /// Is StaticModel component created by this component.
-    bool isStaticModelOwned_;
-
     /// Handle component being added to Node or removed from it.
     virtual void OnNodeSet(Node* node) override;
     /// Handle resizing of element. Setting size of element will automatically resize texture. UIElement size matches size of texture.
     void OnElementResized(StringHash eventType, VariantMap& args);
-};
 
-class URHO3D_API UIElement3D : public UIElement
-{
-    URHO3D_OBJECT(UIElement3D, UIElement);
-public:
-    /// Construct.
-    UIElement3D(Context* context);
-    /// Destruct.
-    virtual ~UIElement3D() override = default;
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Set UIComponent which is using this element as root element.
-    void SetUIComponent(UIComponent* component);
-    /// Set active viewport through which this element is rendered. If viewport is not set, it defaults to first viewport.
-    void SetViewport(Viewport* viewport);
-    /// Convert screen coordinates to element coordinates.
-    IntVector2 ScreenToElement(const IntVector2& screenPos) override;
-    /// Convert element coordinates to screen coordinates.
-    IntVector2 ElementToScreen(const IntVector2& position) override;
-
-protected:
-    /// A UIComponent which owns this element.
-    WeakPtr<UIComponent> component_;
-    /// Viewport which renders this element.
-    WeakPtr<Viewport> viewport_;
+    /// Material that is set to the model.
+    SharedPtr<Material> material_;
+    /// Texture that UIElement will be rendered into.
+    SharedPtr<Texture2D> texture_;
+    /// Model created by this component. If node already has StaticModel then this will be null.
+    SharedPtr<StaticModel> model_;
+    /// UIElement to be rendered into texture. It also handles screen to UI coordinate translation.
+    SharedPtr<UIElement> rootElement_;
+    /// Viewport index to be set when component is added to a node.
+    unsigned viewportIndex_;
 };
 
 }