Browse Source

Scene: Some Editor UI refactoring

Panagiotis Christopoulos Charitos 4 days ago
parent
commit
7e4312f311

+ 14 - 1
AnKi/Core/App.cpp

@@ -31,7 +31,7 @@
 #include <AnKi/Ui/UiManager.h>
 #include <AnKi/Ui/UiCanvas.h>
 #include <AnKi/Scene/DeveloperConsoleUiNode.h>
-#include <csignal>
+#include <AnKi/Resource/ScriptResource.h>
 
 #if ANKI_OS_ANDROID
 #	include <android_native_app_glue.h>
@@ -382,6 +382,14 @@ Error App::mainLoop()
 		return err;
 	}
 
+	if(CString(g_cvarCoreLoadScene) != "")
+	{
+		ANKI_LOGI("Will load scene: %s", CString(g_cvarCoreLoadScene).cstr());
+		ScriptResourcePtr script;
+		ANKI_CHECK(ResourceManager::getSingleton().loadResource(g_cvarCoreLoadScene, script));
+		ANKI_CHECK(ScriptManager::getSingleton().evalString(script->getSource()));
+	}
+
 	// Continue with the main loop
 	ANKI_CORE_LOGI("Entering main loop");
 	Bool quit = false;
@@ -414,6 +422,11 @@ Error App::mainLoop()
 			crntTime = (!benchmarkMode) ? HighRezTimer::getCurrentTime() : (prevUpdateTime + 1.0_sec / 60.0_sec);
 
 			ANKI_CHECK(Input::getSingleton().handleEvents());
+			if(Input::getSingleton().getEvent(InputEvent::kWindowClosed))
+			{
+				quit = true;
+			}
+
 			GrManager::getSingleton().beginFrame();
 
 			GpuSceneMicroPatcher::getSingleton().beginPatching();

+ 1 - 0
AnKi/Core/App.h

@@ -22,6 +22,7 @@ ANKI_CVAR(BoolCVar, Core, VerboseLog, false, "Verbose logging")
 ANKI_CVAR(BoolCVar, Core, BenchmarkMode, false, "Run in a benchmark mode. Fixed timestep, unlimited target FPS")
 ANKI_CVAR(NumericCVar<U32>, Core, BenchmarkModeFrameCount, 60 * 60 * 2, 1, kMaxU32, "How many frames the benchmark will run before it quits")
 ANKI_CVAR(BoolCVar, Core, MeshletRendering, false, "Do meshlet culling and rendering")
+ANKI_CVAR(StringCVar, Core, LoadScene, "", "Load this scene at startup")
 
 #if ANKI_PLATFORM_MOBILE
 ANKI_CVAR(BoolCVar, Core, MaliHwCounters, false, "Enable Mali counters")

+ 2 - 0
AnKi/Scene.h

@@ -32,3 +32,5 @@
 #include <AnKi/Scene/Events/JitterMoveEvent.h>
 #include <AnKi/Scene/Events/LightEvent.h>
 #include <AnKi/Scene/Events/ScriptEvent.h>
+
+#include <AnKi/Scene/EditorUiNode.h>

+ 118 - 0
AnKi/Scene/EditorUiNode.cpp

@@ -0,0 +1,118 @@
+// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Scene/EditorUiNode.h>
+#include <AnKi/Window/Input.h>
+#include <AnKi/Scene/SceneGraph.h>
+
+namespace anki {
+
+void EditorUiNode::frameUpdate([[maybe_unused]] Second prevUpdateTime, [[maybe_unused]] Second crntTime)
+{
+	if(!getFirstComponentOfType<UiComponent>().isEnabled())
+	{
+		return;
+	}
+
+	Input& in = Input::getSingleton();
+
+	if(m_editorUi.m_quit)
+	{
+		in.addEvent(InputEvent::kWindowClosed);
+	}
+
+	static Vec2 mousePosOn1stClick = in.getMousePositionNdc();
+	if(in.getMouseButton(MouseButton::kRight) == 1)
+	{
+		// Re-init mouse pos
+		mousePosOn1stClick = in.getMousePositionNdc();
+	}
+
+	if(in.getMouseButton(MouseButton::kRight) > 0 && !m_editorUi.m_mouseOverAnyWindow)
+	{
+		in.hideCursor(true);
+
+		// move the camera
+		SceneNode& mover = SceneGraph::getSingleton().getActiveCameraNode();
+
+		constexpr F32 kRotateAngle = toRad(2.5f);
+		constexpr F32 kMouseSensitivity = 5.0f;
+
+		if(in.getKey(KeyCode::kUp) > 0)
+		{
+			mover.rotateLocalX(kRotateAngle);
+		}
+
+		if(in.getKey(KeyCode::kDown) > 0)
+		{
+			mover.rotateLocalX(-kRotateAngle);
+		}
+
+		if(in.getKey(KeyCode::kLeft) > 0)
+		{
+			mover.rotateLocalY(kRotateAngle);
+		}
+
+		if(in.getKey(KeyCode::kRight) > 0)
+		{
+			mover.rotateLocalY(-kRotateAngle);
+		}
+
+		F32 moveDistance = 0.1f;
+		if(in.getKey(KeyCode::kLeftShift) > 0)
+		{
+			moveDistance *= 4.0f;
+		}
+
+		if(in.getKey(KeyCode::kA) > 0)
+		{
+			mover.moveLocalX(-moveDistance);
+		}
+
+		if(in.getKey(KeyCode::kD) > 0)
+		{
+			mover.moveLocalX(moveDistance);
+		}
+
+		if(in.getKey(KeyCode::kQ) > 0)
+		{
+			mover.moveLocalY(-moveDistance);
+		}
+
+		if(in.getKey(KeyCode::kE) > 0)
+		{
+			mover.moveLocalY(moveDistance);
+		}
+
+		if(in.getKey(KeyCode::kW) > 0)
+		{
+			mover.moveLocalZ(-moveDistance);
+		}
+
+		if(in.getKey(KeyCode::kS) > 0)
+		{
+			mover.moveLocalZ(moveDistance);
+		}
+
+		const Vec2 velocity = in.getMousePositionNdc() - mousePosOn1stClick;
+		in.moveMouseNdc(mousePosOn1stClick);
+		if(velocity != Vec2(0.0))
+		{
+			const Second dt = crntTime - prevUpdateTime;
+			Euler angles(mover.getLocalRotation().getRotationPart());
+			angles.x() += velocity.y() * toRad(360.0f) * F32(dt) * kMouseSensitivity;
+			angles.x() = clamp(angles.x(), toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
+			angles.y() += -velocity.x() * toRad(360.0f) * F32(dt) * kMouseSensitivity;
+			angles.z() = 0.0f;
+			mover.setLocalRotation(Mat3(angles));
+		}
+	}
+	else
+	{
+		in.hideCursor(false);
+	}
+}
+
+} // end namespace anki

+ 33 - 0
AnKi/Scene/EditorUiNode.h

@@ -0,0 +1,33 @@
+// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Scene/SceneNode.h>
+#include <AnKi/Scene/Components/UiComponent.h>
+#include <AnKi/Editor/EditorUi.h>
+
+namespace anki {
+
+// Contains the Editor UI. If the UI is visible then it steals the input so otheres need to disable input handling.
+class EditorUiNode : public SceneNode
+{
+public:
+	EditorUi m_editorUi;
+
+	EditorUiNode(CString name)
+		: SceneNode(name)
+	{
+		UiComponent* uic = newComponent<UiComponent>();
+		uic->init(
+			[](UiCanvas& canvas, void* ud) {
+				static_cast<EditorUiNode*>(ud)->m_editorUi.draw(canvas);
+			},
+			this);
+	}
+
+private:
+	void frameUpdate([[maybe_unused]] Second prevUpdateTime, [[maybe_unused]] Second crntTime) override;
+};
+
+} // end namespace anki

+ 7 - 2
AnKi/Scene/SceneGraph.cpp

@@ -14,6 +14,7 @@
 #include <AnKi/Core/App.h>
 #include <AnKi/Scene/StatsUiNode.h>
 #include <AnKi/Scene/DeveloperConsoleUiNode.h>
+#include <AnKi/Scene/EditorUiNode.h>
 
 #include <AnKi/Scene/Components/BodyComponent.h>
 #include <AnKi/Scene/Components/CameraComponent.h>
@@ -115,14 +116,14 @@ Error SceneGraph::init(AllocAlignedCallback allocCallback, void* allocCallbackDa
 #include <AnKi/Scene/GpuSceneArrays.def.h>
 
 	// Init the default main camera
-	m_defaultMainCam = newSceneNode<SceneNode>("mainCamera");
+	m_defaultMainCam = newSceneNode<SceneNode>("_MainCamera");
 	CameraComponent* camc = m_defaultMainCam->newComponent<CameraComponent>();
 	camc->setPerspective(0.1f, 1000.0f, toRad(60.0f), (1080.0f / 1920.0f) * toRad(60.0f));
 	m_mainCam = m_defaultMainCam;
 
 	RenderStateBucketContainer::allocateSingleton();
 
-	// Construct a few common nodex
+	// Construct a few common nodes
 	if(g_cvarCoreDisplayStats > 0)
 	{
 		StatsUiNode* statsNode = newSceneNode<StatsUiNode>("_StatsUi");
@@ -131,6 +132,10 @@ Error SceneGraph::init(AllocAlignedCallback allocCallback, void* allocCallbackDa
 
 	newSceneNode<DeveloperConsoleUiNode>("_DevConsole");
 
+	EditorUiNode* editorNode = newSceneNode<EditorUiNode>("_Editor");
+	editorNode->getFirstComponentOfType<UiComponent>().setEnabled(false);
+	m_editorUi = editorNode;
+
 	return Error::kNone;
 }
 

+ 7 - 0
AnKi/Scene/SceneGraph.h

@@ -79,6 +79,12 @@ public:
 
 	void setActiveCameraNode(SceneNode* cam);
 
+	SceneNode& getEditorUiNode()
+	{
+		ANKI_ASSERT(m_editorUi);
+		return *m_editorUi;
+	}
+
 	U32 getSceneNodesCount() const
 	{
 		return m_nodesCount;
@@ -194,6 +200,7 @@ private:
 
 	SceneNode* m_mainCam = nullptr;
 	SceneNode* m_defaultMainCam = nullptr;
+	SceneNode* m_editorUi = nullptr;
 
 	EventManager m_events;
 

+ 7 - 5
AnKi/Window/Input.h

@@ -112,16 +112,18 @@ public:
 	/// Populate the key and button with the new state
 	Error handleEvents();
 
-	/// Add a new event
+	// Add a new event
+	// It's thread-safe
 	void addEvent(InputEvent eventId)
 	{
-		++m_events[eventId];
+		m_events[eventId].fetchAdd(1);
 	}
 
-	/// Get the times an event was triggered and resets the counter
+	// Get the times an event was triggered and resets the counter
+	// It's thread-safe
 	U32 getEvent(InputEvent eventId) const
 	{
-		return m_events[eventId];
+		return m_events[eventId].exchange(0);
 	}
 
 	/// Get some easy to digest input from the keyboard.
@@ -140,7 +142,7 @@ protected:
 	Array<I32, U(TouchPointer::kCount)> m_touchPointers;
 	Array<Vec2, U(TouchPointer::kCount)> m_touchPointerPosNdc;
 
-	Array<U8, U(InputEvent::kCount)> m_events;
+	mutable Array<Atomic<U32>, U(InputEvent::kCount)> m_events;
 
 	/// The keybord input as ascii.
 	static constexpr U32 kMaxTexInput = 256;

+ 1 - 0
AnKi/Window/InputSdl.cpp

@@ -245,6 +245,7 @@ Error InputSdl::handleEventsInternal()
 			m_mousePosNdc.y() = -(F32(event.button.y) / F32(NativeWindow::getSingleton().getHeight()) * 2.0f - 1.0f);
 			break;
 		case SDL_EVENT_QUIT:
+			ANKI_WIND_LOGI("Recieved SDL_EVENT_QUIT");
 			addEvent(InputEvent::kWindowClosed);
 			break;
 		case SDL_EVENT_TEXT_INPUT:

+ 2 - 155
Tools/Editor/EditorMain.cpp

@@ -7,33 +7,12 @@
 
 using namespace anki;
 
-ANKI_CVAR(StringCVar, Editor, Scene, "", "Load this scene at startup")
-
-class EditorUiNode : public SceneNode
-{
-public:
-	EditorUi m_editorUi;
-
-	EditorUiNode(CString name)
-		: SceneNode(name)
-	{
-		UiComponent* uic = newComponent<UiComponent>();
-		uic->init(
-			[](UiCanvas& canvas, void* ud) {
-				static_cast<EditorUiNode*>(ud)->m_editorUi.draw(canvas);
-			},
-			this);
-	}
-};
-
 class MyApp : public App
 {
 public:
 	U32 m_argc = 0;
 	Char** m_argv = nullptr;
 
-	EditorUiNode* m_editorUiNode = nullptr;
-
 	String m_sceneLuaFname;
 
 	MyApp(U32 argc, Char** argv)
@@ -51,151 +30,19 @@ public:
 		g_cvarRsrcTrackFileUpdates = true;
 		ANKI_CHECK(CVarSet::getSingleton().setFromCommandLineArguments(m_argc - 1, m_argv + 1));
 
-		if(CString(g_cvarEditorScene) != "")
-		{
-			ANKI_CHECK(walkDirectoryTree(g_cvarEditorScene, [this](WalkDirectoryArgs& args) {
-				if(!args.m_isDirectory && args.m_path.find("Scene.lua") != CString::kNpos)
-				{
-					m_sceneLuaFname = args.m_path;
-					args.m_stopSearch = true;
-				}
-
-				return Error::kNone;
-			}));
-
-			if(m_sceneLuaFname)
-			{
-				g_cvarRsrcDataPaths = CString(g_cvarEditorScene);
-			}
-			else
-			{
-				ANKI_LOGE("Failed to find a Scene.lua");
-			}
-		}
-
 		return Error::kNone;
 	}
 
 	Error userPostInit() override
 	{
 		SceneGraph::getSingleton().setCheckForResourceUpdates(true);
-		m_editorUiNode = SceneGraph::getSingleton().newSceneNode<EditorUiNode>("MainUi");
-
-		if(m_sceneLuaFname)
-		{
-			ANKI_LOGI("Will load: %s", m_sceneLuaFname.cstr());
-
-			ScriptResourcePtr script;
-			ANKI_CHECK(ResourceManager::getSingleton().loadResource(m_sceneLuaFname, script));
-			ANKI_CHECK(ScriptManager::getSingleton().evalString(script->getSource()));
-		}
+		SceneNode& editorNode = SceneGraph::getSingleton().getEditorUiNode();
+		editorNode.getFirstComponentOfType<UiComponent>().setEnabled(true);
 
 		Renderer::getSingleton().getDbg().enableOptions(DbgOption::kObjectPicking | DbgOption::kIcons);
 
 		return Error::kNone;
 	}
-
-	Error userMainLoop(Bool& quit, [[maybe_unused]] Second elapsedTime) override
-	{
-		Input& in = Input::getSingleton();
-		SceneGraph& scene = SceneGraph::getSingleton();
-		if(m_editorUiNode->m_editorUi.m_quit)
-		{
-			quit = true;
-		}
-
-		static Vec2 mousePosOn1stClick = in.getMousePositionNdc();
-		if(in.getMouseButton(MouseButton::kRight) == 1)
-		{
-			// Re-init mouse pos
-			mousePosOn1stClick = in.getMousePositionNdc();
-		}
-
-		if(in.getMouseButton(MouseButton::kRight) > 0 && !m_editorUiNode->m_editorUi.m_mouseOverAnyWindow)
-		{
-			in.hideCursor(true);
-
-			// move the camera
-			static SceneNode* mover = &scene.getActiveCameraNode();
-
-			constexpr F32 kRotateAngle = toRad(2.5f);
-			constexpr F32 kMouseSensitivity = 5.0f;
-
-			if(in.getKey(KeyCode::kUp) > 0)
-			{
-				mover->rotateLocalX(kRotateAngle);
-			}
-
-			if(in.getKey(KeyCode::kDown) > 0)
-			{
-				mover->rotateLocalX(-kRotateAngle);
-			}
-
-			if(in.getKey(KeyCode::kLeft) > 0)
-			{
-				mover->rotateLocalY(kRotateAngle);
-			}
-
-			if(in.getKey(KeyCode::kRight) > 0)
-			{
-				mover->rotateLocalY(-kRotateAngle);
-			}
-
-			F32 moveDistance = 0.1f;
-			if(in.getKey(KeyCode::kLeftShift) > 0)
-			{
-				moveDistance *= 4.0f;
-			}
-
-			if(in.getKey(KeyCode::kA) > 0)
-			{
-				mover->moveLocalX(-moveDistance);
-			}
-
-			if(in.getKey(KeyCode::kD) > 0)
-			{
-				mover->moveLocalX(moveDistance);
-			}
-
-			if(in.getKey(KeyCode::kQ) > 0)
-			{
-				mover->moveLocalY(-moveDistance);
-			}
-
-			if(in.getKey(KeyCode::kE) > 0)
-			{
-				mover->moveLocalY(moveDistance);
-			}
-
-			if(in.getKey(KeyCode::kW) > 0)
-			{
-				mover->moveLocalZ(-moveDistance);
-			}
-
-			if(in.getKey(KeyCode::kS) > 0)
-			{
-				mover->moveLocalZ(moveDistance);
-			}
-
-			const Vec2 velocity = in.getMousePositionNdc() - mousePosOn1stClick;
-			in.moveMouseNdc(mousePosOn1stClick);
-			if(velocity != Vec2(0.0))
-			{
-				Euler angles(mover->getLocalRotation().getRotationPart());
-				angles.x() += velocity.y() * toRad(360.0f) * F32(elapsedTime) * kMouseSensitivity;
-				angles.x() = clamp(angles.x(), toRad(-90.0f), toRad(90.0f)); // Avoid cycle in Y axis
-				angles.y() += -velocity.x() * toRad(360.0f) * F32(elapsedTime) * kMouseSensitivity;
-				angles.z() = 0.0f;
-				mover->setLocalRotation(Mat3(angles));
-			}
-		}
-		else
-		{
-			in.hideCursor(false);
-		}
-
-		return Error::kNone;
-	}
 };
 
 ANKI_MAIN_FUNCTION(myMain)