mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 23:19:19 +02:00
build 171214. partial control variable normalization for combined engine sounds, conditional cab soundproofing
This commit is contained in:
30
DynObj.cpp
30
DynObj.cpp
@@ -3622,7 +3622,35 @@ void TDynamicObject::RenderSounds() {
|
|||||||
|| ( MoverParameters->EngineType == Dumb ) ) {
|
|| ( MoverParameters->EngineType == Dumb ) ) {
|
||||||
|
|
||||||
// frequency calculation
|
// frequency calculation
|
||||||
frequency = rsSilnik.m_frequencyfactor * std::fabs( MoverParameters->enrot ) + rsSilnik.m_frequencyoffset;
|
auto normalizer { 1.f };
|
||||||
|
// for combined sounds normalize frequency to 0-1 range
|
||||||
|
switch( MoverParameters->EngineType ) {
|
||||||
|
case DieselElectric: {
|
||||||
|
if( true == sConverter.is_combined() ) {
|
||||||
|
normalizer = MoverParameters->DElist[ MoverParameters->MainCtrlPosNo ].RPM / 60;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DieselEngine: {
|
||||||
|
if( true == rsSilnik.is_combined() ) {
|
||||||
|
normalizer = MoverParameters->dizel_nmax;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ElectricInductionMotor: {
|
||||||
|
if( true == rsSilnik.is_combined() ) {
|
||||||
|
// TODO: implement normalization/a way to calculate max expected engine rpm
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
if( true == rsSilnik.is_combined() ) {
|
||||||
|
normalizer = MoverParameters->nmax;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frequency = rsSilnik.m_frequencyfactor * std::abs( MoverParameters->enrot ) / std::max( 1.f, normalizer ) + rsSilnik.m_frequencyoffset;
|
||||||
if( MoverParameters->EngineType == Dumb ) {
|
if( MoverParameters->EngineType == Dumb ) {
|
||||||
frequency -= 0.2 * MoverParameters->EnginePower / ( 1 + MoverParameters->Power * 1000 );
|
frequency -= 0.2 * MoverParameters->EnginePower / ( 1 + MoverParameters->Power * 1000 );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ float Global::FieldOfView = 45.0f;
|
|||||||
GLFWwindow *Global::window;
|
GLFWwindow *Global::window;
|
||||||
bool Global::shiftState;
|
bool Global::shiftState;
|
||||||
bool Global::ctrlState;
|
bool Global::ctrlState;
|
||||||
|
bool Global::CabWindowOpen { false };
|
||||||
int Global::iCameraLast = -1;
|
int Global::iCameraLast = -1;
|
||||||
std::string Global::asVersion = "couldn't retrieve version string";
|
std::string Global::asVersion = "couldn't retrieve version string";
|
||||||
bool Global::ControlPicking = false; // indicates controls pick mode is enabled
|
bool Global::ControlPicking = false; // indicates controls pick mode is enabled
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ public:
|
|||||||
static GLFWwindow *window;
|
static GLFWwindow *window;
|
||||||
static bool shiftState; //m7todo: brzydko
|
static bool shiftState; //m7todo: brzydko
|
||||||
static bool ctrlState;
|
static bool ctrlState;
|
||||||
|
static bool CabWindowOpen; // controls sound attenuation between cab and outside
|
||||||
static int iCameraLast;
|
static int iCameraLast;
|
||||||
static std::string asVersion; // z opisem
|
static std::string asVersion; // z opisem
|
||||||
static bool ControlPicking; // indicates controls pick mode is active
|
static bool ControlPicking; // indicates controls pick mode is active
|
||||||
|
|||||||
@@ -4746,21 +4746,27 @@ double TMoverParameters::TractionForce(double dt)
|
|||||||
|
|
||||||
eimv[eimv_Uzsmax] = Min0R(Voltage - eimc[eimc_f_DU], tmp);
|
eimv[eimv_Uzsmax] = Min0R(Voltage - eimc[eimc_f_DU], tmp);
|
||||||
eimv[eimv_fkr] = eimv[eimv_Uzsmax] / eimc[eimc_f_cfu];
|
eimv[eimv_fkr] = eimv[eimv_Uzsmax] / eimc[eimc_f_cfu];
|
||||||
if ((dizel_fill < 0))
|
if( ( dizel_fill < 0 ) ) {
|
||||||
eimv[ eimv_Pmax ] = eimc[ eimc_p_Ph ];
|
eimv[ eimv_Pmax ] = eimc[ eimc_p_Ph ];
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
eimv[ eimv_Pmax ] =
|
eimv[ eimv_Pmax ] =
|
||||||
Min0R(eimc[eimc_p_Pmax],
|
std::min(
|
||||||
0.001 * Voltage * (eimc[eimc_p_Imax] - eimc[eimc_f_I0]) * Pirazy2 *
|
eimc[ eimc_p_Pmax ],
|
||||||
eimc[eimc_s_cim] / eimc[eimc_s_p] / eimc[eimc_s_cfu]);
|
0.001 * Voltage * ( eimc[ eimc_p_Imax ] - eimc[ eimc_f_I0 ] ) * Pirazy2 * eimc[ eimc_s_cim ] / eimc[ eimc_s_p ] / eimc[ eimc_s_cfu ] );
|
||||||
|
}
|
||||||
eimv[ eimv_FMAXMAX ] =
|
eimv[ eimv_FMAXMAX ] =
|
||||||
0.001 * square(Min0R(eimv[eimv_fkr] / Max0R(abs(enrot) * eimc[eimc_s_p] +
|
0.001
|
||||||
eimc[eimc_s_dfmax] * eimv[eimv_ks],
|
* square(
|
||||||
eimc[eimc_s_dfmax]),
|
std::min(
|
||||||
1) *
|
1.0,
|
||||||
eimc[eimc_f_cfu] / eimc[eimc_s_cfu]) *
|
eimv[ eimv_fkr ] / std::max(
|
||||||
(eimc[eimc_s_dfmax] * eimc[eimc_s_dfic] * eimc[eimc_s_cim]) *
|
abs( enrot ) * eimc[ eimc_s_p ] + eimc[ eimc_s_dfmax ] * eimv[ eimv_ks ],
|
||||||
Transmision.Ratio * NPoweredAxles * 2.0 / WheelDiameter;
|
eimc[ eimc_s_dfmax ] ) )
|
||||||
|
* eimc[ eimc_f_cfu ]
|
||||||
|
/ eimc[ eimc_s_cfu ] )
|
||||||
|
* ( eimc[ eimc_s_dfmax ] * eimc[ eimc_s_dfic ] * eimc[ eimc_s_cim ] )
|
||||||
|
* Transmision.Ratio * NPoweredAxles * 2.0 / WheelDiameter;
|
||||||
if ((dizel_fill < 0))
|
if ((dizel_fill < 0))
|
||||||
{
|
{
|
||||||
eimv[eimv_Fful] = std::min(eimc[eimc_p_Ph] * 3.6 / (Vel != 0.0 ? Vel : 0.001),
|
eimv[eimv_Fful] = std::min(eimc[eimc_p_Ph] * 3.6 / (Vel != 0.0 ? Vel : 0.001),
|
||||||
@@ -4835,10 +4841,11 @@ double TMoverParameters::TractionForce(double dt)
|
|||||||
i = 0;
|
i = 0;
|
||||||
while ((i < RlistSize - 1) && (DElist[i + 1].RPM < abs(tmpV)))
|
while ((i < RlistSize - 1) && (DElist[i + 1].RPM < abs(tmpV)))
|
||||||
i++;
|
i++;
|
||||||
RventRot = (abs(tmpV) - DElist[i].RPM) /
|
RventRot =
|
||||||
(DElist[i + 1].RPM - DElist[i].RPM) *
|
( std::abs( tmpV ) - DElist[ i ].RPM )
|
||||||
(DElist[i + 1].GenPower - DElist[i].GenPower) +
|
/ std::max( 1.0, ( DElist[ i + 1 ].RPM - DElist[ i ].RPM ) )
|
||||||
DElist[i].GenPower;
|
* ( DElist[ i + 1 ].GenPower - DElist[ i ].GenPower )
|
||||||
|
+ DElist[ i ].GenPower;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
RventRot = 0;
|
RventRot = 0;
|
||||||
|
|||||||
@@ -1116,6 +1116,8 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
|
|
||||||
if( DebugCameraFlag ) { DebugCamera.Update(); }
|
if( DebugCameraFlag ) { DebugCamera.Update(); }
|
||||||
else { Camera.Update(); } // uwzględnienie ruchu wywołanego klawiszami
|
else { Camera.Update(); } // uwzględnienie ruchu wywołanego klawiszami
|
||||||
|
// reset window state, it'll be set again if applicable in a check below
|
||||||
|
Global::CabWindowOpen = false;
|
||||||
|
|
||||||
if( ( Train != nullptr )
|
if( ( Train != nullptr )
|
||||||
&& ( Camera.Type == tp_Follow )
|
&& ( Camera.Type == tp_Follow )
|
||||||
@@ -1128,6 +1130,8 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
&& ( (Console::Pressed( Global::Keys[ k_MechLeft ])
|
&& ( (Console::Pressed( Global::Keys[ k_MechLeft ])
|
||||||
|| (Console::Pressed( Global::Keys[ k_MechRight ]))))) {
|
|| (Console::Pressed( Global::Keys[ k_MechRight ]))))) {
|
||||||
// jeśli lusterko lewe albo prawe (bez rzucania na razie)
|
// jeśli lusterko lewe albo prawe (bez rzucania na razie)
|
||||||
|
Global::CabWindowOpen = true;
|
||||||
|
|
||||||
bool lr = Console::Pressed( Global::Keys[ k_MechLeft ] );
|
bool lr = Console::Pressed( Global::Keys[ k_MechLeft ] );
|
||||||
// Camera.Yaw powinno być wyzerowane, aby po powrocie patrzeć do przodu
|
// Camera.Yaw powinno być wyzerowane, aby po powrocie patrzeć do przodu
|
||||||
Camera.Pos = Controlled->GetPosition() + Train->MirrorPosition( lr ); // pozycja lusterka
|
Camera.Pos = Controlled->GetPosition() + Train->MirrorPosition( lr ); // pozycja lusterka
|
||||||
|
|||||||
37
sound.cpp
37
sound.cpp
@@ -331,7 +331,7 @@ void
|
|||||||
sound_source::play_combined() {
|
sound_source::play_combined() {
|
||||||
// combined sound consists of table od samples, each sample associated with certain range of values of controlling variable
|
// combined sound consists of table od samples, each sample associated with certain range of values of controlling variable
|
||||||
// current value of the controlling variable is passed to the source with pitch() call
|
// current value of the controlling variable is passed to the source with pitch() call
|
||||||
auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 100.f ) };
|
auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 99.f ) };
|
||||||
for( std::uint32_t idx = 0; idx < m_soundchunks.size(); ++idx ) {
|
for( std::uint32_t idx = 0; idx < m_soundchunks.size(); ++idx ) {
|
||||||
|
|
||||||
auto const &soundchunk { m_soundchunks[ idx ] };
|
auto const &soundchunk { m_soundchunks[ idx ] };
|
||||||
@@ -520,7 +520,7 @@ sound_source::update_combined( audio::openal_source &Source ) {
|
|||||||
|
|
||||||
if( ( soundhandle & sound_id::chunk ) != 0 ) {
|
if( ( soundhandle & sound_id::chunk ) != 0 ) {
|
||||||
// for sound chunks, test whether the chunk should still be active given current value of the controlling variable
|
// for sound chunks, test whether the chunk should still be active given current value of the controlling variable
|
||||||
auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 100.f ) };
|
auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 99.f ) };
|
||||||
auto const &soundchunk { m_soundchunks[ soundhandle ^ sound_id::chunk ] };
|
auto const &soundchunk { m_soundchunks[ soundhandle ^ sound_id::chunk ] };
|
||||||
if( ( soundpoint < soundchunk.second.fadein )
|
if( ( soundpoint < soundchunk.second.fadein )
|
||||||
|| ( soundpoint > soundchunk.second.fadeout ) ) {
|
|| ( soundpoint > soundchunk.second.fadeout ) ) {
|
||||||
@@ -598,7 +598,7 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 100.f ) };
|
auto const soundpoint { clamp( m_properties.pitch * 100.f, 0.f, 99.f ) };
|
||||||
|
|
||||||
// NOTE: direct access to implementation details ahead, kinda fugly
|
// NOTE: direct access to implementation details ahead, kinda fugly
|
||||||
auto const chunkindex { Chunk ^ sound_id::chunk };
|
auto const chunkindex { Chunk ^ sound_id::chunk };
|
||||||
@@ -607,6 +607,8 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
|||||||
// relative pitch adjustment
|
// relative pitch adjustment
|
||||||
// pitch of each chunk is modified based on ratio of the chunk's pitch to that of its neighbour
|
// pitch of each chunk is modified based on ratio of the chunk's pitch to that of its neighbour
|
||||||
if( soundpoint < chunkdata.threshold ) {
|
if( soundpoint < chunkdata.threshold ) {
|
||||||
|
|
||||||
|
if( chunkindex > 0 ) {
|
||||||
// interpolate between the pitch of previous chunk and this chunk's base pitch,
|
// interpolate between the pitch of previous chunk and this chunk's base pitch,
|
||||||
// based on how far the current soundpoint is in the range of previous chunk
|
// based on how far the current soundpoint is in the range of previous chunk
|
||||||
auto const &previouschunkdata{ m_soundchunks[ chunkindex - 1 ].second };
|
auto const &previouschunkdata{ m_soundchunks[ chunkindex - 1 ].second };
|
||||||
@@ -618,6 +620,7 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
|||||||
( soundpoint - previouschunkdata.threshold ) / ( chunkdata.threshold - previouschunkdata.threshold ),
|
( soundpoint - previouschunkdata.threshold ) / ( chunkdata.threshold - previouschunkdata.threshold ),
|
||||||
0.f, 1.f ) );
|
0.f, 1.f ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
if( chunkindex < ( m_soundchunks.size() - 1 ) ) {
|
if( chunkindex < ( m_soundchunks.size() - 1 ) ) {
|
||||||
@@ -721,6 +724,13 @@ sound_source::is_playing( bool const Includesoundends ) const {
|
|||||||
return isplaying;
|
return isplaying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns true if the source uses sample table
|
||||||
|
bool
|
||||||
|
sound_source::is_combined() const {
|
||||||
|
|
||||||
|
return ( ( !m_soundchunks.empty() ) && ( sound( sound_id::main ).buffer == null_handle ) );
|
||||||
|
}
|
||||||
|
|
||||||
// returns location of the sound source in simulation region space
|
// returns location of the sound source in simulation region space
|
||||||
glm::dvec3 const
|
glm::dvec3 const
|
||||||
sound_source::location() const {
|
sound_source::location() const {
|
||||||
@@ -756,12 +766,11 @@ float const EU07_SOUNDPROOFING_NONE { 1.f };
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
sound_source::update_soundproofing() {
|
sound_source::update_soundproofing() {
|
||||||
|
// NOTE, HACK: current cab id can vary from -1 to +1, and we use another higher priority value for open cab window
|
||||||
// NOTE, HACK: current cab id can vary from -1 to +1
|
// we use this as modifier to force re-calculations when moving between compartments or changing window state
|
||||||
// we use this as modifier to force re-calculations when moving between compartments
|
|
||||||
int const activecab = (
|
int const activecab = (
|
||||||
FreeFlyModeFlag ?
|
Global::CabWindowOpen ? 2 :
|
||||||
0 :
|
FreeFlyModeFlag ? 0 :
|
||||||
( Global::pWorld->train() ?
|
( Global::pWorld->train() ?
|
||||||
Global::pWorld->train()->Dynamic()->MoverParameters->ActiveCab :
|
Global::pWorld->train()->Dynamic()->MoverParameters->ActiveCab :
|
||||||
0 ) );
|
0 ) );
|
||||||
@@ -784,15 +793,15 @@ sound_source::update_soundproofing() {
|
|||||||
}
|
}
|
||||||
case sound_placement::external: {
|
case sound_placement::external: {
|
||||||
m_properties.soundproofing = (
|
m_properties.soundproofing = (
|
||||||
soundproofingstamp == 0 ?
|
( ( soundproofingstamp == 0 ) || ( true == Global::CabWindowOpen ) ) ?
|
||||||
EU07_SOUNDPROOFING_NONE : // listener outside
|
EU07_SOUNDPROOFING_NONE : // listener outside or has a window open
|
||||||
EU07_SOUNDPROOFING_STRONG ); // listener in a vehicle
|
EU07_SOUNDPROOFING_STRONG ); // listener in a vehicle with windows shut
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case sound_placement::internal: {
|
case sound_placement::internal: {
|
||||||
m_properties.soundproofing = (
|
m_properties.soundproofing = (
|
||||||
soundproofingstamp == 0 ?
|
soundproofingstamp == 0 ?
|
||||||
EU07_SOUNDPROOFING_STRONG : // listener outside
|
EU07_SOUNDPROOFING_STRONG : // listener outside HACK: won't be true if active vehicle has open window
|
||||||
( Global::pWorld->train()->Dynamic() != m_owner ?
|
( Global::pWorld->train()->Dynamic() != m_owner ?
|
||||||
EU07_SOUNDPROOFING_STRONG : // in another vehicle
|
EU07_SOUNDPROOFING_STRONG : // in another vehicle
|
||||||
( activecab == 0 ?
|
( activecab == 0 ?
|
||||||
@@ -802,8 +811,8 @@ sound_source::update_soundproofing() {
|
|||||||
}
|
}
|
||||||
case sound_placement::engine: {
|
case sound_placement::engine: {
|
||||||
m_properties.soundproofing = (
|
m_properties.soundproofing = (
|
||||||
soundproofingstamp == 0 ?
|
( ( soundproofingstamp == 0 ) || ( true == Global::CabWindowOpen ) ) ?
|
||||||
EU07_SOUNDPROOFING_SOME : // listener outside
|
EU07_SOUNDPROOFING_SOME : // listener outside or has a window open
|
||||||
( Global::pWorld->train()->Dynamic() != m_owner ?
|
( Global::pWorld->train()->Dynamic() != m_owner ?
|
||||||
EU07_SOUNDPROOFING_STRONG : // in another vehicle
|
EU07_SOUNDPROOFING_STRONG : // in another vehicle
|
||||||
( activecab == 0 ?
|
( activecab == 0 ?
|
||||||
|
|||||||
3
sound.h
3
sound.h
@@ -97,6 +97,9 @@ public:
|
|||||||
// returns true if the source is emitting any sound; by default doesn't take into account optional ending soudnds
|
// returns true if the source is emitting any sound; by default doesn't take into account optional ending soudnds
|
||||||
bool
|
bool
|
||||||
is_playing( bool const Includesoundends = false ) const;
|
is_playing( bool const Includesoundends = false ) const;
|
||||||
|
// returns true if the source uses sample table
|
||||||
|
bool
|
||||||
|
is_combined() const;
|
||||||
// returns location of the sound source in simulation region space
|
// returns location of the sound source in simulation region space
|
||||||
glm::dvec3 const
|
glm::dvec3 const
|
||||||
location() const;
|
location() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user