284 lines
8.2 KiB
C++
284 lines
8.2 KiB
C++
![]() |
// rage
|
||
|
#include "audioengine/controller.h"
|
||
|
#include "audiosoundtypes/soundcontrol.h"
|
||
|
#include "audiosoundtypes/sound.h"
|
||
|
#include "audioengine/engineutil.h"
|
||
|
#include "audiohardware/driverutil.h"
|
||
|
#include "cloth/environmentcloth.h"
|
||
|
#include "fragment/cache.h"
|
||
|
#include "grcore/debugdraw.h"
|
||
|
#include "pheffects/wind.h"
|
||
|
|
||
|
// game
|
||
|
#include "control/replay/replay.h"
|
||
|
#include "objectaudioentity.h"
|
||
|
#include "objects/object.h"
|
||
|
#include "weatheraudioentity.h"
|
||
|
#include "physics/gtaInst.h"
|
||
|
|
||
|
#include "debugaudio.h"
|
||
|
|
||
|
#include "audioentity.h"
|
||
|
|
||
|
AUDIO_OPTIMISATIONS()
|
||
|
//OPTIMISATIONS_OFF()
|
||
|
|
||
|
|
||
|
#if __BANK
|
||
|
f32 audObjectAudioEntity::sm_OverriddenWindStrength = 0.f;
|
||
|
bool audObjectAudioEntity::sm_UseInterpolatedWind = false;
|
||
|
bool audObjectAudioEntity::sm_FindCloth = false;
|
||
|
bool audObjectAudioEntity::sm_ShowClothPlaying = false;
|
||
|
bool audObjectAudioEntity::sm_OverrideWind = false;
|
||
|
#endif
|
||
|
|
||
|
f32 audObjectAudioEntity::sm_SqdDistanceThreshold = 225.f;
|
||
|
|
||
|
audObjectAudioEntity::audObjectAudioEntity():
|
||
|
m_ClothSound(NULL),
|
||
|
m_Object(NULL)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
audObjectAudioEntity::~audObjectAudioEntity()
|
||
|
{
|
||
|
if(m_ClothSound)
|
||
|
{
|
||
|
m_ClothSound->StopAndForget();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void audObjectAudioEntity::Init(CObject *object)
|
||
|
{
|
||
|
naAudioEntity::Init();
|
||
|
audEntity::SetName("audObjectAudioEntity");
|
||
|
naAssertf(object,"Null environment cloth in audObjectAudioEntity::Init");
|
||
|
m_Object = object;
|
||
|
CBaseModelInfo* pModelInfo = m_Object->GetBaseModelInfo();
|
||
|
if(pModelInfo)
|
||
|
{
|
||
|
const ModelAudioCollisionSettings *settings = pModelInfo->GetAudioCollisionSettings();
|
||
|
if(settings)
|
||
|
{
|
||
|
m_WindClothSounds.Init(settings->WindSounds);
|
||
|
}
|
||
|
}
|
||
|
m_LastTimeTriggered = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void audObjectAudioEntity::PreUpdateService(u32 /*timeInMs*/)
|
||
|
{
|
||
|
#if GTA_REPLAY
|
||
|
if(CReplayMgr::IsEditModeActive() && (CReplayMgr::ShouldHideMapObject(m_Object) || CReplayMgr::IsPreCachingScene()))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
#endif //GTA_REPLAY
|
||
|
|
||
|
// Don't process this when we're playing a replay clip and the object is a map object that has been hidden by the replay system.
|
||
|
if(m_Object->isRageEnvCloth())
|
||
|
{
|
||
|
f32 windStrength = g_WeatherAudioEntity.GetWindStrength();
|
||
|
|
||
|
#if __BANK
|
||
|
if(sm_OverrideWind)
|
||
|
{
|
||
|
windStrength = sm_OverriddenWindStrength;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
bool tunableCloth = false;
|
||
|
|
||
|
#if GTA_REPLAY
|
||
|
// Not always valid to query fragInstGta in replays, rely on recorded cloth sounds instead
|
||
|
if(!(CReplayMgr::IsEditModeActive() || CReplayMgr::IsEditorActive() || CReplayMgr::IsReplayInControlOfWorld()))
|
||
|
#endif
|
||
|
{
|
||
|
fragInstGta* pFragInst = (fragInstGta*)m_Object->GetCurrentPhysicsInst();
|
||
|
Assertf(pFragInst, "Failed to allocate new fragInstGta.");
|
||
|
if(pFragInst)
|
||
|
{
|
||
|
// Hoop jumping cloth setup.
|
||
|
fragCacheEntry *cacheEntry = pFragInst->GetCacheEntry();
|
||
|
if( cacheEntry )
|
||
|
{
|
||
|
fragHierarchyInst* hierInst = cacheEntry->GetHierInst();
|
||
|
Assert( hierInst );
|
||
|
environmentCloth * cloth = hierInst->envCloth;
|
||
|
if( cloth && cloth->GetFlag(environmentCloth::CLOTH_IsInInterior))
|
||
|
{
|
||
|
if(cloth->GetFlag(environmentCloth::CLOTH_IsMoving) && !m_ClothSound && m_LastTimeTriggered + 1000 < g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(0))
|
||
|
{
|
||
|
if(m_WindClothSounds.IsInitialised())
|
||
|
{
|
||
|
u32 soundNameHash = ATSTRINGHASH("CLOTH", 0x1951F94C);
|
||
|
m_LastTimeTriggered = g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(0);
|
||
|
audSoundInitParams initParams;
|
||
|
initParams.Tracker = m_Object->GetPlaceableTracker();
|
||
|
initParams.EnvironmentGroup = CreateClothEnvironmentGroup();
|
||
|
CreateAndPlaySound_Persistent(m_WindClothSounds.Find(soundNameHash),&m_ClothSound,&initParams);
|
||
|
|
||
|
#if GTA_REPLAY
|
||
|
if(m_ClothSound && CReplayMgr::ShouldRecord())
|
||
|
{
|
||
|
CReplayMgr::ReplayRecordSoundPersistant(m_WindClothSounds.GetNameHash(), soundNameHash, &initParams, m_ClothSound, m_Object);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
if(m_ClothSound)
|
||
|
{
|
||
|
cloth->SetFlag(environmentCloth::CLOTH_IsMoving,false);
|
||
|
}
|
||
|
}
|
||
|
else if ( !cloth->GetFlag(environmentCloth::CLOTH_IsMoving))
|
||
|
{
|
||
|
if(m_ClothSound)
|
||
|
{
|
||
|
m_ClothSound->StopAndForget();
|
||
|
}
|
||
|
}
|
||
|
tunableCloth = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
f32 sqdDistance = LARGE_FLOAT;
|
||
|
if(m_Object)
|
||
|
{
|
||
|
// Distance check to stop the sound.
|
||
|
sqdDistance = VEC3V_TO_VECTOR3(m_Object->GetTransform().GetPosition() - g_AudioEngine.GetEnvironment().GetVolumeListenerPosition()).Mag2();
|
||
|
}
|
||
|
if(!tunableCloth)
|
||
|
{
|
||
|
if(!m_ClothSound && sqdDistance < sm_SqdDistanceThreshold )
|
||
|
{
|
||
|
if(m_WindClothSounds.IsInitialised())
|
||
|
{
|
||
|
audSoundInitParams initParams;
|
||
|
initParams.Tracker = m_Object->GetPlaceableTracker();
|
||
|
initParams.EnvironmentGroup = CreateClothEnvironmentGroup();
|
||
|
CreateSound_PersistentReference(m_WindClothSounds.Find(ATSTRINGHASH("CLOTH", 0x1951F94C)),&m_ClothSound,&initParams);
|
||
|
}
|
||
|
if(m_ClothSound)
|
||
|
{
|
||
|
//Use local wind
|
||
|
m_ClothSound->FindAndSetVariableValue(ATSTRINGHASH("Strength", 0xFF1C4627),windStrength);
|
||
|
m_ClothSound->PrepareAndPlay();
|
||
|
}
|
||
|
}
|
||
|
else if(m_ClothSound)
|
||
|
{
|
||
|
m_ClothSound->FindAndSetVariableValue(ATSTRINGHASH("Strength", 0xFF1C4627),windStrength);
|
||
|
}
|
||
|
}
|
||
|
if(sqdDistance > sm_SqdDistanceThreshold && m_ClothSound)
|
||
|
{
|
||
|
m_ClothSound->StopAndForget();
|
||
|
}
|
||
|
|
||
|
#if __BANK
|
||
|
if(sm_FindCloth)
|
||
|
{
|
||
|
if(m_Object)
|
||
|
{
|
||
|
Color32 color = Color_red;
|
||
|
if(m_WindClothSounds.IsInitialised())
|
||
|
{
|
||
|
color = Color_green;
|
||
|
}
|
||
|
grcDebugDraw::Capsule(m_Object->GetTransform().GetPosition()
|
||
|
,VECTOR3_TO_VEC3V(VEC3V_TO_VECTOR3(m_Object->GetTransform().GetPosition()) + Vector3(0.f,0.f, 300.f)),1.f,color);
|
||
|
}
|
||
|
}
|
||
|
if(sm_ShowClothPlaying)
|
||
|
{
|
||
|
if(m_Object && m_ClothSound)
|
||
|
{
|
||
|
Color32 color = Color_green;
|
||
|
grcDebugDraw::Capsule(m_Object->GetTransform().GetPosition()
|
||
|
,VECTOR3_TO_VEC3V(VEC3V_TO_VECTOR3(m_Object->GetTransform().GetPosition()) + Vector3(0.f,0.f, 300.f)),1.f,color);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
void audObjectAudioEntity::UpdateCreakSound(const Vector3 &UNUSED_PARAM(pos), const f32 UNUSED_PARAM(theta), const f32 UNUSED_PARAM(speed))
|
||
|
{
|
||
|
#if 0
|
||
|
if(m_ControllerEntityId==AUD_INVALID_CONTROLLER_ENTITY_ID)
|
||
|
{
|
||
|
Init();
|
||
|
}
|
||
|
const f32 speedFactor = speed;
|
||
|
const f32 absTheta = Abs(theta);
|
||
|
//const f32 riseVol = absTheta * 2.f;
|
||
|
//const f32 fallVol = (1.f - absTheta) * 2.f;
|
||
|
//const f32 linVol = audDriverUtil::fsel(absTheta - 0.5f, fallVol, riseVol) * speedFactor;
|
||
|
const f32 linVol = (1.f-Min(1.f,(absTheta*1.36f)))*speedFactor;
|
||
|
const bool shouldPlay = (linVol > g_SilenceVolumeLin);
|
||
|
const s32 pitch = static_cast<s32>(theta * 150.f);
|
||
|
|
||
|
//char buf[128];
|
||
|
//formatf(buf,sizeof(buf), "%f %f %f", theta, speed, linVol);
|
||
|
//grcDebugDraw::Text(pos.x, pos.y, pos.z, Color32(255,255,0), buf);
|
||
|
//
|
||
|
if(shouldPlay)
|
||
|
{
|
||
|
if(!m_CreakSound)
|
||
|
{
|
||
|
audSoundInitParams initParams;
|
||
|
static const audStringHash creakSound("SWAY_CREAK_LOOP");
|
||
|
CreateAndPlaySound_Persistent(creakSound, &m_CreakSound, &initParams);
|
||
|
}
|
||
|
if(m_CreakSound)
|
||
|
{
|
||
|
m_CreakSound->SetRequestedPosition(pos);
|
||
|
m_CreakSound->SetRequestedPitch(pitch);
|
||
|
m_CreakSound->SetRequestedVolume(audDriverUtil::ComputeDbVolumeFromLinear(linVol));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(m_CreakSound)
|
||
|
{
|
||
|
m_CreakSound->StopAndForget();
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
naEnvironmentGroup* audObjectAudioEntity::CreateClothEnvironmentGroup()
|
||
|
{
|
||
|
naEnvironmentGroup* environmentGroup = NULL;
|
||
|
if(m_Object)
|
||
|
{
|
||
|
environmentGroup = naEnvironmentGroup::Allocate("Cloth");
|
||
|
if(environmentGroup)
|
||
|
{
|
||
|
environmentGroup->Init(NULL, 20.0f);
|
||
|
environmentGroup->SetSource(m_Object->GetTransform().GetPosition());
|
||
|
environmentGroup->SetInteriorInfoWithEntity(m_Object);
|
||
|
environmentGroup->SetUsePortalOcclusion(true);
|
||
|
environmentGroup->SetUseInteriorDistanceMetrics(true);
|
||
|
environmentGroup->SetMaxPathDepth(2);
|
||
|
}
|
||
|
}
|
||
|
return environmentGroup;
|
||
|
}
|
||
|
|
||
|
#if __BANK
|
||
|
void audObjectAudioEntity::AddWidgets(bkBank &bank){
|
||
|
|
||
|
bank.PushGroup("Environment Cloths",false);
|
||
|
bank.AddToggle("Find cloths", &sm_FindCloth);
|
||
|
bank.AddToggle("sm_ShowClothPlaying", &sm_ShowClothPlaying);
|
||
|
bank.AddToggle("Use interpolated wind", &sm_UseInterpolatedWind);
|
||
|
bank.AddToggle("Override wind strength", &sm_OverrideWind);
|
||
|
bank.AddSlider("overridden wind strength", &sm_OverriddenWindStrength, 0.0f, 1.0f, 0.001f);
|
||
|
bank.AddSlider("sm_SqdDistanceThreshold", &sm_SqdDistanceThreshold, 0.0f, 10000.0f, 0.001f);
|
||
|
bank.PopGroup();
|
||
|
}
|
||
|
#endif
|