#include "engine.h" #include #include #include #include #include #include #include #include "resourcemanager.h" #include "scene/scenetree.h" #include "sparrowshell/sparrowshell.h" #include "scene/physicsdebugnode.h" #include "imgui/imgui.h" #include "tools/loader.h" #include "editor.h" #include "tools/loadingthread.h" Engine::Engine() : m_window(nullptr), m_input(nullptr), // m_world(nullptr), m_physicsDebugNode(nullptr), m_togglePhysicsDebugAction(NO_ACTION), m_toggleShellAction(NO_ACTION), m_exitGameAction(NO_ACTION), m_showMouseAction(NO_ACTION), m_mouseVisible(true), m_pickerEnabled(false) { m_clock = new sf::Clock(); m_clock->restart(); m_renderer = new SparrowRenderer(); } Engine::~Engine() { LoadingThread::destroy(); delete m_clock; delete m_renderer; if(m_window != NULL) { m_window->close(); delete m_window; delete m_input; } // if(m_world != NULL) // delete m_world; } void Engine::createWindow(std::string title, unsigned int w, unsigned int h, const std::string &mode) { sf::Uint32 style = sf::Style::Close; if(mode == "fullscreen") style = sf::Style::Fullscreen; else if(mode == "borderless") style = sf::Style::None; m_window = new sf::Window(sf::VideoMode(w, h), title, style, sf::ContextSettings(24, 8, 0, 3, 3, sf::ContextSettings::Attribute::Core)); m_window->setFramerateLimit(60); m_input = new Input(m_window); m_renderer->initGL(w, h); m_sparrowshell = new SparrowShell(m_window); m_editor = new Editor(); m_loadingThread = LoadingThread::init(); } /*void Engine::initPhysics() { btDefaultCollisionConfiguration *collisionConfiguration = new btDefaultCollisionConfiguration(); btBroadphaseInterface *broadPhase = new btAxisSweep3(btVector3(-1000, -1000, -1000), btVector3(1000, 1000, 1000)); btCollisionDispatcher *dispatcher = new btCollisionDispatcher(collisionConfiguration); btSequentialImpulseConstraintSolver *solver = new btSequentialImpulseConstraintSolver(); getScene()->setPhysics(new btDiscreteDynamicsWorld(dispatcher, broadPhase, solver, collisionConfiguration)); getScene()->getPhysics()->setGravity(btVector3(0, -9.81f, 0)); }*/ void Engine::update() { // update delta time m_lastTimeStamp = m_timeStamp; m_timeStamp = (unsigned int) m_clock->getElapsedTime().asMilliseconds(); // update Events m_input->updateEvents(); checkSpecialInputs(); // initialize imgui frame ImGuiIO& io = ImGui::GetIO(); io.DeltaTime = float(getDeltaTime()) / 1000.; ImGui::NewFrame(); // settings gui { static bool settingsGuiOpen = true; if(settingsGuiOpen) { ImGui::Begin("Window Settings", &settingsGuiOpen); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); bool physicsDebugEnabled = (m_physicsDebugNode != nullptr); if(ImGui::Checkbox("Toggle physics debug", &physicsDebugEnabled)) { if(physicsDebugEnabled) enablePhysicsDebug(); else disablePhysicsDebug(); } bool isMouseVisible = m_mouseVisible; if(ImGui::Checkbox("Mouse cursor ( shortcut : [M] )", &isMouseVisible)) toggleMouseVisibility(); ImGui::ProgressBar(m_loadingThread->getTotalProgress()); ImGui::End(); } } // update Physics if(getScene()->getPhysics() != nullptr) { getScene()->getPhysics()->stepSimulation(1000.f*(float)getDeltaTime()); if(m_physicsDebugNode != nullptr) { m_physicsDebugNode->clearBuffers(); getScene()->getPhysics()->debugDrawWorld(); getScene()->registerMeshType(m_physicsDebugNode->getFlags()); } } // update Scene getScene()->update(); getScene()->updateShaders(); // update Display if(m_input->isResized()) m_renderer->resizeGL(m_window->getSize().x, m_window->getSize().y); m_renderer->renderGL(); m_window->display(); } void Engine::start() { m_running = true; while(!m_input->isCloseRequested() && m_running) update(); } void Engine::stop() { m_running = false; } unsigned int Engine::getTime() const { return m_timeStamp; } unsigned int Engine::getDeltaTime() const { return m_timeStamp - m_lastTimeStamp; } //void Engine::setScene(SceneTree *scene) void Engine::setScene(std::string scene) { if(m_current_scene.empty()){ m_current_scene = scene; } SceneTree* previous_scene = RESOURCE_GET(SceneTree,m_current_scene); SceneTree* new_scene = RESOURCE_GET(SceneTree,scene); m_current_scene = scene; if(m_physicsDebugNode != nullptr) { previous_scene->removeFromIndex(m_physicsDebugNode); new_scene->addToIndex(m_physicsDebugNode); } previous_scene->getRootObject()->removeChild(m_sparrowshell); previous_scene->getRootObject()->removeChild(m_editor); m_renderer->setScene(new_scene); m_renderer->resizeGL(m_window->getSize().x, m_window->getSize().y); new_scene->getRootObject()->addChild(m_sparrowshell); new_scene->getRootObject()->addChild(m_editor); } void Engine::enablePhysicsDebug() { if(getScene()->getPhysics() != nullptr && m_physicsDebugNode == nullptr) { m_physicsDebugNode = new PhysicsDebugNode(); getScene()->addToIndex(m_physicsDebugNode); getScene()->registerMeshType(m_physicsDebugNode->getGeometryNode()->mesh->getFlags()); getScene()->getPhysics()->setDebugDrawer(m_physicsDebugNode); getScene()->getPhysics()->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe); } } void Engine::disablePhysicsDebug() { if(getScene()->getPhysics() != nullptr && m_physicsDebugNode != nullptr) { getScene()->getPhysics()->setDebugDrawer(nullptr); getScene()->removeFromIndex(m_physicsDebugNode); delete m_physicsDebugNode; m_physicsDebugNode = nullptr; } } void Engine::toggleMouseVisibility() { m_mouseVisible = !m_mouseVisible; m_window->setMouseCursorVisible(m_mouseVisible); m_input->setMouseGrabbed(!m_mouseVisible); } void Engine::setTogglePhysicsDebugAction(int action) { m_togglePhysicsDebugAction = action; } void Engine::setToggleShellAction(int action) { m_toggleShellAction = action; } void Engine::setExitGameAction(int action) { m_exitGameAction = action; } void Engine::setShowMouseAction(int action) { m_showMouseAction = action; } void Engine::checkSpecialInputs() { for(Action action : m_input->getActions()) { if(action.action == NO_ACTION) continue; if(action.action == m_togglePhysicsDebugAction) { if(m_physicsDebugNode == nullptr) enablePhysicsDebug(); else disablePhysicsDebug(); } else if(action.action == m_toggleShellAction) m_sparrowshell->toggleShell(); else if(action.action == m_exitGameAction) { if(m_sparrowshell->isVisible()) m_sparrowshell->toggleShell(); else m_running = false; } else if(action.action == m_showMouseAction) toggleMouseVisibility(); } } void Engine::createScene(std::string scene_name) { RESOURCE_ADD(new SceneTree(*this), SceneTree, scene_name); //return new SceneTree(*this); } SceneTree* Engine::getScene() const { return RESOURCE_GET(SceneTree,m_current_scene); }