From ca8392d8192bfa4d944a0abb599b5b856a15844c Mon Sep 17 00:00:00 2001
From: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com>
Date: Tue, 29 Apr 2025 09:19:11 -0500
Subject: [PATCH] Made Inspector Better, and fixed Load/Craete Scene

---
 imgui.ini                            |  32 ++++----
 remake/build.log                     |   1 -
 src/assets/scenes/Smoke.cene         | 110 ++++++++++++++++++++++++++
 src/assets/scenes/test.cene          |  74 +++++++++---------
 src/src/Engine.cpp                   |   2 +-
 src/src/core/types/color.h           |  13 ++++
 src/src/core/types/vec3.h            | 112 +++++++++++++++++++--------
 src/src/core/utils/FileDialog.cpp    |  60 ++++++++++++--
 src/src/core/utils/FileDialog.h      |   2 +
 src/src/editor/windows/Inspector.cpp |  15 +++-
 10 files changed, 325 insertions(+), 96 deletions(-)
 create mode 100644 src/assets/scenes/Smoke.cene

diff --git a/imgui.ini b/imgui.ini
index 1ce1346..a935e8a 100644
--- a/imgui.ini
+++ b/imgui.ini
@@ -10,24 +10,24 @@ Collapsed=1
 
 [Window][WindowOverViewport_11111111]
 Pos=0,19
-Size=1920,1158
+Size=1280,701
 Collapsed=0
 
 [Window][Inspector]
-Pos=1402,19
-Size=518,1158
+Pos=762,19
+Size=518,701
 Collapsed=0
 DockId=0x00000006,0
 
 [Window][Scene Tree]
 Pos=0,19
-Size=342,575
+Size=342,348
 Collapsed=0
 DockId=0x00000003,0
 
 [Window][Viewport]
 Pos=344,19
-Size=1056,847
+Size=416,390
 Collapsed=0
 DockId=0x00000007,0
 
@@ -36,14 +36,14 @@ Size=1280,19
 Collapsed=0
 
 [Window][Performance Info]
-Pos=344,868
-Size=1056,309
+Pos=344,411
+Size=416,309
 Collapsed=0
 DockId=0x00000008,2
 
 [Window][Console]
-Pos=344,868
-Size=1056,309
+Pos=344,411
+Size=416,309
 Collapsed=0
 DockId=0x00000008,0
 
@@ -54,8 +54,8 @@ Collapsed=0
 DockId=0x00000007,1
 
 [Window][Profiler]
-Pos=344,868
-Size=1056,309
+Pos=344,411
+Size=416,309
 Collapsed=0
 DockId=0x00000008,3
 
@@ -78,14 +78,14 @@ Collapsed=0
 DockId=0x00000008,1
 
 [Window][Color Correction]
-Pos=344,868
-Size=1056,309
+Pos=344,411
+Size=416,309
 Collapsed=0
 DockId=0x00000008,1
 
 [Window][Asset Browser]
-Pos=0,596
-Size=342,581
+Pos=0,369
+Size=342,351
 Collapsed=0
 DockId=0x00000004,0
 
@@ -95,7 +95,7 @@ Size=325,75
 Collapsed=0
 
 [Docking][Data]
-DockSpace       ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1920,1158 Split=X
+DockSpace       ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
   DockNode      ID=0x00000005 Parent=0x11111111 SizeRef=1400,1158 Split=X
     DockNode    ID=0x00000001 Parent=0x00000005 SizeRef=342,701 Split=Y Selected=0x12EF0F59
       DockNode  ID=0x00000003 Parent=0x00000001 SizeRef=342,575 HiddenTabBar=1 Selected=0x12EF0F59
diff --git a/remake/build.log b/remake/build.log
index a79bae6..de46732 100644
--- a/remake/build.log
+++ b/remake/build.log
@@ -1,2 +1 @@
 [LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\ParticleComponent.o src\build\Components\PhysicsComponent.o src\build\Components\ScriptComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\core\utils\AssetManager.o src\build\core\utils\EngineConfig.o src\build\core\utils\ExceptionHandler.o src\build\core\utils\FileDialog.o src\build\core\utils\input.o src\build\core\utils\LoadingWindow.o src\build\core\utils\Logging.o src\build\core\utils\Profiler.o src\build\core\utils\Texture.o src\build\core\utils\utils.o src\build\editor\windows\AssetBrowser.o src\build\editor\windows\Inspector.o src\build\Entitys\Object.o src\build\utils\GameObjectsList.o src\build\utils\Shader.o src\build\utils\UID.o src\build\lapi.o src\build\lauxlib.o src\build\lbaselib.o src\build\lcode.o src\build\lcorolib.o src\build\lctype.o src\build\ldblib.o src\build\ldebug.o src\build\ldo.o src\build\ldump.o src\build\lfunc.o src\build\lgc.o src\build\linit.o src\build\liolib.o src\build\llex.o src\build\lmathlib.o src\build\lmem.o src\build\loadlib.o src\build\lobject.o src\build\lopcodes.o src\build\loslib.o src\build\lparser.o src\build\lstate.o src\build\lstring.o src\build\lstrlib.o src\build\ltable.o src\build\ltablib.o src\build\ltm.o src\build\lua.o src\build\luac.o src\build\lundump.o src\build\lutf8lib.o src\build\lvm.o src\build\lzio.o src\build\imgui.o src\build\imgui_demo.o src\build\imgui_draw.o src\build\imgui_impl_glfw.o src\build\imgui_impl_opengl3.o src\build\imgui_tables.o src\build\imgui_widgets.o src\build\aabb.o src\build\arena_allocator.o src\build\array.o src\build\bitset.o src\build\body.o src\build\broad_phase.o src\build\constraint_graph.o src\build\contact.o src\build\contact_solver.o src\build\core.o src\build\distance.o src\build\distance_joint.o src\build\dynamic_tree.o src\build\geometry.o src\build\hull.o src\build\id_pool.o src\build\island.o src\build\joint.o src\build\manifold.o src\build\math_functions.o src\build\motor_joint.o src\build\mouse_joint.o src\build\mover.o src\build\prismatic_joint.o src\build\revolute_joint.o src\build\sensor.o src\build\shape.o src\build\solver.o src\build\solver_set.o src\build\table.o src\build\timer.o src\build\types.o src\build\weld_joint.o src\build\wheel_joint.o src\build\world.o src\build\xxhash.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto
-[RUN] Executed app.exe successfully.
diff --git a/src/assets/scenes/Smoke.cene b/src/assets/scenes/Smoke.cene
new file mode 100644
index 0000000..eb976d0
--- /dev/null
+++ b/src/assets/scenes/Smoke.cene
@@ -0,0 +1,110 @@
+engine_version: 0.1.0
+scene_name: Smoke
+scene_hash: bb44d49b100c99a58dbbebf7385e4813ce7d55b8aa64a8e00f2fb9949af8306e
+format_version: 1
+objects:
+  - name: Smoke and Light
+    uid: dc6b14507c5f4cd6be29402f26a43bed
+    id: 3
+    position: [53, -28]
+    rotation: 0
+    layer: 0
+    visable: true
+    components:
+      - type: ParticleComponent
+        maxParticles: 10000
+        emissionRate: 10000
+        lifeMin: 0.00999999978
+        lifeMax: 0.800000012
+        sizeMin: 10
+        sizeMax: 100
+        speedMin: 100
+        speedMax: 300
+        direction: [0, 0]
+        spread: 6.27445841
+        startColor: [1, 0, 1, 0.149019614]
+        endColor: [0.588235378, 0, 1, 0]
+        loop: true
+        burst: false
+        roundness: 0
+      - type: LightComponent
+        color:
+          - 1
+          - 0
+          - 1
+        intensity: 1
+        radius: 300
+        falloff: 1
+        type: 0
+    children: []
+  - name: Backround
+    uid: d395b3d1c59140298babbce87efbabc9
+    id: 4
+    position: [1028, 0]
+    rotation: 0
+    layer: 0
+    visable: true
+    components:
+      - type: SpriteComponent
+        texture: 4
+        normalMap: 5
+        renderType: Lit
+    children: []
+color_correction:
+  brightness: 1
+  saturation: 1
+  gamma: 1
+  bloom: false
+  intensity: 1.99000001
+  threshold: 0.219999999
+Assets:
+  - uaid: 5
+    path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_nor_gl_1k.png
+    filename: ganges_river_pebbles_nor_gl_1k.png
+    filetype: png
+    type: 0
+    size: [1024, 1024]
+    hash: 6711b00700d4c94a
+    channels: 4
+    format: GL_RGBA
+    lastModified: 1744565594
+  - uaid: 4
+    path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png
+    filename: ganges_river_pebbles_diff_1k.png
+    filetype: png
+    type: 0
+    size: [1024, 1024]
+    hash: 0349580fcbf62155
+    channels: 4
+    format: GL_RGBA
+    lastModified: 1744565605
+  - uaid: 3
+    path: C:\Users\spenc\OneDrive\Pictures\Pixel Holy Spell Effect 32x32 Pack 3\01.png
+    filename: 01.png
+    filetype: png
+    type: 0
+    size: [704, 576]
+    hash: 82866fcf3324b785
+    channels: 4
+    format: GL_RGBA
+    lastModified: 1687052108
+  - uaid: 2
+    path: C:\Users\spenc\OneDrive\Pictures\Pixel Holy Spell Effect 32x32 Pack 3\00.png
+    filename: 00.png
+    filetype: png
+    type: 0
+    size: [1216, 192]
+    hash: 2b0b3c20179d6f12
+    channels: 4
+    format: GL_RGBA
+    lastModified: 1687052065
+  - uaid: 1
+    path: C:\Users\spenc\OneDrive\Pictures\6656e7221e49a1774d2fb280357e56f8d25d9d95.png
+    filename: 6656e7221e49a1774d2fb280357e56f8d25d9d95.png
+    filetype: png
+    type: 0
+    size: [1024, 1024]
+    hash: e8aaee6025f21557
+    channels: 4
+    format: GL_RGBA
+    lastModified: 1744577923
\ No newline at end of file
diff --git a/src/assets/scenes/test.cene b/src/assets/scenes/test.cene
index 008776d..0563ffe 100644
--- a/src/assets/scenes/test.cene
+++ b/src/assets/scenes/test.cene
@@ -1,12 +1,12 @@
 engine_version: 0.1.0
 scene_name: test
-scene_hash: 2a85407931385c3ec75b04912f97447151603fb317700b3a5b33a0c86182db25
+scene_hash: 5176ce6547df4e17907193d5cfbbb474091eefafd718c7920a34526eaa69172f
 format_version: 1
 objects:
   - name: NewObject
     uid: dc6b14507c5f4cd6be29402f26a43bed
     id: 3
-    position: [48.2000008, -72]
+    position: [158, -28]
     rotation: 0
     layer: 0
     visable: true
@@ -16,14 +16,14 @@ objects:
         emissionRate: 10000
         lifeMin: 0.00999999978
         lifeMax: 0.800000012
-        sizeMin: 5
-        sizeMax: 10
+        sizeMin: 10
+        sizeMax: 100
         speedMin: 100
         speedMax: 300
         direction: [0, 0]
-        spread: 6.28318548
-        startColor: [0.0588235296, 0, 1, 1]
-        endColor: [1, 0, 0.911765099, 0]
+        spread: 6.27445841
+        startColor: [1, 0, 1, 0.149019614]
+        endColor: [0.588235378, 0, 1, 0]
         loop: true
         burst: false
         roundness: 0
@@ -31,7 +31,7 @@ objects:
         color:
           - 1
           - 0
-          - 0.941176414
+          - 1
         intensity: 1
         radius: 300
         falloff: 1
@@ -54,30 +54,30 @@ color_correction:
   brightness: 1
   saturation: 1
   gamma: 1
-  bloom: true
-  intensity: 1.20000005
-  threshold: 0.170000002
+  bloom: false
+  intensity: 1.99000001
+  threshold: 0.219999999
 Assets:
-  - uaid: 5
-    path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_nor_gl_1k.png
-    filename: ganges_river_pebbles_nor_gl_1k.png
+  - uaid: 1
+    path: C:\Users\spenc\OneDrive\Pictures\6656e7221e49a1774d2fb280357e56f8d25d9d95.png
+    filename: 6656e7221e49a1774d2fb280357e56f8d25d9d95.png
     filetype: png
     type: 0
     size: [1024, 1024]
-    hash: 6711b00700d4c94a
+    hash: e8aaee6025f21557
     channels: 4
     format: GL_RGBA
-    lastModified: 1744565594
-  - uaid: 4
-    path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png
-    filename: ganges_river_pebbles_diff_1k.png
+    lastModified: 1744577924
+  - uaid: 2
+    path: C:\Users\spenc\OneDrive\Pictures\Pixel Holy Spell Effect 32x32 Pack 3\00.png
+    filename: 00.png
     filetype: png
     type: 0
-    size: [1024, 1024]
-    hash: 0349580fcbf62155
+    size: [1216, 192]
+    hash: 2b0b3c20179d6f12
     channels: 4
     format: GL_RGBA
-    lastModified: 1744565605
+    lastModified: 1687052064
   - uaid: 3
     path: C:\Users\spenc\OneDrive\Pictures\Pixel Holy Spell Effect 32x32 Pack 3\01.png
     filename: 01.png
@@ -88,23 +88,23 @@ Assets:
     channels: 4
     format: GL_RGBA
     lastModified: 1687052107
-  - uaid: 2
-    path: C:\Users\spenc\OneDrive\Pictures\Pixel Holy Spell Effect 32x32 Pack 3\00.png
-    filename: 00.png
-    filetype: png
-    type: 0
-    size: [1216, 192]
-    hash: 2b0b3c20179d6f12
-    channels: 4
-    format: GL_RGBA
-    lastModified: 1687052065
-  - uaid: 1
-    path: C:\Users\spenc\OneDrive\Pictures\6656e7221e49a1774d2fb280357e56f8d25d9d95.png
-    filename: 6656e7221e49a1774d2fb280357e56f8d25d9d95.png
+  - uaid: 4
+    path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png
+    filename: ganges_river_pebbles_diff_1k.png
     filetype: png
     type: 0
     size: [1024, 1024]
-    hash: e8aaee6025f21557
+    hash: 0349580fcbf62155
     channels: 4
     format: GL_RGBA
-    lastModified: 1744577923
\ No newline at end of file
+    lastModified: 1744565605
+  - uaid: 5
+    path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_nor_gl_1k.png
+    filename: ganges_river_pebbles_nor_gl_1k.png
+    filetype: png
+    type: 0
+    size: [1024, 1024]
+    hash: 6711b00700d4c94a
+    channels: 4
+    format: GL_RGBA
+    lastModified: 1744565594
\ No newline at end of file
diff --git a/src/src/Engine.cpp b/src/src/Engine.cpp
index cac6744..73f874a 100644
--- a/src/src/Engine.cpp
+++ b/src/src/Engine.cpp
@@ -666,7 +666,7 @@ void Engine::Run()
             {
                 if (ImGui::MenuItem("Save Scene"))
                 {
-                    std::string file = OpenFileDialog(FileDialogType::Scenes);
+                    std::string file = CreateFileDialog(FileDialogType::Scenes);
                     if (!file.empty())
                         SaveScene(file);
                     selected = nullptr;
diff --git a/src/src/core/types/color.h b/src/src/core/types/color.h
index 283fe91..b52388e 100644
--- a/src/src/core/types/color.h
+++ b/src/src/core/types/color.h
@@ -1,5 +1,7 @@
 #pragma once
 #include <algorithm>
+#include <glm/glm.hpp>
+#include <imgui.h>
 
 namespace core
 {
@@ -14,6 +16,17 @@ namespace core
       Color(float _r, float _g, float _b, float _a = 1.0f)
           : r(_r), g(_g), b(_b), a(_a) {}
 
+      // Conversions
+      Color(const glm::vec3 &v, float _a = 1.0f)
+          : r(v.x), g(v.y), b(v.z), a(_a) {}
+
+      Color(const ImVec4 &v)
+          : r(v.x), g(v.y), b(v.z), a(v.w) {}
+
+      operator glm::vec3() const { return {r, g, b}; }
+      operator glm::vec4() const { return {r, g, b, a}; }
+      operator ImVec4() const { return {r, g, b, a}; }
+
       // Add
       Color operator+(const Color &other) const
       {
diff --git a/src/src/core/types/vec3.h b/src/src/core/types/vec3.h
index f686d5e..bc44fc6 100644
--- a/src/src/core/types/vec3.h
+++ b/src/src/core/types/vec3.h
@@ -1,4 +1,8 @@
 #pragma once
+#include <cmath>
+#include <algorithm>
+#include <ostream>
+#include <glm/glm.hpp>
 
 namespace core
 {
@@ -10,42 +14,84 @@ namespace core
             float x{0}, y{0}, z{0};
 
             Vec3() = default;
-            Vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
+            Vec3(float x, float y, float z) : x(x), y(y), z(z) {}
+            Vec3(float v) : x(v), y(v), z(v) {}
+            Vec3(const glm::vec3 &v) : x(v.x), y(v.y), z(v.z) {}
 
-            Vec3 &operator+=(const Vec3 &o)
+            operator glm::vec3() const { return {x, y, z}; }
+
+            Vec3 operator+(const Vec3 &rhs) const { return {x + rhs.x, y + rhs.y, z + rhs.z}; }
+            Vec3 operator-(const Vec3 &rhs) const { return {x - rhs.x, y - rhs.y, z - rhs.z}; }
+            Vec3 operator*(float scalar) const { return {x * scalar, y * scalar, z * scalar}; }
+            Vec3 operator/(float scalar) const { return {x / scalar, y / scalar, z / scalar}; }
+
+            Vec3 operator*(const Vec3 &rhs) const { return {x * rhs.x, y * rhs.y, z * rhs.z}; }
+
+            Vec3 &operator+=(const Vec3 &rhs) { x += rhs.x; y += rhs.y; z += rhs.z; return *this; }
+            Vec3 &operator-=(const Vec3 &rhs) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; }
+            Vec3 &operator*=(float scalar) { x *= scalar; y *= scalar; z *= scalar; return *this; }
+            Vec3 &operator/=(float scalar) { x /= scalar; y /= scalar; z /= scalar; return *this; }
+
+            Vec3 operator-() const { return {-x, -y, -z}; }
+
+            bool operator==(const Vec3 &rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z; }
+            bool operator!=(const Vec3 &rhs) const { return !(*this == rhs); }
+
+            float Length() const { return std::sqrt(x * x + y * y + z * z); }
+            float LengthSquared() const { return x * x + y * y + z * z; }
+
+            Vec3 Normalized() const
             {
-                x += o.x;
-                y += o.y;
-                z += o.z;
-                return *this;
-            }
-            Vec3 &operator-=(const Vec3 &o)
-            {
-                x -= o.x;
-                y -= o.y;
-                z -= o.z;
-                return *this;
-            }
-            Vec3 &operator*=(float s)
-            {
-                x *= s;
-                y *= s;
-                z *= s;
-                return *this;
-            }
-            Vec3 &operator/=(float s)
-            {
-                x /= s;
-                y /= s;
-                z /= s;
-                return *this;
+                float len = Length();
+                return len != 0 ? *this / len : Vec3(0.0f);
             }
 
-            friend Vec3 operator+(Vec3 a, const Vec3 &b) { return a += b; }
-            friend Vec3 operator-(Vec3 a, const Vec3 &b) { return a -= b; }
-            friend Vec3 operator*(Vec3 v, float s) { return v *= s; }
-            friend Vec3 operator/(Vec3 v, float s) { return v /= s; }
+            void Normalize()
+            {
+                float len = Length();
+                if (len != 0)
+                {
+                    x /= len;
+                    y /= len;
+                    z /= len;
+                }
+            }
+
+            float Dot(const Vec3 &rhs) const { return x * rhs.x + y * rhs.y + z * rhs.z; }
+
+            Vec3 Cross(const Vec3 &rhs) const
+            {
+                return Vec3(
+                    y * rhs.z - z * rhs.y,
+                    z * rhs.x - x * rhs.z,
+                    x * rhs.y - y * rhs.x
+                );
+            }
+
+            void Clamp(const Vec3 &min, const Vec3 &max)
+            {
+                x = std::max(min.x, std::min(x, max.x));
+                y = std::max(min.y, std::min(y, max.y));
+                z = std::max(min.z, std::min(z, max.z));
+            }
+
+            static Vec3 Lerp(const Vec3 &a, const Vec3 &b, float t)
+            {
+                return a + (b - a) * t;
+            }
+
+            static float Distance(const Vec3 &a, const Vec3 &b)
+            {
+                return (a - b).Length();
+            }
+
+            friend std::ostream &operator<<(std::ostream &os, const Vec3 &v)
+            {
+                return os << "(" << v.x << ", " << v.y << ", " << v.z << ")";
+            }
         };
 
-    }
-}
+        inline Vec3 operator*(float scalar, const Vec3 &v) { return v * scalar; }
+
+    } // namespace types
+} // namespace core
diff --git a/src/src/core/utils/FileDialog.cpp b/src/src/core/utils/FileDialog.cpp
index 566fb2c..846e3cf 100644
--- a/src/src/core/utils/FileDialog.cpp
+++ b/src/src/core/utils/FileDialog.cpp
@@ -2,6 +2,7 @@
 #define NOMINMAX
 #include <windows.h>
 #include <commdlg.h>
+#include <fstream>
 #include <unordered_map>
 #include <string>
 #include <filesystem>
@@ -9,17 +10,18 @@
 
 // Correctly null-terminated filter strings
 static std::unordered_map<FileDialogType, const char*> filters = {
-    { FileDialogType::Images,  "Image Files\0*.png;*.jpg;*.jpeg;*.bmp;*.tga;*.gif;*.dds\0" },
-    { FileDialogType::Scenes,  "CreateScene Files\0*.cene;*.cscene;*.yaml\0" },
-    { FileDialogType::Audio,   "Audio Files\0*.mp3;*.wav;*.ogg;*.flac;*.aac\0" },
-    { FileDialogType::Scripts, "Lua Scripts\0*.lua\0" },
-    { FileDialogType::Shaders, "Shader Files\0*.glsl;*.vert;*.frag;*.hlsl\0" },
-    { FileDialogType::Fonts,   "Font Files\0*.ttf;*.otf;*.fnt\0" },
-    { FileDialogType::Models,  "3D Models\0*.obj;*.fbx;*.gltf;*.dae\0" },
+    { FileDialogType::Images,  "Image Files\0*.png;*.jpg;*.jpeg;*.bmp;*.tga;*.gif;*.dds\0All Files\0*.*\0" },
+    { FileDialogType::Scenes,  "CreateScene Files\0*.cene;*.cscene;*.yaml\0All Files\0*.*\0" },
+    { FileDialogType::Audio,   "Audio Files\0*.mp3;*.wav;*.ogg;*.flac;*.aac\0All Files\0*.*\0" },
+    { FileDialogType::Scripts, "Lua Scripts\0*.lua\0All Files\0*.*\0" },
+    { FileDialogType::Shaders, "Shader Files\0*.glsl;*.vert;*.frag;*.hlsl\0All Files\0*.*\0" },
+    { FileDialogType::Fonts,   "Font Files\0*.ttf;*.otf;*.fnt\0All Files\0*.*\0" },
+    { FileDialogType::Models,  "3D Models\0*.obj;*.fbx;*.gltf;*.dae\0All Files\0*.*\0" },
     { FileDialogType::All,     "All Files\0*.*\0" }
 };
 
 
+
 std::string OpenFileDialog(FileDialogType type) {
     char file[260] = { 0 };
     OPENFILENAMEA ofn = {};
@@ -55,3 +57,47 @@ std::string SaveFileDialog(FileDialogType type) {
 
     return result ? std::string(file) : "";
 }
+
+std::string CreateFileDialog(FileDialogType type) {
+    char file[260] = { 0 };
+    OPENFILENAMEA ofn = {};
+    ofn.lStructSize = sizeof(ofn);
+
+    const char* filterStr = filters.count(type) ? filters[type] : filters[FileDialogType::All];
+    ofn.lpstrFilter = filterStr;
+    ofn.lpstrFile = file;
+    ofn.nMaxFile = sizeof(file);
+    ofn.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR;
+
+    
+    const char* defaultExt = nullptr;
+    switch (type) {
+        case FileDialogType::Images:  defaultExt = "png"; break;
+        case FileDialogType::Scenes:  defaultExt = "cene"; break;
+        case FileDialogType::Audio:   defaultExt = "mp3"; break;
+        case FileDialogType::Scripts: defaultExt = "lua"; break;
+        case FileDialogType::Shaders: defaultExt = "glsl"; break;
+        case FileDialogType::Fonts:   defaultExt = "ttf"; break;
+        case FileDialogType::Models:  defaultExt = "obj"; break;
+        default:                      defaultExt = "txt"; break;
+    }
+    ofn.lpstrDefExt = defaultExt;
+
+    auto originalPath = std::filesystem::current_path();
+    bool result = GetSaveFileNameA(&ofn);
+    std::filesystem::current_path(originalPath);
+
+    if (result && file[0] != '\0') {
+        std::filesystem::path filePath(file);
+
+        if (!std::filesystem::exists(filePath)) {
+            std::ofstream outFile(filePath, std::ios::out | std::ios::trunc);
+            outFile.close();
+        }
+
+        return filePath.string();
+    }
+
+    return "";
+}
+
diff --git a/src/src/core/utils/FileDialog.h b/src/src/core/utils/FileDialog.h
index c8e7844..27854cf 100644
--- a/src/src/core/utils/FileDialog.h
+++ b/src/src/core/utils/FileDialog.h
@@ -15,3 +15,5 @@ enum class FileDialogType {
 
 std::string OpenFileDialog(FileDialogType type);
 std::string SaveFileDialog(FileDialogType type);
+std::string CreateFileDialog(FileDialogType type);
+
diff --git a/src/src/editor/windows/Inspector.cpp b/src/src/editor/windows/Inspector.cpp
index dff9d35..9c21a25 100644
--- a/src/src/editor/windows/Inspector.cpp
+++ b/src/src/editor/windows/Inspector.cpp
@@ -380,7 +380,20 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
         ImGui::DragFloat("Size Max", &settings.sizeMax, 0.1f, 0.1f, 100.0f);
         ImGui::DragFloat("Speed Min", &settings.speedMin, 1.0f, 0.0f, 1000.0f);
         ImGui::DragFloat("Speed Max", &settings.speedMax, 1.0f, 0.0f, 1000.0f);
-        ImGui::DragFloat2("Direction", &settings.direction.x, 0.01f);
+
+        {
+            float directionAngleDeg = glm::degrees(std::atan2(settings.direction.y, settings.direction.x));
+
+            if (directionAngleDeg < 0.0f)
+                directionAngleDeg += 360.0f;
+
+            if (ImGui::DragFloat("Direction", &directionAngleDeg, 0.5f, 0.0f, 360.0f))
+            {
+                float rad = glm::radians(directionAngleDeg);
+                settings.direction.x = std::cos(rad);
+                settings.direction.y = std::sin(rad);
+            }
+        }
 
         {
             float spreadDeg = glm::degrees(settings.spread);