From 462af02a6b0aec3dc1e5b591f95a228b7fd1e820 Mon Sep 17 00:00:00 2001 From: Stiffly Date: Wed, 21 May 2014 17:14:07 +0200 Subject: [PATCH] Added logic for 3D sound --- src/GameWorld.cpp | 13 +++++- src/Systems/SoundSystem.cpp | 88 +++++++++++++++++++++++++++++++++++-- src/Systems/SoundSystem.h | 12 ++++- 3 files changed, 108 insertions(+), 5 deletions(-) diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 85a2869..4135c4e 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -72,7 +72,6 @@ void GameWorld::Initialize() physics->Mass = 10; physics->Static = true; - auto groundshape = CreateEntity(ground); auto transformshape = AddComponent(groundshape); auto meshShape = AddComponent(groundshape); @@ -218,6 +217,8 @@ void GameWorld::Initialize() { auto tank = CreateEntity(); + + auto listener = AddComponent(tank); auto transform = AddComponent(tank); transform->Position = glm::vec3(0, 5, 0); //transform->Orientation = glm::angleAxis(0.f, glm::vec3(0, 1, 0)); @@ -671,6 +672,7 @@ void GameWorld::Initialize() auto physics = AddComponent(brick); physics->Mass = 3; + @@ -686,6 +688,15 @@ void GameWorld::Initialize() } } + auto soundEmitter = CreateEntity(); + auto transform = AddComponent(soundEmitter); + transform->Position = glm::vec3(0,10,0); + transform->Scale = glm::vec3(3); + AddComponent(soundEmitter); + auto model = AddComponent(soundEmitter); + model->ModelFile = "Models/PlaceHolders/PhysicsTest/PointLight.obj"; + + /*for (int x = 0; x < 5; x++) for (int y = 0; y < 5; y++) { diff --git a/src/Systems/SoundSystem.cpp b/src/Systems/SoundSystem.cpp index 1a17f43..ef2c9fe 100755 --- a/src/Systems/SoundSystem.cpp +++ b/src/Systems/SoundSystem.cpp @@ -4,7 +4,7 @@ void Systems::SoundSystem::Initialize() { - FMOD_RESULT result; + /*FMOD_RESULT result; result = FMOD::System_Create(&m_FmodSystem); result = m_FmodSystem->init(32, FMOD_INIT_NORMAL, 0); @@ -16,7 +16,12 @@ void Systems::SoundSystem::Initialize() pos.y = 0.f; pos.z = 0.f; m_FmodSystem->createSound("Sounds/WUB.mp3", FMOD_HARDWARE, 0, &sound); - m_FmodSystem->playSound(FMOD_CHANNEL_FREE, sound, false, 0); + m_FmodSystem->playSound(FMOD_CHANNEL_FREE, sound, false, 0);*/ + + FMOD_System_Create(&m_System); + FMOD_System_Init(m_System, 32, FMOD_INIT_NORMAL, nullptr); + FMOD_System_Set3DSettings(m_System, 10.0f, 10.f, 1.0f); //dopplerScale, distancefactor, rolloffscale + FMOD_System_GetMasterChannelGroup(m_System, &m_ChannelGruoup); } void Systems::SoundSystem::RegisterComponents(ComponentFactory* cf) @@ -32,7 +37,7 @@ void Systems::SoundSystem::RegisterResourceTypes(ResourceManager* rm) void Systems::SoundSystem::Update(double dt) { - m_FmodSystem->update(); + FMOD_System_Update(m_System); } void Systems::SoundSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) @@ -40,6 +45,83 @@ void Systems::SoundSystem::UpdateEntity(double dt, EntityID entity, EntityID par auto listener = m_World->GetComponent(entity); if(listener) { + int lID = std::find(m_Listeners.begin(), m_Listeners.end(), entity) - m_Listeners.begin(); + auto lTransform = m_World->GetComponent(entity); + glm::vec3 tPos = lTransform->Position; + FMOD_VECTOR lPos = {tPos.x, tPos.y, tPos.z}; + + glm::vec3 tVel = lTransform->Velocity; + FMOD_VECTOR lVel = {tVel.x, tVel.y, tVel.z}; + + glm::mat3 tOri = glm::toMat3(lTransform->Orientation); + glm::vec3 tUp = tOri[1]; + FMOD_VECTOR lUp = {tUp.x, tUp.y, tUp.z}; + glm::vec3 tForward = tOri[2]; + FMOD_VECTOR lForward = {tForward.x, tForward.y, tForward.z}; + + FMOD_System_Set3DListenerAttributes(m_System, 0, (const FMOD_VECTOR*)&lPos, (const FMOD_VECTOR*)&lVel, (const FMOD_VECTOR*)&lForward, (const FMOD_VECTOR*)&lUp); + } + + auto emitter = m_World->GetComponent(entity); + if(emitter) + { + FMOD_CHANNEL* channel = m_Channels[entity]; + auto eTransform = m_World->GetComponent(entity); + + glm::vec3 tPos = eTransform->Position; + FMOD_VECTOR ePos = {tPos.x, tPos.y, tPos.z}; + + glm::vec3 tVel = eTransform->Velocity; + FMOD_VECTOR eVel = {tVel.x, tVel.y, tVel.z}; + + + FMOD_Channel_SetMode(channel, FMOD_3D_LINEARROLLOFF); + FMOD_Channel_Set3DAttributes(channel, (const FMOD_VECTOR*)&ePos, (const FMOD_VECTOR*)&eVel); + if(!m_Playing) + { + PlaySound(m_Channels[entity], 1, false); + } + } + +} + +void Systems::SoundSystem::OnComponentCreated(std::string type, std::shared_ptr component) +{ + if(type == typeid(Components::SoundEmitter).name()) + { + m_Listeners.push_back(component->Entity); + } + + if (type == typeid(Components::SoundEmitter).name()) + { + FMOD_CHANNEL* channel; + m_Channels.insert(std::pair(component->Entity, channel)); + LoadSound("Sounds/WUB.mp3"); } } + +bool Systems::SoundSystem::LoadSound(std::string filePath) +{ + bool loadedFile; + FMOD_RESULT result = FMOD_System_CreateSound(m_System, filePath.c_str(), FMOD_3D_LINEARROLLOFF, NULL, &m_Sound); + result = FMOD_Sound_Set3DMinMaxDistance(m_Sound, 1.f, 100.f); + + if(result != FMOD_OK) + { + loadedFile = false; + LOG_ERROR("FMOD ERROR: Could not load sound file: %s \n", filePath.c_str()); + } + else + { + loadedFile = true; + } + return loadedFile; +} + +void Systems::SoundSystem::PlaySound(FMOD_CHANNEL* channel, float volume, bool loop) +{ + m_Playing = true; + FMOD_System_PlaySound(m_System, FMOD_CHANNEL_FREE, m_Sound, false, &channel); + FMOD_Channel_SetVolume(channel, volume); +} \ No newline at end of file diff --git a/src/Systems/SoundSystem.h b/src/Systems/SoundSystem.h index ba7ce9d..c3894d9 100755 --- a/src/Systems/SoundSystem.h +++ b/src/Systems/SoundSystem.h @@ -25,13 +25,23 @@ public: void Initialize() override; void Update(double dt) override; void UpdateEntity(double dt, EntityID entity, EntityID parent) override; - //void OnComponentCreated(std::string type, std::shared_ptr component) override; + void OnComponentCreated(std::string type, std::shared_ptr component) override; FMOD::System *m_FmodSystem; private: // Events EventRelay m_EPlaySound; + + bool LoadSound(std::string filePath); + void PlaySound(FMOD_CHANNEL*, float volume, bool loop); + std::vector m_Listeners; + FMOD_SYSTEM* m_System; + FMOD_CHANNELGROUP* m_ChannelGruoup; + std::map m_Channels; + + FMOD_SOUND* m_Sound; //Temp + bool m_Playing; //TEMP }; }