mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
tmj merge
This commit is contained in:
342
Camera.cpp
342
Camera.cpp
@@ -31,28 +31,29 @@ void TCamera::Init(vector3 NPos, vector3 NAngle)
|
||||
Type = (Global::bFreeFly ? tp_Free : tp_Follow);
|
||||
};
|
||||
|
||||
void TCamera::OnCursorMove(double x, double y)
|
||||
{
|
||||
// McZapkie-170402: zeby mysz dzialala zawsze if (Type==tp_Follow)
|
||||
void TCamera::OnCursorMove(double x, double y) {
|
||||
|
||||
Yaw -= x;
|
||||
Pitch -= y;
|
||||
if (Yaw > M_PI)
|
||||
while( Yaw > M_PI ) {
|
||||
Yaw -= 2 * M_PI;
|
||||
else if (Yaw < -M_PI)
|
||||
}
|
||||
while( Yaw < -M_PI ) {
|
||||
Yaw += 2 * M_PI;
|
||||
if (Type == tp_Follow) // jeżeli jazda z pojazdem
|
||||
{
|
||||
clamp(Pitch, -M_PI_4, M_PI_4); // ograniczenie kąta spoglądania w dół i w górę
|
||||
}
|
||||
Pitch -= y;
|
||||
if (Type == tp_Follow) {
|
||||
// jeżeli jazda z pojazdem ograniczenie kąta spoglądania w dół i w górę
|
||||
Pitch = clamp( Pitch, -M_PI_4, M_PI_4 );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
TCamera::OnCommand( command_data const &Command ) {
|
||||
|
||||
double const walkspeed = 1.0;
|
||||
double const runspeed = ( DebugModeFlag ? 50.0 : 7.5 );
|
||||
double const speedmultiplier = ( DebugModeFlag ? 7.5 : 1.0 );
|
||||
auto const walkspeed { 1.0 };
|
||||
auto const runspeed { 10.0 };
|
||||
|
||||
bool iscameracommand { true };
|
||||
switch( Command.command ) {
|
||||
|
||||
case user_command::viewturn: {
|
||||
@@ -63,232 +64,75 @@ TCamera::OnCommand( command_data const &Command ) {
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::movevector: {
|
||||
case user_command::movehorizontal:
|
||||
case user_command::movehorizontalfast: {
|
||||
|
||||
auto const movespeed =
|
||||
( Type == tp_Free ?
|
||||
runspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
auto const movespeed = (
|
||||
Type == tp_Free ? runspeed :
|
||||
Type == tp_Follow ? walkspeed :
|
||||
0.0 );
|
||||
|
||||
auto const speedmultiplier = (
|
||||
( ( Type == tp_Free ) && ( Command.command == user_command::movehorizontalfast ) ) ?
|
||||
30.0 :
|
||||
1.0 );
|
||||
|
||||
// left-right
|
||||
double const movex = reinterpret_cast<double const &>( Command.param1 );
|
||||
if( movex > 0.0 ) {
|
||||
m_keys.right = true;
|
||||
m_keys.left = false;
|
||||
}
|
||||
else if( movex < 0.0 ) {
|
||||
m_keys.right = false;
|
||||
m_keys.left = true;
|
||||
}
|
||||
else {
|
||||
m_keys.right = false;
|
||||
m_keys.left = false;
|
||||
}
|
||||
auto const movexparam { reinterpret_cast<double const &>( Command.param1 ) };
|
||||
// 2/3rd of the stick range enables walk speed, past that we lerp between walk and run speed
|
||||
m_moverate.x =
|
||||
walkspeed
|
||||
+ ( std::max( 0.0, std::abs( movex ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed );
|
||||
auto const movex { walkspeed + ( std::max( 0.0, std::abs( movexparam ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed ) };
|
||||
|
||||
m_moverate.x = (
|
||||
movexparam > 0.0 ? movex * speedmultiplier :
|
||||
movexparam < 0.0 ? -movex * speedmultiplier :
|
||||
0.0 );
|
||||
|
||||
// forward-back
|
||||
double const movez = reinterpret_cast<double const &>( Command.param2 );
|
||||
if( movez > 0.0 ) {
|
||||
m_keys.forward = true;
|
||||
m_keys.back = false;
|
||||
}
|
||||
else if( movez < 0.0 ) {
|
||||
m_keys.forward = false;
|
||||
m_keys.back = true;
|
||||
}
|
||||
else {
|
||||
m_keys.forward = false;
|
||||
m_keys.back = false;
|
||||
}
|
||||
m_moverate.z =
|
||||
walkspeed
|
||||
+ ( std::max( 0.0, std::abs( movez ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed );
|
||||
double const movezparam { reinterpret_cast<double const &>( Command.param2 ) };
|
||||
auto const movez { walkspeed + ( std::max( 0.0, std::abs( movezparam ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed ) };
|
||||
// NOTE: z-axis is flipped given world coordinate system
|
||||
m_moverate.z = (
|
||||
movezparam > 0.0 ? -movez * speedmultiplier :
|
||||
movezparam < 0.0 ? movez * speedmultiplier :
|
||||
0.0 );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::moveforward: {
|
||||
case user_command::movevertical:
|
||||
case user_command::moveverticalfast: {
|
||||
|
||||
auto const movespeed = (
|
||||
Type == tp_Free ? runspeed * 0.5 :
|
||||
Type == tp_Follow ? walkspeed :
|
||||
0.0 );
|
||||
|
||||
auto const speedmultiplier = (
|
||||
( ( Type == tp_Free ) && ( Command.command == user_command::moveverticalfast ) ) ?
|
||||
10.0 :
|
||||
1.0 );
|
||||
|
||||
// up-down
|
||||
auto const moveyparam { reinterpret_cast<double const &>( Command.param1 ) };
|
||||
// 2/3rd of the stick range enables walk speed, past that we lerp between walk and run speed
|
||||
auto const movey { walkspeed + ( std::max( 0.0, std::abs( moveyparam ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed ) };
|
||||
|
||||
m_moverate.y = (
|
||||
moveyparam > 0.0 ? movey * speedmultiplier :
|
||||
moveyparam < 0.0 ? -movey * speedmultiplier :
|
||||
0.0 );
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.forward = true;
|
||||
m_moverate.z =
|
||||
( Type == tp_Free ?
|
||||
walkspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.forward = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::moveback: {
|
||||
default: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.back = true;
|
||||
m_moverate.z =
|
||||
( Type == tp_Free ?
|
||||
walkspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.back = false;
|
||||
}
|
||||
iscameracommand = false;
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
|
||||
case user_command::moveleft: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.left = true;
|
||||
m_moverate.x =
|
||||
( Type == tp_Free ?
|
||||
walkspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.left = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::moveright: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.right = true;
|
||||
m_moverate.x =
|
||||
( Type == tp_Free ?
|
||||
walkspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.right = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::moveup: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.up = true;
|
||||
m_moverate.y =
|
||||
( Type == tp_Free ?
|
||||
walkspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.up = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::movedown: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.down = true;
|
||||
m_moverate.y =
|
||||
( Type == tp_Free ?
|
||||
walkspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.down = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::moveforwardfast: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.forward = true;
|
||||
m_moverate.z =
|
||||
( Type == tp_Free ?
|
||||
runspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.forward = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::movebackfast: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.back = true;
|
||||
m_moverate.z =
|
||||
( Type == tp_Free ?
|
||||
runspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.back = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::moveleftfast: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.left = true;
|
||||
m_moverate.x =
|
||||
( Type == tp_Free ?
|
||||
runspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.left = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::moverightfast: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.right = true;
|
||||
m_moverate.x =
|
||||
( Type == tp_Free ?
|
||||
runspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.right = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::moveupfast: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.up = true;
|
||||
m_moverate.y =
|
||||
( Type == tp_Free ?
|
||||
runspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.up = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::movedownfast: {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
m_keys.down = true;
|
||||
m_moverate.y =
|
||||
( Type == tp_Free ?
|
||||
runspeed * speedmultiplier :
|
||||
walkspeed );
|
||||
}
|
||||
else {
|
||||
m_keys.down = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return iscameracommand;
|
||||
}
|
||||
|
||||
void TCamera::Update()
|
||||
@@ -309,61 +153,15 @@ void TCamera::Update()
|
||||
|
||||
auto const deltatime = Timer::GetDeltaRenderTime(); // czas bez pauzy
|
||||
|
||||
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
|
||||
double a = 0.8; // default (walk) movement speed
|
||||
if( Type == tp_Free ) {
|
||||
// when not in the cab the speed modifiers are active
|
||||
if( Global::shiftState ) { a = 2.5; }
|
||||
if( Global::ctrlState ) { a *= 10.0; }
|
||||
}
|
||||
|
||||
if( ( Type == tp_Free )
|
||||
|| ( false == Global::ctrlState ) ) {
|
||||
// ctrl is used for mirror view, so we ignore the controls when in vehicle if ctrl is pressed
|
||||
if( Console::Pressed( Global::Keys[ k_MechUp ] ) )
|
||||
Velocity.y = clamp( Velocity.y + a * 10.0 * deltatime, -a, a );
|
||||
if( Console::Pressed( Global::Keys[ k_MechDown ] ) )
|
||||
Velocity.y = clamp( Velocity.y - a * 10.0 * deltatime, -a, a );
|
||||
|
||||
// McZapkie-170402: poruszanie i rozgladanie we free takie samo jak w follow
|
||||
if( Console::Pressed( Global::Keys[ k_MechRight ] ) )
|
||||
Velocity.x = clamp( Velocity.x + a * 10.0 * deltatime, -a, a );
|
||||
if( Console::Pressed( Global::Keys[ k_MechLeft ] ) )
|
||||
Velocity.x = clamp( Velocity.x - a * 10.0 * deltatime, -a, a );
|
||||
if( Console::Pressed( Global::Keys[ k_MechForward ] ) )
|
||||
Velocity.z = clamp( Velocity.z - a * 10.0 * deltatime, -a, a );
|
||||
if( Console::Pressed( Global::Keys[ k_MechBackward ] ) )
|
||||
Velocity.z = clamp( Velocity.z + a * 10.0 * deltatime, -a, a );
|
||||
}
|
||||
#else
|
||||
/*
|
||||
m_moverate = 0.8; // default (walk) movement speed
|
||||
if( Type == tp_Free ) {
|
||||
// when not in the cab the speed modifiers are active
|
||||
if( Global::shiftState ) { m_moverate = 2.5; }
|
||||
if( Global::ctrlState ) { m_moverate *= 10.0; }
|
||||
}
|
||||
*/
|
||||
if( ( Type == tp_Free )
|
||||
|| ( false == Global::ctrlState )
|
||||
|| ( true == DebugCameraFlag) ) {
|
||||
|| ( true == DebugCameraFlag ) ) {
|
||||
// ctrl is used for mirror view, so we ignore the controls when in vehicle if ctrl is pressed
|
||||
if( m_keys.up )
|
||||
Velocity.y = clamp( Velocity.y + m_moverate.y * 10.0 * deltatime, -m_moverate.y, m_moverate.y );
|
||||
if( m_keys.down )
|
||||
Velocity.y = clamp( Velocity.y - m_moverate.y * 10.0 * deltatime, -m_moverate.y, m_moverate.y );
|
||||
|
||||
// McZapkie-170402: poruszanie i rozgladanie we free takie samo jak w follow
|
||||
if( m_keys.right )
|
||||
Velocity.x = clamp( Velocity.x + m_moverate.x * 10.0 * deltatime, -m_moverate.x, m_moverate.x );
|
||||
if( m_keys.left )
|
||||
Velocity.x = clamp( Velocity.x - m_moverate.x * 10.0 * deltatime, -m_moverate.x, m_moverate.x );
|
||||
if( m_keys.forward )
|
||||
Velocity.z = clamp( Velocity.z - m_moverate.z * 10.0 * deltatime, -m_moverate.z, m_moverate.z );
|
||||
if( m_keys.back )
|
||||
Velocity.z = clamp( Velocity.z + m_moverate.z * 10.0 * deltatime, -m_moverate.z, m_moverate.z );
|
||||
Velocity.x = clamp( Velocity.x + m_moverate.x * 10.0 * deltatime, -std::abs( m_moverate.x ), std::abs( m_moverate.x ) );
|
||||
Velocity.z = clamp( Velocity.z + m_moverate.z * 10.0 * deltatime, -std::abs( m_moverate.z ), std::abs( m_moverate.z ) );
|
||||
Velocity.y = clamp( Velocity.y + m_moverate.y * 10.0 * deltatime, -std::abs( m_moverate.y ), std::abs( m_moverate.y ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ( Type == tp_Free )
|
||||
|| ( true == DebugCameraFlag ) ) {
|
||||
|
||||
11
Camera.h
11
Camera.h
@@ -26,15 +26,6 @@ enum TCameraType
|
||||
class TCamera
|
||||
{
|
||||
private:
|
||||
struct keys {
|
||||
bool forward{ false };
|
||||
bool back{ false };
|
||||
bool left{ false };
|
||||
bool right{ false };
|
||||
bool up{ false };
|
||||
bool down{ false };
|
||||
bool run{ false };
|
||||
} m_keys;
|
||||
glm::dvec3 m_moverate;
|
||||
|
||||
public: // McZapkie: potrzebuje do kiwania na boki
|
||||
@@ -51,7 +42,7 @@ class TCamera
|
||||
void Reset() {
|
||||
Pitch = Yaw = Roll = 0; };
|
||||
void OnCursorMove(double const x, double const y);
|
||||
void OnCommand( command_data const &Command );
|
||||
bool OnCommand( command_data const &Command );
|
||||
void Update();
|
||||
vector3 GetDirection();
|
||||
bool SetMatrix(glm::dmat4 &Matrix);
|
||||
|
||||
@@ -4527,7 +4527,6 @@ TController::UpdateSituation(double dt) {
|
||||
AbsAccS /= fMass;
|
||||
}
|
||||
AbsAccS_pub = AbsAccS;
|
||||
AbsAccS_avg = interpolate( AbsAccS_avg, mvOccupied->AccS * iDirection, 0.25 );
|
||||
|
||||
#if LOGVELOCITY
|
||||
// WriteLog("VelDesired="+AnsiString(VelDesired)+",
|
||||
|
||||
1
Driver.h
1
Driver.h
@@ -209,7 +209,6 @@ public:
|
||||
double BrakeAccFactor();
|
||||
double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h)
|
||||
double fAccThreshold = 0.0; // próg opóźnienia dla zadziałania hamulca
|
||||
double AbsAccS_avg = 0.0; // averaged out directional acceleration
|
||||
double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca
|
||||
double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca
|
||||
double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca
|
||||
|
||||
155
DynObj.cpp
155
DynObj.cpp
@@ -1751,10 +1751,11 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
// McZapkie: TypeName musi byc nazwą CHK/MMD pojazdu
|
||||
if (!MoverParameters->LoadFIZ(asBaseDir))
|
||||
{ // jak wczytanie CHK się nie uda, to błąd
|
||||
if (ConversionError == -8)
|
||||
ErrorLog("Missed file: " + BaseDir + "\\" + Type_Name + ".fiz");
|
||||
Error("Cannot load dynamic object " + asName + " from:\r\n" + BaseDir + "\\" + Type_Name +
|
||||
".fiz\r\nError " + to_string(ConversionError));
|
||||
if (ConversionError == 666)
|
||||
ErrorLog( "Bad vehicle: failed do locate definition file \"" + BaseDir + "\\" + Type_Name + ".fiz" + "\"" );
|
||||
else {
|
||||
ErrorLog( "Bad vehicle: failed to load definition from file \"" + BaseDir + "\\" + Type_Name + ".fiz\" (error " + to_string( ConversionError ) + ")" );
|
||||
}
|
||||
return 0.0; // zerowa długość to brak pojazdu
|
||||
}
|
||||
bool driveractive = (fVel != 0.0); // jeśli prędkość niezerowa, to aktywujemy ruch
|
||||
@@ -2966,27 +2967,26 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
}
|
||||
}
|
||||
|
||||
auto axleindex { 0 };
|
||||
for( auto &axle : m_axlesounds ) {
|
||||
axle.distance -= dDOMoveLen * Sign( dDOMoveLen );
|
||||
if( axle.distance < 0 ) {
|
||||
axle.distance += dRailLength;
|
||||
/*
|
||||
// McZapkie-040302
|
||||
if( i == iAxles - 1 ) {
|
||||
rsStukot[ 0 ].stop();
|
||||
MoverParameters->AccV += 0.5 * GetVelocity() / ( 1 + MoverParameters->Vmax );
|
||||
}
|
||||
else {
|
||||
rsStukot[ i + 1 ].stop();
|
||||
}
|
||||
if( i == 1 ) {
|
||||
MoverParameters->AccV -= 0.5 * GetVelocity() / ( 1 + MoverParameters->Vmax );
|
||||
}
|
||||
*/
|
||||
if( MoverParameters->Vel > 2.5 ) {
|
||||
axle.clatter.gain( volume ).play();
|
||||
// crude bump simulation, drop down on even axles, move back up on the odd ones
|
||||
MoverParameters->AccVert +=
|
||||
interpolate(
|
||||
0.25, 0.50,
|
||||
clamp(
|
||||
GetVelocity() / ( 1 + MoverParameters->Vmax ),
|
||||
0.0, 1.0 ) )
|
||||
* ( ( axleindex % 2 ) != 0 ?
|
||||
1 :
|
||||
-1 );
|
||||
}
|
||||
}
|
||||
++axleindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3495,7 +3495,7 @@ void TDynamicObject::RenderSounds() {
|
||||
if( MoverParameters->ConverterFlag ) {
|
||||
frequency = (
|
||||
MoverParameters->EngineType == ElectricSeriesMotor ?
|
||||
MoverParameters->Voltage / ( MoverParameters->NominalVoltage * MoverParameters->RList[ MoverParameters->RlistSize ].Mn ) :
|
||||
( MoverParameters->RunningTraction.TractionVoltage / MoverParameters->NominalVoltage ) * MoverParameters->RList[ MoverParameters->RlistSize ].Mn :
|
||||
1.0 );
|
||||
frequency = sConverter.m_frequencyoffset + sConverter.m_frequencyfactor * frequency;
|
||||
sConverter
|
||||
@@ -3610,21 +3610,22 @@ void TDynamicObject::RenderSounds() {
|
||||
}
|
||||
|
||||
// McZapkie-280302 - pisk mocno zacisnietych hamulcow
|
||||
if( //( false == MoverParameters->SlippingWheels ) &&
|
||||
( MoverParameters->UnitBrakeForce > rsPisk.m_amplitudefactor )
|
||||
&& ( MoverParameters->Vel > 2.5 ) ) {
|
||||
if( MoverParameters->Vel > 2.5 ) {
|
||||
|
||||
rsPisk
|
||||
.gain( MoverParameters->UnitBrakeForce / ( rsPisk.m_amplitudefactor + 1 ) + rsPisk.m_amplitudeoffset )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
volume = rsPisk.m_amplitudeoffset + interpolate( -1.0, 1.0, brakeforceratio ) * rsPisk.m_amplitudefactor;
|
||||
if( volume > 0.075 ) {
|
||||
rsPisk
|
||||
.gain( volume )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// don't stop the sound too abruptly
|
||||
volume = std::max( 0.0, rsPisk.gain() - ( rsPisk.gain() * 2.5 * dt ) );
|
||||
rsPisk.gain( volume );
|
||||
if( volume < 0.05 ) {
|
||||
rsPisk.stop();
|
||||
}
|
||||
}
|
||||
if( volume < 0.05 ) {
|
||||
rsPisk.stop();
|
||||
}
|
||||
|
||||
// other sounds
|
||||
@@ -3771,24 +3772,6 @@ void TDynamicObject::RenderSounds() {
|
||||
|
||||
// McZapkie! - to wazne - SoundFlag wystawiane jest przez moje moduly
|
||||
// gdy zachodza pewne wydarzenia komentowane dzwiekiem.
|
||||
if( TestFlag( MoverParameters->SoundFlag, sound::relay ) ) {
|
||||
// przekaznik - gdy bezpiecznik, automatyczny rozruch itp
|
||||
if( true == TestFlag( MoverParameters->SoundFlag, sound::parallel ) ) {
|
||||
if( TestFlag( MoverParameters->SoundFlag, sound::loud ) )
|
||||
m_powertrainsounds.dsbWejscie_na_bezoporow.play();
|
||||
else
|
||||
m_powertrainsounds.motor_parallel.play();
|
||||
}
|
||||
else {
|
||||
m_powertrainsounds.motor_relay
|
||||
.gain(
|
||||
true == TestFlag( MoverParameters->SoundFlag, sound::loud ) ?
|
||||
1.0f :
|
||||
0.8f )
|
||||
.play();
|
||||
}
|
||||
}
|
||||
|
||||
if( TestFlag( MoverParameters->SoundFlag, sound::pneumatic ) ) {
|
||||
// pneumatic relay
|
||||
dsbPneumaticRelay
|
||||
@@ -3798,7 +3781,6 @@ void TDynamicObject::RenderSounds() {
|
||||
0.8f )
|
||||
.play();
|
||||
}
|
||||
|
||||
// couplers
|
||||
int couplerindex { 0 };
|
||||
for( auto &couplersounds : m_couplersounds ) {
|
||||
@@ -4581,6 +4563,12 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
m_powertrainsounds.engine.m_amplitudefactor /= amplitudedivisor;
|
||||
}
|
||||
|
||||
else if( token == "dieselinc:" ) {
|
||||
// dzwiek przy wlazeniu na obroty woodwarda
|
||||
m_powertrainsounds.engine_revving.deserialize( parser, sound_type::single, sound_parameters::range );
|
||||
m_powertrainsounds.engine_revving.owner( this );
|
||||
}
|
||||
|
||||
else if( ( token == "tractionmotor:" )
|
||||
&& ( MoverParameters->Power > 0 ) ) {
|
||||
// plik z dzwiekiem silnika, mnozniki i ofsety amp. i czest.
|
||||
@@ -4620,6 +4608,11 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
rsPisk.deserialize( parser, sound_type::single, sound_parameters::range | sound_parameters::amplitude );
|
||||
rsPisk.owner( this );
|
||||
|
||||
if( rsPisk.m_amplitudefactor > 10.f ) {
|
||||
// HACK: convert old style activation point threshold to the new, regular amplitude adjustment system
|
||||
rsPisk.m_amplitudefactor = 1.f;
|
||||
rsPisk.m_amplitudeoffset = 0.f;
|
||||
}
|
||||
rsPisk.m_amplitudeoffset *= ( 105.f - Random( 10.f ) ) / 100.f;
|
||||
}
|
||||
|
||||
@@ -4643,12 +4636,6 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
rsDerailment.owner( this );
|
||||
}
|
||||
|
||||
else if( token == "dieselinc:" ) {
|
||||
// dzwiek przy wlazeniu na obroty woodwarda
|
||||
m_powertrainsounds.engine_revving.deserialize( parser, sound_type::single, sound_parameters::range );
|
||||
m_powertrainsounds.engine_revving.owner( this );
|
||||
}
|
||||
|
||||
else if( token == "curve:" ) {
|
||||
rscurve.deserialize( parser, sound_type::single, sound_parameters::range );
|
||||
rscurve.owner( this );
|
||||
@@ -4805,10 +4792,10 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
m_powertrainsounds.motor_relay.deserialize( parser, sound_type::single );
|
||||
m_powertrainsounds.motor_relay.owner( this );
|
||||
}
|
||||
else if( token == "pneumaticrelay:" ) {
|
||||
// wylaczniki pneumatyczne:
|
||||
dsbPneumaticRelay.deserialize( parser, sound_type::single );
|
||||
dsbPneumaticRelay.owner( this );
|
||||
else if( token == "shuntfield:" ) {
|
||||
// styczniki itp:
|
||||
m_powertrainsounds.motor_shuntfield.deserialize( parser, sound_type::single );
|
||||
m_powertrainsounds.motor_shuntfield.owner( this );
|
||||
}
|
||||
else if( token == "wejscie_na_bezoporow:" ) {
|
||||
// hunter-111211: wydzielenie wejscia na bezoporowa i na drugi uklad do pliku
|
||||
@@ -4819,6 +4806,11 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
m_powertrainsounds.motor_parallel.deserialize( parser, sound_type::single );
|
||||
m_powertrainsounds.motor_parallel.owner( this );
|
||||
}
|
||||
else if( token == "pneumaticrelay:" ) {
|
||||
// wylaczniki pneumatyczne:
|
||||
dsbPneumaticRelay.deserialize( parser, sound_type::single );
|
||||
dsbPneumaticRelay.owner( this );
|
||||
}
|
||||
// braking sounds
|
||||
else if( token == "brakesound:" ) {
|
||||
// hamowanie zwykle:
|
||||
@@ -5580,8 +5572,14 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
||||
}
|
||||
engine_revs_last = Vehicle.enrot * 60;
|
||||
|
||||
if( false == engine_revving.is_combined() ) {
|
||||
// if the sound comes with multiple samples we reuse rpm-based calculation from the engine
|
||||
frequency = engine_revving.m_frequencyoffset + engine_revving.m_frequencyfactor * 1.0;
|
||||
}
|
||||
|
||||
if( enginerevvolume > 0.02 ) {
|
||||
engine_revving
|
||||
.pitch( frequency )
|
||||
.gain( enginerevvolume )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
@@ -5757,6 +5755,50 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
||||
motor.stop();
|
||||
}
|
||||
|
||||
auto const soundflags { Vehicle.SoundFlag };
|
||||
if( TestFlag( soundflags, sound::relay ) ) {
|
||||
// przekaznik - gdy bezpiecznik, automatyczny rozruch itp
|
||||
if( true == TestFlag( soundflags, sound::shuntfield ) ) {
|
||||
// shunt field
|
||||
motor_shuntfield
|
||||
.pitch(
|
||||
true == motor_shuntfield.is_combined() ?
|
||||
Vehicle.ScndCtrlActualPos * 0.01f :
|
||||
motor_shuntfield.m_frequencyoffset + 1.f * motor_shuntfield.m_frequencyfactor )
|
||||
.gain(
|
||||
motor_shuntfield.m_amplitudeoffset + (
|
||||
true == TestFlag( soundflags, sound::loud ) ?
|
||||
1.0f :
|
||||
0.8f )
|
||||
* motor_shuntfield.m_amplitudefactor )
|
||||
.play();
|
||||
}
|
||||
else if( true == TestFlag( soundflags, sound::parallel ) ) {
|
||||
// parallel mode
|
||||
if( TestFlag( soundflags, sound::loud ) ) {
|
||||
dsbWejscie_na_bezoporow.play();
|
||||
}
|
||||
else {
|
||||
motor_parallel.play();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// series mode
|
||||
motor_relay
|
||||
.pitch(
|
||||
true == motor_relay.is_combined() ?
|
||||
Vehicle.MainCtrlActualPos * 0.01f :
|
||||
motor_relay.m_frequencyoffset + 1.f * motor_relay.m_frequencyfactor )
|
||||
.gain(
|
||||
motor_relay.m_amplitudeoffset + (
|
||||
true == TestFlag( soundflags, sound::loud ) ?
|
||||
1.0f :
|
||||
0.8f )
|
||||
* motor_relay.m_amplitudefactor )
|
||||
.play();
|
||||
}
|
||||
}
|
||||
|
||||
if( ( Vehicle.EngineType == ElectricSeriesMotor )
|
||||
|| ( Vehicle.EngineType == ElectricInductionMotor ) ) {
|
||||
|
||||
@@ -5778,7 +5820,6 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( Vehicle.TrainType == dt_ET40 ) {
|
||||
if( Vehicle.Vel > 0.1 ) {
|
||||
transmission
|
||||
|
||||
1
DynObj.h
1
DynObj.h
@@ -290,6 +290,7 @@ private:
|
||||
sound_source motor_relay { sound_placement::engine };
|
||||
sound_source dsbWejscie_na_bezoporow { sound_placement::engine }; // moved from cab
|
||||
sound_source motor_parallel { sound_placement::engine }; // moved from cab
|
||||
sound_source motor_shuntfield { sound_placement::engine };
|
||||
sound_source rsWentylator { sound_placement::engine }; // McZapkie-030302
|
||||
sound_source engine { sound_placement::engine }; // generally diesel engine
|
||||
sound_source engine_ignition { sound_placement::engine }; // moved from cab
|
||||
|
||||
@@ -1034,12 +1034,12 @@ event_manager::CheckQuery() {
|
||||
static_cast<int>( m_workevent->Params[ 1 ].asdouble ) );
|
||||
}
|
||||
else {
|
||||
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive );
|
||||
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive | sound_flags::event );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case -1: {
|
||||
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive | sound_flags::looping );
|
||||
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive | sound_flags::looping | sound_flags::event );
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
||||
23
Globals.cpp
23
Globals.cpp
@@ -1013,28 +1013,11 @@ void TTranscripts::AddLine(std::string const &txt, float show, float hide, bool
|
||||
}
|
||||
*/
|
||||
};
|
||||
void TTranscripts::Add(std::string const &txt, float len, bool backgorund)
|
||||
void TTranscripts::Add(std::string const &txt, bool backgorund)
|
||||
{ // dodanie tekstów, długość dźwięku, czy istotne
|
||||
if (true == txt.empty())
|
||||
return; // pusty tekst
|
||||
/*
|
||||
int i = 0, j = int(0.5 + 10.0 * len); //[0.1s]
|
||||
if (*txt == '[')
|
||||
{ // powinny być dwa nawiasy
|
||||
while (*++txt ? *txt != ']' : false)
|
||||
if ((*txt >= '0') && (*txt <= '9'))
|
||||
i = 10 * i + int(*txt - '0'); // pierwsza liczba aż do ]
|
||||
if (*txt ? *++txt == '[' : false)
|
||||
{
|
||||
j = 0; // drugi nawias określa czas zakończenia wyświetlania
|
||||
while (*++txt ? *txt != ']' : false)
|
||||
if ((*txt >= '0') && (*txt <= '9'))
|
||||
j = 10 * j + int(*txt - '0'); // druga liczba aż do ]
|
||||
if (*txt)
|
||||
++txt; // pominięcie drugiego ]
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
std::string asciitext{ txt }; win1250_to_ascii( asciitext ); // TODO: launch relevant conversion table based on language
|
||||
cParser parser( asciitext );
|
||||
while( true == parser.getTokens( 3, false, "[]\n" ) ) {
|
||||
@@ -1051,7 +1034,7 @@ void TTranscripts::Add(std::string const &txt, float len, bool backgorund)
|
||||
std::string transcript; parser >> transcript;
|
||||
while( false == transcript.empty() ) {
|
||||
|
||||
WriteLog( "Transcript text with no display/hide times: \"" + transcript + "\"" );
|
||||
// WriteLog( "Transcript text with no display/hide times: \"" + transcript + "\"" );
|
||||
AddLine( transcript, 0.0, 0.12 * transcript.size(), false );
|
||||
transcript = ""; parser >> transcript;
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ private:
|
||||
~TTranscripts();
|
||||
void AddLine(std::string const &txt, float show, float hide, bool it);
|
||||
// dodanie tekstów, długość dźwięku, czy istotne
|
||||
void Add(std::string const &txt, float len, bool background = false);
|
||||
void Add(std::string const &txt, bool background = false);
|
||||
// usuwanie niepotrzebnych (ok. 10 razy na sekundę)
|
||||
void Update();
|
||||
};
|
||||
|
||||
@@ -204,7 +204,8 @@ enum sound {
|
||||
bufferclash = 0x4,
|
||||
relay = 0x10,
|
||||
parallel = 0x20,
|
||||
pneumatic = 0x40
|
||||
shuntfield = 0x40,
|
||||
pneumatic = 0x80
|
||||
};
|
||||
|
||||
//szczególne typy pojazdów (inna obsługa) dla zmiennej TrainType
|
||||
@@ -769,6 +770,31 @@ public:
|
||||
double dizel_minVelfullengage = 0.0; /*najmniejsza predkosc przy jezdzie ze sprzeglem bez poslizgu*/
|
||||
double dizel_AIM = 1.0; /*moment bezwladnosci walu itp*/
|
||||
double dizel_engageDia = 0.5; double dizel_engageMaxForce = 6000.0; double dizel_engagefriction = 0.5; /*parametry sprzegla*/
|
||||
double engagedownspeed = 0.9;
|
||||
double engageupspeed = 0.5;
|
||||
/*parametry przetwornika momentu*/
|
||||
bool hydro_TC = false; /*obecnosc hydraulicznego przetwornika momentu*/
|
||||
double hydro_TC_TMMax = 2.0; /*maksymalne wzmocnienie momentu*/
|
||||
double hydro_TC_CouplingPoint = 0.85; /*wzgledna predkosc zasprzeglenia*/
|
||||
double hydro_TC_LockupTorque = 3000.0; /*moment graniczny sprzegla blokujacego*/
|
||||
double hydro_TC_LockupRate = 1.0; /*szybkosc zalaczania sprzegla blokujacego*/
|
||||
double hydro_TC_UnlockRate = 1.0; /*szybkosc rozlaczania sprzegla blokujacego*/
|
||||
double hydro_TC_FillRateInc = 1.0; /*szybkosc napelniania sprzegla*/
|
||||
double hydro_TC_FillRateDec = 1.0; /*szybkosc oprozniania sprzegla*/
|
||||
double hydro_TC_TorqueInIn = 4.5; /*stala momentu proporcjonalnego do kwadratu obrotow wejsciowych*/
|
||||
double hydro_TC_TorqueInOut = 0.0; /*stala momentu proporcjonalnego do roznica obrotow wejsciowych i wyjsciowych*/
|
||||
double hydro_TC_TorqueOutOut = 0.0; /*stala momentu proporcjonalnego do kwadratu obrotow wyjsciowych*/
|
||||
double hydro_TC_LockupSpeed = 1.0; /*prog predkosci zalaczania sprzegla blokujacego*/
|
||||
double hydro_TC_UnlockSpeed = 1.0; /*prog predkosci rozlaczania sprzegla blokujacego*/
|
||||
/*parametry retardera*/
|
||||
bool hydro_R = false; /*obecnosc retardera*/
|
||||
int hydro_R_Placement = 0; /*umiejscowienie retardera: 0 - za skrzynia biegow, 1 - miedzy przetwornikiem a biegami, 2 - przed skrzynia biegow */
|
||||
double hydro_R_TorqueInIn = 1.0; /*stala momentu proporcjonalnego do kwadratu obrotow wejsciowych*/
|
||||
double hydro_R_MaxTorque = 1.0; /*maksymalny moment retardera*/
|
||||
double hydro_R_MaxPower = 1.0; /*maksymalna moc retardera - ogranicza moment*/
|
||||
double hydro_R_FillRateInc = 1.0; /*szybkosc napelniania sprzegla*/
|
||||
double hydro_R_FillRateDec = 1.0; /*szybkosc oprozniania sprzegla*/
|
||||
double hydro_R_MinVel = 1.0; /*minimalna predkosc, przy ktorej retarder dziala*/
|
||||
/*- dla lokomotyw spalinowo-elektrycznych -*/
|
||||
double AnPos = 0.0; // pozycja sterowania dokladnego (analogowego)
|
||||
bool AnalogCtrl = false; //
|
||||
@@ -824,8 +850,9 @@ public:
|
||||
double V = 0.0; //predkosc w [m/s] względem sprzęgów (dodania gdy jedzie w stronę 0)
|
||||
double Vel = 0.0; //moduł prędkości w [km/h], używany przez AI
|
||||
double AccS = 0.0; //efektywne przyspieszenie styczne w [m/s^2] (wszystkie siły)
|
||||
double AccN = 0.0; //przyspieszenie normalne w [m/s^2]
|
||||
double AccV = 0.0;
|
||||
double AccSVBased {}; // tangential acceleration calculated from velocity change
|
||||
double AccN = 0.0; // przyspieszenie normalne w [m/s^2]
|
||||
double AccVert = 0.0; // vertical acceleration
|
||||
double nrot = 0.0;
|
||||
double WheelFlat = 0.0;
|
||||
/*! rotacja kol [obr/s]*/
|
||||
@@ -957,6 +984,24 @@ public:
|
||||
double dizel_automaticgearstatus = 0.0; /*0 - bez zmiany, -1 zmiana na nizszy +1 zmiana na wyzszy*/
|
||||
bool dizel_enginestart = false; /*czy trwa rozruch silnika*/
|
||||
double dizel_engagedeltaomega = 0.0; /*roznica predkosci katowych tarcz sprzegla*/
|
||||
double dizel_n_old = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
||||
double dizel_Torque = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
||||
|
||||
/* - zmienne dla przetowrnika momentu */
|
||||
double hydro_TC_Fill = 0.0; /*napelnienie*/
|
||||
bool hydro_TC_Lockup = false; /*zapiecie sprzegla*/
|
||||
double hydro_TC_TorqueIn = 0.0; /*moment*/
|
||||
double hydro_TC_TorqueOut = 0.0; /*moment*/
|
||||
double hydro_TC_TMRatio = 1.0; /*aktualne przelozenie momentu*/
|
||||
double hydro_TC_Request = 0.0; /*zadanie sily*/
|
||||
double hydro_TC_nIn = 0.0; /*predkosc obrotowa walu wejsciowego*/
|
||||
double hydro_TC_nOut = 0.0; /*predkosc obrotowa walu wyjsciowego*/
|
||||
|
||||
/* - zmienne dla przetowrnika momentu */
|
||||
double hydro_R_Fill = 0.0; /*napelnienie*/
|
||||
double hydro_R_Torque = 0.0; /*moment*/
|
||||
double hydro_R_Request = 0.0; /*zadanie sily hamowania*/
|
||||
double hydro_R_n = 0.0; /*predkosc obrotowa retardera*/
|
||||
|
||||
/*- zmienne dla lokomotyw z silnikami indukcyjnymi -*/
|
||||
double eimv[21];
|
||||
|
||||
@@ -1115,7 +1115,6 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
{
|
||||
const double Vepsilon = 1e-5;
|
||||
const double Aepsilon = 1e-3; // ASBSpeed=0.8;
|
||||
double Vprev, AccSprev, d;
|
||||
|
||||
// T_MoverParameters::ComputeMovement(dt, dt1, Shape, Track, ElectricTraction, NewLoc, NewRot);
|
||||
// // najpierw kawalek z funkcji w pliku mover.pas
|
||||
@@ -1259,12 +1258,13 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
|
||||
if (dL == 0) // oblicz przesuniecie}
|
||||
{
|
||||
Vprev = V;
|
||||
AccSprev = AccS;
|
||||
// dt:=ActualTime-LastUpdatedTime; //przyrost czasu
|
||||
auto const AccSprev { AccS };
|
||||
// przyspieszenie styczne
|
||||
AccS = (FTotal / TotalMass + AccSprev) /
|
||||
2.0; // prawo Newtona ale z wygladzaniem (średnia z poprzednim)
|
||||
AccS = interpolate(
|
||||
AccSprev,
|
||||
FTotal / TotalMass,
|
||||
0.5 );
|
||||
// clamp( dt * 3.0, 0.0, 1.0 ) ); // prawo Newtona ale z wygladzaniem (średnia z poprzednim)
|
||||
|
||||
if (TestFlag(DamageFlag, dtrain_out))
|
||||
AccS = -Sign(V) * g * 1; // random(0.0, 0.1)
|
||||
@@ -1275,7 +1275,29 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
else
|
||||
AccN = g * Shape.dHrail / TrackW;
|
||||
|
||||
// velocity change
|
||||
auto const Vprev { V };
|
||||
V += ( 3.0 * AccS - AccSprev ) * dt / 2.0; // przyrost predkosci
|
||||
if( ( V * Vprev <= 0 )
|
||||
&& ( std::abs( FStand ) > std::abs( FTrain ) ) ) {
|
||||
// tlumienie predkosci przy hamowaniu
|
||||
// zahamowany
|
||||
V = 0;
|
||||
}
|
||||
|
||||
// tangential acceleration, from velocity change
|
||||
AccSVBased = interpolate(
|
||||
AccSVBased,
|
||||
( V - Vprev ) / dt,
|
||||
clamp( dt * 3.0, 0.0, 1.0 ) );
|
||||
|
||||
// vertical acceleration
|
||||
AccVert = (
|
||||
std::abs( AccVert ) < 0.01 ?
|
||||
0.0 :
|
||||
AccVert * 0.5 );
|
||||
// szarpanie
|
||||
/*
|
||||
#ifdef EU07_USE_FUZZYLOGIC
|
||||
if( FuzzyLogic( ( 10.0 + Track.DamageFlag ) * Mass * Vel / Vmax, 500000.0, p_accn ) ) {
|
||||
// Ra: czemu tu masa bez ładunku?
|
||||
@@ -1287,7 +1309,7 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
|
||||
if (AccV > 1.0)
|
||||
AccN += (7.0 - Random(5)) * (100.0 + Track.DamageFlag / 2.0) * AccV / 2000.0;
|
||||
|
||||
*/
|
||||
// wykolejanie na luku oraz z braku szyn
|
||||
if (TestFlag(CategoryFlag, 1))
|
||||
{
|
||||
@@ -1322,22 +1344,14 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
Mains = false;
|
||||
DerailReason = 4; // Ra: powód wykolejenia: nieodpowiednia trajektoria
|
||||
}
|
||||
V += (3.0 * AccS - AccSprev) * dt / 2.0; // przyrost predkosci
|
||||
if (TestFlag(DamageFlag, dtrain_out))
|
||||
if (Vel < 1)
|
||||
{
|
||||
V = 0;
|
||||
AccS = 0;
|
||||
}
|
||||
|
||||
if ((V * Vprev <= 0) && (abs(FStand) > abs(FTrain))) // tlumienie predkosci przy hamowaniu
|
||||
{ // zahamowany
|
||||
V = 0;
|
||||
// AccS:=0; //Ra 2014-03: ale siła grawitacji działa, więc nie może być zerowe
|
||||
if( ( true == TestFlag( DamageFlag, dtrain_out ) )
|
||||
&& ( Vel < 1.0 ) ) {
|
||||
V = 0.0;
|
||||
AccS = 0.0;
|
||||
}
|
||||
|
||||
// { dL:=(V+AccS*dt/2)*dt; //przyrost dlugosci czyli
|
||||
// przesuniecie
|
||||
// dL:=(V+AccS*dt/2)*dt;
|
||||
// przyrost dlugosci czyli przesuniecie
|
||||
dL = (3.0 * V - Vprev) * dt / 2.0; // metoda Adamsa-Bashfortha}
|
||||
// ale jesli jest kolizja (zas. zach. pedu) to...}
|
||||
for (int b = 0; b < 2; b++)
|
||||
@@ -1349,10 +1363,11 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
if (Power > 1.0) // w rozrządczym nie (jest błąd w FIZ!) - Ra 2014-07: teraz we wszystkich
|
||||
UpdatePantVolume(dt); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów
|
||||
|
||||
if (EngineType == WheelsDriven)
|
||||
d = (double)CabNo * dL; // na chwile dla testu
|
||||
else
|
||||
d = dL;
|
||||
auto const d { (
|
||||
EngineType == WheelsDriven ?
|
||||
dL * CabNo : // na chwile dla testu
|
||||
dL ) };
|
||||
|
||||
DistCounter += fabs(dL) / 1000.0;
|
||||
dL = 0;
|
||||
|
||||
@@ -1413,6 +1428,7 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
// if (Vel>10) and (not DebugmodeFlag) then
|
||||
if (!DebugModeFlag)
|
||||
SecuritySystemCheck(dt1);
|
||||
|
||||
return d;
|
||||
};
|
||||
|
||||
@@ -1424,7 +1440,6 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape
|
||||
TTrackParam &Track, const TLocation &NewLoc,
|
||||
TRotation &NewRot)
|
||||
{
|
||||
double Vprev, AccSprev, d;
|
||||
int b;
|
||||
// T_MoverParameters::FastComputeMovement(dt, Shape, Track, NewLoc, NewRot);
|
||||
|
||||
@@ -1436,76 +1451,40 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape
|
||||
|
||||
if (dL == 0) // oblicz przesuniecie
|
||||
{
|
||||
Vprev = V;
|
||||
AccSprev = AccS;
|
||||
// dt =ActualTime-LastUpdatedTime; //przyrost czasu
|
||||
auto const AccSprev { AccS };
|
||||
// przyspieszenie styczne
|
||||
AccS = (FTotal / TotalMass + AccSprev) /
|
||||
2.0; // prawo Newtona ale z wygladzaniem (średnia z poprzednim)
|
||||
AccS = interpolate(
|
||||
AccSprev,
|
||||
FTotal / TotalMass,
|
||||
0.5 );
|
||||
// clamp( dt * 3.0, 0.0, 1.0 ) ); // prawo Newtona ale z wygladzaniem (średnia z poprzednim)
|
||||
|
||||
if (TestFlag(DamageFlag, dtrain_out))
|
||||
AccS = -Sign(V) * g * 1; // * random(0.0, 0.1)
|
||||
// przyspieszenie normalne}
|
||||
// if Abs(Shape.R)>0.01 then
|
||||
// AccN:=SQR(V)/Shape.R+g*Shape.dHrail/TrackW
|
||||
// else AccN:=g*Shape.dHrail/TrackW;
|
||||
|
||||
// szarpanie}
|
||||
#ifdef EU07_USE_FUZZYLOGIC
|
||||
if( FuzzyLogic( ( 10.0 + Track.DamageFlag ) * Mass * Vel / Vmax, 500000.0, p_accn ) ) {
|
||||
// Ra: czemu tu masa bez ładunku?
|
||||
AccV /= ( 2.0 * 0.95 + 2.0 * Random() * 0.1 ); // 95-105% of base modifier (2.0)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
AccV = AccV / 2.0;
|
||||
// simple mode skips calculation of normal acceleration
|
||||
|
||||
if (AccV > 1.0)
|
||||
AccN += (7.0 - Random(5)) * (100.0 + Track.DamageFlag / 2.0) * AccV / 2000.0;
|
||||
|
||||
// {wykolejanie na luku oraz z braku szyn}
|
||||
// if TestFlag(CategoryFlag,1) then
|
||||
// begin
|
||||
// if FuzzyLogic((AccN/g)*(1+0.1*(Track.DamageFlag and
|
||||
// dtrack_freerail)),TrackW/Dim.H,1)
|
||||
// or TestFlag(Track.DamageFlag,dtrack_norail) then
|
||||
// if SetFlag(DamageFlag,dtrain_out) then
|
||||
// begin
|
||||
// EventFlag:=true;
|
||||
// MainS:=false;
|
||||
// RunningShape.R:=0;
|
||||
// end;
|
||||
// {wykolejanie na poszerzeniu toru}
|
||||
// if FuzzyLogic(Abs(Track.Width-TrackW),TrackW/10,1) then
|
||||
// if SetFlag(DamageFlag,dtrain_out) then
|
||||
// begin
|
||||
// EventFlag:=true;
|
||||
// MainS:=false;
|
||||
// RunningShape.R:=0;
|
||||
// end;
|
||||
// end;
|
||||
// {wykolejanie wkutek niezgodnosci kategorii toru i pojazdu}
|
||||
// if not TestFlag(RunningTrack.CategoryFlag,CategoryFlag) then
|
||||
// if SetFlag(DamageFlag,dtrain_out) then
|
||||
// begin
|
||||
// EventFlag:=true;
|
||||
// MainS:=false;
|
||||
// end;
|
||||
|
||||
V += (3.0 * AccS - AccSprev) * dt / 2.0; // przyrost predkosci
|
||||
|
||||
if (TestFlag(DamageFlag, dtrain_out))
|
||||
if (Vel < 1)
|
||||
{
|
||||
V = 0;
|
||||
AccS = 0; // Ra 2014-03: ale siła grawitacji działa, więc nie może być zerowe
|
||||
}
|
||||
|
||||
if ((V * Vprev <= 0) && (abs(FStand) > abs(FTrain))) // tlumienie predkosci przy hamowaniu
|
||||
{ // zahamowany}
|
||||
// velocity change
|
||||
auto const Vprev { V };
|
||||
V += ( 3.0 * AccS - AccSprev ) * dt / 2.0; // przyrost predkosci
|
||||
if( ( V * Vprev <= 0 )
|
||||
&& ( std::abs( FStand ) > std::abs( FTrain ) ) ) {
|
||||
// tlumienie predkosci przy hamowaniu
|
||||
// zahamowany
|
||||
V = 0;
|
||||
AccS = 0;
|
||||
}
|
||||
|
||||
// simple mode skips calculation of tangential acceleration
|
||||
|
||||
// simple mode skips calculation of vertical acceleration
|
||||
AccVert = 0.0;
|
||||
|
||||
if( ( true == TestFlag( DamageFlag, dtrain_out ) )
|
||||
&& ( Vel < 1.0 ) ) {
|
||||
V = 0.0;
|
||||
AccS = 0.0;
|
||||
}
|
||||
|
||||
dL = (3.0 * V - Vprev) * dt / 2.0; // metoda Adamsa-Bashfortha
|
||||
// ale jesli jest kolizja (zas. zach. pedu) to...
|
||||
for (b = 0; b < 2; b++)
|
||||
@@ -1515,10 +1494,12 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape
|
||||
// QQQ
|
||||
if (Power > 1.0) // w rozrządczym nie (jest błąd w FIZ!)
|
||||
UpdatePantVolume(dt); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów
|
||||
if (EngineType == WheelsDriven)
|
||||
d = (double)CabNo * dL; // na chwile dla testu
|
||||
else
|
||||
d = dL;
|
||||
|
||||
auto const d { (
|
||||
EngineType == WheelsDriven ?
|
||||
dL * CabNo : // na chwile dla testu
|
||||
dL ) };
|
||||
|
||||
DistCounter += fabs(dL) / 1000.0;
|
||||
dL = 0;
|
||||
|
||||
@@ -1552,6 +1533,7 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape
|
||||
if ((BrakeSlippingTimer > 0.8) && (ASBType != 128)) // ASBSpeed=0.8
|
||||
Hamulec->ASB(0);
|
||||
BrakeSlippingTimer += dt;
|
||||
|
||||
return d;
|
||||
};
|
||||
|
||||
@@ -3743,12 +3725,12 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
|
||||
|| ( ( Couplers[ side::rear ].CouplingFlag & ctrain_power ) == ctrain_power ) ) ) {
|
||||
// potem ulepszyc! pantogtrafy!
|
||||
Voltage =
|
||||
std::max(
|
||||
RunningTraction.TractionVoltage,
|
||||
std::max(
|
||||
RunningTraction.TractionVoltage,
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
std::max( HVCouplers[side::front][hvcoupler::voltage], HVCouplers[side::rear][hvcoupler::voltage] ) );
|
||||
std::max( HVCouplers[side::front][hvcoupler::voltage], HVCouplers[side::rear][hvcoupler::voltage] ) );
|
||||
#else
|
||||
std::max( Couplers[ side::front ].power_high.voltage, Couplers[ side::rear ].power_high.voltage ) );
|
||||
std::max( Couplers[ side::front ].power_high.voltage, Couplers[ side::rear ].power_high.voltage ) );
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
@@ -4190,43 +4172,59 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt)
|
||||
// *************************************************************************************************
|
||||
double TMoverParameters::TractionForce(double dt)
|
||||
{
|
||||
double PosRatio, dmoment, dtrans, tmp;// , tmpV;
|
||||
int i;
|
||||
double PosRatio, dmoment, dtrans, tmp;
|
||||
|
||||
Ft = 0;
|
||||
dtrans = 0;
|
||||
dmoment = 0;
|
||||
// tmpV =Abs(nrot * WheelDiameter / 2);
|
||||
// youBy
|
||||
if (EngineType == DieselElectric)
|
||||
{
|
||||
tmp = DElist[MainCtrlPos].RPM / 60.0;
|
||||
if ((Heating) && (HeatingPower > 0) && (MainCtrlPosNo > MainCtrlPos))
|
||||
{
|
||||
i = MainCtrlPosNo;
|
||||
while (DElist[i - 2].RPM / 60.0 > tmp)
|
||||
i--;
|
||||
tmp = DElist[i].RPM / 60.0;
|
||||
}
|
||||
switch( EngineType ) {
|
||||
case DieselElectric: {
|
||||
if( true == ConverterFlag ) {
|
||||
// NOTE: converter is currently a stand-in for a fuel pump
|
||||
tmp = DElist[ MainCtrlPos ].RPM / 60.0;
|
||||
|
||||
if (enrot != tmp * int(ConverterFlag))
|
||||
if (abs(tmp * int(ConverterFlag) - enrot) < 0.001)
|
||||
enrot = tmp * int(ConverterFlag);
|
||||
else if ((enrot < DElist[0].RPM * 0.01) && (ConverterFlag))
|
||||
enrot += (tmp * int(ConverterFlag) - enrot) * dt / 5.0;
|
||||
if( ( true == Heating )
|
||||
&& ( HeatingPower > 0 )
|
||||
&& ( MainCtrlPosNo > MainCtrlPos ) ) {
|
||||
|
||||
int i = MainCtrlPosNo;
|
||||
while( DElist[ i - 2 ].RPM / 60.0 > tmp ) {
|
||||
--i;
|
||||
}
|
||||
tmp = DElist[ i ].RPM / 60.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tmp = 0.0;
|
||||
}
|
||||
|
||||
if( enrot != tmp ) {
|
||||
enrot = clamp(
|
||||
enrot + ( dt / 1.25 ) * ( // TODO: equivalent of dizel_aim instead of fixed inertia
|
||||
enrot < tmp ?
|
||||
1.0 :
|
||||
-2.0 ), // NOTE: revolutions drop faster than they rise, maybe? TBD: maybe not
|
||||
0.0, std::max( tmp, enrot ) );
|
||||
if( std::abs( tmp - enrot ) < 0.001 ) {
|
||||
enrot = tmp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DieselEngine: {
|
||||
if( ShuntMode ) // dodatkowa przekładnia np. dla 2Ls150
|
||||
dtrans = AnPos * Transmision.Ratio * MotorParam[ ScndCtrlActualPos ].mIsat;
|
||||
else
|
||||
enrot += (tmp * int(ConverterFlag) - enrot) * 1.5 * dt;
|
||||
}
|
||||
else if (EngineType != DieselEngine)
|
||||
enrot = Transmision.Ratio * nrot;
|
||||
else // dla DieselEngine
|
||||
{
|
||||
if (ShuntMode) // dodatkowa przekładnia np. dla 2Ls150
|
||||
dtrans = AnPos * Transmision.Ratio * MotorParam[ScndCtrlActualPos].mIsat;
|
||||
else
|
||||
dtrans = Transmision.Ratio * MotorParam[ScndCtrlActualPos].mIsat;
|
||||
dmoment = dizel_Momentum(dizel_fill, dtrans * nrot * ActiveDir, dt); // oblicza tez
|
||||
// enrot
|
||||
dtrans = Transmision.Ratio * MotorParam[ ScndCtrlActualPos ].mIsat;
|
||||
|
||||
dmoment = dizel_Momentum( dizel_fill, dtrans * nrot * ActiveDir, dt ); // oblicza tez enrot
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
enrot = Transmision.Ratio * nrot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eAngle += enrot * dt;
|
||||
@@ -4251,7 +4249,7 @@ double TMoverParameters::TractionForce(double dt)
|
||||
&& ( ( std::abs( eimv[ eimv_If ] ) > 1.0 )
|
||||
|| ( tmpV > 0.1 ) ) ) {
|
||||
|
||||
i = 0;
|
||||
int i = 0;
|
||||
while( ( i < RlistSize - 1 )
|
||||
&& ( DElist[ i + 1 ].RPM < tmpV ) ) {
|
||||
++i;
|
||||
@@ -4423,7 +4421,7 @@ double TMoverParameters::TractionForce(double dt)
|
||||
if (MainCtrlPos > 1)
|
||||
dmoment -=
|
||||
dizel_Mstand * (0.2 * enrot / dizel_nmax); // dodatkowe opory z powodu sprezarki}
|
||||
Mm = dizel_engage * dmoment;
|
||||
Mm = dmoment; //bylo * dizel_engage
|
||||
Mw = Mm * dtrans; // dmoment i dtrans policzone przy okazji enginerotation
|
||||
Fw = Mw * 2.0 / WheelDiameter / NPoweredAxles;
|
||||
Ft = Fw * NPoweredAxles; // sila trakcyjna
|
||||
@@ -4604,25 +4602,20 @@ double TMoverParameters::TractionForce(double dt)
|
||||
case 45:
|
||||
{
|
||||
if( ( ScndCtrlPos < ScndCtrlPosNo )
|
||||
&& ( MainCtrlPos >= 10 ) ) {
|
||||
if( ScndCtrlPos == 0 ) {
|
||||
if( Im < MPTRelay[ ScndCtrlPos ].Iup ) {
|
||||
++ScndCtrlPos;
|
||||
}
|
||||
&& ( MainCtrlPos >= 11 ) ) {
|
||||
|
||||
if( Im < MPTRelay[ ScndCtrlPos ].Iup ) {
|
||||
++ScndCtrlPos;
|
||||
}
|
||||
else {
|
||||
if( Vel > MPTRelay[ ScndCtrlPos ].Iup ) {
|
||||
++ScndCtrlPos;
|
||||
}
|
||||
// check for cases where the speed drops below threshold for level 2 or 3
|
||||
if( ( ScndCtrlPos > 1 )
|
||||
&& ( Vel < MPTRelay[ ScndCtrlPos - 1 ].Idown ) ) {
|
||||
--ScndCtrlPos;
|
||||
}
|
||||
// check for cases where the speed drops below threshold for level 2 or 3
|
||||
if( ( ScndCtrlPos > 1 )
|
||||
&& ( Vel < MPTRelay[ ScndCtrlPos - 1 ].Idown ) ) {
|
||||
--ScndCtrlPos;
|
||||
}
|
||||
}
|
||||
// malenie
|
||||
if( ( ScndCtrlPos > 0 ) && ( MainCtrlPos < 10 ) ) {
|
||||
if( ( ScndCtrlPos > 0 ) && ( MainCtrlPos < 11 ) ) {
|
||||
|
||||
if( ScndCtrlPos == 1 ) {
|
||||
if( Im > MPTRelay[ ScndCtrlPos - 1 ].Idown ) {
|
||||
--ScndCtrlPos;
|
||||
@@ -4635,19 +4628,26 @@ double TMoverParameters::TractionForce(double dt)
|
||||
}
|
||||
}
|
||||
// 3rd level drops with master controller at position lower than 10...
|
||||
if( MainCtrlPos < 10 ) {
|
||||
if( MainCtrlPos < 11 ) {
|
||||
ScndCtrlPos = std::min( 2, ScndCtrlPos );
|
||||
}
|
||||
// ...and below position 7 field shunt drops altogether
|
||||
if( MainCtrlPos < 7 ) {
|
||||
if( MainCtrlPos < 8 ) {
|
||||
ScndCtrlPos = 0;
|
||||
}
|
||||
/*
|
||||
// crude woodward approximation; difference between rpm for consecutive positions is ~5%
|
||||
// so we get full throttle until ~half way between desired and previous position, or zero on rpm reduction
|
||||
auto const woodward { clamp(
|
||||
( DElist[ MainCtrlPos ].RPM / ( enrot * 60.0 ) - 1.0 ) * 50.0,
|
||||
0.0, 1.0 ) };
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case 46:
|
||||
{
|
||||
// wzrastanie
|
||||
if( ( MainCtrlPos >= 10 )
|
||||
if( ( MainCtrlPos >= 12 )
|
||||
&& ( ScndCtrlPos < ScndCtrlPosNo ) ) {
|
||||
if( ( ScndCtrlPos ) % 2 == 0 ) {
|
||||
if( ( MPTRelay[ ScndCtrlPos ].Iup > Im ) ) {
|
||||
@@ -4662,24 +4662,27 @@ double TMoverParameters::TractionForce(double dt)
|
||||
}
|
||||
}
|
||||
// malenie
|
||||
if( ( MainCtrlPos < 10 )
|
||||
if( ( MainCtrlPos < 12 )
|
||||
&& ( ScndCtrlPos > 0 ) ) {
|
||||
if( ( ScndCtrlPos ) % 2 == 0 ) {
|
||||
if( ( MPTRelay[ ScndCtrlPos ].Idown < Im ) ) {
|
||||
--ScndCtrlPos;
|
||||
if( Vel < 50.0 ) {
|
||||
// above 50 km/h already active shunt field can be maintained until lower controller setting
|
||||
if( ( ScndCtrlPos ) % 2 == 0 ) {
|
||||
if( ( MPTRelay[ ScndCtrlPos ].Idown < Im ) ) {
|
||||
--ScndCtrlPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( ( MPTRelay[ ScndCtrlPos + 1 ].Idown < Im )
|
||||
&& ( MPTRelay[ ScndCtrlPos ].Idown > Vel ) ) {
|
||||
--ScndCtrlPos;
|
||||
else {
|
||||
if( ( MPTRelay[ ScndCtrlPos + 1 ].Idown < Im )
|
||||
&& ( MPTRelay[ ScndCtrlPos ].Idown > Vel ) ) {
|
||||
--ScndCtrlPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( MainCtrlPos < 10 ) {
|
||||
if( MainCtrlPos < 11 ) {
|
||||
ScndCtrlPos = std::min( 2, ScndCtrlPos );
|
||||
}
|
||||
if( MainCtrlPos < 7 ) {
|
||||
if( MainCtrlPos < 8 ) {
|
||||
ScndCtrlPos = 0;
|
||||
}
|
||||
break;
|
||||
@@ -4890,7 +4893,7 @@ double TMoverParameters::TractionForce(double dt)
|
||||
dizel_fill = 0;
|
||||
EnginePower = 0;
|
||||
{
|
||||
for (i = 0; i < 21; i++)
|
||||
for (int i = 0; i < 21; ++i)
|
||||
eimv[i] = 0;
|
||||
}
|
||||
Hamulec->SetED(0);
|
||||
@@ -5207,7 +5210,8 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
{
|
||||
if ((LastRelayTime > CtrlDelay) && (ARFASI2))
|
||||
{
|
||||
ScndCtrlActualPos++;
|
||||
++ScndCtrlActualPos;
|
||||
SetFlag( SoundFlag, sound::shuntfield );
|
||||
OK = true;
|
||||
}
|
||||
}
|
||||
@@ -5215,7 +5219,8 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
{
|
||||
if ((LastRelayTime > CtrlDownDelay) && (TrainType != dt_EZT))
|
||||
{
|
||||
ScndCtrlActualPos--;
|
||||
--ScndCtrlActualPos;
|
||||
SetFlag( SoundFlag, sound::shuntfield );
|
||||
OK = true;
|
||||
}
|
||||
}
|
||||
@@ -5243,7 +5248,7 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
&& ( MainCtrlPos != MainCtrlPosNo )
|
||||
&& ( FastSerialCircuit == 1 ) ) {
|
||||
|
||||
MainCtrlActualPos++;
|
||||
++MainCtrlActualPos;
|
||||
// MainCtrlActualPos:=MainCtrlPos; //hunter-111012:
|
||||
// szybkie wchodzenie na bezoporowa (303E)
|
||||
OK = true;
|
||||
@@ -5258,7 +5263,7 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
(DelayCtrlFlag))) // et22 z walem grupowym
|
||||
if (!DelayCtrlFlag) // najpierw przejscie
|
||||
{
|
||||
MainCtrlActualPos++;
|
||||
++MainCtrlActualPos;
|
||||
DelayCtrlFlag = true; // tryb przejscia
|
||||
OK = true;
|
||||
}
|
||||
@@ -5272,7 +5277,7 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
;
|
||||
else // nie ET22 z wałem grupowym
|
||||
{
|
||||
MainCtrlActualPos++;
|
||||
++MainCtrlActualPos;
|
||||
OK = true;
|
||||
}
|
||||
//---------
|
||||
@@ -5296,7 +5301,7 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
if ((RList[MainCtrlPos].R == 0) && (MainCtrlPos > 0) &&
|
||||
(!(MainCtrlPos == MainCtrlPosNo)) && (FastSerialCircuit == 1))
|
||||
{
|
||||
MainCtrlActualPos--;
|
||||
--MainCtrlActualPos;
|
||||
// MainCtrlActualPos:=MainCtrlPos; //hunter-111012:
|
||||
// szybkie wchodzenie na bezoporowa (303E)
|
||||
OK = true;
|
||||
@@ -5306,13 +5311,12 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
{
|
||||
if (TrainType != dt_EZT) // tutaj powinien być tryb sterowania wałem
|
||||
{
|
||||
MainCtrlActualPos--;
|
||||
--MainCtrlActualPos;
|
||||
OK = true;
|
||||
}
|
||||
if (MainCtrlActualPos > 0) // hunter-111211: poprawki
|
||||
if (RList[MainCtrlActualPos].R ==
|
||||
0) // dzwieki schodzenia z bezoporowej}
|
||||
{
|
||||
if (RList[MainCtrlActualPos].R == 0) {
|
||||
// dzwieki schodzenia z bezoporowej}
|
||||
SetFlag(SoundFlag, sound::parallel);
|
||||
}
|
||||
}
|
||||
@@ -5321,7 +5325,8 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
{
|
||||
if (LastRelayTime > CtrlDownDelay)
|
||||
{
|
||||
ScndCtrlActualPos--; // boczniki nie dzialaja na poz. oporowych
|
||||
--ScndCtrlActualPos; // boczniki nie dzialaja na poz. oporowych
|
||||
SetFlag( SoundFlag, sound::shuntfield );
|
||||
OK = true;
|
||||
}
|
||||
}
|
||||
@@ -5352,45 +5357,61 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
else
|
||||
DelayCtrlFlag = false;
|
||||
|
||||
if ((!StLinFlag) && ((MainCtrlActualPos > 0) || (ScndCtrlActualPos > 0)))
|
||||
if ((TrainType == dt_EZT) && (CoupledCtrl)) // EN57 wal jednokierunkowy calosciowy
|
||||
{
|
||||
if (MainCtrlActualPos == 1)
|
||||
{
|
||||
MainCtrlActualPos = 0;
|
||||
OK = true;
|
||||
}
|
||||
else if (LastRelayTime > CtrlDownDelay)
|
||||
{
|
||||
if (MainCtrlActualPos < RlistSize)
|
||||
MainCtrlActualPos++; // dojdz do konca
|
||||
else if (ScndCtrlActualPos < ScndCtrlPosNo)
|
||||
ScndCtrlActualPos++; // potem boki
|
||||
else
|
||||
{ // i sie przewroc na koniec
|
||||
if( ( false == StLinFlag )
|
||||
&& ( ( MainCtrlActualPos > 0 )
|
||||
|| ( ScndCtrlActualPos > 0 ) ) ) {
|
||||
|
||||
if( true == CoupledCtrl ) {
|
||||
|
||||
if( TrainType == dt_EZT ) {
|
||||
// EN57 wal jednokierunkowy calosciowy
|
||||
if( MainCtrlActualPos == 1 ) {
|
||||
|
||||
MainCtrlActualPos = 0;
|
||||
ScndCtrlActualPos = 0;
|
||||
OK = true;
|
||||
}
|
||||
else {
|
||||
|
||||
if( LastRelayTime > CtrlDownDelay ) {
|
||||
|
||||
if( MainCtrlActualPos < RlistSize ) {
|
||||
// dojdz do konca
|
||||
++MainCtrlActualPos;
|
||||
}
|
||||
else if( ScndCtrlActualPos < ScndCtrlPosNo ) {
|
||||
// potem boki
|
||||
++ScndCtrlActualPos;
|
||||
SetFlag( SoundFlag, sound::shuntfield );
|
||||
}
|
||||
else {
|
||||
// i sie przewroc na koniec
|
||||
MainCtrlActualPos = 0;
|
||||
ScndCtrlActualPos = 0;
|
||||
}
|
||||
OK = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// wal kulakowy dwukierunkowy
|
||||
if( LastRelayTime > CtrlDownDelay ) {
|
||||
if( ScndCtrlActualPos > 0 ) {
|
||||
--ScndCtrlActualPos;
|
||||
SetFlag( SoundFlag, sound::shuntfield );
|
||||
}
|
||||
else {
|
||||
--MainCtrlActualPos;
|
||||
}
|
||||
OK = true;
|
||||
}
|
||||
OK = true;
|
||||
}
|
||||
}
|
||||
else if (CoupledCtrl) // wal kulakowy dwukierunkowy
|
||||
{
|
||||
if (LastRelayTime > CtrlDownDelay)
|
||||
{
|
||||
if (ScndCtrlActualPos > 0)
|
||||
ScndCtrlActualPos--;
|
||||
else
|
||||
MainCtrlActualPos--;
|
||||
OK = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
MainCtrlActualPos = 0;
|
||||
ScndCtrlActualPos = 0;
|
||||
OK = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OK)
|
||||
LastRelayTime = 0;
|
||||
@@ -5527,8 +5548,6 @@ bool TMoverParameters::dizel_EngageSwitch(double state)
|
||||
// *************************************************************************************************
|
||||
bool TMoverParameters::dizel_EngageChange(double dt)
|
||||
{
|
||||
const double engagedownspeed = 0.9;
|
||||
const double engageupspeed = 0.5;
|
||||
double engagespeed = 0; // OK:boolean;
|
||||
bool DEC;
|
||||
|
||||
@@ -5568,7 +5587,7 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
|
||||
OK = false;
|
||||
if (MotorParam[ScndCtrlActualPos].AutoSwitch && Mains)
|
||||
{
|
||||
if (RList[MainCtrlPos].Mn == 0)
|
||||
if ((RList[MainCtrlPos].Mn == 0)&&(!hydro_TC))
|
||||
{
|
||||
if (dizel_engagestate > 0)
|
||||
dizel_EngageSwitch(0);
|
||||
@@ -5617,7 +5636,10 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
|
||||
dizel_EngageSwitch(1.0);
|
||||
break;
|
||||
default:
|
||||
dizel_EngageSwitch(0.0);
|
||||
if (hydro_TC && hydro_TC_Fill>0.01)
|
||||
dizel_EngageSwitch(1.0);
|
||||
else
|
||||
dizel_EngageSwitch(0.0);
|
||||
}
|
||||
else
|
||||
dizel_EngageSwitch(0.0);
|
||||
@@ -5646,7 +5668,7 @@ bool TMoverParameters::dizel_Update(double dt)
|
||||
|
||||
enrot = std::max(
|
||||
enrot,
|
||||
0.1 * ( // TODO: dac zaleznie od temperatury i baterii
|
||||
0.35 * ( // TODO: dac zaleznie od temperatury i baterii
|
||||
EngineType == DieselEngine ?
|
||||
dizel_nmin :
|
||||
DElist[ 0 ].RPM / 60.0 ) );
|
||||
@@ -5673,9 +5695,9 @@ double TMoverParameters::dizel_fillcheck(int mcp)
|
||||
nreg = 0;
|
||||
if (Mains && (MainCtrlPosNo > 0))
|
||||
{
|
||||
if (dizel_enginestart &&
|
||||
(LastSwitchingTime >= 0.9 * InitialCtrlDelay)) // wzbogacenie przy rozruchu
|
||||
realfill = 1;
|
||||
if (dizel_enginestart &&
|
||||
(LastSwitchingTime >= 0.9 * InitialCtrlDelay)) // wzbogacenie przy rozruchu
|
||||
realfill = 1;
|
||||
else
|
||||
realfill = RList[mcp].R; // napelnienie zalezne od MainCtrlPos
|
||||
if (dizel_nmax_cutoff > 0)
|
||||
@@ -5687,7 +5709,7 @@ double TMoverParameters::dizel_fillcheck(int mcp)
|
||||
nreg = dizel_nmin;
|
||||
break;
|
||||
case 2:
|
||||
if (dizel_automaticgearstatus == 0)
|
||||
if ((dizel_automaticgearstatus == 0)&&(true/*(!hydro_TC) || (dizel_engage>dizel_fill)*/))
|
||||
nreg = dizel_nmax;
|
||||
else
|
||||
nreg = dizel_nmin;
|
||||
@@ -5695,12 +5717,18 @@ double TMoverParameters::dizel_fillcheck(int mcp)
|
||||
default:
|
||||
realfill = 0; // sluczaj
|
||||
}
|
||||
if (enrot > nreg)
|
||||
/*if (enrot > nreg)
|
||||
realfill = realfill * (3.9 - 3.0 * abs(enrot) / nreg);
|
||||
if (enrot > dizel_nmax_cutoff)
|
||||
realfill = realfill * (9.8 - 9.0 * abs(enrot) / dizel_nmax_cutoff);
|
||||
if (enrot < dizel_nmin)
|
||||
realfill = realfill * (1.0 + (dizel_nmin - abs(enrot)) / dizel_nmin);
|
||||
realfill = realfill * (1.0 + (dizel_nmin - abs(enrot)) / dizel_nmin);*/
|
||||
if (enrot > nreg) //nad predkoscia regulatora zeruj dawke
|
||||
realfill = 0;
|
||||
if (enrot < nreg) //pod predkoscia regulatora dawka zadana
|
||||
realfill = realfill;
|
||||
if ((enrot < dizel_nmin * 0.98)&&(RList[mcp].R>0.001)) //jesli ponizej biegu jalowego i niezerowa dawka, to dawaj pelna
|
||||
realfill = 1;
|
||||
}
|
||||
}
|
||||
if (realfill < 0)
|
||||
@@ -5716,11 +5744,17 @@ double TMoverParameters::dizel_fillcheck(int mcp)
|
||||
// *************************************************************************************************
|
||||
double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
||||
{ // liczy moment sily wytwarzany przez silnik spalinowy}
|
||||
double Moment = 0, enMoment = 0, eps = 0, newn = 0, friction = 0;
|
||||
|
||||
double Moment = 0, enMoment = 0, gearMoment = 0, eps = 0, newn = 0, friction = 0, neps = 0;
|
||||
double TorqueH = 0, TorqueL = 0, TorqueC = 0;
|
||||
n = n * CabNo;
|
||||
if (MotorParam[ScndCtrlActualPos].mIsat < 0.001)
|
||||
n = enrot;
|
||||
friction = dizel_engagefriction;
|
||||
hydro_TC_nIn = enrot; //wal wejsciowy przetwornika momentu
|
||||
hydro_TC_nOut = dizel_n_old; //wal wyjsciowy przetwornika momentu
|
||||
neps = (n - dizel_n_old) / dt; //przyspieszenie katowe walu wejsciowego skrzyni biegow
|
||||
|
||||
if( enrot > 0 ) {
|
||||
// Moment = dizel_Mmax * dizel_fill - ( dizel_Mmax - dizel_Mnmax * dizel_fill ) * sqr( enrot / ( dizel_nmax - dizel_nMmax * dizel_fill ) ) - dizel_Mstand; // Q: zamieniam SQR() na sqr()
|
||||
Moment = ( dizel_Mmax - ( dizel_Mmax - dizel_Mnmax ) * square( ( enrot - dizel_nMmax ) / ( dizel_nMmax - dizel_nmax ) ) ) * dizel_fill - dizel_Mstand;
|
||||
}
|
||||
else {
|
||||
@@ -5731,43 +5765,126 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
||||
// wstrzymywanie przy malych obrotach
|
||||
Moment -= dizel_Mstand;
|
||||
}
|
||||
//!! abs
|
||||
if (abs(abs(n) - enrot) < 0.1)
|
||||
{
|
||||
if ((Moment) > (dizel_engageMaxForce * dizel_engage * dizel_engageDia * friction *
|
||||
2)) // zerwanie przyczepnosci sprzegla
|
||||
enrot += dt * Moment / dizel_AIM;
|
||||
else
|
||||
{
|
||||
dizel_engagedeltaomega = 0;
|
||||
enrot = abs(n); // jest przyczepnosc tarcz
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((enrot == 0) && (Moment < 0))
|
||||
newn = 0;
|
||||
else
|
||||
{
|
||||
//!! abs
|
||||
dizel_engagedeltaomega = enrot - n; // sliganie tarcz
|
||||
enMoment = Moment -
|
||||
Sign(dizel_engagedeltaomega) * dizel_engageMaxForce * dizel_engage *
|
||||
dizel_engageDia * friction;
|
||||
Moment = Sign(dizel_engagedeltaomega) * dizel_engageMaxForce * dizel_engage *
|
||||
dizel_engageDia * friction;
|
||||
dizel_engagedeltaomega = abs(enrot - abs(n));
|
||||
eps = enMoment / dizel_AIM;
|
||||
newn = enrot + eps * dt;
|
||||
if ((newn * enrot <= 0) && (eps * enrot < 0))
|
||||
newn = 0;
|
||||
}
|
||||
enrot = newn;
|
||||
}
|
||||
if ((enrot == 0) && (!dizel_enginestart))
|
||||
Mains = false;
|
||||
if (true == dizel_enginestart)
|
||||
Moment += dizel_Mstand / (0.3 + std::max(0.0, enrot/dizel_nmin)); //rozrusznik
|
||||
|
||||
return Moment;
|
||||
dizel_Torque = Moment;
|
||||
|
||||
if (hydro_TC) //jesli przetwornik momentu
|
||||
{
|
||||
//napelnianie przetwornika
|
||||
if ((MainCtrlPos > 0) && (Mains) && (enrot>dizel_nmin*0.9))
|
||||
hydro_TC_Fill += hydro_TC_FillRateInc * dt;
|
||||
//oproznianie przetwornika
|
||||
if (((MainCtrlPos == 0) && (Vel<3))
|
||||
|| (!Mains)
|
||||
|| (enrot<dizel_nmin*0.8))
|
||||
hydro_TC_Fill -= hydro_TC_FillRateDec * dt;
|
||||
//obcinanie zakresu
|
||||
hydro_TC_Fill = clamp(hydro_TC_Fill, 0.0, 1.0);
|
||||
|
||||
//blokowanie sprzegla blokującego
|
||||
if ((Vel > hydro_TC_LockupSpeed) && (Mains) && (enrot > 0.9 * dizel_nmin) && (MainCtrlPos>0))
|
||||
hydro_TC_LockupRate += hydro_TC_FillRateInc*dt;
|
||||
//luzowanie sprzegla blokujacego
|
||||
if ((Vel < (MainCtrlPos>0 ? hydro_TC_LockupSpeed : hydro_TC_UnlockSpeed)) || (!Mains) || (enrot < 0.8 * dizel_nmin))
|
||||
hydro_TC_LockupRate -= hydro_TC_FillRateDec*dt;
|
||||
//obcinanie zakresu
|
||||
hydro_TC_LockupRate = clamp(hydro_TC_LockupRate, 0.0, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
hydro_TC_Fill = 0.0;
|
||||
hydro_TC_LockupRate = 0.0;
|
||||
}
|
||||
|
||||
//obliczanie momentow poszczegolnych sprzegiel
|
||||
//sprzeglo glowne (skrzynia biegow)
|
||||
TorqueC = dizel_engageMaxForce * dizel_engage * dizel_engageDia * friction;
|
||||
|
||||
if (hydro_TC) //jesli hydro
|
||||
{
|
||||
double HydroTorque = 0;
|
||||
HydroTorque += hydro_TC_nIn * hydro_TC_nIn * hydro_TC_TorqueInIn;
|
||||
HydroTorque += (hydro_TC_nIn - hydro_TC_nOut) * hydro_TC_TorqueInOut;
|
||||
HydroTorque += hydro_TC_nOut * hydro_TC_nOut * hydro_TC_TorqueOutOut;
|
||||
double nOut2In = hydro_TC_nOut / std::max(0.01, hydro_TC_nIn);
|
||||
if (nOut2In < hydro_TC_CouplingPoint)
|
||||
{
|
||||
hydro_TC_TMRatio = 1 + (hydro_TC_TMMax - 1) * square(1 - nOut2In / hydro_TC_CouplingPoint);
|
||||
hydro_TC_TorqueIn = HydroTorque * hydro_TC_Fill;
|
||||
hydro_TC_TorqueOut = HydroTorque * hydro_TC_Fill * hydro_TC_TMRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
hydro_TC_TMRatio = (1 - nOut2In) / (1 - hydro_TC_CouplingPoint);
|
||||
hydro_TC_TorqueIn = HydroTorque * hydro_TC_Fill * hydro_TC_TMRatio;
|
||||
hydro_TC_TorqueOut = HydroTorque * hydro_TC_Fill * hydro_TC_TMRatio;
|
||||
}
|
||||
TorqueH = hydro_TC_TorqueOut;
|
||||
TorqueL = hydro_TC_LockupTorque * hydro_TC_LockupRate;
|
||||
}
|
||||
else
|
||||
{
|
||||
TorqueH = 0; //brak przetwornika oznacza brak momentu
|
||||
TorqueL = 1 + TorqueC * 2; //zabezpieczenie, polaczenie trwale
|
||||
}
|
||||
|
||||
//sprawdzanie dociskow poszczegolnych sprzegiel
|
||||
if (abs(Moment) > Min0R(TorqueC, TorqueL + abs(hydro_TC_TorqueIn)) || (abs(dizel_n_old - enrot) > 0.1)) //slizga sie z powodu roznic predkosci albo przekroczenia momentu
|
||||
{
|
||||
dizel_engagedeltaomega = enrot - dizel_n_old;
|
||||
|
||||
if (TorqueC > TorqueL)
|
||||
{
|
||||
if (TorqueC > TorqueL + abs(TorqueH))
|
||||
{
|
||||
hydro_TC_nOut = n;
|
||||
gearMoment = TorqueL + abs(TorqueH) * sign(dizel_engagedeltaomega);
|
||||
enMoment = Moment - (TorqueL + abs(hydro_TC_TorqueIn))* sign(dizel_engagedeltaomega);
|
||||
}
|
||||
else
|
||||
{
|
||||
hydro_TC_nOut = enrot - (n - enrot)*(TorqueC - TorqueL) / TorqueH; //slizganie proporcjonalne, zeby przetwornik nadrabial
|
||||
gearMoment = TorqueC * sign(dizel_engagedeltaomega);
|
||||
enMoment = Moment - gearMoment;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
hydro_TC_nOut = enrot;
|
||||
gearMoment = (TorqueC) * sign(dizel_engagedeltaomega);
|
||||
enMoment = Moment - gearMoment;
|
||||
}
|
||||
eps = enMoment / dizel_AIM;
|
||||
newn = enrot + eps * dt;
|
||||
if ((newn - n)*(enrot - dizel_n_old) < 0) //przejscie przez zero - slizgalo sie i przestało
|
||||
newn = n;
|
||||
if ((newn * enrot <= 0) && (eps * enrot < 0)) //przejscie przez zero obrotow
|
||||
newn = 0;
|
||||
enrot = newn;
|
||||
}
|
||||
else //nie slizga sie (jeszcze)
|
||||
{
|
||||
dizel_engagedeltaomega = 0;
|
||||
gearMoment = Moment;
|
||||
enMoment = 0;
|
||||
double enrot_min = enrot - (Min0R(TorqueC, TorqueL + abs(hydro_TC_TorqueIn)) - Moment) / dizel_AIM * dt;
|
||||
double enrot_max = enrot + (Min0R(TorqueC, TorqueL + abs(hydro_TC_TorqueIn)) + Moment) / dizel_AIM * dt;
|
||||
enrot = clamp(n,enrot_min,enrot_max);
|
||||
}
|
||||
|
||||
|
||||
if ((enrot <= 0) && (!dizel_enginestart))
|
||||
{
|
||||
Mains = false;
|
||||
enrot = 0;
|
||||
}
|
||||
|
||||
dizel_n_old = n; //obecna predkosc katowa na potrzeby kolejnej klatki
|
||||
|
||||
return gearMoment;
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
@@ -7439,6 +7556,9 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
||||
extract_value( dizel_nmax_cutoff, "nmax_cutoff", Input, "0.0" );
|
||||
dizel_nmax_cutoff /= 60.0;
|
||||
extract_value( dizel_AIM, "AIM", Input, "1.0" );
|
||||
|
||||
extract_value(engageupspeed, "EUS", Input, "0.5");
|
||||
extract_value(engagedownspeed, "EDS", Input, "0.9");
|
||||
|
||||
if( true == extract_value( AnPos, "ShuntMode", Input, "" ) ) {
|
||||
//dodatkowa przekładnia dla SM03 (2Ls150)
|
||||
@@ -7448,7 +7568,34 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
||||
//"rozruch wysoki" ma dawać większą siłę
|
||||
AnPos = 1.0 / AnPos; //im większa liczba, tym wolniej jedzie
|
||||
}
|
||||
|
||||
}
|
||||
hydro_TC = (extract_value("IsTC", Input) == "Yes");
|
||||
if (true == hydro_TC) {
|
||||
extract_value(hydro_TC_TMMax, "TC_TMMax", Input, "");
|
||||
extract_value(hydro_TC_CouplingPoint, "TC_CP", Input, "");
|
||||
extract_value(hydro_TC_LockupTorque, "TC_LT", Input, "");
|
||||
extract_value(hydro_TC_LockupRate, "TC_LR", Input, "");
|
||||
extract_value(hydro_TC_UnlockRate, "TC_ULR", Input, "");
|
||||
extract_value(hydro_TC_FillRateInc, "TC_FRI", Input, "");
|
||||
extract_value(hydro_TC_FillRateDec, "TC_FRD", Input, "");
|
||||
extract_value(hydro_TC_TorqueInIn, "TC_TII", Input, "");
|
||||
extract_value(hydro_TC_TorqueInOut, "TC_TIO", Input, "");
|
||||
extract_value(hydro_TC_TorqueOutOut, "TC_TOO", Input, "");
|
||||
extract_value(hydro_TC_LockupSpeed, "TC_LS", Input, "");
|
||||
extract_value(hydro_TC_UnlockSpeed, "TC_ULS", Input, "");
|
||||
|
||||
hydro_R = (extract_value("IsRetarder", Input) == "Yes");
|
||||
if (true == hydro_R) {
|
||||
extract_value(hydro_R_Placement, "R_Place", Input, "");
|
||||
extract_value(hydro_R_TorqueInIn, "R_TII", Input, "");
|
||||
extract_value(hydro_R_MaxTorque, "R_MT", Input, "");
|
||||
extract_value(hydro_R_MaxPower, "R_MP", Input, "");
|
||||
extract_value(hydro_R_FillRateInc, "R_FRI", Input, "");
|
||||
extract_value(hydro_R_FillRateDec, "R_FRD", Input, "");
|
||||
extract_value(hydro_R_MinVel, "R_MinVel", Input, "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DieselElectric: { //youBy
|
||||
@@ -7582,6 +7729,11 @@ void TMoverParameters::LoadFIZ_DList( std::string const &Input ) {
|
||||
extract_value( dizel_nmax, "nmax", Input, "" );
|
||||
extract_value( dizel_nominalfill, "nominalfill", Input, "" );
|
||||
extract_value( dizel_Mstand, "Mstand", Input, "" );
|
||||
|
||||
if( dizel_nMmax == dizel_nmax ) {
|
||||
// HACK: guard against cases where nMmax == nmax, leading to division by 0 in momentum calculation
|
||||
dizel_nMmax = dizel_nmax - 1.0 / 60.0;
|
||||
}
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_FFList( std::string const &Input ) {
|
||||
|
||||
32
Model3d.cpp
32
Model3d.cpp
@@ -648,13 +648,14 @@ void TSubModel::InitialRotate(bool doit)
|
||||
if (fMatrix->IdentityIs())
|
||||
iFlags &= ~0x8000; // jednak jednostkowa po obróceniu
|
||||
}
|
||||
if (Child)
|
||||
Child->InitialRotate(false); // potomnych nie obracamy już, tylko
|
||||
// ewentualnie optymalizujemy
|
||||
else if (Global::iConvertModels & 2) // optymalizacja jest opcjonalna
|
||||
if( Child ) {
|
||||
// potomnych nie obracamy już, tylko ewentualnie optymalizujemy
|
||||
Child->InitialRotate( false );
|
||||
}
|
||||
else if (Global::iConvertModels & 2) {
|
||||
// optymalizacja jest opcjonalna
|
||||
if ((iFlags & 0xC000) == 0x8000) // o ile nie ma animacji
|
||||
{ // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować
|
||||
// go
|
||||
{ // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować go
|
||||
float4x4 *mat = GetMatrix(); // transform submodelu
|
||||
if( false == Vertices.empty() ) {
|
||||
for( auto &vertex : Vertices ) {
|
||||
@@ -675,6 +676,7 @@ void TSubModel::InitialRotate(bool doit)
|
||||
mat->Identity(); // jedynkowanie transformu po przeliczeniu wierzchołków
|
||||
iFlags &= ~0x8000; // transform jedynkowy
|
||||
}
|
||||
}
|
||||
}
|
||||
else // jak jest jednostkowy i nie ma animacji
|
||||
if (doit)
|
||||
@@ -1166,11 +1168,11 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const {
|
||||
auto offset { glm::vec3 { glm::make_mat4( parentmatrix.readArray() ) * glm::vec4 { 0, 0, 0, 1 } } };
|
||||
|
||||
if( glm::length2( offset ) < Geometrytestoffsetthreshold ) {
|
||||
// offset of zero generally means the submodel has optimized identity matrix
|
||||
// for such cases we resort to an estimate from submodel geometry
|
||||
// TODO: do proper bounding area calculation for submodel when loading mesh and grab the centre point from it here
|
||||
// offset of zero generally means the submodel has optimized identity matrix
|
||||
// for such cases we resort to an estimate from submodel geometry
|
||||
// TODO: do proper bounding area calculation for submodel when loading mesh and grab the centre point from it here
|
||||
if( m_geometry != null_handle ) {
|
||||
auto const &vertices{ GfxRenderer.Vertices( m_geometry ) };
|
||||
auto const &vertices { GfxRenderer.Vertices( m_geometry ) };
|
||||
if( false == vertices.empty() ) {
|
||||
// transformation matrix for the submodel can still contain rotation and/or scaling,
|
||||
// so we pass the vertex positions through it rather than just grab them directly
|
||||
@@ -1184,6 +1186,16 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const {
|
||||
}
|
||||
}
|
||||
|
||||
if( true == TestFlag( iFlags, 0x0200 ) ) {
|
||||
// flip coordinates for t3d file which wasn't yet initialized
|
||||
if( std::abs( offset.y ) > offset.z ) {
|
||||
// NOTE, HACK: results require flipping if the model wasn't yet initialized, so we're using crude method to detect possible cases
|
||||
// TODO: sort out this mess, either unify offset lookups to take place before (or after) initialization,
|
||||
// or provide way to determine on submodel level whether the initialization took place
|
||||
offset = { -offset.x, offset.z, offset.y };
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
14
Track.cpp
14
Track.cpp
@@ -489,8 +489,18 @@ void TTrack::Load(cParser *parser, vector3 pOrigin)
|
||||
}
|
||||
if( fRadius != 0 ) // gdy podany promień
|
||||
segsize = clamp( std::fabs( fRadius ) * ( 0.02 / Global::SplineFidelity ), 2.0 / Global::SplineFidelity, 10.0 );
|
||||
else
|
||||
segsize = 10.0; // for straights, 10m per segment works good enough
|
||||
else {
|
||||
// HACK: crude check whether claimed straight is an actual straight piece
|
||||
// NOTE: won't detect cases where control points are placed on the straight line formed by the ends, but, eh
|
||||
if( ( cp1 == Math3D::vector3() )
|
||||
&& ( cp1 == Math3D::vector3() ) ) {
|
||||
segsize = 10.0; // for straights, 10m per segment works good enough
|
||||
}
|
||||
else {
|
||||
// HACK: divide roughly in 10 segments.
|
||||
segsize = clamp( fTrackLength * ( 0.1 / Global::SplineFidelity ), 2.0 / Global::SplineFidelity, 10.0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ((((p1 + p1 + p2) / 3.0 - p1 - cp1).Length() < 0.02) ||
|
||||
(((p1 + p2 + p2) / 3.0 - p2 + cp1).Length() < 0.02))
|
||||
|
||||
22
Train.h
22
Train.h
@@ -83,7 +83,6 @@ class TTrain
|
||||
~TTrain();
|
||||
// McZapkie-010302
|
||||
bool Init(TDynamicObject *NewDynamicObject, bool e3d = false);
|
||||
void OnKeyDown(int cKey);
|
||||
|
||||
inline vector3 GetDirection() { return DynamicObject->VectorFront(); };
|
||||
inline vector3 GetUp() { return DynamicObject->VectorUp(); };
|
||||
@@ -114,9 +113,14 @@ class TTrain
|
||||
bool initialize_button(cParser &Parser, std::string const &Label, int const Cabindex);
|
||||
// helper, returns true for EMU with oerlikon brake
|
||||
bool is_eztoer() const;
|
||||
// locates nearest vehicle belonging to the consist
|
||||
TDynamicObject *find_nearest_consist_vehicle() const;
|
||||
|
||||
// command handlers
|
||||
// NOTE: we're currently using universal handlers and static handler map but it may be beneficial to have these implemented on individual class instance basis
|
||||
// TBD, TODO: consider this approach if we ever want to have customized consist behaviour to received commands, based on the consist/vehicle type or whatever
|
||||
static void OnCommand_aidriverenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_aidriverdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerincreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerdecrease( TTrain *Train, command_data const &Command );
|
||||
@@ -139,7 +143,12 @@ class TTrain
|
||||
static void OnCommand_trainbrakefirstservice( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakehandleoff( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakebasepressureincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakebasepressuredecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakebasepressurereset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeoperationtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_manualbrakeincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_manualbrakedecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_alarmchaintoggle( TTrain *Train, command_data const &Command );
|
||||
@@ -148,6 +157,8 @@ class TTrain
|
||||
static void OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeactingspeedincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeactingspeeddecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeloadcompensationincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeloadcompensationdecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mubrakingindicatortoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserdecrease( TTrain *Train, command_data const &Command );
|
||||
@@ -181,6 +192,8 @@ class TTrain
|
||||
static void OnCommand_headlighttogglerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkertogglerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkertogglerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_endsignalstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightsdimtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command );
|
||||
@@ -188,11 +201,17 @@ class TTrain
|
||||
static void OnCommand_doorlocktoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doortoggleleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doortoggleright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_carcouplingdisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_hornlowactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_hornhighactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiochannelincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiochanneldecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_generictoggle( TTrain *Train, command_data const &Command );
|
||||
|
||||
// members
|
||||
@@ -495,7 +514,6 @@ private:
|
||||
inline TMoverParameters *Occupied() { return mvOccupied; };
|
||||
inline TMoverParameters const *Occupied() const { return mvOccupied; };
|
||||
void DynamicSet(TDynamicObject *d);
|
||||
void Silence();
|
||||
|
||||
float get_tacho();
|
||||
float get_tank_pressure();
|
||||
|
||||
228
World.cpp
228
World.cpp
@@ -345,8 +345,7 @@ bool TWorld::Init( GLFWwindow *Window ) {
|
||||
return true;
|
||||
};
|
||||
|
||||
void TWorld::OnKeyDown(int cKey)
|
||||
{
|
||||
void TWorld::OnKeyDown(int cKey) {
|
||||
// dump keypress info in the log
|
||||
if( !Global::iPause ) {
|
||||
// podczas pauzy klawisze nie działają
|
||||
@@ -519,9 +518,7 @@ void TWorld::OnKeyDown(int cKey)
|
||||
// works always in debug mode, or for stopped/slow moving vehicles otherwise
|
||||
Controlled = tmp; // przejmujemy nowy
|
||||
mvControlled = Controlled->ControlledFind()->MoverParameters;
|
||||
if( Train )
|
||||
Train->Silence(); // wyciszenie dźwięków opuszczanego pojazdu
|
||||
else
|
||||
if( Train == nullptr )
|
||||
Train = new TTrain(); // jeśli niczym jeszcze nie jeździlismy
|
||||
if( Train->Init( Controlled ) ) { // przejmujemy sterowanie
|
||||
if( !DebugModeFlag ) // w DebugMode nadal prowadzi AI
|
||||
@@ -654,107 +651,55 @@ void TWorld::OnKeyDown(int cKey)
|
||||
if( Controlled->MoverParameters->Radio )
|
||||
simulation::Region->RadioStop( Camera.Pos );
|
||||
}
|
||||
else if (!Global::iPause) //||(cKey==VK_F4)) //podczas pauzy sterownaie nie działa, F4 tak
|
||||
if (Train)
|
||||
if (Controlled)
|
||||
if ((Controlled->Controller == Humandriver) ? true : DebugModeFlag || (cKey == GLFW_KEY_Q))
|
||||
Train->OnKeyDown(cKey); // przekazanie klawisza do kabiny
|
||||
if (FreeFlyModeFlag) // aby nie odluźniało wagonu za lokomotywą
|
||||
{ // operacje wykonywane na dowolnym pojeździe, przeniesione tu z kabiny
|
||||
/*
|
||||
// NOTE: disabled so it doesn't interfere with new system controls in outside view
|
||||
// TODO: implement as part of the new system
|
||||
if (cKey == Global::Keys[k_Releaser]) // odluźniacz
|
||||
{ // działa globalnie, sprawdzić zasięg
|
||||
TDynamicObject *temp = Global::DynamicNearest();
|
||||
if (temp)
|
||||
{
|
||||
if (Global::ctrlState) // z ctrl odcinanie
|
||||
{
|
||||
temp->MoverParameters->Hamulec->SetBrakeStatus( temp->MoverParameters->Hamulec->GetBrakeStatus() ^ 128 );
|
||||
}
|
||||
else if (temp->MoverParameters->BrakeReleaser(1))
|
||||
{
|
||||
// temp->sBrakeAcc->
|
||||
// dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX);
|
||||
// dsbPneumaticRelay->Play(0,0,0); //temp->Position()-Camera.Pos //???
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
if (cKey == Global::Keys[k_Heating]) // Ra: klawisz nie jest najszczęśliwszy
|
||||
{ // zmiana próżny/ładowny; Ra: zabrane z kabiny
|
||||
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 10, false, false ) ) };
|
||||
if (vehicle)
|
||||
{
|
||||
if (Global::shiftState ? vehicle->MoverParameters->IncBrakeMult() :
|
||||
vehicle->MoverParameters->DecBrakeMult())
|
||||
if (Train)
|
||||
{ // dźwięk oczywiście jest w kabinie
|
||||
Train->dsbSwitch.play();
|
||||
else {
|
||||
|
||||
if( ( true == DebugModeFlag )
|
||||
&& ( false == Global::shiftState )
|
||||
&& ( true == Global::ctrlState )
|
||||
&& ( Controlled != nullptr )
|
||||
&& ( Controlled->Controller == Humandriver ) ) {
|
||||
|
||||
if( DebugModeFlag ) {
|
||||
// przesuwanie składu o 100m
|
||||
TDynamicObject *d = Controlled;
|
||||
if( cKey == GLFW_KEY_LEFT_BRACKET ) {
|
||||
while( d ) {
|
||||
d->Move( 100.0 * d->DirectionGet() );
|
||||
d = d->Next(); // pozostałe też
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cKey == Global::Keys[k_EndSign])
|
||||
{ // Ra 2014-07: zabrane z kabiny
|
||||
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 10, false, true ) ) };
|
||||
if (vehicle)
|
||||
{
|
||||
int CouplNr = (LengthSquared3(vehicle->HeadPosition() - Camera.Pos) >
|
||||
LengthSquared3(vehicle->RearPosition() - Camera.Pos) ?
|
||||
1 :
|
||||
-1) *
|
||||
vehicle->DirectionGet();
|
||||
if (CouplNr < 0)
|
||||
CouplNr = 0; // z [-1,1] zrobić [0,1]
|
||||
int mask, set = 0; // Ra: [Shift]+[Ctrl]+[T] odpala mi jakąś idiotyczną zmianę tapety pulpitu :/
|
||||
if (Global::shiftState) // z [Shift] zapalanie
|
||||
set = mask = light::rearendsignals; // bez [Ctrl] założyć tabliczki
|
||||
else if (Global::ctrlState)
|
||||
set = mask = ( light::redmarker_left | light::redmarker_right ); // z [Ctrl] zapalić światła czerwone
|
||||
else
|
||||
mask = 2 + 32 + 64; // wyłączanie ściąga wszystko
|
||||
if (((vehicle->iLights[CouplNr]) & mask) != set)
|
||||
{
|
||||
vehicle->iLights[CouplNr] = (vehicle->iLights[CouplNr] & ~mask) | set;
|
||||
if (Train)
|
||||
{ // Ra: ten dźwięk z kabiny to przegięcie, ale na razie zostawiam
|
||||
Train->dsbSwitch.play();
|
||||
d = Controlled->Prev();
|
||||
while( d ) {
|
||||
d->Move( 100.0 * d->DirectionGet() );
|
||||
d = d->Prev(); // w drugą stronę też
|
||||
}
|
||||
}
|
||||
else if( cKey == GLFW_KEY_RIGHT_BRACKET ) {
|
||||
while( d ) {
|
||||
d->Move( -100.0 * d->DirectionGet() );
|
||||
d = d->Next(); // pozostałe też
|
||||
}
|
||||
d = Controlled->Prev();
|
||||
while( d ) {
|
||||
d->Move( -100.0 * d->DirectionGet() );
|
||||
d = d->Prev(); // w drugą stronę też
|
||||
}
|
||||
}
|
||||
else if( cKey == GLFW_KEY_TAB ) {
|
||||
while( d ) {
|
||||
d->MoverParameters->V += d->DirectionGet()*2.78;
|
||||
d = d->Next(); // pozostałe też
|
||||
}
|
||||
d = Controlled->Prev();
|
||||
while( d ) {
|
||||
d->MoverParameters->V += d->DirectionGet()*2.78;
|
||||
d = d->Prev(); // w drugą stronę też
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cKey == Global::Keys[k_IncLocalBrakeLevel])
|
||||
{ // zahamowanie dowolnego pojazdu
|
||||
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 10, false, false ) ) };
|
||||
if (vehicle)
|
||||
{
|
||||
if (Global::ctrlState)
|
||||
if ((vehicle->MoverParameters->LocalBrake == ManualBrake) ||
|
||||
(vehicle->MoverParameters->MBrake == true))
|
||||
vehicle->MoverParameters->IncManualBrakeLevel(1);
|
||||
}
|
||||
}
|
||||
else if (cKey == Global::Keys[k_DecLocalBrakeLevel])
|
||||
{ // odhamowanie dowolnego pojazdu
|
||||
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 10, false, false ) ) };
|
||||
if (vehicle)
|
||||
{
|
||||
if (Global::ctrlState)
|
||||
if ((vehicle->MoverParameters->LocalBrake == ManualBrake) ||
|
||||
(vehicle->MoverParameters->MBrake == true))
|
||||
vehicle->MoverParameters->DecManualBrakeLevel(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TWorld::OnMouseMove(double x, double y)
|
||||
{ // McZapkie:060503-definicja obracania myszy
|
||||
Camera.OnCursorMove(x * Global::fMouseXScale / Global::ZoomFactor, -y * Global::fMouseYScale / Global::ZoomFactor);
|
||||
}
|
||||
|
||||
void TWorld::InOutKey( bool const Near )
|
||||
{ // przełączenie widoku z kabiny na zewnętrzny i odwrotnie
|
||||
FreeFlyModeFlag = !FreeFlyModeFlag; // zmiana widoku
|
||||
@@ -763,8 +708,6 @@ void TWorld::InOutKey( bool const Near )
|
||||
if (Train) {
|
||||
// cache current cab position so there's no need to set it all over again after each out-in switch
|
||||
Train->pMechSittingPosition = Train->pMechOffset;
|
||||
// wyłączenie dźwięków kabiny
|
||||
Train->Silence();
|
||||
Train->Dynamic()->bDisplayCab = false;
|
||||
DistantView( Near );
|
||||
}
|
||||
@@ -1244,6 +1187,15 @@ TWorld::Update_UI() {
|
||||
|
||||
uitextline3 = "Brakes:" + to_string( mover->fBrakeCtrlPos, 1, 5 ) + "+" + std::to_string( mover->LocalBrakePos ) + ( mover->SlippingWheels ? " !" : " " );
|
||||
|
||||
uitextline4 = (
|
||||
true == TestFlag( mover->SecuritySystem.Status, s_aware ) ?
|
||||
"!ALERTER! " :
|
||||
" " );
|
||||
uitextline4 += (
|
||||
true == TestFlag( mover->SecuritySystem.Status, s_active ) ?
|
||||
"!SHP! " :
|
||||
" " );
|
||||
|
||||
if( Global::iScreenMode[ Global::iTextMode - GLFW_KEY_F1 ] == 1 ) {
|
||||
// detail mode on second key press
|
||||
uitextline2 +=
|
||||
@@ -1257,7 +1209,7 @@ TWorld::Update_UI() {
|
||||
|
||||
auto const trackblockdistance{ std::abs( Controlled->Mechanik->TrackBlock() ) };
|
||||
if( trackblockdistance <= 75.0 ) {
|
||||
uitextline4 = " Another vehicle ahead (distance: " + to_string( trackblockdistance, 1 ) + " m)";
|
||||
uitextline4 += " Another vehicle ahead (distance: " + to_string( trackblockdistance, 1 ) + " m)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1458,6 +1410,7 @@ TWorld::Update_UI() {
|
||||
|
||||
uitextline3 +=
|
||||
"; LcB: " + to_string( vehicle->MoverParameters->LocBrakePress, 2 )
|
||||
+ "; hat: " + to_string( vehicle->MoverParameters->BrakeCtrlPos2, 2 )
|
||||
+ "; pipes: " + to_string( vehicle->MoverParameters->PipePress, 2 )
|
||||
+ "/" + to_string( vehicle->MoverParameters->ScndPipePress, 2 )
|
||||
+ "/" + to_string( vehicle->MoverParameters->EqvtPipePress, 2 )
|
||||
@@ -1743,6 +1696,40 @@ TWorld::Update_UI() {
|
||||
UITable->text_lines.emplace_back( parameters, Global::UITextColor );
|
||||
}
|
||||
}
|
||||
if (vehicle->MoverParameters->EngineType == DieselEngine) {
|
||||
std::string parameters = "param value";
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "efill: " + to_string(vehicle->MoverParameters->dizel_fill, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "etorq: " + to_string(vehicle->MoverParameters->dizel_Torque, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "creal: " + to_string(vehicle->MoverParameters->dizel_engage, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "cdesi: " + to_string(vehicle->MoverParameters->dizel_engagestate, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "cdelt: " + to_string(vehicle->MoverParameters->dizel_engagedeltaomega, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "gears: " + to_string(vehicle->MoverParameters->dizel_automaticgearstatus, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "hydro value";
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "hTCnI: " + to_string(vehicle->MoverParameters->hydro_TC_nIn, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "hTCnO: " + to_string(vehicle->MoverParameters->hydro_TC_nOut, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "hTCTM: " + to_string(vehicle->MoverParameters->hydro_TC_TMRatio, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "hTCTI: " + to_string(vehicle->MoverParameters->hydro_TC_TorqueIn, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "hTCTO: " + to_string(vehicle->MoverParameters->hydro_TC_TorqueOut, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "hTCfl: " + to_string(vehicle->MoverParameters->hydro_TC_Fill, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
parameters = "hTCLR: " + to_string(vehicle->MoverParameters->hydro_TC_LockupRate, 2, 9);
|
||||
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
//parameters = "hTCXX: " + to_string(vehicle->MoverParameters->hydro_TC_nIn, 2, 9);
|
||||
//UITable->text_lines.emplace_back(parameters, Global::UITextColor);
|
||||
}
|
||||
|
||||
} // if( DebugModeFlag && Controlled )
|
||||
|
||||
@@ -2082,26 +2069,28 @@ void TWorld::CabChange(TDynamicObject *old, TDynamicObject *now)
|
||||
void TWorld::ChangeDynamic() {
|
||||
|
||||
// Ra: to nie może być tak robione, to zbytnia proteza jest
|
||||
Train->Silence(); // wyłączenie dźwięków opuszczanej kabiny
|
||||
if( Train->Dynamic()->Mechanik ) // AI może sobie samo pójść
|
||||
if( !Train->Dynamic()->Mechanik->AIControllFlag ) // tylko jeśli ręcznie prowadzony
|
||||
{ // jeśli prowadzi AI, to mu nie robimy dywersji!
|
||||
if( Train->Dynamic()->Mechanik ) {
|
||||
// AI może sobie samo pójść
|
||||
if( false == Train->Dynamic()->Mechanik->AIControllFlag ) {
|
||||
// tylko jeśli ręcznie prowadzony
|
||||
// jeśli prowadzi AI, to mu nie robimy dywersji!
|
||||
Train->Dynamic()->MoverParameters->CabDeactivisation();
|
||||
Train->Dynamic()->Controller = AIdriver;
|
||||
// Train->Dynamic()->MoverParameters->SecuritySystem.Status=0; //rozwala CA w EZT
|
||||
Train->Dynamic()->MoverParameters->ActiveCab = 0;
|
||||
Train->Dynamic()->MoverParameters->BrakeLevelSet(
|
||||
Train->Dynamic()->MoverParameters->Handle->GetPos(
|
||||
bh_NP ) ); //rozwala sterowanie hamulcem GF 04-2016
|
||||
Train->Dynamic()->MoverParameters->BrakeLevelSet( Train->Dynamic()->MoverParameters->Handle->GetPos( bh_NP ) ); //rozwala sterowanie hamulcem GF 04-2016
|
||||
Train->Dynamic()->MechInside = false;
|
||||
}
|
||||
}
|
||||
TDynamicObject *temp = Global::changeDynObj;
|
||||
Train->Dynamic()->bDisplayCab = false;
|
||||
Train->Dynamic()->ABuSetModelShake( vector3( 0, 0, 0 ) );
|
||||
Train->Dynamic()->ABuSetModelShake( {} );
|
||||
|
||||
if( Train->Dynamic()->Mechanik ) // AI może sobie samo pójść
|
||||
if( !Train->Dynamic()->Mechanik->AIControllFlag ) // tylko jeśli ręcznie prowadzony
|
||||
Train->Dynamic()->Mechanik->MoveTo( temp ); // przsunięcie obiektu zarządzającego
|
||||
if( false == Train->Dynamic()->Mechanik->AIControllFlag ) {
|
||||
// tylko jeśli ręcznie prowadzony
|
||||
// przsunięcie obiektu zarządzającego
|
||||
Train->Dynamic()->Mechanik->MoveTo( temp );
|
||||
}
|
||||
|
||||
Train->DynamicSet( temp );
|
||||
Controlled = temp;
|
||||
@@ -2110,20 +2099,17 @@ void TWorld::ChangeDynamic() {
|
||||
if( Train->Dynamic()->Mechanik ) // AI może sobie samo pójść
|
||||
if( !Train->Dynamic()->Mechanik->AIControllFlag ) // tylko jeśli ręcznie prowadzony
|
||||
{
|
||||
Train->Dynamic()->MoverParameters->LimPipePress =
|
||||
Controlled->MoverParameters->PipePress;
|
||||
Train->Dynamic()
|
||||
->MoverParameters->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
|
||||
Train->Dynamic()->MoverParameters->LimPipePress = Controlled->MoverParameters->PipePress;
|
||||
Train->Dynamic()->MoverParameters->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
|
||||
Train->Dynamic()->Controller = Humandriver;
|
||||
Train->Dynamic()->MechInside = true;
|
||||
}
|
||||
Train->InitializeCab( Train->Dynamic()->MoverParameters->CabNo,
|
||||
Train->Dynamic()->asBaseDir +
|
||||
Train->Dynamic()->MoverParameters->TypeName + ".mmd" );
|
||||
Train->InitializeCab(
|
||||
Train->Dynamic()->MoverParameters->CabNo,
|
||||
Train->Dynamic()->asBaseDir + Train->Dynamic()->MoverParameters->TypeName + ".mmd" );
|
||||
if( !FreeFlyModeFlag ) {
|
||||
Train->Dynamic()->bDisplayCab = true;
|
||||
Train->Dynamic()->ABuSetModelShake(
|
||||
vector3( 0, 0, 0 ) ); // zerowanie przesunięcia przed powrotem?
|
||||
Train->Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
|
||||
Train->MechStop();
|
||||
FollowView(); // na pozycję mecha
|
||||
}
|
||||
|
||||
1
World.h
1
World.h
@@ -102,7 +102,6 @@ TWorld();
|
||||
bool InitPerformed() { return m_init; }
|
||||
bool Update();
|
||||
void OnKeyDown( int cKey );
|
||||
void OnMouseMove( double x, double y );
|
||||
void OnCommandGet( multiplayer::DaneRozkaz *pRozkaz );
|
||||
// passes specified sound to all vehicles within range as a radio message broadcasted on specified channel
|
||||
void radio_message( sound_source *Message, int const Channel );
|
||||
|
||||
16
audio.cpp
16
audio.cpp
@@ -64,6 +64,22 @@ openal_buffer::openal_buffer( std::string const &Filename ) :
|
||||
if (si.channels != 1)
|
||||
delete[] buf;
|
||||
delete[] fbuf;
|
||||
|
||||
fetch_caption();
|
||||
}
|
||||
|
||||
// retrieves sound caption in currently set language
|
||||
void
|
||||
openal_buffer::fetch_caption() {
|
||||
|
||||
std::string captionfilename{ name };
|
||||
captionfilename.erase(captionfilename.rfind('.')); // obcięcie rozszerzenia
|
||||
captionfilename += "-" + Global::asLang + ".txt"; // już może być w różnych językach
|
||||
if (true == FileExists(captionfilename)) {
|
||||
// wczytanie
|
||||
std::ifstream inputfile(captionfilename);
|
||||
caption.assign(std::istreambuf_iterator<char>(inputfile), std::istreambuf_iterator<char>());
|
||||
}
|
||||
}
|
||||
|
||||
buffer_manager::~buffer_manager() {
|
||||
|
||||
8
audio.h
8
audio.h
@@ -20,11 +20,17 @@ ALuint const null_resource{ ~( ALuint { 0 } ) };
|
||||
struct openal_buffer {
|
||||
// members
|
||||
ALuint id { null_resource }; // associated AL resource
|
||||
unsigned int rate { 0 }; // sample rate of the data
|
||||
unsigned int rate {}; // sample rate of the data
|
||||
std::string name;
|
||||
std::string caption;
|
||||
// constructors
|
||||
openal_buffer() = default;
|
||||
explicit openal_buffer( std::string const &Filename );
|
||||
// methods
|
||||
// retrieves sound caption in currently set language
|
||||
void
|
||||
fetch_caption();
|
||||
|
||||
};
|
||||
|
||||
using buffer_handle = std::size_t;
|
||||
|
||||
@@ -165,8 +165,11 @@ openal_source::bind( sound_source *Controller, uint32_sequence Sounds, Iterator_
|
||||
std::vector<ALuint> buffers;
|
||||
std::for_each(
|
||||
First, Last,
|
||||
[&]( audio::buffer_handle const &buffer ) {
|
||||
buffers.emplace_back( audio::renderer.buffer( buffer ).id ); } );
|
||||
[&]( audio::buffer_handle const &bufferhandle ) {
|
||||
auto const &buffer { audio::renderer.buffer( bufferhandle ) };
|
||||
buffers.emplace_back( buffer.id );
|
||||
if( false == buffer.caption.empty() ) {
|
||||
Global::tranTexts.Add( buffer.caption ); } } );
|
||||
|
||||
if( id != audio::null_resource ) {
|
||||
::alSourceQueueBuffers( id, static_cast<ALsizei>( buffers.size() ), buffers.data() );
|
||||
|
||||
233
command.cpp
233
command.cpp
@@ -19,128 +19,123 @@ namespace simulation {
|
||||
command_queue Commands;
|
||||
commanddescription_sequence Commands_descriptions = {
|
||||
|
||||
{ "mastercontrollerincrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "mastercontrollerincreasefast", command_target::vehicle, command_mode::oneoff },
|
||||
{ "mastercontrollerdecrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "mastercontrollerdecreasefast", command_target::vehicle, command_mode::oneoff },
|
||||
{ "secondcontrollerincrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "secondcontrollerincreasefast", command_target::vehicle, command_mode::oneoff },
|
||||
{ "secondcontrollerdecrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "secondcontrollerdecreasefast", command_target::vehicle, command_mode::oneoff },
|
||||
{ "mucurrentindicatorothersourceactivate", command_target::vehicle, command_mode::oneoff },
|
||||
{ "independentbrakeincrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "independentbrakeincreasefast", command_target::vehicle, command_mode::oneoff },
|
||||
{ "independentbrakedecrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "independentbrakedecreasefast", command_target::vehicle, command_mode::oneoff },
|
||||
{ "independentbrakebailoff", command_target::vehicle, command_mode::oneoff },
|
||||
{ "aidriverenable", command_target::vehicle },
|
||||
{ "aidriverdisable", command_target::vehicle },
|
||||
{ "mastercontrollerincrease", command_target::vehicle },
|
||||
{ "mastercontrollerincreasefast", command_target::vehicle },
|
||||
{ "mastercontrollerdecrease", command_target::vehicle },
|
||||
{ "mastercontrollerdecreasefast", command_target::vehicle },
|
||||
{ "secondcontrollerincrease", command_target::vehicle },
|
||||
{ "secondcontrollerincreasefast", command_target::vehicle },
|
||||
{ "secondcontrollerdecrease", command_target::vehicle },
|
||||
{ "secondcontrollerdecreasefast", command_target::vehicle },
|
||||
{ "mucurrentindicatorothersourceactivate", command_target::vehicle },
|
||||
{ "independentbrakeincrease", command_target::vehicle },
|
||||
{ "independentbrakeincreasefast", command_target::vehicle },
|
||||
{ "independentbrakedecrease", command_target::vehicle },
|
||||
{ "independentbrakedecreasefast", command_target::vehicle },
|
||||
{ "independentbrakebailoff", command_target::vehicle },
|
||||
{ "trainbrakeincrease", command_target::vehicle, command_mode::continuous },
|
||||
{ "trainbrakedecrease", command_target::vehicle, command_mode::continuous },
|
||||
{ "trainbrakecharging", command_target::vehicle, command_mode::oneoff },
|
||||
{ "trainbrakerelease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "trainbrakefirstservice", command_target::vehicle, command_mode::oneoff },
|
||||
{ "trainbrakeservice", command_target::vehicle, command_mode::oneoff },
|
||||
{ "trainbrakefullservice", command_target::vehicle, command_mode::oneoff },
|
||||
{ "trainbrakeemergency", command_target::vehicle, command_mode::oneoff },
|
||||
{ "manualbrakeincrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "manualbrakedecrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "alarmchaintoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "wheelspinbrakeactivate", command_target::vehicle, command_mode::oneoff },
|
||||
{ "sandboxactivate", command_target::vehicle, command_mode::oneoff },
|
||||
{ "reverserincrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "reverserdecrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "linebreakertoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "convertertoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "convertertogglelocal", command_target::vehicle, command_mode::oneoff },
|
||||
{ "converteroverloadrelayreset", command_target::vehicle, command_mode::oneoff },
|
||||
{ "compressortoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "compressortogglelocal", command_target::vehicle, command_mode::oneoff },
|
||||
{ "motoroverloadrelaythresholdtoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "motoroverloadrelayreset", command_target::vehicle, command_mode::oneoff },
|
||||
{ "notchingrelaytoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "epbrakecontroltoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "brakeactingspeedincrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "brakeactingspeeddecrease", command_target::vehicle, command_mode::oneoff },
|
||||
{ "mubrakingindicatortoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "alerteracknowledge", command_target::vehicle, command_mode::oneoff },
|
||||
{ "hornlowactivate", command_target::vehicle, command_mode::oneoff },
|
||||
{ "hornhighactivate", command_target::vehicle, command_mode::oneoff },
|
||||
{ "radiotoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "radiostoptest", command_target::vehicle, command_mode::oneoff },
|
||||
/*
|
||||
const int k_FailedEngineCutOff = 35;
|
||||
*/
|
||||
{ "viewturn", command_target::entity, command_mode::oneoff },
|
||||
{ "movevector", command_target::entity, command_mode::oneoff },
|
||||
{ "moveleft", command_target::entity, command_mode::oneoff },
|
||||
{ "moveright", command_target::entity, command_mode::oneoff },
|
||||
{ "moveforward", command_target::entity, command_mode::oneoff },
|
||||
{ "moveback", command_target::entity, command_mode::oneoff },
|
||||
{ "moveup", command_target::entity, command_mode::oneoff },
|
||||
{ "movedown", command_target::entity, command_mode::oneoff },
|
||||
{ "moveleftfast", command_target::entity, command_mode::oneoff },
|
||||
{ "moverightfast", command_target::entity, command_mode::oneoff },
|
||||
{ "moveforwardfast", command_target::entity, command_mode::oneoff },
|
||||
{ "movebackfast", command_target::entity, command_mode::oneoff },
|
||||
{ "moveupfast", command_target::entity, command_mode::oneoff },
|
||||
{ "movedownfast", command_target::entity, command_mode::oneoff },
|
||||
/*
|
||||
const int k_CabForward = 42;
|
||||
const int k_CabBackward = 43;
|
||||
const int k_Couple = 44;
|
||||
const int k_DeCouple = 45;
|
||||
const int k_ProgramQuit = 46;
|
||||
// const int k_ProgramPause= 47;
|
||||
const int k_ProgramHelp = 48;
|
||||
*/
|
||||
{ "doortoggleleft", command_target::vehicle, command_mode::oneoff },
|
||||
{ "doortoggleright", command_target::vehicle, command_mode::oneoff },
|
||||
{ "departureannounce", command_target::vehicle, command_mode::oneoff },
|
||||
{ "doorlocktoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "pantographcompressorvalvetoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "pantographcompressoractivate", command_target::vehicle, command_mode::oneoff },
|
||||
{ "pantographtogglefront", command_target::vehicle, command_mode::oneoff },
|
||||
{ "pantographtogglerear", command_target::vehicle, command_mode::oneoff },
|
||||
{ "pantographlowerall", command_target::vehicle, command_mode::oneoff },
|
||||
{ "heatingtoggle", command_target::vehicle, command_mode::oneoff },
|
||||
/*
|
||||
// const int k_FreeFlyMode= 59;
|
||||
*/
|
||||
{ "lightspresetactivatenext", command_target::vehicle, command_mode::oneoff },
|
||||
{ "lightspresetactivateprevious", command_target::vehicle, command_mode::oneoff },
|
||||
{ "headlighttoggleleft", command_target::vehicle, command_mode::oneoff },
|
||||
{ "headlighttoggleright", command_target::vehicle, command_mode::oneoff },
|
||||
{ "headlighttoggleupper", command_target::vehicle, command_mode::oneoff },
|
||||
{ "redmarkertoggleleft", command_target::vehicle, command_mode::oneoff },
|
||||
{ "redmarkertoggleright", command_target::vehicle, command_mode::oneoff },
|
||||
{ "headlighttogglerearleft", command_target::vehicle, command_mode::oneoff },
|
||||
{ "headlighttogglerearright", command_target::vehicle, command_mode::oneoff },
|
||||
{ "headlighttogglerearupper", command_target::vehicle, command_mode::oneoff },
|
||||
{ "redmarkertogglerearleft", command_target::vehicle, command_mode::oneoff },
|
||||
{ "redmarkertogglerearright", command_target::vehicle, command_mode::oneoff },
|
||||
{ "headlightsdimtoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "motorconnectorsopen", command_target::vehicle, command_mode::oneoff },
|
||||
{ "motordisconnect", command_target::vehicle, command_mode::oneoff },
|
||||
{ "interiorlighttoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "interiorlightdimtoggle", command_target::vehicle, command_mode::oneoff },
|
||||
{ "instrumentlighttoggle", command_target::vehicle, command_mode::oneoff },
|
||||
/*
|
||||
const int k_EndSign = 70;
|
||||
const int k_Active = 71;
|
||||
*/
|
||||
{ "generictoggle0", command_target::vehicle, command_mode::oneoff },
|
||||
{ "generictoggle1", command_target::vehicle, command_mode::oneoff },
|
||||
{ "generictoggle2", command_target::vehicle, command_mode::oneoff },
|
||||
{ "generictoggle3", command_target::vehicle, command_mode::oneoff },
|
||||
{ "generictoggle4", command_target::vehicle, command_mode::oneoff },
|
||||
{ "generictoggle5", command_target::vehicle, command_mode::oneoff },
|
||||
{ "generictoggle6", command_target::vehicle, command_mode::oneoff },
|
||||
{ "generictoggle7", command_target::vehicle, command_mode::oneoff },
|
||||
{ "generictoggle8", command_target::vehicle, command_mode::oneoff },
|
||||
{ "generictoggle9", command_target::vehicle, command_mode::oneoff },
|
||||
{ "trainbrakecharging", command_target::vehicle },
|
||||
{ "trainbrakerelease", command_target::vehicle },
|
||||
{ "trainbrakefirstservice", command_target::vehicle },
|
||||
{ "trainbrakeservice", command_target::vehicle },
|
||||
{ "trainbrakefullservice", command_target::vehicle },
|
||||
{ "trainbrakehandleoff", command_target::vehicle },
|
||||
{ "trainbrakeemergency", command_target::vehicle },
|
||||
{ "trainbrakebasepressureincrease", command_target::vehicle },
|
||||
{ "trainbrakebasepressuredecrease", command_target::vehicle },
|
||||
{ "trainbrakebasepressurereset", command_target::vehicle },
|
||||
{ "trainbrakeoperationtoggle", command_target::vehicle },
|
||||
{ "manualbrakeincrease", command_target::vehicle },
|
||||
{ "manualbrakedecrease", command_target::vehicle },
|
||||
{ "alarmchaintoggle", command_target::vehicle },
|
||||
{ "wheelspinbrakeactivate", command_target::vehicle },
|
||||
{ "sandboxactivate", command_target::vehicle },
|
||||
{ "reverserincrease", command_target::vehicle },
|
||||
{ "reverserdecrease", command_target::vehicle },
|
||||
{ "linebreakertoggle", command_target::vehicle },
|
||||
{ "convertertoggle", command_target::vehicle },
|
||||
{ "convertertogglelocal", command_target::vehicle },
|
||||
{ "converteroverloadrelayreset", command_target::vehicle },
|
||||
{ "compressortoggle", command_target::vehicle },
|
||||
{ "compressortogglelocal", command_target::vehicle },
|
||||
{ "motoroverloadrelaythresholdtoggle", command_target::vehicle },
|
||||
{ "motoroverloadrelayreset", command_target::vehicle },
|
||||
{ "notchingrelaytoggle", command_target::vehicle },
|
||||
{ "epbrakecontroltoggle", command_target::vehicle },
|
||||
{ "brakeactingspeedincrease", command_target::vehicle },
|
||||
{ "brakeactingspeeddecrease", command_target::vehicle },
|
||||
{ "brakeloadcompensationincrease", command_target::vehicle },
|
||||
{ "brakeloadcompensationdecrease", command_target::vehicle },
|
||||
{ "mubrakingindicatortoggle", command_target::vehicle },
|
||||
{ "alerteracknowledge", command_target::vehicle },
|
||||
{ "hornlowactivate", command_target::vehicle },
|
||||
{ "hornhighactivate", command_target::vehicle },
|
||||
{ "radiotoggle", command_target::vehicle },
|
||||
{ "radiochannelincrease", command_target::vehicle },
|
||||
{ "radiochanneldecrease", command_target::vehicle },
|
||||
{ "radiostoptest", command_target::vehicle },
|
||||
// TBD, TODO: make cab change controls entity-centric
|
||||
{ "cabchangeforward", command_target::vehicle },
|
||||
{ "cabchangebackward", command_target::vehicle },
|
||||
|
||||
{ "viewturn", command_target::entity },
|
||||
{ "movehorizontal", command_target::entity },
|
||||
{ "movehorizontalfast", command_target::entity },
|
||||
{ "movevertical", command_target::entity },
|
||||
{ "moveverticalfast", command_target::entity },
|
||||
{ "moveleft", command_target::entity },
|
||||
{ "moveright", command_target::entity },
|
||||
{ "moveforward", command_target::entity },
|
||||
{ "moveback", command_target::entity },
|
||||
{ "moveup", command_target::entity },
|
||||
{ "movedown", command_target::entity },
|
||||
// TBD, TODO: make coupling controls entity-centric
|
||||
{ "carcouplingincrease", command_target::vehicle },
|
||||
{ "carcouplingdisconnect", command_target::vehicle },
|
||||
{ "doortoggleleft", command_target::vehicle },
|
||||
{ "doortoggleright", command_target::vehicle },
|
||||
{ "departureannounce", command_target::vehicle },
|
||||
{ "doorlocktoggle", command_target::vehicle },
|
||||
{ "pantographcompressorvalvetoggle", command_target::vehicle },
|
||||
{ "pantographcompressoractivate", command_target::vehicle },
|
||||
{ "pantographtogglefront", command_target::vehicle },
|
||||
{ "pantographtogglerear", command_target::vehicle },
|
||||
{ "pantographlowerall", command_target::vehicle },
|
||||
{ "heatingtoggle", command_target::vehicle },
|
||||
{ "lightspresetactivatenext", command_target::vehicle },
|
||||
{ "lightspresetactivateprevious", command_target::vehicle },
|
||||
{ "headlighttoggleleft", command_target::vehicle },
|
||||
{ "headlighttoggleright", command_target::vehicle },
|
||||
{ "headlighttoggleupper", command_target::vehicle },
|
||||
{ "redmarkertoggleleft", command_target::vehicle },
|
||||
{ "redmarkertoggleright", command_target::vehicle },
|
||||
{ "headlighttogglerearleft", command_target::vehicle },
|
||||
{ "headlighttogglerearright", command_target::vehicle },
|
||||
{ "headlighttogglerearupper", command_target::vehicle },
|
||||
{ "redmarkertogglerearleft", command_target::vehicle },
|
||||
{ "redmarkertogglerearright", command_target::vehicle },
|
||||
{ "redmarkerstoggle", command_target::vehicle },
|
||||
{ "endsignalstoggle", command_target::vehicle },
|
||||
{ "headlightsdimtoggle", command_target::vehicle },
|
||||
{ "motorconnectorsopen", command_target::vehicle },
|
||||
{ "motordisconnect", command_target::vehicle },
|
||||
{ "interiorlighttoggle", command_target::vehicle },
|
||||
{ "interiorlightdimtoggle", command_target::vehicle },
|
||||
{ "instrumentlighttoggle", command_target::vehicle },
|
||||
{ "generictoggle0", command_target::vehicle },
|
||||
{ "generictoggle1", command_target::vehicle },
|
||||
{ "generictoggle2", command_target::vehicle },
|
||||
{ "generictoggle3", command_target::vehicle },
|
||||
{ "generictoggle4", command_target::vehicle },
|
||||
{ "generictoggle5", command_target::vehicle },
|
||||
{ "generictoggle6", command_target::vehicle },
|
||||
{ "generictoggle7", command_target::vehicle },
|
||||
{ "generictoggle8", command_target::vehicle },
|
||||
{ "generictoggle9", command_target::vehicle },
|
||||
{ "batterytoggle", command_target::vehicle }
|
||||
/*
|
||||
const int k_WalkMode = 73;
|
||||
*/
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
55
command.h
55
command.h
@@ -15,6 +15,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
enum class user_command {
|
||||
|
||||
aidriverenable,
|
||||
aidriverdisable,
|
||||
mastercontrollerincrease,
|
||||
mastercontrollerincreasefast,
|
||||
mastercontrollerdecrease,
|
||||
@@ -36,7 +38,12 @@ enum class user_command {
|
||||
trainbrakefirstservice,
|
||||
trainbrakeservice,
|
||||
trainbrakefullservice,
|
||||
trainbrakehandleoff,
|
||||
trainbrakeemergency,
|
||||
trainbrakebasepressureincrease,
|
||||
trainbrakebasepressuredecrease,
|
||||
trainbrakebasepressurereset,
|
||||
trainbrakeoperationtoggle,
|
||||
manualbrakeincrease,
|
||||
manualbrakedecrease,
|
||||
alarmchaintoggle,
|
||||
@@ -56,38 +63,33 @@ enum class user_command {
|
||||
epbrakecontroltoggle,
|
||||
brakeactingspeedincrease,
|
||||
brakeactingspeeddecrease,
|
||||
brakeloadcompensationincrease,
|
||||
brakeloadcompensationdecrease,
|
||||
mubrakingindicatortoggle,
|
||||
alerteracknowledge,
|
||||
hornlowactivate,
|
||||
hornhighactivate,
|
||||
radiotoggle,
|
||||
radiochannelincrease,
|
||||
radiochanneldecrease,
|
||||
radiostoptest,
|
||||
/*
|
||||
const int k_FailedEngineCutOff = 35;
|
||||
*/
|
||||
cabchangeforward,
|
||||
cabchangebackward,
|
||||
|
||||
viewturn,
|
||||
movevector,
|
||||
movehorizontal,
|
||||
movehorizontalfast,
|
||||
movevertical,
|
||||
moveverticalfast,
|
||||
moveleft,
|
||||
moveright,
|
||||
moveforward,
|
||||
moveback,
|
||||
moveup,
|
||||
movedown,
|
||||
moveleftfast,
|
||||
moverightfast,
|
||||
moveforwardfast,
|
||||
movebackfast,
|
||||
moveupfast,
|
||||
movedownfast,
|
||||
/*
|
||||
const int k_CabForward = 42;
|
||||
const int k_CabBackward = 43;
|
||||
const int k_Couple = 44;
|
||||
const int k_DeCouple = 45;
|
||||
const int k_ProgramQuit = 46;
|
||||
// const int k_ProgramPause= 47;
|
||||
const int k_ProgramHelp = 48;
|
||||
*/
|
||||
|
||||
carcouplingincrease,
|
||||
carcouplingdisconnect,
|
||||
doortoggleleft,
|
||||
doortoggleright,
|
||||
departureannounce,
|
||||
@@ -98,9 +100,6 @@ const int k_ProgramHelp = 48;
|
||||
pantographtogglerear,
|
||||
pantographlowerall,
|
||||
heatingtoggle,
|
||||
/*
|
||||
// const int k_FreeFlyMode= 59;
|
||||
*/
|
||||
lightspresetactivatenext,
|
||||
lightspresetactivateprevious,
|
||||
headlighttoggleleft,
|
||||
@@ -113,16 +112,14 @@ const int k_ProgramHelp = 48;
|
||||
headlighttogglerearupper,
|
||||
redmarkertogglerearleft,
|
||||
redmarkertogglerearright,
|
||||
redmarkerstoggle,
|
||||
endsignalstoggle,
|
||||
headlightsdimtoggle,
|
||||
motorconnectorsopen,
|
||||
motordisconnect,
|
||||
interiorlighttoggle,
|
||||
interiorlightdimtoggle,
|
||||
instrumentlighttoggle,
|
||||
/*
|
||||
const int k_EndSign = 70;
|
||||
const int k_Active = 71;
|
||||
*/
|
||||
generictoggle0,
|
||||
generictoggle1,
|
||||
generictoggle2,
|
||||
@@ -134,9 +131,7 @@ const int k_Active = 71;
|
||||
generictoggle8,
|
||||
generictoggle9,
|
||||
batterytoggle,
|
||||
/*
|
||||
const int k_WalkMode = 73;
|
||||
*/
|
||||
|
||||
none = -1
|
||||
};
|
||||
|
||||
@@ -164,7 +159,7 @@ enum class command_mode {
|
||||
struct command_description {
|
||||
std::string name;
|
||||
command_target target;
|
||||
command_mode mode;
|
||||
command_mode mode = command_mode::oneoff;
|
||||
};
|
||||
|
||||
struct command_data {
|
||||
|
||||
@@ -214,7 +214,7 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g
|
||||
double const movex = static_cast<double>( Leftstick.x );
|
||||
double const movez = static_cast<double>( Leftstick.y );
|
||||
m_relay.post(
|
||||
user_command::movevector,
|
||||
user_command::movehorizontal,
|
||||
reinterpret_cast<std::uint64_t const &>( movex ),
|
||||
reinterpret_cast<std::uint64_t const &>( movez ),
|
||||
GLFW_PRESS,
|
||||
@@ -231,42 +231,6 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g
|
||||
m_triggers = Triggers;
|
||||
}
|
||||
|
||||
void
|
||||
gamepad_input::process_axis( float const Value, float const Previousvalue, float const Multiplier, user_command Command, std::uint16_t const Recipient ) {
|
||||
|
||||
process_axis( Value, Previousvalue, Multiplier, Command, Command, Recipient );
|
||||
}
|
||||
|
||||
void
|
||||
gamepad_input::process_axis( float const Value, float const Previousvalue, float const Multiplier, user_command Command1, user_command Command2, std::uint16_t const Recipient ) {
|
||||
|
||||
user_command command{ Command1 };
|
||||
if( Value * Multiplier > 0.9 ) {
|
||||
command = Command2;
|
||||
}
|
||||
|
||||
if( Value * Multiplier > 0.0f ) {
|
||||
|
||||
m_relay.post(
|
||||
command,
|
||||
0, 0,
|
||||
GLFW_PRESS,
|
||||
Recipient
|
||||
);
|
||||
}
|
||||
else {
|
||||
// if we had movement before but not now, report this as 'button' release
|
||||
if( Previousvalue != 0.0f ) {
|
||||
m_relay.post(
|
||||
command, // doesn't matter which movement 'mode' we report
|
||||
0, 0,
|
||||
GLFW_RELEASE,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gamepad_input::process_mode( float const Value, std::uint16_t const Recipient ) {
|
||||
|
||||
|
||||
@@ -65,8 +65,6 @@ private:
|
||||
// methods
|
||||
void on_button( gamepad_button const Button, int const Action );
|
||||
void process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, glm::vec2 const &Triggers );
|
||||
void process_axis( float const Value, float const Previousvalue, float const Multiplier, user_command Command, std::uint16_t const Recipient );
|
||||
void process_axis( float const Value, float const Previousvalue, float const Multiplier, user_command Command1, user_command Command2, /*user_command Command3,*/ std::uint16_t const Recipient );
|
||||
void process_mode( float const Value, std::uint16_t const Recipient );
|
||||
|
||||
// members
|
||||
|
||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "stdafx.h"
|
||||
#include "keyboardinput.h"
|
||||
#include "Logs.h"
|
||||
#include "Globals.h"
|
||||
#include "parser.h"
|
||||
#include "World.h"
|
||||
|
||||
@@ -30,6 +31,7 @@ keyboard_input::recall_bindings() {
|
||||
std::unordered_map<std::string, int> nametokeymap = {
|
||||
{ "0", GLFW_KEY_0 }, { "1", GLFW_KEY_1 }, { "2", GLFW_KEY_2 }, { "3", GLFW_KEY_3 }, { "4", GLFW_KEY_4 },
|
||||
{ "5", GLFW_KEY_5 }, { "6", GLFW_KEY_6 }, { "7", GLFW_KEY_7 }, { "8", GLFW_KEY_8 }, { "9", GLFW_KEY_9 },
|
||||
{ "-", GLFW_KEY_MINUS }, { "=", GLFW_KEY_EQUAL },
|
||||
{ "a", GLFW_KEY_A }, { "b", GLFW_KEY_B }, { "c", GLFW_KEY_C }, { "d", GLFW_KEY_D }, { "e", GLFW_KEY_E },
|
||||
{ "f", GLFW_KEY_F }, { "g", GLFW_KEY_G }, { "h", GLFW_KEY_H }, { "i", GLFW_KEY_I }, { "j", GLFW_KEY_J },
|
||||
{ "k", GLFW_KEY_K }, { "l", GLFW_KEY_L }, { "m", GLFW_KEY_M }, { "n", GLFW_KEY_N }, { "o", GLFW_KEY_O },
|
||||
@@ -40,6 +42,7 @@ keyboard_input::recall_bindings() {
|
||||
{ ";", GLFW_KEY_SEMICOLON }, { "'", GLFW_KEY_APOSTROPHE }, { "enter", GLFW_KEY_ENTER },
|
||||
{ ",", GLFW_KEY_COMMA }, { ".", GLFW_KEY_PERIOD }, { "/", GLFW_KEY_SLASH },
|
||||
{ "space", GLFW_KEY_SPACE },
|
||||
{ "insert", GLFW_KEY_INSERT },{ "delete", GLFW_KEY_DELETE }, { "home", GLFW_KEY_HOME }, { "end", GLFW_KEY_END },
|
||||
// numpad block
|
||||
{ "num_/", GLFW_KEY_KP_DIVIDE }, { "num_*", GLFW_KEY_KP_MULTIPLY }, { "num_-", GLFW_KEY_KP_SUBTRACT },
|
||||
{ "num_7", GLFW_KEY_KP_7 }, { "num_8", GLFW_KEY_KP_8 }, { "num_9", GLFW_KEY_KP_9 }, { "num_+", GLFW_KEY_KP_ADD },
|
||||
@@ -131,16 +134,16 @@ keyboard_input::key( int const Key, int const Action ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( true == update_movement( Key, Action ) ) {
|
||||
// if the received key was one of movement keys, it's been handled and we don't need to bother further
|
||||
return true;
|
||||
}
|
||||
|
||||
// store key state
|
||||
if( Key != -1 ) {
|
||||
m_keys[ Key ] = Action;
|
||||
}
|
||||
|
||||
if( true == is_movement_key( Key ) ) {
|
||||
// if the received key was one of movement keys, it's been handled and we don't need to bother further
|
||||
return true;
|
||||
}
|
||||
|
||||
// include active modifiers for currently pressed key, except if the key is a modifier itself
|
||||
auto const key =
|
||||
Key
|
||||
@@ -164,6 +167,10 @@ void
|
||||
keyboard_input::default_bindings() {
|
||||
|
||||
m_commands = {
|
||||
// aidriverenable
|
||||
{ GLFW_KEY_Q | keymodifier::shift },
|
||||
// aidriverdisable
|
||||
{ GLFW_KEY_Q },
|
||||
// mastercontrollerincrease
|
||||
{ GLFW_KEY_KP_ADD },
|
||||
// mastercontrollerincreasefast
|
||||
@@ -206,17 +213,27 @@ keyboard_input::default_bindings() {
|
||||
{ GLFW_KEY_KP_5 },
|
||||
// trainbrakefullservice
|
||||
{ GLFW_KEY_KP_2 },
|
||||
// trainbrakehandleoff
|
||||
{ GLFW_KEY_KP_5 | keymodifier::control },
|
||||
// trainbrakeemergency
|
||||
{ GLFW_KEY_KP_0 },
|
||||
// trainbrakebasepressureincrease
|
||||
{ GLFW_KEY_KP_3 | keymodifier::control },
|
||||
// trainbrakebasepressuredecrease
|
||||
{ GLFW_KEY_KP_9 | keymodifier::control },
|
||||
// trainbrakebasepressurereset
|
||||
{ GLFW_KEY_KP_6 | keymodifier::control },
|
||||
// trainbrakeoperationtoggle
|
||||
{ GLFW_KEY_KP_4 | keymodifier::control },
|
||||
// manualbrakeincrease
|
||||
{ GLFW_KEY_KP_1 | keymodifier::control },
|
||||
// manualbrakedecrease
|
||||
{ GLFW_KEY_KP_7 | keymodifier::control },
|
||||
// alarm chain toggle
|
||||
{ GLFW_KEY_B | keymodifier::shift | keymodifier::control },
|
||||
// wheelspinbrakeactivate,
|
||||
// wheelspinbrakeactivate
|
||||
{ GLFW_KEY_KP_ENTER },
|
||||
// sandboxactivate,
|
||||
// sandboxactivate
|
||||
{ GLFW_KEY_S },
|
||||
// reverserincrease
|
||||
{ GLFW_KEY_D },
|
||||
@@ -246,6 +263,10 @@ keyboard_input::default_bindings() {
|
||||
{ GLFW_KEY_B | keymodifier::shift },
|
||||
// brakeactingspeeddecrease
|
||||
{ GLFW_KEY_B },
|
||||
// brakeloadcompensationincrease
|
||||
{ GLFW_KEY_H | keymodifier::shift | keymodifier::control },
|
||||
// brakeloadcompensationdecrease
|
||||
{ GLFW_KEY_H | keymodifier::control },
|
||||
// mubrakingindicatortoggle
|
||||
{ GLFW_KEY_L | keymodifier::shift },
|
||||
// alerteracknowledge
|
||||
@@ -256,11 +277,25 @@ keyboard_input::default_bindings() {
|
||||
{ GLFW_KEY_A | keymodifier::shift },
|
||||
// radiotoggle
|
||||
{ GLFW_KEY_R | keymodifier::control },
|
||||
// radiochannelincrease
|
||||
{ GLFW_KEY_R | keymodifier::shift },
|
||||
// radiochanneldecrease
|
||||
{ GLFW_KEY_R },
|
||||
// radiostoptest
|
||||
{ GLFW_KEY_R | keymodifier::shift | keymodifier::control },
|
||||
// cabchangeforward
|
||||
{ GLFW_KEY_HOME },
|
||||
// cabchangebackward
|
||||
{ GLFW_KEY_END },
|
||||
// viewturn
|
||||
{ -1 },
|
||||
// movevector
|
||||
// movehorizontal
|
||||
{ -1 },
|
||||
// movehorizontalfast
|
||||
{ -1 },
|
||||
// movevertical
|
||||
{ -1 },
|
||||
// moveverticalfast
|
||||
{ -1 },
|
||||
// moveleft
|
||||
{ GLFW_KEY_LEFT },
|
||||
@@ -274,23 +309,11 @@ keyboard_input::default_bindings() {
|
||||
{ GLFW_KEY_PAGE_UP },
|
||||
// movedown
|
||||
{ GLFW_KEY_PAGE_DOWN },
|
||||
// moveleftfast
|
||||
{ -1 },
|
||||
// moverightfast
|
||||
{ -1 },
|
||||
// moveforwardfast
|
||||
{ -1 },
|
||||
// movebackfast
|
||||
{ -1 },
|
||||
// moveupfast
|
||||
{ -1 },
|
||||
// movedownfast
|
||||
{ -1 },
|
||||
// carcouplingincrease
|
||||
{ GLFW_KEY_INSERT },
|
||||
// carcouplingdisconnect
|
||||
{ GLFW_KEY_DELETE },
|
||||
/*
|
||||
const int k_CabForward = 42;
|
||||
const int k_CabBackward = 43;
|
||||
const int k_Couple = 44;
|
||||
const int k_DeCouple = 45;
|
||||
const int k_ProgramQuit = 46;
|
||||
// const int k_ProgramPause= 47;
|
||||
const int k_ProgramHelp = 48;
|
||||
@@ -342,12 +365,16 @@ const int k_ProgramHelp = 48;
|
||||
{ GLFW_KEY_Y | keymodifier::control | keymodifier::shift },
|
||||
// redmarkertogglerearright
|
||||
{ GLFW_KEY_I | keymodifier::control | keymodifier::shift },
|
||||
// redmarkerstoggle
|
||||
{ GLFW_KEY_E | keymodifier::shift },
|
||||
// endsignalstoggle
|
||||
{ GLFW_KEY_E },
|
||||
// headlightsdimtoggle
|
||||
{ GLFW_KEY_L | keymodifier::control },
|
||||
// motorconnectorsopen
|
||||
{ GLFW_KEY_L },
|
||||
// motordisconnect
|
||||
{ GLFW_KEY_E | keymodifier::shift },
|
||||
{ GLFW_KEY_E | keymodifier::control },
|
||||
// interiorlighttoggle
|
||||
{ GLFW_KEY_APOSTROPHE },
|
||||
// interiorlightdimtoggle
|
||||
@@ -355,11 +382,6 @@ const int k_ProgramHelp = 48;
|
||||
// instrumentlighttoggle
|
||||
{ GLFW_KEY_SEMICOLON },
|
||||
/*
|
||||
const int k_Univ1 = 66;
|
||||
const int k_Univ2 = 67;
|
||||
const int k_Univ3 = 68;
|
||||
const int k_Univ4 = 69;
|
||||
const int k_EndSign = 70;
|
||||
const int k_Active = 71;
|
||||
*/
|
||||
// "generictoggle0"
|
||||
@@ -408,8 +430,7 @@ keyboard_input::bind() {
|
||||
}
|
||||
++commandcode;
|
||||
}
|
||||
|
||||
// cache movement key bindings, so we can test them faster in the input loop
|
||||
// cache movement key bindings
|
||||
m_bindingscache.forward = m_commands[ static_cast<std::size_t>( user_command::moveforward ) ].binding;
|
||||
m_bindingscache.back = m_commands[ static_cast<std::size_t>( user_command::moveback ) ].binding;
|
||||
m_bindingscache.left = m_commands[ static_cast<std::size_t>( user_command::moveleft ) ].binding;
|
||||
@@ -418,14 +439,10 @@ keyboard_input::bind() {
|
||||
m_bindingscache.down = m_commands[ static_cast<std::size_t>( user_command::movedown ) ].binding;
|
||||
}
|
||||
|
||||
// NOTE: ugliest code ever, gg
|
||||
bool
|
||||
keyboard_input::update_movement( int const Key, int const Action ) {
|
||||
keyboard_input::is_movement_key( int const Key ) const {
|
||||
|
||||
bool shift =
|
||||
( ( Key == GLFW_KEY_LEFT_SHIFT )
|
||||
|| ( Key == GLFW_KEY_RIGHT_SHIFT ) );
|
||||
bool movementkey =
|
||||
bool const ismovementkey =
|
||||
( ( Key == m_bindingscache.forward )
|
||||
|| ( Key == m_bindingscache.back )
|
||||
|| ( Key == m_bindingscache.left )
|
||||
@@ -433,93 +450,61 @@ keyboard_input::update_movement( int const Key, int const Action ) {
|
||||
|| ( Key == m_bindingscache.up )
|
||||
|| ( Key == m_bindingscache.down ) );
|
||||
|
||||
if( false == ( shift || movementkey ) ) { return false; }
|
||||
return ismovementkey;
|
||||
}
|
||||
|
||||
if( false == shift ) {
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
if( Key == m_bindingscache.forward ) {
|
||||
m_keys[ Key ] = Action;
|
||||
m_relay.post(
|
||||
( m_shift ?
|
||||
user_command::moveforwardfast :
|
||||
user_command::moveforward ),
|
||||
0, 0,
|
||||
m_keys[ m_bindingscache.forward ],
|
||||
0 );
|
||||
return true;
|
||||
}
|
||||
else if( Key == m_bindingscache.back ) {
|
||||
m_keys[ Key ] = Action;
|
||||
m_relay.post(
|
||||
( m_shift ?
|
||||
user_command::movebackfast :
|
||||
user_command::moveback ),
|
||||
0, 0,
|
||||
m_keys[ m_bindingscache.back ],
|
||||
0 );
|
||||
return true;
|
||||
}
|
||||
else if( Key == m_bindingscache.left ) {
|
||||
m_keys[ Key ] = Action;
|
||||
m_relay.post(
|
||||
( m_shift ?
|
||||
user_command::moveleftfast :
|
||||
user_command::moveleft ),
|
||||
0, 0,
|
||||
m_keys[ m_bindingscache.left ],
|
||||
0 );
|
||||
return true;
|
||||
}
|
||||
else if( Key == m_bindingscache.right ) {
|
||||
m_keys[ Key ] = Action;
|
||||
m_relay.post(
|
||||
( m_shift ?
|
||||
user_command::moverightfast :
|
||||
user_command::moveright ),
|
||||
0, 0,
|
||||
m_keys[ m_bindingscache.right ],
|
||||
0 );
|
||||
return true;
|
||||
}
|
||||
else if( Key == m_bindingscache.up ) {
|
||||
m_keys[ Key ] = Action;
|
||||
m_relay.post(
|
||||
( m_shift ?
|
||||
user_command::moveupfast :
|
||||
user_command::moveup ),
|
||||
0, 0,
|
||||
m_keys[ m_bindingscache.up ],
|
||||
0 );
|
||||
return true;
|
||||
}
|
||||
else if( Key == m_bindingscache.down ) {
|
||||
m_keys[ Key ] = Action;
|
||||
m_relay.post(
|
||||
( m_shift ?
|
||||
user_command::movedownfast :
|
||||
user_command::movedown ),
|
||||
0, 0,
|
||||
m_keys[ m_bindingscache.down ],
|
||||
0 );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if it's not the movement keys but one of shift keys, we might potentially need to update movement state
|
||||
if( m_keys[ Key ] == Action ) {
|
||||
// but not if it's just repeat
|
||||
return false;
|
||||
}
|
||||
// bit of recursion voodoo here, we fake relevant key presses so we don't have to duplicate the code from above
|
||||
if( m_keys[ m_bindingscache.forward ] != GLFW_RELEASE ) { update_movement( m_bindingscache.forward, m_keys[ m_bindingscache.forward ] ); }
|
||||
if( m_keys[ m_bindingscache.back ] != GLFW_RELEASE ) { update_movement( m_bindingscache.back, m_keys[ m_bindingscache.back ] ); }
|
||||
if( m_keys[ m_bindingscache.left ] != GLFW_RELEASE ) { update_movement( m_bindingscache.left, m_keys[ m_bindingscache.left ] ); }
|
||||
if( m_keys[ m_bindingscache.right ] != GLFW_RELEASE ) { update_movement( m_bindingscache.right, m_keys[ m_bindingscache.right ] ); }
|
||||
if( m_keys[ m_bindingscache.up ] != GLFW_RELEASE ) { update_movement( m_bindingscache.up, m_keys[ m_bindingscache.up ] ); }
|
||||
if( m_keys[ m_bindingscache.down ] != GLFW_RELEASE ) { update_movement( m_bindingscache.down, m_keys[ m_bindingscache.down ] ); }
|
||||
void
|
||||
keyboard_input::poll() {
|
||||
|
||||
glm::vec2 const movementhorizontal {
|
||||
// x-axis
|
||||
( Global::shiftState ? 1.f : 0.5f ) *
|
||||
( m_keys[ m_bindingscache.left ] != GLFW_RELEASE ? -1.f :
|
||||
m_keys[ m_bindingscache.right ] != GLFW_RELEASE ? 1.f :
|
||||
0.f ),
|
||||
// z-axis
|
||||
( Global::shiftState ? 1.f : 0.5f ) *
|
||||
( m_keys[ m_bindingscache.forward ] != GLFW_RELEASE ? 1.f :
|
||||
m_keys[ m_bindingscache.back ] != GLFW_RELEASE ? -1.f :
|
||||
0.f ) };
|
||||
|
||||
if( ( movementhorizontal.x != 0.f || movementhorizontal.y != 0.f )
|
||||
|| ( m_movementhorizontal.x != 0.f || m_movementhorizontal.y != 0.f ) ) {
|
||||
double const movexparam = static_cast<double>( movementhorizontal.x );
|
||||
double const movezparam = static_cast<double>( movementhorizontal.y );
|
||||
m_relay.post(
|
||||
( true == Global::ctrlState ?
|
||||
user_command::movehorizontalfast :
|
||||
user_command::movehorizontal ),
|
||||
reinterpret_cast<std::uint64_t const &>( movexparam ),
|
||||
reinterpret_cast<std::uint64_t const &>( movezparam ),
|
||||
GLFW_PRESS,
|
||||
0 );
|
||||
}
|
||||
|
||||
return false;
|
||||
m_movementhorizontal = movementhorizontal;
|
||||
|
||||
float const movementvertical {
|
||||
// y-axis
|
||||
( Global::shiftState ? 1.f : 0.5f ) *
|
||||
( m_keys[ m_bindingscache.up ] != GLFW_RELEASE ? 1.f :
|
||||
m_keys[ m_bindingscache.down ] != GLFW_RELEASE ? -1.f :
|
||||
0.f ) };
|
||||
|
||||
if( ( movementvertical != 0.f )
|
||||
|| ( m_movementvertical != 0.f ) ) {
|
||||
double const moveyparam = static_cast<double>( movementvertical );
|
||||
m_relay.post(
|
||||
( true == Global::ctrlState ?
|
||||
user_command::moveverticalfast :
|
||||
user_command::movevertical ),
|
||||
reinterpret_cast<std::uint64_t const &>( moveyparam ),
|
||||
0,
|
||||
GLFW_PRESS,
|
||||
0 );
|
||||
}
|
||||
|
||||
m_movementvertical = movementvertical;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
bool
|
||||
key( int const Key, int const Action );
|
||||
void
|
||||
poll() {}
|
||||
poll();
|
||||
|
||||
private:
|
||||
// types
|
||||
@@ -61,7 +61,7 @@ private:
|
||||
void
|
||||
bind();
|
||||
bool
|
||||
update_movement( int const Key, int const Action );
|
||||
is_movement_key( int const Key ) const;
|
||||
|
||||
// members
|
||||
commandsetup_sequence m_commands;
|
||||
@@ -70,6 +70,8 @@ private:
|
||||
bool m_shift{ false };
|
||||
bool m_ctrl{ false };
|
||||
bindings_cache m_bindingscache;
|
||||
glm::vec2 m_movementhorizontal;
|
||||
float m_movementvertical;
|
||||
std::array<char, GLFW_KEY_LAST + 1> m_keys;
|
||||
};
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ WyslijNamiary(TDynamicObject const *Vehicle)
|
||||
r.fPar[7] = 0; // prędkość ruchu Z
|
||||
r.fPar[8] = Vehicle->MoverParameters->AccS; // przyspieszenie X
|
||||
r.fPar[9] = Vehicle->MoverParameters->AccN; // przyspieszenie Y //na razie nie
|
||||
r.fPar[10] = Vehicle->MoverParameters->AccV; // przyspieszenie Z
|
||||
r.fPar[10] = Vehicle->MoverParameters->AccVert; // przyspieszenie Z
|
||||
r.fPar[11] = Vehicle->MoverParameters->DistCounter; // przejechana odległość w km
|
||||
r.fPar[12] = Vehicle->MoverParameters->PipePress; // ciśnienie w PG
|
||||
r.fPar[13] = Vehicle->MoverParameters->ScndPipePress; // ciśnienie w PZ
|
||||
|
||||
@@ -58,11 +58,9 @@ void motiontelemetry::update()
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
float speed = std::abs(t->Occupied()->V);
|
||||
float forward = t->Occupied()->AccS;
|
||||
float forward = t->Occupied()->AccSVBased;
|
||||
float lateral = t->Occupied()->AccN;
|
||||
float vertical = t->Occupied()->AccV;
|
||||
float
|
||||
float vertical = t->Occupied()->AccVert;
|
||||
|
||||
WriteLog("forward: " + std::to_string(forward) + ", lateral: " + std::to_string(lateral) + ", z: " + std::to_string(vertical));
|
||||
WriteLog("forward: " + std::to_string(forward) + ", lateral: " + std::to_string(lateral) + ", vertical: " + std::to_string(vertical));
|
||||
}
|
||||
16
scene.cpp
16
scene.cpp
@@ -121,6 +121,11 @@ basic_cell::update_events() {
|
||||
// legacy method, updates sounds and polls event launchers within radius around specified point
|
||||
void
|
||||
basic_cell::update_sounds() {
|
||||
|
||||
auto const deltatime = Timer::GetDeltaRenderTime();
|
||||
for( auto *sound : m_sounds ) {
|
||||
sound->play_event();
|
||||
}
|
||||
// TBD, TODO: move to sound renderer
|
||||
for( auto *path : m_paths ) {
|
||||
// dźwięki pojazdów, również niewidocznych
|
||||
@@ -1162,6 +1167,17 @@ basic_region::insert_instance( TAnimModel *Instance, scratch_data &Scratchpad )
|
||||
// inserts provided sound in the region
|
||||
void
|
||||
basic_region::insert_sound( sound_source *Sound, scratch_data &Scratchpad ) {
|
||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||
auto location = Sound->location();
|
||||
|
||||
if( point_inside( location ) ) {
|
||||
// NOTE: nodes placed outside of region boundaries are discarded
|
||||
section( location ).insert( Sound );
|
||||
}
|
||||
else {
|
||||
// tracks are guaranteed to hava a name so we can skip the check
|
||||
ErrorLog( "Bad scenario: sound node \"" + Sound->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||
}
|
||||
}
|
||||
|
||||
// inserts provided event launcher in the region
|
||||
|
||||
41
sound.cpp
41
sound.cpp
@@ -57,14 +57,30 @@ sound_source::deserialize( cParser &Input, sound_type const Legacytype, int cons
|
||||
// on the far end the crossfade section extends to the threshold point of the next chunk...
|
||||
for( std::size_t idx = 0; idx < m_soundchunks.size() - 1; ++idx ) {
|
||||
m_soundchunks[ idx ].second.fadeout = m_soundchunks[ idx + 1 ].second.threshold;
|
||||
/*
|
||||
m_soundchunks[ idx ].second.fadeout =
|
||||
interpolate<float>(
|
||||
m_soundchunks[ idx ].second.threshold,
|
||||
m_soundchunks[ idx + 1 ].second.threshold,
|
||||
m_crossfaderange * 0.01f );
|
||||
*/
|
||||
}
|
||||
// ...and on the other end from the threshold point back into the range of previous chunk
|
||||
m_soundchunks.front().second.fadein = std::max( 0, m_soundchunks.front().second.threshold );
|
||||
// m_soundchunks.front().second.fadein = m_soundchunks.front().second.threshold;
|
||||
for( std::size_t idx = 1; idx < m_soundchunks.size(); ++idx ) {
|
||||
auto const previouschunkwidth { m_soundchunks[ idx ].second.threshold - m_soundchunks[ idx - 1 ].second.threshold };
|
||||
m_soundchunks[ idx ].second.fadein = m_soundchunks[ idx ].second.threshold - 0.01f * m_crossfaderange * previouschunkwidth;
|
||||
/*
|
||||
m_soundchunks[ idx ].second.fadein =
|
||||
interpolate<float>(
|
||||
m_soundchunks[ idx ].second.threshold,
|
||||
m_soundchunks[ idx - 1 ].second.threshold,
|
||||
m_crossfaderange * 0.01f );
|
||||
*/
|
||||
}
|
||||
m_soundchunks.back().second.fadeout = std::max( 100, m_soundchunks.back().second.threshold );
|
||||
// m_soundchunks.back().second.fadeout = m_soundchunks.back().second.threshold;
|
||||
// test if the chunk table contains any actual samples while at it
|
||||
for( auto &soundchunk : m_soundchunks ) {
|
||||
if( soundchunk.first.buffer != null_handle ) {
|
||||
@@ -290,6 +306,10 @@ sound_source::play( int const Flags ) {
|
||||
// if the sound is disabled altogether or nothing can be emitted from this source, no point wasting time
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: we cache the flags early, even if the sound is out of range, to mark activated event sounds
|
||||
m_flags = Flags;
|
||||
|
||||
if( m_range > 0 ) {
|
||||
auto const cutoffrange { m_range * 5 };
|
||||
if( glm::length2( location() - glm::dvec3 { Global::pCameraPosition } ) > std::min( 2750.f * 2750.f, cutoffrange * cutoffrange ) ) {
|
||||
@@ -305,8 +325,6 @@ sound_source::play( int const Flags ) {
|
||||
m_pitchvariation = 0.01f * static_cast<float>( Random( 97.5, 102.5 ) );
|
||||
}
|
||||
|
||||
m_flags = Flags;
|
||||
|
||||
if( sound( sound_id::main ).buffer != null_handle ) {
|
||||
// basic variant: single main sound, with optional bookends
|
||||
play_basic();
|
||||
@@ -352,7 +370,7 @@ sound_source::play_combined() {
|
||||
// a chunk covers range from fade in point, where it starts rising in volume over crossfade distance,
|
||||
// lasts until fadeout - crossfade distance point, past which it grows quiet until fade out point where it ends
|
||||
if( soundpoint < soundchunk.second.fadein ) { break; }
|
||||
if( soundpoint > soundchunk.second.fadeout ) { continue; }
|
||||
if( soundpoint >= soundchunk.second.fadeout ) { continue; }
|
||||
|
||||
if( ( soundchunk.first.playing > 0 )
|
||||
|| ( soundchunk.first.buffer == null_handle ) ) {
|
||||
@@ -402,12 +420,26 @@ sound_source::compute_combined_point() const {
|
||||
) * 100.f;
|
||||
}
|
||||
|
||||
// maintains playback of sounds started by event
|
||||
void
|
||||
sound_source::play_event() {
|
||||
|
||||
if( true == TestFlag( m_flags, ( sound_flags::event | sound_flags::looping ) ) ) {
|
||||
// events can potentially start scenery sounds out of the sound's audible range
|
||||
// such sounds are stopped on renderer side, but unless stopped by the simulation keep their activation flags
|
||||
// we use this to discern event-started sounds which should be re-activated if the listener gets close enough
|
||||
play( m_flags );
|
||||
}
|
||||
}
|
||||
|
||||
// stops currently active play commands controlled by this emitter
|
||||
void
|
||||
sound_source::stop( bool const Skipend ) {
|
||||
|
||||
// if the source was stopped on simulation side, we should play the opening bookend next time it's activated
|
||||
m_playbeginning = true;
|
||||
// clear the event flags to discern between manual stop and out-of-range/sound-end stop
|
||||
m_flags = 0;
|
||||
|
||||
if( false == is_playing() ) { return; }
|
||||
|
||||
@@ -549,7 +581,7 @@ sound_source::update_combined( audio::openal_source &Source ) {
|
||||
auto const soundpoint { compute_combined_point() };
|
||||
auto const &soundchunk { m_soundchunks[ soundhandle ^ sound_id::chunk ] };
|
||||
if( ( soundpoint < soundchunk.second.fadein )
|
||||
|| ( soundpoint > soundchunk.second.fadeout ) ) {
|
||||
|| ( soundpoint >= soundchunk.second.fadeout ) ) {
|
||||
Source.stop();
|
||||
update_counter( soundhandle, -1 );
|
||||
return;
|
||||
@@ -666,7 +698,6 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
||||
m_properties.pitch = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
// if there's no crossfade sections, our work is done
|
||||
if( m_crossfaderange == 0 ) { return; }
|
||||
|
||||
|
||||
12
sound.h
12
sound.h
@@ -30,7 +30,8 @@ enum sound_parameters {
|
||||
|
||||
enum sound_flags {
|
||||
looping = 0x1, // the main sample will be looping; implied for multi-sounds
|
||||
exclusive = 0x2 // the source won't dispatch more than one active instance of the sound; implied for multi-sounds
|
||||
exclusive = 0x2, // the source won't dispatch more than one active instance of the sound; implied for multi-sounds
|
||||
event = 0x80 // sound was activated by an event; we should keep note of the activation state for the update() calls it may receive
|
||||
};
|
||||
|
||||
enum class sound_placement {
|
||||
@@ -64,6 +65,9 @@ public:
|
||||
// issues contextual play commands for the audio renderer
|
||||
void
|
||||
play( int const Flags = 0 );
|
||||
// maintains playback of sounds started by event
|
||||
void
|
||||
play_event();
|
||||
// stops currently active play commands controlled by this emitter
|
||||
void
|
||||
stop( bool const Skipend = false );
|
||||
@@ -194,15 +198,15 @@ private:
|
||||
sound_placement m_placement;
|
||||
float m_range { 50.f }; // audible range of the emitted sounds
|
||||
std::string m_name;
|
||||
int m_flags { 0 }; // requested playback parameters
|
||||
int m_flags {}; // requested playback parameters
|
||||
sound_properties m_properties; // current properties of the emitted sounds
|
||||
float m_pitchvariation { 0.f }; // emitter-specific shift in base pitch
|
||||
float m_pitchvariation {}; // emitter-specific shift in base pitch
|
||||
bool m_stop { false }; // indicates active sample instances should be terminated
|
||||
bool m_playbeginning { true }; // indicates started sounds should be preceeded by opening bookend if there's one
|
||||
std::array<sound_data, 3> m_sounds { {} }; // basic sounds emitted by the source, main and optional bookends
|
||||
std::vector<soundchunk_pair> m_soundchunks; // table of samples activated when associated variable is within certain range
|
||||
bool m_soundchunksempty { true }; // helper, cached check whether sample table is linked with any actual samples
|
||||
int m_crossfaderange {}; // range of transition from one chunk to another
|
||||
int m_crossfaderange {}; // range of transition from one chunk to another
|
||||
};
|
||||
|
||||
// owner setter/getter
|
||||
|
||||
Reference in New Issue
Block a user