diff --git a/Assets/Audio/Master.bank b/Assets/Audio/Master.bank new file mode 100644 index 00000000..a1b4e563 Binary files /dev/null and b/Assets/Audio/Master.bank differ diff --git a/Assets/Audio/Master.strings.bank b/Assets/Audio/Master.strings.bank new file mode 100644 index 00000000..ecad89fe Binary files /dev/null and b/Assets/Audio/Master.strings.bank differ diff --git a/Assets/Audio/footsteps.bank b/Assets/Audio/footsteps.bank new file mode 100644 index 00000000..ce53111e Binary files /dev/null and b/Assets/Audio/footsteps.bank differ diff --git a/Dependencies.bat b/Dependencies.bat index e16c4267..1d4a3473 100644 --- a/Dependencies.bat +++ b/Dependencies.bat @@ -19,10 +19,11 @@ echo "L - yamlcpp" echo "M - SDL" echo "N - dotnet" echo "O - tinyddsloader" +echo "P - fmod" echo --------------------------------------------------- echo. -choice /C ABCDEFGHIJKLMNO /T 10 /D A +choice /C ABCDEFGHIJKLMNOP /T 10 /D A set _e=%ERRORLEVEL% if %_e%==1 goto VMA @@ -40,6 +41,7 @@ if %_e%==12 goto yamlcpp if %_e%==13 goto SDL if %_e%==14 goto dotnet if %_e%==15 goto tinyddsloader +if %_e%==16 goto fmod :VMA echo -----------------------VMA---------------------------- @@ -145,6 +147,12 @@ if %_e%==14 (goto :done) else (goto :tinyddsloader) echo --------------------tinyddsloader------------------------- rmdir "Dependencies/tinyddsloader" /S /Q git clone https://github.com/SHADE-DP/tinyddsloader.git "Dependencies/tinyddsloader" +if %_e%==15 (goto :done) else (goto :fmod) + +:fmod +echo --------------------fmod------------------------- +rmdir "Dependencies/fmod" /S /Q +git clone https://github.com/SHADE-DP/FMOD.git "Dependencies/fmod" :done echo DONE! diff --git a/Dependencies.lua b/Dependencies.lua index 9ae406f0..6dd7a711 100644 --- a/Dependencies.lua +++ b/Dependencies.lua @@ -15,3 +15,4 @@ IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL" IncludeDir["VULKAN"] = "$(VULKAN_SDK)" IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet" IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader" +IncludeDir["fmod"] = "%{wks.location}\\Dependencies\\fmod" \ No newline at end of file diff --git a/SHADE_Application/premake5.lua b/SHADE_Application/premake5.lua index b34b06fa..2119808d 100644 --- a/SHADE_Application/premake5.lua +++ b/SHADE_Application/premake5.lua @@ -30,12 +30,13 @@ project "SHADE_Application" externalincludedirs { - "%{IncludeDir.spdlog}/include", - "%{IncludeDir.VULKAN}/include", - "%{IncludeDir.VMA}/include", - "%{IncludeDir.VULKAN}/Source/SPIRV-Reflect", - "%{IncludeDir.RTTR}/include", - "%{IncludeDir.tinyddsloader}" + "%{IncludeDir.spdlog}/include", + "%{IncludeDir.VULKAN}/include", + "%{IncludeDir.VMA}/include", + "%{IncludeDir.VULKAN}/Source/SPIRV-Reflect", + "%{IncludeDir.tinyddsloader}", + "%{IncludeDir.fmod}/include", + "%{IncludeDir.RTTR}\\include" } externalwarnings "Off" @@ -81,4 +82,4 @@ project "SHADE_Application" filter "configurations:Publish" optimize "On" - defines{"_RELEASE"} + defines{"_RELEASE", "_PUBLISH"} diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index c511ec23..64095e03 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -24,6 +24,8 @@ #include "Scene/SHSceneManager.h" #include "Math/Transform/SHTransformSystem.h" #include "Input/SHInputManagerSystem.h" +#include "FRC/SHFramerateController.h" +//#include "AudioSystem/SHAudioSystem.h" #include "Scenes/SBTestScene.h" #include "Math/Transform/SHTransformComponent.h" @@ -55,6 +57,7 @@ namespace Sandbox SHADE::SHSystemManager::CreateSystem(); SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); SHADE::SHSystemManager::CreateSystem(); + //SHADE::SHSystemManager::CreateSystem(); // Create Routines SHADE::SHSystemManager::RegisterRoutine(); @@ -84,6 +87,8 @@ namespace Sandbox SHADE::SHAssetManager::LoadDataTemp("../../Assets/TD_Checker_Base_Color.dds"); //TODO: REMOVE AFTER PRESENTATION + //SHADE::SHSystemManager::RegisterRoutine(); + // Set up graphics system and windows graphicsSystem->SetWindow(&window); @@ -96,6 +101,7 @@ namespace Sandbox #endif SHSceneManager::InitSceneManager("TestScene"); + SHFrameRateController::UpdateFRC(); } void SBApplication::Update(void) @@ -104,6 +110,7 @@ namespace Sandbox //TODO: Change true to window is open while (!window.WindowShouldClose()) { + SHFrameRateController::UpdateFRC(); SHSceneManager::UpdateSceneManager(); SHSceneManager::SceneUpdate(1/60.0f); //#ifdef SHEDITOR diff --git a/SHADE_Engine/premake5.lua b/SHADE_Engine/premake5.lua index 32a1e30c..f11ccf79 100644 --- a/SHADE_Engine/premake5.lua +++ b/SHADE_Engine/premake5.lua @@ -42,7 +42,8 @@ project "SHADE_Engine" "%{IncludeDir.VULKAN}\\include", "%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect", "%{IncludeDir.dotnet}\\include", - "%{IncludeDir.tinyddsloader}" + "%{IncludeDir.tinyddsloader}", + "%{IncludeDir.fmod}\\include" } externalwarnings "Off" @@ -55,7 +56,8 @@ project "SHADE_Engine" "%{IncludeDir.assimp}/lib/Release", "%{IncludeDir.RTTR}/lib", "%{IncludeDir.SDL}/lib", - "%{IncludeDir.spdlog}/lib" + "%{IncludeDir.spdlog}/lib", + "%{IncludeDir.fmod}/lib", } links @@ -104,14 +106,32 @@ project "SHADE_Engine" { "xcopy /s /r /y /q \"%{IncludeDir.spdlog}\\bin\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.SDL}\\lib\\SDL2.dll\" \"$(OutDir)\"", - "xcopy /s /r /y /q \"%{IncludeDir.dotnet}\\bin\" \"$(OutDir)\"" + "xcopy /s /r /y /q \"%{IncludeDir.dotnet}\\bin\" \"$(OutDir)\"" } filter "configurations:Debug" - postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\""} + postbuildcommands + { + "xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\"", + "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"", + "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\"" + } filter "configurations:Release" - postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""} + postbuildcommands + { + "xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"", + "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"", + "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\"" + } + + filter "configurations:Publish" + postbuildcommands + { + "xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"", + "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"", + "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\"" + } filter "configurations:Publish" postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""} @@ -122,17 +142,17 @@ project "SHADE_Engine" symbols "On" defines {"_DEBUG", "SHEDITOR"} links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"} - --links{"fmodstudioL_vc.lib", "fmodL_vc.lib"} + links{"fmodstudioL_vc.lib", "fmodL_vc.lib"} filter "configurations:Release" optimize "On" defines{"_RELEASE", "SHEDITOR"} links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"} - --links{"fmodstudio_vc.lib", "fmod_vc.lib"} + links{"fmodstudio_vc.lib", "fmod_vc.lib"} filter "configurations:Publish" optimize "On" - defines{"_RELEASE"} + defines{"_RELEASE", "_PUBLISH"} links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"} excludes { @@ -140,4 +160,4 @@ project "SHADE_Engine" "%{prj.location}/src/Editor/**.h", "%{prj.location}/src/Editor/**.hpp", } - --links{"fmodstudio_vc.lib", "fmod_vc.lib"} \ No newline at end of file + links{"fmodstudio_vc.lib", "fmod_vc.lib"} \ No newline at end of file diff --git a/SHADE_Engine/src/AudioSystem/SHAudioListenerComponent.cpp b/SHADE_Engine/src/AudioSystem/SHAudioListenerComponent.cpp new file mode 100644 index 00000000..988b2781 --- /dev/null +++ b/SHADE_Engine/src/AudioSystem/SHAudioListenerComponent.cpp @@ -0,0 +1,58 @@ +/********************************************************************* +* \file SHAudioListenerComponent.cpp +* \author Glence Low +* \brief Definition of the SHAudioListenerComponent class. +* +* \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction + or disclosure of this file or its contents without the prior written + consent of DigiPen Institute of Technology is prohibited. +*********************************************************************/ + +#include "SHpch.h" +#include "SHAudioListenerComponent.h" +#include "ECS_Base/Managers/SHSystemManager.h" + +namespace SHADE +{ + const SHVec3 SHAudioListenerComponent::GetPos() const + { + return pos; + } + + const SHVec3 SHAudioListenerComponent::GetVel() const + { + return vel; + } + + const SHVec3 SHAudioListenerComponent::GetForward() const + { + return forward; + } + + const SHVec3 SHAudioListenerComponent::GetUp() const + { + return up; + } + + void SHAudioListenerComponent::SetPos(const SHVec3 p) + { + pos = p; + } + + void SHAudioListenerComponent::SetVel(const SHVec3 v) + { + vel = v; + } + + void SHAudioListenerComponent::SetForward(const SHVec3 f) + { + forward = f; + } + + void SHAudioListenerComponent::SetUp(const SHVec3 u) + { + up = u; + } + +} + diff --git a/SHADE_Engine/src/AudioSystem/SHAudioListenerComponent.h b/SHADE_Engine/src/AudioSystem/SHAudioListenerComponent.h new file mode 100644 index 00000000..e0fa8104 --- /dev/null +++ b/SHADE_Engine/src/AudioSystem/SHAudioListenerComponent.h @@ -0,0 +1,41 @@ +#pragma once +/********************************************************************* + * \file SHAudioListenerComponent.h + * \author Glence Low + * \brief Declaration of the SHAudioListenerComponent class. + * + * \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction + or disclosure of this file or its contents without the prior written + consent of DigiPen Institute of Technology is prohibited. +*********************************************************************/ + +#pragma once +#include "ECS_Base/Components/SHComponent.h" +#include "Math/SHMath.h" + +namespace SHADE +{ + class SHAudioListenerComponent : public SHComponent + { + friend class SHAudioSystem; + public: + + SHAudioListenerComponent() = default; + ~SHAudioListenerComponent() = default; + + const SHVec3 GetPos() const; + void SetPos(const SHVec3 p); + + const SHVec3 GetVel() const; + const SHVec3 GetForward() const; + const SHVec3 GetUp() const; + + void SetVel(const SHVec3 v); + void SetForward(const SHVec3 f); + void SetUp(const SHVec3 u); + + private: + SHVec3 pos{}, vel{}, forward{}, up{ 0.f,1.f,0.f }; + }; +}//namespace SHADE + diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSourceComponent.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSourceComponent.cpp new file mode 100644 index 00000000..2d623ede --- /dev/null +++ b/SHADE_Engine/src/AudioSystem/SHAudioSourceComponent.cpp @@ -0,0 +1,53 @@ +/********************************************************************* +* \file SHAudioSourceComponet.cpp +* \author Glence Low +* \brief Definition of the SHAudioSourceComponet class. +* +* \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction + or disclosure of this file or its contents without the prior written + consent of DigiPen Institute of Technology is prohibited. +*********************************************************************/ + +#include "SHpch.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "AudioSystem/SHAudioSystem.h" +#include "SHAudioSourceComponent.h" + +namespace SHADE +{ + /** + * @brief play the sound + * + * @param index where the sound is in the index + */ + void SHAudioSourceComponent::PlaySoundSFX(EntityID id, bool loop, bool spatial, float min , float max ) + { + SHSystemManager::GetSystem()->PlaySFX(id, GetEID(),loop,spatial, min, max); + } + + void SHAudioSourceComponent::PlaySoundBGM(EntityID id, bool loop, bool spatial, float min, float max) + { + SHSystemManager::GetSystem()->PlayBGM(id, GetEID(), loop, spatial, min, max); + } + + /** + * @brief Stop the sound + * + * @param index where the sound is in the index + */ + void SHAudioSourceComponent::StopSound(EntityID id) + { + SHSystemManager::GetSystem()->StopSound(id); + } + + /** + * @brief Mute the sound + * + * @param index where the sound is in the index + */ + void SHAudioSourceComponent::SetMute(EntityID id, bool mute) + { + SHSystemManager::GetSystem()->SetMute(id, mute); + } +} + diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSourceComponent.h b/SHADE_Engine/src/AudioSystem/SHAudioSourceComponent.h new file mode 100644 index 00000000..987dc3d4 --- /dev/null +++ b/SHADE_Engine/src/AudioSystem/SHAudioSourceComponent.h @@ -0,0 +1,60 @@ +/********************************************************************* + * \file SHAudioSourceComponet.h + * \author Glence Low + * \brief Declaration of the SHAudioSourceComponet class. + * + * \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction + or disclosure of this file or its contents without the prior written + consent of DigiPen Institute of Technology is prohibited. +*********************************************************************/ + +#pragma once +#include "ECS_Base/Components/SHComponent.h" +#include "ECS_Base/SHECSMacros.h" + +namespace SHADE +{ + class SHAudioSourceComponent : public SHComponent + { + public: + /** + * @brief default constructor for the component + * + */ + SHAudioSourceComponent() = default; + + + /** + * @brief default destructor for the component + * + */ + ~SHAudioSourceComponent() = default; + + /** + * @brief play the sound + * + * @param index where the sound is in the index + */ + void PlaySoundSFX(EntityID id, bool loop = false, bool spatial = false, float min = 5.0f, float max = 1000.f); + + void PlaySoundBGM(EntityID id, bool loop = false, bool spatial = false, float min = 5.0f, float max = 1000.f); + + /** + * @brief Stop the sound + * + * @param index where the sound is in the index + */ + void StopSound(EntityID id); + + /** + * @brief Mute the sound + * + * @param index where the sound is in the index + */ + void SetMute(EntityID id, bool mute); + + private: + + }; +}//namespace SHADE + diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp new file mode 100644 index 00000000..be9ee832 --- /dev/null +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp @@ -0,0 +1,557 @@ +#include "SHpch.h" +#include "SHAudioSystem.h" +#include "Scene/SHSceneManager.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "ECS_Base/Managers/SHEntityManager.h" + +#include + +#include "AudioSystem/SHAudioListenerComponent.h" +#include "AudioSystem/SHAudioSourceComponent.h" +#include "Math/Transform/SHTransformComponent.h" +#pragma warning(push) +#pragma warning(disable:26812) //disable warning about preference of enum class over enum as ImGuizmo uses enums +#include +#include +#include +#include + +namespace SHADE +{ + SHAudioSystem::SHAudioSystem() + : fmodStudioSystem(nullptr) + , extraDriverData(nullptr) + , soundList() + , bgmChannelGroup(nullptr) + , sfxChannelGroup(nullptr) + , masterGroup(nullptr) + , audioChannels() + , result(FMOD_RESULT_FORCEINT) + , bgmVolume(1.F) + , sfxVolume(1.F) + , masterVolume(1.0F) + , version(0) + , speakerMode(FMOD_SPEAKERMODE_5POINT1) + , paused(false) + { + result = FMOD::Studio::System::create(&fmodStudioSystem); + ErrorCheck(); + } + + SHAudioSystem::~SHAudioSystem() + { + } + + void SHADE::SHAudioSystem::Init() + { + + SHADE::SHComponentManager::CreateComponentSparseSet(); + SHADE::SHComponentManager::CreateComponentSparseSet(); + + denseListener = &SHComponentManager::GetDense(); + fmodStudioSystem->getCoreSystem(&fmodSystem); + + result = fmodStudioSystem->initialize(AUDIO_SYS_MAX_CHANNELS, AUDIO_SYS_MAX_CHANNELS, FMOD_STUDIO_INIT_NORMAL, extraDriverData); + ErrorCheck(); + + fmodSystem->setSoftwareFormat(0, speakerMode, 0); + + result = fmodSystem->createChannelGroup("SFX", &sfxChannelGroup); + ErrorCheck(); + + result = fmodSystem->createChannelGroup("BGM", &bgmChannelGroup); + ErrorCheck(); + + result = fmodSystem->getMasterChannelGroup(&masterGroup); + ErrorCheck(); + + result = masterGroup->addGroup(bgmChannelGroup); + ErrorCheck(); + + result = masterGroup->addGroup(sfxChannelGroup); + ErrorCheck(); + + bgmChannelGroup->setVolume(bgmVolume); + sfxChannelGroup->setVolume(sfxVolume); + masterGroup->setVolume(masterVolume); + + //SHResourceManager::LoadAllAudio(system, soundList); + + + LoadBank("../../Assets/Audio/Master.bank"); + LoadBank("../../Assets/Audio/Master.strings.bank"); + //LoadBank("../../Assets/Audio/Music.bank"); + LoadBank("../../Assets/Audio/footsteps.bank"); + + //auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human"); + //clip->Play(); + //PlayEventOnce("event:/Characters/sfx_footsteps_raccoon"); + //PlayEventOnce("event:/SFX/Dawn/Dawn_Attack"); + } + + void SHADE::SHAudioSystem::Run(float dt) + { + static_cast(dt); + if (GetKeyState(VK_SPACE) & 0x8000) + PlayEventOnce("event:/Characters/sfx_footsteps_raccoon"); + + fmodStudioSystem->update(); + if (!denseListener->empty()) + { + SHAudioListenerComponent& listener = denseListener->at(0); + SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s(listener.GetEID()); + if (listenerTransform) + { + listener.SetPos(listenerTransform->GetLocalPosition()); + listener.SetForward({ (listenerTransform->GetLocalScale()[0] > 0.f) ? 1.f : -1.f, 0.f, 0.f }); + FMOD_VECTOR pos = { listener.pos[0] ,listener.pos[1] ,0.f }; + FMOD_VECTOR forward = { listener.forward[0] ,listener.forward[1] ,listener.forward[2] }; + FMOD_VECTOR up = { listener.up[0] ,listener.up[1] ,listener.up[2] }; + fmodSystem->set3DListenerAttributes(0, &pos, nullptr, &forward, &up); + } + } + } + + SHAudioSystem::AudioRoutine::AudioRoutine() + : SHSystemRoutine("Audio Routine", false) {} + + void SHAudioSystem::AudioRoutine::Execute(double dt) noexcept + { + reinterpret_cast(system)->Run(dt); + } + + void SHADE::SHAudioSystem::Exit() + { + for (auto& event : eventMap) + { + result = event.second->releaseAllInstances(); + ErrorCheck(); + } + + for (auto& bank : bankMap) + { + result = bank.second->unload(); + ErrorCheck(); + } + + for (auto& sound : soundList) + { + result = sound.second->release(); + ErrorCheck(); + } + + if (bgmChannelGroup) + { + result = bgmChannelGroup->release(); + ErrorCheck(); + } + + if (sfxChannelGroup) + { + result = sfxChannelGroup->release(); + ErrorCheck(); + } + + if (fmodStudioSystem) + { + result = fmodStudioSystem->release(); + ErrorCheck(); + } + } + + void SHAudioSystem::ErrorCheck() const + { + if (result != FMOD_OK) + std::cerr << "Audio system error: " << FMOD_ErrorString(result) << std::endl; + } + + void SHAudioSystem::PlayEventOnce(const char* path, bool isSFX, EntityID eid, bool spatial) + { + if (paused) + return; + auto it = eventMap.find(path); + if (it != eventMap.end()) + { + FMOD::Studio::EventInstance* event = nullptr; + it->second->createInstance(&event); + if (event) + { + + event->setVolume(masterVolume * (isSFX ? sfxVolume : bgmVolume)); + if (spatial) + { + if (SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s(eid)) + { + FMOD_3D_ATTRIBUTES attributes{ {} }; + attributes.forward.z = 1.0f; + attributes.up.y = 1.0f; + SHAudioListenerComponent& listener = denseListener->at(0); + SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s(listener.GetEID()); + if (listenerTransform) + { + attributes.position.z = listenerTransform->GetLocalPosition()[2]; + } + attributes.position.x = audioTransform->GetLocalPosition()[0]; + attributes.position.y = audioTransform->GetLocalPosition()[1]; + event->set3DAttributes(&attributes); + } + } + event->start(); + event->release(); + } + } + } + + void SHAudioSystem::PlaySFX(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min, float max) + { + SHSound sound = soundList[id]; + int index = GetAvailableChannelIndex(); + if (index >= 0) + { + unsigned int mode{}; + mode |= (loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); + mode |= (spatial ? FMOD_3D : FMOD_2D); + sound->setMode(mode); + result = fmodSystem->playSound(sound, sfxChannelGroup, false, &audioChannels[index]); + if (spatial && SHComponentManager::HasComponent(eid)) + { + SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s(eid); + FMOD_VECTOR fpos{ audioTransform->GetLocalPosition()[0],audioTransform->GetLocalPosition()[1] ,0.f}; + audioChannels[index]->set3DAttributes(&fpos, nullptr); + audioChannels[index]->setMode(mode); + audioChannels[index]->set3DMinMaxDistance(min, max); + } + ErrorCheck(); + } + } + + void SHAudioSystem::PlayBGM(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min, float max) + { + SHSound sound = soundList[id]; + int index = GetAvailableChannelIndex(); + if (index >= 0) + { + unsigned int mode{}; + mode |= (loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); + mode |= (spatial ? FMOD_3D : FMOD_2D); + sound->setMode(mode); + result = fmodSystem->playSound(sound, bgmChannelGroup, false, &audioChannels[index]); + if (spatial && SHComponentManager::HasComponent(eid)) + { + SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s(eid); + FMOD_VECTOR fpos{ audioTransform->GetLocalPosition()[0],audioTransform->GetLocalPosition()[1] ,0.f }; + audioChannels[index]->set3DAttributes(&fpos, nullptr); + audioChannels[index]->setMode(mode); + audioChannels[index]->set3DMinMaxDistance(min, max); + } + ErrorCheck(); + } + } + + void SHAudioSystem::SetMute(EntityID id, bool mute) + { + SHSound sound; + for (auto& channel : audioChannels) + { + channel->getCurrentSound(&sound); + if (soundList.find(id)->second == sound) // tbc + { + channel->setMute(mute); + } + } + } + + void SHAudioSystem::StopSound(EntityID id) + { + SHSound sound; + for (auto& channel : audioChannels) + { + channel->getCurrentSound(&sound); + if (soundList.find(id)->second == sound) // tbc + { + channel->stop(); + } + } + } + + void SHAudioSystem::StopAllSounds() + { + for (auto& channel : audioChannels) + { + bool isPlaying{ false }; + if (channel->isPlaying(&isPlaying) == FMOD_OK && isPlaying) + channel->stop(); + } + } + + std::optional SHAudioSystem::GetEventGUID(const char* path) + { + FMOD_GUID guid; + FMOD::Studio::EventDescription* event; + result = fmodStudioSystem->getEvent(path, &event); + ErrorCheck(); + if (result == FMOD_OK) + { + result = event->getID(&guid); + ErrorCheck(); + if (result == FMOD_OK) + { + return guid; + } + } + return std::nullopt; + } + + AudioClip* SHAudioSystem::CreateAudioClip(const char* path) + { + AudioClipID newID{}; + AudioClip* clip = nullptr; + auto it = eventMap.find(path); + if (it != eventMap.end()) + { + FMOD::Studio::EventInstance* event = nullptr; + it->second->createInstance(&event); + if (event) + { + //event->start(); + newID = clipID; + clipID++; + eventInstances.emplace(newID, AudioClip(newID, event)); + clip = &eventInstances[newID]; + } + } + return clip; + } + + //std::vector SHAudioSystem::GetAllEvents() + //{ + // int count{}; + // stringsBank->getEventCount(&count); + + // std::vector events(count); + // auto eventData = events.data(); + // int finalCount{}; + // stringsBank->getEventList(eventData, count, &finalCount); + // std::vector eventNames; + // std::transform(events.begin(), events.end(), std::back_inserter(eventNames), [](FMOD::Studio::EventDescription* event) + // { + // char path[256]; + // event->getPath(path, 256, nullptr); + // return path; + // }); + // return eventNames; + //} + + //void SHAudioSystem::PlayEventInstance(FMOD::Studio::EventInstance* instance, bool isSFX, EntityID eid, bool spatial) + //{ + // instance->setVolume(masterVolume * (isSFX ? sfxVolume : bgmVolume)); + // FMOD::ChannelGroup* channelGroup; + // if (spatial) + // { + // if (SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s(eid)) + // { + // FMOD_3D_ATTRIBUTES attributes{ {} }; + // attributes.forward.z = 1.0f; + // attributes.up.y = 1.0f; + // SHAudioListenerComponent& listener = denseListener->at(0); + // SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s(listener.GetEID()); + // if (listenerTransform) + // { + // attributes.position.z = listenerTransform->GetTranslation()[2]; + // } + // attributes.position.x = audioTransform->GetTranslation()[0]; + // attributes.position.y = audioTransform->GetTranslation()[1]; + // instance->set3DAttributes(&attributes); + // } + // } + // instance->start(); + //} + + int SHAudioSystem::GetAvailableChannelIndex() + { + bool isPlaying = false; + for (int i = 0; i < AUDIO_SYS_MAX_CHANNELS; ++i) + { + audioChannels[i]->isPlaying(&isPlaying); + if (!isPlaying) + return i; + } + return -1; + } + + float SHAudioSystem::GetBgmVolume() + { + return bgmVolume; + } + float SHAudioSystem::GetSfxVolume() + { + return sfxVolume; + } + float SHAudioSystem::GetMasterVolume() + { + return masterVolume; + } + void SHAudioSystem::SetBgmVolume(float const bgmvol) + { + bgmChannelGroup->setVolume(bgmvol); + } + void SHAudioSystem::SetSfxVolume(float const sfxvol) + { + sfxChannelGroup->setVolume(sfxvol); + } + void SHAudioSystem::SetMasterVolume(float const mastervol) + { + masterGroup->setVolume(mastervol); + } + + void SHAudioSystem::SetPaused(bool pause) + { + paused = pause; + for (auto const& channel : audioChannels) + { + channel->setPaused(paused); + } + for (auto const& event : eventMap) + { + int instanceCount = 0; + event.second->getInstanceCount(&instanceCount); + std::vector instances(instanceCount); + event.second->getInstanceList(instances.data(), instances.size(), &instanceCount); + for (auto const& instance : instances) + { + instance->setPaused(pause); + } + } + } + + bool SHAudioSystem::GetPaused() const + { + return paused; + } + + SHVec3 SHAudioSystem::GetListenerPosition() + { + auto &listener = denseListener->at(0); + SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s(listener.GetEID()); + if (listenerTransform) + { + return listenerTransform->GetLocalPosition(); + } + return {}; + } + + void SHAudioSystem::LoadBank(const char* path) + { + FMOD::Studio::Bank* bank = nullptr; + result = fmodStudioSystem->loadBankFile(path, FMOD_STUDIO_LOAD_BANK_NORMAL, &bank); + ErrorCheck(); + if (result != FMOD_OK) + return; + bankMap.emplace(path, bank); + bank->loadSampleData(); + int numOfEvents; + bank->getEventCount(&numOfEvents); + if (numOfEvents > 0) + { + std::vector events(numOfEvents); + bank->getEventList(events.data(), numOfEvents, &numOfEvents); + char eventName[512]; + for (int i{}; i < numOfEvents; ++i) + { + FMOD::Studio::EventDescription* event = events[i]; + event->getPath(eventName, 512, nullptr); + eventMap.emplace(eventName, event); + } + } + } + + AudioClip::AudioClip(AudioClipID clipID, FMOD::Studio::EventInstance* inst) + :instance(inst), id(clipID) + { + } + + AudioClip::~AudioClip() + { + } + + void AudioClip::Play(bool isSfx) + { + if (!instance) + return; + instance->start(); + auto audioSystem = SHSystemManager::GetSystem(); + instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume())); + } + + void AudioClip::Play(SHVec3 position, bool isSfx) + { + if (!instance) + return; + instance->start(); + FMOD_3D_ATTRIBUTES attributes{ {} }; + attributes.forward.z = 1.0f; + attributes.up.y = 1.0f; + + auto audioSystem = SHSystemManager::GetSystem(); + SHVec3 listenerPos = audioSystem->GetListenerPosition(); + attributes.position.x = position[0]; + attributes.position.y = position[1]; + attributes.position.z = listenerPos[2]; + instance->set3DAttributes(&attributes); + instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume())); + } + + void AudioClip::Stop(bool fadeOut) + { + if (!instance) + return; + instance->stop(fadeOut ? FMOD_STUDIO_STOP_ALLOWFADEOUT : FMOD_STUDIO_STOP_IMMEDIATE); + } + + void AudioClip::SetPause(bool pause) + { + if (!instance) + return; + instance->setPaused(pause); + } + + bool AudioClip::IsPaused() + { + if (!instance) + return true; + + bool paused{}; + instance->getPaused(&paused); + return paused; + } + + + void AudioClip::SetParameter(const char* paramName, float value) + { + if (!instance) + return; + instance->setParameterByName(paramName, value); + } + + void AudioClip::SetParameterLabel(const char* paramName, const char* label) + { + if (!instance) + return; + instance->setParameterByNameWithLabel(paramName, label); + } + + float AudioClip::GetParameterValue(const char* paramName) + { + if (!instance) + return {}; + float value{}; + instance->getParameterByName(paramName, &value); + return value; + } + +} + +#pragma warning(pop) + + diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h new file mode 100644 index 00000000..04fad1f0 --- /dev/null +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h @@ -0,0 +1,110 @@ +#pragma once +#include +#include +#include +#include +#include +#include "ECS_Base/System/SHSystem.h" +#include "ECS_Base/System/SHSystemRoutine.h" +#include "ECS_Base/SHECSMacros.h" +#include "Math/SHMath.h" +#include +#include +#include "SH_API.h" +#define AUDIO_SYS_MAX_CHANNELS 1024 + +namespace SHADE +{ + typedef FMOD::Sound* SHSound; + typedef FMOD::Studio::Bank* SHBank; + + class SHAudioListenerComponent; + + typedef uint64_t AudioClipID; + + class AudioClip + { + public: + AudioClip() = default; + AudioClip(AudioClipID clipID, FMOD::Studio::EventInstance* inst); + ~AudioClip(); + void Play(bool isSfx = true); + void Play(SHVec3 position, bool isSfx = true); + void Stop(bool fadeOut = true); + + void SetPause(bool pause); + bool IsPaused(); + void SetParameter(const char* paramName, float value); + void SetParameterLabel(const char* paramName, const char* label); + float GetParameterValue(const char* paramName); + friend class SHAudioSystem; + private: + FMOD::Studio::EventInstance* instance; + AudioClipID id; + }; + + class SH_API SHAudioSystem : public SHSystem + { + public: + SHAudioSystem(); + ~SHAudioSystem(); + + void Init(); + void Run(float dt); + class SH_API AudioRoutine final : public SHSystemRoutine + { + public: + AudioRoutine(); + void Execute(double dt) noexcept override final; + }; + void Exit(); + + int GetAvailableChannelIndex(); + /*std::vector::size_type CreateSound(const char* filepath, bool loop = false);*/ + void PlaySFX(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f); + void PlayBGM(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f); + void PlayEventOnce(const char* path, bool isSFX = true, EntityID eid = MAX_EID, bool spatial = false); + void SetMute(EntityID id, bool); + void StopSound(EntityID id); + void StopAllSounds(); + + std::optional GetEventGUID(const char* path); + AudioClip* CreateAudioClip(const char* path); + //std::vector GetAllEvents(); + + float GetBgmVolume(); + float GetSfxVolume(); + float GetMasterVolume(); + void SetBgmVolume(float const bgmvol); + void SetSfxVolume(float const sfxvol); + void SetMasterVolume(float const mastervol); + void SetPaused(bool pause); + bool GetPaused() const; + SHVec3 GetListenerPosition(); + void LoadBank(const char* path); + private: + FMOD::Studio::System* fmodStudioSystem; + FMOD::System* fmodSystem; + bool paused; + void ErrorCheck() const; + + void* extraDriverData; + std::unordered_map soundList; + //std::unordered_map bankMap; + std::unordered_map bankMap; + std::unordered_map eventMap; + std::unordered_map eventInstances; + FMOD::ChannelGroup* bgmChannelGroup, * sfxChannelGroup, * masterGroup; + FMOD::Channel* audioChannels[AUDIO_SYS_MAX_CHANNELS]; + FMOD_RESULT result; + float bgmVolume, sfxVolume, masterVolume; + unsigned int version; + FMOD_SPEAKERMODE speakerMode; + SHBank masterBank, stringsBank, musicBank, sfxBank; //To do: change to map of banks loaded by resource manager + + std::vector* denseListener; + AudioClipID clipID = 0; + }; + +} + diff --git a/SHADE_Engine/src/ECS_Base/UnitTesting/SHTestComponents.h b/SHADE_Engine/src/ECS_Base/UnitTesting/SHTestComponents.h index e2e53d6b..b95a0233 100644 --- a/SHADE_Engine/src/ECS_Base/UnitTesting/SHTestComponents.h +++ b/SHADE_Engine/src/ECS_Base/UnitTesting/SHTestComponents.h @@ -1,6 +1,7 @@ #pragma once #include "../Components/SHComponent.h" +#include namespace SHADE { @@ -27,4 +28,50 @@ namespace SHADE std::string value{}; }; + class SHComponent_ENUM : public SHComponent + { + public: + enum class Option + { + OPT_A, + OPT_B, + OPT_C + }; + + bool boolTest{}; + int intTest{}; + float floatTest{}; + double doubleTest{}; + long longTest{}; + uint8_t uint8Test{}; + uint16_t uint16Test{}; + uint32_t uint32Test{}; + uint64_t uint64Test{}; + + + Option option; + RTTR_ENABLE() + }; + + RTTR_REGISTRATION + { + using namespace rttr; + registration::enumeration("Option") + ( + value("Option A", SHComponent_ENUM::Option::OPT_A), + value("Option B", SHComponent_ENUM::Option::OPT_B), + value("Option C", SHComponent_ENUM::Option::OPT_C) + ); + rttr::registration::class_("Enum Component") + .property("Option", &SHComponent_ENUM::option) + .property("boolTest", &SHComponent_ENUM::boolTest) + .property("intTest", &SHComponent_ENUM::intTest)( metadata("MIN", 0.0f), metadata("MAX", 1.f)) + .property("floatTest", &SHComponent_ENUM::floatTest)(metadata("MIN", 0.0f), metadata("MAX", 1.f)) + .property("doubleTest", &SHComponent_ENUM::doubleTest)(metadata("MIN", 0.0f), metadata("MAX", 1.f)) + .property("uint8Test", &SHComponent_ENUM::uint8Test)(metadata("MIN", 0.0f), metadata("MAX", 1.f)) + .property("uint16Test", &SHComponent_ENUM::uint16Test)(metadata("MIN", 0.0f), metadata("MAX", 1.f)) + .property("uint32Test", &SHComponent_ENUM::uint32Test)(metadata("MIN", 0.0f), metadata("MAX", 1.f)) + .property("uint64Test", &SHComponent_ENUM::uint64Test)(metadata("MIN", 0.0f), metadata("MAX", 1.f)); + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 080cbf2c..2d326d09 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -12,6 +12,7 @@ #include "Editor/IconsMaterialDesign.h" #include "ECS_Base/Components/SHComponent.h" #include "Editor/SHEditorWidgets.hpp" +#include "Reflection/SHReflectionMetadata.h" namespace SHADE { template::value, bool> = true> @@ -55,7 +56,124 @@ namespace SHADE { auto const& type = property.get_type(); - if (type == rttr::type::get()) + if(type.is_enumeration()) + { + auto enumAlign = type.get_enumeration(); + auto names = enumAlign.get_names(); + std::vector list; + for(auto const& name : names) + list.push_back(name.data()); + ComboBox(property.get_name().data(), list, [component, property]{return property.get_value(component).to_int();}, [component, property](int const& idx) + { + auto enumAlign = property.get_enumeration(); + auto values = enumAlign.get_values(); + auto it = std::next(values.begin(), idx); + property.set_value(component, *it); + }); + } + else if(type.is_arithmetic()) + { + if (type == rttr::type::get()) + { + CheckBox(property.get_name().data(), [component, property]{return property.get_value(component).to_bool();}, [component, property](bool const& result){property.set_value(component, result);}); + } + //else if (type == rttr::type::get()) + //{ + // + //} + else if (type == rttr::type::get() || type == rttr::type::get() || type == rttr::type::get() || type == rttr::type::get()) + { + auto metaMin = property.get_metadata(META::min); + auto metaMax = property.get_metadata(META::max); + if(metaMin && metaMax) + { + SliderInt(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);}); + } + else + { + DragInt(property.get_name().data(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);}); + } + } + else if (type == rttr::type::get()) + { + auto metaMin = property.get_metadata(META::min); + auto metaMax = property.get_metadata(META::max); + if(metaMin.is_valid() && metaMax.is_valid()) + { + SliderScalar(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value(), metaMax.template get_value(), [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},"%zu"); + } + else + { + DragScalar(property.get_name().data(), ImGuiDataType_U8, [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu"); + } + } + else if (type == rttr::type::get()) + { + auto metaMin = property.get_metadata(META::min); + auto metaMax = property.get_metadata(META::max); + if(metaMin.is_valid() && metaMax.is_valid()) + { + SliderScalar(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},"%zu"); + } + else + { + DragScalar(property.get_name().data(), ImGuiDataType_U16, [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu"); + } + } + else if (type == rttr::type::get()) + { + auto metaMin = property.get_metadata(META::min); + auto metaMax = property.get_metadata(META::max); + if (metaMin.is_valid() && metaMax.is_valid()) + { + SliderScalar(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value(), metaMin.template get_value(), [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },"%zu"); + } + else + { + DragScalar(property.get_name().data(), ImGuiDataType_U32, [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },0.1f,0,0,"%zu"); + } + } + else if (type == rttr::type::get()) + { + auto metaMin = property.get_metadata(META::min); + auto metaMax = property.get_metadata(META::max); + if(metaMin.is_valid() && metaMax.is_valid()) + { + SliderScalar(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},"%zu"); + } + else + { + DragScalar(property.get_name().data(), ImGuiDataType_U64, [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu"); + } + } + else if (type == rttr::type::get()) + { + auto metaMin = property.get_metadata(META::min); + auto metaMax = property.get_metadata(META::max); + if(metaMin.is_valid() && metaMax.is_valid()) + { + SliderFloat(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);}); + } + else + { + DragFloat(property.get_name().data(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);}); + } + } + else if (type == rttr::type::get()) + { + auto metaMin = property.get_metadata(META::min); + auto metaMax = property.get_metadata(META::max); + if(metaMin.is_valid() && metaMax.is_valid()) + { + SliderScalar(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);}); + } + else + { + DragScalar(property.get_name().data(), ImGuiDataType_Double, [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);}, 0.1f); + } + } + } + else if (type == rttr::type::get()) { DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); }); } @@ -63,6 +181,11 @@ namespace SHADE { DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); }); } + else if (type == rttr::type::get()) + { + DragVec2(property.get_name().data(), { "X", "Y"}, [component, property]() {return property.get_value(component).template convert(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); }); + } + } } else DrawContextMenu(component); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index fba9512e..7ba0c609 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -11,8 +11,12 @@ #include "Editor/SHImGuiHelpers.hpp" #include "Editor/SHEditorWidgets.hpp" #include "SHEditorComponentView.hpp" +#include "ECS_Base/UnitTesting/SHTestComponents.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "AudioSystem/SHAudioSystem.h" + namespace SHADE { template, bool> = true> @@ -54,11 +58,20 @@ namespace SHADE { DrawComponent(transformComponent); } + if(auto renderableComponent = SHComponentManager::GetComponent_s(eid)) + { + DrawComponent(renderableComponent); + } + if(auto testComponent = SHComponentManager::GetComponent_s(eid)) + { + DrawComponent(testComponent); + } ImGui::Separator(); if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data())) { DrawAddComponentButton(eid); DrawAddComponentButton(eid); + DrawAddComponentButton(eid); ImGui::EndMenu(); } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp new file mode 100644 index 00000000..4b36fe5d --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp @@ -0,0 +1,48 @@ +#include "SHpch.h" +#include "SHEditorProfiler.h" +#include + +#include "ECS_Base/Managers/SHSystemManager.h" +#include "FRC/SHFramerateController.h" + +namespace SHADE +{ + SHEditorProfiler::SHEditorProfiler() + :SHEditorWindow("Profiler", ImGuiWindowFlags_None) + { + } + + void SHEditorProfiler::Init() + { + SHEditorWindow::Init(); + } + + void SHEditorProfiler::Update() + { + SHEditorWindow::Update(); + + const float dt = static_cast(SHFrameRateController::GetRawDeltaTime()); + if(frames.size() > MaxFramesDisplayed) + { + for (size_t i = 1; i < frames.size(); i++) + { + frames[i-1] = frames[i]; + } + frames[frames.size() - 1] = dt; + } + else + { + frames.push_back(dt); + } + if(Begin()) + { + ImGui::PlotLines("DT", frames.data(), static_cast(frames.size()), 0, nullptr, 0.0f, 16.0f); + ImGui::End(); + } + } + + void SHEditorProfiler::Exit() + { + SHEditorWindow::Exit(); + } +} diff --git a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.h b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.h new file mode 100644 index 00000000..3f817a53 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Editor/EditorWindow/SHEditorWindow.h" +#include +constexpr uint32_t MaxFramesDisplayed = 100; +namespace SHADE +{ + class SHEditorProfiler final : public SHEditorWindow + { + public: + SHEditorProfiler(); + void Init() override; + void Update() override; + void Exit() override; + + private: + std::vector frames; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h index 2ed34109..d1ebfbf4 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h @@ -1,4 +1,5 @@ #pragma once #include "MenuBar/SHEditorMenuBar.h" //Menu Bar #include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel -#include "Inspector/SHEditorInspector.h" //Inspector \ No newline at end of file +#include "Inspector/SHEditorInspector.h" //Inspector +#include "Profiling/SHEditorProfiler.h" //Profiler \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 17f7d720..b36518fd 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -95,6 +95,7 @@ namespace SHADE CreateEditorWindow(); CreateEditorWindow(); CreateEditorWindow(); + CreateEditorWindow(); SHLOG_INFO("Successfully initialised SHADE Engine Editor") } @@ -106,7 +107,8 @@ namespace SHADE for (const auto& window : editorWindows | std::views::values) { - window->Update(); + if(window->isOpen) + window->Update(); } if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z)) @@ -292,7 +294,9 @@ namespace SHADE imguiCommandBuffer->EndRecording(); gfxSystem->GetQueue()->SubmitCommandBuffer({ imguiCommandBuffer }, {}, {}, vk::PipelineStageFlagBits::eNone, {}); - //ImGui_ImplVulkan_DestroyFontUploadObjects(); + gfxSystem->GetDevice()->WaitIdle(); + + ImGui_ImplVulkan_DestroyFontUploadObjects(); renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle& cmd) { ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer()); diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 4a934e8c..6dcf5dfd 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -80,13 +80,13 @@ namespace SHADE return valueChanged; } - static bool DragVec2(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, + static bool DragVec2(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec2 values = get(); bool changed = false; - if (DragN(fieldLabel, componentLabels, {&values.x, &values.y}, speed, displayFormat, valueMin, valueMax, flags)) + if (DragN(fieldLabel, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags)) { changed = true; } @@ -95,22 +95,22 @@ namespace SHADE { if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); - else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); - else if(ImGui::IsItemDeactivatedAfterEdit()) + else if (ImGui::IsItemDeactivatedAfterEdit()) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); } return changed; } - static bool DragVec3(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, + static bool DragVec3(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec3 values = get(); bool changed = false; - if (DragN(fieldLabel, componentLabels, {&values.x, &values.y, &values.z}, speed, displayFormat, valueMin, valueMax, flags)) + if (DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags)) { changed = true; } @@ -119,22 +119,22 @@ namespace SHADE { if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); - else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); - else if(ImGui::IsItemDeactivatedAfterEdit()) + else if (ImGui::IsItemDeactivatedAfterEdit()) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); } return changed; } - static bool DragVec4(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, + static bool DragVec4(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec4 values = get(); bool changed = false; - if (DragN(fieldLabel, componentLabels, {&values.x, &values.y, &values.z, &values.w}, speed, displayFormat, valueMin, valueMax, flags)) + if (DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags)) { changed = true; } @@ -143,9 +143,9 @@ namespace SHADE { if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); - else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); - else if(ImGui::IsItemDeactivatedAfterEdit()) + else if (ImGui::IsItemDeactivatedAfterEdit()) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); } @@ -155,7 +155,7 @@ namespace SHADE //#==============================================================# //|| Widget Extensions || //#==============================================================# - + static bool CheckBox(std::string const& label, std::function get, std::function set) { bool value = get(); @@ -182,6 +182,149 @@ namespace SHADE return true; } - + static bool InputText(const std::string& label, const std::function get, + const std::function set, ImGuiInputTextFlags flag = 0, + ImGuiInputTextCallback callback = (ImGuiInputTextCallback)0, void* userData = (void*)0) + { + std::string text = get(); + if (ImGui::InputText(label.c_str(), &text, flag, callback, userData)) + { + if (ImGui::IsItemDeactivatedAfterEdit()) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), text, set)), false); + + return true; + } + return false; + } + + template + static bool DragScalar(const std::string& fieldLabel, ImGuiDataType data_type, std::function get, std::function set, + float speed = 1.0f, T p_min = T(), T p_max = T(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) + { + T value = get(); + std::cout << value <<" \n"; + //bool hasChange = ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags); + + if (ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags)) + { + if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + else if (ImGui::IsItemDeactivatedAfterEdit()) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + + return true; + } + return false; + } + + static bool DragFloat(const std::string& fieldLabel, std::function get, std::function set, + float speed = 0.1f, float p_min = float(), float p_max = float(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) + { + float value = get(); + //bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags); + if (ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags)) + { + if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + else if (ImGui::IsItemDeactivatedAfterEdit()) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + + return true; + } + + return false; + } + + static bool DragInt(const std::string& fieldLabel, std::function get, std::function set, + float speed = 1.0f, int p_min = int(), int p_max = int(), const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) + { + int value = get(); + //bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags); + if (ImGui::DragInt(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags)) + { + if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + else if (ImGui::IsItemDeactivatedAfterEdit()) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + + return true; + } + + return false; + } + template + static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function get, std::function set, + const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) + { + T value = get(); + if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags)) + { + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + + return true; + } + + return false; + } + + static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function get, std::function set, + const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) + { + float value = get(); + if (ImGui::SliderFloat(fieldLabel.c_str(), &value, min, max, displayFormat, flags)) + { + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + + + return true; + } + + return false; + } + + static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function get, std::function set, + const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) + { + int value = get(); + if (ImGui::SliderInt(fieldLabel.c_str(), &value, min, max, displayFormat, flags)) + { + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + + return true; + } + + return false; + } + + static bool ComboBox(const std::string& fieldLabel, std::vector list, std::function get, std::function set) + { + bool edited = false; + int selected = get(); + ImGui::PushID(fieldLabel.c_str()); + ImGui::Text(fieldLabel.c_str()); ImGui::SameLine(); + + if (edited = ImGui::Combo("##Combo", &selected, list.data(), list.size())) + { + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), selected, set)), false); + } + ImGui::PopID(); + return edited; + } + }//namespace SHADE diff --git a/SHADE_Engine/src/FRC/SHFramerateController.cpp b/SHADE_Engine/src/FRC/SHFramerateController.cpp index d64c6336..0791d628 100644 --- a/SHADE_Engine/src/FRC/SHFramerateController.cpp +++ b/SHADE_Engine/src/FRC/SHFramerateController.cpp @@ -9,12 +9,31 @@ consent of DigiPen Institute of Technology is prohibited. *********************************************************************/ + +//TODO Legacy code. Delete soon + #include #include #include #include "SHFramerateController.h" #include "../Tools/SHLogger.h" +namespace SHADE +{ + double SHFrameRateController::rawDeltaTime = 0.0; + std::chrono::steady_clock::time_point SHFrameRateController::prevFrameTime = std::chrono::high_resolution_clock::now(); + + void SHFrameRateController::UpdateFRC() noexcept + { + std::chrono::duration deltaTime; + deltaTime = std::chrono::high_resolution_clock::now() - prevFrameTime; + prevFrameTime = std::chrono::high_resolution_clock::now(); + rawDeltaTime = deltaTime.count(); + } +} + +//TODO Legacy code. Delete soon +#if 0 namespace SHADE { //Init statics @@ -131,4 +150,5 @@ namespace SHADE currentScene = nextScene; } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/SHADE_Engine/src/FRC/SHFramerateController.h b/SHADE_Engine/src/FRC/SHFramerateController.h index 26f276d8..b9637cf2 100644 --- a/SHADE_Engine/src/FRC/SHFramerateController.h +++ b/SHADE_Engine/src/FRC/SHFramerateController.h @@ -13,6 +13,38 @@ #define SH_FRAMERATECONTROLLER_H #pragma once +#include +#include "Tools/SHLogger.h" +#include "SH_API.h" + +namespace SHADE +{ + class SH_API SHFrameRateController + { + private: + //Varying delta time. The actual time it took for every frame + static double rawDeltaTime; + static std::chrono::steady_clock::time_point prevFrameTime; + + + public: + //Gets the raw delta time + static inline double GetRawDeltaTime() noexcept + { + return rawDeltaTime; + } + + //Updates the raw delta time accordingly + static void UpdateFRC() noexcept; + + }; + +} + + + +//TODO Legacy code. Delete soon +#if 0 #include "../Scene/SHScene.h" namespace SHADE @@ -56,7 +88,19 @@ namespace SHADE //halt execution of the current scene and prepare //execution of the next static inline void SetNextScene(SHScene* const next) { nextScene = next; } + + + }; + + + } +#endif + + + + + #endif \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Vector/SHVec2.cpp b/SHADE_Engine/src/Math/Vector/SHVec2.cpp index 2d2eafd2..545492cb 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec2.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec2.cpp @@ -165,7 +165,7 @@ namespace SHADE return XMVector2NotEqual(V1, V2); } - float SHVec2::operator[](int index) + float& SHVec2::operator[](int index) { if (index >= SIZE || index < 0) throw std::invalid_argument("Index out of range!"); @@ -174,11 +174,10 @@ namespace SHADE { case 0: return x; case 1: return y; - default: return 0.0f; } } - float SHVec2::operator[](size_t index) + float& SHVec2::operator[](size_t index) { if (index >= SIZE) throw std::invalid_argument("Index out of range!"); @@ -187,7 +186,6 @@ namespace SHADE { case 0: return x; case 1: return y; - default: return 0.0f; } } @@ -200,7 +198,6 @@ namespace SHADE { case 0: return x; case 1: return y; - default: return 0.0f; } } @@ -213,7 +210,6 @@ namespace SHADE { case 0: return x; case 1: return y; - default: return 0.0f; } } diff --git a/SHADE_Engine/src/Math/Vector/SHVec2.h b/SHADE_Engine/src/Math/Vector/SHVec2.h index 3e6287aa..17642126 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec2.h +++ b/SHADE_Engine/src/Math/Vector/SHVec2.h @@ -81,8 +81,8 @@ namespace SHADE [[nodiscard]] bool operator== (const SHVec2& rhs) const noexcept; [[nodiscard]] bool operator!= (const SHVec2& rhs) const noexcept; - [[nodiscard]] float operator[] (int index); - [[nodiscard]] float operator[] (size_t index); + [[nodiscard]] float& operator[] (int index); + [[nodiscard]] float& operator[] (size_t index); [[nodiscard]] float operator[] (int index) const; [[nodiscard]] float operator[] (size_t index) const; diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.cpp b/SHADE_Engine/src/Math/Vector/SHVec3.cpp index 194f7964..1bcb47b3 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec3.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec3.cpp @@ -171,7 +171,7 @@ namespace SHADE return XMVector3NotEqual(V1, V2); } - float SHVec3::operator[](int index) + float& SHVec3::operator[](int index) { if (index >= SIZE || index < 0) throw std::invalid_argument("Index out of range!"); @@ -181,11 +181,10 @@ namespace SHADE case 0: return x; case 1: return y; case 2: return z; - default: return 0.0f; } } - float SHVec3::operator[](size_t index) + float& SHVec3::operator[](size_t index) { if (index >= SIZE) throw std::invalid_argument("Index out of range!"); @@ -195,7 +194,6 @@ namespace SHADE case 0: return x; case 1: return y; case 2: return z; - default: return 0.0f; } } @@ -209,7 +207,6 @@ namespace SHADE case 0: return x; case 1: return y; case 2: return z; - default: return 0.0f; } } @@ -223,7 +220,6 @@ namespace SHADE case 0: return x; case 1: return y; case 2: return z; - default: return 0.0f; } } diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.h b/SHADE_Engine/src/Math/Vector/SHVec3.h index 476d7b0f..cc0e043e 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec3.h +++ b/SHADE_Engine/src/Math/Vector/SHVec3.h @@ -86,8 +86,8 @@ namespace SHADE [[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept; [[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept; - [[nodiscard]] float operator[] (int index); - [[nodiscard]] float operator[] (size_t index); + [[nodiscard]] float& operator[] (int index); + [[nodiscard]] float& operator[] (size_t index); [[nodiscard]] float operator[] (int index) const; [[nodiscard]] float operator[] (size_t index) const; diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.cpp b/SHADE_Engine/src/Math/Vector/SHVec4.cpp index 5d75af33..d1c87865 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec4.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec4.cpp @@ -161,7 +161,7 @@ namespace SHADE return XMVector4NotEqual(V1, V2); } - float SHVec4::operator[](int index) + float& SHVec4::operator[](int index) { if (index >= SIZE || index < 0) throw std::invalid_argument("Index out of range!"); @@ -172,11 +172,10 @@ namespace SHADE case 1: return y; case 2: return z; case 3: return w; - default: return 0.0f; } } - float SHVec4::operator[](size_t index) + float& SHVec4::operator[](size_t index) { if (index >= SIZE) throw std::invalid_argument("Index out of range!"); @@ -187,7 +186,6 @@ namespace SHADE case 1: return y; case 2: return z; case 3: return w; - default: return 0.0f; } } @@ -202,7 +200,6 @@ namespace SHADE case 1: return y; case 2: return z; case 3: return w; - default: return 0.0f; } } @@ -217,7 +214,6 @@ namespace SHADE case 1: return y; case 2: return z; case 3: return w; - default: return 0.0f; } } diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.h b/SHADE_Engine/src/Math/Vector/SHVec4.h index a4a5208a..59038065 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec4.h +++ b/SHADE_Engine/src/Math/Vector/SHVec4.h @@ -80,8 +80,8 @@ namespace SHADE [[nodiscard]] bool operator== (const SHVec4& rhs) const noexcept; [[nodiscard]] bool operator!= (const SHVec4& rhs) const noexcept; - [[nodiscard]] float operator[] (int index); - [[nodiscard]] float operator[] (size_t index); + [[nodiscard]] float& operator[] (int index); + [[nodiscard]] float& operator[] (size_t index); [[nodiscard]] float operator[] (int index) const; [[nodiscard]] float operator[] (size_t index) const; diff --git a/SHADE_Engine/src/Reflection/SHReflectionMetadata.h b/SHADE_Engine/src/Reflection/SHReflectionMetadata.h new file mode 100644 index 00000000..0cc6d8a5 --- /dev/null +++ b/SHADE_Engine/src/Reflection/SHReflectionMetadata.h @@ -0,0 +1,11 @@ +#pragma once +#include "string_view" +namespace SHADE +{ + namespace META + { + constexpr const char* min = "MIN"; + constexpr const char* max = "MAX"; + constexpr const char* tooltip = "tooltip"; + } +} diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index 39afbb31..3f3ebf92 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -99,7 +99,7 @@ namespace SHADE using EntityNodeMap = std::unordered_map; - using UnaryPredicate = void (*)(SHSceneNode*); + using UnaryPredicate = std::function; /*---------------------------------------------------------------------------------*/