From 3aa23acd63c717d05b11e0f735f429d1f75dd155 Mon Sep 17 00:00:00 2001 From: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com> Date: Tue, 6 May 2025 09:07:27 -0500 Subject: [PATCH] Added Lighting to Animation components --- remake.yaml | 4 + remake/build.log | 4 +- src/assets/scenes/drag_n_drop_tests.cene | 1852 ++++++------ src/assets/scenes/isometric_test.cene | 3236 ++++++++++++--------- src/src/Components/AnimationComponent.cpp | 20 +- src/src/Components/AnimationComponent.h | 15 +- src/src/Engine.cpp | 90 +- src/src/Renderer.cpp | 13 +- src/src/core/utils/input.cpp | 74 +- src/src/core/utils/input.h | 31 +- src/src/editor/windows/Inspector.cpp | 5 + src/vendor/imguizmo/ImGuizmo.cpp | 3151 ++++++++++++++++++++ src/vendor/imguizmo/ImGuizmo.h | 306 ++ 13 files changed, 6607 insertions(+), 2194 deletions(-) create mode 100644 src/vendor/imguizmo/ImGuizmo.cpp create mode 100644 src/vendor/imguizmo/ImGuizmo.h diff --git a/remake.yaml b/remake.yaml index 906b893..f03b5f8 100644 --- a/remake.yaml +++ b/remake.yaml @@ -7,6 +7,8 @@ src_dirs: - src/vendor/box2d - src/vendor/xxhash - src/vendor/miniaudio + - src/vendor/imguizmo + @@ -19,6 +21,8 @@ include_dirs: - src/vendor/box2d - src/vendor/xxhash - src/vendor/miniaudio + - src/vendor/imguizmo + - C:/msys64/mingw64/include diff --git a/remake/build.log b/remake/build.log index b1eb964..d230a99 100644 --- a/remake/build.log +++ b/remake/build.log @@ -1,3 +1,3 @@ -[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -IC:/msys64/mingw64/include -Isrc\vendor\imgui -IC:\msys64\mingw64\lib\libyaml-cpp.a -MMD -MP -c src\src\Engine.cpp -o src\build\Engine.o -[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\AudioPlayerComponent.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\audio\AudioEngine.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\AudioInfo.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 src\build\miniaudio.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto -ldbghelp +[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Renderer.cpp -o src\build\Renderer.o +[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\AudioPlayerComponent.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\audio\AudioEngine.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\AudioInfo.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 src\build\miniaudio.o src\build\ImGuizmo.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto -ldbghelp [RUN] Executed app.exe successfully. diff --git a/src/assets/scenes/drag_n_drop_tests.cene b/src/assets/scenes/drag_n_drop_tests.cene index 06a740c..debe6c2 100644 --- a/src/assets/scenes/drag_n_drop_tests.cene +++ b/src/assets/scenes/drag_n_drop_tests.cene @@ -1,6 +1,6 @@ engine_version: 0.1.0 scene_name: drag_n_drop_tests -scene_hash: a487fb03e18781768c5dccdc2b801f8e85313b7a6c14e05a1e8d33e1543cf3f5 +scene_hash: 8c78d1f779e5a1adb7be267b9d4a2c5c407c5e7b4cf8c1bb94b9bbdeccb6c5ea format_version: 1 objects: - name: NewObject @@ -873,6 +873,162 @@ objects: normalMap: 0 renderType: Lit children: [] + - name: tile_028.png + uid: bac54db03d8b4507a1138768db2ce2f1 + id: 71 + position: [-17.2237396, 138.836761] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 29 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_031.png + uid: 2e3e8e939e7e4758bd62d917f333c613 + id: 72 + position: [11.3386536, 120.830032] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 32 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_030.png + uid: 57d2d2102d15498e9582dbb80c5788a2 + id: 73 + position: [43.005661, 99.0977783] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 31 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_032.png + uid: 5f27a4cb3842436f9690d4ac80af91d9 + id: 74 + position: [74.6726685, 81.0910492] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 33 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_034.png + uid: 5530a0545f7e4e00993b81e777c46ab5 + id: 75 + position: [103.855988, 64.9470825] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 35 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_036.png + uid: 0688a67cff51416fab3f2d41af00cdaf + id: 76 + position: [132.418381, 49.4240456] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 37 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_040.png + uid: bdbb107bb2c947c4b718a0851cf03c4e + id: 77 + position: [18.733284, 155.827454] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 41 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_033.png + uid: aa2e13adf13745d2964c19166590cbeb + id: 78 + position: [45.8280487, 136.635315] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 34 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_027.png + uid: 56571e9c0f15495b8f6c6944173b38a5 + id: 79 + position: [76.3096619, 118.007668] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 28 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_031.png + uid: ad2e91976ba84154b6d0a43539e66398 + id: 80 + position: [107.920227, 104.460281] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 32 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_029.png + uid: 0c004f821f8c484f938c9745c09f9dd4 + id: 81 + position: [133.886047, 89.7839508] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 30 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_032.png + uid: f781918d60874b868f1d4ae6ead18be6 + id: 82 + position: [168.318985, 68.3339233] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 33 + normalMap: 0 + renderType: Lit + children: [] - name: Animated uid: 82b18591393b492fb65e99bd5a0e0aa6 id: 68 @@ -910,161 +1066,682 @@ color_correction: intensity: 4 threshold: 1 Assets: - - uaid: 123 - path: C:\Users\spenc\Music\Stereo Test - LeftRight Audio Test for HeadphonesSpeakers.mp3 - filename: Stereo Test - LeftRight Audio Test for HeadphonesSpeakers.mp3 - filetype: mp3 - type: 1 - hash: 5885c8cc38709f22 - lastModified: 1746052188 - - uaid: 122 - path: C:\Users\spenc\Music\simple-notification-152054.wav - filename: simple-notification-152054.wav - filetype: wav - type: 1 - hash: 0f5adca8b95e7494 - lastModified: 1745953000 - - uaid: 121 - path: C:\Users\spenc\Music\simple-notification-152054.mp3 - filename: simple-notification-152054.mp3 - filetype: mp3 - type: 1 - hash: 3e57c2530f08c1ab - lastModified: 1745951640 - - uaid: 120 - path: C:\Users\spenc\Music\reflected-light-147979.mp3 - filename: reflected-light-147979.mp3 - filetype: mp3 - type: 1 - hash: b4d344d1f668e25d - lastModified: 1735362210 - - uaid: 119 - path: C:\Users\spenc\Music\good-night-lofi-cozy-chill-music-160166.mp3 - filename: good-night-lofi-cozy-chill-music-160166.mp3 - filetype: mp3 - type: 1 - hash: 246561eaa4e21fad - lastModified: 1735362096 - - uaid: 118 - path: C:\Users\spenc\Music\ethereal-vistas-191254.mp3 - filename: ethereal-vistas-191254.mp3 - filetype: mp3 - type: 1 - hash: 0da03a50fc5a40a8 - lastModified: 1735362078 - - uaid: 117 - path: C:\Users\spenc\Music\creative-technology-showreel-241274.mp3 - filename: creative-technology-showreel-241274.mp3 - filetype: mp3 - type: 1 - hash: d7f8e8b2954d438f - lastModified: 1730076792 - - uaid: 88 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_087.png - filename: tile_087.png + - uaid: 29 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_028.png + filename: tile_028.png filetype: png type: 0 - hash: b5be37e278b5a0e8 - lastModified: 1728871745 + hash: e7beb61a6e9cabf5 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 28 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_027.png - filename: tile_027.png + - uaid: 89 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_088.png + filename: tile_088.png filetype: png type: 0 - hash: 82735e0fe1556323 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 87 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_086.png - filename: tile_086.png - filetype: png - type: 0 - hash: 405549c9596a8b02 + hash: a052591c3e581551 lastModified: 1728871744 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 26 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_025.png - filename: tile_025.png + - uaid: 31 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_030.png + filename: tile_030.png filetype: png type: 0 - hash: 59f5a825963b4b58 + hash: 2f6e1c7bd159e049 lastModified: 1728871742 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 25 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_024.png - filename: tile_024.png + - uaid: 90 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_089.png + filename: tile_089.png filetype: png type: 0 - hash: 52d6f7a1f1aaf096 - lastModified: 1728871742 + hash: 7f30d8350216f6bb + lastModified: 1728871745 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 24 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_023.png - filename: tile_023.png + - uaid: 32 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_031.png + filename: tile_031.png filetype: png type: 0 - hash: ca52dd2852403677 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 23 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_022.png - filename: tile_022.png - filetype: png - type: 0 - hash: 2217b4ba2738d800 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 22 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_021.png - filename: tile_021.png - filetype: png - type: 0 - hash: a2b2f33d53eafbe1 + hash: 551fe37520f82310 lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 21 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_020.png - filename: tile_020.png + - uaid: 91 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_090.png + filename: tile_090.png filetype: png type: 0 - hash: 9ab8e82f77ecda85 + hash: 49ac491580bfc4f8 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 92 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_091.png + filename: tile_091.png + filetype: png + type: 0 + hash: 2c31a5fc8d71be6e + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 93 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_092.png + filename: tile_092.png + filetype: png + type: 0 + hash: d546c3d4f31aa5a0 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 94 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_093.png + filename: tile_093.png + filetype: png + type: 0 + hash: fecc9a1f3e9802d8 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 95 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_094.png + filename: tile_094.png + filetype: png + type: 0 + hash: 26efe00187d8dde5 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 96 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_095.png + filename: tile_095.png + filetype: png + type: 0 + hash: 2c4018746bda7639 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 97 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_096.png + filename: tile_096.png + filetype: png + type: 0 + hash: 61e5ba2ec5cc2e03 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 98 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_097.png + filename: tile_097.png + filetype: png + type: 0 + hash: 4140eb0e01c42458 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 99 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_098.png + filename: tile_098.png + filetype: png + type: 0 + hash: f505363f6721ed43 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 100 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_099.png + filename: tile_099.png + filetype: png + type: 0 + hash: 64bc27961c23a597 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 101 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_100.png + filename: tile_100.png + filetype: png + type: 0 + hash: bce6842fe9a78d1e + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 102 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_101.png + filename: tile_101.png + filetype: png + type: 0 + hash: e5a269d460d00e69 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 115 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_114.png + filename: tile_114.png + filetype: png + type: 0 + hash: bffbedcad0c620c7 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 114 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_113.png + filename: tile_113.png + filetype: png + type: 0 + hash: 5d615b590fe9431a + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 113 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_112.png + filename: tile_112.png + filetype: png + type: 0 + hash: ea99517d8b684ab8 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 112 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_111.png + filename: tile_111.png + filetype: png + type: 0 + hash: a5a090079e1eb3b5 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 111 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_110.png + filename: tile_110.png + filetype: png + type: 0 + hash: a97225d051b0be0f + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 110 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_109.png + filename: tile_109.png + filetype: png + type: 0 + hash: 8f7568ef2b75f210 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 109 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_108.png + filename: tile_108.png + filetype: png + type: 0 + hash: dc8c15964e615c28 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 108 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_107.png + filename: tile_107.png + filetype: png + type: 0 + hash: a0843e8681231325 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 107 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_106.png + filename: tile_106.png + filetype: png + type: 0 + hash: 9559b168bb797f61 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 106 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_105.png + filename: tile_105.png + filetype: png + type: 0 + hash: 893cb7a825c3def2 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 105 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_104.png + filename: tile_104.png + filetype: png + type: 0 + hash: 2d73577cfe2985f8 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 104 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_103.png + filename: tile_103.png + filetype: png + type: 0 + hash: 93be22329a97f13a + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 103 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_102.png + filename: tile_102.png + filetype: png + type: 0 + hash: ee4893b0b0e389b0 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 71 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_070.png + filename: tile_070.png + filetype: png + type: 0 + hash: ee1ef8567b8a3df0 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 70 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_069.png + filename: tile_069.png + filetype: png + type: 0 + hash: 6cc14afc186ec771 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 69 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_068.png + filename: tile_068.png + filetype: png + type: 0 + hash: be2caa45ef20fd82 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 68 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_067.png + filename: tile_067.png + filetype: png + type: 0 + hash: fb3139953ea9d8d1 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 67 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_066.png + filename: tile_066.png + filetype: png + type: 0 + hash: 7fcc1e121b9c475a + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 66 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_065.png + filename: tile_065.png + filetype: png + type: 0 + hash: 70dd4177ac2aacd3 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 65 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_064.png + filename: tile_064.png + filetype: png + type: 0 + hash: dc1ce13185d6f9dd lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 20 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_019.png - filename: tile_019.png + - uaid: 63 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_062.png + filename: tile_062.png filetype: png type: 0 - hash: f4d73b8ef85ddfbf + hash: 54ba3afbbf9a9b9d + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 62 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_061.png + filename: tile_061.png + filetype: png + type: 0 + hash: c8a1b22d67f32e16 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 61 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_060.png + filename: tile_060.png + filetype: png + type: 0 + hash: 5871fcecf1d47e1c + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 60 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_059.png + filename: tile_059.png + filetype: png + type: 0 + hash: 8deb3108a6f2fd67 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 64 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_063.png + filename: tile_063.png + filetype: png + type: 0 + hash: 3f62dcdb053f6abe + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 116 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\spritesheet.png + filename: spritesheet.png + filetype: png + type: 0 + hash: d178a6f5b597b470 + lastModified: 1728871741 + size: [352, 352] + channels: 4 + format: GL_RGBA + - uaid: 72 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_071.png + filename: tile_071.png + filetype: png + type: 0 + hash: 07cff9b3939795f5 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 73 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_072.png + filename: tile_072.png + filetype: png + type: 0 + hash: cda73d6cbd54d108 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 74 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_073.png + filename: tile_073.png + filetype: png + type: 0 + hash: 75748e5776001213 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 75 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_074.png + filename: tile_074.png + filetype: png + type: 0 + hash: 42121b492147d8fb + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 76 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_075.png + filename: tile_075.png + filetype: png + type: 0 + hash: 077768331bb39105 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 77 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_076.png + filename: tile_076.png + filetype: png + type: 0 + hash: 414a4fc402bf8d9a + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 78 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_077.png + filename: tile_077.png + filetype: png + type: 0 + hash: 51e120ce40647450 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 79 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_078.png + filename: tile_078.png + filetype: png + type: 0 + hash: 0c75dd1dfcb324e2 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 80 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_079.png + filename: tile_079.png + filetype: png + type: 0 + hash: 6a517ee8c8a504b3 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 81 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_080.png + filename: tile_080.png + filetype: png + type: 0 + hash: 24af11a711c4a405 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 82 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_081.png + filename: tile_081.png + filetype: png + type: 0 + hash: e37d943f98df117c + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 83 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_082.png + filename: tile_082.png + filetype: png + type: 0 + hash: a7d389b57649b8c1 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 84 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_083.png + filename: tile_083.png + filetype: png + type: 0 + hash: 7e26027e93ae8665 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 85 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_084.png + filename: tile_084.png + filetype: png + type: 0 + hash: a720f40abed06305 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 27 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_026.png + filename: tile_026.png + filetype: png + type: 0 + hash: 455f9cc034a4e240 lastModified: 1728871742 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 19 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_018.png - filename: tile_018.png + - uaid: 86 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_085.png + filename: tile_085.png filetype: png type: 0 - hash: 2f4aa3d6c9a88136 + hash: c921026208aff689 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 33 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_032.png + filename: tile_032.png + filetype: png + type: 0 + hash: ab38b324f6e3068e + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 34 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_033.png + filename: tile_033.png + filetype: png + type: 0 + hash: 9bc4f952ca3d6104 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 35 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_034.png + filename: tile_034.png + filetype: png + type: 0 + hash: 4c68d41935c4c205 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 36 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_035.png + filename: tile_035.png + filetype: png + type: 0 + hash: 4bf836f83d492422 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 37 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_036.png + filename: tile_036.png + filetype: png + type: 0 + hash: 9b60a4c308beee86 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 14 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_013.png + filename: tile_013.png + filetype: png + type: 0 + hash: be9b2566c79ca9e3 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 15 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_014.png + filename: tile_014.png + filetype: png + type: 0 + hash: e9c9d0a81a34e191 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 16 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_015.png + filename: tile_015.png + filetype: png + type: 0 + hash: dfbb87d88e7b361a + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 17 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_016.png + filename: tile_016.png + filetype: png + type: 0 + hash: d66738b42167c25b lastModified: 1728871742 size: [32, 32] channels: 4 @@ -1079,86 +1756,63 @@ Assets: size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 17 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_016.png - filename: tile_016.png + - uaid: 19 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_018.png + filename: tile_018.png filetype: png type: 0 - hash: d66738b42167c25b + hash: 2f4aa3d6c9a88136 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 20 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_019.png + filename: tile_019.png + filetype: png + type: 0 + hash: f4d73b8ef85ddfbf + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 21 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_020.png + filename: tile_020.png + filetype: png + type: 0 + hash: 9ab8e82f77ecda85 lastModified: 1728871742 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 16 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_015.png - filename: tile_015.png + - uaid: 22 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_021.png + filename: tile_021.png filetype: png type: 0 - hash: dfbb87d88e7b361a + hash: a2b2f33d53eafbe1 lastModified: 1728871742 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 15 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_014.png - filename: tile_014.png + - uaid: 23 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_022.png + filename: tile_022.png filetype: png type: 0 - hash: e9c9d0a81a34e191 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 14 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_013.png - filename: tile_013.png - filetype: png - type: 0 - hash: be9b2566c79ca9e3 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 1 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_000.png - filename: tile_000.png - filetype: png - type: 0 - hash: 43b1a791b2f610aa - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 2 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_001.png - filename: tile_001.png - filetype: png - type: 0 - hash: 58e2a6949c806ed4 - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 3 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_002.png - filename: tile_002.png - filetype: png - type: 0 - hash: 9d00d31c498403a5 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 4 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_003.png - filename: tile_003.png - filetype: png - type: 0 - hash: 2ce62d3fa5f83a85 - lastModified: 1728871742 + hash: 2217b4ba2738d800 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA + - uaid: 123 + path: C:\Users\spenc\Music\Stereo Test - LeftRight Audio Test for HeadphonesSpeakers.mp3 + filename: Stereo Test - LeftRight Audio Test for HeadphonesSpeakers.mp3 + filetype: mp3 + type: 1 + hash: 5885c8cc38709f22 + lastModified: 1746052188 - uaid: 5 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_004.png filename: tile_004.png @@ -1179,13 +1833,175 @@ Assets: size: [32, 32] channels: 4 format: GL_RGBA + - uaid: 122 + path: C:\Users\spenc\Music\simple-notification-152054.wav + filename: simple-notification-152054.wav + filetype: wav + type: 1 + hash: 0f5adca8b95e7494 + lastModified: 1745952999 + - uaid: 4 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_003.png + filename: tile_003.png + filetype: png + type: 0 + hash: 2ce62d3fa5f83a85 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 121 + path: C:\Users\spenc\Music\simple-notification-152054.mp3 + filename: simple-notification-152054.mp3 + filetype: mp3 + type: 1 + hash: 3e57c2530f08c1ab + lastModified: 1745951640 + - uaid: 3 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_002.png + filename: tile_002.png + filetype: png + type: 0 + hash: 9d00d31c498403a5 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 120 + path: C:\Users\spenc\Music\reflected-light-147979.mp3 + filename: reflected-light-147979.mp3 + filetype: mp3 + type: 1 + hash: b4d344d1f668e25d + lastModified: 1735362210 + - uaid: 2 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_001.png + filename: tile_001.png + filetype: png + type: 0 + hash: 58e2a6949c806ed4 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 119 + path: C:\Users\spenc\Music\good-night-lofi-cozy-chill-music-160166.mp3 + filename: good-night-lofi-cozy-chill-music-160166.mp3 + filetype: mp3 + type: 1 + hash: 246561eaa4e21fad + lastModified: 1735362097 + - uaid: 1 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_000.png + filename: tile_000.png + filetype: png + type: 0 + hash: 43b1a791b2f610aa + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 28 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_027.png + filename: tile_027.png + filetype: png + type: 0 + hash: 82735e0fe1556323 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 87 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_086.png + filename: tile_086.png + filetype: png + type: 0 + hash: 405549c9596a8b02 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 118 + path: C:\Users\spenc\Music\ethereal-vistas-191254.mp3 + filename: ethereal-vistas-191254.mp3 + filetype: mp3 + type: 1 + hash: 0da03a50fc5a40a8 + lastModified: 1735362078 + - uaid: 59 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_058.png + filename: tile_058.png + filetype: png + type: 0 + hash: d7e53d66d6608e44 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 26 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_025.png + filename: tile_025.png + filetype: png + type: 0 + hash: 59f5a825963b4b58 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 117 + path: C:\Users\spenc\Music\creative-technology-showreel-241274.mp3 + filename: creative-technology-showreel-241274.mp3 + filetype: mp3 + type: 1 + hash: d7f8e8b2954d438f + lastModified: 1730076792 + - uaid: 58 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_057.png + filename: tile_057.png + filetype: png + type: 0 + hash: 62e0d421dc1b94ca + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 88 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_087.png + filename: tile_087.png + filetype: png + type: 0 + hash: b5be37e278b5a0e8 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 25 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_024.png + filename: tile_024.png + filetype: png + type: 0 + hash: 52d6f7a1f1aaf096 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 24 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_023.png + filename: tile_023.png + filetype: png + type: 0 + hash: ca52dd2852403677 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA - uaid: 7 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_006.png filename: tile_006.png filetype: png type: 0 hash: 977d38606f54ec1a - lastModified: 1728871742 + lastModified: 1728871741 size: [32, 32] channels: 4 format: GL_RGBA @@ -1245,7 +2061,7 @@ Assets: filetype: png type: 0 hash: 32bf6597d4a096f7 - lastModified: 1728871742 + lastModified: 1728871741 size: [32, 32] channels: 4 format: GL_RGBA @@ -1255,7 +2071,7 @@ Assets: filetype: png type: 0 hash: 3d1f20d336f5a0e4 - lastModified: 1728871743 + lastModified: 1728871742 size: [32, 32] channels: 4 format: GL_RGBA @@ -1265,7 +2081,7 @@ Assets: filetype: png type: 0 hash: a6ce3c9db850be68 - lastModified: 1728871744 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA @@ -1275,7 +2091,7 @@ Assets: filetype: png type: 0 hash: 6398a4447dcb5e13 - lastModified: 1728871744 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA @@ -1295,7 +2111,7 @@ Assets: filetype: png type: 0 hash: 1f1918a8c669d3c1 - lastModified: 1728871744 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA @@ -1345,7 +2161,7 @@ Assets: filetype: png type: 0 hash: f4cb8b97cee3bb7c - lastModified: 1728871744 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA @@ -1365,37 +2181,17 @@ Assets: filetype: png type: 0 hash: 54c17c59498db1fc - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 58 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_057.png - filename: tile_057.png - filetype: png - type: 0 - hash: 62e0d421dc1b94ca lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 59 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_058.png - filename: tile_058.png - filetype: png - type: 0 - hash: d7e53d66d6608e44 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - uaid: 46 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_045.png filename: tile_045.png filetype: png type: 0 hash: a42f65407bd8d9c8 - lastModified: 1728871744 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA @@ -1405,7 +2201,7 @@ Assets: filetype: png type: 0 hash: cc99aeb78832013d - lastModified: 1728871743 + lastModified: 1728871744 size: [32, 32] channels: 4 format: GL_RGBA @@ -1445,7 +2241,7 @@ Assets: filetype: png type: 0 hash: 56430e898f7e9789 - lastModified: 1728871744 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA @@ -1455,7 +2251,7 @@ Assets: filetype: png type: 0 hash: d35fb51aa3acdc47 - lastModified: 1728871743 + lastModified: 1728871742 size: [32, 32] channels: 4 format: GL_RGBA @@ -1478,644 +2274,4 @@ Assets: lastModified: 1728871743 size: [32, 32] channels: 4 - format: GL_RGBA - - uaid: 37 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_036.png - filename: tile_036.png - filetype: png - type: 0 - hash: 9b60a4c308beee86 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 36 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_035.png - filename: tile_035.png - filetype: png - type: 0 - hash: 4bf836f83d492422 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 35 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_034.png - filename: tile_034.png - filetype: png - type: 0 - hash: 4c68d41935c4c205 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 34 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_033.png - filename: tile_033.png - filetype: png - type: 0 - hash: 9bc4f952ca3d6104 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 33 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_032.png - filename: tile_032.png - filetype: png - type: 0 - hash: ab38b324f6e3068e - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 86 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_085.png - filename: tile_085.png - filetype: png - type: 0 - hash: c921026208aff689 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 27 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_026.png - filename: tile_026.png - filetype: png - type: 0 - hash: 455f9cc034a4e240 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 85 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_084.png - filename: tile_084.png - filetype: png - type: 0 - hash: a720f40abed06305 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 84 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_083.png - filename: tile_083.png - filetype: png - type: 0 - hash: 7e26027e93ae8665 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 83 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_082.png - filename: tile_082.png - filetype: png - type: 0 - hash: a7d389b57649b8c1 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 82 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_081.png - filename: tile_081.png - filetype: png - type: 0 - hash: e37d943f98df117c - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 81 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_080.png - filename: tile_080.png - filetype: png - type: 0 - hash: 24af11a711c4a405 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 80 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_079.png - filename: tile_079.png - filetype: png - type: 0 - hash: 6a517ee8c8a504b3 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 79 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_078.png - filename: tile_078.png - filetype: png - type: 0 - hash: 0c75dd1dfcb324e2 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 78 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_077.png - filename: tile_077.png - filetype: png - type: 0 - hash: 51e120ce40647450 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 77 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_076.png - filename: tile_076.png - filetype: png - type: 0 - hash: 414a4fc402bf8d9a - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 76 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_075.png - filename: tile_075.png - filetype: png - type: 0 - hash: 077768331bb39105 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 75 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_074.png - filename: tile_074.png - filetype: png - type: 0 - hash: 42121b492147d8fb - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 74 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_073.png - filename: tile_073.png - filetype: png - type: 0 - hash: 75748e5776001213 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 73 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_072.png - filename: tile_072.png - filetype: png - type: 0 - hash: cda73d6cbd54d108 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 72 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_071.png - filename: tile_071.png - filetype: png - type: 0 - hash: 07cff9b3939795f5 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 116 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\spritesheet.png - filename: spritesheet.png - filetype: png - type: 0 - hash: d178a6f5b597b470 - lastModified: 1728871742 - size: [352, 352] - channels: 4 - format: GL_RGBA - - uaid: 64 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_063.png - filename: tile_063.png - filetype: png - type: 0 - hash: 3f62dcdb053f6abe - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 60 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_059.png - filename: tile_059.png - filetype: png - type: 0 - hash: 8deb3108a6f2fd67 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 61 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_060.png - filename: tile_060.png - filetype: png - type: 0 - hash: 5871fcecf1d47e1c - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 62 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_061.png - filename: tile_061.png - filetype: png - type: 0 - hash: c8a1b22d67f32e16 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 63 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_062.png - filename: tile_062.png - filetype: png - type: 0 - hash: 54ba3afbbf9a9b9d - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 65 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_064.png - filename: tile_064.png - filetype: png - type: 0 - hash: dc1ce13185d6f9dd - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 66 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_065.png - filename: tile_065.png - filetype: png - type: 0 - hash: 70dd4177ac2aacd3 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 67 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_066.png - filename: tile_066.png - filetype: png - type: 0 - hash: 7fcc1e121b9c475a - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 68 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_067.png - filename: tile_067.png - filetype: png - type: 0 - hash: fb3139953ea9d8d1 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 69 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_068.png - filename: tile_068.png - filetype: png - type: 0 - hash: be2caa45ef20fd82 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 70 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_069.png - filename: tile_069.png - filetype: png - type: 0 - hash: 6cc14afc186ec771 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 71 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_070.png - filename: tile_070.png - filetype: png - type: 0 - hash: ee1ef8567b8a3df0 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 103 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_102.png - filename: tile_102.png - filetype: png - type: 0 - hash: ee4893b0b0e389b0 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 104 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_103.png - filename: tile_103.png - filetype: png - type: 0 - hash: 93be22329a97f13a - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 105 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_104.png - filename: tile_104.png - filetype: png - type: 0 - hash: 2d73577cfe2985f8 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 106 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_105.png - filename: tile_105.png - filetype: png - type: 0 - hash: 893cb7a825c3def2 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 107 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_106.png - filename: tile_106.png - filetype: png - type: 0 - hash: 9559b168bb797f61 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 108 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_107.png - filename: tile_107.png - filetype: png - type: 0 - hash: a0843e8681231325 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 109 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_108.png - filename: tile_108.png - filetype: png - type: 0 - hash: dc8c15964e615c28 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 110 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_109.png - filename: tile_109.png - filetype: png - type: 0 - hash: 8f7568ef2b75f210 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 111 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_110.png - filename: tile_110.png - filetype: png - type: 0 - hash: a97225d051b0be0f - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 112 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_111.png - filename: tile_111.png - filetype: png - type: 0 - hash: a5a090079e1eb3b5 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 113 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_112.png - filename: tile_112.png - filetype: png - type: 0 - hash: ea99517d8b684ab8 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 114 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_113.png - filename: tile_113.png - filetype: png - type: 0 - hash: 5d615b590fe9431a - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 115 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_114.png - filename: tile_114.png - filetype: png - type: 0 - hash: bffbedcad0c620c7 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 102 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_101.png - filename: tile_101.png - filetype: png - type: 0 - hash: e5a269d460d00e69 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 101 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_100.png - filename: tile_100.png - filetype: png - type: 0 - hash: bce6842fe9a78d1e - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 100 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_099.png - filename: tile_099.png - filetype: png - type: 0 - hash: 64bc27961c23a597 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 99 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_098.png - filename: tile_098.png - filetype: png - type: 0 - hash: f505363f6721ed43 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 98 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_097.png - filename: tile_097.png - filetype: png - type: 0 - hash: 4140eb0e01c42458 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 97 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_096.png - filename: tile_096.png - filetype: png - type: 0 - hash: 61e5ba2ec5cc2e03 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 96 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_095.png - filename: tile_095.png - filetype: png - type: 0 - hash: 2c4018746bda7639 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 95 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_094.png - filename: tile_094.png - filetype: png - type: 0 - hash: 26efe00187d8dde5 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 94 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_093.png - filename: tile_093.png - filetype: png - type: 0 - hash: fecc9a1f3e9802d8 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 93 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_092.png - filename: tile_092.png - filetype: png - type: 0 - hash: d546c3d4f31aa5a0 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 92 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_091.png - filename: tile_091.png - filetype: png - type: 0 - hash: 2c31a5fc8d71be6e - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 91 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_090.png - filename: tile_090.png - filetype: png - type: 0 - hash: 49ac491580bfc4f8 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 32 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_031.png - filename: tile_031.png - filetype: png - type: 0 - hash: 551fe37520f82310 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 90 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_089.png - filename: tile_089.png - filetype: png - type: 0 - hash: 7f30d8350216f6bb - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 31 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_030.png - filename: tile_030.png - filetype: png - type: 0 - hash: 2f6e1c7bd159e049 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 89 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_088.png - filename: tile_088.png - filetype: png - type: 0 - hash: a052591c3e581551 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 29 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_028.png - filename: tile_028.png - filetype: png - type: 0 - hash: e7beb61a6e9cabf5 - lastModified: 1728871743 - size: [32, 32] - channels: 4 format: GL_RGBA \ No newline at end of file diff --git a/src/assets/scenes/isometric_test.cene b/src/assets/scenes/isometric_test.cene index cfec2b8..06dc51e 100644 --- a/src/assets/scenes/isometric_test.cene +++ b/src/assets/scenes/isometric_test.cene @@ -1,421 +1,11 @@ engine_version: 0.1.0 scene_name: isometric_test -scene_hash: 25995851850cd5bbf2bdbd169b945a5fe0db89d37af1de470f2e3d546647d7fa +scene_hash: fbcf8ee416ca823a7fa30fe96a4bb1302b4bde91c1965c9cb8fb23ac506f801f format_version: 1 objects: - - name: Hello, Create - uid: 440c5cc8b27f4d1c9c127f2ddcf2ab18 - id: 0 - position: [0, 0] - rotation: 0 - layer: 0 - visable: true - components: [] - children: [] - - name: tile_037.png - uid: a6dfc3eeb0f34c5da6470ffc545755ed - id: 11 - position: [-128.5, -88.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 38 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_030.png - uid: 74893ccd73614c91a36806f927423d78 - id: 12 - position: [-95.5, -71.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 31 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_031.png - uid: e6c2abbf97914bf6bc5ebc8874fafffd - id: 13 - position: [-61.5, -55.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 32 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_029.png - uid: 81b39ababeaf43be8942b654275e5fe1 - id: 14 - position: [-28.5, -38.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 30 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_032.png - uid: 87332fee5f964d77a3a80f2599e09ba8 - id: 15 - position: [8.5, -20.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 33 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_039.png - uid: 6be36a4c0a8c441798fc490f2ab0a861 - id: 16 - position: [-163.5, -68.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 40 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_037.png - uid: 9cc1fbb79520491dafe0eabdb66b9b6c - id: 17 - position: [-128.5, -48.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 38 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_038.png - uid: b783547b62084c348197e07a44d376f2 - id: 18 - position: [-96.5, -30.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 39 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_038.png - uid: 88ecd280be5348de8f6aa48fdec67fc2 - id: 19 - position: [-60.5, -12.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 39 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_032.png - uid: 2ce26442422b41c091188f4d6fc38cda - id: 20 - position: [-26.5, 2.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 33 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_038.png - uid: 2cba861c1ab04bbabccfb0335605fc7f - id: 21 - position: [36.5, 1.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 39 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_031.png - uid: 1fbd41c54f1348c1872a29385ec1d0eb - id: 27 - position: [4.5, 20.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 32 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: 6a5258c5e198481fb99b9a79078a24c1 - id: 28 - position: [-192.5, -50.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: 5d498c9e69ff48c5a5434f2fdd757e1d - id: 29 - position: [-158.5, -33.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: c9df0247484b489f927602bfc12d4025 - id: 30 - position: [-125.5, -17.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: d2bc09ec9fc84c998d7b8e5c9a96a542 - id: 31 - position: [-92.5, 0.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: d6fc3967321241e3b95beb7574643a91 - id: 32 - position: [-59.5, 16.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: e382eab57275422b9855c46c478e002e - id: 33 - position: [-26.5, 33.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: f94b7208f06f4ec38c2806dfb272be9f - id: 34 - position: [-222.5, -32.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: 52e7db8645e942aba356e12b22e2a9a9 - id: 35 - position: [-190.5, -17.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: 0f5ab154b77b4ed4b71b8ec2b7f89740 - id: 36 - position: [-156.5, -0.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: 813f64a82c18411c8050593012d21b28 - id: 37 - position: [-123.5, 19.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: a3e3e598e4a045538e0b892812bc1fa0 - id: 38 - position: [-89.5, 36.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_011.png - uid: 523ae2cbf4734069a6d516506e937d72 - id: 39 - position: [-54.5, 52.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 12 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_044.png - uid: 76f65522c6fb4657ba05552e68e0a599 - id: 40 - position: [-96.5, -49.5] - rotation: 0 - layer: 1 - visable: true - components: - - type: SpriteComponent - texture: 45 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_022.png - uid: 46a6724bf3384e009e2c4e3a2a20bc27 - id: 64 - position: [36.5, 29.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 23 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_022.png - uid: 99cade4e8b47450a9d8f973915122ec6 - id: 65 - position: [7.5, 47.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 23 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_024.png - uid: 26d61f1f90af4530ae18112b8aff95ee - id: 66 - position: [-22.5, 66.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 25 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_028.png - uid: 792c9f480f9f45f9be59c1ceac365765 - id: 67 - position: [14.5, 83.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 29 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_027.png - uid: c0c272acf23e4d5387672352ad1713c2 - id: 68 - position: [41.5, 61.5] - rotation: 0 - layer: 0 - visable: true - components: - - type: SpriteComponent - texture: 28 - normalMap: 0 - renderType: Lit - children: [] - - name: NewObject - uid: 3c93194d0f1b4a02a5bc892ccee48d32 - id: 73 - position: [0, 0] - rotation: 0 - layer: 0 - visable: true - components: - - type: ScriptComponent - scriptPath: C:\Users\spenc\OneDrive\Documents\GitHub\Create-Engine\src\assets\lua\light_test.lua - children: [] - name: Light uid: cabd139ec6ac4245b4e4075668a6d971 - id: 74 + id: 81 position: [-61.2999992, 2.5999999] rotation: 0 layer: 0 @@ -430,67 +20,1514 @@ objects: radius: 100000000 falloff: 1 type: 0 + - type: ScriptComponent + scriptPath: C:\Users\spenc\OneDrive\Documents\GitHub\Create-Engine\src\assets\lua\light_test.lua children: [] - - name: tile_045.png - uid: d9ac006ad61e4d3e87fa1cd6ef88eecc - id: 116 - position: [-59.9570007, -33.0279999] + - name: Tiles + uid: 2917181dc75c4b3e9c052b2d9120dc1e + id: 82 + position: [0, 0] + rotation: 0 + layer: 0 + visable: true + components: [] + children: + - name: tile_053.png + uid: 0f6135a7c4dc4cca857bf16c080a3bce + id: 83 + position: [-58.2519989, 26.0020008] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 54 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_049.png + uid: 8aeb05965e4d408b9456cb0f144cb118 + id: 84 + position: [-165.057999, -90.435997] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 50 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_044.png + uid: 40b88ad3429e42af94466d658a3ec42d + id: 85 + position: [8.5340004, 23.6730003] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 45 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_045.png + uid: d9ac006ad61e4d3e87fa1cd6ef88eecc + id: 86 + position: [-59.9570007, -33.0279999] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 46 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_027.png + uid: c0c272acf23e4d5387672352ad1713c2 + id: 87 + position: [41.5, 61.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 28 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_028.png + uid: 792c9f480f9f45f9be59c1ceac365765 + id: 88 + position: [14.5, 83.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 29 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_024.png + uid: 26d61f1f90af4530ae18112b8aff95ee + id: 89 + position: [-22.5, 66.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 25 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_022.png + uid: 99cade4e8b47450a9d8f973915122ec6 + id: 90 + position: [7.5, 47.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 23 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_022.png + uid: 46a6724bf3384e009e2c4e3a2a20bc27 + id: 91 + position: [36.5, 29.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 23 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_044.png + uid: 76f65522c6fb4657ba05552e68e0a599 + id: 92 + position: [-96.5, -49.5] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 45 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: 523ae2cbf4734069a6d516506e937d72 + id: 93 + position: [-54.5, 52.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: a3e3e598e4a045538e0b892812bc1fa0 + id: 94 + position: [-89.5, 36.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: 813f64a82c18411c8050593012d21b28 + id: 95 + position: [-123.5, 19.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: 0f5ab154b77b4ed4b71b8ec2b7f89740 + id: 96 + position: [-156.5, -0.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: 52e7db8645e942aba356e12b22e2a9a9 + id: 97 + position: [-190.5, -17.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: f94b7208f06f4ec38c2806dfb272be9f + id: 98 + position: [-222.5, -32.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: e382eab57275422b9855c46c478e002e + id: 99 + position: [-26.5, 33.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: d6fc3967321241e3b95beb7574643a91 + id: 100 + position: [-59.5, 16.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: d2bc09ec9fc84c998d7b8e5c9a96a542 + id: 101 + position: [-92.5, 0.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: c9df0247484b489f927602bfc12d4025 + id: 102 + position: [-125.5, -17.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: 5d498c9e69ff48c5a5434f2fdd757e1d + id: 103 + position: [-158.5, -33.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_011.png + uid: 6a5258c5e198481fb99b9a79078a24c1 + id: 104 + position: [-192.5, -50.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 12 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_031.png + uid: 1fbd41c54f1348c1872a29385ec1d0eb + id: 105 + position: [4.5, 20.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 32 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_038.png + uid: 2cba861c1ab04bbabccfb0335605fc7f + id: 106 + position: [36.5, 1.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 39 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_032.png + uid: 2ce26442422b41c091188f4d6fc38cda + id: 107 + position: [-26.5, 2.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 33 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_038.png + uid: 88ecd280be5348de8f6aa48fdec67fc2 + id: 108 + position: [-60.5, -12.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 39 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_038.png + uid: b783547b62084c348197e07a44d376f2 + id: 109 + position: [-96.5, -30.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 39 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_037.png + uid: 9cc1fbb79520491dafe0eabdb66b9b6c + id: 110 + position: [-128.5, -48.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 38 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_039.png + uid: 6be36a4c0a8c441798fc490f2ab0a861 + id: 111 + position: [-163.5, -68.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 40 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_032.png + uid: 87332fee5f964d77a3a80f2599e09ba8 + id: 112 + position: [8.5, -20.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 33 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_029.png + uid: 81b39ababeaf43be8942b654275e5fe1 + id: 113 + position: [-28.5, -38.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 30 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_031.png + uid: e6c2abbf97914bf6bc5ebc8874fafffd + id: 114 + position: [-61.5, -55.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 32 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_030.png + uid: 74893ccd73614c91a36806f927423d78 + id: 115 + position: [-95.5, -71.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 31 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_037.png + uid: a6dfc3eeb0f34c5da6470ffc545755ed + id: 116 + position: [-128.5, -88.5] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 38 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_022.png + uid: 1d59fd6958ab47579b786da6c08f1a3f + id: 117 + position: [95.9465179, 30.9888229] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 23 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_023.png + uid: 4b4a69b0089e464596ecc779089602af + id: 118 + position: [68.4461136, 44.2444115] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 24 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_023.png + uid: 0d6cbb03f06540eb913c6cd66ac6f5ba + id: 119 + position: [66.4676666, 11.995739] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 24 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_044.png + uid: be8626864f5c48e7b7e60fbf9181e620 + id: 120 + position: [100.766998, 6.04500008] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 45 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: 446b1ef5445c466a86f97e305c12dc93 + id: 121 + position: [-253.18512, -14.0298166] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: 3ceb19b1609f4e9bb92df0a035904934 + id: 122 + position: [-221.640671, 2.443398] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: 3c4cf37eec42417ca8dd6abd21601311 + id: 123 + position: [-196.054626, 15.4116726] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: 6d35bade3dff40188afb99282edc94a4 + id: 124 + position: [-170.468536, 27.6789627] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: 1071051d54714904a018078e14dfbf9d + id: 125 + position: [-145.282059, 40.9676094] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: f765f75c483c4b5c81bdb15b2c5ff700 + id: 126 + position: [-119.188309, 53.8947716] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: 1864bb513b6e47fca816f03bb204c07a + id: 127 + position: [-93.8127518, 66.3431549] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: c982bb4b85a347d8b124d1a0fd922cfe + id: 128 + position: [-68.9159698, 79.2703552] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: 7425db5cd8e5484d849bf31bce798a67 + id: 129 + position: [-43.3010292, 92.197525] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_061.png + uid: 4f4dec982027487da6f0556fed8051f2 + id: 130 + position: [-16.7285137, 105.842873] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 62 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_015.png + uid: 2957588db3f443fc8a583aae4aee0707 + id: 131 + position: [-284.383118, 4.68400383] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 16 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_015.png + uid: d4d7d210151b48ec966df90b2d2ec14c + id: 132 + position: [-250.431122, 21.8027191] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 16 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_015.png + uid: 5fb7d971a0c448bdbee716899616149c + id: 133 + position: [-217.905701, 38.636116] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 16 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_014.png + uid: 8f4feabb8f4a4ae69118cbb0c37bd194 + id: 134 + position: [-184.809586, 55.7548294] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 15 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_015.png + uid: 19152cf672064c01b39b19ec8329c16b + id: 135 + position: [-151.142792, 71.1616669] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 16 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_015.png + uid: 740f68c1ab3b49a58fb17918098f0ae6 + id: 136 + position: [-116.620041, 88.2801971] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 16 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_015.png + uid: a4636904a9d04046ab2d9d9fd79684f6 + id: 137 + position: [-82.9532471, 104.25766] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 16 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_015.png + uid: 0f5d9d9f8c4248798a621087a612aa7c + id: 138 + position: [-52.7101898, 122.517609] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 16 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_065.png + uid: c9565d5e49994f2b9c0285f6924e81c3 + id: 139 + position: [-193.240005, -5.04500008] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 66 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_062.png + uid: f26efe24b9ea432895fdfa1dba30fc68 + id: 140 + position: [-120.778999, 32.2639999] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 63 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_082.png + uid: 14787a0a6a7c4344a8ab0016468354fd + id: 141 + position: [-158.194, 12.6339998] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 83 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_058.png + uid: ff92f17b4f864a98b6083e4ec813b46d + id: 142 + position: [-227.75, -54.2232857] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 59 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_045.png + uid: b33545748be34999aa0a69fbc08e2d91 + id: 143 + position: [-140.867996, -38.8449745] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 46 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_047.png + uid: b13d4cc28b544d5299d0bae06e5d9bf3 + id: 144 + position: [-91.4160004, -15.3730001] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 48 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_042.png + uid: 238a50ddf5944c3baad2000eae337f3e + id: 145 + position: [-188.693695, 27.3759041] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 43 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_052.png + uid: 1456e2eb4d7f4a5b951429a91ff8baf1 + id: 146 + position: [-21.875, 44.987999] + rotation: 0 + layer: 1 + visable: true + components: + - type: SpriteComponent + texture: 53 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_028.png + uid: bac54db03d8b4507a1138768db2ce2f1 + id: 147 + position: [-17.2237396, 138.836761] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 29 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_031.png + uid: 2e3e8e939e7e4758bd62d917f333c613 + id: 148 + position: [11.3386536, 120.830032] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 32 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_030.png + uid: 57d2d2102d15498e9582dbb80c5788a2 + id: 149 + position: [43.005661, 99.0977783] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 31 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_032.png + uid: 5f27a4cb3842436f9690d4ac80af91d9 + id: 150 + position: [74.6726685, 81.0910492] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 33 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_034.png + uid: 5530a0545f7e4e00993b81e777c46ab5 + id: 151 + position: [103.855988, 64.9470825] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 35 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_036.png + uid: 0688a67cff51416fab3f2d41af00cdaf + id: 152 + position: [132.418381, 49.4240456] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 37 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_040.png + uid: bdbb107bb2c947c4b718a0851cf03c4e + id: 153 + position: [18.733284, 155.827454] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 41 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_033.png + uid: aa2e13adf13745d2964c19166590cbeb + id: 154 + position: [45.8280487, 136.635315] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 34 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_027.png + uid: 56571e9c0f15495b8f6c6944173b38a5 + id: 155 + position: [76.3096619, 118.007668] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 28 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_031.png + uid: ad2e91976ba84154b6d0a43539e66398 + id: 156 + position: [107.920227, 104.460281] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 32 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_029.png + uid: 0c004f821f8c484f938c9745c09f9dd4 + id: 157 + position: [133.886047, 89.7839508] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 30 + normalMap: 0 + renderType: Lit + children: [] + - name: tile_032.png + uid: f781918d60874b868f1d4ae6ead18be6 + id: 158 + position: [168.318985, 68.3339233] + rotation: 0 + layer: 0 + visable: true + components: + - type: SpriteComponent + texture: 33 + normalMap: 0 + renderType: Lit + children: [] + - name: Animated + uid: 82b18591393b492fb65e99bd5a0e0aa6 + id: 159 + position: [-300.600006, -28] rotation: 0 layer: 1 visable: true components: - - type: SpriteComponent - texture: 46 - normalMap: 0 + - type: AnimationComponent + TextureUAID: 116 + TexelWidth: 32 + TexelHeight: 32 + FrameDuration: 0.100000001 + StartFrame: 0 + EndFrame: 120 renderType: Lit children: [] - - name: tile_044.png - uid: 40b88ad3429e42af94466d658a3ec42d - id: 117 - position: [8.5340004, 23.6730003] + - name: Music + uid: ebc9765f40964609a5e945417a02a7f3 + id: 160 + position: [0, 0] rotation: 0 - layer: 1 + layer: 0 visable: true components: - - type: SpriteComponent - texture: 45 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_049.png - uid: 8aeb05965e4d408b9456cb0f144cb118 - id: 118 - position: [-165.057999, -90.435997] - rotation: 0 - layer: 1 - visable: true - components: - - type: SpriteComponent - texture: 50 - normalMap: 0 - renderType: Lit - children: [] - - name: tile_053.png - uid: 0f6135a7c4dc4cca857bf16c080a3bce - id: 119 - position: [-58.2519989, 26.0020008] - rotation: 0 - layer: 1 - visable: true - components: - - type: SpriteComponent - texture: 54 - normalMap: 0 - renderType: Lit + - type: AudioPlayerComponent + uaid: 119 + volume: 1 + loop: true children: [] color_correction: brightness: 1 saturation: 1 gamma: 1 - bloom: false - intensity: 1.20000005 + bloom: true + intensity: 4 threshold: 1 Assets: + - uaid: 86 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_085.png + filename: tile_085.png + filetype: png + type: 0 + hash: c921026208aff689 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 27 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_026.png + filename: tile_026.png + filetype: png + type: 0 + hash: 455f9cc034a4e240 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 85 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_084.png + filename: tile_084.png + filetype: png + type: 0 + hash: a720f40abed06305 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 84 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_083.png + filename: tile_083.png + filetype: png + type: 0 + hash: 7e26027e93ae8665 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 83 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_082.png + filename: tile_082.png + filetype: png + type: 0 + hash: a7d389b57649b8c1 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 82 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_081.png + filename: tile_081.png + filetype: png + type: 0 + hash: e37d943f98df117c + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 81 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_080.png + filename: tile_080.png + filetype: png + type: 0 + hash: 24af11a711c4a405 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 80 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_079.png + filename: tile_079.png + filetype: png + type: 0 + hash: 6a517ee8c8a504b3 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 79 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_078.png + filename: tile_078.png + filetype: png + type: 0 + hash: 0c75dd1dfcb324e2 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 78 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_077.png + filename: tile_077.png + filetype: png + type: 0 + hash: 51e120ce40647450 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 77 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_076.png + filename: tile_076.png + filetype: png + type: 0 + hash: 414a4fc402bf8d9a + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 76 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_075.png + filename: tile_075.png + filetype: png + type: 0 + hash: 077768331bb39105 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 75 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_074.png + filename: tile_074.png + filetype: png + type: 0 + hash: 42121b492147d8fb + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 74 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_073.png + filename: tile_073.png + filetype: png + type: 0 + hash: 75748e5776001213 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 73 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_072.png + filename: tile_072.png + filetype: png + type: 0 + hash: cda73d6cbd54d108 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 72 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_071.png + filename: tile_071.png + filetype: png + type: 0 + hash: 07cff9b3939795f5 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 116 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\spritesheet.png + filename: spritesheet.png + filetype: png + type: 0 + hash: d178a6f5b597b470 + lastModified: 1728871741 + size: [352, 352] + channels: 4 + format: GL_RGBA + - uaid: 64 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_063.png + filename: tile_063.png + filetype: png + type: 0 + hash: 3f62dcdb053f6abe + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 60 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_059.png + filename: tile_059.png + filetype: png + type: 0 + hash: 8deb3108a6f2fd67 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 61 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_060.png + filename: tile_060.png + filetype: png + type: 0 + hash: 5871fcecf1d47e1c + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 62 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_061.png + filename: tile_061.png + filetype: png + type: 0 + hash: c8a1b22d67f32e16 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 63 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_062.png + filename: tile_062.png + filetype: png + type: 0 + hash: 54ba3afbbf9a9b9d + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 65 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_064.png + filename: tile_064.png + filetype: png + type: 0 + hash: dc1ce13185d6f9dd + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 66 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_065.png + filename: tile_065.png + filetype: png + type: 0 + hash: 70dd4177ac2aacd3 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 67 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_066.png + filename: tile_066.png + filetype: png + type: 0 + hash: 7fcc1e121b9c475a + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 68 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_067.png + filename: tile_067.png + filetype: png + type: 0 + hash: fb3139953ea9d8d1 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 69 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_068.png + filename: tile_068.png + filetype: png + type: 0 + hash: be2caa45ef20fd82 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 70 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_069.png + filename: tile_069.png + filetype: png + type: 0 + hash: 6cc14afc186ec771 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 71 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_070.png + filename: tile_070.png + filetype: png + type: 0 + hash: ee1ef8567b8a3df0 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 103 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_102.png + filename: tile_102.png + filetype: png + type: 0 + hash: ee4893b0b0e389b0 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 98 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_097.png + filename: tile_097.png + filetype: png + type: 0 + hash: 4140eb0e01c42458 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 95 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_094.png + filename: tile_094.png + filetype: png + type: 0 + hash: 26efe00187d8dde5 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 93 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_092.png + filename: tile_092.png + filetype: png + type: 0 + hash: d546c3d4f31aa5a0 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 92 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_091.png + filename: tile_091.png + filetype: png + type: 0 + hash: 2c31a5fc8d71be6e + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 97 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_096.png + filename: tile_096.png + filetype: png + type: 0 + hash: 61e5ba2ec5cc2e03 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 91 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_090.png + filename: tile_090.png + filetype: png + type: 0 + hash: 49ac491580bfc4f8 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 32 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_031.png + filename: tile_031.png + filetype: png + type: 0 + hash: 551fe37520f82310 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 96 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_095.png + filename: tile_095.png + filetype: png + type: 0 + hash: 2c4018746bda7639 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 90 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_089.png + filename: tile_089.png + filetype: png + type: 0 + hash: 7f30d8350216f6bb + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 31 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_030.png + filename: tile_030.png + filetype: png + type: 0 + hash: 2f6e1c7bd159e049 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 89 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_088.png + filename: tile_088.png + filetype: png + type: 0 + hash: a052591c3e581551 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 94 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_093.png + filename: tile_093.png + filetype: png + type: 0 + hash: fecc9a1f3e9802d8 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 29 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_028.png + filename: tile_028.png + filetype: png + type: 0 + hash: e7beb61a6e9cabf5 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 99 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_098.png + filename: tile_098.png + filetype: png + type: 0 + hash: f505363f6721ed43 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 100 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_099.png + filename: tile_099.png + filetype: png + type: 0 + hash: 64bc27961c23a597 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 101 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_100.png + filename: tile_100.png + filetype: png + type: 0 + hash: bce6842fe9a78d1e + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 102 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_101.png + filename: tile_101.png + filetype: png + type: 0 + hash: e5a269d460d00e69 + lastModified: 1728871746 + size: [32, 32] + channels: 4 + format: GL_RGBA - uaid: 115 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_114.png filename: tile_114.png @@ -557,7 +1594,7 @@ Assets: filetype: png type: 0 hash: dc8c15964e615c28 - lastModified: 1728871746 + lastModified: 1728871745 size: [32, 32] channels: 4 format: GL_RGBA @@ -577,7 +1614,7 @@ Assets: filetype: png type: 0 hash: 9559b168bb797f61 - lastModified: 1728871745 + lastModified: 1728871746 size: [32, 32] channels: 4 format: GL_RGBA @@ -587,7 +1624,7 @@ Assets: filetype: png type: 0 hash: 893cb7a825c3def2 - lastModified: 1728871745 + lastModified: 1728871746 size: [32, 32] channels: 4 format: GL_RGBA @@ -597,7 +1634,7 @@ Assets: filetype: png type: 0 hash: 2d73577cfe2985f8 - lastModified: 1728871745 + lastModified: 1728871746 size: [32, 32] channels: 4 format: GL_RGBA @@ -611,773 +1648,13 @@ Assets: size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 103 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_102.png - filename: tile_102.png - filetype: png - type: 0 - hash: ee4893b0b0e389b0 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 102 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_101.png - filename: tile_101.png - filetype: png - type: 0 - hash: e5a269d460d00e69 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 101 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_100.png - filename: tile_100.png - filetype: png - type: 0 - hash: bce6842fe9a78d1e - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 100 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_099.png - filename: tile_099.png - filetype: png - type: 0 - hash: 64bc27961c23a597 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 99 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_098.png - filename: tile_098.png - filetype: png - type: 0 - hash: f505363f6721ed43 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 98 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_097.png - filename: tile_097.png - filetype: png - type: 0 - hash: 4140eb0e01c42458 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 97 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_096.png - filename: tile_096.png - filetype: png - type: 0 - hash: 61e5ba2ec5cc2e03 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 96 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_095.png - filename: tile_095.png - filetype: png - type: 0 - hash: 2c4018746bda7639 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 95 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_094.png - filename: tile_094.png - filetype: png - type: 0 - hash: 26efe00187d8dde5 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 94 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_093.png - filename: tile_093.png - filetype: png - type: 0 - hash: fecc9a1f3e9802d8 - lastModified: 1728871746 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 93 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_092.png - filename: tile_092.png - filetype: png - type: 0 - hash: d546c3d4f31aa5a0 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 92 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_091.png - filename: tile_091.png - filetype: png - type: 0 - hash: 2c31a5fc8d71be6e - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 91 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_090.png - filename: tile_090.png - filetype: png - type: 0 - hash: 49ac491580bfc4f8 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 90 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_089.png - filename: tile_089.png - filetype: png - type: 0 - hash: 7f30d8350216f6bb - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 89 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_088.png - filename: tile_088.png - filetype: png - type: 0 - hash: a052591c3e581551 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 88 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_087.png - filename: tile_087.png - filetype: png - type: 0 - hash: b5be37e278b5a0e8 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 87 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_086.png - filename: tile_086.png - filetype: png - type: 0 - hash: 405549c9596a8b02 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 86 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_085.png - filename: tile_085.png - filetype: png - type: 0 - hash: c921026208aff689 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 85 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_084.png - filename: tile_084.png - filetype: png - type: 0 - hash: a720f40abed06305 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 84 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_083.png - filename: tile_083.png - filetype: png - type: 0 - hash: 7e26027e93ae8665 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 83 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_082.png - filename: tile_082.png - filetype: png - type: 0 - hash: a7d389b57649b8c1 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 82 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_081.png - filename: tile_081.png - filetype: png - type: 0 - hash: e37d943f98df117c - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 81 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_080.png - filename: tile_080.png - filetype: png - type: 0 - hash: 24af11a711c4a405 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 80 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_079.png - filename: tile_079.png - filetype: png - type: 0 - hash: 6a517ee8c8a504b3 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 79 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_078.png - filename: tile_078.png - filetype: png - type: 0 - hash: 0c75dd1dfcb324e2 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 78 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_077.png - filename: tile_077.png - filetype: png - type: 0 - hash: 51e120ce40647450 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 77 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_076.png - filename: tile_076.png - filetype: png - type: 0 - hash: 414a4fc402bf8d9a - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 76 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_075.png - filename: tile_075.png - filetype: png - type: 0 - hash: 077768331bb39105 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 75 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_074.png - filename: tile_074.png - filetype: png - type: 0 - hash: 42121b492147d8fb - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 74 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_073.png - filename: tile_073.png - filetype: png - type: 0 - hash: 75748e5776001213 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 73 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_072.png - filename: tile_072.png - filetype: png - type: 0 - hash: cda73d6cbd54d108 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 72 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_071.png - filename: tile_071.png - filetype: png - type: 0 - hash: 07cff9b3939795f5 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 71 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_070.png - filename: tile_070.png - filetype: png - type: 0 - hash: ee1ef8567b8a3df0 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 70 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_069.png - filename: tile_069.png - filetype: png - type: 0 - hash: 6cc14afc186ec771 - lastModified: 1728871745 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 69 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_068.png - filename: tile_068.png - filetype: png - type: 0 - hash: be2caa45ef20fd82 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 68 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_067.png - filename: tile_067.png - filetype: png - type: 0 - hash: fb3139953ea9d8d1 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 67 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_066.png - filename: tile_066.png - filetype: png - type: 0 - hash: 7fcc1e121b9c475a - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 66 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_065.png - filename: tile_065.png - filetype: png - type: 0 - hash: 70dd4177ac2aacd3 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 65 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_064.png - filename: tile_064.png - filetype: png - type: 0 - hash: dc1ce13185d6f9dd - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 64 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_063.png - filename: tile_063.png - filetype: png - type: 0 - hash: 3f62dcdb053f6abe - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 63 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_062.png - filename: tile_062.png - filetype: png - type: 0 - hash: 54ba3afbbf9a9b9d - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 62 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_061.png - filename: tile_061.png - filetype: png - type: 0 - hash: c8a1b22d67f32e16 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 61 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_060.png - filename: tile_060.png - filetype: png - type: 0 - hash: 5871fcecf1d47e1c - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 60 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_059.png - filename: tile_059.png - filetype: png - type: 0 - hash: 8deb3108a6f2fd67 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 29 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_028.png - filename: tile_028.png - filetype: png - type: 0 - hash: e7beb61a6e9cabf5 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 28 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_027.png - filename: tile_027.png - filetype: png - type: 0 - hash: 82735e0fe1556323 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 27 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_026.png - filename: tile_026.png - filetype: png - type: 0 - hash: 455f9cc034a4e240 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 26 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_025.png - filename: tile_025.png - filetype: png - type: 0 - hash: 59f5a825963b4b58 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 25 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_024.png - filename: tile_024.png - filetype: png - type: 0 - hash: 52d6f7a1f1aaf096 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 24 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_023.png - filename: tile_023.png - filetype: png - type: 0 - hash: ca52dd2852403677 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 23 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_022.png - filename: tile_022.png - filetype: png - type: 0 - hash: 2217b4ba2738d800 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 22 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_021.png - filename: tile_021.png - filetype: png - type: 0 - hash: a2b2f33d53eafbe1 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 21 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_020.png - filename: tile_020.png - filetype: png - type: 0 - hash: 9ab8e82f77ecda85 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 20 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_019.png - filename: tile_019.png - filetype: png - type: 0 - hash: f4d73b8ef85ddfbf - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 19 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_018.png - filename: tile_018.png - filetype: png - type: 0 - hash: 2f4aa3d6c9a88136 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 18 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_017.png - filename: tile_017.png - filetype: png - type: 0 - hash: 32c7b5c15559556f - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 17 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_016.png - filename: tile_016.png - filetype: png - type: 0 - hash: d66738b42167c25b - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 16 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_015.png - filename: tile_015.png - filetype: png - type: 0 - hash: dfbb87d88e7b361a - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 15 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_014.png - filename: tile_014.png - filetype: png - type: 0 - hash: e9c9d0a81a34e191 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 14 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_013.png - filename: tile_013.png - filetype: png - type: 0 - hash: be9b2566c79ca9e3 - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 1 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_000.png - filename: tile_000.png - filetype: png - type: 0 - hash: 43b1a791b2f610aa - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 2 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_001.png - filename: tile_001.png - filetype: png - type: 0 - hash: 58e2a6949c806ed4 - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 3 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_002.png - filename: tile_002.png - filetype: png - type: 0 - hash: 9d00d31c498403a5 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 4 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_003.png - filename: tile_003.png - filetype: png - type: 0 - hash: 2ce62d3fa5f83a85 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 5 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_004.png - filename: tile_004.png - filetype: png - type: 0 - hash: 15054cba03033497 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 6 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_005.png - filename: tile_005.png - filetype: png - type: 0 - hash: 75d134cdb99c01b0 - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 7 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_006.png - filename: tile_006.png - filetype: png - type: 0 - hash: 977d38606f54ec1a - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 8 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_007.png - filename: tile_007.png - filetype: png - type: 0 - hash: acc98f6bf6af4471 - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 9 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_008.png - filename: tile_008.png - filetype: png - type: 0 - hash: e38d301f66207712 - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 10 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_009.png - filename: tile_009.png - filetype: png - type: 0 - hash: 0ea909aad0cb11d5 - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 11 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_010.png - filename: tile_010.png - filetype: png - type: 0 - hash: 027bca2fa1b70126 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 12 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_011.png - filename: tile_011.png - filetype: png - type: 0 - hash: 0c92bd2b1322d0e7 - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 13 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_012.png - filename: tile_012.png - filetype: png - type: 0 - hash: 32bf6597d4a096f7 - lastModified: 1728871741 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 30 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_029.png - filename: tile_029.png - filetype: png - type: 0 - hash: 3d1f20d336f5a0e4 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 31 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_030.png - filename: tile_030.png - filetype: png - type: 0 - hash: 2f6e1c7bd159e049 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 32 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_031.png - filename: tile_031.png - filetype: png - type: 0 - hash: 551fe37520f82310 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - uaid: 33 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_032.png filename: tile_032.png filetype: png type: 0 hash: ab38b324f6e3068e - lastModified: 1728871743 + lastModified: 1728871742 size: [32, 32] channels: 4 format: GL_RGBA @@ -1387,7 +1664,7 @@ Assets: filetype: png type: 0 hash: 9bc4f952ca3d6104 - lastModified: 1728871742 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA @@ -1397,7 +1674,7 @@ Assets: filetype: png type: 0 hash: 4c68d41935c4c205 - lastModified: 1728871743 + lastModified: 1728871742 size: [32, 32] channels: 4 format: GL_RGBA @@ -1421,103 +1698,43 @@ Assets: size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 38 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_037.png - filename: tile_037.png + - uaid: 7 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_006.png + filename: tile_006.png filetype: png type: 0 - hash: b02749d8ee945f27 - lastModified: 1728871743 + hash: 977d38606f54ec1a + lastModified: 1728871741 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 39 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_038.png - filename: tile_038.png + - uaid: 8 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_007.png + filename: tile_007.png filetype: png type: 0 - hash: 835f3dbf895d2518 + hash: acc98f6bf6af4471 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 30 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_029.png + filename: tile_029.png + filetype: png + type: 0 + hash: 3d1f20d336f5a0e4 lastModified: 1728871742 size: [32, 32] channels: 4 format: GL_RGBA - - uaid: 40 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_039.png - filename: tile_039.png - filetype: png - type: 0 - hash: d35fb51aa3acdc47 - lastModified: 1728871742 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 41 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_040.png - filename: tile_040.png - filetype: png - type: 0 - hash: 56430e898f7e9789 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 42 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_041.png - filename: tile_041.png - filetype: png - type: 0 - hash: 279113f5a4cbbc98 - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 43 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_042.png - filename: tile_042.png - filetype: png - type: 0 - hash: 00a8e91ac50d0582 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 44 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_043.png - filename: tile_043.png - filetype: png - type: 0 - hash: 49e0ee588a2d510c - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 45 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_044.png - filename: tile_044.png - filetype: png - type: 0 - hash: cc99aeb78832013d - lastModified: 1728871744 - size: [32, 32] - channels: 4 - format: GL_RGBA - - uaid: 46 - path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_045.png - filename: tile_045.png - filetype: png - type: 0 - hash: a42f65407bd8d9c8 - lastModified: 1728871743 - size: [32, 32] - channels: 4 - format: GL_RGBA - uaid: 47 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_046.png filename: tile_046.png filetype: png type: 0 hash: a6ce3c9db850be68 - lastModified: 1728871743 + lastModified: 1728871744 size: [32, 32] channels: 4 format: GL_RGBA @@ -1537,7 +1754,7 @@ Assets: filetype: png type: 0 hash: 7d5264eea52a6006 - lastModified: 1728871743 + lastModified: 1728871744 size: [32, 32] channels: 4 format: GL_RGBA @@ -1571,6 +1788,16 @@ Assets: size: [32, 32] channels: 4 format: GL_RGBA + - uaid: 24 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_023.png + filename: tile_023.png + filetype: png + type: 0 + hash: ca52dd2852403677 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA - uaid: 53 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_052.png filename: tile_052.png @@ -1581,12 +1808,112 @@ Assets: size: [32, 32] channels: 4 format: GL_RGBA + - uaid: 9 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_008.png + filename: tile_008.png + filetype: png + type: 0 + hash: e38d301f66207712 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 38 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_037.png + filename: tile_037.png + filetype: png + type: 0 + hash: b02749d8ee945f27 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 10 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_009.png + filename: tile_009.png + filetype: png + type: 0 + hash: 0ea909aad0cb11d5 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 39 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_038.png + filename: tile_038.png + filetype: png + type: 0 + hash: 835f3dbf895d2518 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 11 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_010.png + filename: tile_010.png + filetype: png + type: 0 + hash: 027bca2fa1b70126 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 40 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_039.png + filename: tile_039.png + filetype: png + type: 0 + hash: d35fb51aa3acdc47 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 12 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_011.png + filename: tile_011.png + filetype: png + type: 0 + hash: 0c92bd2b1322d0e7 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 41 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_040.png + filename: tile_040.png + filetype: png + type: 0 + hash: 56430e898f7e9789 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA - uaid: 54 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_053.png filename: tile_053.png filetype: png type: 0 hash: 7b09d94969ebc484 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 13 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_012.png + filename: tile_012.png + filetype: png + type: 0 + hash: 32bf6597d4a096f7 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 42 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_041.png + filename: tile_041.png + filetype: png + type: 0 + hash: 279113f5a4cbbc98 lastModified: 1728871744 size: [32, 32] channels: 4 @@ -1597,7 +1924,17 @@ Assets: filetype: png type: 0 hash: f4cb8b97cee3bb7c - lastModified: 1728871744 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 43 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_042.png + filename: tile_042.png + filetype: png + type: 0 + hash: 00a8e91ac50d0582 + lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA @@ -1607,6 +1944,16 @@ Assets: filetype: png type: 0 hash: 7456f3530ede598b + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 44 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_043.png + filename: tile_043.png + filetype: png + type: 0 + hash: 49e0ee588a2d510c lastModified: 1728871743 size: [32, 32] channels: 4 @@ -1617,10 +1964,50 @@ Assets: filetype: png type: 0 hash: 54c17c59498db1fc + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 45 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_044.png + filename: tile_044.png + filetype: png + type: 0 + hash: cc99aeb78832013d + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 46 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_045.png + filename: tile_045.png + filetype: png + type: 0 + hash: a42f65407bd8d9c8 lastModified: 1728871743 size: [32, 32] channels: 4 format: GL_RGBA + - uaid: 25 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_024.png + filename: tile_024.png + filetype: png + type: 0 + hash: 52d6f7a1f1aaf096 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 88 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_087.png + filename: tile_087.png + filetype: png + type: 0 + hash: b5be37e278b5a0e8 + lastModified: 1728871744 + size: [32, 32] + channels: 4 + format: GL_RGBA - uaid: 58 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_057.png filename: tile_057.png @@ -1631,6 +2018,23 @@ Assets: size: [32, 32] channels: 4 format: GL_RGBA + - uaid: 117 + path: C:\Users\spenc\Music\creative-technology-showreel-241274.mp3 + filename: creative-technology-showreel-241274.mp3 + filetype: mp3 + type: 1 + hash: d7f8e8b2954d438f + lastModified: 1730076791 + - uaid: 26 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_025.png + filename: tile_025.png + filetype: png + type: 0 + hash: 59f5a825963b4b58 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA - uaid: 59 path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_058.png filename: tile_058.png @@ -1640,4 +2044,226 @@ Assets: lastModified: 1728871743 size: [32, 32] channels: 4 + format: GL_RGBA + - uaid: 118 + path: C:\Users\spenc\Music\ethereal-vistas-191254.mp3 + filename: ethereal-vistas-191254.mp3 + filetype: mp3 + type: 1 + hash: 0da03a50fc5a40a8 + lastModified: 1735362077 + - uaid: 87 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_086.png + filename: tile_086.png + filetype: png + type: 0 + hash: 405549c9596a8b02 + lastModified: 1728871745 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 28 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_027.png + filename: tile_027.png + filetype: png + type: 0 + hash: 82735e0fe1556323 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 1 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_000.png + filename: tile_000.png + filetype: png + type: 0 + hash: 43b1a791b2f610aa + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 119 + path: C:\Users\spenc\Music\good-night-lofi-cozy-chill-music-160166.mp3 + filename: good-night-lofi-cozy-chill-music-160166.mp3 + filetype: mp3 + type: 1 + hash: 246561eaa4e21fad + lastModified: 1735362096 + - uaid: 2 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_001.png + filename: tile_001.png + filetype: png + type: 0 + hash: 58e2a6949c806ed4 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 120 + path: C:\Users\spenc\Music\reflected-light-147979.mp3 + filename: reflected-light-147979.mp3 + filetype: mp3 + type: 1 + hash: b4d344d1f668e25d + lastModified: 1735362210 + - uaid: 3 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_002.png + filename: tile_002.png + filetype: png + type: 0 + hash: 9d00d31c498403a5 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 121 + path: C:\Users\spenc\Music\simple-notification-152054.mp3 + filename: simple-notification-152054.mp3 + filetype: mp3 + type: 1 + hash: 3e57c2530f08c1ab + lastModified: 1745951639 + - uaid: 4 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_003.png + filename: tile_003.png + filetype: png + type: 0 + hash: 2ce62d3fa5f83a85 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 122 + path: C:\Users\spenc\Music\simple-notification-152054.wav + filename: simple-notification-152054.wav + filetype: wav + type: 1 + hash: 0f5adca8b95e7494 + lastModified: 1745953000 + - uaid: 6 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_005.png + filename: tile_005.png + filetype: png + type: 0 + hash: 75d134cdb99c01b0 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 5 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_004.png + filename: tile_004.png + filetype: png + type: 0 + hash: 15054cba03033497 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 123 + path: C:\Users\spenc\Music\Stereo Test - LeftRight Audio Test for HeadphonesSpeakers.mp3 + filename: Stereo Test - LeftRight Audio Test for HeadphonesSpeakers.mp3 + filetype: mp3 + type: 1 + hash: 5885c8cc38709f22 + lastModified: 1746052188 + - uaid: 23 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_022.png + filename: tile_022.png + filetype: png + type: 0 + hash: 2217b4ba2738d800 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 22 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_021.png + filename: tile_021.png + filetype: png + type: 0 + hash: a2b2f33d53eafbe1 + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 21 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_020.png + filename: tile_020.png + filetype: png + type: 0 + hash: 9ab8e82f77ecda85 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 20 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_019.png + filename: tile_019.png + filetype: png + type: 0 + hash: f4d73b8ef85ddfbf + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 19 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_018.png + filename: tile_018.png + filetype: png + type: 0 + hash: 2f4aa3d6c9a88136 + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 18 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_017.png + filename: tile_017.png + filetype: png + type: 0 + hash: 32c7b5c15559556f + lastModified: 1728871743 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 17 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_016.png + filename: tile_016.png + filetype: png + type: 0 + hash: d66738b42167c25b + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 16 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_015.png + filename: tile_015.png + filetype: png + type: 0 + hash: dfbb87d88e7b361a + lastModified: 1728871742 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 15 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_014.png + filename: tile_014.png + filetype: png + type: 0 + hash: e9c9d0a81a34e191 + lastModified: 1728871741 + size: [32, 32] + channels: 4 + format: GL_RGBA + - uaid: 14 + path: C:\Users\spenc\OneDrive\Pictures\isometric tileset\separated images\tile_013.png + filename: tile_013.png + filetype: png + type: 0 + hash: be9b2566c79ca9e3 + lastModified: 1728871742 + size: [32, 32] + channels: 4 format: GL_RGBA \ No newline at end of file diff --git a/src/src/Components/AnimationComponent.cpp b/src/src/Components/AnimationComponent.cpp index cfaa4f3..5b4b977 100644 --- a/src/src/Components/AnimationComponent.cpp +++ b/src/src/Components/AnimationComponent.cpp @@ -15,14 +15,14 @@ void AnimationComponent::SetTextureAtlas(uint64_t uaid, int texelWidth, int texe { textureUAID = uaid; - const auto* asset = AssetManager::GetAssetByID(uaid); + const auto *asset = AssetManager::GetAssetByID(uaid); if (!asset || !asset->loaded) { Logger::LogError("SetTextureAtlas: Asset not found or not loaded (UAID: %llu)", uaid); return; } - const auto* imageAsset = dynamic_cast(asset); + const auto *imageAsset = dynamic_cast(asset); if (!imageAsset) { Logger::LogError("SetTextureAtlas: Asset with UAID %llu is not an image", uaid); @@ -68,7 +68,6 @@ void AnimationComponent::SetTextureAtlas(uint64_t uaid, int texelWidth, int texe renderType = RenderType::Unlit; } - void AnimationComponent::Play() { playing = true; } void AnimationComponent::Stop() { playing = false; } void AnimationComponent::SetLooping(bool loop_) { loop = loop_; } @@ -139,6 +138,8 @@ void AnimationComponent::Save(YAML::Emitter &out) const out << YAML::Key << "FrameDuration" << YAML::Value << frameDuration; out << YAML::Key << "StartFrame" << YAML::Value << startFrame; out << YAML::Key << "EndFrame" << YAML::Value << endFrame; + out << YAML::Key << "renderType" << YAML::Value << (renderType == RenderType::Lit ? "Lit" : "Unlit"); + out << YAML::EndMap; } @@ -151,6 +152,19 @@ void AnimationComponent::Load(const YAML::Node &node) float duration = node["FrameDuration"].as(); int start = node["StartFrame"] ? node["StartFrame"].as() : 0; int end = node["EndFrame"] ? node["EndFrame"].as() : 0; + + if (node["renderType"] && node["renderType"].IsScalar()) + { + std::string typeStr = node["renderType"].as(); + if (typeStr == "Lit") + renderType = RenderType::Lit; + else if (typeStr == "Unlit") + renderType = RenderType::Unlit; + else + RecoverableError("Invalid 'renderType' value in AnimationComponent: " + typeStr, + Create::Exceptions::InvalidFormat) + .Handle(); + } SetTextureAtlas(uaid, texelWidth, texelHeight, duration, start, end); } diff --git a/src/src/Components/AnimationComponent.h b/src/src/Components/AnimationComponent.h index 25cd067..681e815 100644 --- a/src/src/Components/AnimationComponent.h +++ b/src/src/Components/AnimationComponent.h @@ -52,13 +52,18 @@ public: uint64_t GetTextureUAID() const; void SetTextureUAID(uint64_t uaid); + + void SetRenderType(RenderType type) { renderType = type; } + RenderType GetRenderType() const { return renderType; } + + // Timing float GetFrameDuration() const; void SetFrameDuration(float duration); // Access atlas - TextureAtlas* GetAtlas(); - const TextureAtlas* GetAtlas() const; + TextureAtlas *GetAtlas(); + const TextureAtlas *GetAtlas() const; // Update per tick void Update(float dt); @@ -68,7 +73,6 @@ public: void Save(YAML::Emitter &out) const override; void Load(const YAML::Node &node) override; - RenderType renderType; private: std::shared_ptr texture; @@ -90,4 +94,9 @@ private: float speed = 1.0f; uint64_t textureUAID = 0; + + RenderType renderType; + + + }; diff --git a/src/src/Engine.cpp b/src/src/Engine.cpp index b342be8..6a96127 100644 --- a/src/src/Engine.cpp +++ b/src/src/Engine.cpp @@ -12,6 +12,8 @@ #include "core/utils/FileDialog.h" #include "core/utils/Logging.h" +#include "core/utils/Input.h" + #include "core/audio/AudioEngine.h" @@ -21,6 +23,7 @@ #include "core/utils/utils.h" #include "core/utils/LoadingWindow.h" + #include "editor/windows/AssetBrowser.h" #include "editor/windows/Inspector.h" #include "editor/windows/AudioInfo.h" @@ -30,6 +33,9 @@ #include #include #include +#include "ImGuizmo.h" +#include + #include #include @@ -432,6 +438,53 @@ void ShowColorCorrectionWindow() ImGui::End(); } + + + + + +void DrawGizmoForObject(const std::shared_ptr& obj, const glm::mat4& view, const glm::mat4& projection) +{ + if (!obj) + return; + + glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(obj->GetLocalPosition(), 0.0f)); + + model = glm::rotate(model, obj->GetLocalRotation(), glm::vec3(0.0f, 0.0f, 1.0f)); + + // Setup ImGuizmo + ImGuizmo::SetOrthographic(false); + ImGuizmo::SetDrawlist(); + + ImVec2 windowPos = ImGui::GetWindowPos(); + ImVec2 windowSize = ImGui::GetWindowSize(); + ImGuizmo::SetRect(windowPos.x, windowPos.y, windowSize.x, windowSize.y); + + static ImGuizmo::OPERATION operation = ImGuizmo::TRANSLATE; + if (ImGui::IsKeyPressed(ImGuiKey_T)) operation = ImGuizmo::TRANSLATE; + if (ImGui::IsKeyPressed(ImGuiKey_R)) operation = ImGuizmo::ROTATE; + + glm::mat4 manipulated = model; + ImGuizmo::Manipulate(glm::value_ptr(view), glm::value_ptr(projection), + operation, ImGuizmo::LOCAL, glm::value_ptr(manipulated)); + + if (ImGuizmo::IsUsing()) + { + glm::vec3 translation, rotation, dummyScale; + ImGuizmo::DecomposeMatrixToComponents(glm::value_ptr(manipulated), + glm::value_ptr(translation), + glm::value_ptr(rotation), + glm::value_ptr(dummyScale)); + + obj->SetLocalPosition(translation); + obj->SetLocalRotation(rotation.z); + } +} + + + + + void Engine::Init() { @@ -523,6 +576,12 @@ void Engine::Init() AudioEngine::Init(); + + Logger::LogVerbose("Init Input Core"); + + Input::Init(window); + + // AssetManager::LoadAssetAsync("C:\\Users\\spenc\\Music\\creative-technology-showreel-241274.mp3", AssetType::Audio); Logger::LogVerbose("Resverving Objects"); @@ -624,6 +683,8 @@ void Engine::Run() glfwPollEvents(); profiler.EndEngineSection(); + Input::Update(); + profiler.BeginEngineSection("NewFrame"); profiler.BeginEngineSection("ImGui_ImplOpenGL3_NewFrame"); @@ -1197,6 +1258,19 @@ void Engine::Run() previewUAID = 0; } + + glm::mat4 projection = glm::ortho( + 0.0f, static_cast(size.x), // left, right + static_cast(size.y), 0.0f, // bottom, top (y-down) + -1.0f, 1.0f // near, far + ); + + glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(-cameraPos, 0.0f)); + + + DrawGizmoForObject(selected, view, projection); + + ImGui::End(); profiler.EndEngineSection(); @@ -1250,7 +1324,7 @@ void Engine::Run() } } -void Engine::DrawObjectNode(const std::shared_ptr& obj) +void Engine::DrawObjectNode(const std::shared_ptr &obj) { if (!obj) return; @@ -1262,7 +1336,7 @@ void Engine::DrawObjectNode(const std::shared_ptr& obj) ImGuiTreeNodeFlags_DefaultOpen | (obj == selected ? ImGuiTreeNodeFlags_Selected : 0); - bool open = ImGui::TreeNodeEx((void*)(intptr_t)obj->uid.id, flags, "%s", obj->GetName().c_str()); + bool open = ImGui::TreeNodeEx((void *)(intptr_t)obj->uid.id, flags, "%s", obj->GetName().c_str()); if (ImGui::IsItemClicked()) selected = obj; @@ -1293,12 +1367,12 @@ void Engine::DrawObjectNode(const std::shared_ptr& obj) { if (auto payload = ImGui::AcceptDragDropPayload("OBJECT")) { - auto dragged = *static_cast*>(payload->Data); + auto dragged = *static_cast *>(payload->Data); if (dragged && dragged != obj) { bool valid = true; - for (Object* a = obj.get(); a; a = a->GetParent()) + for (Object *a = obj.get(); a; a = a->GetParent()) if (a == dragged.get()) { valid = false; @@ -1311,12 +1385,10 @@ void Engine::DrawObjectNode(const std::shared_ptr& obj) oldP->RemoveChild(dragged.get()); else objects.erase(std::remove(objects.begin(), objects.end(), dragged), objects.end()); - obj->AddChild(dragged); dragged->SetWorldPosition( - dragged->GetWorldPosition() - obj->GetWorldPosition() - ); + dragged->GetWorldPosition() - obj->GetWorldPosition()); } } } @@ -1325,15 +1397,13 @@ void Engine::DrawObjectNode(const std::shared_ptr& obj) if (open) { - for (auto& child : obj->GetChildren()) + for (auto &child : obj->GetChildren()) if (child) DrawObjectNode(child); ImGui::TreePop(); } } - - bool VerifySceneHash(const YAML::Node &root) { if (!root["scene_hash"] || !root["objects"]) diff --git a/src/src/Renderer.cpp b/src/src/Renderer.cpp index 22962c2..ea60596 100644 --- a/src/src/Renderer.cpp +++ b/src/src/Renderer.cpp @@ -683,18 +683,25 @@ void Renderer::DrawAnimator(const AnimationComponent *anim, const core::types::V entry.rotationRad = 0.0f; entry.textureID = tex->GetID(); entry.normalMapID = defaultNormalMap; - entry.renderType = anim->renderType; + entry.renderType = anim->GetRenderType(); entry.sprite = nullptr; entry.texCoords = glm::vec4(uvMin.x, uvMin.y, uvMax.x, uvMax.y); + + SortedDrawEntry drawEntry; drawEntry.sprite = entry; - drawEntry.shader = &unlitShader; - drawEntry.useLighting = false; + drawEntry.shader = (g_engineConfig.settings.lighting_enabled && entry.renderType == RenderType::Lit) + ? &spriteShader + : &unlitShader; + drawEntry.useLighting = (drawEntry.shader == &spriteShader); + drawEntry.usesUV = true; sortedDrawList.push_back(drawEntry); } + + void Renderer::FlushQuads() { PROFILE_ENGINE_SCOPE("Renderer::FlushQuads"); diff --git a/src/src/core/utils/input.cpp b/src/src/core/utils/input.cpp index c9d25e2..96ce08f 100644 --- a/src/src/core/utils/input.cpp +++ b/src/src/core/utils/input.cpp @@ -1,20 +1,62 @@ #include "input.h" +#include "Logging.h" +#include "Profiler.h" -#include -#include - -extern GLFWwindow* window; - -namespace Input +void Input::Init(GLFWwindow* window) { - bool IsKeyDown(Keycode key) - { - return glfwGetKey(window, static_cast(key)) == GLFW_PRESS; - } - - core::types::Vec2 GetMousePosition() - { - ImVec2 p = ImGui::GetMousePos(); - return core::types::Vec2 { p.x, p.y }; - } + s_Window = window; + Logger::LogOk("Input Core"); +} + +void Input::Update() +{ + PROFILE_ENGINE_SCOPE("Input::Update"); + + std::copy(std::begin(s_KeysCurrent), std::end(s_KeysCurrent), s_KeysPrevious); + std::copy(std::begin(s_MouseCurrent), std::end(s_MouseCurrent), s_MousePrevious); + + for (int key = 0; key <= GLFW_KEY_LAST; ++key) + s_KeysCurrent[key] = glfwGetKey(s_Window, key) == GLFW_PRESS; + + for (int button = 0; button <= GLFW_MOUSE_BUTTON_LAST; ++button) + s_MouseCurrent[button] = glfwGetMouseButton(s_Window, button) == GLFW_PRESS; +} + +bool Input::IsKeyDown(Keycode key) +{ + return s_KeysCurrent[static_cast(key)]; +} + +bool Input::IsKeyPressed(Keycode key) +{ + int k = static_cast(key); + return s_KeysCurrent[k] && !s_KeysPrevious[k]; +} + +bool Input::IsKeyReleased(Keycode key) +{ + int k = static_cast(key); + return !s_KeysCurrent[k] && s_KeysPrevious[k]; +} + +bool Input::IsMouseButtonDown(int button) +{ + return s_MouseCurrent[button]; +} + +bool Input::IsMouseButtonPressed(int button) +{ + return s_MouseCurrent[button] && !s_MousePrevious[button]; +} + +bool Input::IsMouseButtonReleased(int button) +{ + return !s_MouseCurrent[button] && s_MousePrevious[button]; +} + +core::types::Vec2 Input::GetMousePosition() +{ + double x, y; + glfwGetCursorPos(s_Window, &x, &y); + return { static_cast(x), static_cast(y) }; } diff --git a/src/src/core/utils/input.h b/src/src/core/utils/input.h index 79a494f..473078e 100644 --- a/src/src/core/utils/input.h +++ b/src/src/core/utils/input.h @@ -2,9 +2,32 @@ #include "keycode.h" #include "../types/vec2.h" +#include +#include -namespace Input + +class Input { - bool IsKeyDown(Keycode key); - core::types::Vec2 GetMousePosition(); -} +public: + static void Init(GLFWwindow* window); + static void Update(); + + static bool IsKeyDown(Keycode key); + static bool IsKeyPressed(Keycode key); + static bool IsKeyReleased(Keycode key); + + static bool IsMouseButtonDown(int button); + static bool IsMouseButtonPressed(int button); + static bool IsMouseButtonReleased(int button); + + static core::types::Vec2 GetMousePosition(); + +private: + static inline GLFWwindow* s_Window = nullptr; + + static inline bool s_KeysCurrent[GLFW_KEY_LAST + 1]{}; + static inline bool s_KeysPrevious[GLFW_KEY_LAST + 1]{}; + + static inline bool s_MouseCurrent[GLFW_MOUSE_BUTTON_LAST + 1]{}; + static inline bool s_MousePrevious[GLFW_MOUSE_BUTTON_LAST + 1]{}; +}; diff --git a/src/src/editor/windows/Inspector.cpp b/src/src/editor/windows/Inspector.cpp index 1c286e3..d4bc323 100644 --- a/src/src/editor/windows/Inspector.cpp +++ b/src/src/editor/windows/Inspector.cpp @@ -278,6 +278,11 @@ void DrawInspectorUI(std::shared_ptr selected) { ImGui::SeparatorText("Animation Component"); + const char *renderTypes[] = {"Unlit", "Lit"}; + int currentTypeIndex = static_cast(anim->GetRenderType()); + if (ImGui::Combo("Render Type", ¤tTypeIndex, renderTypes, IM_ARRAYSIZE(renderTypes))) + anim->SetRenderType(static_cast(currentTypeIndex)); + static int frameWidth = anim->GetAtlas()->frameWidth; static int frameHeight = anim->GetAtlas()->frameHeight; static float frameDuration = anim->GetFrameDuration(); diff --git a/src/vendor/imguizmo/ImGuizmo.cpp b/src/vendor/imguizmo/ImGuizmo.cpp new file mode 100644 index 0000000..5f848c7 --- /dev/null +++ b/src/vendor/imguizmo/ImGuizmo.cpp @@ -0,0 +1,3151 @@ +// https://github.com/CedricGuillemet/ImGuizmo +// v1.91.3 WIP +// +// The MIT License(MIT) +// +// Copyright(c) 2021 Cedric Guillemet +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include "imgui.h" +#include "imgui_internal.h" +#include "ImGuizmo.h" + +#if defined(_MSC_VER) || defined(__MINGW32__) +#include +#endif +#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR) +#define _malloca(x) alloca(x) +#define _freea(x) +#endif + +// includes patches for multiview from +// https://github.com/CedricGuillemet/ImGuizmo/issues/15 + +namespace IMGUIZMO_NAMESPACE +{ + static const float ZPI = 3.14159265358979323846f; + static const float RAD2DEG = (180.f / ZPI); + static const float DEG2RAD = (ZPI / 180.f); + const float screenRotateSize = 0.06f; + // scale a bit so translate axis do not touch when in universal + const float rotationDisplayFactor = 1.2f; + + static OPERATION operator&(OPERATION lhs, OPERATION rhs) + { + return static_cast(static_cast(lhs) & static_cast(rhs)); + } + + static bool operator!=(OPERATION lhs, int rhs) + { + return static_cast(lhs) != rhs; + } + + static bool Intersects(OPERATION lhs, OPERATION rhs) + { + return (lhs & rhs) != 0; + } + + // True if lhs contains rhs + static bool Contains(OPERATION lhs, OPERATION rhs) + { + return (lhs & rhs) == rhs; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // utility and math + + void FPU_MatrixF_x_MatrixF(const float* a, const float* b, float* r) + { + r[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12]; + r[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13]; + r[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14]; + r[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15]; + + r[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12]; + r[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13]; + r[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14]; + r[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15]; + + r[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12]; + r[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13]; + r[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14]; + r[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15]; + + r[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12]; + r[13] = a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13]; + r[14] = a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14]; + r[15] = a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15]; + } + + void Frustum(float left, float right, float bottom, float top, float znear, float zfar, float* m16) + { + float temp, temp2, temp3, temp4; + temp = 2.0f * znear; + temp2 = right - left; + temp3 = top - bottom; + temp4 = zfar - znear; + m16[0] = temp / temp2; + m16[1] = 0.0; + m16[2] = 0.0; + m16[3] = 0.0; + m16[4] = 0.0; + m16[5] = temp / temp3; + m16[6] = 0.0; + m16[7] = 0.0; + m16[8] = (right + left) / temp2; + m16[9] = (top + bottom) / temp3; + m16[10] = (-zfar - znear) / temp4; + m16[11] = -1.0f; + m16[12] = 0.0; + m16[13] = 0.0; + m16[14] = (-temp * zfar) / temp4; + m16[15] = 0.0; + } + + void Perspective(float fovyInDegrees, float aspectRatio, float znear, float zfar, float* m16) + { + float ymax, xmax; + ymax = znear * tanf(fovyInDegrees * DEG2RAD); + xmax = ymax * aspectRatio; + Frustum(-xmax, xmax, -ymax, ymax, znear, zfar, m16); + } + + void Cross(const float* a, const float* b, float* r) + { + r[0] = a[1] * b[2] - a[2] * b[1]; + r[1] = a[2] * b[0] - a[0] * b[2]; + r[2] = a[0] * b[1] - a[1] * b[0]; + } + + float Dot(const float* a, const float* b) + { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + + void Normalize(const float* a, float* r) + { + float il = 1.f / (sqrtf(Dot(a, a)) + FLT_EPSILON); + r[0] = a[0] * il; + r[1] = a[1] * il; + r[2] = a[2] * il; + } + + void LookAt(const float* eye, const float* at, const float* up, float* m16) + { + float X[3], Y[3], Z[3], tmp[3]; + + tmp[0] = eye[0] - at[0]; + tmp[1] = eye[1] - at[1]; + tmp[2] = eye[2] - at[2]; + Normalize(tmp, Z); + Normalize(up, Y); + Cross(Y, Z, tmp); + Normalize(tmp, X); + Cross(Z, X, tmp); + Normalize(tmp, Y); + + m16[0] = X[0]; + m16[1] = Y[0]; + m16[2] = Z[0]; + m16[3] = 0.0f; + m16[4] = X[1]; + m16[5] = Y[1]; + m16[6] = Z[1]; + m16[7] = 0.0f; + m16[8] = X[2]; + m16[9] = Y[2]; + m16[10] = Z[2]; + m16[11] = 0.0f; + m16[12] = -Dot(X, eye); + m16[13] = -Dot(Y, eye); + m16[14] = -Dot(Z, eye); + m16[15] = 1.0f; + } + + template T Clamp(T x, T y, T z) { return ((x < y) ? y : ((x > z) ? z : x)); } + template T max(T x, T y) { return (x > y) ? x : y; } + template T min(T x, T y) { return (x < y) ? x : y; } + template bool IsWithin(T x, T y, T z) { return (x >= y) && (x <= z); } + + struct matrix_t; + struct vec_t + { + public: + float x, y, z, w; + + void Lerp(const vec_t& v, float t) + { + x += (v.x - x) * t; + y += (v.y - y) * t; + z += (v.z - z) * t; + w += (v.w - w) * t; + } + + void Set(float v) { x = y = z = w = v; } + void Set(float _x, float _y, float _z = 0.f, float _w = 0.f) { x = _x; y = _y; z = _z; w = _w; } + + vec_t& operator -= (const vec_t& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; } + vec_t& operator += (const vec_t& v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; } + vec_t& operator *= (const vec_t& v) { x *= v.x; y *= v.y; z *= v.z; w *= v.w; return *this; } + vec_t& operator *= (float v) { x *= v; y *= v; z *= v; w *= v; return *this; } + + vec_t operator * (float f) const; + vec_t operator - () const; + vec_t operator - (const vec_t& v) const; + vec_t operator + (const vec_t& v) const; + vec_t operator * (const vec_t& v) const; + + const vec_t& operator + () const { return (*this); } + float Length() const { return sqrtf(x * x + y * y + z * z); }; + float LengthSq() const { return (x * x + y * y + z * z); }; + vec_t Normalize() { (*this) *= (1.f / ( Length() > FLT_EPSILON ? Length() : FLT_EPSILON ) ); return (*this); } + vec_t Normalize(const vec_t& v) { this->Set(v.x, v.y, v.z, v.w); this->Normalize(); return (*this); } + vec_t Abs() const; + + void Cross(const vec_t& v) + { + vec_t res; + res.x = y * v.z - z * v.y; + res.y = z * v.x - x * v.z; + res.z = x * v.y - y * v.x; + + x = res.x; + y = res.y; + z = res.z; + w = 0.f; + } + + void Cross(const vec_t& v1, const vec_t& v2) + { + x = v1.y * v2.z - v1.z * v2.y; + y = v1.z * v2.x - v1.x * v2.z; + z = v1.x * v2.y - v1.y * v2.x; + w = 0.f; + } + + float Dot(const vec_t& v) const + { + return (x * v.x) + (y * v.y) + (z * v.z) + (w * v.w); + } + + float Dot3(const vec_t& v) const + { + return (x * v.x) + (y * v.y) + (z * v.z); + } + + void Transform(const matrix_t& matrix); + void Transform(const vec_t& s, const matrix_t& matrix); + + void TransformVector(const matrix_t& matrix); + void TransformPoint(const matrix_t& matrix); + void TransformVector(const vec_t& v, const matrix_t& matrix) { (*this) = v; this->TransformVector(matrix); } + void TransformPoint(const vec_t& v, const matrix_t& matrix) { (*this) = v; this->TransformPoint(matrix); } + + float& operator [] (size_t index) { return ((float*)&x)[index]; } + const float& operator [] (size_t index) const { return ((float*)&x)[index]; } + bool operator!=(const vec_t& other) const { return memcmp(this, &other, sizeof(vec_t)) != 0; } + }; + + vec_t makeVect(float _x, float _y, float _z = 0.f, float _w = 0.f) { vec_t res; res.x = _x; res.y = _y; res.z = _z; res.w = _w; return res; } + vec_t makeVect(ImVec2 v) { vec_t res; res.x = v.x; res.y = v.y; res.z = 0.f; res.w = 0.f; return res; } + vec_t vec_t::operator * (float f) const { return makeVect(x * f, y * f, z * f, w * f); } + vec_t vec_t::operator - () const { return makeVect(-x, -y, -z, -w); } + vec_t vec_t::operator - (const vec_t& v) const { return makeVect(x - v.x, y - v.y, z - v.z, w - v.w); } + vec_t vec_t::operator + (const vec_t& v) const { return makeVect(x + v.x, y + v.y, z + v.z, w + v.w); } + vec_t vec_t::operator * (const vec_t& v) const { return makeVect(x * v.x, y * v.y, z * v.z, w * v.w); } + vec_t vec_t::Abs() const { return makeVect(fabsf(x), fabsf(y), fabsf(z)); } + + vec_t Normalized(const vec_t& v) { vec_t res; res = v; res.Normalize(); return res; } + vec_t Cross(const vec_t& v1, const vec_t& v2) + { + vec_t res; + res.x = v1.y * v2.z - v1.z * v2.y; + res.y = v1.z * v2.x - v1.x * v2.z; + res.z = v1.x * v2.y - v1.y * v2.x; + res.w = 0.f; + return res; + } + + float Dot(const vec_t& v1, const vec_t& v2) + { + return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z); + } + + vec_t BuildPlan(const vec_t& p_point1, const vec_t& p_normal) + { + vec_t normal, res; + normal.Normalize(p_normal); + res.w = normal.Dot(p_point1); + res.x = normal.x; + res.y = normal.y; + res.z = normal.z; + return res; + } + + struct matrix_t + { + public: + + union + { + float m[4][4]; + float m16[16]; + struct + { + vec_t right, up, dir, position; + } v; + vec_t component[4]; + }; + + operator float* () { return m16; } + operator const float* () const { return m16; } + void Translation(float _x, float _y, float _z) { this->Translation(makeVect(_x, _y, _z)); } + + void Translation(const vec_t& vt) + { + v.right.Set(1.f, 0.f, 0.f, 0.f); + v.up.Set(0.f, 1.f, 0.f, 0.f); + v.dir.Set(0.f, 0.f, 1.f, 0.f); + v.position.Set(vt.x, vt.y, vt.z, 1.f); + } + + void Scale(float _x, float _y, float _z) + { + v.right.Set(_x, 0.f, 0.f, 0.f); + v.up.Set(0.f, _y, 0.f, 0.f); + v.dir.Set(0.f, 0.f, _z, 0.f); + v.position.Set(0.f, 0.f, 0.f, 1.f); + } + void Scale(const vec_t& s) { Scale(s.x, s.y, s.z); } + + matrix_t& operator *= (const matrix_t& mat) + { + matrix_t tmpMat; + tmpMat = *this; + tmpMat.Multiply(mat); + *this = tmpMat; + return *this; + } + matrix_t operator * (const matrix_t& mat) const + { + matrix_t matT; + matT.Multiply(*this, mat); + return matT; + } + + void Multiply(const matrix_t& matrix) + { + matrix_t tmp; + tmp = *this; + + FPU_MatrixF_x_MatrixF((float*)&tmp, (float*)&matrix, (float*)this); + } + + void Multiply(const matrix_t& m1, const matrix_t& m2) + { + FPU_MatrixF_x_MatrixF((float*)&m1, (float*)&m2, (float*)this); + } + + float GetDeterminant() const + { + return m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + m[0][2] * m[1][0] * m[2][1] - + m[0][2] * m[1][1] * m[2][0] - m[0][1] * m[1][0] * m[2][2] - m[0][0] * m[1][2] * m[2][1]; + } + + float Inverse(const matrix_t& srcMatrix, bool affine = false); + void SetToIdentity() + { + v.right.Set(1.f, 0.f, 0.f, 0.f); + v.up.Set(0.f, 1.f, 0.f, 0.f); + v.dir.Set(0.f, 0.f, 1.f, 0.f); + v.position.Set(0.f, 0.f, 0.f, 1.f); + } + void Transpose() + { + matrix_t tmpm; + for (int l = 0; l < 4; l++) + { + for (int c = 0; c < 4; c++) + { + tmpm.m[l][c] = m[c][l]; + } + } + (*this) = tmpm; + } + + void RotationAxis(const vec_t& axis, float angle); + + void OrthoNormalize() + { + v.right.Normalize(); + v.up.Normalize(); + v.dir.Normalize(); + } + }; + + void vec_t::Transform(const matrix_t& matrix) + { + vec_t out; + + out.x = x * matrix.m[0][0] + y * matrix.m[1][0] + z * matrix.m[2][0] + w * matrix.m[3][0]; + out.y = x * matrix.m[0][1] + y * matrix.m[1][1] + z * matrix.m[2][1] + w * matrix.m[3][1]; + out.z = x * matrix.m[0][2] + y * matrix.m[1][2] + z * matrix.m[2][2] + w * matrix.m[3][2]; + out.w = x * matrix.m[0][3] + y * matrix.m[1][3] + z * matrix.m[2][3] + w * matrix.m[3][3]; + + x = out.x; + y = out.y; + z = out.z; + w = out.w; + } + + void vec_t::Transform(const vec_t& s, const matrix_t& matrix) + { + *this = s; + Transform(matrix); + } + + void vec_t::TransformPoint(const matrix_t& matrix) + { + vec_t out; + + out.x = x * matrix.m[0][0] + y * matrix.m[1][0] + z * matrix.m[2][0] + matrix.m[3][0]; + out.y = x * matrix.m[0][1] + y * matrix.m[1][1] + z * matrix.m[2][1] + matrix.m[3][1]; + out.z = x * matrix.m[0][2] + y * matrix.m[1][2] + z * matrix.m[2][2] + matrix.m[3][2]; + out.w = x * matrix.m[0][3] + y * matrix.m[1][3] + z * matrix.m[2][3] + matrix.m[3][3]; + + x = out.x; + y = out.y; + z = out.z; + w = out.w; + } + + void vec_t::TransformVector(const matrix_t& matrix) + { + vec_t out; + + out.x = x * matrix.m[0][0] + y * matrix.m[1][0] + z * matrix.m[2][0]; + out.y = x * matrix.m[0][1] + y * matrix.m[1][1] + z * matrix.m[2][1]; + out.z = x * matrix.m[0][2] + y * matrix.m[1][2] + z * matrix.m[2][2]; + out.w = x * matrix.m[0][3] + y * matrix.m[1][3] + z * matrix.m[2][3]; + + x = out.x; + y = out.y; + z = out.z; + w = out.w; + } + + float matrix_t::Inverse(const matrix_t& srcMatrix, bool affine) + { + float det = 0; + + if (affine) + { + det = GetDeterminant(); + float s = 1 / det; + m[0][0] = (srcMatrix.m[1][1] * srcMatrix.m[2][2] - srcMatrix.m[1][2] * srcMatrix.m[2][1]) * s; + m[0][1] = (srcMatrix.m[2][1] * srcMatrix.m[0][2] - srcMatrix.m[2][2] * srcMatrix.m[0][1]) * s; + m[0][2] = (srcMatrix.m[0][1] * srcMatrix.m[1][2] - srcMatrix.m[0][2] * srcMatrix.m[1][1]) * s; + m[1][0] = (srcMatrix.m[1][2] * srcMatrix.m[2][0] - srcMatrix.m[1][0] * srcMatrix.m[2][2]) * s; + m[1][1] = (srcMatrix.m[2][2] * srcMatrix.m[0][0] - srcMatrix.m[2][0] * srcMatrix.m[0][2]) * s; + m[1][2] = (srcMatrix.m[0][2] * srcMatrix.m[1][0] - srcMatrix.m[0][0] * srcMatrix.m[1][2]) * s; + m[2][0] = (srcMatrix.m[1][0] * srcMatrix.m[2][1] - srcMatrix.m[1][1] * srcMatrix.m[2][0]) * s; + m[2][1] = (srcMatrix.m[2][0] * srcMatrix.m[0][1] - srcMatrix.m[2][1] * srcMatrix.m[0][0]) * s; + m[2][2] = (srcMatrix.m[0][0] * srcMatrix.m[1][1] - srcMatrix.m[0][1] * srcMatrix.m[1][0]) * s; + m[3][0] = -(m[0][0] * srcMatrix.m[3][0] + m[1][0] * srcMatrix.m[3][1] + m[2][0] * srcMatrix.m[3][2]); + m[3][1] = -(m[0][1] * srcMatrix.m[3][0] + m[1][1] * srcMatrix.m[3][1] + m[2][1] * srcMatrix.m[3][2]); + m[3][2] = -(m[0][2] * srcMatrix.m[3][0] + m[1][2] * srcMatrix.m[3][1] + m[2][2] * srcMatrix.m[3][2]); + } + else + { + // transpose matrix + float src[16]; + for (int i = 0; i < 4; ++i) + { + src[i] = srcMatrix.m16[i * 4]; + src[i + 4] = srcMatrix.m16[i * 4 + 1]; + src[i + 8] = srcMatrix.m16[i * 4 + 2]; + src[i + 12] = srcMatrix.m16[i * 4 + 3]; + } + + // calculate pairs for first 8 elements (cofactors) + float tmp[12]; // temp array for pairs + tmp[0] = src[10] * src[15]; + tmp[1] = src[11] * src[14]; + tmp[2] = src[9] * src[15]; + tmp[3] = src[11] * src[13]; + tmp[4] = src[9] * src[14]; + tmp[5] = src[10] * src[13]; + tmp[6] = src[8] * src[15]; + tmp[7] = src[11] * src[12]; + tmp[8] = src[8] * src[14]; + tmp[9] = src[10] * src[12]; + tmp[10] = src[8] * src[13]; + tmp[11] = src[9] * src[12]; + + // calculate first 8 elements (cofactors) + m16[0] = (tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7]) - (tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7]); + m16[1] = (tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7]) - (tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7]); + m16[2] = (tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7]) - (tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7]); + m16[3] = (tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6]) - (tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6]); + m16[4] = (tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3]) - (tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3]); + m16[5] = (tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3]) - (tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3]); + m16[6] = (tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3]) - (tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3]); + m16[7] = (tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2]) - (tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2]); + + // calculate pairs for second 8 elements (cofactors) + tmp[0] = src[2] * src[7]; + tmp[1] = src[3] * src[6]; + tmp[2] = src[1] * src[7]; + tmp[3] = src[3] * src[5]; + tmp[4] = src[1] * src[6]; + tmp[5] = src[2] * src[5]; + tmp[6] = src[0] * src[7]; + tmp[7] = src[3] * src[4]; + tmp[8] = src[0] * src[6]; + tmp[9] = src[2] * src[4]; + tmp[10] = src[0] * src[5]; + tmp[11] = src[1] * src[4]; + + // calculate second 8 elements (cofactors) + m16[8] = (tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15]) - (tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15]); + m16[9] = (tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15]) - (tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15]); + m16[10] = (tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15]) - (tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15]); + m16[11] = (tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14]) - (tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14]); + m16[12] = (tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9]) - (tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10]); + m16[13] = (tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10]) - (tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8]); + m16[14] = (tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8]) - (tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9]); + m16[15] = (tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9]) - (tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8]); + + // calculate determinant + det = src[0] * m16[0] + src[1] * m16[1] + src[2] * m16[2] + src[3] * m16[3]; + + // calculate matrix inverse + float invdet = 1 / det; + for (int j = 0; j < 16; ++j) + { + m16[j] *= invdet; + } + } + + return det; + } + + void matrix_t::RotationAxis(const vec_t& axis, float angle) + { + float length2 = axis.LengthSq(); + if (length2 < FLT_EPSILON) + { + SetToIdentity(); + return; + } + + vec_t n = axis * (1.f / sqrtf(length2)); + float s = sinf(angle); + float c = cosf(angle); + float k = 1.f - c; + + float xx = n.x * n.x * k + c; + float yy = n.y * n.y * k + c; + float zz = n.z * n.z * k + c; + float xy = n.x * n.y * k; + float yz = n.y * n.z * k; + float zx = n.z * n.x * k; + float xs = n.x * s; + float ys = n.y * s; + float zs = n.z * s; + + m[0][0] = xx; + m[0][1] = xy + zs; + m[0][2] = zx - ys; + m[0][3] = 0.f; + m[1][0] = xy - zs; + m[1][1] = yy; + m[1][2] = yz + xs; + m[1][3] = 0.f; + m[2][0] = zx + ys; + m[2][1] = yz - xs; + m[2][2] = zz; + m[2][3] = 0.f; + m[3][0] = 0.f; + m[3][1] = 0.f; + m[3][2] = 0.f; + m[3][3] = 1.f; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + + enum MOVETYPE + { + MT_NONE, + MT_MOVE_X, + MT_MOVE_Y, + MT_MOVE_Z, + MT_MOVE_YZ, + MT_MOVE_ZX, + MT_MOVE_XY, + MT_MOVE_SCREEN, + MT_ROTATE_X, + MT_ROTATE_Y, + MT_ROTATE_Z, + MT_ROTATE_SCREEN, + MT_SCALE_X, + MT_SCALE_Y, + MT_SCALE_Z, + MT_SCALE_XYZ + }; + + static bool IsTranslateType(int type) + { + return type >= MT_MOVE_X && type <= MT_MOVE_SCREEN; + } + + static bool IsRotateType(int type) + { + return type >= MT_ROTATE_X && type <= MT_ROTATE_SCREEN; + } + + static bool IsScaleType(int type) + { + return type >= MT_SCALE_X && type <= MT_SCALE_XYZ; + } + + // Matches MT_MOVE_AB order + static const OPERATION TRANSLATE_PLANS[3] = { TRANSLATE_Y | TRANSLATE_Z, TRANSLATE_X | TRANSLATE_Z, TRANSLATE_X | TRANSLATE_Y }; + + Style::Style() + { + // default values + TranslationLineThickness = 3.0f; + TranslationLineArrowSize = 6.0f; + RotationLineThickness = 2.0f; + RotationOuterLineThickness = 3.0f; + ScaleLineThickness = 3.0f; + ScaleLineCircleSize = 6.0f; + HatchedAxisLineThickness = 6.0f; + CenterCircleSize = 6.0f; + + // initialize default colors + Colors[DIRECTION_X] = ImVec4(0.666f, 0.000f, 0.000f, 1.000f); + Colors[DIRECTION_Y] = ImVec4(0.000f, 0.666f, 0.000f, 1.000f); + Colors[DIRECTION_Z] = ImVec4(0.000f, 0.000f, 0.666f, 1.000f); + Colors[PLANE_X] = ImVec4(0.666f, 0.000f, 0.000f, 0.380f); + Colors[PLANE_Y] = ImVec4(0.000f, 0.666f, 0.000f, 0.380f); + Colors[PLANE_Z] = ImVec4(0.000f, 0.000f, 0.666f, 0.380f); + Colors[SELECTION] = ImVec4(1.000f, 0.500f, 0.062f, 0.541f); + Colors[INACTIVE] = ImVec4(0.600f, 0.600f, 0.600f, 0.600f); + Colors[TRANSLATION_LINE] = ImVec4(0.666f, 0.666f, 0.666f, 0.666f); + Colors[SCALE_LINE] = ImVec4(0.250f, 0.250f, 0.250f, 1.000f); + Colors[ROTATION_USING_BORDER] = ImVec4(1.000f, 0.500f, 0.062f, 1.000f); + Colors[ROTATION_USING_FILL] = ImVec4(1.000f, 0.500f, 0.062f, 0.500f); + Colors[HATCHED_AXIS_LINES] = ImVec4(0.000f, 0.000f, 0.000f, 0.500f); + Colors[TEXT] = ImVec4(1.000f, 1.000f, 1.000f, 1.000f); + Colors[TEXT_SHADOW] = ImVec4(0.000f, 0.000f, 0.000f, 1.000f); + } + + struct Context + { + Context() : mbUsing(false), mbUsingViewManipulate(false), mbEnable(true), mIsViewManipulatorHovered(false), mbUsingBounds(false) + { + } + + ImDrawList* mDrawList; + Style mStyle; + + MODE mMode; + matrix_t mViewMat; + matrix_t mProjectionMat; + matrix_t mModel; + matrix_t mModelLocal; // orthonormalized model + matrix_t mModelInverse; + matrix_t mModelSource; + matrix_t mModelSourceInverse; + matrix_t mMVP; + matrix_t mMVPLocal; // MVP with full model matrix whereas mMVP's model matrix might only be translation in case of World space edition + matrix_t mViewProjection; + + vec_t mModelScaleOrigin; + vec_t mCameraEye; + vec_t mCameraRight; + vec_t mCameraDir; + vec_t mCameraUp; + vec_t mRayOrigin; + vec_t mRayVector; + + float mRadiusSquareCenter; + ImVec2 mScreenSquareCenter; + ImVec2 mScreenSquareMin; + ImVec2 mScreenSquareMax; + + float mScreenFactor; + vec_t mRelativeOrigin; + + bool mbUsing; + bool mbUsingViewManipulate; + bool mbEnable; + bool mbMouseOver; + bool mReversed; // reversed projection matrix + bool mIsViewManipulatorHovered; + + // translation + vec_t mTranslationPlan; + vec_t mTranslationPlanOrigin; + vec_t mMatrixOrigin; + vec_t mTranslationLastDelta; + + // rotation + vec_t mRotationVectorSource; + float mRotationAngle; + float mRotationAngleOrigin; + //vec_t mWorldToLocalAxis; + + // scale + vec_t mScale; + vec_t mScaleValueOrigin; + vec_t mScaleLast; + float mSaveMousePosx; + + // save axis factor when using gizmo + bool mBelowAxisLimit[3]; + int mAxisMask = 0; + bool mBelowPlaneLimit[3]; + float mAxisFactor[3]; + + float mAxisLimit=0.0025f; + float mPlaneLimit=0.02f; + + // bounds stretching + vec_t mBoundsPivot; + vec_t mBoundsAnchor; + vec_t mBoundsPlan; + vec_t mBoundsLocalPivot; + int mBoundsBestAxis; + int mBoundsAxis[2]; + bool mbUsingBounds; + matrix_t mBoundsMatrix; + + // + int mCurrentOperation; + + float mX = 0.f; + float mY = 0.f; + float mWidth = 0.f; + float mHeight = 0.f; + float mXMax = 0.f; + float mYMax = 0.f; + float mDisplayRatio = 1.f; + + bool mIsOrthographic = false; + // check to not have multiple gizmo highlighted at the same time + bool mbOverGizmoHotspot = false; + + ImGuiWindow* mAlternativeWindow = nullptr; + ImVector mIDStack; + ImGuiID mEditingID = -1; + OPERATION mOperation = OPERATION(-1); + + bool mAllowAxisFlip = true; + float mGizmoSizeClipSpace = 0.1f; + + inline ImGuiID GetCurrentID() + { + if (mIDStack.empty()) + { + mIDStack.push_back(-1); + } + return mIDStack.back(); + } + }; + + static Context gContext; + + static const vec_t directionUnary[3] = { makeVect(1.f, 0.f, 0.f), makeVect(0.f, 1.f, 0.f), makeVect(0.f, 0.f, 1.f) }; + static const char* translationInfoMask[] = { "X : %5.3f", "Y : %5.3f", "Z : %5.3f", + "Y : %5.3f Z : %5.3f", "X : %5.3f Z : %5.3f", "X : %5.3f Y : %5.3f", + "X : %5.3f Y : %5.3f Z : %5.3f" }; + static const char* scaleInfoMask[] = { "X : %5.2f", "Y : %5.2f", "Z : %5.2f", "XYZ : %5.2f" }; + static const char* rotationInfoMask[] = { "X : %5.2f deg %5.2f rad", "Y : %5.2f deg %5.2f rad", "Z : %5.2f deg %5.2f rad", "Screen : %5.2f deg %5.2f rad" }; + static const int translationInfoIndex[] = { 0,0,0, 1,0,0, 2,0,0, 1,2,0, 0,2,0, 0,1,0, 0,1,2 }; + static const float quadMin = 0.5f; + static const float quadMax = 0.8f; + static const float quadUV[8] = { quadMin, quadMin, quadMin, quadMax, quadMax, quadMax, quadMax, quadMin }; + static const int halfCircleSegmentCount = 64; + static const float snapTension = 0.5f; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + static int GetMoveType(OPERATION op, vec_t* gizmoHitProportion); + static int GetRotateType(OPERATION op); + static int GetScaleType(OPERATION op); + + Style& GetStyle() + { + return gContext.mStyle; + } + + static ImU32 GetColorU32(int idx) + { + IM_ASSERT(idx < COLOR::COUNT); + return ImGui::ColorConvertFloat4ToU32(gContext.mStyle.Colors[idx]); + } + + static ImVec2 worldToPos(const vec_t& worldPos, const matrix_t& mat, ImVec2 position = ImVec2(gContext.mX, gContext.mY), ImVec2 size = ImVec2(gContext.mWidth, gContext.mHeight)) + { + vec_t trans; + trans.TransformPoint(worldPos, mat); + trans *= 0.5f / trans.w; + trans += makeVect(0.5f, 0.5f); + trans.y = 1.f - trans.y; + trans.x *= size.x; + trans.y *= size.y; + trans.x += position.x; + trans.y += position.y; + return ImVec2(trans.x, trans.y); + } + + static void ComputeCameraRay(vec_t& rayOrigin, vec_t& rayDir, ImVec2 position = ImVec2(gContext.mX, gContext.mY), ImVec2 size = ImVec2(gContext.mWidth, gContext.mHeight)) + { + ImGuiIO& io = ImGui::GetIO(); + + matrix_t mViewProjInverse; + mViewProjInverse.Inverse(gContext.mViewMat * gContext.mProjectionMat); + + const float mox = ((io.MousePos.x - position.x) / size.x) * 2.f - 1.f; + const float moy = (1.f - ((io.MousePos.y - position.y) / size.y)) * 2.f - 1.f; + + const float zNear = gContext.mReversed ? (1.f - FLT_EPSILON) : 0.f; + const float zFar = gContext.mReversed ? 0.f : (1.f - FLT_EPSILON); + + rayOrigin.Transform(makeVect(mox, moy, zNear, 1.f), mViewProjInverse); + rayOrigin *= 1.f / rayOrigin.w; + vec_t rayEnd; + rayEnd.Transform(makeVect(mox, moy, zFar, 1.f), mViewProjInverse); + rayEnd *= 1.f / rayEnd.w; + rayDir = Normalized(rayEnd - rayOrigin); + } + + static float GetSegmentLengthClipSpace(const vec_t& start, const vec_t& end, const bool localCoordinates = false) + { + vec_t startOfSegment = start; + const matrix_t& mvp = localCoordinates ? gContext.mMVPLocal : gContext.mMVP; + startOfSegment.TransformPoint(mvp); + if (fabsf(startOfSegment.w) > FLT_EPSILON) // check for axis aligned with camera direction + { + startOfSegment *= 1.f / startOfSegment.w; + } + + vec_t endOfSegment = end; + endOfSegment.TransformPoint(mvp); + if (fabsf(endOfSegment.w) > FLT_EPSILON) // check for axis aligned with camera direction + { + endOfSegment *= 1.f / endOfSegment.w; + } + + vec_t clipSpaceAxis = endOfSegment - startOfSegment; + if (gContext.mDisplayRatio < 1.0) + clipSpaceAxis.x *= gContext.mDisplayRatio; + else + clipSpaceAxis.y /= gContext.mDisplayRatio; + float segmentLengthInClipSpace = sqrtf(clipSpaceAxis.x * clipSpaceAxis.x + clipSpaceAxis.y * clipSpaceAxis.y); + return segmentLengthInClipSpace; + } + + static float GetParallelogram(const vec_t& ptO, const vec_t& ptA, const vec_t& ptB) + { + vec_t pts[] = { ptO, ptA, ptB }; + for (unsigned int i = 0; i < 3; i++) + { + pts[i].TransformPoint(gContext.mMVP); + if (fabsf(pts[i].w) > FLT_EPSILON) // check for axis aligned with camera direction + { + pts[i] *= 1.f / pts[i].w; + } + } + vec_t segA = pts[1] - pts[0]; + vec_t segB = pts[2] - pts[0]; + segA.y /= gContext.mDisplayRatio; + segB.y /= gContext.mDisplayRatio; + vec_t segAOrtho = makeVect(-segA.y, segA.x); + segAOrtho.Normalize(); + float dt = segAOrtho.Dot3(segB); + float surface = sqrtf(segA.x * segA.x + segA.y * segA.y) * fabsf(dt); + return surface; + } + + inline vec_t PointOnSegment(const vec_t& point, const vec_t& vertPos1, const vec_t& vertPos2) + { + vec_t c = point - vertPos1; + vec_t V; + + V.Normalize(vertPos2 - vertPos1); + float d = (vertPos2 - vertPos1).Length(); + float t = V.Dot3(c); + + if (t < 0.f) + { + return vertPos1; + } + + if (t > d) + { + return vertPos2; + } + + return vertPos1 + V * t; + } + + static float IntersectRayPlane(const vec_t& rOrigin, const vec_t& rVector, const vec_t& plan) + { + const float numer = plan.Dot3(rOrigin) - plan.w; + const float denom = plan.Dot3(rVector); + + if (fabsf(denom) < FLT_EPSILON) // normal is orthogonal to vector, cant intersect + { + return -1.0f; + } + + return -(numer / denom); + } + + static float DistanceToPlane(const vec_t& point, const vec_t& plan) + { + return plan.Dot3(point) + plan.w; + } + + static bool IsInContextRect(ImVec2 p) + { + return IsWithin(p.x, gContext.mX, gContext.mXMax) && IsWithin(p.y, gContext.mY, gContext.mYMax); + } + + static bool IsHoveringWindow() + { + ImGuiContext& g = *ImGui::GetCurrentContext(); + ImGuiWindow* window = ImGui::FindWindowByName(gContext.mDrawList->_OwnerName); + if (g.HoveredWindow == window) // Mouse hovering drawlist window + return true; + if (gContext.mAlternativeWindow != nullptr && g.HoveredWindow == gContext.mAlternativeWindow) + return true; + if (g.HoveredWindow != NULL) // Any other window is hovered + return false; + if (ImGui::IsMouseHoveringRect(window->InnerRect.Min, window->InnerRect.Max, false)) // Hovering drawlist window rect, while no other window is hovered (for _NoInputs windows) + return true; + return false; + } + + void SetRect(float x, float y, float width, float height) + { + gContext.mX = x; + gContext.mY = y; + gContext.mWidth = width; + gContext.mHeight = height; + gContext.mXMax = gContext.mX + gContext.mWidth; + gContext.mYMax = gContext.mY + gContext.mXMax; + gContext.mDisplayRatio = width / height; + } + + void SetOrthographic(bool isOrthographic) + { + gContext.mIsOrthographic = isOrthographic; + } + + void SetDrawlist(ImDrawList* drawlist) + { + gContext.mDrawList = drawlist ? drawlist : ImGui::GetWindowDrawList(); + } + + void SetImGuiContext(ImGuiContext* ctx) + { + ImGui::SetCurrentContext(ctx); + } + + void BeginFrame() + { + const ImU32 flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBringToFrontOnFocus; + +#ifdef IMGUI_HAS_VIEWPORT + ImGui::SetNextWindowSize(ImGui::GetMainViewport()->Size); + ImGui::SetNextWindowPos(ImGui::GetMainViewport()->Pos); +#else + ImGuiIO& io = ImGui::GetIO(); + ImGui::SetNextWindowSize(io.DisplaySize); + ImGui::SetNextWindowPos(ImVec2(0, 0)); +#endif + + ImGui::PushStyleColor(ImGuiCol_WindowBg, 0); + ImGui::PushStyleColor(ImGuiCol_Border, 0); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + + ImGui::Begin("gizmo", NULL, flags); + gContext.mDrawList = ImGui::GetWindowDrawList(); + gContext.mbOverGizmoHotspot = false; + ImGui::End(); + ImGui::PopStyleVar(); + ImGui::PopStyleColor(2); + } + + bool IsUsing() + { + return (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID)) || gContext.mbUsingBounds; + } + + bool IsUsingViewManipulate() + { + return gContext.mbUsingViewManipulate; + } + + bool IsViewManipulateHovered() + { + return gContext.mIsViewManipulatorHovered; + } + + bool IsUsingAny() + { + return gContext.mbUsing || gContext.mbUsingBounds; + } + + bool IsOver() + { + return (Intersects(gContext.mOperation, TRANSLATE) && GetMoveType(gContext.mOperation, NULL) != MT_NONE) || + (Intersects(gContext.mOperation, ROTATE) && GetRotateType(gContext.mOperation) != MT_NONE) || + (Intersects(gContext.mOperation, SCALE) && GetScaleType(gContext.mOperation) != MT_NONE) || IsUsing(); + } + + bool IsOver(OPERATION op) + { + if(IsUsing()) + { + return true; + } + if(Intersects(op, SCALE) && GetScaleType(op) != MT_NONE) + { + return true; + } + if(Intersects(op, ROTATE) && GetRotateType(op) != MT_NONE) + { + return true; + } + if(Intersects(op, TRANSLATE) && GetMoveType(op, NULL) != MT_NONE) + { + return true; + } + return false; + } + + void Enable(bool enable) + { + gContext.mbEnable = enable; + if (!enable) + { + gContext.mbUsing = false; + gContext.mbUsingBounds = false; + } + } + + static void ComputeContext(const float* view, const float* projection, float* matrix, MODE mode) + { + gContext.mMode = mode; + gContext.mViewMat = *(matrix_t*)view; + gContext.mProjectionMat = *(matrix_t*)projection; + gContext.mbMouseOver = IsHoveringWindow(); + + gContext.mModelLocal = *(matrix_t*)matrix; + gContext.mModelLocal.OrthoNormalize(); + + if (mode == LOCAL) + { + gContext.mModel = gContext.mModelLocal; + } + else + { + gContext.mModel.Translation(((matrix_t*)matrix)->v.position); + } + gContext.mModelSource = *(matrix_t*)matrix; + gContext.mModelScaleOrigin.Set(gContext.mModelSource.v.right.Length(), gContext.mModelSource.v.up.Length(), gContext.mModelSource.v.dir.Length()); + + gContext.mModelInverse.Inverse(gContext.mModel); + gContext.mModelSourceInverse.Inverse(gContext.mModelSource); + gContext.mViewProjection = gContext.mViewMat * gContext.mProjectionMat; + gContext.mMVP = gContext.mModel * gContext.mViewProjection; + gContext.mMVPLocal = gContext.mModelLocal * gContext.mViewProjection; + + matrix_t viewInverse; + viewInverse.Inverse(gContext.mViewMat); + gContext.mCameraDir = viewInverse.v.dir; + gContext.mCameraEye = viewInverse.v.position; + gContext.mCameraRight = viewInverse.v.right; + gContext.mCameraUp = viewInverse.v.up; + + // projection reverse + vec_t nearPos, farPos; + nearPos.Transform(makeVect(0, 0, 1.f, 1.f), gContext.mProjectionMat); + farPos.Transform(makeVect(0, 0, 2.f, 1.f), gContext.mProjectionMat); + + gContext.mReversed = (nearPos.z/nearPos.w) > (farPos.z / farPos.w); + + // compute scale from the size of camera right vector projected on screen at the matrix position + vec_t pointRight = viewInverse.v.right; + pointRight.TransformPoint(gContext.mViewProjection); + + vec_t rightViewInverse = viewInverse.v.right; + rightViewInverse.TransformVector(gContext.mModelInverse); + float rightLength = GetSegmentLengthClipSpace(makeVect(0.f, 0.f), rightViewInverse); + gContext.mScreenFactor = gContext.mGizmoSizeClipSpace / rightLength; + + ImVec2 centerSSpace = worldToPos(makeVect(0.f, 0.f), gContext.mMVP); + gContext.mScreenSquareCenter = centerSSpace; + gContext.mScreenSquareMin = ImVec2(centerSSpace.x - 10.f, centerSSpace.y - 10.f); + gContext.mScreenSquareMax = ImVec2(centerSSpace.x + 10.f, centerSSpace.y + 10.f); + + ComputeCameraRay(gContext.mRayOrigin, gContext.mRayVector); + } + + static void ComputeColors(ImU32* colors, int type, OPERATION operation) + { + if (gContext.mbEnable) + { + ImU32 selectionColor = GetColorU32(SELECTION); + + switch (operation) + { + case TRANSLATE: + colors[0] = (type == MT_MOVE_SCREEN) ? selectionColor : IM_COL32_WHITE; + for (int i = 0; i < 3; i++) + { + colors[i + 1] = (type == (int)(MT_MOVE_X + i)) ? selectionColor : GetColorU32(DIRECTION_X + i); + colors[i + 4] = (type == (int)(MT_MOVE_YZ + i)) ? selectionColor : GetColorU32(PLANE_X + i); + colors[i + 4] = (type == MT_MOVE_SCREEN) ? selectionColor : colors[i + 4]; + } + break; + case ROTATE: + colors[0] = (type == MT_ROTATE_SCREEN) ? selectionColor : IM_COL32_WHITE; + for (int i = 0; i < 3; i++) + { + colors[i + 1] = (type == (int)(MT_ROTATE_X + i)) ? selectionColor : GetColorU32(DIRECTION_X + i); + } + break; + case SCALEU: + case SCALE: + colors[0] = (type == MT_SCALE_XYZ) ? selectionColor : IM_COL32_WHITE; + for (int i = 0; i < 3; i++) + { + colors[i + 1] = (type == (int)(MT_SCALE_X + i)) ? selectionColor : GetColorU32(DIRECTION_X + i); + } + break; + // note: this internal function is only called with three possible values for operation + default: + break; + } + } + else + { + ImU32 inactiveColor = GetColorU32(INACTIVE); + for (int i = 0; i < 7; i++) + { + colors[i] = inactiveColor; + } + } + } + + static void ComputeTripodAxisAndVisibility(const int axisIndex, vec_t& dirAxis, vec_t& dirPlaneX, vec_t& dirPlaneY, bool& belowAxisLimit, bool& belowPlaneLimit, const bool localCoordinates = false) + { + dirAxis = directionUnary[axisIndex]; + dirPlaneX = directionUnary[(axisIndex + 1) % 3]; + dirPlaneY = directionUnary[(axisIndex + 2) % 3]; + + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID)) + { + // when using, use stored factors so the gizmo doesn't flip when we translate + + // Apply axis mask to axes and planes + belowAxisLimit = gContext.mBelowAxisLimit[axisIndex] && ((1< FLT_EPSILON) ? -1.f : 1.f; + float mulAxisX = (allowFlip && lenDirPlaneX < lenDirMinusPlaneX&& fabsf(lenDirPlaneX - lenDirMinusPlaneX) > FLT_EPSILON) ? -1.f : 1.f; + float mulAxisY = (allowFlip && lenDirPlaneY < lenDirMinusPlaneY&& fabsf(lenDirPlaneY - lenDirMinusPlaneY) > FLT_EPSILON) ? -1.f : 1.f; + dirAxis *= mulAxis; + dirPlaneX *= mulAxisX; + dirPlaneY *= mulAxisY; + + // for axis + float axisLengthInClipSpace = GetSegmentLengthClipSpace(makeVect(0.f, 0.f, 0.f), dirAxis * gContext.mScreenFactor, localCoordinates); + + float paraSurf = GetParallelogram(makeVect(0.f, 0.f, 0.f), dirPlaneX * gContext.mScreenFactor, dirPlaneY * gContext.mScreenFactor); + // Apply axis mask to axes and planes + belowPlaneLimit = (paraSurf > gContext.mAxisLimit) && (((1< gContext.mPlaneLimit) && !((1< (1.f - snapTension)) + { + *value = *value - modulo + snap * ((*value < 0.f) ? -1.f : 1.f); + } + } + static void ComputeSnap(vec_t& value, const float* snap) + { + for (int i = 0; i < 3; i++) + { + ComputeSnap(&value[i], snap[i]); + } + } + + static float ComputeAngleOnPlan() + { + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan); + vec_t localPos = Normalized(gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position); + + vec_t perpendicularVector; + perpendicularVector.Cross(gContext.mRotationVectorSource, gContext.mTranslationPlan); + perpendicularVector.Normalize(); + float acosAngle = Clamp(Dot(localPos, gContext.mRotationVectorSource), -1.f, 1.f); + float angle = acosf(acosAngle); + angle *= (Dot(localPos, perpendicularVector) < 0.f) ? 1.f : -1.f; + return angle; + } + + static void DrawRotationGizmo(OPERATION op, int type) + { + if(!Intersects(op, ROTATE)) + { + return; + } + ImDrawList* drawList = gContext.mDrawList; + + bool isMultipleAxesMasked = (gContext.mAxisMask & (gContext.mAxisMask - 1)) != 0; + bool isNoAxesMasked = !gContext.mAxisMask; + + // colors + ImU32 colors[7]; + ComputeColors(colors, type, ROTATE); + + vec_t cameraToModelNormalized; + if (gContext.mIsOrthographic) + { + matrix_t viewInverse; + viewInverse.Inverse(*(matrix_t*)&gContext.mViewMat); + cameraToModelNormalized = -viewInverse.v.dir; + } + else + { + cameraToModelNormalized = Normalized(gContext.mModel.v.position - gContext.mCameraEye); + } + + cameraToModelNormalized.TransformVector(gContext.mModelInverse); + + gContext.mRadiusSquareCenter = screenRotateSize * gContext.mHeight; + + bool hasRSC = Intersects(op, ROTATE_SCREEN); + for (int axis = 0; axis < 3; axis++) + { + if(!Intersects(op, static_cast(ROTATE_Z >> axis))) + { + continue; + } + + bool isAxisMasked = ((1 << (2 - axis)) & gContext.mAxisMask) != 0; + + if ((!isAxisMasked || isMultipleAxesMasked) && !isNoAxesMasked) + { + continue; + } + const bool usingAxis = (gContext.mbUsing && type == MT_ROTATE_Z - axis); + const int circleMul = (hasRSC && !usingAxis) ? 1 : 2; + + ImVec2* circlePos = (ImVec2*)alloca(sizeof(ImVec2) * (circleMul * halfCircleSegmentCount + 1)); + + float angleStart = atan2f(cameraToModelNormalized[(4 - axis) % 3], cameraToModelNormalized[(3 - axis) % 3]) + ZPI * 0.5f; + + for (int i = 0; i < circleMul * halfCircleSegmentCount + 1; i++) + { + float ng = angleStart + (float)circleMul * ZPI * ((float)i / (float)(circleMul * halfCircleSegmentCount)); + vec_t axisPos = makeVect(cosf(ng), sinf(ng), 0.f); + vec_t pos = makeVect(axisPos[axis], axisPos[(axis + 1) % 3], axisPos[(axis + 2) % 3]) * gContext.mScreenFactor * rotationDisplayFactor; + circlePos[i] = worldToPos(pos, gContext.mMVP); + } + if (!gContext.mbUsing || usingAxis) + { + drawList->AddPolyline(circlePos, circleMul* halfCircleSegmentCount + 1, colors[3 - axis], false, gContext.mStyle.RotationLineThickness); + } + + float radiusAxis = sqrtf((ImLengthSqr(worldToPos(gContext.mModel.v.position, gContext.mViewProjection) - circlePos[0]))); + if (radiusAxis > gContext.mRadiusSquareCenter) + { + gContext.mRadiusSquareCenter = radiusAxis; + } + } + if(hasRSC && (!gContext.mbUsing || type == MT_ROTATE_SCREEN) && (!isMultipleAxesMasked && isNoAxesMasked)) + { + drawList->AddCircle(worldToPos(gContext.mModel.v.position, gContext.mViewProjection), gContext.mRadiusSquareCenter, colors[0], 64, gContext.mStyle.RotationOuterLineThickness); + } + + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsRotateType(type)) + { + ImVec2 circlePos[halfCircleSegmentCount + 1]; + + circlePos[0] = worldToPos(gContext.mModel.v.position, gContext.mViewProjection); + for (unsigned int i = 1; i < halfCircleSegmentCount + 1; i++) + { + float ng = gContext.mRotationAngle * ((float)(i - 1) / (float)(halfCircleSegmentCount - 1)); + matrix_t rotateVectorMatrix; + rotateVectorMatrix.RotationAxis(gContext.mTranslationPlan, ng); + vec_t pos; + pos.TransformPoint(gContext.mRotationVectorSource, rotateVectorMatrix); + pos *= gContext.mScreenFactor * rotationDisplayFactor; + circlePos[i] = worldToPos(pos + gContext.mModel.v.position, gContext.mViewProjection); + } + drawList->AddConvexPolyFilled(circlePos, halfCircleSegmentCount + 1, GetColorU32(ROTATION_USING_FILL)); + drawList->AddPolyline(circlePos, halfCircleSegmentCount + 1, GetColorU32(ROTATION_USING_BORDER), true, gContext.mStyle.RotationLineThickness); + + ImVec2 destinationPosOnScreen = circlePos[1]; + char tmps[512]; + ImFormatString(tmps, sizeof(tmps), rotationInfoMask[type - MT_ROTATE_X], (gContext.mRotationAngle / ZPI) * 180.f, gContext.mRotationAngle); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), GetColorU32(TEXT_SHADOW), tmps); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), GetColorU32(TEXT), tmps); + } + } + + static void DrawHatchedAxis(const vec_t& axis) + { + if (gContext.mStyle.HatchedAxisLineThickness <= 0.0f) + { + return; + } + + for (int j = 1; j < 10; j++) + { + ImVec2 baseSSpace2 = worldToPos(axis * 0.05f * (float)(j * 2) * gContext.mScreenFactor, gContext.mMVP); + ImVec2 worldDirSSpace2 = worldToPos(axis * 0.05f * (float)(j * 2 + 1) * gContext.mScreenFactor, gContext.mMVP); + gContext.mDrawList->AddLine(baseSSpace2, worldDirSSpace2, GetColorU32(HATCHED_AXIS_LINES), gContext.mStyle.HatchedAxisLineThickness); + } + } + + static void DrawScaleGizmo(OPERATION op, int type) + { + ImDrawList* drawList = gContext.mDrawList; + + if(!Intersects(op, SCALE)) + { + return; + } + + // colors + ImU32 colors[7]; + ComputeColors(colors, type, SCALE); + + // draw + vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f }; + + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID)) + { + scaleDisplay = gContext.mScale; + } + + for (int i = 0; i < 3; i++) + { + if(!Intersects(op, static_cast(SCALE_X << i))) + { + continue; + } + const bool usingAxis = (gContext.mbUsing && type == MT_SCALE_X + i); + if (!gContext.mbUsing || usingAxis) + { + vec_t dirPlaneX, dirPlaneY, dirAxis; + bool belowAxisLimit, belowPlaneLimit; + ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit, true); + + // draw axis + if (belowAxisLimit) + { + bool hasTranslateOnAxis = Contains(op, static_cast(TRANSLATE_X << i)); + float markerScale = hasTranslateOnAxis ? 1.4f : 1.0f; + ImVec2 baseSSpace = worldToPos(dirAxis * 0.1f * gContext.mScreenFactor, gContext.mMVP); + ImVec2 worldDirSSpaceNoScale = worldToPos(dirAxis * markerScale * gContext.mScreenFactor, gContext.mMVP); + ImVec2 worldDirSSpace = worldToPos((dirAxis * markerScale * scaleDisplay[i]) * gContext.mScreenFactor, gContext.mMVP); + + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID)) + { + ImU32 scaleLineColor = GetColorU32(SCALE_LINE); + drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, scaleLineColor, gContext.mStyle.ScaleLineThickness); + drawList->AddCircleFilled(worldDirSSpaceNoScale, gContext.mStyle.ScaleLineCircleSize, scaleLineColor); + } + + if (!hasTranslateOnAxis || gContext.mbUsing) + { + drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], gContext.mStyle.ScaleLineThickness); + } + drawList->AddCircleFilled(worldDirSSpace, gContext.mStyle.ScaleLineCircleSize, colors[i + 1]); + + if (gContext.mAxisFactor[i] < 0.f) + { + DrawHatchedAxis(dirAxis * scaleDisplay[i]); + } + } + } + } + + // draw screen cirle + drawList->AddCircleFilled(gContext.mScreenSquareCenter, gContext.mStyle.CenterCircleSize, colors[0], 32); + + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsScaleType(type)) + { + //ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection); + ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection); + /*vec_t dif(destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y); + dif.Normalize(); + dif *= 5.f; + drawList->AddCircle(sourcePosOnScreen, 6.f, translationLineColor); + drawList->AddCircle(destinationPosOnScreen, 6.f, translationLineColor); + drawList->AddLine(ImVec2(sourcePosOnScreen.x + dif.x, sourcePosOnScreen.y + dif.y), ImVec2(destinationPosOnScreen.x - dif.x, destinationPosOnScreen.y - dif.y), translationLineColor, 2.f); + */ + char tmps[512]; + //vec_t deltaInfo = gContext.mModel.v.position - gContext.mMatrixOrigin; + int componentInfoIndex = (type - MT_SCALE_X) * 3; + ImFormatString(tmps, sizeof(tmps), scaleInfoMask[type - MT_SCALE_X], scaleDisplay[translationInfoIndex[componentInfoIndex]]); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), GetColorU32(TEXT_SHADOW), tmps); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), GetColorU32(TEXT), tmps); + } + } + + + static void DrawScaleUniveralGizmo(OPERATION op, int type) + { + ImDrawList* drawList = gContext.mDrawList; + + if (!Intersects(op, SCALEU)) + { + return; + } + + // colors + ImU32 colors[7]; + ComputeColors(colors, type, SCALEU); + + // draw + vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f }; + + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID)) + { + scaleDisplay = gContext.mScale; + } + + for (int i = 0; i < 3; i++) + { + if (!Intersects(op, static_cast(SCALE_XU << i))) + { + continue; + } + const bool usingAxis = (gContext.mbUsing && type == MT_SCALE_X + i); + if (!gContext.mbUsing || usingAxis) + { + vec_t dirPlaneX, dirPlaneY, dirAxis; + bool belowAxisLimit, belowPlaneLimit; + ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit, true); + + // draw axis + if (belowAxisLimit) + { + bool hasTranslateOnAxis = Contains(op, static_cast(TRANSLATE_X << i)); + float markerScale = hasTranslateOnAxis ? 1.4f : 1.0f; + //ImVec2 baseSSpace = worldToPos(dirAxis * 0.1f * gContext.mScreenFactor, gContext.mMVPLocal); + //ImVec2 worldDirSSpaceNoScale = worldToPos(dirAxis * markerScale * gContext.mScreenFactor, gContext.mMVP); + ImVec2 worldDirSSpace = worldToPos((dirAxis * markerScale * scaleDisplay[i]) * gContext.mScreenFactor, gContext.mMVPLocal); + +#if 0 + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID)) + { + drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, IM_COL32(0x40, 0x40, 0x40, 0xFF), 3.f); + drawList->AddCircleFilled(worldDirSSpaceNoScale, 6.f, IM_COL32(0x40, 0x40, 0x40, 0xFF)); + } + /* + if (!hasTranslateOnAxis || gContext.mbUsing) + { + drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 3.f); + } + */ +#endif + drawList->AddCircleFilled(worldDirSSpace, 12.f, colors[i + 1]); + } + } + } + + // draw screen cirle + drawList->AddCircle(gContext.mScreenSquareCenter, 20.f, colors[0], 32, gContext.mStyle.CenterCircleSize); + + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsScaleType(type)) + { + //ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection); + ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection); + /*vec_t dif(destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y); + dif.Normalize(); + dif *= 5.f; + drawList->AddCircle(sourcePosOnScreen, 6.f, translationLineColor); + drawList->AddCircle(destinationPosOnScreen, 6.f, translationLineColor); + drawList->AddLine(ImVec2(sourcePosOnScreen.x + dif.x, sourcePosOnScreen.y + dif.y), ImVec2(destinationPosOnScreen.x - dif.x, destinationPosOnScreen.y - dif.y), translationLineColor, 2.f); + */ + char tmps[512]; + //vec_t deltaInfo = gContext.mModel.v.position - gContext.mMatrixOrigin; + int componentInfoIndex = (type - MT_SCALE_X) * 3; + ImFormatString(tmps, sizeof(tmps), scaleInfoMask[type - MT_SCALE_X], scaleDisplay[translationInfoIndex[componentInfoIndex]]); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), GetColorU32(TEXT_SHADOW), tmps); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), GetColorU32(TEXT), tmps); + } + } + + static void DrawTranslationGizmo(OPERATION op, int type) + { + ImDrawList* drawList = gContext.mDrawList; + if (!drawList) + { + return; + } + + if(!Intersects(op, TRANSLATE)) + { + return; + } + + // colors + ImU32 colors[7]; + ComputeColors(colors, type, TRANSLATE); + + const ImVec2 origin = worldToPos(gContext.mModel.v.position, gContext.mViewProjection); + + // draw + bool belowAxisLimit = false; + bool belowPlaneLimit = false; + for (int i = 0; i < 3; ++i) + { + vec_t dirPlaneX, dirPlaneY, dirAxis; + ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit); + + if (!gContext.mbUsing || (gContext.mbUsing && type == MT_MOVE_X + i)) + { + // draw axis + if (belowAxisLimit && Intersects(op, static_cast(TRANSLATE_X << i))) + { + ImVec2 baseSSpace = worldToPos(dirAxis * 0.1f * gContext.mScreenFactor, gContext.mMVP); + ImVec2 worldDirSSpace = worldToPos(dirAxis * gContext.mScreenFactor, gContext.mMVP); + + drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], gContext.mStyle.TranslationLineThickness); + + // Arrow head begin + ImVec2 dir(origin - worldDirSSpace); + + float d = sqrtf(ImLengthSqr(dir)); + dir /= d; // Normalize + dir *= gContext.mStyle.TranslationLineArrowSize; + + ImVec2 ortogonalDir(dir.y, -dir.x); // Perpendicular vector + ImVec2 a(worldDirSSpace + dir); + drawList->AddTriangleFilled(worldDirSSpace - dir, a + ortogonalDir, a - ortogonalDir, colors[i + 1]); + // Arrow head end + + if (gContext.mAxisFactor[i] < 0.f) + { + DrawHatchedAxis(dirAxis); + } + } + } + // draw plane + if (!gContext.mbUsing || (gContext.mbUsing && type == MT_MOVE_YZ + i)) + { + if (belowPlaneLimit && Contains(op, TRANSLATE_PLANS[i])) + { + ImVec2 screenQuadPts[4]; + for (int j = 0; j < 4; ++j) + { + vec_t cornerWorldPos = (dirPlaneX * quadUV[j * 2] + dirPlaneY * quadUV[j * 2 + 1]) * gContext.mScreenFactor; + screenQuadPts[j] = worldToPos(cornerWorldPos, gContext.mMVP); + } + drawList->AddPolyline(screenQuadPts, 4, GetColorU32(DIRECTION_X + i), true, 1.0f); + drawList->AddConvexPolyFilled(screenQuadPts, 4, colors[i + 4]); + } + } + } + + drawList->AddCircleFilled(gContext.mScreenSquareCenter, gContext.mStyle.CenterCircleSize, colors[0], 32); + + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsTranslateType(type)) + { + ImU32 translationLineColor = GetColorU32(TRANSLATION_LINE); + + ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection); + ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection); + vec_t dif = { destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y, 0.f, 0.f }; + dif.Normalize(); + dif *= 5.f; + drawList->AddCircle(sourcePosOnScreen, 6.f, translationLineColor); + drawList->AddCircle(destinationPosOnScreen, 6.f, translationLineColor); + drawList->AddLine(ImVec2(sourcePosOnScreen.x + dif.x, sourcePosOnScreen.y + dif.y), ImVec2(destinationPosOnScreen.x - dif.x, destinationPosOnScreen.y - dif.y), translationLineColor, 2.f); + + char tmps[512]; + vec_t deltaInfo = gContext.mModel.v.position - gContext.mMatrixOrigin; + int componentInfoIndex = (type - MT_MOVE_X) * 3; + ImFormatString(tmps, sizeof(tmps), translationInfoMask[type - MT_MOVE_X], deltaInfo[translationInfoIndex[componentInfoIndex]], deltaInfo[translationInfoIndex[componentInfoIndex + 1]], deltaInfo[translationInfoIndex[componentInfoIndex + 2]]); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), GetColorU32(TEXT_SHADOW), tmps); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), GetColorU32(TEXT), tmps); + } + } + + static bool CanActivate() + { + if (ImGui::IsMouseClicked(0) && !ImGui::IsAnyItemHovered() && !ImGui::IsAnyItemActive()) + { + return true; + } + return false; + } + + static void HandleAndDrawLocalBounds(const float* bounds, matrix_t* matrix, const float* snapValues, OPERATION operation) + { + ImGuiIO& io = ImGui::GetIO(); + ImDrawList* drawList = gContext.mDrawList; + + // compute best projection axis + vec_t axesWorldDirections[3]; + vec_t bestAxisWorldDirection = { 0.0f, 0.0f, 0.0f, 0.0f }; + int axes[3]; + unsigned int numAxes = 1; + axes[0] = gContext.mBoundsBestAxis; + int bestAxis = axes[0]; + if (!gContext.mbUsingBounds) + { + numAxes = 0; + float bestDot = 0.f; + for (int i = 0; i < 3; i++) + { + vec_t dirPlaneNormalWorld; + dirPlaneNormalWorld.TransformVector(directionUnary[i], gContext.mModelSource); + dirPlaneNormalWorld.Normalize(); + + float dt = fabsf(Dot(Normalized(gContext.mCameraEye - gContext.mModelSource.v.position), dirPlaneNormalWorld)); + if (dt >= bestDot) + { + bestDot = dt; + bestAxis = i; + bestAxisWorldDirection = dirPlaneNormalWorld; + } + + if (dt >= 0.1f) + { + axes[numAxes] = i; + axesWorldDirections[numAxes] = dirPlaneNormalWorld; + ++numAxes; + } + } + } + + if (numAxes == 0) + { + axes[0] = bestAxis; + axesWorldDirections[0] = bestAxisWorldDirection; + numAxes = 1; + } + + else if (bestAxis != axes[0]) + { + unsigned int bestIndex = 0; + for (unsigned int i = 0; i < numAxes; i++) + { + if (axes[i] == bestAxis) + { + bestIndex = i; + break; + } + } + int tempAxis = axes[0]; + axes[0] = axes[bestIndex]; + axes[bestIndex] = tempAxis; + vec_t tempDirection = axesWorldDirections[0]; + axesWorldDirections[0] = axesWorldDirections[bestIndex]; + axesWorldDirections[bestIndex] = tempDirection; + } + + for (unsigned int axisIndex = 0; axisIndex < numAxes; ++axisIndex) + { + bestAxis = axes[axisIndex]; + bestAxisWorldDirection = axesWorldDirections[axisIndex]; + + // corners + vec_t aabb[4]; + + int secondAxis = (bestAxis + 1) % 3; + int thirdAxis = (bestAxis + 2) % 3; + + for (int i = 0; i < 4; i++) + { + aabb[i][3] = aabb[i][bestAxis] = 0.f; + aabb[i][secondAxis] = bounds[secondAxis + 3 * (i >> 1)]; + aabb[i][thirdAxis] = bounds[thirdAxis + 3 * ((i >> 1) ^ (i & 1))]; + } + + // draw bounds + unsigned int anchorAlpha = gContext.mbEnable ? IM_COL32_BLACK : IM_COL32(0, 0, 0, 0x80); + + matrix_t boundsMVP = gContext.mModelSource * gContext.mViewProjection; + for (int i = 0; i < 4; i++) + { + ImVec2 worldBound1 = worldToPos(aabb[i], boundsMVP); + ImVec2 worldBound2 = worldToPos(aabb[(i + 1) % 4], boundsMVP); + if (!IsInContextRect(worldBound1) || !IsInContextRect(worldBound2)) + { + continue; + } + float boundDistance = sqrtf(ImLengthSqr(worldBound1 - worldBound2)); + int stepCount = (int)(boundDistance / 10.f); + stepCount = min(stepCount, 1000); + for (int j = 0; j < stepCount; j++) + { + float stepLength = 1.f / (float)stepCount; + float t1 = (float)j * stepLength; + float t2 = (float)j * stepLength + stepLength * 0.5f; + ImVec2 worldBoundSS1 = ImLerp(worldBound1, worldBound2, ImVec2(t1, t1)); + ImVec2 worldBoundSS2 = ImLerp(worldBound1, worldBound2, ImVec2(t2, t2)); + //drawList->AddLine(worldBoundSS1, worldBoundSS2, IM_COL32(0, 0, 0, 0) + anchorAlpha, 3.f); + drawList->AddLine(worldBoundSS1, worldBoundSS2, IM_COL32(0xAA, 0xAA, 0xAA, 0) + anchorAlpha, 2.f); + } + vec_t midPoint = (aabb[i] + aabb[(i + 1) % 4]) * 0.5f; + ImVec2 midBound = worldToPos(midPoint, boundsMVP); + static const float AnchorBigRadius = 8.f; + static const float AnchorSmallRadius = 6.f; + bool overBigAnchor = ImLengthSqr(worldBound1 - io.MousePos) <= (AnchorBigRadius * AnchorBigRadius); + bool overSmallAnchor = ImLengthSqr(midBound - io.MousePos) <= (AnchorBigRadius * AnchorBigRadius); + + int type = MT_NONE; + vec_t gizmoHitProportion; + + if(Intersects(operation, TRANSLATE)) + { + type = GetMoveType(operation, &gizmoHitProportion); + } + if(Intersects(operation, ROTATE) && type == MT_NONE) + { + type = GetRotateType(operation); + } + if(Intersects(operation, SCALE) && type == MT_NONE) + { + type = GetScaleType(operation); + } + + if (type != MT_NONE) + { + overBigAnchor = false; + overSmallAnchor = false; + } + + ImU32 selectionColor = GetColorU32(SELECTION); + + unsigned int bigAnchorColor = overBigAnchor ? selectionColor : (IM_COL32(0xAA, 0xAA, 0xAA, 0) + anchorAlpha); + unsigned int smallAnchorColor = overSmallAnchor ? selectionColor : (IM_COL32(0xAA, 0xAA, 0xAA, 0) + anchorAlpha); + + drawList->AddCircleFilled(worldBound1, AnchorBigRadius, IM_COL32_BLACK); + drawList->AddCircleFilled(worldBound1, AnchorBigRadius - 1.2f, bigAnchorColor); + + drawList->AddCircleFilled(midBound, AnchorSmallRadius, IM_COL32_BLACK); + drawList->AddCircleFilled(midBound, AnchorSmallRadius - 1.2f, smallAnchorColor); + int oppositeIndex = (i + 2) % 4; + // big anchor on corners + if (!gContext.mbUsingBounds && gContext.mbEnable && overBigAnchor && CanActivate()) + { + gContext.mBoundsPivot.TransformPoint(aabb[(i + 2) % 4], gContext.mModelSource); + gContext.mBoundsAnchor.TransformPoint(aabb[i], gContext.mModelSource); + gContext.mBoundsPlan = BuildPlan(gContext.mBoundsAnchor, bestAxisWorldDirection); + gContext.mBoundsBestAxis = bestAxis; + gContext.mBoundsAxis[0] = secondAxis; + gContext.mBoundsAxis[1] = thirdAxis; + + gContext.mBoundsLocalPivot.Set(0.f); + gContext.mBoundsLocalPivot[secondAxis] = aabb[oppositeIndex][secondAxis]; + gContext.mBoundsLocalPivot[thirdAxis] = aabb[oppositeIndex][thirdAxis]; + + gContext.mbUsingBounds = true; + gContext.mEditingID = gContext.GetCurrentID(); + gContext.mBoundsMatrix = gContext.mModelSource; + } + // small anchor on middle of segment + if (!gContext.mbUsingBounds && gContext.mbEnable && overSmallAnchor && CanActivate()) + { + vec_t midPointOpposite = (aabb[(i + 2) % 4] + aabb[(i + 3) % 4]) * 0.5f; + gContext.mBoundsPivot.TransformPoint(midPointOpposite, gContext.mModelSource); + gContext.mBoundsAnchor.TransformPoint(midPoint, gContext.mModelSource); + gContext.mBoundsPlan = BuildPlan(gContext.mBoundsAnchor, bestAxisWorldDirection); + gContext.mBoundsBestAxis = bestAxis; + int indices[] = { secondAxis , thirdAxis }; + gContext.mBoundsAxis[0] = indices[i % 2]; + gContext.mBoundsAxis[1] = -1; + + gContext.mBoundsLocalPivot.Set(0.f); + gContext.mBoundsLocalPivot[gContext.mBoundsAxis[0]] = aabb[oppositeIndex][indices[i % 2]];// bounds[gContext.mBoundsAxis[0]] * (((i + 1) & 2) ? 1.f : -1.f); + + gContext.mbUsingBounds = true; + gContext.mEditingID = gContext.GetCurrentID(); + gContext.mBoundsMatrix = gContext.mModelSource; + } + } + + if (gContext.mbUsingBounds && (gContext.GetCurrentID() == gContext.mEditingID)) + { + matrix_t scale; + scale.SetToIdentity(); + + // compute projected mouse position on plan + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mBoundsPlan); + vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len; + + // compute a reference and delta vectors base on mouse move + vec_t deltaVector = (newPos - gContext.mBoundsPivot).Abs(); + vec_t referenceVector = (gContext.mBoundsAnchor - gContext.mBoundsPivot).Abs(); + + // for 1 or 2 axes, compute a ratio that's used for scale and snap it based on resulting length + for (int i = 0; i < 2; i++) + { + int axisIndex1 = gContext.mBoundsAxis[i]; + if (axisIndex1 == -1) + { + continue; + } + + float ratioAxis = 1.f; + vec_t axisDir = gContext.mBoundsMatrix.component[axisIndex1].Abs(); + + float dtAxis = axisDir.Dot(referenceVector); + float boundSize = bounds[axisIndex1 + 3] - bounds[axisIndex1]; + if (dtAxis > FLT_EPSILON) + { + ratioAxis = axisDir.Dot(deltaVector) / dtAxis; + } + + if (snapValues) + { + float length = boundSize * ratioAxis; + ComputeSnap(&length, snapValues[axisIndex1]); + if (boundSize > FLT_EPSILON) + { + ratioAxis = length / boundSize; + } + } + scale.component[axisIndex1] *= ratioAxis; + } + + // transform matrix + matrix_t preScale, postScale; + preScale.Translation(-gContext.mBoundsLocalPivot); + postScale.Translation(gContext.mBoundsLocalPivot); + matrix_t res = preScale * scale * postScale * gContext.mBoundsMatrix; + *matrix = res; + + // info text + char tmps[512]; + ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection); + ImFormatString(tmps, sizeof(tmps), "X: %.2f Y: %.2f Z: %.2f" + , (bounds[3] - bounds[0]) * gContext.mBoundsMatrix.component[0].Length() * scale.component[0].Length() + , (bounds[4] - bounds[1]) * gContext.mBoundsMatrix.component[1].Length() * scale.component[1].Length() + , (bounds[5] - bounds[2]) * gContext.mBoundsMatrix.component[2].Length() * scale.component[2].Length() + ); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), GetColorU32(TEXT_SHADOW), tmps); + drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), GetColorU32(TEXT), tmps); + } + + if (!io.MouseDown[0]) { + gContext.mbUsingBounds = false; + gContext.mEditingID = -1; + } + if (gContext.mbUsingBounds) + { + break; + } + } + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + + static int GetScaleType(OPERATION op) + { + if (gContext.mbUsing) + { + return MT_NONE; + } + ImGuiIO& io = ImGui::GetIO(); + int type = MT_NONE; + + // screen + if (io.MousePos.x >= gContext.mScreenSquareMin.x && io.MousePos.x <= gContext.mScreenSquareMax.x && + io.MousePos.y >= gContext.mScreenSquareMin.y && io.MousePos.y <= gContext.mScreenSquareMax.y && + Contains(op, SCALE)) + { + type = MT_SCALE_XYZ; + } + + // compute + for (int i = 0; i < 3 && type == MT_NONE; i++) + { + if(!Intersects(op, static_cast(SCALE_X << i))) + { + continue; + } + bool isAxisMasked = ((1 << i) & gContext.mAxisMask) != 0; + + vec_t dirPlaneX, dirPlaneY, dirAxis; + bool belowAxisLimit, belowPlaneLimit; + ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit, true); + dirAxis.TransformVector(gContext.mModelLocal); + dirPlaneX.TransformVector(gContext.mModelLocal); + dirPlaneY.TransformVector(gContext.mModelLocal); + + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, BuildPlan(gContext.mModelLocal.v.position, dirAxis)); + vec_t posOnPlan = gContext.mRayOrigin + gContext.mRayVector * len; + + const float startOffset = Contains(op, static_cast(TRANSLATE_X << i)) ? 1.0f : 0.1f; + const float endOffset = Contains(op, static_cast(TRANSLATE_X << i)) ? 1.4f : 1.0f; + const ImVec2 posOnPlanScreen = worldToPos(posOnPlan, gContext.mViewProjection); + const ImVec2 axisStartOnScreen = worldToPos(gContext.mModelLocal.v.position + dirAxis * gContext.mScreenFactor * startOffset, gContext.mViewProjection); + const ImVec2 axisEndOnScreen = worldToPos(gContext.mModelLocal.v.position + dirAxis * gContext.mScreenFactor * endOffset, gContext.mViewProjection); + + vec_t closestPointOnAxis = PointOnSegment(makeVect(posOnPlanScreen), makeVect(axisStartOnScreen), makeVect(axisEndOnScreen)); + + if ((closestPointOnAxis - makeVect(posOnPlanScreen)).Length() < 12.f) // pixel size + { + if (!isAxisMasked) + type = MT_SCALE_X + i; + } + } + + // universal + + vec_t deltaScreen = { io.MousePos.x - gContext.mScreenSquareCenter.x, io.MousePos.y - gContext.mScreenSquareCenter.y, 0.f, 0.f }; + float dist = deltaScreen.Length(); + if (Contains(op, SCALEU) && dist >= 17.0f && dist < 23.0f) + { + type = MT_SCALE_XYZ; + } + + for (int i = 0; i < 3 && type == MT_NONE; i++) + { + if (!Intersects(op, static_cast(SCALE_XU << i))) + { + continue; + } + + vec_t dirPlaneX, dirPlaneY, dirAxis; + bool belowAxisLimit, belowPlaneLimit; + ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit, true); + + // draw axis + if (belowAxisLimit) + { + bool hasTranslateOnAxis = Contains(op, static_cast(TRANSLATE_X << i)); + float markerScale = hasTranslateOnAxis ? 1.4f : 1.0f; + //ImVec2 baseSSpace = worldToPos(dirAxis * 0.1f * gContext.mScreenFactor, gContext.mMVPLocal); + //ImVec2 worldDirSSpaceNoScale = worldToPos(dirAxis * markerScale * gContext.mScreenFactor, gContext.mMVP); + ImVec2 worldDirSSpace = worldToPos((dirAxis * markerScale) * gContext.mScreenFactor, gContext.mMVPLocal); + + float distance = sqrtf(ImLengthSqr(worldDirSSpace - io.MousePos)); + if (distance < 12.f) + { + type = MT_SCALE_X + i; + } + } + } + return type; + } + + static int GetRotateType(OPERATION op) + { + if (gContext.mbUsing) + { + return MT_NONE; + } + + bool isNoAxesMasked = !gContext.mAxisMask; + bool isMultipleAxesMasked = (gContext.mAxisMask & (gContext.mAxisMask - 1)) != 0; + + ImGuiIO& io = ImGui::GetIO(); + int type = MT_NONE; + + vec_t deltaScreen = { io.MousePos.x - gContext.mScreenSquareCenter.x, io.MousePos.y - gContext.mScreenSquareCenter.y, 0.f, 0.f }; + float dist = deltaScreen.Length(); + if (Intersects(op, ROTATE_SCREEN) && dist >= (gContext.mRadiusSquareCenter - 4.0f) && dist < (gContext.mRadiusSquareCenter + 4.0f)) + { + if (!isNoAxesMasked) + return MT_NONE; + type = MT_ROTATE_SCREEN; + } + + const vec_t planNormals[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir }; + + vec_t modelViewPos; + modelViewPos.TransformPoint(gContext.mModel.v.position, gContext.mViewMat); + + for (int i = 0; i < 3 && type == MT_NONE; i++) + { + if(!Intersects(op, static_cast(ROTATE_X << i))) + { + continue; + } + bool isAxisMasked = ((1 << i) & gContext.mAxisMask) != 0; + // pickup plan + vec_t pickupPlan = BuildPlan(gContext.mModel.v.position, planNormals[i]); + + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, pickupPlan); + const vec_t intersectWorldPos = gContext.mRayOrigin + gContext.mRayVector * len; + vec_t intersectViewPos; + intersectViewPos.TransformPoint(intersectWorldPos, gContext.mViewMat); + + if (ImAbs(modelViewPos.z) - ImAbs(intersectViewPos.z) < -FLT_EPSILON) + { + continue; + } + + const vec_t localPos = intersectWorldPos - gContext.mModel.v.position; + vec_t idealPosOnCircle = Normalized(localPos); + idealPosOnCircle.TransformVector(gContext.mModelInverse); + const ImVec2 idealPosOnCircleScreen = worldToPos(idealPosOnCircle * rotationDisplayFactor * gContext.mScreenFactor, gContext.mMVP); + + //gContext.mDrawList->AddCircle(idealPosOnCircleScreen, 5.f, IM_COL32_WHITE); + const ImVec2 distanceOnScreen = idealPosOnCircleScreen - io.MousePos; + + const float distance = makeVect(distanceOnScreen).Length(); + if (distance < 8.f) // pixel size + { + if ((!isAxisMasked || isMultipleAxesMasked) && !isNoAxesMasked) + break; + type = MT_ROTATE_X + i; + } + } + + return type; + } + + static int GetMoveType(OPERATION op, vec_t* gizmoHitProportion) + { + if(!Intersects(op, TRANSLATE) || gContext.mbUsing || !gContext.mbMouseOver) + { + return MT_NONE; + } + + bool isNoAxesMasked = !gContext.mAxisMask; + bool isMultipleAxesMasked = (gContext.mAxisMask & (gContext.mAxisMask - 1)) != 0; + + ImGuiIO& io = ImGui::GetIO(); + int type = MT_NONE; + + // screen + if (io.MousePos.x >= gContext.mScreenSquareMin.x && io.MousePos.x <= gContext.mScreenSquareMax.x && + io.MousePos.y >= gContext.mScreenSquareMin.y && io.MousePos.y <= gContext.mScreenSquareMax.y && + Contains(op, TRANSLATE)) + { + type = MT_MOVE_SCREEN; + } + + const vec_t screenCoord = makeVect(io.MousePos - ImVec2(gContext.mX, gContext.mY)); + + // compute + for (int i = 0; i < 3 && type == MT_NONE; i++) + { + bool isAxisMasked = ((1 << i) & gContext.mAxisMask) != 0; + vec_t dirPlaneX, dirPlaneY, dirAxis; + bool belowAxisLimit, belowPlaneLimit; + ComputeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit); + dirAxis.TransformVector(gContext.mModel); + dirPlaneX.TransformVector(gContext.mModel); + dirPlaneY.TransformVector(gContext.mModel); + + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, BuildPlan(gContext.mModel.v.position, dirAxis)); + vec_t posOnPlan = gContext.mRayOrigin + gContext.mRayVector * len; + + const ImVec2 axisStartOnScreen = worldToPos(gContext.mModel.v.position + dirAxis * gContext.mScreenFactor * 0.1f, gContext.mViewProjection) - ImVec2(gContext.mX, gContext.mY); + const ImVec2 axisEndOnScreen = worldToPos(gContext.mModel.v.position + dirAxis * gContext.mScreenFactor, gContext.mViewProjection) - ImVec2(gContext.mX, gContext.mY); + + vec_t closestPointOnAxis = PointOnSegment(screenCoord, makeVect(axisStartOnScreen), makeVect(axisEndOnScreen)); + if ((closestPointOnAxis - screenCoord).Length() < 12.f && Intersects(op, static_cast(TRANSLATE_X << i))) // pixel size + { + if (isAxisMasked) + break; + type = MT_MOVE_X + i; + } + + const float dx = dirPlaneX.Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor)); + const float dy = dirPlaneY.Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor)); + if (belowPlaneLimit && dx >= quadUV[0] && dx <= quadUV[4] && dy >= quadUV[1] && dy <= quadUV[3] && Contains(op, TRANSLATE_PLANS[i])) + { + if ((!isAxisMasked || isMultipleAxesMasked) && !isNoAxesMasked) + break; + type = MT_MOVE_YZ + i; + } + + if (gizmoHitProportion) + { + *gizmoHitProportion = makeVect(dx, dy, 0.f); + } + } + return type; + } + + static bool HandleTranslation(float* matrix, float* deltaMatrix, OPERATION op, int& type, const float* snap) + { + if(!Intersects(op, TRANSLATE) || type != MT_NONE) + { + return false; + } + const ImGuiIO& io = ImGui::GetIO(); + const bool applyRotationLocaly = gContext.mMode == LOCAL || type == MT_MOVE_SCREEN; + bool modified = false; + + // move + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsTranslateType(gContext.mCurrentOperation)) + { +#if IMGUI_VERSION_NUM >= 18723 + ImGui::SetNextFrameWantCaptureMouse(true); +#else + ImGui::CaptureMouseFromApp(); +#endif + const float signedLength = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan); + const float len = fabsf(signedLength); // near plan + const vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len; + + // compute delta + const vec_t newOrigin = newPos - gContext.mRelativeOrigin * gContext.mScreenFactor; + vec_t delta = newOrigin - gContext.mModel.v.position; + + // 1 axis constraint + if (gContext.mCurrentOperation >= MT_MOVE_X && gContext.mCurrentOperation <= MT_MOVE_Z) + { + const int axisIndex = gContext.mCurrentOperation - MT_MOVE_X; + const vec_t& axisValue = *(vec_t*)&gContext.mModel.m[axisIndex]; + const float lengthOnAxis = Dot(axisValue, delta); + delta = axisValue * lengthOnAxis; + } + + // snap + if (snap) + { + vec_t cumulativeDelta = gContext.mModel.v.position + delta - gContext.mMatrixOrigin; + if (applyRotationLocaly) + { + matrix_t modelSourceNormalized = gContext.mModelSource; + modelSourceNormalized.OrthoNormalize(); + matrix_t modelSourceNormalizedInverse; + modelSourceNormalizedInverse.Inverse(modelSourceNormalized); + cumulativeDelta.TransformVector(modelSourceNormalizedInverse); + ComputeSnap(cumulativeDelta, snap); + cumulativeDelta.TransformVector(modelSourceNormalized); + } + else + { + ComputeSnap(cumulativeDelta, snap); + } + delta = gContext.mMatrixOrigin + cumulativeDelta - gContext.mModel.v.position; + + } + + if (delta != gContext.mTranslationLastDelta) + { + modified = true; + } + gContext.mTranslationLastDelta = delta; + + // compute matrix & delta + matrix_t deltaMatrixTranslation; + deltaMatrixTranslation.Translation(delta); + if (deltaMatrix) + { + memcpy(deltaMatrix, deltaMatrixTranslation.m16, sizeof(float) * 16); + } + + const matrix_t res = gContext.mModelSource * deltaMatrixTranslation; + *(matrix_t*)matrix = res; + + if (!io.MouseDown[0]) + { + gContext.mbUsing = false; + } + + type = gContext.mCurrentOperation; + } + else + { + // find new possible way to move + vec_t gizmoHitProportion; + type = gContext.mbOverGizmoHotspot ? MT_NONE : GetMoveType(op, &gizmoHitProportion); + gContext.mbOverGizmoHotspot |= type != MT_NONE; + if (type != MT_NONE) + { +#if IMGUI_VERSION_NUM >= 18723 + ImGui::SetNextFrameWantCaptureMouse(true); +#else + ImGui::CaptureMouseFromApp(); +#endif + } + if (CanActivate() && type != MT_NONE) + { + gContext.mbUsing = true; + gContext.mEditingID = gContext.GetCurrentID(); + gContext.mCurrentOperation = type; + vec_t movePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, + gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, + -gContext.mCameraDir }; + + vec_t cameraToModelNormalized = Normalized(gContext.mModel.v.position - gContext.mCameraEye); + for (unsigned int i = 0; i < 3; i++) + { + vec_t orthoVector = Cross(movePlanNormal[i], cameraToModelNormalized); + movePlanNormal[i].Cross(orthoVector); + movePlanNormal[i].Normalize(); + } + // pickup plan + gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, movePlanNormal[type - MT_MOVE_X]); + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan); + gContext.mTranslationPlanOrigin = gContext.mRayOrigin + gContext.mRayVector * len; + gContext.mMatrixOrigin = gContext.mModel.v.position; + + gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor); + } + } + return modified; + } + + static bool HandleScale(float* matrix, float* deltaMatrix, OPERATION op, int& type, const float* snap) + { + if((!Intersects(op, SCALE) && !Intersects(op, SCALEU)) || type != MT_NONE || !gContext.mbMouseOver) + { + return false; + } + ImGuiIO& io = ImGui::GetIO(); + bool modified = false; + + if (!gContext.mbUsing) + { + // find new possible way to scale + type = gContext.mbOverGizmoHotspot ? MT_NONE : GetScaleType(op); + gContext.mbOverGizmoHotspot |= type != MT_NONE; + + if (type != MT_NONE) + { +#if IMGUI_VERSION_NUM >= 18723 + ImGui::SetNextFrameWantCaptureMouse(true); +#else + ImGui::CaptureMouseFromApp(); +#endif + } + if (CanActivate() && type != MT_NONE) + { + gContext.mbUsing = true; + gContext.mEditingID = gContext.GetCurrentID(); + gContext.mCurrentOperation = type; + const vec_t movePlanNormal[] = { gContext.mModelLocal.v.up, gContext.mModelLocal.v.dir, gContext.mModelLocal.v.right, gContext.mModelLocal.v.dir, gContext.mModelLocal.v.up, gContext.mModelLocal.v.right, -gContext.mCameraDir }; + // pickup plan + + gContext.mTranslationPlan = BuildPlan(gContext.mModelLocal.v.position, movePlanNormal[type - MT_SCALE_X]); + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan); + gContext.mTranslationPlanOrigin = gContext.mRayOrigin + gContext.mRayVector * len; + gContext.mMatrixOrigin = gContext.mModelLocal.v.position; + gContext.mScale.Set(1.f, 1.f, 1.f); + gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModelLocal.v.position) * (1.f / gContext.mScreenFactor); + gContext.mScaleValueOrigin = makeVect(gContext.mModelSource.v.right.Length(), gContext.mModelSource.v.up.Length(), gContext.mModelSource.v.dir.Length()); + gContext.mSaveMousePosx = io.MousePos.x; + } + } + // scale + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsScaleType(gContext.mCurrentOperation)) + { +#if IMGUI_VERSION_NUM >= 18723 + ImGui::SetNextFrameWantCaptureMouse(true); +#else + ImGui::CaptureMouseFromApp(); +#endif + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan); + vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len; + vec_t newOrigin = newPos - gContext.mRelativeOrigin * gContext.mScreenFactor; + vec_t delta = newOrigin - gContext.mModelLocal.v.position; + + // 1 axis constraint + if (gContext.mCurrentOperation >= MT_SCALE_X && gContext.mCurrentOperation <= MT_SCALE_Z) + { + int axisIndex = gContext.mCurrentOperation - MT_SCALE_X; + const vec_t& axisValue = *(vec_t*)&gContext.mModelLocal.m[axisIndex]; + float lengthOnAxis = Dot(axisValue, delta); + delta = axisValue * lengthOnAxis; + + vec_t baseVector = gContext.mTranslationPlanOrigin - gContext.mModelLocal.v.position; + float ratio = Dot(axisValue, baseVector + delta) / Dot(axisValue, baseVector); + + gContext.mScale[axisIndex] = max(ratio, 0.001f); + } + else + { + float scaleDelta = (io.MousePos.x - gContext.mSaveMousePosx) * 0.01f; + gContext.mScale.Set(max(1.f + scaleDelta, 0.001f)); + } + + // snap + if (snap) + { + float scaleSnap[] = { snap[0], snap[0], snap[0] }; + ComputeSnap(gContext.mScale, scaleSnap); + } + + // no 0 allowed + for (int i = 0; i < 3; i++) + gContext.mScale[i] = max(gContext.mScale[i], 0.001f); + + if (gContext.mScaleLast != gContext.mScale) + { + modified = true; + } + gContext.mScaleLast = gContext.mScale; + + // compute matrix & delta + matrix_t deltaMatrixScale; + deltaMatrixScale.Scale(gContext.mScale * gContext.mScaleValueOrigin); + + matrix_t res = deltaMatrixScale * gContext.mModelLocal; + *(matrix_t*)matrix = res; + + if (deltaMatrix) + { + vec_t deltaScale = gContext.mScale * gContext.mScaleValueOrigin; + + vec_t originalScaleDivider; + originalScaleDivider.x = 1 / gContext.mModelScaleOrigin.x; + originalScaleDivider.y = 1 / gContext.mModelScaleOrigin.y; + originalScaleDivider.z = 1 / gContext.mModelScaleOrigin.z; + + deltaScale = deltaScale * originalScaleDivider; + + deltaMatrixScale.Scale(deltaScale); + memcpy(deltaMatrix, deltaMatrixScale.m16, sizeof(float) * 16); + } + + if (!io.MouseDown[0]) + { + gContext.mbUsing = false; + gContext.mScale.Set(1.f, 1.f, 1.f); + } + + type = gContext.mCurrentOperation; + } + return modified; + } + + static bool HandleRotation(float* matrix, float* deltaMatrix, OPERATION op, int& type, const float* snap) + { + if(!Intersects(op, ROTATE) || type != MT_NONE || !gContext.mbMouseOver) + { + return false; + } + ImGuiIO& io = ImGui::GetIO(); + bool applyRotationLocaly = gContext.mMode == LOCAL; + bool modified = false; + + if (!gContext.mbUsing) + { + type = gContext.mbOverGizmoHotspot ? MT_NONE : GetRotateType(op); + gContext.mbOverGizmoHotspot |= type != MT_NONE; + + if (type != MT_NONE) + { +#if IMGUI_VERSION_NUM >= 18723 + ImGui::SetNextFrameWantCaptureMouse(true); +#else + ImGui::CaptureMouseFromApp(); +#endif + } + + if (type == MT_ROTATE_SCREEN) + { + applyRotationLocaly = true; + } + + if (CanActivate() && type != MT_NONE) + { + gContext.mbUsing = true; + gContext.mEditingID = gContext.GetCurrentID(); + gContext.mCurrentOperation = type; + const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir }; + // pickup plan + if (applyRotationLocaly) + { + gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, rotatePlanNormal[type - MT_ROTATE_X]); + } + else + { + gContext.mTranslationPlan = BuildPlan(gContext.mModelSource.v.position, directionUnary[type - MT_ROTATE_X]); + } + + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan); + vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position; + gContext.mRotationVectorSource = Normalized(localPos); + gContext.mRotationAngleOrigin = ComputeAngleOnPlan(); + } + } + + // rotation + if (gContext.mbUsing && (gContext.GetCurrentID() == gContext.mEditingID) && IsRotateType(gContext.mCurrentOperation)) + { +#if IMGUI_VERSION_NUM >= 18723 + ImGui::SetNextFrameWantCaptureMouse(true); +#else + ImGui::CaptureMouseFromApp(); +#endif + gContext.mRotationAngle = ComputeAngleOnPlan(); + if (snap) + { + float snapInRadian = snap[0] * DEG2RAD; + ComputeSnap(&gContext.mRotationAngle, snapInRadian); + } + vec_t rotationAxisLocalSpace; + + rotationAxisLocalSpace.TransformVector(makeVect(gContext.mTranslationPlan.x, gContext.mTranslationPlan.y, gContext.mTranslationPlan.z, 0.f), gContext.mModelInverse); + rotationAxisLocalSpace.Normalize(); + + matrix_t deltaRotation; + deltaRotation.RotationAxis(rotationAxisLocalSpace, gContext.mRotationAngle - gContext.mRotationAngleOrigin); + if (gContext.mRotationAngle != gContext.mRotationAngleOrigin) + { + modified = true; + } + gContext.mRotationAngleOrigin = gContext.mRotationAngle; + + matrix_t scaleOrigin; + scaleOrigin.Scale(gContext.mModelScaleOrigin); + + if (applyRotationLocaly) + { + *(matrix_t*)matrix = scaleOrigin * deltaRotation * gContext.mModelLocal; + } + else + { + matrix_t res = gContext.mModelSource; + res.v.position.Set(0.f); + + *(matrix_t*)matrix = res * deltaRotation; + ((matrix_t*)matrix)->v.position = gContext.mModelSource.v.position; + } + + if (deltaMatrix) + { + *(matrix_t*)deltaMatrix = gContext.mModelInverse * deltaRotation * gContext.mModel; + } + + if (!io.MouseDown[0]) + { + gContext.mbUsing = false; + gContext.mEditingID = -1; + } + type = gContext.mCurrentOperation; + } + return modified; + } + + void DecomposeMatrixToComponents(const float* matrix, float* translation, float* rotation, float* scale) + { + matrix_t mat = *(matrix_t*)matrix; + + scale[0] = mat.v.right.Length(); + scale[1] = mat.v.up.Length(); + scale[2] = mat.v.dir.Length(); + + mat.OrthoNormalize(); + + rotation[0] = RAD2DEG * atan2f(mat.m[1][2], mat.m[2][2]); + rotation[1] = RAD2DEG * atan2f(-mat.m[0][2], sqrtf(mat.m[1][2] * mat.m[1][2] + mat.m[2][2] * mat.m[2][2])); + rotation[2] = RAD2DEG * atan2f(mat.m[0][1], mat.m[0][0]); + + translation[0] = mat.v.position.x; + translation[1] = mat.v.position.y; + translation[2] = mat.v.position.z; + } + + void RecomposeMatrixFromComponents(const float* translation, const float* rotation, const float* scale, float* matrix) + { + matrix_t& mat = *(matrix_t*)matrix; + + matrix_t rot[3]; + for (int i = 0; i < 3; i++) + { + rot[i].RotationAxis(directionUnary[i], rotation[i] * DEG2RAD); + } + + mat = rot[0] * rot[1] * rot[2]; + + float validScale[3]; + for (int i = 0; i < 3; i++) + { + if (fabsf(scale[i]) < FLT_EPSILON) + { + validScale[i] = 0.001f; + } + else + { + validScale[i] = scale[i]; + } + } + mat.v.right *= validScale[0]; + mat.v.up *= validScale[1]; + mat.v.dir *= validScale[2]; + mat.v.position.Set(translation[0], translation[1], translation[2], 1.f); + } + + void SetAlternativeWindow(ImGuiWindow* window) + { + gContext.mAlternativeWindow = window; + } + + void SetID(int id) + { + if (gContext.mIDStack.empty()) + { + gContext.mIDStack.push_back(-1); + } + gContext.mIDStack.back() = id; + } + + ImGuiID GetID(const char* str, const char* str_end) + { + ImGuiID seed = gContext.GetCurrentID(); + ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); + return id; + } + + ImGuiID GetID(const char* str) + { + return GetID(str, nullptr); + } + + ImGuiID GetID(const void* ptr) + { + ImGuiID seed = gContext.GetCurrentID(); + ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); + return id; + } + + ImGuiID GetID(int n) + { + ImGuiID seed = gContext.GetCurrentID(); + ImGuiID id = ImHashData(&n, sizeof(n), seed); + return id; + } + + void PushID(const char* str_id) + { + ImGuiID id = GetID(str_id); + gContext.mIDStack.push_back(id); + } + + void PushID(const char* str_id_begin, const char* str_id_end) + { + ImGuiID id = GetID(str_id_begin, str_id_end); + gContext.mIDStack.push_back(id); + } + + void PushID(const void* ptr_id) + { + ImGuiID id = GetID(ptr_id); + gContext.mIDStack.push_back(id); + } + + void PushID(int int_id) + { + ImGuiID id = GetID(int_id); + gContext.mIDStack.push_back(id); + } + + void PopID() + { + IM_ASSERT(gContext.mIDStack.Size > 1); // Too many PopID(), or could be popping in a wrong/different window? + gContext.mIDStack.pop_back(); + } + + void AllowAxisFlip(bool value) + { + gContext.mAllowAxisFlip = value; + } + + void SetAxisLimit(float value) + { + gContext.mAxisLimit=value; + } + + void SetAxisMask(bool x, bool y, bool z) + { + gContext.mAxisMask = (x ? 1 : 0) + (y ? 2 : 0) + (z ? 4 : 0); + } + + void SetPlaneLimit(float value) + { + gContext.mPlaneLimit = value; + } + + bool IsOver(float* position, float pixelRadius) + { + const ImGuiIO& io = ImGui::GetIO(); + + float radius = sqrtf((ImLengthSqr(worldToPos({ position[0], position[1], position[2], 0.0f }, gContext.mViewProjection) - io.MousePos))); + return radius < pixelRadius; + } + + bool Manipulate(const float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float* deltaMatrix, const float* snap, const float* localBounds, const float* boundsSnap) + { + gContext.mDrawList->PushClipRect (ImVec2 (gContext.mX, gContext.mY), ImVec2 (gContext.mX + gContext.mWidth, gContext.mY + gContext.mHeight), false); + + // Scale is always local or matrix will be skewed when applying world scale or oriented matrix + ComputeContext(view, projection, matrix, (operation & SCALE) ? LOCAL : mode); + + // set delta to identity + if (deltaMatrix) + { + ((matrix_t*)deltaMatrix)->SetToIdentity(); + } + + // behind camera + vec_t camSpacePosition; + camSpacePosition.TransformPoint(makeVect(0.f, 0.f, 0.f), gContext.mMVP); + if (!gContext.mIsOrthographic && camSpacePosition.z < 0.001f && !gContext.mbUsing) + { + return false; + } + + // -- + int type = MT_NONE; + bool manipulated = false; + if (gContext.mbEnable) + { + if (!gContext.mbUsingBounds) + { + manipulated = HandleTranslation(matrix, deltaMatrix, operation, type, snap) || + HandleScale(matrix, deltaMatrix, operation, type, snap) || + HandleRotation(matrix, deltaMatrix, operation, type, snap); + } + } + + if (localBounds && !gContext.mbUsing) + { + HandleAndDrawLocalBounds(localBounds, (matrix_t*)matrix, boundsSnap, operation); + } + + gContext.mOperation = operation; + if (!gContext.mbUsingBounds) + { + DrawRotationGizmo(operation, type); + DrawTranslationGizmo(operation, type); + DrawScaleGizmo(operation, type); + DrawScaleUniveralGizmo(operation, type); + } + + gContext.mDrawList->PopClipRect (); + return manipulated; + } + + void SetGizmoSizeClipSpace(float value) + { + gContext.mGizmoSizeClipSpace = value; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeFrustumPlanes(vec_t* frustum, const float* clip) + { + frustum[0].x = clip[3] - clip[0]; + frustum[0].y = clip[7] - clip[4]; + frustum[0].z = clip[11] - clip[8]; + frustum[0].w = clip[15] - clip[12]; + + frustum[1].x = clip[3] + clip[0]; + frustum[1].y = clip[7] + clip[4]; + frustum[1].z = clip[11] + clip[8]; + frustum[1].w = clip[15] + clip[12]; + + frustum[2].x = clip[3] + clip[1]; + frustum[2].y = clip[7] + clip[5]; + frustum[2].z = clip[11] + clip[9]; + frustum[2].w = clip[15] + clip[13]; + + frustum[3].x = clip[3] - clip[1]; + frustum[3].y = clip[7] - clip[5]; + frustum[3].z = clip[11] - clip[9]; + frustum[3].w = clip[15] - clip[13]; + + frustum[4].x = clip[3] - clip[2]; + frustum[4].y = clip[7] - clip[6]; + frustum[4].z = clip[11] - clip[10]; + frustum[4].w = clip[15] - clip[14]; + + frustum[5].x = clip[3] + clip[2]; + frustum[5].y = clip[7] + clip[6]; + frustum[5].z = clip[11] + clip[10]; + frustum[5].w = clip[15] + clip[14]; + + for (int i = 0; i < 6; i++) + { + frustum[i].Normalize(); + } + } + + void DrawCubes(const float* view, const float* projection, const float* matrices, int matrixCount) + { + matrix_t viewInverse; + viewInverse.Inverse(*(matrix_t*)view); + + struct CubeFace + { + float z; + ImVec2 faceCoordsScreen[4]; + ImU32 color; + }; + CubeFace* faces = (CubeFace*)_malloca(sizeof(CubeFace) * matrixCount * 6); + + if (!faces) + { + return; + } + + vec_t frustum[6]; + matrix_t viewProjection = *(matrix_t*)view * *(matrix_t*)projection; + ComputeFrustumPlanes(frustum, viewProjection.m16); + + int cubeFaceCount = 0; + for (int cube = 0; cube < matrixCount; cube++) + { + const float* matrix = &matrices[cube * 16]; + + matrix_t res = *(matrix_t*)matrix * *(matrix_t*)view * *(matrix_t*)projection; + + for (int iFace = 0; iFace < 6; iFace++) + { + const int normalIndex = (iFace % 3); + const int perpXIndex = (normalIndex + 1) % 3; + const int perpYIndex = (normalIndex + 2) % 3; + const float invert = (iFace > 2) ? -1.f : 1.f; + + const vec_t faceCoords[4] = { directionUnary[normalIndex] + directionUnary[perpXIndex] + directionUnary[perpYIndex], + directionUnary[normalIndex] + directionUnary[perpXIndex] - directionUnary[perpYIndex], + directionUnary[normalIndex] - directionUnary[perpXIndex] - directionUnary[perpYIndex], + directionUnary[normalIndex] - directionUnary[perpXIndex] + directionUnary[perpYIndex], + }; + + // clipping + /* + bool skipFace = false; + for (unsigned int iCoord = 0; iCoord < 4; iCoord++) + { + vec_t camSpacePosition; + camSpacePosition.TransformPoint(faceCoords[iCoord] * 0.5f * invert, res); + if (camSpacePosition.z < 0.001f) + { + skipFace = true; + break; + } + } + if (skipFace) + { + continue; + } + */ + vec_t centerPosition, centerPositionVP; + centerPosition.TransformPoint(directionUnary[normalIndex] * 0.5f * invert, *(matrix_t*)matrix); + centerPositionVP.TransformPoint(directionUnary[normalIndex] * 0.5f * invert, res); + + bool inFrustum = true; + for (int iFrustum = 0; iFrustum < 6; iFrustum++) + { + float dist = DistanceToPlane(centerPosition, frustum[iFrustum]); + if (dist < 0.f) + { + inFrustum = false; + break; + } + } + + if (!inFrustum) + { + continue; + } + CubeFace& cubeFace = faces[cubeFaceCount]; + + // 3D->2D + //ImVec2 faceCoordsScreen[4]; + for (unsigned int iCoord = 0; iCoord < 4; iCoord++) + { + cubeFace.faceCoordsScreen[iCoord] = worldToPos(faceCoords[iCoord] * 0.5f * invert, res); + } + + ImU32 directionColor = GetColorU32(DIRECTION_X + normalIndex); + cubeFace.color = directionColor | IM_COL32(0x80, 0x80, 0x80, 0); + + cubeFace.z = centerPositionVP.z / centerPositionVP.w; + cubeFaceCount++; + } + } + qsort(faces, cubeFaceCount, sizeof(CubeFace), [](void const* _a, void const* _b) { + CubeFace* a = (CubeFace*)_a; + CubeFace* b = (CubeFace*)_b; + if (a->z < b->z) + { + return 1; + } + return -1; + }); + // draw face with lighter color + for (int iFace = 0; iFace < cubeFaceCount; iFace++) + { + const CubeFace& cubeFace = faces[iFace]; + gContext.mDrawList->AddConvexPolyFilled(cubeFace.faceCoordsScreen, 4, cubeFace.color); + } + + _freea(faces); + } + + void DrawGrid(const float* view, const float* projection, const float* matrix, const float gridSize) + { + matrix_t viewProjection = *(matrix_t*)view * *(matrix_t*)projection; + vec_t frustum[6]; + ComputeFrustumPlanes(frustum, viewProjection.m16); + matrix_t res = *(matrix_t*)matrix * viewProjection; + + for (float f = -gridSize; f <= gridSize; f += 1.f) + { + for (int dir = 0; dir < 2; dir++) + { + vec_t ptA = makeVect(dir ? -gridSize : f, 0.f, dir ? f : -gridSize); + vec_t ptB = makeVect(dir ? gridSize : f, 0.f, dir ? f : gridSize); + bool visible = true; + for (int i = 0; i < 6; i++) + { + float dA = DistanceToPlane(ptA, frustum[i]); + float dB = DistanceToPlane(ptB, frustum[i]); + if (dA < 0.f && dB < 0.f) + { + visible = false; + break; + } + if (dA > 0.f && dB > 0.f) + { + continue; + } + if (dA < 0.f) + { + float len = fabsf(dA - dB); + float t = fabsf(dA) / len; + ptA.Lerp(ptB, t); + } + if (dB < 0.f) + { + float len = fabsf(dB - dA); + float t = fabsf(dB) / len; + ptB.Lerp(ptA, t); + } + } + if (visible) + { + ImU32 col = IM_COL32(0x80, 0x80, 0x80, 0xFF); + col = (fmodf(fabsf(f), 10.f) < FLT_EPSILON) ? IM_COL32(0x90, 0x90, 0x90, 0xFF) : col; + col = (fabsf(f) < FLT_EPSILON) ? IM_COL32(0x40, 0x40, 0x40, 0xFF): col; + + float thickness = 1.f; + thickness = (fmodf(fabsf(f), 10.f) < FLT_EPSILON) ? 1.5f : thickness; + thickness = (fabsf(f) < FLT_EPSILON) ? 2.3f : thickness; + + gContext.mDrawList->AddLine(worldToPos(ptA, res), worldToPos(ptB, res), col, thickness); + } + } + } + } + + void ViewManipulate(float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor) + { + // Scale is always local or matrix will be skewed when applying world scale or oriented matrix + ComputeContext(view, projection, matrix, (operation & SCALE) ? LOCAL : mode); + ViewManipulate(view, length, position, size, backgroundColor); + } + + void ViewManipulate(float* view, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor) + { + static bool isDraging = false; + static bool isClicking = false; + static vec_t interpolationUp; + static vec_t interpolationDir; + static int interpolationFrames = 0; + const vec_t referenceUp = makeVect(0.f, 1.f, 0.f); + + matrix_t svgView, svgProjection; + svgView = gContext.mViewMat; + svgProjection = gContext.mProjectionMat; + + ImGuiIO& io = ImGui::GetIO(); + gContext.mDrawList->AddRectFilled(position, position + size, backgroundColor); + matrix_t viewInverse; + viewInverse.Inverse(*(matrix_t*)view); + + const vec_t camTarget = viewInverse.v.position - viewInverse.v.dir * length; + + // view/projection matrices + const float distance = 3.f; + matrix_t cubeProjection, cubeView; + float fov = acosf(distance / (sqrtf(distance * distance + 3.f))) * RAD2DEG; + Perspective(fov / sqrtf(2.f), size.x / size.y, 0.01f, 1000.f, cubeProjection.m16); + + vec_t dir = makeVect(viewInverse.m[2][0], viewInverse.m[2][1], viewInverse.m[2][2]); + vec_t up = makeVect(viewInverse.m[1][0], viewInverse.m[1][1], viewInverse.m[1][2]); + vec_t eye = dir * distance; + vec_t zero = makeVect(0.f, 0.f); + LookAt(&eye.x, &zero.x, &up.x, cubeView.m16); + + // set context + gContext.mViewMat = cubeView; + gContext.mProjectionMat = cubeProjection; + ComputeCameraRay(gContext.mRayOrigin, gContext.mRayVector, position, size); + + const matrix_t res = cubeView * cubeProjection; + + // panels + static const ImVec2 panelPosition[9] = { ImVec2(0.75f,0.75f), ImVec2(0.25f, 0.75f), ImVec2(0.f, 0.75f), + ImVec2(0.75f, 0.25f), ImVec2(0.25f, 0.25f), ImVec2(0.f, 0.25f), + ImVec2(0.75f, 0.f), ImVec2(0.25f, 0.f), ImVec2(0.f, 0.f) }; + + static const ImVec2 panelSize[9] = { ImVec2(0.25f,0.25f), ImVec2(0.5f, 0.25f), ImVec2(0.25f, 0.25f), + ImVec2(0.25f, 0.5f), ImVec2(0.5f, 0.5f), ImVec2(0.25f, 0.5f), + ImVec2(0.25f, 0.25f), ImVec2(0.5f, 0.25f), ImVec2(0.25f, 0.25f) }; + + // tag faces + bool boxes[27]{}; + static int overBox = -1; + for (int iPass = 0; iPass < 2; iPass++) + { + for (int iFace = 0; iFace < 6; iFace++) + { + const int normalIndex = (iFace % 3); + const int perpXIndex = (normalIndex + 1) % 3; + const int perpYIndex = (normalIndex + 2) % 3; + const float invert = (iFace > 2) ? -1.f : 1.f; + const vec_t indexVectorX = directionUnary[perpXIndex] * invert; + const vec_t indexVectorY = directionUnary[perpYIndex] * invert; + const vec_t boxOrigin = directionUnary[normalIndex] * -invert - indexVectorX - indexVectorY; + + // plan local space + const vec_t n = directionUnary[normalIndex] * invert; + vec_t viewSpaceNormal = n; + vec_t viewSpacePoint = n * 0.5f; + viewSpaceNormal.TransformVector(cubeView); + viewSpaceNormal.Normalize(); + viewSpacePoint.TransformPoint(cubeView); + const vec_t viewSpaceFacePlan = BuildPlan(viewSpacePoint, viewSpaceNormal); + + // back face culling + if (viewSpaceFacePlan.w > 0.f) + { + continue; + } + + const vec_t facePlan = BuildPlan(n * 0.5f, n); + + const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, facePlan); + vec_t posOnPlan = gContext.mRayOrigin + gContext.mRayVector * len - (n * 0.5f); + + float localx = Dot(directionUnary[perpXIndex], posOnPlan) * invert + 0.5f; + float localy = Dot(directionUnary[perpYIndex], posOnPlan) * invert + 0.5f; + + // panels + const vec_t dx = directionUnary[perpXIndex]; + const vec_t dy = directionUnary[perpYIndex]; + const vec_t origin = directionUnary[normalIndex] - dx - dy; + for (int iPanel = 0; iPanel < 9; iPanel++) + { + vec_t boxCoord = boxOrigin + indexVectorX * float(iPanel % 3) + indexVectorY * float(iPanel / 3) + makeVect(1.f, 1.f, 1.f); + const ImVec2 p = panelPosition[iPanel] * 2.f; + const ImVec2 s = panelSize[iPanel] * 2.f; + ImVec2 faceCoordsScreen[4]; + vec_t panelPos[4] = { dx * p.x + dy * p.y, + dx * p.x + dy * (p.y + s.y), + dx * (p.x + s.x) + dy * (p.y + s.y), + dx * (p.x + s.x) + dy * p.y }; + + for (unsigned int iCoord = 0; iCoord < 4; iCoord++) + { + faceCoordsScreen[iCoord] = worldToPos((panelPos[iCoord] + origin) * 0.5f * invert, res, position, size); + } + + const ImVec2 panelCorners[2] = { panelPosition[iPanel], panelPosition[iPanel] + panelSize[iPanel] }; + bool insidePanel = localx > panelCorners[0].x && localx < panelCorners[1].x && localy > panelCorners[0].y && localy < panelCorners[1].y; + int boxCoordInt = int(boxCoord.x * 9.f + boxCoord.y * 3.f + boxCoord.z); + IM_ASSERT(boxCoordInt < 27); + boxes[boxCoordInt] |= insidePanel && (!isDraging) && gContext.mbMouseOver; + + // draw face with lighter color + if (iPass) + { + ImU32 directionColor = GetColorU32(DIRECTION_X + normalIndex); + gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, (directionColor | IM_COL32(0x80, 0x80, 0x80, 0x80)) | (gContext.mIsViewManipulatorHovered ? IM_COL32(0x08, 0x08, 0x08, 0) : 0)); + if (boxes[boxCoordInt]) + { + gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, IM_COL32(0xF0, 0xA0, 0x60, 0x80)); + + if (io.MouseDown[0] && !isClicking && !isDraging && GImGui->ActiveId == 0) { + overBox = boxCoordInt; + isClicking = true; + isDraging = true; + } + } + } + } + } + } + if (interpolationFrames) + { + interpolationFrames--; + vec_t newDir = viewInverse.v.dir; + newDir.Lerp(interpolationDir, 0.2f); + newDir.Normalize(); + + vec_t newUp = viewInverse.v.up; + newUp.Lerp(interpolationUp, 0.3f); + newUp.Normalize(); + newUp = interpolationUp; + vec_t newEye = camTarget + newDir * length; + LookAt(&newEye.x, &camTarget.x, &newUp.x, view); + } + gContext.mIsViewManipulatorHovered = gContext.mbMouseOver && ImRect(position, position + size).Contains(io.MousePos); + + if (io.MouseDown[0] && (fabsf(io.MouseDelta[0]) || fabsf(io.MouseDelta[1])) && isClicking) + { + isClicking = false; + } + + if (!io.MouseDown[0]) + { + if (isClicking) + { + // apply new view direction + int cx = overBox / 9; + int cy = (overBox - cx * 9) / 3; + int cz = overBox % 3; + interpolationDir = makeVect(1.f - (float)cx, 1.f - (float)cy, 1.f - (float)cz); + interpolationDir.Normalize(); + + if (fabsf(Dot(interpolationDir, referenceUp)) > 1.0f - 0.01f) + { + vec_t right = viewInverse.v.right; + if (fabsf(right.x) > fabsf(right.z)) + { + right.z = 0.f; + } + else + { + right.x = 0.f; + } + right.Normalize(); + interpolationUp = Cross(interpolationDir, right); + interpolationUp.Normalize(); + } + else + { + interpolationUp = referenceUp; + } + interpolationFrames = 40; + + } + isClicking = false; + isDraging = false; + } + + + if (isDraging) + { + matrix_t rx, ry, roll; + + rx.RotationAxis(referenceUp, -io.MouseDelta.x * 0.01f); + ry.RotationAxis(viewInverse.v.right, -io.MouseDelta.y * 0.01f); + + roll = rx * ry; + + vec_t newDir = viewInverse.v.dir; + newDir.TransformVector(roll); + newDir.Normalize(); + + // clamp + vec_t planDir = Cross(viewInverse.v.right, referenceUp); + planDir.y = 0.f; + planDir.Normalize(); + float dt = Dot(planDir, newDir); + if (dt < 0.0f) + { + newDir += planDir * dt; + newDir.Normalize(); + } + + vec_t newEye = camTarget + newDir * length; + LookAt(&newEye.x, &camTarget.x, &referenceUp.x, view); + } + + gContext.mbUsingViewManipulate = (interpolationFrames != 0) || isDraging; + if (isClicking || gContext.mbUsingViewManipulate || gContext.mIsViewManipulatorHovered) { +#if IMGUI_VERSION_NUM >= 18723 + ImGui::SetNextFrameWantCaptureMouse(true); +#else + ImGui::CaptureMouseFromApp(); +#endif + } + + // restore view/projection because it was used to compute ray + ComputeContext(svgView.m16, svgProjection.m16, gContext.mModelSource.m16, gContext.mMode); + } +}; diff --git a/src/vendor/imguizmo/ImGuizmo.h b/src/vendor/imguizmo/ImGuizmo.h new file mode 100644 index 0000000..4ccff18 --- /dev/null +++ b/src/vendor/imguizmo/ImGuizmo.h @@ -0,0 +1,306 @@ +// https://github.com/CedricGuillemet/ImGuizmo +// v1.91.3 WIP +// +// The MIT License(MIT) +// +// Copyright(c) 2021 Cedric Guillemet +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ------------------------------------------------------------------------------------------- +// History : +// 2019/11/03 View gizmo +// 2016/09/11 Behind camera culling. Scaling Delta matrix not multiplied by source matrix scales. local/world rotation and translation fixed. Display message is incorrect (X: ... Y:...) in local mode. +// 2016/09/09 Hatched negative axis. Snapping. Documentation update. +// 2016/09/04 Axis switch and translation plan autohiding. Scale transform stability improved +// 2016/09/01 Mogwai changed to Manipulate. Draw debug cube. Fixed inverted scale. Mixing scale and translation/rotation gives bad results. +// 2016/08/31 First version +// +// ------------------------------------------------------------------------------------------- +// Future (no order): +// +// - Multi view +// - display rotation/translation/scale infos in local/world space and not only local +// - finish local/world matrix application +// - OPERATION as bitmask +// +// ------------------------------------------------------------------------------------------- +// Example +#if 0 +void EditTransform(const Camera& camera, matrix_t& matrix) +{ + static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::ROTATE); + static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD); + if (ImGui::IsKeyPressed(90)) + mCurrentGizmoOperation = ImGuizmo::TRANSLATE; + if (ImGui::IsKeyPressed(69)) + mCurrentGizmoOperation = ImGuizmo::ROTATE; + if (ImGui::IsKeyPressed(82)) // r Key + mCurrentGizmoOperation = ImGuizmo::SCALE; + if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE)) + mCurrentGizmoOperation = ImGuizmo::TRANSLATE; + ImGui::SameLine(); + if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE)) + mCurrentGizmoOperation = ImGuizmo::ROTATE; + ImGui::SameLine(); + if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE)) + mCurrentGizmoOperation = ImGuizmo::SCALE; + float matrixTranslation[3], matrixRotation[3], matrixScale[3]; + ImGuizmo::DecomposeMatrixToComponents(matrix.m16, matrixTranslation, matrixRotation, matrixScale); + ImGui::InputFloat3("Tr", matrixTranslation, 3); + ImGui::InputFloat3("Rt", matrixRotation, 3); + ImGui::InputFloat3("Sc", matrixScale, 3); + ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix.m16); + + if (mCurrentGizmoOperation != ImGuizmo::SCALE) + { + if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL)) + mCurrentGizmoMode = ImGuizmo::LOCAL; + ImGui::SameLine(); + if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD)) + mCurrentGizmoMode = ImGuizmo::WORLD; + } + static bool useSnap(false); + if (ImGui::IsKeyPressed(83)) + useSnap = !useSnap; + ImGui::Checkbox("", &useSnap); + ImGui::SameLine(); + vec_t snap; + switch (mCurrentGizmoOperation) + { + case ImGuizmo::TRANSLATE: + snap = config.mSnapTranslation; + ImGui::InputFloat3("Snap", &snap.x); + break; + case ImGuizmo::ROTATE: + snap = config.mSnapRotation; + ImGui::InputFloat("Angle Snap", &snap.x); + break; + case ImGuizmo::SCALE: + snap = config.mSnapScale; + ImGui::InputFloat("Scale Snap", &snap.x); + break; + } + ImGuiIO& io = ImGui::GetIO(); + ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y); + ImGuizmo::Manipulate(camera.mView.m16, camera.mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, matrix.m16, NULL, useSnap ? &snap.x : NULL); +} +#endif +#pragma once + +#ifdef USE_IMGUI_API +#include "imconfig.h" +#endif +#ifndef IMGUI_API +#define IMGUI_API +#endif + +#ifndef IMGUIZMO_NAMESPACE +#define IMGUIZMO_NAMESPACE ImGuizmo +#endif + +struct ImGuiWindow; + +namespace IMGUIZMO_NAMESPACE +{ + // call inside your own window and before Manipulate() in order to draw gizmo to that window. + // Or pass a specific ImDrawList to draw to (e.g. ImGui::GetForegroundDrawList()). + IMGUI_API void SetDrawlist(ImDrawList* drawlist = nullptr); + + // call BeginFrame right after ImGui_XXXX_NewFrame(); + IMGUI_API void BeginFrame(); + + // this is necessary because when imguizmo is compiled into a dll, and imgui into another + // globals are not shared between them. + // More details at https://stackoverflow.com/questions/19373061/what-happens-to-global-and-static-variables-in-a-shared-library-when-it-is-dynam + // expose method to set imgui context + IMGUI_API void SetImGuiContext(ImGuiContext* ctx); + + // return true if mouse cursor is over any gizmo control (axis, plan or screen component) + IMGUI_API bool IsOver(); + + // return true if mouse IsOver or if the gizmo is in moving state + IMGUI_API bool IsUsing(); + + // return true if the view gizmo is in moving state + IMGUI_API bool IsUsingViewManipulate(); + // only check if your mouse is over the view manipulator - no matter whether it's active or not + IMGUI_API bool IsViewManipulateHovered(); + + // return true if any gizmo is in moving state + IMGUI_API bool IsUsingAny(); + + // enable/disable the gizmo. Stay in the state until next call to Enable. + // gizmo is rendered with gray half transparent color when disabled + IMGUI_API void Enable(bool enable); + + // helper functions for manualy editing translation/rotation/scale with an input float + // translation, rotation and scale float points to 3 floats each + // Angles are in degrees (more suitable for human editing) + // example: + // float matrixTranslation[3], matrixRotation[3], matrixScale[3]; + // ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale); + // ImGui::InputFloat3("Tr", matrixTranslation, 3); + // ImGui::InputFloat3("Rt", matrixRotation, 3); + // ImGui::InputFloat3("Sc", matrixScale, 3); + // ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16); + // + // These functions have some numerical stability issues for now. Use with caution. + IMGUI_API void DecomposeMatrixToComponents(const float* matrix, float* translation, float* rotation, float* scale); + IMGUI_API void RecomposeMatrixFromComponents(const float* translation, const float* rotation, const float* scale, float* matrix); + + IMGUI_API void SetRect(float x, float y, float width, float height); + // default is false + IMGUI_API void SetOrthographic(bool isOrthographic); + + // Render a cube with face color corresponding to face normal. Usefull for debug/tests + IMGUI_API void DrawCubes(const float* view, const float* projection, const float* matrices, int matrixCount); + IMGUI_API void DrawGrid(const float* view, const float* projection, const float* matrix, const float gridSize); + + // call it when you want a gizmo + // Needs view and projection matrices. + // matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional + // translation is applied in world space + enum OPERATION + { + TRANSLATE_X = (1u << 0), + TRANSLATE_Y = (1u << 1), + TRANSLATE_Z = (1u << 2), + ROTATE_X = (1u << 3), + ROTATE_Y = (1u << 4), + ROTATE_Z = (1u << 5), + ROTATE_SCREEN = (1u << 6), + SCALE_X = (1u << 7), + SCALE_Y = (1u << 8), + SCALE_Z = (1u << 9), + BOUNDS = (1u << 10), + SCALE_XU = (1u << 11), + SCALE_YU = (1u << 12), + SCALE_ZU = (1u << 13), + + TRANSLATE = TRANSLATE_X | TRANSLATE_Y | TRANSLATE_Z, + ROTATE = ROTATE_X | ROTATE_Y | ROTATE_Z | ROTATE_SCREEN, + SCALE = SCALE_X | SCALE_Y | SCALE_Z, + SCALEU = SCALE_XU | SCALE_YU | SCALE_ZU, // universal + UNIVERSAL = TRANSLATE | ROTATE | SCALEU + }; + + inline OPERATION operator|(OPERATION lhs, OPERATION rhs) + { + return static_cast(static_cast(lhs) | static_cast(rhs)); + } + + enum MODE + { + LOCAL, + WORLD + }; + + IMGUI_API bool Manipulate(const float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float* deltaMatrix = NULL, const float* snap = NULL, const float* localBounds = NULL, const float* boundsSnap = NULL); + // + // Please note that this cubeview is patented by Autodesk : https://patents.google.com/patent/US7782319B2/en + // It seems to be a defensive patent in the US. I don't think it will bring troubles using it as + // other software are using the same mechanics. But just in case, you are now warned! + // + IMGUI_API void ViewManipulate(float* view, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor); + + // use this version if you did not call Manipulate before and you are just using ViewManipulate + IMGUI_API void ViewManipulate(float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor); + + IMGUI_API void SetAlternativeWindow(ImGuiWindow* window); + + [[deprecated("Use PushID/PopID instead.")]] + IMGUI_API void SetID(int id); + + // ID stack/scopes + // Read the FAQ (docs/FAQ.md or http://dearimgui.org/faq) for more details about how ID are handled in dear imgui. + // - Those questions are answered and impacted by understanding of the ID stack system: + // - "Q: Why is my widget not reacting when I click on it?" + // - "Q: How can I have widgets with an empty label?" + // - "Q: How can I have multiple widgets with the same label?" + // - Short version: ID are hashes of the entire ID stack. If you are creating widgets in a loop you most likely + // want to push a unique identifier (e.g. object pointer, loop index) to uniquely differentiate them. + // - You can also use the "Label##foobar" syntax within widget label to distinguish them from each others. + // - In this header file we use the "label"/"name" terminology to denote a string that will be displayed + used as an ID, + // whereas "str_id" denote a string that is only used as an ID and not normally displayed. + IMGUI_API void PushID(const char* str_id); // push string into the ID stack (will hash string). + IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); // push string into the ID stack (will hash string). + IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer). + IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer). + IMGUI_API void PopID(); // pop from the ID stack. + IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself + IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); + IMGUI_API ImGuiID GetID(const void* ptr_id); + + // return true if the cursor is over the operation's gizmo + IMGUI_API bool IsOver(OPERATION op); + IMGUI_API void SetGizmoSizeClipSpace(float value); + + // Allow axis to flip + // When true (default), the guizmo axis flip for better visibility + // When false, they always stay along the positive world/local axis + IMGUI_API void AllowAxisFlip(bool value); + + // Configure the limit where axis are hidden + IMGUI_API void SetAxisLimit(float value); + // Set an axis mask to permanently hide a given axis (true -> hidden, false -> shown) + IMGUI_API void SetAxisMask(bool x, bool y, bool z); + // Configure the limit where planes are hiden + IMGUI_API void SetPlaneLimit(float value); + // from a x,y,z point in space and using Manipulation view/projection matrix, check if mouse is in pixel radius distance of that projected point + IMGUI_API bool IsOver(float* position, float pixelRadius); + + enum COLOR + { + DIRECTION_X, // directionColor[0] + DIRECTION_Y, // directionColor[1] + DIRECTION_Z, // directionColor[2] + PLANE_X, // planeColor[0] + PLANE_Y, // planeColor[1] + PLANE_Z, // planeColor[2] + SELECTION, // selectionColor + INACTIVE, // inactiveColor + TRANSLATION_LINE, // translationLineColor + SCALE_LINE, + ROTATION_USING_BORDER, + ROTATION_USING_FILL, + HATCHED_AXIS_LINES, + TEXT, + TEXT_SHADOW, + COUNT + }; + + struct Style + { + IMGUI_API Style(); + + float TranslationLineThickness; // Thickness of lines for translation gizmo + float TranslationLineArrowSize; // Size of arrow at the end of lines for translation gizmo + float RotationLineThickness; // Thickness of lines for rotation gizmo + float RotationOuterLineThickness; // Thickness of line surrounding the rotation gizmo + float ScaleLineThickness; // Thickness of lines for scale gizmo + float ScaleLineCircleSize; // Size of circle at the end of lines for scale gizmo + float HatchedAxisLineThickness; // Thickness of hatched axis lines + float CenterCircleSize; // Size of circle at the center of the translate/scale gizmo + + ImVec4 Colors[COLOR::COUNT]; + }; + + IMGUI_API Style& GetStyle(); +}