Browse Source

Working on 3D view

Josh Engebretson 10 years ago
parent
commit
75e2e568ed
19 changed files with 508 additions and 494 deletions
  1. 4 0
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/BlueUnlit.xml
  2. 4 0
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/BrightBlueUnlit.xml
  3. 4 0
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/BrightGreenUnlit.xml
  4. 4 0
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/BrightRedUnlit.xml
  5. 4 0
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/GreenUnlit.xml
  6. 4 0
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/RedUnlit.xml
  7. BIN
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Models/Axes.mdl
  8. BIN
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Models/ImagePlane.mdl
  9. BIN
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Models/RotateAxes.mdl
  10. BIN
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/Models/ScaleAxes.mdl
  11. 47 0
      Source/AtomicEditor/Source/Editors/SceneEditor3D/Gizmo3D.cpp
  12. 116 0
      Source/AtomicEditor/Source/Editors/SceneEditor3D/Gizmo3D.h
  13. 116 0
      Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneEditor3D.cpp
  14. 17 15
      Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneEditor3D.h
  15. 30 93
      Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneView3D.cpp
  16. 64 0
      Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneView3D.h
  17. 92 4
      Source/AtomicEditor/Source/UI/UIInspectorDataBinding.cpp
  18. 0 380
      Source/AtomicEditor/Source/UI/UIInspectorFrame.cpp
  19. 2 2
      Source/AtomicEditor/Source/UI/UIResourceFrame.cpp

+ 4 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/BlueUnlit.xml

@@ -0,0 +1,4 @@
+<material>
+    <technique name="Techniques/NoTextureOverlay.xml" />
+    <parameter name="MatDiffColor" value="0 0 0.5 1" />
+</material>

+ 4 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/BrightBlueUnlit.xml

@@ -0,0 +1,4 @@
+<material>
+    <technique name="Techniques/NoTextureOverlay.xml" />
+    <parameter name="MatDiffColor" value="0 0 1 1" />
+</material>

+ 4 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/BrightGreenUnlit.xml

@@ -0,0 +1,4 @@
+<material>
+    <technique name="Techniques/NoTextureOverlay.xml" />
+    <parameter name="MatDiffColor" value="0 1 0 1" />
+</material>

+ 4 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/BrightRedUnlit.xml

@@ -0,0 +1,4 @@
+<material>
+    <technique name="Techniques/NoTextureOverlay.xml" />
+    <parameter name="MatDiffColor" value="1 0 0 1" />
+</material>

+ 4 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/GreenUnlit.xml

@@ -0,0 +1,4 @@
+<material>
+    <technique name="Techniques/NoTextureOverlay.xml" />
+    <parameter name="MatDiffColor" value="0 0.5 0 1" />
+</material>

+ 4 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Materials/RedUnlit.xml

@@ -0,0 +1,4 @@
+<material>
+    <technique name="Techniques/NoTextureOverlay.xml" />
+    <parameter name="MatDiffColor" value="0.5 0 0 1" />
+</material>

BIN
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Models/Axes.mdl


BIN
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Models/ImagePlane.mdl


BIN
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Models/RotateAxes.mdl


BIN
Data/AtomicEditor/Resources/EditorData/AtomicEditor/Models/ScaleAxes.mdl


+ 47 - 0
Source/AtomicEditor/Source/Editors/SceneEditor3D/Gizmo3D.cpp

@@ -0,0 +1,47 @@
+// Portions Copyright (c) 2008-2015 the Urho3D project.
+
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// Please see LICENSE.md in repository root for license information
+// https://github.com/AtomicGameEngine/AtomicGameEngine
+
+#include "AtomicEditor.h"
+
+#include <Atomic/Graphics/Model.h>
+#include <Atomic/Graphics/Material.h>
+#include <Atomic/Resource/ResourceCache.h>
+
+#include "Gizmo3D.h"
+
+namespace AtomicEditor
+{
+
+
+Gizmo3D::Gizmo3D(Context* context) : Object(context)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+
+    gizmoNode_ = new Node(context_);
+    gizmo_ = gizmoNode_->CreateComponent<StaticModel>();
+    gizmo_->SetModel(cache->GetResource<Model>("AtomicEditor/Models/Axes.mdl"));
+    gizmo_->SetMaterial(0, cache->GetResource<Material>("Materials/Editor/RedUnlit.xml"));
+    gizmo_->SetMaterial(1, cache->GetResource<Material>("Materials/Editor/GreenUnlit.xml"));
+    gizmo_->SetMaterial(2, cache->GetResource<Material>("Materials/Editor/BlueUnlit.xml"));
+
+
+    gizmo_->SetEnabled(false);
+    gizmo_->SetViewMask(0x80000000); // Editor raycasts use viewmask 0x7fffffff
+    gizmo_->SetOccludee(false);
+
+    gizmoAxisX_.lastSelected_ = false;
+    gizmoAxisY_.lastSelected_ = false;
+    gizmoAxisZ_.lastSelected_ = false;
+    lastGizmoMode_ = EDIT_MOVE;
+
+}
+
+Gizmo3D::~Gizmo3D()
+{
+
+}
+
+}

+ 116 - 0
Source/AtomicEditor/Source/Editors/SceneEditor3D/Gizmo3D.h

@@ -0,0 +1,116 @@
+
+// Portions Copyright (c) 2008-2015 the Urho3D project.
+
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// Please see LICENSE.md in repository root for license information
+// https://github.com/AtomicGameEngine/AtomicGameEngine
+
+#pragma once
+
+#include <Atomic/Core/Object.h>
+#include <Atomic/Math/Ray.h>
+#include <Atomic/Scene/Scene.h>
+
+#include <Atomic/Graphics/StaticModel.h>
+
+using namespace Atomic;
+
+namespace Atomic
+{
+    class Node;
+}
+
+namespace AtomicEditor
+{
+
+class Gizmo3DAxis
+{
+public:
+
+    Ray axisRay_;
+    bool selected_;
+    bool lastSelected_;
+    float t_;
+    float d_;
+    float lastT_;
+    float lastD_;
+
+    Gizmo3DAxis()
+    {
+        selected_ = false;
+        lastSelected_ = false;
+        t_ = 0.0;
+        d_ = 0.0;
+        lastT_ = 0.0;
+        lastD_ = 0.0;
+    }
+
+    /*
+    void Update(Ray cameraRay, float scale, bool drag)
+    {
+        // Do not select when UI has modal element
+        if (ui.HasModalElement())
+        {
+            selected = false;
+            return;
+        }
+
+        Vector3 closest = cameraRay.ClosestPoint(axisRay);
+        Vector3 projected = axisRay.Project(closest);
+        d = axisRay.Distance(closest);
+        t = (projected - axisRay.origin).DotProduct(axisRay.direction);
+
+        // Determine the sign of d from a plane that goes through the camera position to the axis
+        Plane axisPlane(cameraNode.position, axisRay.origin, axisRay.origin + axisRay.direction);
+        if (axisPlane.Distance(closest) < 0.0)
+            d = -d;
+
+        // Update selected status only when not dragging
+        if (!drag)
+        {
+            selected = Abs(d) < axisMaxD * scale && t >= -axisMaxD * scale && t <= axisMaxT * scale;
+            lastT = t;
+            lastD = d;
+        }
+    }
+    */
+
+    void Moved()
+    {
+        lastT_ = t_;
+        lastD_ = d_;
+    }
+};
+
+class Gizmo3D: public Object
+{
+    OBJECT(Gizmo3D);
+
+public:
+
+    enum GizmoMode
+    {
+        EDIT_MOVE
+    };
+
+    Gizmo3D(Context* context);
+    virtual ~Gizmo3D();
+
+    Node* GetGizmoNode() { return gizmoNode_; }
+
+private:
+
+    SharedPtr<Node> gizmoNode_;
+
+    WeakPtr<StaticModel> gizmo_;
+
+    Gizmo3DAxis gizmoAxisX_;
+    Gizmo3DAxis gizmoAxisY_;
+    Gizmo3DAxis gizmoAxisZ_;
+
+    GizmoMode lastGizmoMode_;
+
+};
+
+}
+

+ 116 - 0
Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneEditor3D.cpp

@@ -0,0 +1,116 @@
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// Please see LICENSE.md in repository root for license information
+// https://github.com/AtomicGameEngine/AtomicGameEngine
+
+#include "AtomicEditor.h"
+#include <Atomic/IO/Log.h>
+#include <Atomic/Core/CoreEvents.h>
+#include <Atomic/Scene/Scene.h>
+#include <Atomic/Graphics/Camera.h>
+
+#include <Atomic/Graphics/DebugRenderer.h>
+#include <Atomic/Graphics/Viewport.h>
+#include <Atomic/Graphics/Octree.h>
+
+#include <Atomic/IO/FileSystem.h>
+#include <Atomic/Resource/ResourceCache.h>
+
+#include <Atomic/Physics/PhysicsWorld.h>
+
+#include "AEEditor.h"
+#include "AEEvents.h"
+
+#include <Atomic/Input/Input.h>
+#include "SceneEditor3D.h"
+
+#include <Atomic/UI/TBUI.h>
+#include <Atomic/UI/UI.h>
+#include <Atomic/UI/View3D.h>
+
+namespace AtomicEditor
+{
+
+SceneEditor3D ::SceneEditor3D(Context* context, const String &fullpath, TBTabContainer *container) :
+    ResourceEditor(context, fullpath, container),
+    layout_(0),
+    view3DContainer_(0)
+{
+    layout_ = new TBLayout();
+    layout_->SetLayoutDistribution(LAYOUT_DISTRIBUTION_GRAVITY);
+    layout_->SetSize(container_->GetRect().w, container_->GetRect().h);
+
+    view3DContainer_ = new TBContainer();
+    view3DContainer_->SetGravity(WIDGET_GRAVITY_ALL);
+
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+
+    scene_ = new Scene(context_);
+    SharedPtr<File> xmlFile = cache->GetFile(fullpath);
+
+    if (GetExtension(fullpath) == ".scene")
+        scene_->LoadXML(*xmlFile);
+    else
+        scene_->Load(*xmlFile);
+
+    scene_->SetUpdateEnabled(false);
+
+    debugRenderer_ = scene_->GetComponent<DebugRenderer>();
+
+    if (debugRenderer_.Null())
+    {
+        debugRenderer_ = scene_->CreateComponent<DebugRenderer>();
+    }
+
+    octree_ = scene_->GetComponent<Octree>();
+
+    if (octree_.Null())
+    {
+        LOGWARNING("Scene without an octree loaded");
+        octree_ = scene_->CreateComponent<Octree>();
+    }
+
+    // once octree/debugrenderer exist
+    sceneView_ = new SceneView3D(context_, this);
+
+    layout_->AddChild(view3DContainer_);
+
+    container_->GetContentRoot()->AddChild(layout_);
+
+    SubscribeToEvent(E_UPDATE, HANDLER(SceneEditor3D, HandleUpdate));
+    SubscribeToEvent(E_EDITORACTIVENODECHANGE, HANDLER(SceneEditor3D, HandleEditorActiveNodeChange));
+
+    // TODO: generate this event properly
+    VariantMap eventData;
+    eventData[EditorActiveSceneChange::P_SCENE] = scene_;
+    SendEvent(E_EDITORACTIVESCENECHANGE, eventData);
+
+}
+
+SceneEditor3D::~SceneEditor3D()
+{
+}
+
+bool SceneEditor3D::OnEvent(const TBWidgetEvent &ev)
+{
+    return false;
+}
+
+void SceneEditor3D::SelectNode(Node* node)
+{
+
+}
+
+void SceneEditor3D::HandleUpdate(StringHash eventType, VariantMap& eventData)
+{
+    // view3D_->QueueUpdate();
+}
+
+void SceneEditor3D::HandleEditorActiveNodeChange(StringHash eventType, VariantMap& eventData)
+{
+    Node* node = (Node*) (eventData[EditorActiveNodeChange::P_NODE].GetPtr());
+    SelectNode(node);
+}
+
+
+
+}

+ 17 - 15
Source/AtomicEditor/Source/Editors/SceneResourceEditor.h → Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneEditor3D.h

@@ -5,7 +5,9 @@
 #pragma once
 #pragma once
 
 
 #include <TurboBadger/tb_widgets_common.h>
 #include <TurboBadger/tb_widgets_common.h>
-#include "ResourceEditor.h"
+
+#include "../ResourceEditor.h"
+#include "SceneView3D.h"
 
 
 using namespace Atomic;
 using namespace Atomic;
 using namespace tb;
 using namespace tb;
@@ -18,44 +20,44 @@ class View3D;
 class Camera;
 class Camera;
 class DebugRenderer;
 class DebugRenderer;
 class Octree;
 class Octree;
+
 }
 }
 
 
 namespace AtomicEditor
 namespace AtomicEditor
 {
 {
 
 
-class JSAutocomplete;
-
-class SceneResourceEditor: public ResourceEditor
+class SceneEditor3D: public ResourceEditor
 {
 {
-    OBJECT(SceneResourceEditor);
+    OBJECT(SceneEditor3D);
 
 
 public:
 public:
 
 
-    SceneResourceEditor(Context* context, const String& fullpath, TBTabContainer* container);
+    SceneEditor3D(Context* context, const String& fullpath, TBTabContainer* container);
 
 
-    virtual ~SceneResourceEditor();
+    virtual ~SceneEditor3D();
 
 
     bool OnEvent(const TBWidgetEvent &ev);
     bool OnEvent(const TBWidgetEvent &ev);
 
 
+    void SelectNode(Node* node);
+
+    Scene* GetScene() { return scene_; }
+
 private:
 private:
 
 
     void HandleUpdate(StringHash eventType, VariantMap& eventData);
     void HandleUpdate(StringHash eventType, VariantMap& eventData);
-    void HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData);
-
-    void MoveCamera(float timeStep);
+    void HandleEditorActiveNodeChange(StringHash eventType, VariantMap& eventData);
 
 
     SharedPtr<Scene> scene_;
     SharedPtr<Scene> scene_;
-    SharedPtr<Node> cameraNode_;
-    SharedPtr<View3D> view3D_;
-    SharedPtr<Camera> camera_;
-    float yaw_;
-    float pitch_;
+
+    // TODO: multiple views
+    SharedPtr<SceneView3D> sceneView_;
 
 
     TBLayout* layout_;
     TBLayout* layout_;
     TBContainer* view3DContainer_;
     TBContainer* view3DContainer_;
 
 
     WeakPtr<DebugRenderer> debugRenderer_;
     WeakPtr<DebugRenderer> debugRenderer_;
     WeakPtr<Octree> octree_;
     WeakPtr<Octree> octree_;
+    WeakPtr<Node> selectedNode_;
 
 
 };
 };
 
 

+ 30 - 93
Source/AtomicEditor/Source/Editors/SceneResourceEditor.cpp → Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneView3D.cpp

@@ -12,6 +12,8 @@
 #include <Atomic/Graphics/Viewport.h>
 #include <Atomic/Graphics/Viewport.h>
 #include <Atomic/Graphics/Octree.h>
 #include <Atomic/Graphics/Octree.h>
 
 
+#include <Atomic/Input/Input.h>
+
 #include <Atomic/IO/FileSystem.h>
 #include <Atomic/IO/FileSystem.h>
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/Resource/ResourceCache.h>
 
 
@@ -20,8 +22,8 @@
 #include "AEEditor.h"
 #include "AEEditor.h"
 #include "AEEvents.h"
 #include "AEEvents.h"
 
 
-#include <Atomic/Input/Input.h>
-#include "SceneResourceEditor.h"
+#include "SceneView3D.h"
+#include "SceneEditor3D.h"
 
 
 #include <Atomic/UI/TBUI.h>
 #include <Atomic/UI/TBUI.h>
 #include <Atomic/UI/UI.h>
 #include <Atomic/UI/UI.h>
@@ -30,65 +32,38 @@
 namespace AtomicEditor
 namespace AtomicEditor
 {
 {
 
 
-SceneResourceEditor ::SceneResourceEditor(Context* context, const String &fullpath, TBTabContainer *container) :
-    ResourceEditor(context, fullpath, container),
-    layout_(0),
-    view3DContainer_(0),
+SceneView3D ::SceneView3D(Context* context, SceneEditor3D *sceneEditor) :
+    Object(context),
     yaw_(0.0f),
     yaw_(0.0f),
     pitch_(0.0f)
     pitch_(0.0f)
 {
 {
-    layout_ = new TBLayout();
-    layout_->SetLayoutDistribution(LAYOUT_DISTRIBUTION_GRAVITY);
-    layout_->SetSize(container_->GetRect().w, container_->GetRect().h);
 
 
-    view3DContainer_ = new TBContainer();
-    view3DContainer_->SetGravity(WIDGET_GRAVITY_ALL);
+    sceneEditor_ = sceneEditor;
 
 
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
 
 
-    scene_ = new Scene(context_);
-    SharedPtr<File> xmlFile = cache->GetFile(fullpath);
+    scene_ = sceneEditor->GetScene();
 
 
-    if (GetExtension(fullpath) == ".scene")
-        scene_->LoadXML(*xmlFile);
-    else
-        scene_->Load(*xmlFile);
-
-    scene_->SetUpdateEnabled(false);
+    cameraNode_ = scene_->CreateChild("Camera");
+    camera_ = cameraNode_->CreateComponent<Camera>();
 
 
     debugRenderer_ = scene_->GetComponent<DebugRenderer>();
     debugRenderer_ = scene_->GetComponent<DebugRenderer>();
-
-    if (debugRenderer_.Null())
-    {
-        debugRenderer_ = scene_->CreateComponent<DebugRenderer>();
-    }
-
+    assert(debugRenderer_.NotNull());
     octree_ = scene_->GetComponent<Octree>();
     octree_ = scene_->GetComponent<Octree>();
-
-    if (octree_.Null())
-    {
-        LOGWARNING("Scene without an octree loaded");
-        octree_ = scene_->CreateComponent<Octree>();
-    }
-
-
-    cameraNode_ = scene_->CreateChild("Camera");
-    camera_ = cameraNode_->CreateComponent<Camera>();
+    assert(octree_.NotNull());
 
 
     cameraNode_->SetPosition(Vector3(0, 0, -10));
     cameraNode_->SetPosition(Vector3(0, 0, -10));
 
 
-    layout_->AddChild(view3DContainer_);
-
-    container_->GetContentRoot()->AddChild(layout_);
-
     view3D_ = new View3D(context_);
     view3D_ = new View3D(context_);
     view3D_->SetView(scene_, camera_);
     view3D_->SetView(scene_, camera_);
     view3D_->SetAutoUpdate(false);
     view3D_->SetAutoUpdate(false);
+    view3D_->SetSize(800, 800);
 
 
     GetSubsystem<UI>()->GetRoot()->AddChild(view3D_);
     GetSubsystem<UI>()->GetRoot()->AddChild(view3D_);
 
 
-    SubscribeToEvent(E_UPDATE, HANDLER(SceneResourceEditor, HandleUpdate));
-    SubscribeToEvent(E_POSTRENDERUPDATE, HANDLER(SceneResourceEditor, HandlePostRenderUpdate));
+    SubscribeToEvent(E_UPDATE, HANDLER(SceneView3D, HandleUpdate));
+    SubscribeToEvent(E_EDITORACTIVENODECHANGE, HANDLER(SceneView3D, HandleEditorActiveNodeChange));
+    SubscribeToEvent(E_POSTRENDERUPDATE, HANDLER(SceneView3D, HandlePostRenderUpdate));
 
 
     // TODO: generate this event properly
     // TODO: generate this event properly
     VariantMap eventData;
     VariantMap eventData;
@@ -97,17 +72,12 @@ SceneResourceEditor ::SceneResourceEditor(Context* context, const String &fullpa
 
 
 }
 }
 
 
-SceneResourceEditor::~SceneResourceEditor()
+SceneView3D::~SceneView3D()
 {
 {
     GetSubsystem<UI>()->GetRoot()->RemoveChild(view3D_);
     GetSubsystem<UI>()->GetRoot()->RemoveChild(view3D_);
 }
 }
 
 
-bool SceneResourceEditor::OnEvent(const TBWidgetEvent &ev)
-{
-    return false;
-}
-
-void SceneResourceEditor::MoveCamera(float timeStep)
+void SceneView3D::MoveCamera(float timeStep)
 {
 {
     // Do not move if the UI has a focused element (the console)
     // Do not move if the UI has a focused element (the console)
     if (GetSubsystem<UI>()->GetFocusElement())
     if (GetSubsystem<UI>()->GetFocusElement())
@@ -144,7 +114,7 @@ void SceneResourceEditor::MoveCamera(float timeStep)
         cameraNode_->Translate(Vector3::RIGHT * MOVE_SPEED * timeStep);
         cameraNode_->Translate(Vector3::RIGHT * MOVE_SPEED * timeStep);
 }
 }
 
 
-void SceneResourceEditor::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
+void SceneView3D::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
 {
 {
     if (!view3D_->IsVisible())
     if (!view3D_->IsVisible())
         return;
         return;
@@ -176,61 +146,28 @@ void SceneResourceEditor::HandlePostRenderUpdate(StringHash eventType, VariantMa
 
 
 }
 }
 
 
-void SceneResourceEditor::HandleUpdate(StringHash eventType, VariantMap& eventData)
+void SceneView3D::SelectNode(Node* node)
 {
 {
 
 
-    if ((layout_->GetVisibility() != WIDGET_VISIBILITY_VISIBLE) || GetSubsystem<Editor>()->IsPlayingProject())
-    {
-        if (view3D_->IsVisible())
-            view3D_->SetVisible(false);
-
-        return;
-    }
-
-    if (!view3D_->IsVisible())
-        view3D_->SetVisible(true);
+}
 
 
-    /*
-    Vector3 cpos = cameraNode_->GetPosition();
-    Quaternion crot = cameraNode_->GetRotation();
-    LOGINFOF("%f %f %f - %f %f", cpos.x_, cpos.y_, cpos.z_, pitch_, yaw_);
-    */
+void SceneView3D::HandleUpdate(StringHash eventType, VariantMap& eventData)
+{
 
 
     // Timestep parameter is same no matter what event is being listened to
     // Timestep parameter is same no matter what event is being listened to
     float timeStep = eventData[Update::P_TIMESTEP].GetFloat();
     float timeStep = eventData[Update::P_TIMESTEP].GetFloat();
 
 
     MoveCamera(timeStep);
     MoveCamera(timeStep);
 
 
-    bool dirty = false;
-
-    TBRect rect = layout_->GetRect();
-    TBWidget* parent = layout_->GetParent();
-    while (parent)
-    {
-        TBRect prect = parent->GetRect();
-        rect.x += prect.x;
-        rect.y += prect.y;
-        parent = parent->GetParent();
-    }
-
-    const IntVector2& pos = view3D_->GetPosition();
-    if (pos.x_ != rect.x || pos.y_ != rect.y)
-        dirty = true;
-
-    const IntVector2& size = view3D_->GetSize();
-
-    if (size.x_ != rect.w || size.y_ != rect.h)
-        dirty = true;
-
-    if (dirty)
-    {
-
-        view3D_->SetPosition(rect.x, rect.y);
-        view3D_->SetSize(rect.w, rect.h);
-    }
-
     view3D_->QueueUpdate();
     view3D_->QueueUpdate();
 }
 }
 
 
+void SceneView3D::HandleEditorActiveNodeChange(StringHash eventType, VariantMap& eventData)
+{
+    Node* node = (Node*) (eventData[EditorActiveNodeChange::P_NODE].GetPtr());
+    SelectNode(node);
+}
+
+
 
 
 }
 }

+ 64 - 0
Source/AtomicEditor/Source/Editors/SceneEditor3D/SceneView3D.h

@@ -0,0 +1,64 @@
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// Please see LICENSE.md in repository root for license information
+// https://github.com/AtomicGameEngine/AtomicGameEngine
+
+#pragma once
+
+#include <Atomic/Core/Object.h>
+
+using namespace Atomic;
+
+namespace Atomic
+{
+class Scene;
+class Node;
+class View3D;
+class Camera;
+class DebugRenderer;
+class Octree;
+}
+
+namespace AtomicEditor
+{
+
+class SceneEditor3D;
+
+class SceneView3D: public Object
+{
+    OBJECT(SceneView3D);
+
+public:
+
+    SceneView3D(Context* context, SceneEditor3D* sceneEditor);
+
+    virtual ~SceneView3D();
+
+    void SelectNode(Node* node);
+
+private:
+
+    void HandleUpdate(StringHash eventType, VariantMap& eventData);
+    void HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData);
+    void HandleEditorActiveNodeChange(StringHash eventType, VariantMap& eventData);
+
+    void MoveCamera(float timeStep);
+
+    WeakPtr<SceneEditor3D> sceneEditor_;
+    WeakPtr<Scene> scene_;
+
+    // Camera
+    WeakPtr<Node> cameraNode_;
+    WeakPtr<Camera> camera_;
+
+    float yaw_;
+    float pitch_;
+
+    SharedPtr<View3D> view3D_;
+
+    WeakPtr<DebugRenderer> debugRenderer_;
+    WeakPtr<Octree> octree_;
+    WeakPtr<Node> selectedNode_;
+
+};
+
+}

+ 92 - 4
Source/AtomicEditor/Source/UI/UIInspectorDataBinding.cpp

@@ -1,5 +1,6 @@
 
 
 #include <TurboBadger/tb_widgets_common.h>
 #include <TurboBadger/tb_widgets_common.h>
+#include <TurboBadger/tb_menu_window.h>
 #include <TurboBadger/tb_inline_select.h>
 #include <TurboBadger/tb_inline_select.h>
 
 
 #include "AtomicEditor.h"
 #include "AtomicEditor.h"
@@ -25,9 +26,52 @@ void InspectorDataBinding::SetObjectValueFromWidget(TBWidget *srcWidget)
         TBCheckBox* box = (TBCheckBox *) widget_;
         TBCheckBox* box = (TBCheckBox *) widget_;
         Variant v(box->GetValue() ? true : false);
         Variant v(box->GetValue() ? true : false);
         object_->SetAttribute(attrInfo_->name_, v);
         object_->SetAttribute(attrInfo_->name_, v);
+    }
+    else if (type == VAR_INT)
+    {
+        TBEditField* field = (TBEditField*) widget_;
+        Variant v(ToInt(field->GetText().CStr()));
+        object_->SetAttribute(attrInfo_->name_, v);
+    }
+    else if (type == VAR_FLOAT)
+    {
+        TBEditField* field = (TBEditField*) widget_;
+        Variant v(ToFloat(field->GetText().CStr()));
+        object_->SetAttribute(attrInfo_->name_, v);
+    }
+    else if (type == VAR_STRING)
+    {
+        TBEditField* field = (TBEditField*) widget_;
+        Variant v(String(field->GetText().CStr()));
+        object_->SetAttribute(attrInfo_->name_, v);
+    }
+    else if (type == VAR_COLOR && srcWidget)
+    {
+        Color value = object_->GetAttribute(attrInfo_->name_).GetColor();
+
+        TBInlineSelect* select = NULL;
+        if (srcWidget->GetID() == TBID(unsigned(1)))
+        {
+            select = (TBInlineSelect*) srcWidget;
+            value.r_ = (float ) select->GetValueDouble();
+        }
+        else if (srcWidget->GetID() == TBID(unsigned(2)))
+        {
+            select = (TBInlineSelect*) srcWidget;
+            value.g_ = (float ) select->GetValueDouble();
+        }
+        else if (srcWidget->GetID() == TBID(unsigned(3)))
+        {
+            select = (TBInlineSelect*) srcWidget;
+            value.b_ = (float ) select->GetValueDouble();
+        }
+        else if (srcWidget->GetID() == TBID(unsigned(4)))
+        {
+            select = (TBInlineSelect*) srcWidget;
+            value.a_ = (float ) select->GetValueDouble();
+        }
 
 
-        // refresh widget
-        SetWidgetValueFromObject();
+        object_->SetAttribute(attrInfo_->name_, value);
     }
     }
     else if (type == VAR_VECTOR3 && srcWidget)
     else if (type == VAR_VECTOR3 && srcWidget)
     {
     {
@@ -60,6 +104,8 @@ void InspectorDataBinding::SetObjectValueFromWidget(TBWidget *srcWidget)
         object_->SetAttribute(attrInfo_->name_, q);
         object_->SetAttribute(attrInfo_->name_, q);
     }
     }
 
 
+    // refresh widget
+    //SetWidgetValueFromObject();
 
 
     objectLocked_ = false;
     objectLocked_ = false;
 
 
@@ -76,7 +122,7 @@ void InspectorDataBinding::SetWidgetValueFromObject()
     {
     {
         bool value = object_->GetAttribute(attrInfo_->name_).GetBool();
         bool value = object_->GetAttribute(attrInfo_->name_).GetBool();
         widget_->SetValue(value ? 1 : 0);
         widget_->SetValue(value ? 1 : 0);
-    }
+            }
     else if (attrInfo_->type_ == VAR_VECTOR3)
     else if (attrInfo_->type_ == VAR_VECTOR3)
     {
     {
         Vector3 value = object_->GetAttribute(attrInfo_->name_).GetVector3();
         Vector3 value = object_->GetAttribute(attrInfo_->name_).GetVector3();
@@ -129,6 +175,25 @@ void InspectorDataBinding::SetWidgetValueFromObject()
         }
         }
 
 
     }
     }
+    else if (attrInfo_->type_ == VAR_COLOR)
+    {
+        Color value = object_->GetAttribute(attrInfo_->name_).GetColor();
+
+        TBInlineSelect* select = widget_->GetWidgetByIDAndType<TBInlineSelect>(TBID(unsigned(1)));
+        if (select)
+            select->SetValue(value.r_);
+        select = widget_->GetWidgetByIDAndType<TBInlineSelect>(TBID(unsigned(2)));
+        if (select)
+            select->SetValue(value.g_);
+        select = widget_->GetWidgetByIDAndType<TBInlineSelect>(TBID(unsigned(3)));
+        if (select)
+            select->SetValue(value.b_);
+        select = widget_->GetWidgetByIDAndType<TBInlineSelect>(TBID(unsigned(4)));
+        if (select)
+            select->SetValue(value.a_);
+
+    }
+
 
 
     widgetLocked_ = false;
     widgetLocked_ = false;
 
 
@@ -141,7 +206,30 @@ bool InspectorDataBinding::OnEvent(const TBWidgetEvent &ev)
         if (objectLocked_)
         if (objectLocked_)
             return false;
             return false;
 
 
-        if (widget_ == ev.target || widget_->IsAncestorOf(ev.target))
+        String id = attrInfo_->name_;
+        id += " enum popup";
+
+        if (ev.target->GetID() == TBIDC(id.CString()))
+        {
+            Variant value(int(ev.ref_id-1));
+            object_->SetAttribute(attrInfo_->name_, value);
+            SetWidgetValueFromObject();
+        }
+        else if (widget_ == ev.target && attrInfo_->enumNames_)
+        {
+            TBMenuWindow *menu = new TBMenuWindow(ev.target, TBIDC(id.CString()));
+            TBGenericStringItemSource* source = menu->GetList()->GetDefaultSource();
+            const char** enumPtr = attrInfo_->enumNames_;
+            unsigned v = 1;
+            while (*enumPtr)
+            {
+                source->AddItem(new TBGenericStringItem(*enumPtr, TBID(v++)));
+                enumPtr++;
+            }
+            menu->Show(source, TBPopupAlignment());
+
+        }
+        else if (widget_ == ev.target || widget_->IsAncestorOf(ev.target))
         {
         {
             SetObjectValueFromWidget(ev.target);
             SetObjectValueFromWidget(ev.target);
         }
         }

+ 0 - 380
Source/AtomicEditor/Source/UI/UIInspectorFrame.cpp

@@ -50,351 +50,14 @@ InspectorFrame::~InspectorFrame()
 
 
 }
 }
 
 
-/*
-TBLayout* InspectorFrame::CreateComponentLayout(Component* component)
-{
-    TBLayout* componentLayout = new TBLayout(AXIS_Y);
-    componentLayout->SetLayoutPosition(LAYOUT_POSITION_LEFT_TOP);
-
-    TBFontDescription fd;
-    fd.SetID(TBIDC("Vera"));
-    fd.SetSize(11);
-
-    TBTextField* name = new TBTextField();
-    name->SetFontDescription(fd);
-    name->SetText(component->GetTypeName().CString());
-    componentLayout->AddChild(name);
-
-    const Vector<AttributeInfo>* attr = component->GetAttributes();
-
-    if (attr)
-    {
-        for (unsigned i = 0; i < attr->Size(); i++)
-        {
-            TBLayout* attrLayout = new TBLayout();
-            attrLayout->SetLayoutDistribution(LAYOUT_DISTRIBUTION_GRAVITY);
-
-            const AttributeInfo& info = attr->At(i);
-            TBTextField* attrName = new TBTextField();
-            attrName->SetFontDescription(fd);
-
-            String name = info.name_;
-            if (name == "Is Enabled")
-                name = "Enabled";
-
-            attrName->SetText(name.CString());
-
-            attrLayout->AddChild(attrName);
-
-            TBWidget* widget = NULL;
-
-            if (info.enumNames_)
-            {
-                TBButton* button = new TBButton();
-                widget = button;
-                int value = component->GetAttribute(i).GetInt();
-                button->SetText(info.enumNames_[value]);
-            }
-
-            if (info.type_ == VAR_BOOL)
-            {
-                TBCheckBox* box = new TBCheckBox();
-                widget = box;
-                box->SetValue(component->GetAttribute(i).GetBool() ? 1 : 0);
-            }
-
-            if (info.type_ == VAR_FLOAT)
-            {
-                TBEditField* editField = new TBEditField();
-                editField->SetFontDescription(fd);
-                widget = editField;
-                editField->SetEditType(EDIT_TYPE_NUMBER);
-                editField->SetText(ToString("%f", component->GetAttribute(i).GetFloat()).CString());
-            }
-
-            if (info.type_ == VAR_COLOR)
-            {
-                TBLayout* colorLayout = new TBLayout();
-
-                LayoutParams lp;
-                lp.SetWidth(32);
-
-                TBEditField* red = new TBEditField();
-                TBEditField* green = new TBEditField();
-                TBEditField* blue = new TBEditField();
-                TBEditField* alpha = new TBEditField();
-
-                red->SetEditType(EDIT_TYPE_NUMBER);
-                green->SetEditType(EDIT_TYPE_NUMBER);
-                blue->SetEditType(EDIT_TYPE_NUMBER);
-                alpha->SetEditType(EDIT_TYPE_NUMBER);
-
-                red->SetLayoutParams(lp);
-                green->SetLayoutParams(lp);
-                blue->SetLayoutParams(lp);
-                alpha->SetLayoutParams(lp);
-
-                red->SetFontDescription(fd);
-                green->SetFontDescription(fd);
-                blue->SetFontDescription(fd);
-                alpha->SetFontDescription(fd);
-
-                Color color = component->GetAttribute(i).GetColor();
-
-                red->SetText(ToString("%f", color.r_).CString());
-                green->SetText(ToString("%f", color.g_).CString());
-                blue->SetText(ToString("%f", color.b_).CString());
-                alpha->SetText(ToString("%f", color.a_).CString());
-
-                colorLayout->AddChild(red);
-                colorLayout->AddChild(green);
-                colorLayout->AddChild(blue);
-                colorLayout->AddChild(alpha);
-
-                widget = colorLayout;
-
-            }
-
-            if (widget)
-            {
-
-                attrLayout->AddChild(widget);
-
-                DataBinding binding;
-                binding.widget = widget;
-                binding.component = component;
-                binding.attrIndex = i;
-                dataBindings_.Push(binding);
-            }
-
-            componentLayout->AddChild(attrLayout);
-        }
-    }
-
-    return componentLayout;
-}
-
-*/
-
 bool InspectorFrame::OnEvent(const TBWidgetEvent &ev)
 bool InspectorFrame::OnEvent(const TBWidgetEvent &ev)
 {
 {
     for (unsigned i = 0; i < dataBindings_.Size(); i++)
     for (unsigned i = 0; i < dataBindings_.Size(); i++)
         dataBindings_[i]->OnEvent(ev);
         dataBindings_[i]->OnEvent(ev);
 
 
-    /*
-    if (ev.type == EVENT_TYPE_KEY_DOWN)
-    {
-        for (unsigned i = 0; i < dataBindings_.Size(); i++)
-        {
-            const DataBinding& binding = dataBindings_[i];
-
-            if (binding.widget == ev.target || binding.widget->IsAncestorOf(ev.target))
-            {
-                const AttributeInfo& info = binding.component->GetAttributes()->At(binding.attrIndex);
-                return true;
-            }
-        }
-    }
-
-    if (ev.type == EVENT_TYPE_CHANGED)
-    {
-        if (refreshing_)
-            return true;
-
-        for (unsigned i = 0; i < dataBindings_.Size(); i++)
-        {
-            const DataBinding& binding = dataBindings_[i];
-
-            if (binding.widget == ev.target || binding.widget->IsAncestorOf(ev.target))
-            {
-                const AttributeInfo& info = binding.component->GetAttributes()->At(binding.attrIndex);
-
-                if (info.type_ == VAR_FLOAT)
-                {
-                    TBEditField* edit = (TBEditField*) ev.target;
-                    float v = ToFloat(edit->GetText());
-                    binding.component->SetAttribute(binding.attrIndex, Variant(v));
-
-                }
-                else if (info.type_ == VAR_COLOR)
-                {
-                    Color c = binding.component->GetAttribute(binding.attrIndex).GetColor();
-
-                    if (ev.target == binding.widget->GetChildFromIndex(0))
-                    {
-                        TBEditField* red = (TBEditField*) ev.target;
-                        c.r_ = ToFloat(red->GetText());
-                    }
-                    else if (ev.target == binding.widget->GetChildFromIndex(1))
-                    {
-                        TBEditField* green = (TBEditField*) ev.target;
-                        c.g_ = ToFloat(green->GetText());
-                    }
-                    else if (ev.target == binding.widget->GetChildFromIndex(2))
-                    {
-                        TBEditField* blue = (TBEditField*) ev.target;
-                        c.b_ = ToFloat(blue->GetText());
-                    }
-
-                    binding.component->SetAttribute(binding.attrIndex, Variant(c));
-
-                }
-
-                return true;
-
-            }
-        }
-
-        return true;
-    }
-
-    if (ev.type == EVENT_TYPE_CLICK)
-    {
-        if (ev.target->GetID() == TBIDC("enum popup"))
-        {
-            int value = (int) (ev.ref_id & 0xFFFF);
-            int bindingIdx = (int) (ev.ref_id >> 16);
-
-            const DataBinding& binding = dataBindings_[bindingIdx];
-            Variant v(value);
-            binding.component->SetAttribute(binding.attrIndex, v);
-            const AttributeInfo& info = binding.component->GetAttributes()->At(binding.attrIndex);
-            binding.widget->SetText(info.enumNames_[value]);
-
-        }
-        else
-        {
-            for (unsigned i = 0; i < dataBindings_.Size(); i++)
-            {
-                const DataBinding& binding = dataBindings_[i];
-
-                if (binding.widget == ev.target)
-                {
-                    const AttributeInfo& info = binding.component->GetAttributes()->At(binding.attrIndex);
-
-                    if (info.type_ == VAR_BOOL)
-                    {
-                        TBCheckBox* box = (TBCheckBox *) binding.widget;
-                        Variant v(box->GetValue() ? true : false);
-                        binding.component->SetAttribute(binding.attrIndex, v);
-                    }
-                    else if (info.enumNames_)
-                    {
-                        TBMenuWindow *menu = new TBMenuWindow(ev.target, TBIDC("enum popup"));
-                        TBGenericStringItemSource* source = menu->GetList()->GetDefaultSource();
-                        const char** enumPtr = info.enumNames_;
-                        unsigned v = i << 16;
-                        while (*enumPtr)
-                        {
-                            source->AddItem(new TBGenericStringItem(*enumPtr, TBID(v++)));
-                            enumPtr++;
-                        }
-                        menu->Show(source, TBPopupAlignment());
-
-                    }
-
-                }
-            }
-        }
-
-    }
-    */
-
     return false;
     return false;
 }
 }
 
 
-/*
-void InspectorFrame::CreateTransformLayout()
-{
-    // transform
-
-    TBFontDescription fd;
-    fd.SetID(TBIDC("Vera"));
-    fd.SetSize(11);
-
-    transformLayout_ = new TBLayout(AXIS_Y);
-    transformLayout_->SetLayoutPosition(LAYOUT_POSITION_LEFT_TOP);
-
-    // POSITION
-    TBTextField* posText = new TBTextField();
-    posText->SetText("Position");
-    posText->SetFontDescription(fd);
-    transformLayout_->AddChild(posText);
-
-    TBLayout* positionLayout = new TBLayout();
-    positionLayout->SetSpacing(0);
-
-    posXSelect_ = new TBInlineSelect();
-    posXSelect_->SetFontDescription(fd);
-    posXSelect_->SetLimits(-10000000, 10000000);
-    positionLayout->AddChild(posXSelect_);
-
-    posYSelect_ = new TBInlineSelect();
-    posYSelect_->SetFontDescription(fd);
-    posYSelect_->SetLimits(-10000000, 10000000);
-    positionLayout->AddChild(posYSelect_);
-
-    posZSelect_ = new TBInlineSelect();
-    posZSelect_->SetFontDescription(fd);
-    posZSelect_->SetLimits(-10000000, 10000000);
-    positionLayout->AddChild(posZSelect_);
-
-    transformLayout_->AddChild(positionLayout);
-
-    // ROTATION
-    TBTextField* rotText = new TBTextField();
-    rotText->SetText("Rotation");
-    rotText->SetFontDescription(fd);
-    transformLayout_->AddChild(rotText);
-
-    TBLayout* rotLayout = new TBLayout();
-    rotLayout->SetSpacing(0);
-
-    rotXSelect_ = new TBInlineSelect();
-    rotXSelect_->SetFontDescription(fd);
-    rotXSelect_->SetLimits(-10000000, 10000000);
-    rotLayout->AddChild(rotXSelect_);
-
-    rotYSelect_ = new TBInlineSelect();
-    rotYSelect_->SetFontDescription(fd);
-    rotYSelect_->SetLimits(-10000000, 10000000);
-    rotLayout->AddChild(rotYSelect_);
-
-    rotZSelect_ = new TBInlineSelect();
-    rotZSelect_->SetFontDescription(fd);
-    rotZSelect_->SetLimits(-10000000, 10000000);
-    rotLayout->AddChild(rotZSelect_);
-
-    transformLayout_->AddChild(rotLayout);
-
-    // SCALE
-    TBTextField* scaleText = new TBTextField();
-    scaleText->SetText("Scale");
-    scaleText->SetFontDescription(fd);
-    transformLayout_->AddChild(scaleText);
-
-    TBLayout* scaleLayout = new TBLayout();
-    scaleLayout->SetSpacing(0);
-
-    scaleXSelect_ = new TBInlineSelect();
-    scaleXSelect_->SetFontDescription(fd);
-    scaleXSelect_->SetLimits(-10000000, 10000000);
-    scaleLayout->AddChild(scaleXSelect_);
-
-    scaleYSelect_ = new TBInlineSelect();
-    scaleYSelect_->SetFontDescription(fd);
-    scaleYSelect_->SetLimits(-10000000, 10000000);
-    scaleLayout->AddChild(scaleYSelect_);
-
-    scaleZSelect_ = new TBInlineSelect();
-    scaleZSelect_->SetFontDescription(fd);
-    scaleZSelect_->SetLimits(-10000000, 10000000);
-    scaleLayout->AddChild(scaleZSelect_);
-
-    transformLayout_->AddChild(scaleLayout);
-
-}
-*/
 
 
 void InspectorFrame::InspectNode(Node* node)
 void InspectorFrame::InspectNode(Node* node)
 {
 {
@@ -529,49 +192,6 @@ void InspectorFrame::InspectNode(Node* node)
 
 
         }
         }
 
 
-
-        /*
-
-
-        // enabled and name
-        TBLayout* nameLayout = new TBLayout();
-        TBCheckBox* checkBox = new TBCheckBox();
-        TBEditField* nameField = new TBEditField();
-        String name = node->GetName();
-        if (!name.Length())
-            name = "(Anonymous)";
-
-        nameField->SetText(name.CString());
-        nameField->SetGravity(WIDGET_GRAVITY_LEFT_RIGHT);
-        nameLayout->AddChild(checkBox);
-        nameLayout->AddChild(nameField);
-        nodeLayout->AddChild(nameLayout);
-
-        nodeLayout->AddChild(transformLayout_);
-
-        TBSeparator* sep = new TBSeparator();
-        sep->SetGravity(WIDGET_GRAVITY_LEFT_RIGHT);
-        sep->SetSkinBg("AESeparator");
-        nodeLayout->AddChild(sep);
-
-        const Vector<SharedPtr<Component> > components = node->GetComponents();
-        for (unsigned i = 0; i < components.Size(); i++)
-        {
-            Component* c = components[i];
-            TBLayout* clayout = CreateComponentLayout(c);
-            nodeLayout->AddChild(clayout);
-
-            TBSeparator* sep = new TBSeparator();
-            sep->SetGravity(WIDGET_GRAVITY_LEFT_RIGHT);
-            sep->SetSkinBg("AESeparator");
-            nodeLayout->AddChild(sep);
-        }
-
-
-
-        RefreshTransform();
-        */
-
         inspectorContainer_->AddChild(nodeLayout);
         inspectorContainer_->AddChild(nodeLayout);
 
 
         for (unsigned i = 0; i < dataBindings_.Size(); i++)
         for (unsigned i = 0; i < dataBindings_.Size(); i++)

+ 2 - 2
Source/AtomicEditor/Source/UI/UIResourceFrame.cpp

@@ -16,7 +16,7 @@
 #include "UIResourceFrame.h"
 #include "UIResourceFrame.h"
 
 
 #include "../Editors/JSResourceEditor.h"
 #include "../Editors/JSResourceEditor.h"
-#include "../Editors/SceneResourceEditor.h"
+#include "../Editors/SceneEditor3D/SceneEditor3D.h"
 #include "../Editors/ModelResourceEditor.h"
 #include "../Editors/ModelResourceEditor.h"
 #include "../Editors/TextResourceEditor.h"
 #include "../Editors/TextResourceEditor.h"
 #include "../AEEvents.h"
 #include "../AEEvents.h"
@@ -120,7 +120,7 @@ void ResourceFrame::EditResource(const String& fullpath)
     }
     }
     else if (ext == ".scene")
     else if (ext == ".scene")
     {
     {
-        SceneResourceEditor* sre = new SceneResourceEditor(context_, fullpath, tabcontainer_);
+        SceneEditor3D* sre = new SceneEditor3D(context_, fullpath, tabcontainer_);
         editor = sre;
         editor = sre;
     }
     }
     else if (ext == ".xml" || ext == ".txt")
     else if (ext == ".xml" || ext == ".txt")