Merge remote-tracking branch 'origin/main' into SP3-1-Rendering

This commit is contained in:
Brandon Mak 2022-09-28 20:39:42 +08:00
commit 363e09bd55
32 changed files with 1438 additions and 61 deletions

BIN
Assets/Audio/Master.bank Normal file

Binary file not shown.

Binary file not shown.

BIN
Assets/Audio/footsteps.bank Normal file

Binary file not shown.

View File

@ -19,10 +19,11 @@ echo "L - yamlcpp"
echo "M - SDL" echo "M - SDL"
echo "N - dotnet" echo "N - dotnet"
echo "O - tinyddsloader" echo "O - tinyddsloader"
echo "P - fmod"
echo --------------------------------------------------- echo ---------------------------------------------------
echo. echo.
choice /C ABCDEFGHIJKLMNO /T 10 /D A choice /C ABCDEFGHIJKLMNOP /T 10 /D A
set _e=%ERRORLEVEL% set _e=%ERRORLEVEL%
if %_e%==1 goto VMA if %_e%==1 goto VMA
@ -40,6 +41,7 @@ if %_e%==12 goto yamlcpp
if %_e%==13 goto SDL if %_e%==13 goto SDL
if %_e%==14 goto dotnet if %_e%==14 goto dotnet
if %_e%==15 goto tinyddsloader if %_e%==15 goto tinyddsloader
if %_e%==16 goto fmod
:VMA :VMA
echo -----------------------VMA---------------------------- echo -----------------------VMA----------------------------
@ -145,6 +147,12 @@ if %_e%==14 (goto :done) else (goto :tinyddsloader)
echo --------------------tinyddsloader------------------------- echo --------------------tinyddsloader-------------------------
rmdir "Dependencies/tinyddsloader" /S /Q rmdir "Dependencies/tinyddsloader" /S /Q
git clone https://github.com/SHADE-DP/tinyddsloader.git "Dependencies/tinyddsloader" 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 :done
echo DONE! echo DONE!

View File

@ -15,3 +15,4 @@ IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
IncludeDir["VULKAN"] = "$(VULKAN_SDK)" IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet" IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader" IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader"
IncludeDir["fmod"] = "%{wks.location}\\Dependencies\\fmod"

View File

@ -34,8 +34,9 @@ project "SHADE_Application"
"%{IncludeDir.VULKAN}/include", "%{IncludeDir.VULKAN}/include",
"%{IncludeDir.VMA}/include", "%{IncludeDir.VMA}/include",
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect", "%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
"%{IncludeDir.RTTR}/include", "%{IncludeDir.tinyddsloader}",
"%{IncludeDir.tinyddsloader}" "%{IncludeDir.fmod}/include",
"%{IncludeDir.RTTR}\\include"
} }
externalwarnings "Off" externalwarnings "Off"
@ -81,4 +82,4 @@ project "SHADE_Application"
filter "configurations:Publish" filter "configurations:Publish"
optimize "On" optimize "On"
defines{"_RELEASE"} defines{"_RELEASE", "_PUBLISH"}

View File

@ -24,6 +24,8 @@
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "Math/Transform/SHTransformSystem.h" #include "Math/Transform/SHTransformSystem.h"
#include "Input/SHInputManagerSystem.h" #include "Input/SHInputManagerSystem.h"
#include "FRC/SHFramerateController.h"
//#include "AudioSystem/SHAudioSystem.h"
#include "Scenes/SBTestScene.h" #include "Scenes/SBTestScene.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
@ -55,6 +57,7 @@ namespace Sandbox
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>(); SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>()); SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>(); SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>();
//SHADE::SHSystemManager::CreateSystem<SHADE::SHAudioSystem>();
// Create Routines // Create Routines
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameSetUpRoutine>(); SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameSetUpRoutine>();
@ -84,6 +87,8 @@ namespace Sandbox
SHADE::SHAssetManager::LoadDataTemp("../../Assets/TD_Checker_Base_Color.dds"); SHADE::SHAssetManager::LoadDataTemp("../../Assets/TD_Checker_Base_Color.dds");
//TODO: REMOVE AFTER PRESENTATION //TODO: REMOVE AFTER PRESENTATION
//SHADE::SHSystemManager::RegisterRoutine<SHADE::SHAudioSystem, SHADE::SHAudioSystem::AudioRoutine>();
// Set up graphics system and windows // Set up graphics system and windows
graphicsSystem->SetWindow(&window); graphicsSystem->SetWindow(&window);
@ -96,6 +101,7 @@ namespace Sandbox
#endif #endif
SHSceneManager::InitSceneManager<SBTestScene>("TestScene"); SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
SHFrameRateController::UpdateFRC();
} }
void SBApplication::Update(void) void SBApplication::Update(void)
@ -104,6 +110,7 @@ namespace Sandbox
//TODO: Change true to window is open //TODO: Change true to window is open
while (!window.WindowShouldClose()) while (!window.WindowShouldClose())
{ {
SHFrameRateController::UpdateFRC();
SHSceneManager::UpdateSceneManager(); SHSceneManager::UpdateSceneManager();
SHSceneManager::SceneUpdate(1/60.0f); SHSceneManager::SceneUpdate(1/60.0f);
//#ifdef SHEDITOR //#ifdef SHEDITOR

View File

@ -42,7 +42,8 @@ project "SHADE_Engine"
"%{IncludeDir.VULKAN}\\include", "%{IncludeDir.VULKAN}\\include",
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect", "%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
"%{IncludeDir.dotnet}\\include", "%{IncludeDir.dotnet}\\include",
"%{IncludeDir.tinyddsloader}" "%{IncludeDir.tinyddsloader}",
"%{IncludeDir.fmod}\\include"
} }
externalwarnings "Off" externalwarnings "Off"
@ -55,7 +56,8 @@ project "SHADE_Engine"
"%{IncludeDir.assimp}/lib/Release", "%{IncludeDir.assimp}/lib/Release",
"%{IncludeDir.RTTR}/lib", "%{IncludeDir.RTTR}/lib",
"%{IncludeDir.SDL}/lib", "%{IncludeDir.SDL}/lib",
"%{IncludeDir.spdlog}/lib" "%{IncludeDir.spdlog}/lib",
"%{IncludeDir.fmod}/lib",
} }
links links
@ -108,10 +110,28 @@ project "SHADE_Engine"
} }
filter "configurations:Debug" 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" 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" filter "configurations:Publish"
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)\""}
@ -122,17 +142,17 @@ project "SHADE_Engine"
symbols "On" symbols "On"
defines {"_DEBUG", "SHEDITOR"} defines {"_DEBUG", "SHEDITOR"}
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"} 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" filter "configurations:Release"
optimize "On" optimize "On"
defines{"_RELEASE", "SHEDITOR"} defines{"_RELEASE", "SHEDITOR"}
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"} 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" filter "configurations:Publish"
optimize "On" optimize "On"
defines{"_RELEASE"} defines{"_RELEASE", "_PUBLISH"}
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"} links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
excludes excludes
{ {
@ -140,4 +160,4 @@ project "SHADE_Engine"
"%{prj.location}/src/Editor/**.h", "%{prj.location}/src/Editor/**.h",
"%{prj.location}/src/Editor/**.hpp", "%{prj.location}/src/Editor/**.hpp",
} }
--links{"fmodstudio_vc.lib", "fmod_vc.lib"} links{"fmodstudio_vc.lib", "fmod_vc.lib"}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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<SHAudioSystem>()->PlaySFX(id, GetEID(),loop,spatial, min, max);
}
void SHAudioSourceComponent::PlaySoundBGM(EntityID id, bool loop, bool spatial, float min, float max)
{
SHSystemManager::GetSystem<SHAudioSystem>()->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<SHAudioSystem>()->StopSound(id);
}
/**
* @brief Mute the sound
*
* @param index where the sound is in the index
*/
void SHAudioSourceComponent::SetMute(EntityID id, bool mute)
{
SHSystemManager::GetSystem<SHAudioSystem>()->SetMute(id, mute);
}
}

View File

@ -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

View File

@ -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 <iostream>
#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 <FMOD/fmod_errors.h>
#include <FMOD/fmod.hpp>
#include <FMOD/fmod_studio.hpp>
#include <SDL_keyboard.h>
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::SHAudioSourceComponent>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHAudioListenerComponent>();
denseListener = &SHComponentManager::GetDense<SHAudioListenerComponent>();
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<void>(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<SHTransformComponent>(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<SHAudioSystem*>(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<SHTransformComponent>(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<SHTransformComponent>(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<SHTransformComponent>(eid))
{
SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(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<SHTransformComponent>(eid))
{
SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(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<FMOD_GUID> 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<const char*> SHAudioSystem::GetAllEvents()
//{
// int count{};
// stringsBank->getEventCount(&count);
// std::vector<FMOD::Studio::EventDescription*> events(count);
// auto eventData = events.data();
// int finalCount{};
// stringsBank->getEventList(eventData, count, &finalCount);
// std::vector<const char*> 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<SHTransformComponent>(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<SHTransformComponent>(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<FMOD::Studio::EventInstance*> 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<SHTransformComponent>(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<FMOD::Studio::EventDescription*> 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<SHADE::SHAudioSystem>();
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<SHADE::SHAudioSystem>();
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)

View File

@ -0,0 +1,110 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <set>
#include <unordered_map>
#include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "ECS_Base/SHECSMacros.h"
#include "Math/SHMath.h"
#include <optional>
#include <FMOD/fmod_studio.hpp>
#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<SHSound>::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<FMOD_GUID> GetEventGUID(const char* path);
AudioClip* CreateAudioClip(const char* path);
//std::vector<const char*> 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<EntityID, SHSound> soundList;
//std::unordered_map<ResourceID, SHBank> bankMap;
std::unordered_map<std::string, SHBank> bankMap;
std::unordered_map<std::string, FMOD::Studio::EventDescription*> eventMap;
std::unordered_map<AudioClipID, AudioClip> 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<SHAudioListenerComponent>* denseListener;
AudioClipID clipID = 0;
};
}

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "../Components/SHComponent.h" #include "../Components/SHComponent.h"
#include <rttr/registration>
namespace SHADE namespace SHADE
{ {
@ -27,4 +28,50 @@ namespace SHADE
std::string value{}; 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<SHComponent_ENUM::Option>("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_<SHComponent_ENUM>("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));
}
} }

View File

@ -12,6 +12,7 @@
#include "Editor/IconsMaterialDesign.h" #include "Editor/IconsMaterialDesign.h"
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "Editor/SHEditorWidgets.hpp" #include "Editor/SHEditorWidgets.hpp"
#include "Reflection/SHReflectionMetadata.h"
namespace SHADE namespace SHADE
{ {
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true> template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
@ -55,7 +56,124 @@ namespace SHADE
{ {
auto const& type = property.get_type(); auto const& type = property.get_type();
if (type == rttr::type::get<SHVec4>()) if(type.is_enumeration())
{
auto enumAlign = type.get_enumeration();
auto names = enumAlign.get_names();
std::vector<const char*> 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<bool>())
{
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<char>())
//{
//
//}
else if (type == rttr::type::get<int8_t>() || type == rttr::type::get<int16_t>() || type == rttr::type::get<int32_t>() || type == rttr::type::get<int64_t>())
{
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<int>(), metaMin.template get_value<int>(), [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<uint8_t>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin.is_valid() && metaMax.is_valid())
{
SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},"%zu");
}
else
{
DragScalar<uint8_t>(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<uint16_t>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin.is_valid() && metaMax.is_valid())
{
SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMin.template get_value<uint16_t>(), [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},"%zu");
}
else
{
DragScalar<uint16_t>(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<uint32_t>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if (metaMin.is_valid() && metaMax.is_valid())
{
SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMin.template get_value<uint32_t>(), [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },"%zu");
}
else
{
DragScalar<uint32_t>(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<uint64_t>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin.is_valid() && metaMax.is_valid())
{
SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMin.template get_value<uint64_t>(), [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},"%zu");
}
else
{
DragScalar<uint64_t>(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<float>())
{
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<float>(), metaMin.template get_value<float>(), [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<double>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin.is_valid() && metaMax.is_valid())
{
SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMin.template get_value<double>(), [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);});
}
else
{
DragScalar<double>(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<SHVec4>())
{ {
DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); }); DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [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<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); }); DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); });
} }
else if (type == rttr::type::get<SHVec2>())
{
DragVec2(property.get_name().data(), { "X", "Y"}, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
}
} }
} }
else DrawContextMenu(component); else DrawContextMenu(component);

View File

@ -11,8 +11,12 @@
#include "Editor/SHImGuiHelpers.hpp" #include "Editor/SHImGuiHelpers.hpp"
#include "Editor/SHEditorWidgets.hpp" #include "Editor/SHEditorWidgets.hpp"
#include "SHEditorComponentView.hpp" #include "SHEditorComponentView.hpp"
#include "ECS_Base/UnitTesting/SHTestComponents.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "AudioSystem/SHAudioSystem.h"
namespace SHADE namespace SHADE
{ {
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true> template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
@ -54,11 +58,20 @@ namespace SHADE
{ {
DrawComponent(transformComponent); DrawComponent(transformComponent);
} }
if(auto renderableComponent = SHComponentManager::GetComponent_s<SHRenderable>(eid))
{
DrawComponent(renderableComponent);
}
if(auto testComponent = SHComponentManager::GetComponent_s<SHComponent_ENUM>(eid))
{
DrawComponent(testComponent);
}
ImGui::Separator(); ImGui::Separator();
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data())) if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
{ {
DrawAddComponentButton<SHTransformComponent>(eid); DrawAddComponentButton<SHTransformComponent>(eid);
DrawAddComponentButton<SHRenderable>(eid); DrawAddComponentButton<SHRenderable>(eid);
DrawAddComponentButton<SHComponent_ENUM>(eid);
ImGui::EndMenu(); ImGui::EndMenu();
} }
} }

View File

@ -0,0 +1,48 @@
#include "SHpch.h"
#include "SHEditorProfiler.h"
#include <imgui.h>
#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<float>(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<int>(frames.size()), 0, nullptr, 0.0f, 16.0f);
ImGui::End();
}
}
void SHEditorProfiler::Exit()
{
SHEditorWindow::Exit();
}
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "Editor/EditorWindow/SHEditorWindow.h"
#include <vector>
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<float> frames;
};
}

View File

@ -2,3 +2,4 @@
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar #include "MenuBar/SHEditorMenuBar.h" //Menu Bar
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel #include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
#include "Inspector/SHEditorInspector.h" //Inspector #include "Inspector/SHEditorInspector.h" //Inspector
#include "Profiling/SHEditorProfiler.h" //Profiler

View File

@ -95,6 +95,7 @@ namespace SHADE
CreateEditorWindow<SHEditorMenuBar>(); CreateEditorWindow<SHEditorMenuBar>();
CreateEditorWindow<SHHierarchyPanel>(); CreateEditorWindow<SHHierarchyPanel>();
CreateEditorWindow<SHEditorInspector>(); CreateEditorWindow<SHEditorInspector>();
CreateEditorWindow<SHEditorProfiler>();
SHLOG_INFO("Successfully initialised SHADE Engine Editor") SHLOG_INFO("Successfully initialised SHADE Engine Editor")
} }
@ -106,6 +107,7 @@ namespace SHADE
for (const auto& window : editorWindows | std::views::values) for (const auto& window : editorWindows | std::views::values)
{ {
if(window->isOpen)
window->Update(); window->Update();
} }
@ -292,7 +294,9 @@ namespace SHADE
imguiCommandBuffer->EndRecording(); imguiCommandBuffer->EndRecording();
gfxSystem->GetQueue()->SubmitCommandBuffer({ imguiCommandBuffer }, {}, {}, vk::PipelineStageFlagBits::eNone, {}); 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<SHVkCommandBuffer>& cmd) { renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer()); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());

View File

@ -182,6 +182,149 @@ namespace SHADE
return true; return true;
} }
static bool InputText(const std::string& label, const std::function<std::string(void)> get,
const std::function<void(std::string)> 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<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
return true;
}
return false;
}
template <typename T>
static bool DragScalar(const std::string& fieldLabel, ImGuiDataType data_type, std::function<T(void)> get, std::function<void(T const&)> 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<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
else if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
return true;
}
return false;
}
static bool DragFloat(const std::string& fieldLabel, std::function<float(void)> get, std::function<void(float const&)> 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<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
else if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
return true;
}
return false;
}
static bool DragInt(const std::string& fieldLabel, std::function<int(void)> get, std::function<void(int const&)> 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<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
else if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
return true;
}
return false;
}
template <typename T>
static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function<T(void)> get, std::function<void(T const&)> 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<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
return true;
}
return false;
}
static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function<float(void)> get, std::function<void(float const&)> 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<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
return true;
}
return false;
}
static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function<int(void)> get, std::function<void(int const&)> 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<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
return true;
}
return false;
}
static bool ComboBox(const std::string& fieldLabel, std::vector<const char*> list, std::function<int(void)> get, std::function<void(int const&)> 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<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), selected, set)), false);
}
ImGui::PopID();
return edited;
}
}//namespace SHADE }//namespace SHADE

View File

@ -9,12 +9,31 @@
consent of DigiPen Institute of Technology is prohibited. consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/ *********************************************************************/
//TODO Legacy code. Delete soon
#include <chrono> #include <chrono>
#include <cassert> #include <cassert>
#include <SHpch.h> #include <SHpch.h>
#include "SHFramerateController.h" #include "SHFramerateController.h"
#include "../Tools/SHLogger.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<double> 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 namespace SHADE
{ {
//Init statics //Init statics
@ -132,3 +151,4 @@ namespace SHADE
} }
} }
} }
#endif

View File

@ -13,6 +13,38 @@
#define SH_FRAMERATECONTROLLER_H #define SH_FRAMERATECONTROLLER_H
#pragma once #pragma once
#include <chrono>
#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" #include "../Scene/SHScene.h"
namespace SHADE namespace SHADE
@ -56,7 +88,19 @@ namespace SHADE
//halt execution of the current scene and prepare //halt execution of the current scene and prepare
//execution of the next //execution of the next
static inline void SetNextScene(SHScene* const next) { nextScene = next; } static inline void SetNextScene(SHScene* const next) { nextScene = next; }
}; };
} }
#endif
#endif #endif

View File

@ -165,7 +165,7 @@ namespace SHADE
return XMVector2NotEqual(V1, V2); return XMVector2NotEqual(V1, V2);
} }
float SHVec2::operator[](int index) float& SHVec2::operator[](int index)
{ {
if (index >= SIZE || index < 0) if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!"); throw std::invalid_argument("Index out of range!");
@ -174,11 +174,10 @@ namespace SHADE
{ {
case 0: return x; case 0: return x;
case 1: return y; case 1: return y;
default: return 0.0f;
} }
} }
float SHVec2::operator[](size_t index) float& SHVec2::operator[](size_t index)
{ {
if (index >= SIZE) if (index >= SIZE)
throw std::invalid_argument("Index out of range!"); throw std::invalid_argument("Index out of range!");
@ -187,7 +186,6 @@ namespace SHADE
{ {
case 0: return x; case 0: return x;
case 1: return y; case 1: return y;
default: return 0.0f;
} }
} }
@ -200,7 +198,6 @@ namespace SHADE
{ {
case 0: return x; case 0: return x;
case 1: return y; case 1: return y;
default: return 0.0f;
} }
} }
@ -213,7 +210,6 @@ namespace SHADE
{ {
case 0: return x; case 0: return x;
case 1: return y; case 1: return y;
default: return 0.0f;
} }
} }

View File

@ -81,8 +81,8 @@ namespace SHADE
[[nodiscard]] bool operator== (const SHVec2& rhs) const noexcept; [[nodiscard]] bool operator== (const SHVec2& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHVec2& rhs) const noexcept; [[nodiscard]] bool operator!= (const SHVec2& rhs) const noexcept;
[[nodiscard]] float operator[] (int index); [[nodiscard]] float& operator[] (int index);
[[nodiscard]] float operator[] (size_t index); [[nodiscard]] float& operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const; [[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const; [[nodiscard]] float operator[] (size_t index) const;

View File

@ -171,7 +171,7 @@ namespace SHADE
return XMVector3NotEqual(V1, V2); return XMVector3NotEqual(V1, V2);
} }
float SHVec3::operator[](int index) float& SHVec3::operator[](int index)
{ {
if (index >= SIZE || index < 0) if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!"); throw std::invalid_argument("Index out of range!");
@ -181,11 +181,10 @@ namespace SHADE
case 0: return x; case 0: return x;
case 1: return y; case 1: return y;
case 2: return z; case 2: return z;
default: return 0.0f;
} }
} }
float SHVec3::operator[](size_t index) float& SHVec3::operator[](size_t index)
{ {
if (index >= SIZE) if (index >= SIZE)
throw std::invalid_argument("Index out of range!"); throw std::invalid_argument("Index out of range!");
@ -195,7 +194,6 @@ namespace SHADE
case 0: return x; case 0: return x;
case 1: return y; case 1: return y;
case 2: return z; case 2: return z;
default: return 0.0f;
} }
} }
@ -209,7 +207,6 @@ namespace SHADE
case 0: return x; case 0: return x;
case 1: return y; case 1: return y;
case 2: return z; case 2: return z;
default: return 0.0f;
} }
} }
@ -223,7 +220,6 @@ namespace SHADE
case 0: return x; case 0: return x;
case 1: return y; case 1: return y;
case 2: return z; case 2: return z;
default: return 0.0f;
} }
} }

View File

@ -86,8 +86,8 @@ namespace SHADE
[[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept; [[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept; [[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept;
[[nodiscard]] float operator[] (int index); [[nodiscard]] float& operator[] (int index);
[[nodiscard]] float operator[] (size_t index); [[nodiscard]] float& operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const; [[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const; [[nodiscard]] float operator[] (size_t index) const;

View File

@ -161,7 +161,7 @@ namespace SHADE
return XMVector4NotEqual(V1, V2); return XMVector4NotEqual(V1, V2);
} }
float SHVec4::operator[](int index) float& SHVec4::operator[](int index)
{ {
if (index >= SIZE || index < 0) if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!"); throw std::invalid_argument("Index out of range!");
@ -172,11 +172,10 @@ namespace SHADE
case 1: return y; case 1: return y;
case 2: return z; case 2: return z;
case 3: return w; case 3: return w;
default: return 0.0f;
} }
} }
float SHVec4::operator[](size_t index) float& SHVec4::operator[](size_t index)
{ {
if (index >= SIZE) if (index >= SIZE)
throw std::invalid_argument("Index out of range!"); throw std::invalid_argument("Index out of range!");
@ -187,7 +186,6 @@ namespace SHADE
case 1: return y; case 1: return y;
case 2: return z; case 2: return z;
case 3: return w; case 3: return w;
default: return 0.0f;
} }
} }
@ -202,7 +200,6 @@ namespace SHADE
case 1: return y; case 1: return y;
case 2: return z; case 2: return z;
case 3: return w; case 3: return w;
default: return 0.0f;
} }
} }
@ -217,7 +214,6 @@ namespace SHADE
case 1: return y; case 1: return y;
case 2: return z; case 2: return z;
case 3: return w; case 3: return w;
default: return 0.0f;
} }
} }

View File

@ -80,8 +80,8 @@ namespace SHADE
[[nodiscard]] bool operator== (const SHVec4& rhs) const noexcept; [[nodiscard]] bool operator== (const SHVec4& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHVec4& rhs) const noexcept; [[nodiscard]] bool operator!= (const SHVec4& rhs) const noexcept;
[[nodiscard]] float operator[] (int index); [[nodiscard]] float& operator[] (int index);
[[nodiscard]] float operator[] (size_t index); [[nodiscard]] float& operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const; [[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const; [[nodiscard]] float operator[] (size_t index) const;

View File

@ -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";
}
}

View File

@ -99,7 +99,7 @@ namespace SHADE
using EntityNodeMap = std::unordered_map<EntityID, SHSceneNode*>; using EntityNodeMap = std::unordered_map<EntityID, SHSceneNode*>;
using UnaryPredicate = void (*)(SHSceneNode*); using UnaryPredicate = std::function<void(SHSceneNode*)>;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/