Răsfoiți Sursa

Decoupled FMOD studio from AudioScene (moved it to AudioSystem), thus allowing multiple creation and destruction of AudioScenes without recreating FMOD core and studio
Added volume parameters of different audio types in AudioSystem and AudioScene
Added support and detection for buses of different audio types in AudioSystem
Added automatic detection for sound events of different types of impacts (created in FMOD studio) in AudioScene
Added world transform matrix storage in CollisionEventComponent after a collision has occured, for use in AudioScene for settings 3D attributes of impact sounds
Added more ErrorCodes and error strings
Fixed a bug of a loud noise playing for a split second after starting a SoundComponent audio (the 3D attributes of a sound would only be set the next frame, after starting a sound for the first time) in AudioScene
Fixed a bug of setting the data of a wrong member of pair of collided objects in CollisionEvenComponent
Fixed a bug of calling the setup method of a SystemScene before calling setup on the System itself in SceneLoader

Paul A 2 ani în urmă
părinte
comite
d01f1e313b

+ 63 - 1
Praxis3D/Data/Maps/componentTest.pmap

@@ -162,7 +162,7 @@
 			{
 				"ImpactSoundComponent":
 				{
-					"Type" : "Box"
+					"Type" : "Concrete"
 				},
 				"SoundComponent":
 				{
@@ -238,6 +238,68 @@
 				}
 			}
 		},
+		{
+			"ID": "55",
+			"Name": "Sound1",
+			"Parent": "0",
+			"Audio":
+			{
+				"SoundComponent":
+				{
+					"Filename": "Spinning out.wav",
+					"Type": "Music",
+					"Spatialized": "true",
+					"Loop": "true",
+					"StartPlaying": "true",
+					"Volume": "0.5f"
+				}
+			},
+			"World":
+			{
+				"ObjectMaterialComponent":
+				{
+					"Type": "Wood"
+				},
+				"SpatialComponent":
+				{
+					"LocalPosition": "20.0f, 5.0f, 0.0f",
+					"LocalRotation": "0.0f, 0.0f, 0.0f"
+				}
+			},
+			"Rendering":
+			{
+				"ModelComponent":
+				{
+					"Models":
+					[
+						{
+							"Filename": "sphereNew4.3DS",
+							"Meshes":
+							[
+								{
+									"Index": "0",
+									"AlphaThreshold": "0.0f",
+									"HeightScale": "0.0f",
+									"Materials":
+									{
+										"Diffuse":
+										{
+											"Filename": "test_albedoGold.png",
+											"TextureScale": "1.0f, 1.0f"
+										},
+										"RMHAO":
+										{
+											"Filename": "test1_RM.png",
+											"TextureScale": "1.0f, 1.0f"
+										}
+									}
+								}
+							]
+						}
+					]
+				}
+			}
+		},
 		{
 			"ID": "4",
 			"Name": "Sphere 1",

+ 1 - 0
Praxis3D/Data/error-strings-eng.data

@@ -8,6 +8,7 @@
 		"Initialize_failure"								: "Failed to initialized",
 		"File_not_found"										: "File missing",
 		"Filename_empty"										: "Filename is empty",
+		"Audio_invalid_bus_type"						: "Trying to assign an invalid audio bus type",
 		"Audio_no_drivers"									: "System has no sound devices",
 		"Audio_system_init_failed"					: "Audio system has failed to initialize",
 		"Destroy_obj_not_found"							: "Destruction: object not found",

+ 148 - 287
Praxis3D/Source/AudioScene.cpp

@@ -1,5 +1,7 @@
+#include <glm/gtc/type_ptr.hpp>
 
 #include "AudioScene.h"
+#include "AudioSystem.h"
 #include "ComponentConstructorInfo.h"
 #include "NullSystemObjects.h"
 #include "TaskManagerLocator.h"
@@ -10,180 +12,34 @@ AudioScene::AudioScene(SystemBase *p_system, SceneLoader *p_sceneLoader) : Syste
 	m_audioTask = nullptr;
 	m_coreSystem = nullptr;
 	m_studioSystem = nullptr;
-	m_masterChannelGroup = nullptr;
-	m_ambientChannelGroup = nullptr;
-	m_sfxChannelGroup = nullptr;
-	m_musicChannelGroup = nullptr;
-	m_impactBank = nullptr;
-	m_defaultImpactSoundsLoaded = false;
-	m_numSoundDrivers = 0;
-
-	m_lastPlayedImpactSound = 0;
-	m_distribution = std::uniform_real_distribution<float>(0.5f, 1.5f);
-
-	m_dTime = 0.0f;
+
+	volume_ambient = 0.0f;
+	volume_master = 0.0f;
+	volume_music = 0.0f;
+	volume_sfx = 0.0f;
+
+	for(unsigned int i = 0; i < ObjectMaterialType::NumberOfMaterialTypes; i++)
+		m_impactEvents[i] = nullptr;
+
+	// Get audio system
+	m_audioSystem = static_cast<AudioSystem *>(p_system);
 }
 
 AudioScene::~AudioScene()
 {
-	if(m_studioSystem != nullptr)
-	{
-		if(m_coreSystem != nullptr)
-			m_coreSystem->release();
-
-		m_studioSystem->release();
-	}
+	deactivate();
 }
 
 ErrorCode AudioScene::init()
 {
 	ErrorCode returnError = ErrorCode::Success;
 
+	// Create audio task, required for task scheduler to call update of this scene
 	m_audioTask = new AudioTask(this);
 
-	// Create the FMOD studio system
-	auto fmodError = FMOD::Studio::System::create(&m_studioSystem);
-
-	// Check if the sound system was created successfully
-	if(fmodError != FMOD_OK)
-	{
-		ErrHandlerLoc::get().log(ErrorCode::Audio_system_init_failed, ErrorSource::Source_AudioScene);
-		returnError = ErrorCode::Audio_system_init_failed;
-	}
-	else
-	{
-		// Get the FMOD core system
-		m_studioSystem->getCoreSystem(&m_coreSystem);
-
-		// Get the number of sound drivers
-		m_coreSystem->getNumDrivers(&m_numSoundDrivers);
-
-		// Do not continue if there are no sound drivers
-		if(m_numSoundDrivers == 0)
-		{
-			ErrHandlerLoc::get().log(ErrorCode::Audio_no_drivers, ErrorSource::Source_AudioScene);
-			returnError = ErrorCode::Audio_no_drivers;
-		}
-		else
-		{
-			// Initialize our Instance with 36 Channels
-			m_studioSystem->initialize(Config::audioVar().num_audio_channels, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL | FMOD_INIT_VOL0_BECOMES_VIRTUAL | FMOD_INIT_3D_RIGHTHANDED, NULL);
-
-			m_coreSystem->createChannelGroup("music", &m_musicChannelGroup);
-
-			//fmodErrorLog(m_coreSystem->loadPlugin((Config::filepathVar().sound_path + "fmod_distance_filter.dll").c_str(), 0, 0));
-
-			//fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + "Master.bank").c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &m_testBank1));
-			//fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + "bmw_1m_s3.bank").c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &m_testBank1));
-			//fmodErrorLog(m_testBank1->loadSampleData());
-			//fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + "Master.strings.bank").c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &m_testBank1));
-			//fmodErrorLog(m_testBank1->loadSampleData());
-			//fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + "SFX.bank").c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &m_testBank1));
-
-			auto loadError = m_testBank1->loadSampleData();
-
-			if(loadError != FMOD_OK)
-			{
-				std::cout << "LOAD FAILED" << std::endl;
-			}
-
-			//m_testBank1->
-
-			int eventCount;
-
-			m_testBank1->getEventCount(&eventCount);
-
-			std::cout << "Event count: " << eventCount << std::endl;
-
-			FMOD::Studio::EventDescription *eventDescription[50];
-			//FMOD::Studio::EventInstance *eventInstance;
-
-			m_testBank1->getEventList(eventDescription, 50, &eventCount);
-
-			FMOD::Studio::EventDescription *description1;
-			FMOD::Studio::EventInstance *instance1;
-
-			auto error1 = m_studioSystem->getEvent("event:/Interactables/Wooden Collision", &description1);
-
-			if(error1 == FMOD_OK)
-			{
-				std::cout << "EVENT FOUND" << std::endl;
-				//description1->
-				description1->loadSampleData();
-				description1->createInstance(&m_eventInstance1);
-				m_eventInstance1->start();
-			}
-			else
-			{
-				std::cout << "EVENT NOT FOUND" << std::endl;
-			}
-
-			for(int i = 0; i < eventCount; i++)
-			{
-				char path[100];
-				int retrieved;
-
-				eventDescription[i]->getPath(path, 100, &retrieved);
-
-				//eventDescription[i]->
-
-				std::cout << path << std::endl;
-
-				//eventDescription[i]->loadSampleData();
-
-				int descrCount;
-				eventDescription[i]->getParameterDescriptionCount(&descrCount);
-
-				FMOD_STUDIO_USER_PROPERTY paramDescr;
-				auto userPropError = eventDescription[i]->getUserProperty("Music_prop", &paramDescr);
-
-				if(userPropError == FMOD_OK)
-				{
-					std::cout << paramDescr.name << std::endl;
-
-					switch(paramDescr.type)
-					{
-					case FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER:
-						std::cout << paramDescr.intvalue << std::endl;
-						break;
-					case FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN:
-						std::cout << paramDescr.boolvalue << std::endl;
-						break;
-					case FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT:
-						std::cout << paramDescr.floatvalue << std::endl;
-						break;
-					case FMOD_STUDIO_USER_PROPERTY_TYPE_STRING:
-						std::cout << paramDescr.stringvalue << std::endl;
-						break;
-					}
-				}
-
-				//for(int i = 0; i < descrCount; i++)
-				//{
-				//	FMOD_STUDIO_PARAMETER_DESCRIPTION *paramDescr = nullptr;
-				//	eventDescription[i]->getParameterDescriptionByIndex(i, paramDescr);
-
-				//	std::cout << paramDescr->name << std::endl;
-				//}
-
-				//auto instanceError = eventDescription[i]->createInstance(&m_eventInstance1);
-				//if(instanceError != FMOD_OK)
-				//{
-				//	std::cout << "CREATE INSTANCE FAILED" << std::endl;
-				//}
-				//else
-				{
-					//auto startError = m_eventInstance1->start();
-					//if(startError != FMOD_OK)
-					//{
-					//	std::cout << "START FAILED" << std::endl;
-					//}
-				}
-
-				//std::cout << i << ": Path: " << path << std::endl;
-			}
-		}
-	}
+	// Get the handles to FMOD studio and core systems
+	m_studioSystem = m_audioSystem->getStudioSystem();
+	m_coreSystem = m_audioSystem->getCoreSystem();
 
 	return returnError;
 }
@@ -200,17 +56,6 @@ ErrorCode AudioScene::setup(const PropertySet &p_properties)
 	worldScene->reserve<SoundComponent>(std::max(Config::objectPoolVar().sound_component_default_pool_size, objectPoolSizeProperty.getPropertyByID(Properties::SoundComponent).getInt()));
 	worldScene->reserve<SoundListenerComponent>(std::max(Config::objectPoolVar().sound_listener_component_default_pool_size, objectPoolSizeProperty.getPropertyByID(Properties::SoundListenerComponent).getInt()));
 
-	FMOD::Studio::Bank *defaultSoundBank = nullptr;
-
-	// Load default sound bank
-	if(fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + Config::audioVar().default_sound_bank).c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &defaultSoundBank), Config::audioVar().default_sound_bank))
-		if(fmodErrorLog(defaultSoundBank->loadSampleData(), Config::audioVar().default_sound_bank))
-			addImpactSoundBank(defaultSoundBank);
-
-	// Load default string bank
-	if(fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + Config::audioVar().default_sound_bank_string).c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &defaultSoundBank), Config::audioVar().default_sound_bank_string))
-		fmodErrorLog(defaultSoundBank->loadSampleData(), Config::audioVar().default_sound_bank_string);
-
 	auto const &banksProperty = p_properties.getPropertySetByID(Properties::Banks);
 	if(banksProperty)
 	{
@@ -224,10 +69,10 @@ ErrorCode AudioScene::setup(const PropertySet &p_properties)
 
 				FMOD::Studio::Bank *soundBank = nullptr;
 
-				if(fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + filename).c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &soundBank), filename))
+				if(AudioSystem::fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + filename).c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &soundBank), filename))
 				{
-					if(fmodErrorLog(soundBank->loadSampleData(), filename))
-						addImpactSoundBank(soundBank);
+					if(AudioSystem::fmodErrorLog(soundBank->loadSampleData(), filename))
+						m_audioSystem->addImpactSoundBank(soundBank);
 
 					m_bankFilenames.push_back(std::make_pair(filename, soundBank));
 				}
@@ -235,57 +80,31 @@ ErrorCode AudioScene::setup(const PropertySet &p_properties)
 		}
 	}
 
-	// Load default impact sound bank for basic object impact sounds
-	//if(fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + Config::audioVar().default_impact_sound_bank).c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &m_impactBank), Config::audioVar().default_impact_sound_bank))
-	//{
-	//	m_defaultImpactSoundsLoaded = true;
+	for(unsigned int materialTypeIndex = 0; materialTypeIndex < ObjectMaterialType::NumberOfMaterialTypes; materialTypeIndex++)
+	{
+		std::string materialTypeString = GetString(static_cast<ObjectMaterialType>(materialTypeIndex));
 
-	//	// Load default impact sound bank to memory
-	//	if(fmodErrorLog(m_impactBank->loadSampleData(), Config::audioVar().default_impact_sound_bank))
+		for(auto &sound : m_audioSystem->m_impactSounds)
+		{
+			if(sound.first == materialTypeString)
+			{
+				std::cout << "found sound: " << sound.first << std::endl;
+				m_impactEvents[materialTypeIndex] = sound.second;
+				break;
+			}
+		}
+	}
+	
+	//FMOD::Studio::Bank *soundBank = nullptr;
+	//if(AudioSystem::fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + "Music.bank").c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &soundBank), "Music.bank"))
+	//{
+	//	if(AudioSystem::fmodErrorLog(soundBank->loadSampleData(), "Music.bank"))
 	//	{
-	//		addImpactSoundBank(m_impactBank);
-	//		for(int i = 0; i < ObjectMaterialType::NumberOfMaterialTypes; i++)
-	//		{
-	//			std::string eventName = GetString(static_cast<ObjectMaterialType>(i));
-	//			std::string fullEventName = "event:/" + eventName;
-	//			fmodErrorLog(m_studioSystem->getEvent(fullEventName.c_str(), &m_impactEvents[i]), eventName);
-	//		}
+	//		std::cout << "Music.bank loaded" << std::endl;
 	//	}
-
-	//	m_studioSystem->getEvent("event:/Metal", &m_eventDescr1);
-	//	m_eventDescr1->createInstance(&m_eventInstance1);
 	//}
 
-	FMOD_MODE mode = FMOD_LOOP_OFF | FMOD_3D | FMOD_3D_WORLDRELATIVE | FMOD_3D_INVERSEROLLOFF;
-
-	for(unsigned int i = 0; i < ObjectMaterialType::NumberOfMaterialTypes; i++)
-	{
-		m_collisionSounds[i].m_filename = "Footsteps_MetalV1_Jump_Land_02.wav";
-
-		m_coreSystem->createSound((Config::filepathVar().sound_path + m_collisionSounds[i].m_filename).c_str(), mode, nullptr, &m_collisionSounds[i].m_sound);
-	}
-
-	m_coreSystem->createChannelGroup("sfx", &m_sfxChannelGroup);
-
-	m_coreSystem->createDSPByType(FMOD_DSP_TYPE::FMOD_DSP_TYPE_PITCHSHIFT, &m_pitch);
-	m_sfxChannelGroup->addDSP(0, m_pitch);
-
-	m_coreSystem->createSound((Config::filepathVar().sound_path + "metal_solid_impact_soft1.wav").c_str(), FMOD_LOOP_OFF | FMOD_2D, nullptr, &m_metalImpactSound[0]);
-	m_coreSystem->createSound((Config::filepathVar().sound_path + "metal_solid_impact_soft2.wav").c_str(), FMOD_LOOP_OFF | FMOD_2D, nullptr, &m_metalImpactSound[1]);
-	m_coreSystem->createSound((Config::filepathVar().sound_path + "metal_solid_impact_soft3.wav").c_str(), FMOD_LOOP_OFF | FMOD_2D, nullptr, &m_metalImpactSound[2]);
-
-	m_coreSystem->playSound(m_metalImpactSound[0], m_sfxChannelGroup, true, &m_metalImpactChannel[0]);
-	//m_coreSystem->playSound(m_metalImpactSound[1], m_sfxChannelGroup, false, &m_metalImpactChannel[1]);
-	//m_coreSystem->playSound(m_metalImpactSound[2], m_sfxChannelGroup, false, &m_metalImpactChannel[2]);
-
-	std::cout << "EVENT NAMES:" << std::endl;
-	for(auto &it : m_impactSounds)
-	{
-		// Do stuff
-		std::cout << it.first << std::endl;
-	}
-
-	loadParameterGUIDs();
+	//loadParameterGUIDs();
 
 	return ErrorCode::Success;
 }
@@ -317,6 +136,7 @@ void AudioScene::deactivate()
 	// Get the entity registry 
 	auto &entityRegistry = static_cast<WorldScene*>(m_sceneLoader->getSystemScene(Systems::World))->getEntityRegistry();
 
+	// Stop all audio from Sound Components (FMOD CORE)
 	auto soundComponentView = entityRegistry.view<SoundComponent>();
 	for(auto entity : soundComponentView)
 	{
@@ -331,58 +151,28 @@ void AudioScene::deactivate()
 			}
 		}
 	}
+
+	// Stop all audio going through master bus (FMOD STUDIO)
+	m_audioSystem->getBus(AudioBusType::AudioBusType_Master)->stopAllEvents(FMOD_STUDIO_STOP_MODE::FMOD_STUDIO_STOP_IMMEDIATE);
 }
 
 void AudioScene::update(const float p_deltaTime)
 {
-	m_dTime += p_deltaTime;
-
-	FMOD_STUDIO_PLAYBACK_STATE playbackState;
-	m_eventInstance1->getPlaybackState(&playbackState);
-	if(playbackState != FMOD_STUDIO_PLAYBACK_STATE::FMOD_STUDIO_PLAYBACK_PLAYING)
-	{
-		//m_eventInstance1->setParameterByName("Speed", 4.0f);
-		//m_eventInstance1->setParameterByName("Box", 1.0f);
-		//m_eventInstance1->start();
-	}
-	
-	if(m_dTime > 1.0f)
-	{
-		m_dTime -= 1.0f;
+	//FMOD::Studio::EventDescription *musicDescription;
+	//m_studioSystem->getEvent("event:/MainMenuMusic", &musicDescription);
 
-		FMOD::Studio::EventInstance *eventInstance;
-
-		m_eventDescr1->createInstance(&eventInstance);
-
-		eventInstance->setParameterByName("Speed", 4.0f);
-		eventInstance->setParameterByName("Barrel", 1.0f);
-		//eventInstance->start();
-		//eventInstance->release();
-
-	}
+	//int instanceCount = 0;
+	//musicDescription->getInstanceCount(&instanceCount);
 
-	bool metalImpactPlaying = false;
-	m_metalImpactChannel[0]->isPlaying(&metalImpactPlaying);
-	if(!metalImpactPlaying)
-	{
-		std::uniform_real_distribution<float> dis(0.95f, 1.05f);
-		std::uniform_int_distribution<int> dis2(0, 2);
-
-		float randomPitch = dis(m_randomEngine);
-		int randomSound = dis2(m_randomEngine);
-
-		while(randomSound == m_lastPlayedImpactSound)
-		{
-			randomSound = dis2(m_randomEngine);
-		}
-
-		//std::cout << "random sound: " << randomSound << std::endl;
+	//if(instanceCount == 0)
+	//{
+	//	FMOD::Studio::EventInstance *eventInstance;
 
-		m_lastPlayedImpactSound = randomSound;
+	//	musicDescription->createInstance(&eventInstance);
 
-		m_pitch->setParameterFloat(0, randomPitch);
-		//m_coreSystem->playSound(m_metalImpactSound[randomSound], m_sfxChannelGroup, false, &m_metalImpactChannel[0]);
-	}
+	//	eventInstance->start();
+	//	eventInstance->release();
+	//}
 
 	// Get double buffering FRONT index
 	auto frontIndex = ClockLocator::get().getDoubleBufferingIndexFront();
@@ -393,6 +183,11 @@ void AudioScene::update(const float p_deltaTime)
 	// Get the entity registry 
 	auto &entityRegistry = worldScene->getEntityRegistry();
 
+	//	 ___________________________
+	//	|							|
+	//	|	SOUND LISTENER UPDATE	|
+	//	|___________________________|
+	//
 	// Find the first active sound listener and get its spatial component
 	auto listenerSpatialComponentView = entityRegistry.view<SoundListenerComponent, SpatialComponent>();
 	for(auto entity : listenerSpatialComponentView)
@@ -407,20 +202,27 @@ void AudioScene::update(const float p_deltaTime)
 
 			// Get the world matrix of the camera
 			auto &worldTransform = listenerSpatialComponent.getSpatialDataChangeManager().getWorldTransform();
+			auto const worldTranslate = glm::mat3(worldTransform);
 
 			// Calculate all 3D listener attributes
-			FMOD_VECTOR position = Math::toFmodVector(worldTransform[3]);
-			FMOD_VECTOR velocity = Math::toFmodVector(listenerSpatialComponent.getSpatialDataChangeManager().getVelocity());
-			FMOD_VECTOR forwardDirection = Math::toFmodVector(glm::vec3(0.0f, 0.0f, -1.0f) * glm::mat3(worldTransform));
-			FMOD_VECTOR upDirection = Math::toFmodVector(glm::vec3(0.0f, 1.0f, 0.0f) * glm::mat3(worldTransform));
+			FMOD_3D_ATTRIBUTES spatialAttributes;
+			spatialAttributes.position = Math::toFmodVector(worldTransform[3]);
+			spatialAttributes.velocity = Math::toFmodVector(listenerSpatialComponent.getSpatialDataChangeManager().getVelocity());
+			spatialAttributes.forward = Math::toFmodVector(glm::vec3(0.0f, 0.0f, -1.0f) * worldTranslate);
+			spatialAttributes.up = Math::toFmodVector(glm::vec3(0.0f, 1.0f, 0.0f) * worldTranslate);
 
 			// Update the listener
-			m_coreSystem->set3DListenerAttributes(listenerComponent.m_listenerID, &position, &velocity, &forwardDirection, &upDirection);
+			m_studioSystem->setListenerAttributes(listenerComponent.m_listenerID, &spatialAttributes);
 
 			break;
 		}
 	}
 
+	//	 ___________________________
+	//	|							|
+	//	|  SOUND COMPONENTS UPDATE	|
+	//	|___________________________|
+	//
 	auto soundComponentView = entityRegistry.view<SoundComponent>();
 	for(auto entity : soundComponentView)
 	{
@@ -435,6 +237,19 @@ void AudioScene::update(const float p_deltaTime)
 					component.m_playing = true;
 					m_coreSystem->playSound(component.m_sound, 0, true, &component.m_channel);
 					component.m_channel->setVolume(component.m_volume);
+
+					if(component.m_spatialized)
+					{
+						auto spatialComponent = entityRegistry.try_get<SpatialComponent>(entity);
+						if(spatialComponent != nullptr)
+						{
+							FMOD_VECTOR velocity = Math::toFmodVector(spatialComponent->getSpatialDataChangeManager().getVelocity());
+							FMOD_VECTOR position = Math::toFmodVector(spatialComponent->getSpatialDataChangeManager().getWorldTransform()[3]);
+
+							component.m_channel->set3DAttributes(&position, &velocity);
+						}
+					}
+
 					component.m_channel->setPaused(false);
 				}
 			}
@@ -460,7 +275,12 @@ void AudioScene::update(const float p_deltaTime)
 			}
 		}
 	}	
-	
+
+	//	 ___________________________
+	//	|							|
+	//	|  COLLISION EVENTS UPDATE	|
+	//	|___________________________|
+	//
 	auto collisionEventMaterialView = worldScene->getEntityRegistry().view<CollisionEventComponent, ObjectMaterialComponent>();
 	for(auto entity : collisionEventMaterialView)
 	{
@@ -472,29 +292,70 @@ void AudioScene::update(const float p_deltaTime)
 
 			for(size_t i = 0, size = collisionComponent.m_numOfDynamicCollisions[frontIndex]; i < size; i++)
 			{
-				if(collisionComponent.m_dynamicCollisions[frontIndex][i].m_firstObjInCollisionPair)
+				//if(collisionComponent.m_dynamicCollisions[frontIndex][i].m_firstObjInCollisionPair)
 				{
-					FMOD_VECTOR position = Math::toFmodVector(collisionComponent.m_dynamicCollisions[frontIndex][i].m_position);
-					FMOD_VECTOR velocity = Math::toFmodVector(collisionComponent.m_dynamicCollisions[frontIndex][i].m_velocity);
-
-					float volume = glm::min(collisionComponent.m_dynamicCollisions[frontIndex][i].m_appliedImpulse / 200.0f, 1.0f);
-
-					FMOD::Channel *channel;
-					m_coreSystem->playSound(m_collisionSounds[materialComponent.getObjectMaterialType()].m_sound, 0, true, &channel);
-					channel->setVolume(volume);
-					channel->set3DAttributes(&position, &velocity);
-					channel->setPaused(false);
-
-					//m_eventInstance1->set3DAttributes()
-					//m_eventInstance1->start();
+					// Get the transform matrix
+					glm::mat4 transformMatrix;
+					collisionComponent.m_dynamicCollisions[frontIndex][i].m_worldTransform.getOpenGLMatrix(glm::value_ptr(transformMatrix));
+					const glm::mat3 translateMatrix = glm::mat3(transformMatrix);
+
+					// Get 3D attributes
+					FMOD_3D_ATTRIBUTES spatialAttributes;
+					spatialAttributes.position = Math::toFmodVector(transformMatrix[3]);
+					spatialAttributes.velocity = Math::toFmodVector(collisionComponent.m_dynamicCollisions[frontIndex][i].m_velocity);
+					spatialAttributes.forward = Math::toFmodVector(glm::vec3(0.0f, 0.0f, -1.0f) * translateMatrix);
+					spatialAttributes.up = Math::toFmodVector(glm::vec3(0.0f, 1.0f, 0.0f) * translateMatrix);
+					const float volume = glm::min(collisionComponent.m_dynamicCollisions[frontIndex][i].m_appliedImpulse / Config::audioVar().impact_impulse_volume_divider, Config::audioVar().impact_max_volume_threshold);
+
+					// Create an event (sound) instance
+					FMOD::Studio::EventInstance *eventInstance;
+					m_impactEvents[materialComponent.getObjectMaterialType()]->createInstance(&eventInstance);
+
+					// Set sound parameters and play the sound
+					eventInstance->setParameterByName("Impulse", collisionComponent.m_dynamicCollisions[frontIndex][i].m_appliedImpulse / Config::audioVar().impact_impulse_param_divider);
+					eventInstance->setVolume(volume);
+					eventInstance->set3DAttributes(&spatialAttributes);
+					eventInstance->start();
+					eventInstance->setPaused(false);
+					eventInstance->release();
 				}
 			}
 		}
 	}
 
+
+	//	 ___________________________
+	//	|							|
+	//	|	   VOLUME CHANGES		|
+	//	|___________________________|
+	//
+	// Ambient volume
+	if(volume_ambient != Config::audioVar().volume_ambient)
+	{
+		volume_ambient = Config::audioVar().volume_ambient;
+		m_audioSystem->getBus(AudioBusType::AudioBusType_Ambient)->setVolume(volume_ambient);
+	}
+	// Master volume
+	if(volume_master != Config::audioVar().volume_master)
+	{
+		volume_master = Config::audioVar().volume_master;
+		m_audioSystem->getBus(AudioBusType::AudioBusType_Master)->setVolume(volume_master);
+	}
+	// Music volume
+	if(volume_music != Config::audioVar().volume_music)
+	{
+		volume_music = Config::audioVar().volume_music;
+		m_audioSystem->getBus(AudioBusType::AudioBusType_Music)->setVolume(volume_music);
+	}
+	// SFX volume
+	if(volume_sfx != Config::audioVar().volume_sfx)
+	{
+		volume_sfx = Config::audioVar().volume_sfx;
+		m_audioSystem->getBus(AudioBusType::AudioBusType_SFX)->setVolume(volume_sfx);
+	}
+
 	// Update the sound system
 	m_studioSystem->update();
-	//m_coreSystem->update();
 }
 
 ErrorCode AudioScene::preload()

+ 10 - 83
Praxis3D/Source/AudioScene.h

@@ -1,13 +1,5 @@
 #pragma once
 
-#pragma comment(lib, "fmod/fmod_vc.lib")
-//#pragma comment(lib, "fmod/fmodL_vc.lib")
-#pragma comment(lib, "fmod/fmodstudio_vc.lib")
-//#pragma comment(lib, "fmod/fmodstudioL_vc.lib")
-//#pragma comment(lib, "fmod/fsbank_vc.lib")
-
-#include <fmod/fmod.hpp>
-#include <fmod/fmod_errors.h>
 #include <fmod/fmod_studio.hpp>
 #include <random>
 
@@ -17,6 +9,7 @@
 #include "SoundListenerComponent.h"
 #include "System.h"
 
+class AudioSystem;
 struct ComponentsConstructionInfo;
 
 struct AudioComponentsConstructionInfo
@@ -128,92 +121,26 @@ public:
 	BitMask getPotentialSystemChanges() { return Systems::Changes::None; }
 
 private:
-	// Returns true if the operation was successful; returns false if operation failed and logs an error
-	const inline bool fmodErrorLog(const FMOD_RESULT p_fmodResult, const std::string &p_objectName = "", const ErrorType p_errorType = ErrorType::Warning, const ErrorSource p_errorSource = ErrorSource::Source_AudioScene) const noexcept
-	{
-		// Check if the operation result is OK
-		if(p_fmodResult != FMOD_RESULT::FMOD_OK)
-		{
-			// Convert the FMOD error to a string of the actual error name
-			// If the object name was given, include it in the error
-			if(p_objectName.empty())
-				ErrHandlerLoc::get().log(p_errorType, p_errorSource, GetString(static_cast<FmodErrorCodes>(p_fmodResult)));
-			else
-				ErrHandlerLoc::get().log(p_errorType, p_errorSource, "\'" + p_objectName + "\': " + GetString(static_cast<FmodErrorCodes>(p_fmodResult)));
-
-			// Operation failed - return false
-			return false;
-		}
-		else // Operation successful - return true
-			return true;
-	}
-
-	void addImpactSoundBank(FMOD::Studio::Bank *p_soundBank)
-	{
-		// Get the number of sound events
-		int numOfEvents = 0;
-		p_soundBank->getEventCount(&numOfEvents);
-
-		if(numOfEvents > 0)
-		{
-			// Get the list of sound events
-			FMOD::Studio::EventDescription **events = new FMOD::Studio::EventDescription * [numOfEvents];
-			p_soundBank->getEventList(events, numOfEvents, &numOfEvents);
-
-			// Go over each sound event
-			for(int eventIndex = 0; eventIndex < numOfEvents; eventIndex++)
-			{
-				// Get sound event path
-				char path[512];
-				events[eventIndex]->getPath(path, 512, nullptr);
-
-				// Extract the sound event name from the path, and assign the event itself to the event name entry in the impact sound map
-				m_impactSounds[Utilities::splitStringAfterDelimiter(Config::audioVar().pathDelimiter, std::string(path))] = events[eventIndex];
-			}
-
-			// Delete the pointer to an array of pointers that was created
-			delete events;
-		}
-	}
-
 	void loadParameterGUIDs();
 
 	AudioTask *m_audioTask;
+	AudioSystem *m_audioSystem;
+
+	// FMOD studio and core system handles
 	FMOD::Studio::System *m_studioSystem;
 	FMOD::System *m_coreSystem;
 
-	FMOD::ChannelGroup *m_masterChannelGroup;
-	FMOD::ChannelGroup *m_ambientChannelGroup;
-	FMOD::ChannelGroup *m_sfxChannelGroup;
-	FMOD::ChannelGroup *m_musicChannelGroup;
-
-	// Sound effects for object impacts
-	FMOD::Studio::Bank *m_impactBank;
-
 	// Sound events for object impacts
 	FMOD::Studio::EventDescription *m_impactEvents[ObjectMaterialType::NumberOfMaterialTypes];
 
 	SingleSound m_collisionSounds[ObjectMaterialType::NumberOfMaterialTypes];
 
-	bool m_defaultImpactSoundsLoaded;
+	// Volume values of different buses
+	float volume_ambient;
+	float volume_master;
+	float volume_music;
+	float volume_sfx;
 
-	int m_numSoundDrivers;
-
-	FMOD::Studio::Bank *m_testBank1;
-	FMOD::Studio::EventDescription *m_eventDescr1;
-	FMOD::Studio::EventInstance *m_eventInstance1;
-	FMOD::Sound *m_metalImpactSound[3];
-	FMOD::Channel *m_metalImpactChannel[3];
-	FMOD::DSP *m_pitch;
-	std::random_device m_randomDevice;
-	std::default_random_engine m_randomEngine;
-	std::uniform_real_distribution<float> m_distribution;
-	int m_lastPlayedImpactSound;
-
-	//std::vector<FMOD::Studio::EventDescription*> m_impactSounds;
-	//std::unordered_map<std::string, std::size_t> m_impactSoundsIndexMap;
-	std::unordered_map<std::string, FMOD::Studio::EventDescription*> m_impactSounds;
+	// All banks that this scene have loaded
 	std::vector<std::pair<std::string, FMOD::Studio::Bank *>> m_bankFilenames;
-
-	float m_dTime;
 };

+ 51 - 2
Praxis3D/Source/AudioSystem.cpp

@@ -2,9 +2,58 @@
 
 ErrorCode AudioSystem::init()
 {
-	ErrorCode returnCode = ErrorCode::Success;
+	ErrorCode returnError = ErrorCode::Success;
+
+	// Create the FMOD studio system
+	auto fmodError = FMOD::Studio::System::create(&m_studioSystem);
+
+	// Check if the sound system was created successfully
+	if(fmodError != FMOD_OK)
+	{
+		ErrHandlerLoc::get().log(ErrorCode::Audio_system_init_failed, ErrorSource::Source_AudioScene);
+		returnError = ErrorCode::Audio_system_init_failed;
+	}
+	else
+	{
+		// Get the FMOD core system
+		m_studioSystem->getCoreSystem(&m_coreSystem);
+
+		// Get the number of sound drivers
+		m_coreSystem->getNumDrivers(&m_numSoundDrivers);
+
+		// Do not continue if there are no sound drivers
+		if(m_numSoundDrivers == 0)
+		{
+			ErrHandlerLoc::get().log(ErrorCode::Audio_no_drivers, ErrorSource::Source_AudioScene);
+			returnError = ErrorCode::Audio_no_drivers;
+		}
+		else
+		{
+			// Initialize our Instance with 36 Channels
+			m_studioSystem->initialize(Config::audioVar().num_audio_channels, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL | FMOD_INIT_VOL0_BECOMES_VIRTUAL | FMOD_INIT_3D_RIGHTHANDED, NULL);
+
+			FMOD::Studio::Bank *defaultSoundBank = nullptr;
+
+			// Load default sound bank
+			if(fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + Config::audioVar().default_sound_bank).c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &defaultSoundBank), Config::audioVar().default_sound_bank))
+				if(fmodErrorLog(defaultSoundBank->loadSampleData(), Config::audioVar().default_sound_bank))
+					addImpactSoundBank(defaultSoundBank);
 
-	ErrHandlerLoc::get().log(ErrorCode::Initialize_success, ErrorSource::Source_AudioSystem);
+			// Load default string bank
+			if(fmodErrorLog(m_studioSystem->loadBankFile((Config::filepathVar().sound_path + Config::audioVar().default_sound_bank_string).c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &defaultSoundBank), Config::audioVar().default_sound_bank_string))
+				fmodErrorLog(defaultSoundBank->loadSampleData(), Config::audioVar().default_sound_bank_string);
+		}
+	}
+
+	if(returnError == ErrorCode::Success)
+		ErrHandlerLoc::get().log(ErrorCode::Initialize_success, ErrorSource::Source_AudioSystem);
+
+	return returnError;
+}
+
+ErrorCode AudioSystem::setup(const PropertySet &p_properties)
+{
+	ErrorCode returnCode = ErrorCode::Success;
 
 	return returnCode;
 }

+ 118 - 6
Praxis3D/Source/AudioSystem.h

@@ -1,11 +1,22 @@
 #pragma once
 
+#pragma comment(lib, "fmod/fmod_vc.lib")
+//#pragma comment(lib, "fmod/fmodL_vc.lib")
+#pragma comment(lib, "fmod/fmodstudio_vc.lib")
+//#pragma comment(lib, "fmod/fmodstudioL_vc.lib")
+//#pragma comment(lib, "fmod/fsbank_vc.lib")
+
+#include <fmod/fmod.hpp>
+#include <fmod/fmod_errors.h>
+#include <fmod/fmod_studio.hpp>
+
 #include "AudioScene.h"
 #include "ErrorHandlerLocator.h"
 #include "System.h"
 
 class AudioSystem : public SystemBase
 {
+	friend class AudioScene;
 public:
 	AudioSystem()
 	{
@@ -13,22 +24,32 @@ public:
 			m_audioScenes[i] = nullptr;
 
 		m_systemName = GetString(Systems::Audio);
+		m_coreSystem = nullptr;
+		m_studioSystem = nullptr;
+		m_impactBank = nullptr;
+		m_numSoundDrivers = 0;
+
+		for(unsigned int i = 0; i < AudioBusType::AudioBusType_NumOfTypes; i++)
+			m_buses[i] = nullptr;
 	}
 	~AudioSystem()
 	{
 		for(unsigned int i = 0; i < EngineStateType::EngineStateType_NumOfTypes; i++)
 			if(m_audioScenes[i] != nullptr)
 				delete m_audioScenes[i];
+
+		if(m_studioSystem != nullptr)
+		{
+			if(m_coreSystem != nullptr)
+				m_coreSystem->release();
+
+			m_studioSystem->release();
+		}
 	}
 
 	ErrorCode init();
 
-	ErrorCode setup(const PropertySet &p_properties)
-	{
-		ErrorCode returnCode = ErrorCode::Success;
-
-		return returnCode;
-	}
+	ErrorCode setup(const PropertySet &p_properties);
 
 	virtual ErrorCode preload()
 	{
@@ -40,6 +61,8 @@ public:
 	void loadInBackground() { }
 
 	Systems::TypeID getSystemType() { return Systems::Audio; }
+	FMOD::Studio::System *getStudioSystem() { return m_studioSystem; }
+	FMOD::System *getCoreSystem() { return m_coreSystem; }
 
 	SystemScene *createScene(SceneLoader *p_sceneLoader, EngineStateType p_engineState)
 	{
@@ -73,5 +96,94 @@ public:
 	}
 
 protected:
+	// Returns true if the operation was successful; returns false if operation failed and logs an error
+	static inline bool fmodErrorLog(const FMOD_RESULT p_fmodResult, const std::string &p_objectName = "", const ErrorType p_errorType = ErrorType::Warning, const ErrorSource p_errorSource = ErrorSource::Source_AudioScene) noexcept
+	{
+		// Check if the operation result is OK
+		if(p_fmodResult != FMOD_RESULT::FMOD_OK)
+		{
+			// Convert the FMOD error to a string of the actual error name
+			// If the object name was given, include it in the error
+			if(p_objectName.empty())
+				ErrHandlerLoc::get().log(p_errorType, p_errorSource, GetString(static_cast<FmodErrorCodes>(p_fmodResult)));
+			else
+				ErrHandlerLoc::get().log(p_errorType, p_errorSource, "\'" + p_objectName + "\': " + GetString(static_cast<FmodErrorCodes>(p_fmodResult)));
+
+			// Operation failed - return false
+			return false;
+		}
+		else // Operation successful - return true
+			return true;
+	}
+
+	void addImpactSoundBank(FMOD::Studio::Bank *p_soundBank)
+	{
+		// Get the number of sound events
+		int numOfEvents = 0;
+		p_soundBank->getEventCount(&numOfEvents);
+
+		if(numOfEvents > 0)
+		{
+			// Get the list of sound events
+			FMOD::Studio::EventDescription **events = new FMOD::Studio::EventDescription * [numOfEvents];
+			p_soundBank->getEventList(events, numOfEvents, &numOfEvents);
+
+			// Go over each sound event
+			for(int eventIndex = 0; eventIndex < numOfEvents; eventIndex++)
+			{
+				// Get sound event path
+				char path[512];
+				events[eventIndex]->getPath(path, 512, nullptr);
+
+				// Extract the sound event name from the path, and assign the event itself to the event name entry in the impact sound map
+				m_impactSounds[Utilities::splitStringAfterDelimiter(Config::audioVar().pathDelimiter, std::string(path))] = events[eventIndex];
+			}
+
+			// Delete the pointer to an array of pointers that was created
+			delete events;
+		}
+	}
+
+	// Load all the audio buses from the studio system into a buses array
+	void assignBusses()
+	{
+		for(unsigned int busType = 0; busType < AudioBusType::AudioBusType_NumOfTypes; busType++)
+			switch(busType)
+			{
+				case AudioBusType_Ambient:
+					m_studioSystem->getBus((Config::audioVar().bus_name_prefix + Config::audioVar().bus_name_ambient).c_str(), &m_buses[busType]);
+					break;
+				case AudioBusType_Master:
+					m_studioSystem->getBus((Config::audioVar().bus_name_prefix + Config::audioVar().bus_name_master).c_str(), &m_buses[busType]);
+					break;
+				case AudioBusType_Music:
+					m_studioSystem->getBus((Config::audioVar().bus_name_prefix + Config::audioVar().bus_name_music).c_str(), &m_buses[busType]);
+					break;
+				case AudioBusType_SFX:
+					m_studioSystem->getBus((Config::audioVar().bus_name_prefix + Config::audioVar().bus_name_sfx).c_str(), &m_buses[busType]);
+					break;
+				case AudioBusType_NumOfTypes:
+				default:
+					// Log an error if this portion is reached, as more Audio Bus Types might have been added without modifying this method
+					ErrHandlerLoc::get().log(ErrorCode::Audio_invalid_bus_type, ErrorSource::Source_AudioSystem);
+					break;
+			}
+	}
+
+	FMOD::Studio::Bus *getBus(const AudioBusType p_busType) { return m_buses[p_busType]; }
+
 	AudioScene *m_audioScenes[EngineStateType::EngineStateType_NumOfTypes];
+
+	// Sound effects for object impacts
+	FMOD::Studio::Bank *m_impactBank;
+	std::unordered_map<std::string, FMOD::Studio::EventDescription *> m_impactSounds;
+
+	// FMOD studio and core system handles
+	FMOD::Studio::System *m_studioSystem;
+	FMOD::System *m_coreSystem;
+
+	// Holds all the audio bus types, used for manipulating grouped sounds (like changing volume)
+	FMOD::Studio::Bus *m_buses[AudioBusType::AudioBusType_NumOfTypes];
+
+	int m_numSoundDrivers;
 };

+ 1 - 0
Praxis3D/Source/CollisionEventComponent.h

@@ -11,6 +11,7 @@ struct CollisionEvent
 	EntityID m_entityID;
 	glm::vec3 m_position;
 	glm::vec3 m_velocity;
+	btTransform m_worldTransform;
 	float m_appliedImpulse;
 	bool m_firstObjInCollisionPair;
 };

+ 9 - 0
Praxis3D/Source/CommonDefinitions.h

@@ -241,6 +241,15 @@ enum GBufferTextureType : unsigned int
 	ObjectMaterialType_NumOfTypes
 };*/
 
+enum AudioBusType : unsigned int
+{
+	AudioBusType_Ambient,
+	AudioBusType_Master,
+	AudioBusType_Music,
+	AudioBusType_SFX,
+	AudioBusType_NumOfTypes
+};
+
 #define OBJ_MATERIAL_ID(Code) \
 	Code(Concrete, = 0) \
 	Code(Glass,) \

+ 14 - 0
Praxis3D/Source/Config.cpp

@@ -54,7 +54,21 @@ void Config::init()
 	// Note: not all the variables are assigned to containers, as some are not meant to be loaded from config file.
 
 	// Audio Variables
+	AddVariablePredef(m_audioVar, impact_impulse_param_divider);
+	AddVariablePredef(m_audioVar, impact_impulse_volume_divider);
+	AddVariablePredef(m_audioVar, impact_max_volume_threshold); 
+	AddVariablePredef(m_audioVar, impact_soft_hard_threshold);
+	AddVariablePredef(m_audioVar, max_impact_volume);
+	AddVariablePredef(m_audioVar, volume_ambient);
+	AddVariablePredef(m_audioVar, volume_master);
+	AddVariablePredef(m_audioVar, volume_music);
+	AddVariablePredef(m_audioVar, volume_sfx);
 	AddVariablePredef(m_audioVar, num_audio_channels);
+	AddVariablePredef(m_audioVar, bus_name_ambient);
+	AddVariablePredef(m_audioVar, bus_name_master);
+	AddVariablePredef(m_audioVar, bus_name_music);
+	AddVariablePredef(m_audioVar, bus_name_prefix);
+	AddVariablePredef(m_audioVar, bus_name_sfx);
 	AddVariablePredef(m_audioVar, default_sound_bank);
 	AddVariablePredef(m_audioVar, default_sound_bank_string);
 	AddVariablePredef(m_audioVar, default_impact_sound_bank);

+ 24 - 1
Praxis3D/Source/Config.h

@@ -571,19 +571,42 @@ public:
 	{
 		AudioVariables()
 		{
-			impact_max_volume_threshold = 200.0f;
+			impact_impulse_param_divider = 1.0f;
+			impact_impulse_volume_divider = 200.0f;
+			impact_max_volume_threshold = 1.0f;
 			impact_soft_hard_threshold = 30.0f;
 			max_impact_volume = 2.0f;
+			volume_ambient = 1.0f;
+			volume_master = 1.0f;
+			volume_music = 1.0f;
+			volume_sfx = 1.0f;
 			num_audio_channels = 32;
+			bus_name_ambient = "Ambient";
+			bus_name_master = "";
+			bus_name_music = "Music";
+			bus_name_prefix = "bus:/";
+			bus_name_sfx = "SFX";
 			default_sound_bank = "Master.bank";
 			default_sound_bank_string = "Master.strings.bank";
 			default_impact_sound_bank = "Impact.bank";
 			pathDelimiter = ":/";
 		}
+
+		float impact_impulse_param_divider;
+		float impact_impulse_volume_divider;
 		float impact_max_volume_threshold;
 		float impact_soft_hard_threshold;
 		float max_impact_volume;
+		float volume_ambient;
+		float volume_master;
+		float volume_music;
+		float volume_sfx;
 		int num_audio_channels;
+		std::string bus_name_ambient;
+		std::string bus_name_master;
+		std::string bus_name_music;
+		std::string bus_name_prefix;
+		std::string bus_name_sfx;
 		std::string default_sound_bank;
 		std::string default_sound_bank_string;
 		std::string default_impact_sound_bank;

+ 1 - 0
Praxis3D/Source/ErrorCodes.h

@@ -41,6 +41,7 @@ DECLARE_ENUM(ErrorType, ERROR_TYPES)
     Code(File_not_found,) \
     Code(Filename_empty,) \
 	/* Audio system errors */\
+	Code(Audio_invalid_bus_type, ) \
 	Code(Audio_no_drivers, ) \
 	Code(Audio_system_init_failed, ) \
 	/* General engine errors */\

+ 1 - 0
Praxis3D/Source/ErrorHandler.cpp

@@ -28,6 +28,7 @@ ErrorHandler::ErrorHandler()
 	AssignErrorType(Initialize_failure, Info);
 	AssignErrorType(File_not_found, Warning);
 	AssignErrorType(Filename_empty, Warning);
+	AssignErrorType(Audio_invalid_bus_type, Warning);
 	AssignErrorType(Audio_no_drivers, Error);
 	AssignErrorType(Audio_system_init_failed, Error);
 	AssignErrorType(Destroy_obj_not_found, Warning);

+ 8 - 4
Praxis3D/Source/PhysicsScene.cpp

@@ -204,10 +204,11 @@ void PhysicsScene::internalTickCallback(btDynamicsWorld *p_world, btScalar p_tim
 					if(collisionEventComponentObjectA->m_numOfDynamicCollisions[dbIndex] < NUM_DYNAMIC_COLLISION_EVENTS)
 					{
 						collisionEventComponentObjectA->m_dynamicCollisions[dbIndex][collisionEventComponentObjectA->m_numOfDynamicCollisions[dbIndex]].m_firstObjInCollisionPair = true;
-						collisionEventComponentObjectA->m_dynamicCollisions[dbIndex][collisionEventComponentObjectA->m_numOfDynamicCollisions[dbIndex]].m_entityID = entityB;
+						collisionEventComponentObjectA->m_dynamicCollisions[dbIndex][collisionEventComponentObjectA->m_numOfDynamicCollisions[dbIndex]].m_entityID = entityA;
 						collisionEventComponentObjectA->m_dynamicCollisions[dbIndex][collisionEventComponentObjectA->m_numOfDynamicCollisions[dbIndex]].m_appliedImpulse = manifoldPoint.m_appliedImpulse;
 						collisionEventComponentObjectA->m_dynamicCollisions[dbIndex][collisionEventComponentObjectA->m_numOfDynamicCollisions[dbIndex]].m_position = Math::toGlmVec3(manifoldPoint.getPositionWorldOnA());
 						collisionEventComponentObjectA->m_dynamicCollisions[dbIndex][collisionEventComponentObjectA->m_numOfDynamicCollisions[dbIndex]].m_velocity = Math::toGlmVec3(objectA->getInterpolationLinearVelocity());
+						collisionEventComponentObjectA->m_dynamicCollisions[dbIndex][collisionEventComponentObjectA->m_numOfDynamicCollisions[dbIndex]].m_worldTransform = objectA->getWorldTransform();
 
 						collisionEventComponentObjectA->m_numOfDynamicCollisions[dbIndex]++;
 					}
@@ -219,10 +220,11 @@ void PhysicsScene::internalTickCallback(btDynamicsWorld *p_world, btScalar p_tim
 					if(collisionEventComponentObjectB->m_numOfDynamicCollisions[dbIndex] < NUM_DYNAMIC_COLLISION_EVENTS)
 					{
 						collisionEventComponentObjectB->m_dynamicCollisions[dbIndex][collisionEventComponentObjectB->m_numOfDynamicCollisions[dbIndex]].m_firstObjInCollisionPair = false;
-						collisionEventComponentObjectB->m_dynamicCollisions[dbIndex][collisionEventComponentObjectB->m_numOfDynamicCollisions[dbIndex]].m_entityID = entityA;
+						collisionEventComponentObjectB->m_dynamicCollisions[dbIndex][collisionEventComponentObjectB->m_numOfDynamicCollisions[dbIndex]].m_entityID = entityB;
 						collisionEventComponentObjectB->m_dynamicCollisions[dbIndex][collisionEventComponentObjectB->m_numOfDynamicCollisions[dbIndex]].m_appliedImpulse = manifoldPoint.m_appliedImpulse;
 						collisionEventComponentObjectB->m_dynamicCollisions[dbIndex][collisionEventComponentObjectB->m_numOfDynamicCollisions[dbIndex]].m_position = Math::toGlmVec3(manifoldPoint.getPositionWorldOnB());
 						collisionEventComponentObjectB->m_dynamicCollisions[dbIndex][collisionEventComponentObjectB->m_numOfDynamicCollisions[dbIndex]].m_velocity = Math::toGlmVec3(objectB->getInterpolationLinearVelocity());
+						collisionEventComponentObjectB->m_dynamicCollisions[dbIndex][collisionEventComponentObjectB->m_numOfDynamicCollisions[dbIndex]].m_worldTransform = objectB->getWorldTransform();
 
 						collisionEventComponentObjectB->m_numOfDynamicCollisions[dbIndex]++;
 					}
@@ -237,10 +239,11 @@ void PhysicsScene::internalTickCallback(btDynamicsWorld *p_world, btScalar p_tim
 					if(collisionEventComponentObjectA->m_numOfStaticCollisions[dbIndex] < NUM_STATIC_COLLISION_EVENTS)
 					{
 						collisionEventComponentObjectA->m_staticCollisions[dbIndex][collisionEventComponentObjectA->m_numOfStaticCollisions[dbIndex]].m_firstObjInCollisionPair = true;
-						collisionEventComponentObjectA->m_staticCollisions[dbIndex][collisionEventComponentObjectA->m_numOfStaticCollisions[dbIndex]].m_entityID = entityB;
+						collisionEventComponentObjectA->m_staticCollisions[dbIndex][collisionEventComponentObjectA->m_numOfStaticCollisions[dbIndex]].m_entityID = entityA;
 						collisionEventComponentObjectA->m_staticCollisions[dbIndex][collisionEventComponentObjectA->m_numOfStaticCollisions[dbIndex]].m_appliedImpulse = manifoldPoint.m_appliedImpulse;
 						collisionEventComponentObjectA->m_staticCollisions[dbIndex][collisionEventComponentObjectA->m_numOfStaticCollisions[dbIndex]].m_position = Math::toGlmVec3(manifoldPoint.getPositionWorldOnA());
 						collisionEventComponentObjectA->m_staticCollisions[dbIndex][collisionEventComponentObjectA->m_numOfStaticCollisions[dbIndex]].m_velocity = Math::toGlmVec3(objectA->getInterpolationLinearVelocity());
+						collisionEventComponentObjectA->m_staticCollisions[dbIndex][collisionEventComponentObjectA->m_numOfStaticCollisions[dbIndex]].m_worldTransform = objectA->getWorldTransform();
 
 						collisionEventComponentObjectA->m_numOfStaticCollisions[dbIndex]++;
 					}
@@ -252,10 +255,11 @@ void PhysicsScene::internalTickCallback(btDynamicsWorld *p_world, btScalar p_tim
 					if(collisionEventComponentObjectB->m_numOfStaticCollisions[dbIndex] < NUM_STATIC_COLLISION_EVENTS)
 					{
 						collisionEventComponentObjectB->m_staticCollisions[dbIndex][collisionEventComponentObjectB->m_numOfStaticCollisions[dbIndex]].m_firstObjInCollisionPair = false;
-						collisionEventComponentObjectB->m_staticCollisions[dbIndex][collisionEventComponentObjectB->m_numOfStaticCollisions[dbIndex]].m_entityID = entityA;
+						collisionEventComponentObjectB->m_staticCollisions[dbIndex][collisionEventComponentObjectB->m_numOfStaticCollisions[dbIndex]].m_entityID = entityB;
 						collisionEventComponentObjectB->m_staticCollisions[dbIndex][collisionEventComponentObjectB->m_numOfStaticCollisions[dbIndex]].m_appliedImpulse = manifoldPoint.m_appliedImpulse;
 						collisionEventComponentObjectB->m_staticCollisions[dbIndex][collisionEventComponentObjectB->m_numOfStaticCollisions[dbIndex]].m_position = Math::toGlmVec3(manifoldPoint.getPositionWorldOnB());
 						collisionEventComponentObjectB->m_staticCollisions[dbIndex][collisionEventComponentObjectB->m_numOfStaticCollisions[dbIndex]].m_velocity = Math::toGlmVec3(objectB->getInterpolationLinearVelocity());
+						collisionEventComponentObjectB->m_staticCollisions[dbIndex][collisionEventComponentObjectB->m_numOfStaticCollisions[dbIndex]].m_worldTransform = objectB->getWorldTransform();
 
 						collisionEventComponentObjectB->m_numOfStaticCollisions[dbIndex]++;
 					}

+ 1 - 1
Praxis3D/Source/SceneLoader.cpp

@@ -59,8 +59,8 @@ ErrorCode SceneLoader::loadFromFile(const std::string &p_filename)
 			}
 
 			// Pass the scene and system propertySet parameters
-			m_systemScenes[sysIndex]->setup(scenePropertySet);
 			m_systemScenes[sysIndex]->getSystem()->setup(systemropertySet);
+			m_systemScenes[sysIndex]->setup(scenePropertySet);
 		}
 
 		// Get Game Objects