diff --git a/CMakeLists.txt b/CMakeLists.txt index 3554584..d1ab2c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -519,10 +519,20 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") JPH_OBJECT_STREAM JPH_DEBUG_RENDERER ) + + target_compile_definitions(ScriptModule PRIVATE + JPH_ENABLE_ASSERTS + JPH_PROFILE_ENABLED + JPH_OBJECT_STREAM + JPH_DEBUG_RENDERER + ) else() # Release target_compile_definitions(Engine PRIVATE JPH_OBJECT_STREAM ) + target_compile_definitions(ScriptModule PRIVATE + JPH_OBJECT_STREAM + ) endif() target_link_libraries(Engine diff --git a/lib/All/JoltPhysics/lib/Debug/libJolt.a b/lib/All/JoltPhysics/lib/Debug/libJolt.a index a21b2ef..0c121f2 100644 Binary files a/lib/All/JoltPhysics/lib/Debug/libJolt.a and b/lib/All/JoltPhysics/lib/Debug/libJolt.a differ diff --git a/lib/All/JoltPhysics/lib/Release/libJolt.a b/lib/All/JoltPhysics/lib/Release/libJolt.a index 0d59514..177594a 100644 Binary files a/lib/All/JoltPhysics/lib/Release/libJolt.a and b/lib/All/JoltPhysics/lib/Release/libJolt.a differ diff --git a/lib/All/json-schema-validator/lib/libnlohmann_json_schema_validator.a b/lib/All/json-schema-validator/lib/libnlohmann_json_schema_validator.a index 757b834..a9d95dc 100644 Binary files a/lib/All/json-schema-validator/lib/libnlohmann_json_schema_validator.a and b/lib/All/json-schema-validator/lib/libnlohmann_json_schema_validator.a differ diff --git a/src/Engine/Configurations/Configuration/CConfiguration.cpp b/src/Engine/Configurations/Configuration/CConfiguration.cpp deleted file mode 100644 index d5f17f0..0000000 --- a/src/Engine/Configurations/Configuration/CConfiguration.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "CConfiguration.hpp" -#include "nlohmann/json.hpp" - -#include - - -namespace CosmicConfig { - CModuleConfig CConfiguration::moduleConfiguration; - - - void CModuleConfig::parse(nlohmann::json& jsonModule) - { - modulesDirectory = jsonModule["modulesDirectory"].get(); - } - - void CConfiguration::init(std::filesystem::path configFilePath) - { - std::ifstream fileConf(configFilePath); - auto json = nlohmann::json::parse(fileConf); - if(json.contains("Modules")) - { - moduleConfiguration.parse(json["Modules"]); - } - } -} \ No newline at end of file diff --git a/src/Engine/Configurations/Configuration/CConfiguration.hpp b/src/Engine/Configurations/Configuration/CConfiguration.hpp deleted file mode 100644 index aded165..0000000 --- a/src/Engine/Configurations/Configuration/CConfiguration.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CCONFIGURATION_HPP -#define CCONFIGURATION_HPP - -#include "nlohmann/json_fwd.hpp" -#include -namespace CosmicConfig { - class CModuleConfig{ - private: - std::filesystem::path modulesDirectory; - public: - std::filesystem::path getModulesDirectory(){return modulesDirectory;}; - void parse(nlohmann::json& jsonModule); - }; - - class CConfiguration - { - public: - static CModuleConfig moduleConfiguration; - static void init(std::filesystem::path configFilePath = "engineConfiguration.json"); - }; -} -#endif \ No newline at end of file diff --git a/src/Engine/Core/Component/Input/CInputManager.cpp b/src/Engine/Core/Component/Input/CInputManager.cpp new file mode 100644 index 0000000..5696a17 --- /dev/null +++ b/src/Engine/Core/Component/Input/CInputManager.cpp @@ -0,0 +1,67 @@ +#include "CInputManager.hpp" +#include "Core/Systems/Input/API/CInputAPI.hpp" + +namespace CosmicCore { + + void CInputManager::onPressed(const std::string& actionName, std::function cb) + { + m_onPressed.push_back({actionName, cb, 0, false}); + } + + void CInputManager::onHeld(const std::string& actionName, std::function cb) + { + m_onHeld.push_back({actionName, cb, 0, false}); + } + + void CInputManager::onReleased(const std::string& actionName, std::function cb) + { + m_onReleased.push_back({actionName, cb, 0, false}); + } + + void CInputManager::onMouseMove(std::function cb) + { + m_onMouseMove = cb; + } + + // appelé par CInputWorld::updateWorld() + void CInputManager::dispatch(const CInputDispatcher& inputWorld) { + if (!m_enabled) return; + auto& entity = getEntity(); + + // résolution lazy — une seule fois par action + for (auto& bound : m_onHeld) { + if (!bound.resolved) { + auto action = CInputAPI::getAction(bound.name); + if (action) { + bound.resolvedId = *action; + bound.resolved = true; + } + // si pas encore enregistrée → retry au prochain frame + } + if (bound.resolved && inputWorld.isActive(bound.resolvedId)) + bound.cb(entity); + } + + for (auto& bound : m_onPressed) { + if (!bound.resolved) { + auto action = CInputAPI::getAction(bound.name); + if (action) { bound.resolvedId = *action; bound.resolved = true; } + } + if (bound.resolved && inputWorld.isJustPressed(bound.resolvedId)) + bound.cb(entity); + } + + for (auto& bound : m_onReleased) { + if (!bound.resolved) { + auto action = CInputAPI::getAction(bound.name); + if (action) { bound.resolvedId = *action; bound.resolved = true; } + } + if (bound.resolved && inputWorld.isJustReleased(bound.resolvedId)) + bound.cb(entity); + } + + glm::vec2 mouseRel = inputWorld.getMouseRelative(); + if (m_onMouseMove && (mouseRel.x != 0 || mouseRel.y != 0)) + m_onMouseMove(entity, mouseRel); + } +} \ No newline at end of file diff --git a/src/Engine/Core/Component/Input/CInputManager.hpp b/src/Engine/Core/Component/Input/CInputManager.hpp new file mode 100644 index 0000000..e92a7be --- /dev/null +++ b/src/Engine/Core/Component/Input/CInputManager.hpp @@ -0,0 +1,48 @@ +#ifndef CINPUTMANAGER_HPP +#define CINPUTMANAGER_HPP + +#include "../CAbstractComponent.hpp" +#include "../../Systems/Input/API/CInputAPI.hpp" +#include "../../Systems/Input/CInputDispatcher.hpp" +#include "glm/fwd.hpp" +#include "nlohmann/json_fwd.hpp" + +namespace CosmicCore { + + class CInputManager : public CAbstractComponent + { + private: + + struct BoundAction { + std::string name; + std::function cb; + InputAction resolvedId = 0; + bool resolved = false; + }; + std::vector m_onHeld; + std::vector m_onPressed; + std::vector m_onReleased; + + std::function m_onMouseMove; + + bool m_enabled = true; + + public: + CInputManager(CEntity& entity) : CAbstractComponent(entity) {} + + + void onPressed(const std::string& actionName, std::function cb); + void onHeld(const std::string& actionName, std::function cb); + void onReleased(const std::string& actionNamen, std::function cb); + void onMouseMove(std::function cb); + + void setEnabled(bool enabled) { m_enabled = enabled; } + + void dispatch(const CInputDispatcher& inputWorld); + + nlohmann::json to_json(){return nlohmann::json();} + + }; +} + +#endif \ No newline at end of file diff --git a/src/Engine/Core/Component/Light/CAbstractLight.cpp b/src/Engine/Core/Component/Light/CAbstractLight.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/Engine/Core/Component/Light/CAbstractLight.hpp b/src/Engine/Core/Component/Light/CAbstractLight.hpp deleted file mode 100644 index 678059d..0000000 --- a/src/Engine/Core/Component/Light/CAbstractLight.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef CABSTRACTLIGHT_HPP -#define CABSTRACTLIGHT_HPP -#include "../CAbstractComponent.hpp" -namespace CosmicCore { - class CAbstractLight: public CAbstractComponent - { - - }; -} -#endif \ No newline at end of file diff --git a/src/Engine/Core/Component/Light/CLight.cpp b/src/Engine/Core/Component/Light/CLight.cpp new file mode 100644 index 0000000..0954e62 --- /dev/null +++ b/src/Engine/Core/Component/Light/CLight.cpp @@ -0,0 +1,5 @@ +#include "CLight.hpp" + +namespace CosmicCore { + +} \ No newline at end of file diff --git a/src/Engine/Core/Component/Light/CLight.hpp b/src/Engine/Core/Component/Light/CLight.hpp new file mode 100644 index 0000000..4aebf3d --- /dev/null +++ b/src/Engine/Core/Component/Light/CLight.hpp @@ -0,0 +1,51 @@ +#ifndef CLIGHT_HPP +#define CLIGHT_HPP +#include "../CAbstractComponent.hpp" +#include "glm/ext/vector_float3.hpp" +namespace CosmicCore { + + enum class ELightType { + Directional, // soleil + Point, // ampoule + Spot // lampe torche + }; + + class CLight: public CAbstractComponent + { + // données communes + glm::vec3 color = {1.0f, 1.0f, 1.0f}; + float intensity = 1.0f; + bool castShadow = false; + + // Point + Spot + float range = 10.0f; + float attenuation = 1.0f; // falloff + + // Spot uniquement + float innerAngle = 15.0f; // degrés + float outerAngle = 30.0f; // degrés + + ELightType type = ELightType::Directional; + + CLight(CEntity& entity, ELightType type = ELightType::Directional) + : CAbstractComponent(entity), type(type) {} + + CLight(CLight&&) = default; + CLight& operator=(CLight&&) = default; + CLight(const CLight&) = delete; + CLight& operator=(const CLight&) = delete; + + nlohmann::json to_json() const { + nlohmann::json j; + j["type"] = (int)type; + j["color"] = {color.r, color.g, color.b}; + j["intensity"] = intensity; + j["range"] = range; + j["innerAngle"] = innerAngle; + j["outerAngle"] = outerAngle; + j["castShadow"] = castShadow; + return j; + } + }; +} +#endif \ No newline at end of file diff --git a/src/Engine/Core/Component/Script/CAbstractScript.hpp b/src/Engine/Core/Component/Script/CAbstractScript.hpp index a24fb4c..a325e5b 100644 --- a/src/Engine/Core/Component/Script/CAbstractScript.hpp +++ b/src/Engine/Core/Component/Script/CAbstractScript.hpp @@ -14,7 +14,7 @@ namespace CosmicCore { CAbstractScript(CEntity& entity, const std::string& name); CAbstractScript(CAbstractScript&& other) = default; CAbstractScript& operator=(CAbstractScript&&) = default; - + virtual void onCreate() = 0; virtual void start() = 0; virtual void update() = 0; virtual void destroy() = 0; diff --git a/src/Engine/Core/Component/Script/CScript.cpp b/src/Engine/Core/Component/Script/CScript.cpp index ae4e5fa..baa0b2c 100644 --- a/src/Engine/Core/Component/Script/CScript.cpp +++ b/src/Engine/Core/Component/Script/CScript.cpp @@ -6,12 +6,13 @@ namespace CosmicCore { CScript::CScript(CEntity& entity, const std::string& name, std::unique_ptr&& innerScript) : CAbstractScript(entity, name), m_innerScript(std::move(innerScript)) { - + onCreate(); } CScript::CScript(CEntity& entity, const std::string& name) : CAbstractScript(entity, name) { m_innerScript = CScriptAPI::scripts().create(name, entity, name); + onCreate(); } void CScript::start() @@ -29,6 +30,11 @@ namespace CosmicCore { m_innerScript->destroy(); } + void CScript::onCreate() + { + m_innerScript->onCreate(); + } + nlohmann::json CScript::to_json() { return m_innerScript->to_json(); diff --git a/src/Engine/Core/Component/Script/CScript.hpp b/src/Engine/Core/Component/Script/CScript.hpp index ca5ca15..7f525d9 100644 --- a/src/Engine/Core/Component/Script/CScript.hpp +++ b/src/Engine/Core/Component/Script/CScript.hpp @@ -17,7 +17,7 @@ namespace CosmicCore { CScript(CEntity& entity, const std::string& name); CScript(CScript&& mov) = default; CScript& operator=(CScript&&) = default; - + void onCreate() override; void start() override; void update() override; void destroy() override; diff --git a/src/Engine/Core/Kernel/CKernel.cpp b/src/Engine/Core/Kernel/CKernel.cpp index f874d28..de58ca6 100644 --- a/src/Engine/Core/Kernel/CKernel.cpp +++ b/src/Engine/Core/Kernel/CKernel.cpp @@ -1,226 +1,6 @@ + #include "CKernel.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../Systems/Graphics/CContext.hpp" -#include "../Systems/Graphics/API/GraphicsAPI.hpp" -#include "../Systems/Physics/API/CPhysicsAPI.hpp" -#include "../Scene/CScene.hpp" -#include "../Entity/CEntity.hpp" -#include "../Component/Camera/CCamera.hpp" -#include "../../Utils/Factory/CEntityFactory.hpp" -#include "../../Utils/Factory/ComponentFactory.hpp" -#include "../../Utils/JsonParser/Identifier.hpp" - -#include "../Component/Graphics/CRenderer.hpp" - -#include "../Modules/Scripts/CScriptRegister.hpp" -#include "Core/Systems/Scripts/API/CScriptAPI.hpp" -#include "glm/ext/vector_float3.hpp" -//CShader* CKernel::m_mainShader; - -// #define NAME "Cosmic Engine" -#define LOGO "assets/spaceEngineIcon.png" -// #define SPLASH "../assets/shrekt.png" -// #define SPLASH_HEIGHT 512 -// #define SPLASH_WIDTH 512 -// #define GAME_HEIGHT 360 -// #define GAME_WIDTH 640 - namespace CosmicCore { - - CKernel* CKernel::m_kernel; - - CKernel::CKernel(std::string name, std::string gameName) : - m_gameName(gameName), m_window(gameName, LOGO, 1270, 720, true, false) - { - m_kernel = this; - CContext::init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC); - CScriptAPI::init(); - } - - CKernel::~CKernel() - { - } - - CScene* CKernel::getActiveScene() - { - return m_activeScene; - } - - void CKernel::start(bool isPreview) { - //CScriptRegister::registerAllScripts(); - JPH::RegisterDefaultAllocator(); - //JPH::Trace = JoltTraceImpl; - JPH::Factory::sInstance = new JPH::Factory(); - JPH::RegisterTypes(); - - std::filesystem::path pathToSchema("schema_json.json"); - CosmicUtils::JsonValidator::init(pathToSchema); - if(!isPreview) - { - m_window.initialization(); - auto scene = CScene::load("scenes/scene1.json"); - m_activeScene = scene.get(); - m_sceneMap[scene->getName()] = std::move(scene); - } - } - - void CKernel::loop() { - - unsigned int frameRate(1000 / 144); - unsigned int beginIterationTime(0); - unsigned int endIterationTime(0); - unsigned int spendedIterationTime(0); - unsigned int lastFrame = 0; - m_window.setVisible(true); - m_window.setResizable(true); - while (!m_finished) { - // Define the starting time. - beginIterationTime = SDL_GetTicks(); - - // Compute the delta time. - unsigned int currentFrame = beginIterationTime; - m_deltaTime = currentFrame - lastFrame; - lastFrame = currentFrame; - - // Update event system. - //m_inputHandler.updateEvent(); - // ####### start render ####### - - SDL_Event event; - while (SDL_PollEvent(&event)) - { - if (event.type == SDL_EVENT_QUIT) - m_finished = true; - if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(m_window.getWindow())) - m_finished = true; - if (event.type == SDL_EVENT_KEY_DOWN) { - // Handle key press - SDL_Keycode keyPressed = event.key.key; - auto entities = m_activeScene->getECManager().registry.view(); - auto shrek = m_activeScene->getECManager().registry.view(); - - auto& ent = m_activeScene->getECManager().registry.get(entities.front()); - auto& speaker = m_activeScene->getECManager().registry.get(shrek.front()); - - switch (keyPressed) { - case SDLK_Z: - ent.forward({0.0f, 0.0f, -0.08f}); - break; - case SDLK_Q: - ent.forward({-0.08f, 0.0f, 0.0f}); - break; - case SDLK_S: - ent.forward({0.0f, 0.0f, 0.08f}); - break; - case SDLK_D: - ent.forward({0.08f, 0.0f, 0.0f}); - break; - case SDLK_E: - ent.forward({0.0f, -0.08f, 0.0f}); - break; - case SDLK_A: - ent.forward({0.0f, 0.08f, 0.0f}); - break; - case SDLK_P: - speaker.play("assets/GiveAlittleBit.flac"); - break; - default: - break; - } - - // Process the key pressed - } - if(event.type == SDL_EVENT_MOUSE_MOTION) - { - auto entities = m_activeScene->getECManager().registry.view(); - auto& ent = m_activeScene->getECManager().registry.get(entities.front()); - static const float sensitivity = 0.1f; - // yaw : rotation autour de Y global (axe monde) - ent.rotate(glm::vec3(0.0f, 1.0f, 0.0f), glm::radians(-event.motion.xrel * sensitivity)); - - // pitch : rotation autour de X local (axe de la caméra) - ent.rotate(glm::vec3(1.0f, 0.0f, 0.0f), glm::radians(-event.motion.yrel * sensitivity)); - } - } - - if(m_activeScene) - { - m_activeScene->getTangibleWorld().updateWorld(1.0f/60.0f); - m_activeScene->getAudioWorld().updateWorld(1.0f/60.0f); - m_activeScene->getScriptWorld().updateWorld(1.0f/60.0f); - - //TODO scne update -> physics + audio + scripts ? - GraphicsAPI::getAPI()->drawFrame(); - } - - // ####### end render ####### - - // Compute the end and spended time . - endIterationTime = SDL_GetTicks(); - - spendedIterationTime = endIterationTime - beginIterationTime; - // If need, we pause the programm to have the right fps amount. - if (spendedIterationTime < frameRate) { - SDL_Delay(frameRate - spendedIterationTime); - } - } - GraphicsAPI::getAPI()->cleanup(); - CContext::quit(); - } - - void CKernel::quit() { - m_finished = true; - JPH::UnregisterTypes(); - // Destroy the factory - delete JPH::Factory::sInstance; - JPH::Factory::sInstance = nullptr; - } - - - void CKernel::fullscreen() { - /*if (!m_config.getFullscreen()) { - m_window.setSize(m_config.getFullScreenSize()); - m_window.setCursorGrabbed(true); - m_window.setFullscreen(true); - m_config.setFullscreen(true); - glViewport(0, 0, m_config.getFullScreenSize().first, m_config.getFullScreenSize().second); - } - else { - m_window.setSize(m_config.getWindowSize()); - m_window.setCursorGrabbed(true); - m_window.setFullscreen(false); - m_config.setFullscreen(false); - glViewport(0, 0, m_config.getWindowSize().first, m_config.getWindowSize().second); - } - // Sauvegarde la nouvelle conf. - m_config.save();*/ - } - - void CKernel::desktop() { - /*if (m_config.getFullscreen()) { - m_window.setSize(m_config.getWindowSize()); - m_window.setCursorGrabbed(false); - m_window.setFullscreen(false); - m_config.setFullscreen(false); - glViewport(0, 0, m_config.getWindowSize().first, m_config.getWindowSize().second); - } - m_window.setCursorGrabbed(false);*/ - } - - void CKernel::focus() { - //m_window.setCursorGrabbed(true); - } - + CKernelBase* CKernelBase::m_kernelBase = nullptr; } diff --git a/src/Engine/Core/Kernel/CKernel.hpp b/src/Engine/Core/Kernel/CKernel.hpp index c2c8d3f..56523c3 100644 --- a/src/Engine/Core/Kernel/CKernel.hpp +++ b/src/Engine/Core/Kernel/CKernel.hpp @@ -1,6 +1,8 @@ #ifndef CKERNEL_HPP #define CKERNEL_HPP +#include "Core/Systems/Input/CInputDispatcher.hpp" +#include "../../Utils/Configurations/CBasicConfiguration.hpp" #include #define GLM_ENABLE_EXPERIMENTAL #include @@ -10,8 +12,59 @@ #include "../Systems/Graphics/Window/CGameWindow.hpp" #include "../Scene/CScene.hpp" +#include "../../Utils/Configurations/CEngineConfiguration.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../Systems/Graphics/CContext.hpp" +#include "../Systems/Graphics/API/GraphicsAPI.hpp" +#include "../Systems/Physics/API/CPhysicsAPI.hpp" +#include "../Scene/CScene.hpp" +#include "../Entity/CEntity.hpp" +#include "../../Utils/Factory/CEntityFactory.hpp" +#include "../../Utils/JsonParser/Identifier.hpp" + +#include "Core/Systems/Scripts/API/CScriptAPI.hpp" +//CShader* CKernel::m_mainShader; + +// #define NAME "Cosmic Engine" +#define LOGO "assets/spaceEngineIcon.png" +// #define SPLASH "../assets/shrekt.png" +// #define SPLASH_HEIGHT 512 +// #define SPLASH_WIDTH 512 +// #define GAME_HEIGHT 360 +// #define GAME_WIDTH 640 + namespace CosmicCore { + using namespace CosmicUtils; + + class CKernelBase { + private: + static CKernelBase* m_kernelBase; + + public: + static CKernelBase* instance() { return m_kernelBase; } + static void setKernelInstance(CKernelBase* ins){m_kernelBase = ins;} + // Méthodes virtuelles que tous les kernels doivent avoir + virtual std::string getName() = 0; + virtual unsigned int getDeltatime() = 0; + virtual void setDeltatime(unsigned int delta) = 0; + virtual CScene* getActiveScene() = 0; + virtual void quit() = 0; + virtual void cleanup() = 0; + + virtual ~CKernelBase() = default; + }; /** * @file CKernel.hpp @@ -21,18 +74,20 @@ namespace CosmicCore { /** * @brief Central class of the game, handle window and I/O. */ - class CKernel { + template + class CKernel : public CKernelBase{ private: std::string m_configPath; std::string m_gameName; // The config. - //CGameConfiguration m_config; - //CEngineConfiguration m_engineConfig; + CEngineConfiguration m_engineConfig; + TGameConfig m_gameConfig; // The windows. //CLoadingWindow m_loadingWindow; CGameWindow m_window; - + CInputDispatcher m_inputWorld; + // Global game var. bool m_finished; unsigned int m_deltaTime; @@ -42,38 +97,13 @@ namespace CosmicCore { std::map> m_sceneMap; public: - /** - * @brief A pointer to the simulation which is accessible from anywhere. - */ - static CKernel* m_kernel; CKernel() = delete; - CKernel(std::string name, std::string gameName); - - ~CKernel(); std::string getName() { return m_gameName; }; - - //CGameConfiguration* getConfig() { return &m_config; }; - //CEngineConfiguration* getEngineConfig() { return &m_engineConfig; }; - //void addScene(std::shared_ptr& scene); - //void setActiveScene(std::string scene); - - CScene* getActiveScene(); void cleanup(){m_sceneMap.clear();}; - //unsigned int getNbScene() { return m_sceneList.size(); }; - //std::map& getScenes() { return m_sceneList; }; - - /*CKeyboard* getKeyboard(void) { - return m_inputHandler.getKeyboard(); - }*/ - - /*CMouse* getMouse(void) { - return m_inputHandler.getMouse(); - }*/ - unsigned int getDeltatime(void) { return m_deltaTime; } @@ -82,15 +112,153 @@ namespace CosmicCore { m_deltaTime = delta; } - //CGameWindow& getGameWindow(){return m_window;}; + CKernel(std::string name, std::string gameName) : + m_gameName(gameName), m_window(gameName, LOGO, 1270, 720, true, false) + { + setKernelInstance(this); + } + + ~CKernel() + { + } + + CScene* getActiveScene() + { + return m_activeScene; + } + + void start(bool isPreview = false) { + loadConfigurations(); + CContext::init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC); + CScriptAPI::init(); + + //CScriptRegister::registerAllScripts(); + CPhysicsAPI::init(); + + std::filesystem::path pathToSchema("schema_json.json"); + CosmicUtils::JsonValidator::init(pathToSchema); + if(!isPreview) + { + m_window.initialization(); + auto scene = CScene::load("scenes/scene1.json"); + m_activeScene = scene.get(); + m_sceneMap[scene->getName()] = std::move(scene); + } + } + + void loadConfigurations() + { + if(m_engineConfig.load("config/engine/engine.json")) + { + // Configuration fenêtre + // TODO: appliquer les settings de fenêtre via CGameWindow ou GraphicsAPI + m_window.setSize(m_engineConfig.window.width, m_engineConfig.window.height); + m_window.setTitle(m_engineConfig.window.title); + if(m_engineConfig.window.fullscreen) m_window.setFullscreen(true); + + // Configuration input + m_inputWorld.loadActions(m_engineConfig.input.actionsPath); + m_inputWorld.loadBindings(m_engineConfig.input.bindingsPath); + + m_inputWorld.getMapping().setMouseSensitivity(m_engineConfig.input.mouseSensitivity); + } + if(m_gameConfig.load("config/game/game.json")) + { + m_window.setSize(m_gameConfig.window.width, m_gameConfig.window.height); + m_window.setTitle(m_gameConfig.window.title); + if(m_gameConfig.window.fullscreen) m_window.setFullscreen(true); + m_inputWorld.loadActions(m_gameConfig.input.actionsPath); + m_inputWorld.loadBindings(m_gameConfig.input.bindingsPath); + m_inputWorld.getMapping().setMouseSensitivity(m_gameConfig.input.mouseSensitivity); + } + // Configuration graphique + // TODO: GraphicsAPI::getAPI()->setValidationLayers(m_gameConfig.graphics.validationLayers); + // TODO: GraphicsAPI::getAPI()->setMaxFramesInFlight(m_gameConfig.graphics.maxFramesInFlight); + + // Configuration audio + // TODO: C AudioAPI::setMasterGain(m_gameConfig.audio.masterGain); + // TODO: C AudioAPI::setMusicGain(m_gameConfig.audio.musicGain); + + } + + void loop() { + + unsigned int frameRate(1000 / 144); + unsigned int beginIterationTime(0); + unsigned int endIterationTime(0); + unsigned int spendedIterationTime(0); + unsigned int lastFrame = 0; + m_window.setVisible(true); + m_window.setResizable(true); + while (!m_finished) { + // Define the starting time. + beginIterationTime = SDL_GetTicks(); + + // Compute the delta time. + unsigned int currentFrame = beginIterationTime; + m_deltaTime = currentFrame - lastFrame; + lastFrame = currentFrame; + + // Update event system. + //m_inputHandler.updateEvent(); + // ####### start render ####### + + SDL_Event event; + while (SDL_PollEvent(&event)) + { + if (event.type == SDL_EVENT_QUIT) + m_finished = true; + if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(m_window.getWindow())) + m_finished = true; + + m_inputWorld.processEvent(event); + } + + if(m_activeScene) + { + m_inputWorld.dispatch(m_activeScene); + m_activeScene->getScriptWorld().updateWorld(1.0f/60.0f); + m_activeScene->getTangibleWorld().updateWorld(1.0f/60.0f); + m_activeScene->getAudioWorld().updateWorld(1.0f/60.0f); + + //TODO scne update -> physics + audio + scripts ? + GraphicsAPI::getAPI()->drawFrame(); + } + + // ####### end render ####### + + // Compute the end and spended time . + endIterationTime = SDL_GetTicks(); + + spendedIterationTime = endIterationTime - beginIterationTime; + // If need, we pause the programm to have the right fps amount. + if (spendedIterationTime < frameRate) { + SDL_Delay(frameRate - spendedIterationTime); + } + } + GraphicsAPI::getAPI()->cleanup(); + CPhysicsAPI::cleanup(); + CContext::quit(); + } + + void quit() { + m_finished = true; + } + + + void fullscreen() { + } + + void desktop() { + } + + void focus() { + } + - void start(bool isPreview = false); - void loop(); - void quit(); - void fullscreen(); - void desktop(); - void focus(); }; + //template CKernel* CKernel::m_kernel; } + #endif \ No newline at end of file diff --git a/src/Engine/Core/Scene/CScene.cpp b/src/Engine/Core/Scene/CScene.cpp index d72810a..6fea9c6 100644 --- a/src/Engine/Core/Scene/CScene.cpp +++ b/src/Engine/Core/Scene/CScene.cpp @@ -21,7 +21,10 @@ namespace CosmicCore { CScene::CScene(std::string name) : CSerializable(), - m_name(std::move(name)), m_tangibleWorld(this), m_audioWorld(this), m_scriptWorld(this) + m_name(std::move(name)), + m_tangibleWorld(this), + m_audioWorld(this), + m_scriptWorld(this) { m_tangibleWorld.initWorld(); m_audioWorld.initWorld(); diff --git a/src/Engine/Core/Scene/CScene.hpp b/src/Engine/Core/Scene/CScene.hpp index d7de811..4561f62 100644 --- a/src/Engine/Core/Scene/CScene.hpp +++ b/src/Engine/Core/Scene/CScene.hpp @@ -7,7 +7,7 @@ #include #include "../Systems/Physics/CTangibleWorld.hpp" #include "../Systems/Audio/CAudioWorld.hpp" -#include "Core/Systems/Scripts/CScriptWorld.hpp" +#include "../Systems/Scripts/CScriptWorld.hpp" namespace CosmicCore { class CEntity; diff --git a/src/Engine/Core/Systems/Graphics/API/VulkanImplementation/VulkanImpl.cpp b/src/Engine/Core/Systems/Graphics/API/VulkanImplementation/VulkanImpl.cpp index c7828b1..ce06c71 100644 --- a/src/Engine/Core/Systems/Graphics/API/VulkanImplementation/VulkanImpl.cpp +++ b/src/Engine/Core/Systems/Graphics/API/VulkanImplementation/VulkanImpl.cpp @@ -82,7 +82,7 @@ void VulkanImpl::cleanup(){ // (buffers, pipelines, descriptor sets...) m_deletionQueue.flushAll(); - CosmicCore::CKernel::m_kernel->cleanup(); + CosmicCore::CKernelBase::instance()->cleanup(); CResourceAPI::resources().cleanup(); m_deletionQueue.flushAll(); @@ -450,7 +450,7 @@ void VulkanImpl::recordCommandBuffer(uint32_t imageIndex) commandBuffer.setViewport(0, vk::Viewport(0.0f, 0.0f, static_cast(swapChainExtent.width), static_cast(swapChainExtent.height), 0.0f, 1.0f)); commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(0, 0), swapChainExtent)); - CosmicCore::CKernel::m_kernel->getActiveScene()->render(commandBuffer, frameIndex); + CosmicCore::CKernelBase::instance()->getActiveScene()->render(commandBuffer, frameIndex); commandBuffer.endRendering(); // After rendering, transition the swapchain image to PRESENT_SRC diff --git a/src/Engine/Core/Systems/Input/API/CInputAPI.cpp b/src/Engine/Core/Systems/Input/API/CInputAPI.cpp new file mode 100644 index 0000000..fbc4044 --- /dev/null +++ b/src/Engine/Core/Systems/Input/API/CInputAPI.cpp @@ -0,0 +1,18 @@ +#include "CInputAPI.hpp" + +namespace CosmicCore { + + std::unordered_map CInputAPI::m_nameToId = {}; + std::unordered_map CInputAPI::m_idToName = {}; + InputAction CInputAPI::m_nextId = 0; + + InputAction CInputAPI::registerAction(const std::string& name) { + auto it = m_nameToId.find(name); + if (it != m_nameToId.end()) return it->second; + + InputAction id = m_nextId++; + m_nameToId[name] = id; + m_idToName[id] = name; + return id; + } +} diff --git a/src/Engine/Core/Systems/Input/API/CInputAPI.hpp b/src/Engine/Core/Systems/Input/API/CInputAPI.hpp new file mode 100644 index 0000000..dd8f44b --- /dev/null +++ b/src/Engine/Core/Systems/Input/API/CInputAPI.hpp @@ -0,0 +1,40 @@ +#ifndef CINPUTAPI_HPP +#define CINPUTAPI_HPP + + +#include +#include +#include +#include +#include +namespace CosmicCore { + + using InputAction = uint32_t; + + class CScene; + + class CInputAPI + { + private: + static std::unordered_map m_nameToId; + static std::unordered_map m_idToName; + static InputAction m_nextId; + + public: + static InputAction registerAction(const std::string& name); + + static std::optional getAction(const std::string& name) { + std::cout << &m_nameToId << std::endl; + return (m_nameToId.find(name) != m_nameToId.end() ? std::optional(m_nameToId[name]) : std::nullopt);}; + + }; + + + + // macro helper + #define REGISTER_ACTION(name) \ + namespace EAction { \ + inline const InputAction name = CInputAPI::registerAction(#name);\ + } +} +#endif \ No newline at end of file diff --git a/src/Engine/Core/Systems/Input/CInputBinding.hpp b/src/Engine/Core/Systems/Input/CInputBinding.hpp new file mode 100644 index 0000000..5b2745e --- /dev/null +++ b/src/Engine/Core/Systems/Input/CInputBinding.hpp @@ -0,0 +1,39 @@ +#ifndef CINPUTBINDING_HPP +#define CINPUTBINDING_HPP + +#include + +namespace CosmicCore { + enum class EInputDevice { + Keyboard, + Mouse, + GamepadButton, + GamepadAxis + }; + + struct CInputBinding + { + EInputDevice device = EInputDevice::Keyboard; + + SDL_Keycode key = SDLK_UNKNOWN; // keyboard + uint8_t button = 0; // mouse button / gamepad button + uint8_t axis = 0; // gamepad axis + float scale = 1.0f; // pour inverser ou pondérer + + // constructeurs helpers + static CInputBinding fromKey(SDL_Keycode key, float scale = 1.0f) { + return {EInputDevice::Keyboard, key, 0, 0, scale}; + } + static CInputBinding fromMouseButton(uint8_t button, float scale = 1.0f) { + return {EInputDevice::Mouse, SDLK_UNKNOWN, button, 0, scale}; + } + static CInputBinding fromGamepadAxis(uint8_t axis, float scale = 1.0f) { + return {EInputDevice::GamepadAxis, SDLK_UNKNOWN, 0, axis, scale}; + } + static CInputBinding fromGamepadButton(uint8_t button, float scale = 1.0f) { + return {EInputDevice::GamepadButton, SDLK_UNKNOWN, button, 0, scale}; + } + }; +} + +#endif \ No newline at end of file diff --git a/src/Engine/Core/Systems/Input/CInputDispatcher.cpp b/src/Engine/Core/Systems/Input/CInputDispatcher.cpp new file mode 100644 index 0000000..8470087 --- /dev/null +++ b/src/Engine/Core/Systems/Input/CInputDispatcher.cpp @@ -0,0 +1,103 @@ +#include "CInputDispatcher.hpp" +#include "../../Scene/CScene.hpp" +#include "../../Component/Input/CInputManager.hpp" +#include "Core/Systems/Input/API/CInputAPI.hpp" +#include +namespace CosmicCore { + + CInputDispatcher::~CInputDispatcher() + { + + } + + void CInputDispatcher::dispatch(CScene* scene) { + auto& registry = scene->getECManager().registry; + auto view = registry.view(); + + for (auto entity : view) { + auto& input = registry.get(entity); + input.dispatch(*this); + } + + // reset souris relative après dispatch + m_mouseRelative = {0, 0}; + } + + void CInputDispatcher::processEvent(const SDL_Event& event) + { + m_justPressed.clear(); + m_justReleased.clear(); + + switch (event.type) { + case SDL_EVENT_KEY_DOWN: { + auto action = m_mapping.findAction(event.key.key); + if (action) { + if (!m_activeActions.count(*action)) + m_justPressed.insert(*action); + m_activeActions.insert(*action); + } + break; + } + case SDL_EVENT_KEY_UP: { + auto action = m_mapping.findAction(event.key.key); + if (action) { + m_activeActions.erase(*action); + m_justReleased.insert(*action); + } + break; + } + case SDL_EVENT_MOUSE_MOTION: { + m_mouseRelative = {event.motion.xrel, event.motion.yrel}; + m_mousePosition = {event.motion.x, event.motion.y}; + break; + } + } + } + + void CInputDispatcher::loadActions(const std::string& path) { + std::ifstream file(path); + nlohmann::json j = nlohmann::json::parse(file); + + for (auto& name : j["actions"]) + CInputAPI::registerAction(name.get()); + } + + void CInputDispatcher::loadBindings(const std::string& path) { + std::ifstream file(path); + nlohmann::json j = nlohmann::json::parse(file); + + m_mapping.clearAll(); + + for (auto& binding : j["bindings"]) { + std::string actionName = binding["action"]; + auto action = CInputAPI::getAction(actionName); + if (!action) { + continue; + } + + std::string device = binding["device"]; + if (device == "keyboard") { + SDL_Keycode key = SDL_GetKeyFromName( + binding["key"].get().c_str() + ); + m_mapping.bind(*action, CInputBinding::fromKey(key)); + } + else if (device == "mouse") { + m_mapping.bind(*action, + CInputBinding::fromMouseButton(binding["button"])); + } + else if (device == "gamepad_button") { + m_mapping.bind(*action, + CInputBinding::fromGamepadButton(binding["button"])); + } + else if (device == "gamepad_axis") { + float scale = binding.value("scale", 1.0f); + m_mapping.bind(*action, + CInputBinding::fromGamepadAxis(binding["axis"], scale)); + } + } + + if (j.contains("mouse_sensitivity")) + m_mapping.setMouseSensitivity(j["mouse_sensitivity"]); + } +} \ No newline at end of file diff --git a/src/Engine/Core/Systems/Input/CInputDispatcher.hpp b/src/Engine/Core/Systems/Input/CInputDispatcher.hpp new file mode 100644 index 0000000..b5e9123 --- /dev/null +++ b/src/Engine/Core/Systems/Input/CInputDispatcher.hpp @@ -0,0 +1,48 @@ +#ifndef CINPUTWORLD_HPP +#define CINPUTWORLD_HPP + +#include "API/CInputAPI.hpp" +#include "CInputMapping.hpp" +#include "../../Scene/CScene.hpp" +#include "glm/ext/vector_float2.hpp" +#include +#include + +namespace CosmicCore { + + class CInputDispatcher{ + + private: + std::unordered_set m_activeActions; + std::unordered_set m_justPressed; + std::unordered_set m_justReleased; + glm::vec2 m_mouseRelative = {0, 0}; + glm::vec2 m_mousePosition = {0, 0}; + CInputMapping m_mapping; + + public: + CInputDispatcher() {} + ~CInputDispatcher(); + + void dispatch(CScene* scene); + + void processEvent(const SDL_Event& event); + + glm::vec2 getMouseRelative() const { return m_mouseRelative; } + glm::vec2 getMousePosition() const { return m_mousePosition; } + float getSensitivity() const { return m_mapping.getMouseSensitivity(); } + + bool isActive(InputAction action) const { return m_activeActions.count(action); } + bool isJustPressed(InputAction action) const { return m_justPressed.count(action); } + bool isJustReleased(InputAction action)const { return m_justReleased.count(action); } + + + void loadActions(const std::string& path); + void loadBindings(const std::string& path); + + CInputMapping& getMapping() { return m_mapping; } + }; + +} + +#endif \ No newline at end of file diff --git a/src/Engine/Core/Systems/Input/CInputMapping.cpp b/src/Engine/Core/Systems/Input/CInputMapping.cpp new file mode 100644 index 0000000..438711c --- /dev/null +++ b/src/Engine/Core/Systems/Input/CInputMapping.cpp @@ -0,0 +1,49 @@ +#include "CInputMapping.hpp" + +namespace CosmicCore { + // ajoute un binding à une action + void CInputMapping::bind(InputAction action, CInputBinding binding) + { + m_bindings[action].push_back(binding); + } + + // remplace tous les bindings d'une action + void CInputMapping::rebind(InputAction action, CInputBinding binding) + { + m_bindings[action] = {binding}; + } + + // ajoute un binding supplémentaire + void CInputMapping::addBinding(InputAction action, CInputBinding binding) + { + m_bindings[action].push_back(binding); + } + + // supprime tous les bindings d'une action + void CInputMapping::clearBindings(InputAction action) + { + m_bindings[action].clear(); + } + + // retourne les bindings d'une action + const std::vector& CInputMapping::getBindings(InputAction action) + { + static std::vector empty; + auto it = m_bindings.find(action); + return it != m_bindings.end() ? it->second : empty; + } + + // trouve l'action correspondant à une touche + std::optional CInputMapping::findAction(SDL_Keycode key) + { + for (auto& [action, bindings] : m_bindings) + { + for (auto& binding : bindings) + { + if (binding.device == EInputDevice::Keyboard && binding.key == key) + return action; + } + } + return std::nullopt; + } +} \ No newline at end of file diff --git a/src/Engine/Core/Systems/Input/CInputMapping.hpp b/src/Engine/Core/Systems/Input/CInputMapping.hpp new file mode 100644 index 0000000..3968045 --- /dev/null +++ b/src/Engine/Core/Systems/Input/CInputMapping.hpp @@ -0,0 +1,45 @@ +#ifndef CINPUTMAPPING_HPP +#define CINPUTMAPPING_HPP + +#include "API/CInputAPI.hpp" +#include "CInputBinding.hpp" +#include +#include + +namespace CosmicCore { + class CInputMapping { + // une action peut avoir plusieurs bindings + std::unordered_map> m_bindings; + + float m_mouseSensitivity = 0.1f; + + public: + CInputMapping() {} + + // ajoute un binding à une action + void bind(InputAction action, CInputBinding binding); + + // remplace tous les bindings d'une action + void rebind(InputAction action, CInputBinding binding); + + // ajoute un binding supplémentaire + void addBinding(InputAction action, CInputBinding binding); + + // supprime tous les bindings d'une action + void clearBindings(InputAction action); + + // retourne les bindings d'une action + const std::vector& getBindings(InputAction action); + + // trouve l'action correspondant à une touche + std::optional findAction(SDL_Keycode key); + + float getMouseSensitivity() const { return m_mouseSensitivity; } + void setMouseSensitivity(float s){ m_mouseSensitivity = s; } + + void clearAll(){return m_bindings.clear();} + }; + +} + +#endif \ No newline at end of file diff --git a/src/Engine/Core/Systems/Physics/API/CPhysicsAPI.cpp b/src/Engine/Core/Systems/Physics/API/CPhysicsAPI.cpp index 0c3b6ee..cd73ce5 100644 --- a/src/Engine/Core/Systems/Physics/API/CPhysicsAPI.cpp +++ b/src/Engine/Core/Systems/Physics/API/CPhysicsAPI.cpp @@ -1,7 +1,26 @@ #include "CPhysicsAPI.hpp" + +#include "Jolt/Jolt.h" +#include +#include + namespace CosmicCore { CPhysicsAPI::~CPhysicsAPI() { } + void CPhysicsAPI::init() + { + JPH::RegisterDefaultAllocator(); + JPH::Factory::sInstance = new JPH::Factory(); + JPH::RegisterTypes(); + } + + void CPhysicsAPI::cleanup() + { + JPH::UnregisterTypes(); + // Destroy the factory + delete JPH::Factory::sInstance; + JPH::Factory::sInstance = nullptr; + } } \ No newline at end of file diff --git a/src/Engine/Core/Systems/Physics/API/CPhysicsAPI.hpp b/src/Engine/Core/Systems/Physics/API/CPhysicsAPI.hpp index 1450744..c62ba1f 100644 --- a/src/Engine/Core/Systems/Physics/API/CPhysicsAPI.hpp +++ b/src/Engine/Core/Systems/Physics/API/CPhysicsAPI.hpp @@ -1,5 +1,6 @@ #ifndef CPHYSICSAPI_HPP #define CPHYSICSAPI_HPP + namespace CosmicCore { class CScene; @@ -18,7 +19,8 @@ namespace CosmicCore { virtual void initWorld() = 0; virtual void destroy() = 0; - + static void init(); + static void cleanup(); CScene* getScene(){return m_scene;}; }; } diff --git a/src/Engine/Core/Systems/Physics/CTangibleWorld.hpp b/src/Engine/Core/Systems/Physics/CTangibleWorld.hpp index b2f8aee..8bc1a02 100644 --- a/src/Engine/Core/Systems/Physics/CTangibleWorld.hpp +++ b/src/Engine/Core/Systems/Physics/CTangibleWorld.hpp @@ -2,8 +2,6 @@ #define CTANGIBLEWORLD_HPP #include "API/CPhysicsAPI.hpp" #include "PhysicsLayers.hpp" -#include -#include #include #include #include diff --git a/src/Engine/Core/Systems/Scripts/API/CScriptAPI.cpp b/src/Engine/Core/Systems/Scripts/API/CScriptAPI.cpp index 9b50729..e50c0d0 100644 --- a/src/Engine/Core/Systems/Scripts/API/CScriptAPI.cpp +++ b/src/Engine/Core/Systems/Scripts/API/CScriptAPI.cpp @@ -6,7 +6,7 @@ namespace CosmicCore { void CScriptAPI::init() { - void* lib = dlopen("./libScriptModule.so", RTLD_NOW | RTLD_DEEPBIND); + void* lib = dlopen("./libScriptModule.so", RTLD_NOW | RTLD_GLOBAL); if (lib) { auto registerFunc = (void(*)(CScriptRegistry* reg))dlsym(lib, "registerAllScripts"); registerFunc(&CScriptAPI::scripts()); // Passer l'API à la lib diff --git a/src/Engine/Utils/Configurations/CBasicConfiguration.cpp b/src/Engine/Utils/Configurations/CBasicConfiguration.cpp new file mode 100644 index 0000000..fd580bf --- /dev/null +++ b/src/Engine/Utils/Configurations/CBasicConfiguration.cpp @@ -0,0 +1,75 @@ +#include "CBasicConfiguration.hpp" + +namespace CosmicUtils { + + bool CBasicConfiguration::load(const std::string& path) { + m_data = readFile(path); + if (m_data.empty()) { reset(); return false; } + + // window + if (m_data.contains("window")) { + auto& w = m_data["window"]; + window.width = w.value("width", 1280u); + window.height = w.value("height", 720u); + window.fullscreen = w.value("fullscreen", false); + window.vsync = w.value("vsync", true); + window.title = w.value("title", "CosmicEngine"); + } + + // graphics + if (m_data.contains("graphics")) { + auto& g = m_data["graphics"]; + graphics.validationLayers = g.value("validationLayers", false); + graphics.maxFramesInFlight = g.value("maxFramesInFlight", 2u); + graphics.msaa = g.value("msaa", false); + } + + // audio + if (m_data.contains("audio")) { + auto& a = m_data["audio"]; + audio.masterGain = a.value("masterGain", 1.0f); + audio.musicGain = a.value("musicGain", 1.0f); + audio.ambianceGain = a.value("ambianceGain", 1.0f); + audio.uiGain = a.value("uiGain", 1.0f); + } + + if (m_data.contains("input")) { + auto& i = m_data["input"]; + input.mouseSensitivity = i.value("mouseSensitivity", 0.1f); + input.invertMouseX = i.value("invertMouseX", false); + input.invertMouseY = i.value("invertMouseY", false); + input.bindingsPath = i.value("bindingsPath", "config/engine/bindings_default.json"); + input.actionsPath = i.value("actionsPath", "config/engine/bindings_default.json"); + } + return true; + } + + void CBasicConfiguration::save(const std::string& path) const { + nlohmann::json j; + j["window"]["width"] = window.width; + j["window"]["height"] = window.height; + j["window"]["fullscreen"] = window.fullscreen; + j["window"]["vsync"] = window.vsync; + j["window"]["title"] = window.title; + + j["graphics"]["validationLayers"] = graphics.validationLayers; + j["graphics"]["maxFramesInFlight"] = graphics.maxFramesInFlight; + j["graphics"]["msaa"] = graphics.msaa; + + j["audio"]["masterGain"] = audio.masterGain; + j["audio"]["musicGain"] = audio.musicGain; + j["audio"]["ambianceGain"] = audio.ambianceGain; + j["audio"]["uiGain"] = audio.uiGain; + + //TODO input + + writeFile(path, j); + } + + void CBasicConfiguration::reset() { + window = WindowSettings{}; + graphics = GraphicsSettings{}; + audio = AudioSettings{}; + input = InputSettings{}; + } +} \ No newline at end of file diff --git a/src/Engine/Utils/Configurations/CBasicConfiguration.hpp b/src/Engine/Utils/Configurations/CBasicConfiguration.hpp new file mode 100644 index 0000000..9d65d2e --- /dev/null +++ b/src/Engine/Utils/Configurations/CBasicConfiguration.hpp @@ -0,0 +1,75 @@ +#ifndef CABSTRACTCONFIGURATION_HPP +#define CABSTRACTCONFIGURATION_HPP + +#include "nlohmann/json.hpp" +#include +#include +namespace CosmicUtils { + + class CBasicConfiguration { + + public: + + struct WindowSettings { + uint32_t width = 1280; + uint32_t height = 720; + bool fullscreen = false; + bool vsync = true; + std::string title = "CosmicEngine"; + }; + + struct GraphicsSettings { + bool validationLayers = false; + uint32_t maxFramesInFlight = 2; + bool msaa = false; + }; + + struct AudioSettings { + float masterGain = 1.0f; + float musicGain = 1.0f; + float ambianceGain = 1.0f; + float uiGain = 1.0f; + }; + + struct InputSettings { + float mouseSensitivity = 0.1f; + bool invertMouseX = false; + bool invertMouseY = false; + std::string bindingsPath = "config/engine/bindings_default.json"; + std::string actionsPath = "config/engine/actions.json"; + }; + + WindowSettings window; + GraphicsSettings graphics; + AudioSettings audio; + InputSettings input; + + + + virtual bool load(const std::string& path); + virtual void save(const std::string& path) const; + virtual void reset(); + virtual ~CBasicConfiguration() = default; + + protected: + nlohmann::json m_data; + + nlohmann::json readFile(const std::string& path) { + std::ifstream file(path); + if (!file.good()) + return nlohmann::json{}; + return nlohmann::json::parse(file); + } + + void writeFile(const std::string& path, + const nlohmann::json& j) const { + std::filesystem::create_directories( + std::filesystem::path(path).parent_path() + ); + std::ofstream file(path); + file << j.dump(4); + } + }; +} + +#endif \ No newline at end of file diff --git a/src/Engine/Utils/Configurations/CEngineConfiguration.cpp b/src/Engine/Utils/Configurations/CEngineConfiguration.cpp new file mode 100644 index 0000000..429329c --- /dev/null +++ b/src/Engine/Utils/Configurations/CEngineConfiguration.cpp @@ -0,0 +1,5 @@ +#include "CEngineConfiguration.hpp" + +namespace CosmicUtils { + +} \ No newline at end of file diff --git a/src/Engine/Utils/Configurations/CEngineConfiguration.hpp b/src/Engine/Utils/Configurations/CEngineConfiguration.hpp new file mode 100644 index 0000000..b4e0d2f --- /dev/null +++ b/src/Engine/Utils/Configurations/CEngineConfiguration.hpp @@ -0,0 +1,12 @@ +#ifndef CENGINECONFIGURATION_HPP +#define CENGINECONFIGURATION_HPP +#include "CBasicConfiguration.hpp" +namespace CosmicUtils { + + class CEngineConfiguration : public CBasicConfiguration + { + public: + }; +} + +#endif \ No newline at end of file diff --git a/src/Modules/Scripts/CScriptRegister.cpp b/src/Modules/Scripts/CScriptRegister.cpp index 99c123d..ff8e3bc 100644 --- a/src/Modules/Scripts/CScriptRegister.cpp +++ b/src/Modules/Scripts/CScriptRegister.cpp @@ -1,5 +1,4 @@ #include "CScriptRegister.hpp" -#include "UserScripts/CExampleScript.hpp" #include std::vector& CScriptRegister::getRegistrars() { diff --git a/src/Modules/Scripts/UserScripts/CExampleScript.cpp b/src/Modules/Scripts/UserScripts/CExampleScript.cpp index 078a398..fef7fd3 100644 --- a/src/Modules/Scripts/UserScripts/CExampleScript.cpp +++ b/src/Modules/Scripts/UserScripts/CExampleScript.cpp @@ -3,15 +3,51 @@ #include "../CScriptRegister.hpp" #include +#include "Core/Component/Input/CInputManager.hpp" + +#include "Core/Component/Geometry/CTransform.hpp" + void CExampleScript::start() { std::cout << "Hello example script" << std::endl; } +void CExampleScript::onCreate() +{ + using namespace CosmicCore; + auto& reg = getEntity().getRegistry().registry; + + // vérifie que l'entité a un CInputComponent + if (!reg.all_of(getEntity().getHandle())) + reg.emplace(getEntity().getHandle(), getEntity()); + + auto& input = reg.get(getEntity().getHandle()); + + // bind les actions depuis le script + input.onHeld("MoveForward", [](CEntity& e) { + e.getRegistry().registry.get(e.getHandle()) + .forward({0, 0, -0.05f}); + }); + + input.onHeld("MoveBackward", [](CEntity& e) { + e.getRegistry().registry.get(e.getHandle()) + .forward({0, 0, 0.05f}); + }); + + input.onMouseMove([](CEntity& e, glm::vec2 delta) { + auto& tr = e.getRegistry().registry.get(e.getHandle()); + float sensitivity = 0.1f; + glm::quat yaw = glm::angleAxis( + glm::radians(-delta.x * sensitivity), glm::vec3(0,1,0)); + glm::quat pitch = glm::angleAxis( + glm::radians(-delta.y * sensitivity), glm::vec3(1,0,0)); + tr.setQuaternion(yaw * tr.getOrientation() * pitch); + }); +} + void CExampleScript::update() { - static int co = 0; - std::cout << ++co << std::endl; + } void CExampleScript::destroy() diff --git a/src/Modules/Scripts/UserScripts/CExampleScript.hpp b/src/Modules/Scripts/UserScripts/CExampleScript.hpp index 9a452c9..9fe4d6d 100644 --- a/src/Modules/Scripts/UserScripts/CExampleScript.hpp +++ b/src/Modules/Scripts/UserScripts/CExampleScript.hpp @@ -1,17 +1,16 @@ #ifndef CEXAMPLESCRIPT_HPP #define CEXAMPLESCRIPT_HPP #include "Core/Entity/CEntity.hpp" -#include "Core/Systems/Scripts/API/CScriptAPI.hpp" #include -#include class CExampleScript : public CosmicCore::CAbstractScript { public: CExampleScript(CosmicCore::CEntity& entity, std::string name): CosmicCore::CAbstractScript(entity, name){}; - virtual void start() override; - virtual void update() override; - virtual void destroy() override; + void start() override; + void update() override; + void destroy() override; + void onCreate() override; virtual nlohmann::json to_json() override; virtual ~CExampleScript(); };