#pragma once #include "Common.h" #include "SceneObject.h" #include "Camera.h" #include "Rendering.h" #include "ProjectManager.h" #include "EditorUI.h" #include "MeshBuilder.h" #include "ScriptCompiler.h" #include "ScriptRuntime.h" #include "../include/Window/Window.h" void window_size_callback(GLFWwindow* window, int width, int height); class Engine { private: Window window; GLFWwindow* editorWindow = nullptr; Renderer renderer; Camera camera; ViewportController viewportController; float deltaTime = 0.0f; float lastFrame = 0.0f; bool cursorLocked = false; // true only while holding right mouse for freelook int viewportWidth = 800; int viewportHeight = 600; bool gizmoHistoryCaptured = false; // Standalone material inspection cache std::string inspectedMaterialPath; MaterialProperties inspectedMaterial; std::string inspectedAlbedo; std::string inspectedOverlay; std::string inspectedNormal; std::string inspectedVertShader; std::string inspectedFragShader; bool inspectedUseOverlay = false; bool inspectedMaterialValid = false; struct SceneSnapshot { std::vector objects; std::vector selectedIds; int nextId = 0; }; std::vector undoStack; std::vector redoStack; std::vector sceneObjects; int selectedObjectId = -1; // primary selection (last) std::vector selectedObjectIds; // multi-select int nextObjectId = 0; // Gizmo state ImGuizmo::OPERATION mCurrentGizmoOperation = ImGuizmo::TRANSLATE; ImGuizmo::MODE mCurrentGizmoMode = ImGuizmo::LOCAL; bool useSnap = false; float snapValue[3] = { 0.5f, 0.5f, 0.5f }; float rotationSnapValue = 15.0f; FileBrowser fileBrowser; bool viewportFullscreen = false; bool showHierarchy = true; bool showInspector = true; bool showFileBrowser = true; bool showConsole = true; bool showProjectBrowser = true; // Now merged into file browser bool showMeshBuilder = false; bool firstFrame = true; std::vector consoleLog; int draggedObjectId = -1; ProjectManager projectManager; bool showLauncher = true; bool showNewSceneDialog = false; bool showSaveSceneAsDialog = false; char newSceneName[128] = ""; char saveSceneAsName[128] = ""; bool rendererInitialized = false; bool showImportOBJDialog = false; bool showImportModelDialog = false; // For Assimp models std::string pendingOBJPath; std::string pendingModelPath; // For Assimp models char importOBJName[128] = ""; char importModelName[128] = ""; // For Assimp models char fileBrowserSearch[256] = ""; float fileBrowserIconScale = 1.0f; // 0.5 to 2.0 range bool showEnvironmentWindow = true; bool showCameraWindow = true; bool isPlaying = false; bool isPaused = false; bool showViewOutput = true; int previewCameraId = -1; MeshBuilder meshBuilder; char meshBuilderPath[260] = ""; char meshBuilderFaceInput[128] = ""; bool meshEditMode = false; bool meshEditLoaded = false; std::string meshEditPath; RawMeshAsset meshEditAsset; std::vector meshEditSelectedVertices; std::vector meshEditSelectedEdges; // indices into generated edge list std::vector meshEditSelectedFaces; // indices into mesh faces enum class MeshEditSelectionMode { Vertex = 0, Edge = 1, Face = 2 }; MeshEditSelectionMode meshEditSelectionMode = MeshEditSelectionMode::Vertex; ScriptCompiler scriptCompiler; ScriptRuntime scriptRuntime; bool showCompilePopup = false; bool lastCompileSuccess = false; std::string lastCompileStatus; std::string lastCompileLog; bool specMode = false; bool testMode = false; // Private methods SceneObject* getSelectedObject(); glm::vec3 getSelectionCenterWorld(bool worldSpace) const; void setPrimarySelection(int id, bool additive = false); void clearSelection(); static void DecomposeMatrix(const glm::mat4& matrix, glm::vec3& pos, glm::vec3& rot, glm::vec3& scale); void importOBJToScene(const std::string& filepath, const std::string& objectName); void importModelToScene(const std::string& filepath, const std::string& objectName); // Assimp import void convertModelToRawMesh(const std::string& filepath); bool ensureMeshEditTarget(SceneObject* obj); bool syncMeshEditToGPU(SceneObject* obj); void handleKeyboardShortcuts(); void OpenProjectPath(const std::string& path); // UI rendering methods void renderLauncher(); void renderNewProjectDialog(); void renderOpenProjectDialog(); void renderMainMenuBar(); void renderEnvironmentWindow(); void renderCameraWindow(); void renderHierarchyPanel(); void renderObjectNode(SceneObject& obj, const std::string& filter); void renderFileBrowserPanel(); void renderMeshBuilderPanel(); void renderInspectorPanel(); void renderConsolePanel(); void renderViewport(); void renderDialogs(); void renderProjectBrowserPanel(); Camera makeCameraFromObject(const SceneObject& obj) const; void compileScriptFile(const fs::path& scriptPath); void updateScripts(float delta); void renderFileBrowserToolbar(); void renderFileBrowserBreadcrumb(); void renderFileBrowserGridView(); void renderFileBrowserListView(); void renderFileContextMenu(const fs::directory_entry& entry); void handleFileDoubleClick(const fs::directory_entry& entry); ImVec4 getFileCategoryColor(FileCategory category) const; const char* getFileCategoryIconText(FileCategory category) const; // Project/scene management void createNewProject(const char* name, const char* location); void loadRecentScenes(); void saveCurrentScene(); void loadScene(const std::string& sceneName); void createNewScene(const std::string& sceneName); // Scene object management void addObject(ObjectType type, const std::string& baseName); void duplicateSelected(); void deleteSelected(); void setParent(int childId, int parentId); void loadMaterialFromFile(SceneObject& obj); void saveMaterialToFile(const SceneObject& obj); void recordState(const char* reason = ""); void undo(); void redo(); // Console/logging void addConsoleMessage(const std::string& message, ConsoleMessageType type); void logToConsole(const std::string& message); // Material helpers bool loadMaterialData(const std::string& path, MaterialProperties& props, std::string& albedo, std::string& overlay, std::string& normal, bool& useOverlay, std::string* vertexShaderOut = nullptr, std::string* fragmentShaderOut = nullptr); bool saveMaterialData(const std::string& path, const MaterialProperties& props, const std::string& albedo, const std::string& overlay, const std::string& normal, bool useOverlay, const std::string& vertexShader, const std::string& fragmentShader); // ImGui setup void setupImGui(); bool initRenderer(); public: Engine() = default; bool init(); void run(); void shutdown(); SceneObject* findObjectByName(const std::string& name); SceneObject* findObjectById(int id); fs::path resolveScriptBinary(const fs::path& sourcePath); void markProjectDirty(); // Script-accessible logging wrapper void addConsoleMessageFromScript(const std::string& message, ConsoleMessageType type); };