Upgraded to C++ 20 & better audio voice management

This commit is contained in:
Antoine Pilote
2023-09-23 00:37:42 -04:00
parent a89852b4d3
commit a4724e2a91
30 changed files with 319 additions and 80 deletions

View File

@@ -121,7 +121,7 @@ int ApplicationMain(int argc, char* argv[])
// Initialize Engine & Window
Engine::Init();
auto& window = Engine::GetCurrentWindow();
auto window = Engine::GetCurrentWindow();
window->SetSize(launchSettings.resolution);
window->SetTitle(launchSettings.windowTitle);

View File

@@ -56,6 +56,16 @@ public:
ComponentTableReset(component.IsPlaying, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Loop");
ImGui::TableNextColumn();
ImGui::Checkbox("##Loop", &component.Loop);
ImGui::TableNextColumn();
ComponentTableReset(component.Loop, false);
}
ImGui::TableNextColumn();
{
ImGui::Text("Volume");
ImGui::TableNextColumn();
@@ -85,6 +95,51 @@ public:
ComponentTableReset(component.Pan, 0.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Spatialized");
ImGui::TableNextColumn();
ImGui::Checkbox("##Spatialized", &component.Spatialized);
ImGui::TableNextColumn();
ComponentTableReset(component.Spatialized, false);
}
if (component.Spatialized)
{
ImGui::TableNextColumn();
{
ImGui::Text("Min Distance");
ImGui::TableNextColumn();
ImGui::DragFloat("##minDistance", &component.MinDistance, 0.001f, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.MinDistance, 1.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Max Distance");
ImGui::TableNextColumn();
ImGui::DragFloat("##maxDistance", &component.MaxDistance, 0.001f, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.MaxDistance, 10.0f);
}
ImGui::TableNextColumn();
{
ImGui::Text("Attenuation Factor");
ImGui::TableNextColumn();
ImGui::DragFloat("##attenuationFactor", &component.AttenuationFactor, 0.001f, 0.0f);
ImGui::TableNextColumn();
ComponentTableReset(component.AttenuationFactor, 1.0f);
}
}
}
EndComponentTable();
}

View File

@@ -126,7 +126,7 @@ public:
uint32_t animIndex = model->GetCurrentAnimationIndex();
uint32_t oldAnimIndex = animIndex;
auto& animations = model->GetAnimations();
auto animations = model->GetAnimations();
if (ImGui::BeginCombo("Type", model->GetCurrentAnimation()->GetName().c_str()))
{
for (int n = 0; n < model->GetAnimationsCount(); n++)

View File

@@ -175,7 +175,7 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene)
auto capsuleColliderView = scene->m_Registry.view<TransformComponent, CapsuleColliderComponent>();
for (auto e : capsuleColliderView)
{
auto& [transform, capsule] = scene->m_Registry.get<TransformComponent, CapsuleColliderComponent>(e);
auto [transform, capsule] = scene->m_Registry.get<TransformComponent, CapsuleColliderComponent>(e);
const auto entityId = (uint32_t)e;
if (_CapsuleEntity.find(entityId) == _CapsuleEntity.end())
@@ -199,7 +199,7 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene)
auto cylinderColliderView = scene->m_Registry.view<TransformComponent, CylinderColliderComponent>();
for (auto e : cylinderColliderView)
{
auto& [transform, cylinder] = scene->m_Registry.get<TransformComponent, CylinderColliderComponent>(e);
auto [transform, cylinder] = scene->m_Registry.get<TransformComponent, CylinderColliderComponent>(e);
const auto entityId = (uint32_t)e;
if (_CylinderEntity.find(entityId) == _CylinderEntity.end())
@@ -235,7 +235,7 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene)
auto meshColliderView = scene->m_Registry.view<TransformComponent, MeshColliderComponent, ModelComponent>();
for (auto e : meshColliderView)
{
auto& [transform, mesh, model] = scene->m_Registry.get<TransformComponent, MeshColliderComponent, ModelComponent>(e);
auto [transform, mesh, model] = scene->m_Registry.get<TransformComponent, MeshColliderComponent, ModelComponent>(e);
// Component has no mesh set.
if (!model.ModelResource)

View File

@@ -6,5 +6,5 @@ class PopupHelper
public:
static void OpenPopup(const std::string& id);
static bool DefineConfirmationDialog(const std::string& id, const std::string& text);
static bool PopupHelper::DefineTextDialog(const std::string& id, std::string& currentText);
static bool DefineTextDialog(const std::string& id, std::string& currentText);
};

View File

@@ -269,7 +269,7 @@ namespace Nuake {
if (const int result = gbuffer.ReadPixel(3, pixelPos); result > 0)
{
auto& ent = Entity{ (entt::entity)(result - 1), Engine::GetCurrentScene().get() };
auto ent = Entity{ (entt::entity)(result - 1), Engine::GetCurrentScene().get() };
if (ent.IsValid())
{
Selection = EditorSelection(ent);
@@ -423,9 +423,9 @@ namespace Nuake {
ImGui::TableNextColumn();
{
bool& isVisible = e.GetComponent<VisibilityComponent>().Visible;
char* visibilityIcon = isVisible ? ICON_FA_EYE : ICON_FA_EYE_SLASH;
std::string visibilityIcon = isVisible ? ICON_FA_EYE : ICON_FA_EYE_SLASH;
ImGui::PushStyleColor(ImGuiCol_Button, { 0, 0, 0, 0 });
if (ImGui::Button(visibilityIcon, { 40, 0 }))
if (ImGui::Button(visibilityIcon.c_str(), {40, 0}))
{
isVisible = !isVisible;
}
@@ -1540,7 +1540,7 @@ namespace Nuake {
_WelcomeWindow->LoadQueuedProject();
isLoadingProjectQueue = false;
auto& window = Window::Get();
auto window = Window::Get();
window->SetDecorated(true);
window->SetSize({ 1900, 1000 });
window->Center();

View File

@@ -16,7 +16,7 @@ private:
Ref<Nuake::Texture> _NuakeLogo;
public:
static LoadingSplash& LoadingSplash::Get()
static LoadingSplash& Get()
{
static LoadingSplash instance;
return instance;

View File

@@ -76,7 +76,7 @@ namespace Nuake {
{
//ImGuiTextSTD("Name", p.name);
ImGui::TableNextColumn();
std::string current_item = NULL;
std::string current_item = "";
if (ImGui::BeginCombo(("TypeSelection" + std::to_string(idx)).c_str(), current_item.c_str()))
{
for (int n = 0; n < IM_ARRAYSIZE(items); n++)

View File

@@ -37,9 +37,30 @@ namespace Nuake {
void AudioManager::Deinitialize()
{
m_WavSamples.clear();
m_ActiveClips.clear();
m_Soloud->deinit();
}
void AudioManager::SetListenerPosition(const Vector3& position, const Vector3& direction, const Vector3& up)
{
const std::lock_guard<std::mutex> lock(m_AudioQueueMutex);
if (position != m_ListenerPosition || direction != m_ListenerDirection || up != m_ListenerUp)
{
m_ListenerPosition = position;
m_ListenerDirection = direction;
m_ListenerUp = up;
m_Soloud->set3dListenerParameters(m_ListenerPosition.x, m_ListenerPosition.y, m_ListenerPosition.z,
m_ListenerDirection.x, m_ListenerDirection.y, m_ListenerDirection.z,
m_ListenerUp.x, m_ListenerUp.y, m_ListenerUp.z
);
m_Soloud->update3dAudio();
}
}
void AudioManager::PlayTTS(const std::string& text)
{
@@ -60,11 +81,53 @@ namespace Nuake {
m_AudioQueue.push(request);
}
void AudioManager::UpdateVoice(const AudioRequest& request)
{
// Acquire mutex lock
const std::lock_guard<std::mutex> lock(m_AudioQueueMutex);
if (IsVoiceActive(request.audioFile))
{
if (!m_Soloud->isValidVoiceHandle(m_ActiveClips[request.audioFile]))
{
m_ActiveClips.erase(request.audioFile);
return;
}
}
SoLoud::handle& voice = m_ActiveClips[request.audioFile];
m_Soloud->set3dSourcePosition(voice, request.position.x, request.position.y, request.position.z);
m_Soloud->setLooping(voice, request.Loop);
m_Soloud->set3dSourceMinMaxDistance(voice, request.MinDistance, request.MaxDistance);
m_Soloud->set3dSourceAttenuation(voice, 1, request.AttenuationFactor);
m_Soloud->setRelativePlaySpeed(voice, request.speed);
m_Soloud->setPan(voice, request.pan);
m_Soloud->update3dAudio();
}
void AudioManager::StopVoice(const std::string& filePath)
{
const std::lock_guard<std::mutex> lock(m_AudioQueueMutex);
if (!IsVoiceActive(filePath))
{
return;
}
SoLoud::handle& voice = m_ActiveClips[filePath];
m_Soloud->stop(voice);
}
bool AudioManager::IsWavLoaded(const std::string& filePath) const
{
return m_WavSamples.find(filePath) != m_WavSamples.end();
}
bool AudioManager::IsVoiceActive(const std::string& voice) const
{
return m_ActiveClips.find(voice) != m_ActiveClips.end();
}
void AudioManager::LoadWavAudio(const std::string& filePath)
{
m_WavSamples[filePath] = SoLoud::Wav();
@@ -73,24 +136,57 @@ namespace Nuake {
void AudioManager::AudioThreadLoop()
{
while(m_AudioThreadRunning)
{
// Acquire mutex lock
const std::lock_guard<std::mutex> lock(m_AudioQueueMutex);
//CleanupInactiveVoices();
// Check if we have audio queued
while (!m_AudioQueue.empty())
{
AudioRequest& currentAudio = m_AudioQueue.front();
AudioRequest& audioRequest = m_AudioQueue.front();
SoLoud::Wav& audio = m_WavSamples[audioRequest.audioFile];
SoLoud::handle soloudHandle = m_Soloud->play(m_WavSamples[currentAudio.audioFile]);
m_Soloud->setVolume(soloudHandle, currentAudio.volume);
m_Soloud->setPan(soloudHandle, currentAudio.pan);
m_Soloud->setRelativePlaySpeed(soloudHandle, currentAudio.speed);
SoLoud::handle soloudHandle;
if (!audioRequest.spatialized)
{
soloudHandle = m_Soloud->play(audio);
m_Soloud->setVolume(soloudHandle, audioRequest.volume);
m_Soloud->setPan(soloudHandle, audioRequest.pan);
m_Soloud->setRelativePlaySpeed(soloudHandle, audioRequest.speed);
m_Soloud->setLooping(soloudHandle, audioRequest.Loop);
}
else
{
const Vector3& position = audioRequest.position;
soloudHandle = m_Soloud->play3d(audio, position.x, position.y, position.z);
m_Soloud->set3dSourceMinMaxDistance(soloudHandle, audioRequest.MinDistance, audioRequest.MaxDistance);
m_Soloud->set3dSourceAttenuation(soloudHandle, 1, audioRequest.AttenuationFactor);
m_Soloud->setLooping(soloudHandle, audioRequest.Loop);
}
m_ActiveClips[audioRequest.audioFile] = soloudHandle;
// Remove item from queue.
m_AudioQueue.pop();
}
}
}
void AudioManager::CleanupInactiveVoices()
{
if (m_ActiveClips.empty())
{
return;
}
std::erase_if(m_ActiveClips, [this](const auto& item)
{
return !m_Soloud->isValidVoiceHandle(item.second);
});
}
}

View File

@@ -1,25 +1,17 @@
#pragma once
#include "src/Core/Core.h"
#include <src/Core/Maths.h>
#include <mutex>
#include <thread>
namespace SoLoud
{
class Soloud;
class AudioSource;
}
// Temp code
struct AudioRequest
{
std::string audioFile;
float volume = 1.0f;
float pan = 0.0f;
float speed = 1.0f;
};
namespace SoLoud
{
class Wav;
@@ -27,6 +19,20 @@ namespace SoLoud
namespace Nuake
{
struct AudioRequest
{
std::string audioFile;
float volume = 1.0f;
float pan = 0.0f;
float speed = 1.0f;
bool spatialized = false;
Vector3 position;
float MinDistance = 1.0f;
float MaxDistance = 25.0f;
float AttenuationFactor = 1.0f;
bool Loop = false;
};
// This is a singleton that manages everything for audio.
class AudioManager
{
@@ -41,7 +47,13 @@ namespace Nuake
std::atomic<bool> m_AudioQueued = { false };
std::queue<AudioRequest> m_AudioQueue;
Vector3 m_ListenerPosition;
Vector3 m_ListenerDirection;
Vector3 m_ListenerUp;
std::unordered_map<std::string, SoLoud::Wav> m_WavSamples;
std::unordered_map<std::string, unsigned int> m_ActiveClips;
public:
AudioManager();
~AudioManager();
@@ -59,12 +71,20 @@ namespace Nuake
float GetVolume() const;
void SetVolume(float volume);
void SetListenerPosition(const Vector3& position, const Vector3& direction, const Vector3& up);
void PlayTTS(const std::string& text);
void QueueWavAudio(const AudioRequest& request);
void UpdateVoice(const AudioRequest & request);
void StopVoice(const std::string& filePath);
bool IsWavLoaded(const std::string& filePath) const;
bool IsVoiceActive(const std::string & voice) const;
void LoadWavAudio(const std::string& filePath);
private:
void AudioThreadLoop();
void CleanupInactiveVoices();
};
}

View File

@@ -192,7 +192,7 @@ namespace Nuake
Ref<File> FileSystem::GetFile(const std::string& path)
{
// Note, Might be broken on other platforms.
auto& splits = String::Split(path, '/');
auto splits = String::Split(path, '/');
int currentDepth = -1;
std::string currentDirName = ".";

View File

@@ -338,7 +338,7 @@ namespace Nuake
settings->mPredictiveContactDistance = 0.01f;
settings->mShape = GetJoltShape(cc->Shape);
auto& joltPosition = JPH::Vec3(cc->Position.x, cc->Position.y, cc->Position.z);
auto joltPosition = JPH::Vec3(cc->Position.x, cc->Position.y, cc->Position.z);
const Quat& bodyRotation = cc->Rotation;
const auto& joltRotation = JPH::Quat(bodyRotation.x, bodyRotation.y, bodyRotation.z, bodyRotation.w);
@@ -487,14 +487,18 @@ namespace Nuake
if(ts > minStepDuration)
{
#ifdef NK_DEBUG
Logger::Log("Large step detected: " + std::to_string(ts), "physics", WARNING);
#endif
collisionSteps = static_cast<float>(ts) / minStepDuration;
}
#ifdef NK_DEBUG
if (collisionSteps >= maxStepCount)
{
Logger::Log("Very large step detected: " + std::to_string(ts), "physics", WARNING);
}
#endif
// Prevents having too many steps and running out of jobs
collisionSteps = std::min(collisionSteps, maxStepCount);
@@ -502,7 +506,6 @@ namespace Nuake
// Step the world
try
{
// TODO: Potential memory leak with new keyword.
auto joltTempAllocator = CreateRef<JPH::TempAllocatorMalloc>();
JPH::CharacterVirtual::ExtendedUpdateSettings joltUpdateSettings;
@@ -563,11 +566,6 @@ namespace Nuake
if (!_registeredCharacters.empty())
{
for (auto& character : _registeredCharacters)
{
//character.second->RemoveFromPhysicsSystem();
}
_registeredCharacters.clear();
}
}

View File

@@ -34,7 +34,6 @@ namespace Nuake {
template<typename T>
void Push(unsigned int count)
{
static_assert(false);
}
template<>

View File

@@ -21,12 +21,12 @@ namespace Nuake
_ssaoFramebuffer = CreateRef<FrameBuffer>(false, Vector2(_size));
auto& renderTarget = CreateRef<Texture>(_size, GL_RGBA, GL_RGBA16F, GL_FLOAT);
auto renderTarget = CreateRef<Texture>(_size, GL_RGBA, GL_RGBA16F, GL_FLOAT);
_ssaoFramebuffer->SetTexture(renderTarget, GL_COLOR_ATTACHMENT0);
_ssaoBlurFramebuffer = CreateRef<FrameBuffer>(false, Vector2(_size));
auto& renderTargetBlur = CreateRef<Texture>(_size, GL_RGBA, GL_RGBA16F, GL_FLOAT);
auto renderTargetBlur = CreateRef<Texture>(_size, GL_RGBA, GL_RGBA16F, GL_FLOAT);
_ssaoBlurFramebuffer->SetTexture(renderTargetBlur);
}

View File

@@ -95,7 +95,7 @@ namespace Nuake
float lineHeight = 0.0f;
for (char const& c : str)
{
Char& letter = style.font->GetChar((int)c);
Char letter = style.font->GetChar((int)c);
if (letter.PlaneBounds.top - letter.PlaneBounds.bottom > lineHeight)
lineHeight = letter.PlaneBounds.top - letter.PlaneBounds.bottom;
@@ -104,7 +104,7 @@ namespace Nuake
float advance = 0.0f;
for (char const& c : str)
{
Char& letter = style.font->GetChar((int)c);
Char letter = style.font->GetChar((int)c);
advance += letter.Advance * style.fontSize;
}
return Vector2(advance, lineHeight * style.fontSize);
@@ -121,7 +121,7 @@ namespace Nuake
float lineHeight = 0.0f;
for (char const& c : str)
{
Char& letter = style.font->GetChar((int)c);
Char letter = style.font->GetChar((int)c);
if (letter.PlaneBounds.top - letter.PlaneBounds.bottom > lineHeight)
lineHeight = letter.PlaneBounds.top - letter.PlaneBounds.bottom;
@@ -130,7 +130,7 @@ namespace Nuake
float advance = 0.0f;
for (char const& c : str)
{
Char& letter = style.font->GetChar((int)c);
Char letter = style.font->GetChar((int)c);
Matrix4 mat = glm::translate(model, Vector3(advance, (-(letter.PlaneBounds.top ) + (lineHeight)) * style.fontSize, 0.f));
float scaleX = letter.PlaneBounds.right - letter.PlaneBounds.left;

View File

@@ -235,7 +235,7 @@ namespace Nuake
if (!visibility.Visible || !sprite.SpriteMesh)
continue;
auto& finalQuadTransform = transform.GetGlobalTransform();
auto finalQuadTransform = transform.GetGlobalTransform();
if (sprite.Billboard)
{
finalQuadTransform = glm::inverse(mView);
@@ -358,7 +358,7 @@ namespace Nuake
if (!visibility.Visible || !sprite.SpriteMesh)
continue;
auto& finalQuadTransform = transform.GetGlobalTransform();
auto finalQuadTransform = transform.GetGlobalTransform();
if (sprite.Billboard)
{
finalQuadTransform = glm::inverse(mView);

View File

@@ -71,7 +71,7 @@ namespace Nuake
{
m_RendererId = 0;
int channels = 0;
m_LocalBuffer = stbi_load_from_memory(data, len, &m_Width, &m_Height, &channels, 0);
m_LocalBuffer = stbi_load_from_memory(data, len, &m_Width, &m_Height, &channels, 4);
glGenTextures(1, &m_RendererId);
glBindTexture(GL_TEXTURE_2D, m_RendererId);
glGenerateMipmap(GL_TEXTURE_2D);

View File

@@ -0,0 +1,12 @@
#pragma once
#include "src/Resource/Resource.h"
namespace Nuake {
class AudioResource : public Resource
{
public:
std::string Path;
};
}

View File

@@ -147,7 +147,7 @@ namespace Nuake
SkeletonNode rootSkeletonNode;
ProcessAnimationNode(rootSkeletonNode, scene->mRootNode);
model->SetSkeletonRootNode(std::move(rootSkeletonNode));
model->SetSkeletonRootNode(rootSkeletonNode);
model->SetAnimations(std::move(animations));
}
@@ -189,10 +189,10 @@ namespace Nuake
Ref<SkinnedMesh> ModelLoader::ProcessSkinnedMesh(aiMesh* node, const aiScene* scene)
{
auto& vertices = ProcessSkinnedVertices(node);
auto& indices = ProcessIndices(node);
auto& material = ProcessMaterials(scene, node);
auto& bones = std::vector<Bone>();
auto vertices = ProcessSkinnedVertices(node);
auto indices = ProcessIndices(node);
auto material = ProcessMaterials(scene, node);
auto bones = std::vector<Bone>();
if (node->HasBones())
{

View File

@@ -1,13 +1,20 @@
#include "AudioEmitterComponent.h"
namespace Nuake {
json AudioEmitterComponent::Serialize()
{
BEGIN_SERIALIZE();
SERIALIZE_VAL(FilePath);
SERIALIZE_VAL(IsPlaying);
SERIALIZE_VAL(Volume);
SERIALIZE_VAL(Pan);
SERIALIZE_VAL(PlaybackSpeed);
SERIALIZE_VAL(Spatialized);
SERIALIZE_VAL(MinDistance);
SERIALIZE_VAL(MaxDistance);
SERIALIZE_VAL(AttenuationFactor);
SERIALIZE_VAL(Loop);
END_SERIALIZE();
}
@@ -15,8 +22,14 @@ namespace Nuake {
{
DESERIALIZE_VAL(FilePath);
DESERIALIZE_VAL(Volume);
DESERIALIZE_VAL(IsPlaying);
DESERIALIZE_VAL(Pan);
DESERIALIZE_VAL(PlaybackSpeed);
DESERIALIZE_VAL(Spatialized);
DESERIALIZE_VAL(MinDistance);
DESERIALIZE_VAL(MaxDistance);
DESERIALIZE_VAL(AttenuationFactor);
DESERIALIZE_VAL(Loop);
return true;
}
}

View File

@@ -7,11 +7,19 @@ namespace Nuake {
class AudioEmitterComponent
{
public:
std::string FilePath;
bool IsPlaying = false;
bool Loop = false;
float Volume = 1.0f;
float Pan = 0.0f;
float PlaybackSpeed = 1.0f;
bool IsPlaying = false;
std::string FilePath;
bool Spatialized = false;
float MinDistance = 1.0f;
float MaxDistance = 10.0f;
float AttenuationFactor = 1.0f;
json Serialize();
bool Deserialize(const json& j);

View File

@@ -464,7 +464,7 @@ namespace Nuake
if (!parentComponent.HasParent)
continue;
auto& entity = Entity{ e, this };
auto entity = Entity{ e, this };
auto parentEntity = GetEntityByID(parentComponent.ParentID);
parentEntity.AddChild(entity);
}

View File

@@ -80,11 +80,6 @@ namespace Nuake
Ref<Environment> GetEnvironment() const;
void SetEnvironment(Ref<Environment> env);
template<class T>
Ref<T> GetResource(const UUID& uuid)
{
return m_Resources[uuid];
}
bool Save();
bool SaveAs(const std::string& path);

View File

@@ -47,7 +47,7 @@ namespace Nuake
{
auto& animationTrack = animation->GetTrack(bone.Name);
Entity& boneEnt = m_Scene->GetEntityByID(bone.EntityHandle);
Entity boneEnt = m_Scene->GetEntityByID(bone.EntityHandle);
if (boneEnt.IsValid())
{
auto& transformComponent = boneEnt.GetComponent<TransformComponent>();

View File

@@ -1,5 +1,6 @@
#include "AudioSystem.h"
#include "Engine.h"
#include "src/Scene/Scene.h"
#include "src/Scene/Entities/Entity.h"
#include "src/Scene/Components/AudioEmitterComponent.h"
@@ -23,6 +24,19 @@ namespace Nuake
void AudioSystem::Update(Timestep ts)
{
auto& audioManager = AudioManager::Get();
// Update 3D listener of the audio system
auto currentCamera = m_Scene->GetCurrentCamera();
Vector3 direction = currentCamera->GetDirection();
if (Engine::IsPlayMode())
{
direction *= Vector3(-1, -1, -1);
}
audioManager.SetListenerPosition(currentCamera->GetTranslation(), std::move(direction), currentCamera->GetUp());
auto view = m_Scene->m_Registry.view<TransformComponent, AudioEmitterComponent>();
for (auto& e : view)
{
@@ -30,21 +44,50 @@ namespace Nuake
if (audioEmitterComponent.FilePath.empty())
{
// Doesn't have a file
continue;
}
if (audioEmitterComponent.IsPlaying)
const bool isPlaying = audioEmitterComponent.IsPlaying;
const std::string absoluteFilePath = FileSystem::RelativeToAbsolute(audioEmitterComponent.FilePath);
const bool isVoiceActive = audioManager.IsVoiceActive(absoluteFilePath);
AudioRequest audioRequest;
audioRequest.audioFile = absoluteFilePath;
audioRequest.pan = audioEmitterComponent.Pan;
audioRequest.volume = audioEmitterComponent.Volume;
audioRequest.speed = audioEmitterComponent.PlaybackSpeed;
audioRequest.spatialized = audioEmitterComponent.Spatialized;
audioRequest.Loop = audioEmitterComponent.Loop;
audioRequest.position = transformComponent.GetGlobalTransform()[3];
audioRequest.MinDistance = audioEmitterComponent.MinDistance;
audioRequest.MaxDistance = audioEmitterComponent.MaxDistance;
audioRequest.AttenuationFactor = audioEmitterComponent.AttenuationFactor;
if (isVoiceActive)
{
const std::string absoluteFilePath = FileSystem::RelativeToAbsolute(audioEmitterComponent.FilePath);
AudioRequest audioRequest;
audioRequest.audioFile = absoluteFilePath;
audioRequest.pan = audioEmitterComponent.Pan;
audioRequest.volume = audioEmitterComponent.Volume;
audioRequest.speed = audioEmitterComponent.PlaybackSpeed;
AudioManager::Get().QueueWavAudio(std::move(audioRequest));
audioEmitterComponent.IsPlaying = false;
if (!isPlaying && audioEmitterComponent.Loop)
{
audioManager.StopVoice(absoluteFilePath); // Stop audio
}
else
{
// Update the active voice with new params
audioManager.UpdateVoice(audioRequest);
}
}
else if (isPlaying)
{
// Reset the play status to false since the audio has been fired
if (!audioEmitterComponent.Loop)
{
audioManager.QueueWavAudio(std::move(audioRequest));
audioEmitterComponent.IsPlaying = false;
}
else if (!isVoiceActive)
{
audioManager.QueueWavAudio(std::move(audioRequest));
}
}
}
}

View File

@@ -19,7 +19,7 @@ namespace Nuake
void ParticleSystem::Update(Timestep ts)
{
auto& view = m_Scene->m_Registry.view<TransformComponent, ParticleEmitterComponent>();
auto view = m_Scene->m_Registry.view<TransformComponent, ParticleEmitterComponent>();
for (auto& e : view)
{
auto [transformComponent, emitterComponent] = view.get<TransformComponent, ParticleEmitterComponent>(e);
@@ -42,7 +42,7 @@ namespace Nuake
void ParticleSystem::FixedUpdate(Timestep ts)
{
auto& view = m_Scene->m_Registry.view<TransformComponent, ParticleEmitterComponent>();
auto view = m_Scene->m_Registry.view<TransformComponent, ParticleEmitterComponent>();
for (auto& e : view)
{
auto [transformComponent, emitterComponent] = view.get<TransformComponent, ParticleEmitterComponent>(e);

View File

@@ -15,7 +15,7 @@ namespace Nuake {
Logger::Log("Initializing ScriptingSystem");
auto& entities = m_Scene->m_Registry.view<WrenScriptComponent>();
auto entities = m_Scene->m_Registry.view<WrenScriptComponent>();
for (auto& e : entities)
{
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);

View File

@@ -25,7 +25,7 @@ namespace Nuake
{
bool hasFoundModule = false;
auto& splits = String::Split(fileContent, ' ');
auto splits = String::Split(fileContent, ' ');
for (unsigned int i = 0; i < splits.size(); i++)
{
std::string s = splits[i];

View File

@@ -22,14 +22,14 @@ int ApplicationMain(int argc, char* argv[])
if (!FileSystem::FileExists(projectPath))
{
Logger::Log("game.project not found", "runtime", CRITICAL);
return;
return -1;
}
const std::string& projectfileContent = FileSystem::ReadFile(projectPath, true);
if (projectfileContent.empty())
{
Logger::Log("game.project was empty", "runtime", CRITICAL);
return;
return -1;
}
project->Deserialize(json::parse(projectfileContent));
@@ -90,7 +90,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR cdmline, int cmds
#else
void main(int argc, char* argv[])
int main(int argc, char* argv[])
{
return ApplicationMain(argc, argv);
}

View File

@@ -73,7 +73,7 @@ project "Nuake"
}
filter "system:windows"
cppdialect "C++17"
cppdialect "C++20"
staticruntime "On"
defines {
"NK_WIN"
@@ -154,7 +154,7 @@ project "NuakeRuntime"
}
filter "system:windows"
cppdialect "C++17"
cppdialect "C++20"
staticruntime "On"
defines {
"NK_WIN"
@@ -243,7 +243,7 @@ project "Editor"
}
filter "system:windows"
cppdialect "C++17"
cppdialect "C++20"
staticruntime "On"
filter "configurations:Debug"