From e2960d67e40698d092089cc8f16dbdf83cb384ea Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Sat, 18 Apr 2026 11:35:38 +0300 Subject: [PATCH] Added character models and lua scripts to groups --- src/features/editScene/CMakeLists.txt | 6 + src/features/editScene/EditorApp.cpp | 150 +++--- src/features/editScene/EditorApp.hpp | 25 +- src/features/sceneEditor/EditorApp.cpp | 658 ++++++++++++------------- 4 files changed, 444 insertions(+), 395 deletions(-) diff --git a/src/features/editScene/CMakeLists.txt b/src/features/editScene/CMakeLists.txt index f25b80d..5dc2638 100644 --- a/src/features/editScene/CMakeLists.txt +++ b/src/features/editScene/CMakeLists.txt @@ -161,6 +161,12 @@ add_custom_command(TARGET editSceneEditor POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_BINARY_DIR}/resources" "${CMAKE_CURRENT_BINARY_DIR}/resources" + COMMAND ${CMAKE_COMMAND} -E copy_directory + "${CMAKE_BINARY_DIR}/characters" + "${CMAKE_CURRENT_BINARY_DIR}/characters" + COMMAND ${CMAKE_COMMAND} -E copy_directory + "${CMAKE_BINARY_DIR}/lua-scripts" + "${CMAKE_CURRENT_BINARY_DIR}/lua-scripts" COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/resources.cfg" "${CMAKE_CURRENT_BINARY_DIR}/resources.cfg" diff --git a/src/features/editScene/EditorApp.cpp b/src/features/editScene/EditorApp.cpp index 0cd335f..5528005 100644 --- a/src/features/editScene/EditorApp.cpp +++ b/src/features/editScene/EditorApp.cpp @@ -40,7 +40,7 @@ ImGuiRenderListener::ImGuiRenderListener(Ogre::ImGuiOverlay *imguiOverlay, EditorUISystem *uiSystem, - Ogre::RenderWindow* renderWindow) + Ogre::RenderWindow *renderWindow) : m_imguiOverlay(imguiOverlay) , m_uiSystem(uiSystem) , m_renderWindow(renderWindow) @@ -52,12 +52,12 @@ void ImGuiRenderListener::preViewportUpdate( const Ogre::RenderTargetViewportEvent &evt) { (void)evt; - + // Calculate delta time unsigned long currentTime = m_timer.getMilliseconds(); m_deltaTime = (currentTime - m_lastTime) / 1000.0f; m_lastTime = currentTime; - + // Start ImGui frame before viewport renders Ogre::ImGuiOverlay::NewFrame(); @@ -71,13 +71,15 @@ void ImGuiRenderListener::postViewportUpdate( const Ogre::RenderTargetViewportEvent &evt) { (void)evt; - + // Capture stats after rendering (they're updated at end of frame) if (m_renderWindow && m_uiSystem) { - Ogre::RenderTarget::FrameStats stats = m_renderWindow->getStatistics(); - m_uiSystem->setLastBatchCount(static_cast(stats.batchCount)); + Ogre::RenderTarget::FrameStats stats = + m_renderWindow->getStatistics(); + m_uiSystem->setLastBatchCount( + static_cast(stats.batchCount)); } - + // End ImGui frame after viewport renders ImGui::EndFrame(); } @@ -101,20 +103,21 @@ EditorApp::~EditorApp() if (m_uiSystem) { m_uiSystem->shutdown(); } - + // Delete all editor entities before OGRE cleanup // This ensures all components with Ogre resources are cleaned up while SceneManager exists // Collect entities first, then delete after iteration (can't modify during iteration) std::vector entitiesToDelete; - m_world.query().each([&](flecs::entity e, EditorMarkerComponent) { - entitiesToDelete.push_back(e); - }); - for (auto& e : entitiesToDelete) { + m_world.query().each( + [&](flecs::entity e, EditorMarkerComponent) { + entitiesToDelete.push_back(e); + }); + for (auto &e : entitiesToDelete) { if (e.is_alive()) { e.destruct(); } } - + // Release all systems m_proceduralMeshSystem.reset(); m_proceduralMaterialSystem.reset(); @@ -127,7 +130,7 @@ EditorApp::~EditorApp() m_imguiListener.reset(); m_uiSystem.reset(); m_camera.reset(); - + // Now OGRE can shut down safely // Singletons are managed by OGRE, don't delete them } @@ -141,7 +144,8 @@ void EditorApp::setup() // Get root and create scene manager Ogre::Root *root = getRoot(); m_sceneMgr = root->createSceneManager(); - m_sceneMgr->setAmbientLight(Ogre::ColourValue(0.3f, 0.3f, 0.3f)); + m_sceneMgr->setAmbientLight( + Ogre::ColourValue(0.3f, 0.3f, 0.3f)); // Add scene manager to RTShader generator Ogre::RTShader::ShaderGenerator *shadergen = @@ -164,8 +168,8 @@ void EditorApp::setup() } // Setup camera - m_camera = - std::make_unique(m_sceneMgr, getRenderWindow()); + m_camera = std::make_unique(m_sceneMgr, + getRenderWindow()); // Setup ECS and scene setupECS(); @@ -175,46 +179,58 @@ void EditorApp::setup() createDefaultEntities(); // Setup UI system - m_uiSystem = std::make_unique(m_world, m_sceneMgr, getRenderWindow()); + m_uiSystem = std::make_unique( + m_world, m_sceneMgr, getRenderWindow()); // Setup physics system - m_physicsSystem = std::make_unique(m_world, m_sceneMgr); + m_physicsSystem = std::make_unique( + m_world, m_sceneMgr); m_physicsSystem->initialize(); m_uiSystem->setPhysicsSystem(m_physicsSystem.get()); - + // Setup light system - m_lightSystem = std::make_unique(m_world, m_sceneMgr); - + m_lightSystem = std::make_unique(m_world, + m_sceneMgr); + // Setup camera system - m_cameraSystem = std::make_unique(m_world, m_sceneMgr, - getRenderWindow()); - + m_cameraSystem = std::make_unique( + m_world, m_sceneMgr, getRenderWindow()); + // Setup LOD system - m_lodSystem = std::make_unique(m_world, m_sceneMgr); + m_lodSystem = + std::make_unique(m_world, m_sceneMgr); m_lodSystem->initialize(); - + // Setup StaticGeometry system - m_staticGeometrySystem = std::make_unique(m_world, m_sceneMgr); + m_staticGeometrySystem = std::make_unique( + m_world, m_sceneMgr); m_staticGeometrySystem->initialize(); - + // Setup ProceduralTexture system - m_proceduralTextureSystem = std::make_unique(m_world, m_sceneMgr); + m_proceduralTextureSystem = + std::make_unique(m_world, + m_sceneMgr); m_proceduralTextureSystem->initialize(); - + // Setup ProceduralMaterial system - m_proceduralMaterialSystem = std::make_unique(m_world, m_sceneMgr); + m_proceduralMaterialSystem = + std::make_unique(m_world, + m_sceneMgr); m_proceduralMaterialSystem->initialize(); - + // Setup ProceduralMesh system - m_proceduralMeshSystem = std::make_unique(m_world, m_sceneMgr); + m_proceduralMeshSystem = std::make_unique( + m_world, m_sceneMgr); m_proceduralMeshSystem->initialize(); - + // Setup CellGrid system - m_cellGridSystem = std::make_unique(m_world, m_sceneMgr); + m_cellGridSystem = + std::make_unique(m_world, m_sceneMgr); m_cellGridSystem->initialize(); - + // Setup RoomLayout system - m_roomLayoutSystem = std::make_unique(m_world, m_sceneMgr); + m_roomLayoutSystem = + std::make_unique(m_world, m_sceneMgr); m_roomLayoutSystem->initialize(); // Add default entities to UI cache @@ -230,9 +246,10 @@ void EditorApp::setup() // Register input listeners addInputListener(this); addInputListener(getImGuiInputListener()); - - } catch (const std::exception& e) { - Ogre::LogManager::getSingleton().logMessage("Setup failed: " + Ogre::String(e.what())); + + } catch (const std::exception &e) { + Ogre::LogManager::getSingleton().logMessage( + "Setup failed: " + Ogre::String(e.what())); throw; } } @@ -244,34 +261,34 @@ void EditorApp::setupECS() m_world.component(); m_world.component(); m_world.component(); - + // Register physics components m_world.component(); m_world.component(); m_world.component(); - + // Register light and camera components m_world.component(); m_world.component(); - + // Register LOD components m_world.component(); m_world.component(); - + // Register StaticGeometry components m_world.component(); m_world.component(); - + // Register ProceduralTexture component m_world.component(); - + // Register ProceduralMaterial component m_world.component(); - + // Register Primitive and TriangleBuffer components m_world.component(); m_world.component(); - + // Register CellGrid/Town components CellGridModule::registerComponents(m_world); } @@ -401,47 +418,47 @@ bool EditorApp::frameRenderingQueued(const Ogre::FrameEvent &evt) if (m_physicsSystem) { m_physicsSystem->update(evt.timeSinceLastFrame); } - + // Update lights if (m_lightSystem) { m_lightSystem->update(); } - + // Update cameras if (m_cameraSystem) { m_cameraSystem->update(); } - + // Update LOD system if (m_lodSystem) { m_lodSystem->update(); } - + // Update StaticGeometry system if (m_staticGeometrySystem) { m_staticGeometrySystem->update(); } - + // Update ProceduralTexture system if (m_proceduralTextureSystem) { m_proceduralTextureSystem->update(); } - + // Update ProceduralMaterial system if (m_proceduralMaterialSystem) { m_proceduralMaterialSystem->update(); } - + // Update ProceduralMesh system if (m_proceduralMeshSystem) { m_proceduralMeshSystem->update(); } - + // Update RoomLayout system FIRST (generates cells for CellGrid) if (m_roomLayoutSystem) { m_roomLayoutSystem->update(); } - + // Update CellGrid system (builds mesh from cells) if (m_cellGridSystem) { m_cellGridSystem->update(); @@ -565,3 +582,20 @@ flecs::entity EditorApp::getSelectedEntity() const } return flecs::entity::null(); } + +void EditorApp::locateResources() +{ + Ogre::ResourceGroupManager::getSingleton().createResourceGroup( + "Characters", true); + // Ogre::ResourceGroupManager::getSingleton().createResourceGroup( + // "Water", true); + Ogre::ResourceGroupManager::getSingleton().createResourceGroup( + "LuaScripts", false); + Ogre::ResourceGroupManager::getSingleton().addResourceLocation( + "./lua-scripts", "FileSystem", "LuaScripts", true, true); + Ogre::ResourceGroupManager::getSingleton().addResourceLocation( + "./characters/male", "FileSystem", "Characters", false, true); + Ogre::ResourceGroupManager::getSingleton().addResourceLocation( + "./characters/female", "FileSystem", "Characters", false, true); + OgreBites::ApplicationContext::locateResources(); +} \ No newline at end of file diff --git a/src/features/editScene/EditorApp.hpp b/src/features/editScene/EditorApp.hpp index 8ad9c25..5e2663c 100644 --- a/src/features/editScene/EditorApp.hpp +++ b/src/features/editScene/EditorApp.hpp @@ -32,21 +32,23 @@ class ImGuiRenderListener : public Ogre::RenderTargetListener { public: ImGuiRenderListener(Ogre::ImGuiOverlay *imguiOverlay, EditorUISystem *uiSystem, - Ogre::RenderWindow* renderWindow); + Ogre::RenderWindow *renderWindow); - void preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override; - void postViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override; + void + preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override; + void + postViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override; private: Ogre::ImGuiOverlay *m_imguiOverlay; EditorUISystem *m_uiSystem; - Ogre::RenderWindow* m_renderWindow; - + Ogre::RenderWindow *m_renderWindow; + // Timer for delta time calculation Ogre::Timer m_timer; unsigned long m_lastTime = 0; float m_deltaTime = 0.0f; - + // Frame stats (updated in postViewportUpdate) int m_lastBatchCount = 0; }; @@ -63,6 +65,7 @@ public: // OgreBites::ApplicationContext overrides void setup() override; bool frameRenderingQueued(const Ogre::FrameEvent &evt) override; + void locateResources() override; // OgreBites::InputListener overrides bool mouseMoved(const OgreBites::MouseMotionEvent &evt) override; @@ -82,8 +85,14 @@ public: // Getters flecs::entity getSelectedEntity() const; - Ogre::SceneManager *getSceneManager() const { return m_sceneMgr; } - flecs::world *getWorld() { return &m_world; } + Ogre::SceneManager *getSceneManager() const + { + return m_sceneMgr; + } + flecs::world *getWorld() + { + return &m_world; + } private: // Ogre objects diff --git a/src/features/sceneEditor/EditorApp.cpp b/src/features/sceneEditor/EditorApp.cpp index 9bbe282..bde5265 100644 --- a/src/features/sceneEditor/EditorApp.cpp +++ b/src/features/sceneEditor/EditorApp.cpp @@ -7,445 +7,445 @@ #include "components/EulerUtils.hpp" EditorApp::EditorApp() - : OgreBites::ApplicationContext("OgreEditor") - , mSceneMgr(nullptr) - , mOverlaySystem(nullptr) - , mImGuiOverlay(nullptr) - , mIsDraggingCursor(false) - , mCurrentModifiers(0) - , mGridVisible(true) - , mAxesVisible(true) - , m3DCursorPosition(Ogre::Vector3::ZERO) + : OgreBites::ApplicationContext("OgreEditor") + , mSceneMgr(nullptr) + , mOverlaySystem(nullptr) + , mImGuiOverlay(nullptr) + , mIsDraggingCursor(false) + , mCurrentModifiers(0) + , mGridVisible(true) + , mAxesVisible(true) + , m3DCursorPosition(Ogre::Vector3::ZERO) { } EditorApp::~EditorApp() { - if (mImGuiOverlay) { - delete mImGuiOverlay; - mImGuiOverlay = nullptr; - } - if (mOverlaySystem) { - delete mOverlaySystem; - mOverlaySystem = nullptr; - } + if (mImGuiOverlay) { + delete mImGuiOverlay; + mImGuiOverlay = nullptr; + } + if (mOverlaySystem) { + delete mOverlaySystem; + mOverlaySystem = nullptr; + } } void EditorApp::setup() { - // Call base class setup first - OgreBites::ApplicationContext::setup(); + // Call base class setup first + OgreBites::ApplicationContext::setup(); - // Get root and setup scene - Ogre::Root *root = getRoot(); - if (!root) { - OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, - "Failed to get Ogre::Root", "EditorApp::setup"); - return; - } + // Get root and setup scene + Ogre::Root *root = getRoot(); + if (!root) { + OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, + "Failed to get Ogre::Root", "EditorApp::setup"); + return; + } - mSceneMgr = root->createSceneManager(); - if (!mSceneMgr) { - OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, - "Failed to create SceneManager", - "EditorApp::setup"); - return; - } + mSceneMgr = root->createSceneManager(); + if (!mSceneMgr) { + OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, + "Failed to create SceneManager", + "EditorApp::setup"); + return; + } - // Setup overlay system - mOverlaySystem = new Ogre::OverlaySystem(); - mSceneMgr->addRenderQueueListener(mOverlaySystem); + // Setup overlay system + mOverlaySystem = new Ogre::OverlaySystem(); + mSceneMgr->addRenderQueueListener(mOverlaySystem); - // Setup render window - Ogre::RenderWindow *window = getRenderWindow(); - if (!window) { - OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, - "Failed to get RenderWindow", "EditorApp::setup"); - return; - } + // Setup render window + Ogre::RenderWindow *window = getRenderWindow(); + if (!window) { + OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, + "Failed to get RenderWindow", "EditorApp::setup"); + return; + } - // Setup ImGui overlay - setupImGui(); + // Setup ImGui overlay + setupImGui(); - setupFlecs(); - setupScene(); + setupFlecs(); + setupScene(); - // Setup editor camera - mEditorCamera = std::make_unique(mSceneMgr, window); + // Setup editor camera + mEditorCamera = std::make_unique(mSceneMgr, window); - // Setup UI system - mUISystem = std::make_unique(mWorld, mSceneMgr, - m3DCursorPosition); + // Setup UI system + mUISystem = std::make_unique(mWorld, mSceneMgr, + m3DCursorPosition); - // Set the cursor moved callback - mUISystem->setOnCursorMoved( - [this](const Ogre::Vector3 &pos) { m3DCursorPosition = pos; }); + // Set the cursor moved callback + mUISystem->setOnCursorMoved( + [this](const Ogre::Vector3 &pos) { m3DCursorPosition = pos; }); - // Register input listeners - addInputListener(this); + // Register input listeners + addInputListener(this); - // Add ImGui input listener - this is a method of ApplicationContext - OgreBites::InputListener *imguiListener = getImGuiInputListener(); - if (imguiListener) { - addInputListener(imguiListener); - } + // Add ImGui input listener - this is a method of ApplicationContext + OgreBites::InputListener *imguiListener = getImGuiInputListener(); + if (imguiListener) { + addInputListener(imguiListener); + } } void EditorApp::setupFlecs() { - // Configure flecs - mWorld.set_entity_range(1, 10000); + // Configure flecs + mWorld.set_entity_range(1, 10000); - // Register components using the helper function - registerComponents(mWorld); + // Register components using the helper function + registerComponents(mWorld); - // Create default entities - flecs::entity rootEntity = mWorld.entity(); - rootEntity.set({ "Root" }); + // Create default entities + flecs::entity rootEntity = mWorld.entity(); + rootEntity.set({ "Root" }); - // Create a test entity with mesh - flecs::entity testEntity = mWorld.entity(); - testEntity.set({ "Test Cube" }); + // Create a test entity with mesh + flecs::entity testEntity = mWorld.entity(); + testEntity.set({ "Test Cube" }); - // Create transform with scene node - TransformComponent transform; - transform.node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - transform.position = Ogre::Vector3(0, 0, 0); - transform.applyToNode(); - testEntity.set(transform); + // Create transform with scene node + TransformComponent transform; + transform.node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + transform.position = Ogre::Vector3(0, 0, 0); + transform.applyToNode(); + testEntity.set(transform); - // Try to load a mesh - try { - RenderableComponent renderable("cube.mesh"); - renderable.entity = mSceneMgr->createEntity("cube.mesh"); - testEntity.set(renderable); + // Try to load a mesh + try { + RenderableComponent renderable("cube.mesh"); + renderable.entity = mSceneMgr->createEntity("cube.mesh"); + testEntity.set(renderable); - // Attach to node - if (testEntity.has()) { - auto &testTransform = - testEntity.get_mut(); - if (testTransform.node && renderable.entity) { - testTransform.node->attachObject( - renderable.entity); - } - } - } catch (const std::exception &e) { - Ogre::LogManager::getSingleton().logMessage( - "Failed to load cube.mesh: " + std::string(e.what())); - } + // Attach to node + if (testEntity.has()) { + auto &testTransform = + testEntity.get_mut(); + if (testTransform.node && renderable.entity) { + testTransform.node->attachObject( + renderable.entity); + } + } + } catch (const std::exception &e) { + Ogre::LogManager::getSingleton().logMessage( + "Failed to load cube.mesh: " + std::string(e.what())); + } - // Optional: Add a system for auto-updating transforms - mWorld.system().each( - [](flecs::entity e, TransformComponent &transform) { - // Auto-sync transforms if needed - // transform.updateFromNode(); - }); + // Optional: Add a system for auto-updating transforms + mWorld.system().each( + [](flecs::entity e, TransformComponent &transform) { + // Auto-sync transforms if needed + // transform.updateFromNode(); + }); } void EditorApp::setupScene() { - // Setup ambient light - mSceneMgr->setAmbientLight(Ogre::ColourValue(0.3f, 0.3f, 0.3f)); + // Setup ambient light + mSceneMgr->setAmbientLight(Ogre::ColourValue(0.3f, 0.3f, 0.3f)); - // Create directional light with scene node - Ogre::Light *directionalLight = mSceneMgr->createLight("MainLight"); - directionalLight->setType(Ogre::Light::LT_DIRECTIONAL); - directionalLight->setDiffuseColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f)); - directionalLight->setSpecularColour( - Ogre::ColourValue(0.5f, 0.5f, 0.5f)); + // Create directional light with scene node + Ogre::Light *directionalLight = mSceneMgr->createLight("MainLight"); + directionalLight->setType(Ogre::Light::LT_DIRECTIONAL); + directionalLight->setDiffuseColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f)); + directionalLight->setSpecularColour( + Ogre::ColourValue(0.5f, 0.5f, 0.5f)); - // Create scene node for directional light and set direction - Ogre::SceneNode *lightNode = - mSceneMgr->getRootSceneNode()->createChildSceneNode(); - lightNode->attachObject(directionalLight); - lightNode->setDirection(Ogre::Vector3(1, -1, 0), Ogre::Node::TS_WORLD); + // Create scene node for directional light and set direction + Ogre::SceneNode *lightNode = + mSceneMgr->getRootSceneNode()->createChildSceneNode(); + lightNode->attachObject(directionalLight); + lightNode->setDirection(Ogre::Vector3(1, -1, 0), Ogre::Node::TS_WORLD); - // Create a fill light from below - Ogre::Light *fillLight = mSceneMgr->createLight("FillLight"); - fillLight->setType(Ogre::Light::LT_DIRECTIONAL); - fillLight->setDiffuseColour(Ogre::ColourValue(0.4f, 0.4f, 0.4f)); - fillLight->setSpecularColour(Ogre::ColourValue(0.2f, 0.2f, 0.2f)); + // Create a fill light from below + Ogre::Light *fillLight = mSceneMgr->createLight("FillLight"); + fillLight->setType(Ogre::Light::LT_DIRECTIONAL); + fillLight->setDiffuseColour(Ogre::ColourValue(0.4f, 0.4f, 0.4f)); + fillLight->setSpecularColour(Ogre::ColourValue(0.2f, 0.2f, 0.2f)); - Ogre::SceneNode *fillLightNode = - mSceneMgr->getRootSceneNode()->createChildSceneNode(); - fillLightNode->attachObject(fillLight); - fillLightNode->setDirection(Ogre::Vector3(-0.5f, -1.0f, 0.5f), - Ogre::Node::TS_WORLD); + Ogre::SceneNode *fillLightNode = + mSceneMgr->getRootSceneNode()->createChildSceneNode(); + fillLightNode->attachObject(fillLight); + fillLightNode->setDirection(Ogre::Vector3(-0.5f, -1.0f, 0.5f), + Ogre::Node::TS_WORLD); - // Optional: Add a grid helper with named node for toggling - try { - Ogre::Plane plane(Ogre::Vector3::UNIT_Y, -1); - Ogre::MeshManager::getSingleton().createPlane( - "grid_plane", - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - plane, 20, 20, 20, 20, true, 1, 5, 5, - Ogre::Vector3::UNIT_Z); + // Optional: Add a grid helper with named node for toggling + try { + Ogre::Plane plane(Ogre::Vector3::UNIT_Y, -1); + Ogre::MeshManager::getSingleton().createPlane( + "grid_plane", + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + plane, 20, 20, 20, 20, true, 1, 5, 5, + Ogre::Vector3::UNIT_Z); - Ogre::Entity *gridEntity = - mSceneMgr->createEntity("grid_plane"); + Ogre::Entity *gridEntity = + mSceneMgr->createEntity("grid_plane"); - // Try to set a grid material if available - if (Ogre::MaterialManager::getSingleton().resourceExists( - "GridMaterial")) { - gridEntity->setMaterialName("GridMaterial"); - } + // Try to set a grid material if available + if (Ogre::MaterialManager::getSingleton().resourceExists( + "GridMaterial")) { + gridEntity->setMaterialName("GridMaterial"); + } - // Create node with a name for easy access - Ogre::SceneNode *gridNode = - mSceneMgr->getRootSceneNode()->createChildSceneNode( - "GridNode"); - gridNode->attachObject(gridEntity); - gridNode->setPosition(0, -1, 0); + // Create node with a name for easy access + Ogre::SceneNode *gridNode = + mSceneMgr->getRootSceneNode()->createChildSceneNode( + "GridNode"); + gridNode->attachObject(gridEntity); + gridNode->setPosition(0, -1, 0); - Ogre::LogManager::getSingleton().logMessage( - "Grid created successfully"); - } catch (const std::exception &e) { - Ogre::LogManager::getSingleton().logMessage( - "Grid plane creation failed: " + std::string(e.what())); - } + Ogre::LogManager::getSingleton().logMessage( + "Grid created successfully"); + } catch (const std::exception &e) { + Ogre::LogManager::getSingleton().logMessage( + "Grid plane creation failed: " + std::string(e.what())); + } - // Add a simple axis helper - createAxisHelper(); + // Add a simple axis helper + createAxisHelper(); } void EditorApp::createAxisHelper() { - try { - // X-axis (red) - Ogre::ManualObject *axisX = - mSceneMgr->createManualObject("AxisX"); - axisX->begin("BaseWhiteNoLighting", - Ogre::RenderOperation::OT_LINE_LIST); - axisX->colour(Ogre::ColourValue(1.0f, 0.0f, 0.0f)); - axisX->position(0, 0, 0); - axisX->position(2, 0, 0); - axisX->end(); + try { + // X-axis (red) + Ogre::ManualObject *axisX = + mSceneMgr->createManualObject("AxisX"); + axisX->begin("BaseWhiteNoLighting", + Ogre::RenderOperation::OT_LINE_LIST); + axisX->colour(Ogre::ColourValue(1.0f, 0.0f, 0.0f)); + axisX->position(0, 0, 0); + axisX->position(2, 0, 0); + axisX->end(); - // Y-axis (green) - Ogre::ManualObject *axisY = - mSceneMgr->createManualObject("AxisY"); - axisY->begin("BaseWhiteNoLighting", - Ogre::RenderOperation::OT_LINE_LIST); - axisY->colour(Ogre::ColourValue(0.0f, 1.0f, 0.0f)); - axisY->position(0, 0, 0); - axisY->position(0, 2, 0); - axisY->end(); + // Y-axis (green) + Ogre::ManualObject *axisY = + mSceneMgr->createManualObject("AxisY"); + axisY->begin("BaseWhiteNoLighting", + Ogre::RenderOperation::OT_LINE_LIST); + axisY->colour(Ogre::ColourValue(0.0f, 1.0f, 0.0f)); + axisY->position(0, 0, 0); + axisY->position(0, 2, 0); + axisY->end(); - // Z-axis (blue) - Ogre::ManualObject *axisZ = - mSceneMgr->createManualObject("AxisZ"); - axisZ->begin("BaseWhiteNoLighting", - Ogre::RenderOperation::OT_LINE_LIST); - axisZ->colour(Ogre::ColourValue(0.0f, 0.0f, 1.0f)); - axisZ->position(0, 0, 0); - axisZ->position(0, 0, 2); - axisZ->end(); + // Z-axis (blue) + Ogre::ManualObject *axisZ = + mSceneMgr->createManualObject("AxisZ"); + axisZ->begin("BaseWhiteNoLighting", + Ogre::RenderOperation::OT_LINE_LIST); + axisZ->colour(Ogre::ColourValue(0.0f, 0.0f, 1.0f)); + axisZ->position(0, 0, 0); + axisZ->position(0, 0, 2); + axisZ->end(); - // Create named node for easy access - Ogre::SceneNode *axisNode = - mSceneMgr->getRootSceneNode()->createChildSceneNode( - "AxisNode"); - axisNode->attachObject(axisX); - axisNode->attachObject(axisY); - axisNode->attachObject(axisZ); + // Create named node for easy access + Ogre::SceneNode *axisNode = + mSceneMgr->getRootSceneNode()->createChildSceneNode( + "AxisNode"); + axisNode->attachObject(axisX); + axisNode->attachObject(axisY); + axisNode->attachObject(axisZ); - } catch (const std::exception &e) { - Ogre::LogManager::getSingleton().logMessage( - "Axis helper creation failed: " + - std::string(e.what())); - } + } catch (const std::exception &e) { + Ogre::LogManager::getSingleton().logMessage( + "Axis helper creation failed: " + + std::string(e.what())); + } } void EditorApp::setupImGui() { - // Create ImGui overlay using Ogre's built-in integration - mImGuiOverlay = new Ogre::ImGuiOverlay(); + // Create ImGui overlay using Ogre's built-in integration + mImGuiOverlay = new Ogre::ImGuiOverlay(); - // Show the overlay - this enables it in the overlay system - mImGuiOverlay->show(); + // Show the overlay - this enables it in the overlay system + mImGuiOverlay->show(); - // Setup ImGui style - ImGui::StyleColorsDark(); + // Setup ImGui style + ImGui::StyleColorsDark(); - // Configure ImGui IO (standard features only) - ImGuiIO &io = ImGui::GetIO(); - io.ConfigWindowsMoveFromTitleBarOnly = true; + // Configure ImGui IO (standard features only) + ImGuiIO &io = ImGui::GetIO(); + io.ConfigWindowsMoveFromTitleBarOnly = true; - Ogre::LogManager::getSingleton().logMessage( - "ImGui overlay initialized"); + Ogre::LogManager::getSingleton().logMessage( + "ImGui overlay initialized"); } bool EditorApp::frameRenderingQueued(const Ogre::FrameEvent &evt) { - // Update camera - if (mEditorCamera) { - mEditorCamera->update(evt.timeSinceLastFrame); - } + // Update camera + if (mEditorCamera) { + mEditorCamera->update(evt.timeSinceLastFrame); + } - // Start ImGui frame - if (mImGuiOverlay) { - mImGuiOverlay->NewFrame(); - } + // Start ImGui frame + if (mImGuiOverlay) { + mImGuiOverlay->NewFrame(); + } - // Update UI system (this will render all ImGui windows) - if (mUISystem) { - mUISystem->update(); - } + // Update UI system (this will render all ImGui windows) + if (mUISystem) { + mUISystem->update(); + } - return OgreBites::ApplicationContext::frameRenderingQueued(evt); + return OgreBites::ApplicationContext::frameRenderingQueued(evt); } bool EditorApp::mouseMoved(const OgreBites::MouseMotionEvent &evt) { - if (mEditorCamera) { - mEditorCamera->handleMouseMove(evt); - } - return true; + if (mEditorCamera) { + mEditorCamera->handleMouseMove(evt); + } + return true; } bool EditorApp::mousePressed(const OgreBites::MouseButtonEvent &evt) { - if (mEditorCamera) { - mEditorCamera->handleMousePress(evt); + if (mEditorCamera) { + mEditorCamera->handleMousePress(evt); - // Check for Ctrl key using current modifier state - if (evt.button == OgreBites::BUTTON_LEFT && isCtrlPressed()) { - Ogre::Viewport *vp = - mEditorCamera->getCamera()->getViewport(); - if (vp) { - float screenX = static_cast(evt.x) / - static_cast( - vp->getActualWidth()); - float screenY = static_cast(evt.y) / - static_cast( - vp->getActualHeight()); + // Check for Ctrl key using current modifier state + if (evt.button == OgreBites::BUTTON_LEFT && isCtrlPressed()) { + Ogre::Viewport *vp = + mEditorCamera->getCamera()->getViewport(); + if (vp) { + float screenX = static_cast(evt.x) / + static_cast( + vp->getActualWidth()); + float screenY = static_cast(evt.y) / + static_cast( + vp->getActualHeight()); - Ogre::Vector3 cursorPos = - mEditorCamera->getMouseRay(screenX, - screenY); - m3DCursorPosition = cursorPos; - } - } - } - return true; + Ogre::Vector3 cursorPos = + mEditorCamera->getMouseRay(screenX, + screenY); + m3DCursorPosition = cursorPos; + } + } + } + return true; } bool EditorApp::mouseReleased(const OgreBites::MouseButtonEvent &evt) { - if (mEditorCamera) { - mEditorCamera->handleMouseRelease(evt); - } - return true; + if (mEditorCamera) { + mEditorCamera->handleMouseRelease(evt); + } + return true; } bool EditorApp::keyPressed(const OgreBites::KeyboardEvent &evt) { - if (mEditorCamera) { - mEditorCamera->handleKeyboard(evt); - } + if (mEditorCamera) { + mEditorCamera->handleKeyboard(evt); + } - // Update current modifiers from the event - mCurrentModifiers = evt.keysym.mod; + // Update current modifiers from the event + mCurrentModifiers = evt.keysym.mod; - // Handle delete key - if (evt.keysym.sym == OgreBites::SDLK_DELETE) { - if (mUISystem && mSelectedEntity) { - // Clean up scene node - if (mSelectedEntity.has()) { - auto &transform = - mSelectedEntity - .get_mut(); - if (transform.node) { - mSceneMgr->destroySceneNode( - transform.node); - transform.node = nullptr; - } - } + // Handle delete key + if (evt.keysym.sym == OgreBites::SDLK_DELETE) { + if (mUISystem && mSelectedEntity) { + // Clean up scene node + if (mSelectedEntity.has()) { + auto &transform = + mSelectedEntity + .get_mut(); + if (transform.node) { + mSceneMgr->destroySceneNode( + transform.node); + transform.node = nullptr; + } + } - // Clean up renderable - if (mSelectedEntity.has()) { - auto &renderable = - mSelectedEntity - .get_mut(); - if (renderable.entity) { - mSceneMgr->destroyEntity( - renderable.entity); - renderable.entity = nullptr; - } - } + // Clean up renderable + if (mSelectedEntity.has()) { + auto &renderable = + mSelectedEntity + .get_mut(); + if (renderable.entity) { + mSceneMgr->destroyEntity( + renderable.entity); + renderable.entity = nullptr; + } + } - mSelectedEntity.destruct(); - mUISystem->setSelectedEntity(flecs::entity::null()); - } - } + mSelectedEntity.destruct(); + mUISystem->setSelectedEntity(flecs::entity::null()); + } + } - // Handle F5 for reloading resources - if (evt.keysym.sym == OgreBites::SDLK_F5) { - reloadResources(); - } + // Handle F5 for reloading resources + if (evt.keysym.sym == OgreBites::SDLK_F5) { + reloadResources(); + } - // Handle F3 for showing/hiding grid - if (evt.keysym.sym == OgreBites::SDLK_F3) { - toggleGrid(); - } + // Handle F3 for showing/hiding grid + if (evt.keysym.sym == OgreBites::SDLK_F3) { + toggleGrid(); + } - // Handle F4 for showing/hiding axes - if (evt.keysym.sym == OgreBites::SDLK_F4) { - toggleAxes(); - } + // Handle F4 for showing/hiding axes + if (evt.keysym.sym == OgreBites::SDLK_F4) { + toggleAxes(); + } - return true; + return true; } bool EditorApp::keyReleased(const OgreBites::KeyboardEvent &evt) { - // Update current modifiers from the event - mCurrentModifiers = evt.keysym.mod; + // Update current modifiers from the event + mCurrentModifiers = evt.keysym.mod; - return true; + return true; } void EditorApp::toggleGrid() { - // Use getChild and cast to SceneNode - Ogre::Node *node = mSceneMgr->getRootSceneNode()->getChild("GridNode"); - if (node) { - Ogre::SceneNode *gridNode = - static_cast(node); - mGridVisible = !mGridVisible; - gridNode->setVisible(mGridVisible); - Ogre::LogManager::getSingleton().logMessage( - "Grid visibility: " + - std::string(mGridVisible ? "ON" : "OFF")); - } else { - Ogre::LogManager::getSingleton().logMessage( - "Grid node not found"); - } + // Use getChild and cast to SceneNode + Ogre::Node *node = mSceneMgr->getRootSceneNode()->getChild("GridNode"); + if (node) { + Ogre::SceneNode *gridNode = + static_cast(node); + mGridVisible = !mGridVisible; + gridNode->setVisible(mGridVisible); + Ogre::LogManager::getSingleton().logMessage( + "Grid visibility: " + + std::string(mGridVisible ? "ON" : "OFF")); + } else { + Ogre::LogManager::getSingleton().logMessage( + "Grid node not found"); + } } void EditorApp::toggleAxes() { - // Use getChild and cast to SceneNode - Ogre::Node *node = mSceneMgr->getRootSceneNode()->getChild("AxisNode"); - if (node) { - Ogre::SceneNode *axisNode = - static_cast(node); - mAxesVisible = !mAxesVisible; - axisNode->setVisible(mAxesVisible); - Ogre::LogManager::getSingleton().logMessage( - "Axes visibility: " + - std::string(mAxesVisible ? "ON" : "OFF")); - } else { - Ogre::LogManager::getSingleton().logMessage( - "Axis node not found"); - } + // Use getChild and cast to SceneNode + Ogre::Node *node = mSceneMgr->getRootSceneNode()->getChild("AxisNode"); + if (node) { + Ogre::SceneNode *axisNode = + static_cast(node); + mAxesVisible = !mAxesVisible; + axisNode->setVisible(mAxesVisible); + Ogre::LogManager::getSingleton().logMessage( + "Axes visibility: " + + std::string(mAxesVisible ? "ON" : "OFF")); + } else { + Ogre::LogManager::getSingleton().logMessage( + "Axis node not found"); + } } void EditorApp::reloadResources() { - // Reload all materials - Ogre::LogManager::getSingleton().logMessage("Reloading materials..."); - Ogre::MaterialManager::getSingleton().reloadAll(); + // Reload all materials + Ogre::LogManager::getSingleton().logMessage("Reloading materials..."); + Ogre::MaterialManager::getSingleton().reloadAll(); - Ogre::LogManager::getSingleton().logMessage("Resources reloaded"); + Ogre::LogManager::getSingleton().logMessage("Resources reloaded"); }