mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
Reorganize source files into logical subdirectories
Co-authored-by: Hirek193 <23196899+Hirek193@users.noreply.github.com>
This commit is contained in:
91
vehicle/AirCoupler.cpp
Normal file
91
vehicle/AirCoupler.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "AirCoupler.h"
|
||||
|
||||
#include "Model3d.h"
|
||||
#include "parser.h"
|
||||
|
||||
AirCoupler::AirCoupler()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
AirCoupler::~AirCoupler()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \return 1 when \(straight\) TModel3d \c only ModelOn exists
|
||||
* \return 2 when \(slanted\) TModel3d \c ModelxOn exists
|
||||
* \return 0 when neither of them exist
|
||||
*/
|
||||
int AirCoupler::GetStatus()
|
||||
{
|
||||
if (ModelxOn)
|
||||
return 2;
|
||||
if (ModelOn)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset pointers and variables.
|
||||
*/
|
||||
void AirCoupler::Clear()
|
||||
{
|
||||
ModelOn = NULL;
|
||||
ModelOff = NULL;
|
||||
ModelxOn = NULL;
|
||||
On = false;
|
||||
xOn = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for submodels in the model and updates pointers.
|
||||
*/
|
||||
void AirCoupler::Init(std::string const &asName, TModel3d *Model)
|
||||
{
|
||||
if (!Model)
|
||||
return;
|
||||
ModelOn = Model->GetFromName(asName + "_on"); // Straight connect.
|
||||
ModelOff = Model->GetFromName(asName + "_off"); // Not connected. Hung up.
|
||||
ModelxOn = Model->GetFromName(asName + "_xon"); // Slanted connect.
|
||||
}
|
||||
/**
|
||||
* Gets name of submodel \(from cParser \b *Parser\),
|
||||
* looks for it in the TModel3d \b *Model and update pointers.
|
||||
* If submodel is not found, reset pointers.
|
||||
*/
|
||||
void AirCoupler::Load(cParser *Parser, TModel3d *Model)
|
||||
{
|
||||
std::string name = Parser->getToken<std::string>();
|
||||
if(Model)
|
||||
{
|
||||
Init(name, Model);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelOn = NULL;
|
||||
ModelxOn = NULL;
|
||||
ModelOff = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Update submodels visibility.
|
||||
void AirCoupler::Update()
|
||||
{
|
||||
if (ModelOn)
|
||||
ModelOn->iVisible = On;
|
||||
if (ModelOff)
|
||||
ModelOff->iVisible = !(On || xOn);
|
||||
if (ModelxOn)
|
||||
ModelxOn->iVisible = xOn;
|
||||
}
|
||||
80
vehicle/AirCoupler.h
Normal file
80
vehicle/AirCoupler.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Classes.h"
|
||||
|
||||
class AirCoupler
|
||||
{
|
||||
private:
|
||||
TSubModel *ModelOn, *ModelOff, *ModelxOn;
|
||||
bool On;
|
||||
bool xOn;
|
||||
void Update();
|
||||
|
||||
public:
|
||||
AirCoupler();
|
||||
~AirCoupler();
|
||||
///Reset members.
|
||||
void Clear();
|
||||
///Looks for submodels.
|
||||
void Init(std::string const &asName, TModel3d *Model);
|
||||
///Loads info about coupler.
|
||||
void Load(cParser *Parser, TModel3d *Model);
|
||||
int GetStatus();
|
||||
inline void TurnOn() ///Turns on straight coupler.
|
||||
{
|
||||
On = true;
|
||||
xOn = false;
|
||||
Update();
|
||||
};
|
||||
inline void TurnOff() ///Turns on disconnected coupler.
|
||||
{
|
||||
On = false;
|
||||
xOn = false;
|
||||
Update();
|
||||
};
|
||||
inline void TurnxOn() ///Turns on slanted coupler.
|
||||
{
|
||||
On = false;
|
||||
xOn = true;
|
||||
Update();
|
||||
};
|
||||
|
||||
// if the xOn model is missing, activate plain On instead
|
||||
inline void TurnxOnWithOnAsFallback()
|
||||
{
|
||||
if (ModelxOn != nullptr) {
|
||||
On = false;
|
||||
xOn = true;
|
||||
Update();
|
||||
}
|
||||
else {
|
||||
TurnOn();
|
||||
}
|
||||
};
|
||||
// if the xOn model is missing, activate plain Off instead
|
||||
inline void TurnxOnWithOffAsFallback()
|
||||
{
|
||||
if (ModelxOn != nullptr) {
|
||||
On = false;
|
||||
xOn = true;
|
||||
Update();
|
||||
}
|
||||
else {
|
||||
TurnOff();
|
||||
}
|
||||
};
|
||||
inline bool Active() const
|
||||
{
|
||||
return ( ( ModelOn != nullptr ) || ( ModelxOn != nullptr ) );
|
||||
};
|
||||
};
|
||||
|
||||
166
vehicle/Button.cpp
Normal file
166
vehicle/Button.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Button.h"
|
||||
#include "parser.h"
|
||||
#include "Model3d.h"
|
||||
#include "DynObj.h"
|
||||
#include "Console.h"
|
||||
#include "Logs.h"
|
||||
#include "renderer.h"
|
||||
|
||||
void TButton::Clear(int i)
|
||||
{
|
||||
*this = TButton();
|
||||
if( i >= 0 ) {
|
||||
FeedbackBitSet( i );
|
||||
}
|
||||
Update(); // kasowanie bitu Feedback, o ile jakiś ustawiony
|
||||
};
|
||||
|
||||
bool TButton::Init( std::string const &asName, TModel3d const *pModel, bool bNewOn ) {
|
||||
|
||||
if( pModel == nullptr ) { return false; }
|
||||
|
||||
pModelOn = pModel->GetFromName( asName + "_on" );
|
||||
pModelOff = pModel->GetFromName( asName + "_off" );
|
||||
m_state = bNewOn;
|
||||
Update();
|
||||
|
||||
return( ( pModelOn != nullptr ) || ( pModelOff != nullptr ) );
|
||||
};
|
||||
|
||||
void TButton::Load( cParser &Parser, TDynamicObject const *Owner ) {
|
||||
|
||||
std::string submodelname;
|
||||
|
||||
Parser.getTokens();
|
||||
if( Parser.peek() != "{" ) {
|
||||
// old fixed size config
|
||||
Parser >> submodelname;
|
||||
}
|
||||
else {
|
||||
// new, block type config
|
||||
// TODO: rework the base part into yaml-compatible flow style mapping
|
||||
submodelname = Parser.getToken<std::string>( false );
|
||||
while( true == Load_mapping( Parser ) ) {
|
||||
; // all work done by while()
|
||||
}
|
||||
}
|
||||
|
||||
// bind defined sounds with the button owner
|
||||
m_soundfxincrease.owner( Owner );
|
||||
m_soundfxdecrease.owner( Owner );
|
||||
|
||||
std::array<TModel3d *, 3> sources { Owner->mdKabina, Owner->mdLowPolyInt, Owner->mdModel };
|
||||
for( auto const *source : sources ) {
|
||||
if( true == Init( submodelname, source, false ) ) {
|
||||
// got what we wanted, don't need to search further
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ( pModelOn == nullptr )
|
||||
&& ( pModelOff == nullptr ) ) {
|
||||
// if we failed to locate even one state submodel, cry
|
||||
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model(s) of \"" + Owner->name() + "\"", logtype::model );
|
||||
}
|
||||
|
||||
// pass submodel location to defined sounds
|
||||
auto const nulloffset { glm::vec3{} };
|
||||
auto const offset { model_offset() };
|
||||
if( m_soundfxincrease.offset() == nulloffset ) {
|
||||
m_soundfxincrease.offset( offset );
|
||||
}
|
||||
if( m_soundfxdecrease.offset() == nulloffset ) {
|
||||
m_soundfxdecrease.offset( offset );
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TButton::Load_mapping( cParser &Input ) {
|
||||
|
||||
// token can be a key or block end
|
||||
std::string const key { Input.getToken<std::string>( true, "\n\r\t ,;" ) };
|
||||
if( ( true == key.empty() ) || ( key == "}" ) ) { return false; }
|
||||
// if not block end then the key is followed by assigned value or sub-block
|
||||
if( key == "soundinc:" ) { m_soundfxincrease.deserialize( Input, sound_type::single ); }
|
||||
else if( key == "sounddec:" ) { m_soundfxdecrease.deserialize( Input, sound_type::single ); }
|
||||
|
||||
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
|
||||
}
|
||||
|
||||
// returns offset of submodel associated with the button from the model centre
|
||||
glm::vec3
|
||||
TButton::model_offset() const {
|
||||
|
||||
auto const
|
||||
submodel { (
|
||||
pModelOn ? pModelOn :
|
||||
pModelOff ? pModelOff :
|
||||
nullptr ) };
|
||||
|
||||
return (
|
||||
submodel != nullptr ?
|
||||
submodel->offset( std::numeric_limits<float>::max() ) :
|
||||
glm::vec3() );
|
||||
}
|
||||
|
||||
void
|
||||
TButton::Turn( bool const State ) {
|
||||
|
||||
if( State != m_state ) {
|
||||
|
||||
m_state = State;
|
||||
play();
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
void TButton::Update( bool const Power ) {
|
||||
// TODO: remove passing manually power state when LD is in place
|
||||
|
||||
auto const state { Power && ( bData ? *bData : m_state ) };
|
||||
|
||||
if( state != m_state ) {
|
||||
|
||||
m_state = state;
|
||||
play();
|
||||
}
|
||||
|
||||
if( pModelOn != nullptr ) { pModelOn->iVisible = m_state; }
|
||||
if( pModelOff != nullptr ) { pModelOff->iVisible = (!m_state); }
|
||||
|
||||
#ifdef _WIN32
|
||||
if (iFeedbackBit) {
|
||||
// jeżeli generuje informację zwrotną
|
||||
if (m_state) // zapalenie
|
||||
Console::BitsSet(iFeedbackBit);
|
||||
else
|
||||
Console::BitsClear(iFeedbackBit);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
void TButton::AssignBool(bool const *bValue) {
|
||||
|
||||
bData = bValue;
|
||||
}
|
||||
|
||||
void
|
||||
TButton::play() {
|
||||
if( m_state == true ) { m_soundfxincrease.play(); }
|
||||
else { m_soundfxdecrease.play(); }
|
||||
}
|
||||
|
||||
void
|
||||
TButton::gain(float new_volume) {
|
||||
m_soundfxincrease.gain(new_volume);
|
||||
m_soundfxdecrease.gain(new_volume);
|
||||
}
|
||||
62
vehicle/Button.h
Normal file
62
vehicle/Button.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Classes.h"
|
||||
#include "sound.h"
|
||||
|
||||
// animacja dwustanowa, włącza jeden z dwóch submodeli (jednego z nich może nie być)
|
||||
class TButton {
|
||||
|
||||
public:
|
||||
// methods
|
||||
TButton() = default;
|
||||
void Clear(int const i = -1);
|
||||
inline
|
||||
void FeedbackBitSet( int const i ) {
|
||||
iFeedbackBit = 1 << i; };
|
||||
void Turn( bool const State );
|
||||
inline
|
||||
bool GetValue() const {
|
||||
return m_state; }
|
||||
inline
|
||||
bool Active() {
|
||||
return ( ( pModelOn != nullptr )
|
||||
|| ( pModelOff != nullptr ) ); }
|
||||
void Update( bool const Power = true );
|
||||
bool Init( std::string const &asName, TModel3d const *pModel, bool bNewOn = false );
|
||||
void Load( cParser &Parser, TDynamicObject const *Owner );
|
||||
void AssignBool(bool const *bValue);
|
||||
// returns offset of submodel associated with the button from the model centre
|
||||
glm::vec3 model_offset() const;
|
||||
void gain(float new_volume);
|
||||
inline uint8_t b() { return m_state ? 1 : 0; };
|
||||
|
||||
private:
|
||||
// methods
|
||||
// imports member data pair from the config file
|
||||
bool
|
||||
Load_mapping( cParser &Input );
|
||||
// plays the sound associated with current state
|
||||
void
|
||||
play();
|
||||
|
||||
// members
|
||||
TSubModel
|
||||
*pModelOn { nullptr },
|
||||
*pModelOff { nullptr }; // submodel dla stanu załączonego i wyłączonego
|
||||
bool m_state { false };
|
||||
bool const *bData { nullptr };
|
||||
int iFeedbackBit { 0 }; // Ra: bit informacji zwrotnej, do wyprowadzenia na pulpit
|
||||
sound_source m_soundfxincrease { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // sound associated with increasing control's value
|
||||
sound_source m_soundfxdecrease { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // sound associated with decreasing control's value
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
234
vehicle/Camera.cpp
Normal file
234
vehicle/Camera.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Camera.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "utilities.h"
|
||||
#include "Console.h"
|
||||
#include "Timer.h"
|
||||
#include "Driver.h"
|
||||
#include "DynObj.h"
|
||||
#include "MOVER.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void TCamera::Init( Math3D::vector3 const &NPos, Math3D::vector3 const &NAngle/*, TCameraType const NType*/, TDynamicObject *Owner ) {
|
||||
|
||||
vUp = { 0, 1, 0 };
|
||||
Velocity = { 0, 0, 0 };
|
||||
Angle = NAngle;
|
||||
Pos = NPos;
|
||||
|
||||
m_owner = Owner;
|
||||
};
|
||||
|
||||
void TCamera::Reset() {
|
||||
|
||||
Angle = {};
|
||||
m_rotationoffsets = {};
|
||||
};
|
||||
|
||||
|
||||
void TCamera::OnCursorMove(double x, double y) {
|
||||
m_rotationoffsets.x += y;
|
||||
m_rotationoffsets.y += x;
|
||||
}
|
||||
|
||||
static double ComputeAxisSpeed(double param, double walkspeed, double maxspeed, double threshold) {
|
||||
double absval = std::abs(param);
|
||||
// 2/3rd of the stick range lerps walk speed, past that we lerp between max walk and run speed
|
||||
double walk = walkspeed * std::min(absval / threshold, 1.0);
|
||||
double run = (std::max(0.0, absval - threshold) / (1.0 - threshold)) * std::max(0.0, maxspeed - walkspeed);
|
||||
return (param >= 0.0 ? 1.0 : -1.0) * (walk + run);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TCamera::OnCommand( command_data const &Command ) {
|
||||
|
||||
auto const walkspeed { 1.0 };
|
||||
auto const runspeed { 10.0 };
|
||||
|
||||
// threshold position on stick between walk lerp and walk/run lerp
|
||||
auto const stickthreshold = 2.0 / 3.0;
|
||||
|
||||
bool iscameracommand { true };
|
||||
switch( Command.command ) {
|
||||
|
||||
case user_command::viewturn: {
|
||||
|
||||
OnCursorMove(
|
||||
Command.param1 * 0.005 * Global.fMouseXScale / Global.ZoomFactor,
|
||||
Command.param2 * 0.01 * Global.fMouseYScale / Global.ZoomFactor );
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::movehorizontal:
|
||||
case user_command::movehorizontalfast: {
|
||||
|
||||
auto const movespeed = (
|
||||
m_owner == nullptr ? runspeed : // free roam
|
||||
false == FreeFlyModeFlag ? walkspeed : // vehicle cab
|
||||
0.0 ); // vehicle external
|
||||
|
||||
// if( movespeed == 0.0 ) { break; } // enable to fix external cameras in place
|
||||
|
||||
auto const speedmultiplier = (
|
||||
( ( m_owner == nullptr ) && ( Command.command == user_command::movehorizontalfast ) ) ?
|
||||
30.0 :
|
||||
1.0 );
|
||||
|
||||
// left-right
|
||||
m_moverate.x = ComputeAxisSpeed(Command.param1, walkspeed, movespeed, stickthreshold) * speedmultiplier;
|
||||
// forward-back
|
||||
m_moverate.z = -ComputeAxisSpeed(Command.param2, walkspeed, movespeed, stickthreshold) * speedmultiplier;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case user_command::movevertical:
|
||||
case user_command::moveverticalfast: {
|
||||
|
||||
auto const movespeed = (
|
||||
m_owner == nullptr ? runspeed * 0.5 : // free roam
|
||||
false == FreeFlyModeFlag ? walkspeed : // vehicle cab
|
||||
0.0 ); // vehicle external
|
||||
|
||||
// if( movespeed == 0.0 ) { break; } // enable to fix external cameras in place
|
||||
|
||||
auto const speedmultiplier = (
|
||||
( ( m_owner == nullptr ) && ( Command.command == user_command::moveverticalfast ) ) ?
|
||||
10.0 :
|
||||
1.0 );
|
||||
// up-down
|
||||
m_moverate.y = ComputeAxisSpeed(Command.param1, walkspeed, movespeed, stickthreshold) * speedmultiplier;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
|
||||
iscameracommand = false;
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
|
||||
return iscameracommand;
|
||||
}
|
||||
|
||||
static void UpdateVelocityAxis(double& velocity, double moverate, double deltatime)
|
||||
{
|
||||
velocity = clamp(velocity + moverate * 10.0 * deltatime, -std::abs(moverate), std::abs(moverate));
|
||||
}
|
||||
|
||||
|
||||
void TCamera::Update()
|
||||
{
|
||||
// check for sent user commands
|
||||
// NOTE: this is a temporary arrangement, for the transition period from old command setup to the new one
|
||||
// ultimately we'll need to track position of camera/driver for all human entities present in the scenario
|
||||
command_data command;
|
||||
// NOTE: currently we're only storing commands for local entity and there's no id system in place,
|
||||
// so we're supplying 'default' entity id of 0
|
||||
while( simulation::Commands.pop( command, static_cast<std::size_t>( command_target::entity ) | 0 ) ) {
|
||||
|
||||
OnCommand( command );
|
||||
}
|
||||
|
||||
auto const deltatime { Timer::GetDeltaRenderTime() }; // czas bez pauzy
|
||||
|
||||
// update rotation
|
||||
auto const rotationfactor { std::min( 1.0, 20 * deltatime ) };
|
||||
|
||||
Angle.y -= m_rotationoffsets.y * rotationfactor;
|
||||
m_rotationoffsets.y *= ( 1.0 - rotationfactor );
|
||||
Angle.y = std::remainder(Angle.y, 2.0 * M_PI);
|
||||
|
||||
// Limit the camera pitch to +/- 90°.
|
||||
Angle.x = clamp(Angle.x - (m_rotationoffsets.x * rotationfactor), -M_PI_2, M_PI_2);
|
||||
m_rotationoffsets.x *= ( 1.0 - rotationfactor );
|
||||
|
||||
// update position
|
||||
if( ( m_owner == nullptr )
|
||||
|| ( false == Global.ctrlState )
|
||||
|| ( true == DebugCameraFlag ) ) {
|
||||
// ctrl is used for mirror view, so we ignore the controls when in vehicle if ctrl is pressed
|
||||
// McZapkie-170402: poruszanie i rozgladanie we free takie samo jak w follow
|
||||
UpdateVelocityAxis(Velocity.x, m_moverate.x, deltatime);
|
||||
UpdateVelocityAxis(Velocity.y, m_moverate.y, deltatime);
|
||||
UpdateVelocityAxis(Velocity.z, m_moverate.z, deltatime);
|
||||
}
|
||||
if( ( m_owner == nullptr )
|
||||
|| ( true == DebugCameraFlag ) ) {
|
||||
// free movement position update
|
||||
auto movement { Velocity };
|
||||
movement.RotateY( Angle.y );
|
||||
Pos += movement * 5.0 * deltatime;
|
||||
}
|
||||
else {
|
||||
// attached movement position update
|
||||
auto movement { Velocity * -2.0 };
|
||||
movement.y = -movement.y;
|
||||
auto const *owner { (
|
||||
m_owner->Mechanik ?
|
||||
m_owner->Mechanik :
|
||||
m_owner->ctOwner ) };
|
||||
if( ( owner && owner->Occupied() )
|
||||
&& ( owner->Occupied()->CabOccupied < 0 ) ) {
|
||||
movement *= -1.f;
|
||||
movement.y = -movement.y;
|
||||
}
|
||||
/*
|
||||
if( ( m_owner->ctOwner )
|
||||
&& ( m_owner->ctOwner->Vehicle()->DirectionGet() != m_owner->DirectionGet() ) ) {
|
||||
movement *= -1.f;
|
||||
movement.y = -movement.y;
|
||||
}
|
||||
*/
|
||||
movement.RotateY( Angle.y );
|
||||
|
||||
m_owneroffset += movement * deltatime;
|
||||
}
|
||||
}
|
||||
|
||||
bool TCamera::SetMatrix( glm::dmat4 &Matrix ) {
|
||||
|
||||
Matrix = glm::rotate( Matrix, -Angle.z, glm::dvec3( 0.0, 0.0, 1.0 ) ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
|
||||
Matrix = glm::rotate( Matrix, -Angle.x, glm::dvec3( 1.0, 0.0, 0.0 ) );
|
||||
Matrix = glm::rotate( Matrix, -Angle.y, glm::dvec3( 0.0, 1.0, 0.0 ) ); // w zewnętrznym widoku: kierunek patrzenia
|
||||
|
||||
if( ( m_owner != nullptr ) && ( false == DebugCameraFlag ) ) {
|
||||
|
||||
Matrix *= glm::lookAt(
|
||||
glm::dvec3{ Pos },
|
||||
glm::dvec3{ LookAt },
|
||||
glm::dvec3{ vUp } );
|
||||
}
|
||||
else {
|
||||
Matrix = glm::translate( Matrix, glm::dvec3{ -Pos } ); // nie zmienia kierunku patrzenia
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TCamera::RaLook()
|
||||
{ // zmiana kierunku patrzenia - przelicza Yaw
|
||||
Math3D::vector3 where = LookAt - Pos /*+ Math3D::vector3(0, 3, 0)*/; // trochę w górę od szyn
|
||||
if( ( where.x != 0.0 ) || ( where.z != 0.0 ) ) {
|
||||
Angle.y = atan2( -where.x, -where.z ); // kąt horyzontalny
|
||||
m_rotationoffsets.y = 0.0;
|
||||
}
|
||||
double l = Math3D::Length3(where);
|
||||
if( l > 0.0 ) {
|
||||
Angle.x = asin( where.y / l ); // kąt w pionie
|
||||
m_rotationoffsets.x = 0.0;
|
||||
}
|
||||
};
|
||||
49
vehicle/Camera.h
Normal file
49
vehicle/Camera.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dumb3d.h"
|
||||
#include "command.h"
|
||||
#include "DynObj.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class TCamera {
|
||||
|
||||
public: // McZapkie: potrzebuje do kiwania na boki
|
||||
void Init( Math3D::vector3 const &Location, Math3D::vector3 const &Angle, TDynamicObject *Owner );
|
||||
void Reset();
|
||||
void OnCursorMove(double const x, double const y);
|
||||
bool OnCommand( command_data const &Command );
|
||||
void Update();
|
||||
bool SetMatrix(glm::dmat4 &Matrix);
|
||||
void RaLook();
|
||||
|
||||
Math3D::vector3 Angle; // pitch, yaw, roll
|
||||
Math3D::vector3 Pos; // współrzędne obserwatora
|
||||
Math3D::vector3 LookAt; // współrzędne punktu, na który ma patrzeć
|
||||
Math3D::vector3 vUp;
|
||||
Math3D::vector3 Velocity;
|
||||
|
||||
TDynamicObject *m_owner { nullptr }; // TODO: change to const when shake calculations are part of vehicles update
|
||||
Math3D::vector3 m_owneroffset {};
|
||||
|
||||
private:
|
||||
glm::dvec3 m_moverate;
|
||||
glm::dvec3 m_rotationoffsets; // requested changes to pitch, yaw and roll
|
||||
|
||||
};
|
||||
|
||||
struct viewport_proj_config {
|
||||
glm::vec3 pa; // screen lower left corner
|
||||
glm::vec3 pb; // screen lower right corner
|
||||
glm::vec3 pc; // screen upper left corner
|
||||
glm::vec3 pe; // eye position
|
||||
};
|
||||
8421
vehicle/Driver.cpp
Normal file
8421
vehicle/Driver.cpp
Normal file
File diff suppressed because it is too large
Load Diff
652
vehicle/Driver.h
Normal file
652
vehicle/Driver.h
Normal file
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "Classes.h"
|
||||
#include "MOVER.h"
|
||||
#include "sound.h"
|
||||
#include "DynObj.h"
|
||||
#include "mtable.h"
|
||||
#include "translation.h"
|
||||
#include "driverhints.h"
|
||||
|
||||
auto const EU07_AI_ACCELERATION = 0.05;
|
||||
auto const EU07_AI_NOACCELERATION = -0.05;
|
||||
auto const EU07_AI_BRAKINGTESTACCELERATION = -0.06;
|
||||
auto const EU07_AI_NOMOVEMENT = 0.05; // standstill velocity threshold
|
||||
auto const EU07_AI_MOVEMENT = 1.0; // deliberate movement velocity threshold
|
||||
auto const EU07_AI_SPEEDLIMITEXTENDSBEYONDSCANRANGE = 10000.0;
|
||||
|
||||
enum TOrders
|
||||
{ // rozkazy dla AI
|
||||
Wait_for_orders = 0, // czekanie na dostarczenie następnych rozkazów
|
||||
// operacje tymczasowe
|
||||
Prepare_engine = 1 << 0, // włączenie silnika
|
||||
Release_engine = 1 << 1, // wyłączenie silnika
|
||||
Change_direction = 1 << 2, // zmiana kierunku (bez skanowania sygnalizacji)
|
||||
Connect = 1 << 3, // podłączanie wagonów (z częściowym skanowaniem sygnalizacji)
|
||||
Disconnect = 1 << 4, // odłączanie wagonów (bez skanowania sygnalizacji)
|
||||
// jazda
|
||||
Shunt = 1 << 5, // tryb manewrowy
|
||||
Loose_shunt = 1 << 6, // coupling-free shunting mode
|
||||
Obey_train = 1 << 7, // tryb pociągowy
|
||||
Bank = 1 << 8, // assist mode
|
||||
// others
|
||||
Jump_to_first_order = 1 << 9, // zapęlenie do pierwszej pozycji (po co?)
|
||||
};
|
||||
|
||||
// TSignals is shifted into TMovementStatus
|
||||
enum TSignals
|
||||
{
|
||||
Signal_START = 30,
|
||||
Signal_Pc6 = 30,
|
||||
Signal_A1 = 31,
|
||||
Signal_MAX = 31
|
||||
};
|
||||
|
||||
enum TMovementStatus
|
||||
{ // flagi bitowe ruchu (iDrivigFlags)
|
||||
moveStopCloser = 1, // podjechać blisko W4 (nie podjeżdżać na początku ani po zmianie czoła)
|
||||
moveStopPoint = 2, // stawać na W4 (wyłączone podczas zmiany czoła)
|
||||
moveActive = 4, // pojazd jest załączony i skanuje
|
||||
movePress = 8, // dociskanie przy odłączeniu (zamiast zmiennej Prepare2press)
|
||||
moveConnect = 0x10, // jest blisko innego pojazdu i można próbować podłączyć
|
||||
movePrimary = 0x20, // ma priorytet w składzie (master)
|
||||
moveLate = 0x40, // flaga spóźnienia, włączy bardziej
|
||||
moveStopHere = 0x80, // nie podjeżdżać do semafora, jeśli droga nie jest wolna
|
||||
moveStartHorn = 0x100, // podawaj sygnał po podaniu wolnej drogi
|
||||
moveStartHornNow = 0x200, // podaj sygnał po odhamowaniu
|
||||
moveStartHornDone = 0x400, // podano sygnał po podaniu wolnej drogi
|
||||
moveOerlikons = 0x800, // skład wyłącznie z zaworami? Oerlikona
|
||||
moveIncSpeed = 0x1000, // załączenie jazdy (np. dla EZT)
|
||||
moveTrackEnd = 0x2000, // dalsza jazda do przodu trwale ograniczona (W5, koniec toru)
|
||||
moveSwitchFound = 0x4000, // na drodze skanowania do przodu jest rozjazd
|
||||
moveGuardSignal = 0x8000, // sygnał od kierownika (minął czas postoju)
|
||||
moveVisibility = 0x10000, // jazda na widoczność po przejechaniu S1 na SBL
|
||||
moveDoorOpened = 0x20000, // drzwi zostały otwarte - doliczyć czas na zamknięcie
|
||||
movePushPull = 0x40000, // zmiana czoła przez zmianę kabiny - nie odczepiać przy zmianie kierunku
|
||||
moveSignalFound = 0x80000, // na drodze skanowania został znaleziony semafor
|
||||
moveStopPointFound = 0x100000, // stop point detected ahead
|
||||
moveGuardOpenDoor = 0x200000 // time for opening a door before departure
|
||||
/*
|
||||
moveSemaphorWasElapsed = 0x100000, // minięty został semafor
|
||||
moveTrainInsideStation = 0x200000, // pociąg między semaforem a rozjazdami lub następnym semaforem
|
||||
moveSpeedLimitFound = 0x400000 // pociąg w ograniczeniu z podaną jego długością
|
||||
*/
|
||||
};
|
||||
|
||||
enum TStopReason
|
||||
{ // powód zatrzymania, dodawany do SetVelocity 0 - w zasadzie do usunięcia
|
||||
stopNone, // nie ma powodu - powinien jechać
|
||||
stopSleep, // nie został odpalony, to nie pojedzie
|
||||
stopSem, // semafor zamknięty
|
||||
stopTime, // czekanie na godzinę odjazdu
|
||||
stopEnd, // brak dalszej części toru
|
||||
stopDir, // trzeba stanąć, by zmienić kierunek jazdy
|
||||
stopJoin, // stoi w celu połączenia wagonów
|
||||
stopBlock, // przeszkoda na drodze ruchu
|
||||
stopComm, // otrzymano taką komendę (niewiadomego pochodzenia)
|
||||
stopOut, // komenda wyjazdu poza stację (raczej nie powinna zatrzymywać!)
|
||||
stopRadio, // komunikat przekazany radiem (Radiostop)
|
||||
stopExt, // komenda z zewnątrz
|
||||
stopError // z powodu błędu w obliczeniu drogi hamowania
|
||||
};
|
||||
|
||||
enum class TAction : int
|
||||
{ // przechowanie aktualnego stanu AI od poprzedniego przebłysku świadomości
|
||||
actUnknown, // stan nieznany (domyślny na początku)
|
||||
actPantUp, // podnieś pantograf (info dla użytkownika)
|
||||
actConv, // załącz przetwornicę (info dla użytkownika)
|
||||
actCompr, // załącz sprężarkę (info dla użytkownika)
|
||||
actSleep, //śpi (wygaszony)
|
||||
actDrive, // jazda
|
||||
actGo, // ruszanie z miejsca
|
||||
actSlow, // przyhamowanie przed ograniczeniem
|
||||
sctStop, // hamowanie w celu precyzyjnego zatrzymania
|
||||
actIdle, // luzowanie składu przed odjazdem
|
||||
actRelease, // luzowanie składu po zmniejszeniu prędkości
|
||||
actConnect, // dojazd w celu podczepienia
|
||||
actWait, // czekanie na przystanku
|
||||
actReady, // zgłoszona gotowość do odjazdu od kierownika
|
||||
actEmergency, // hamowanie awaryjne
|
||||
actGoUphill, // ruszanie pod górę
|
||||
actTest, // hamowanie kontrolne (podczas jazdy)
|
||||
actTrial // próba hamulca (na postoju)
|
||||
};
|
||||
|
||||
enum TSpeedPosFlag
|
||||
{ // wartości dla iFlag w TSpeedPos
|
||||
spNone = 0x0,
|
||||
spEnabled = 0x1, // pozycja brana pod uwagę
|
||||
spTrack = 0x2, // to jest tor
|
||||
spReverse = 0x4, // odwrotnie
|
||||
spSwitch = 0x8, // to zwrotnica
|
||||
spSwitchStatus = 0x10, // stan zwrotnicy
|
||||
spElapsed = 0x20, // pozycja minięta przez pojazd
|
||||
spEnd = 0x40, // koniec
|
||||
spCurve = 0x80, // łuk
|
||||
spEvent = 0x100, // event
|
||||
spShuntSemaphor = 0x200, // tarcza manewrowa
|
||||
spPassengerStopPoint = 0x400, // przystanek osobowy (wskaźnik W4)
|
||||
spStopOnSBL = 0x800, // zatrzymanie na SBL
|
||||
spCommandSent = 0x1000, // komenda wysłana
|
||||
spOutsideStation = 0x2000, // wskaźnik końca manewrów
|
||||
spSemaphor = 0x4000, // semafor pociągowy
|
||||
spRoadVel = 0x8000, // zadanie prędkości drogowej
|
||||
spSectionVel = 0x20000, // odcinek z ograniczeniem
|
||||
spProximityVelocity = 0x40000 // odcinek z ograniczeniem i podaną jego długościa
|
||||
// spDontApplySpeedLimit = 0x10000 // this point won't apply its speed limit. potentially set by the scanning vehicle
|
||||
};
|
||||
|
||||
class TSpeedPos
|
||||
{ // pozycja tabeli prędkości dla AI
|
||||
public:
|
||||
double fDist{ 0.0 }; // aktualna odległość (ujemna gdy minięte)
|
||||
double fVelNext{ -1.0 }; // prędkość obowiązująca od tego miejsca
|
||||
double fSectionVelocityDist{ 0.0 }; // długość ograniczenia prędkości
|
||||
int iFlags{ spNone }; // flagi typu wpisu do tabelki
|
||||
bool bMoved{ false }; // czy przesunięty (dotyczy punktu zatrzymania w peronie)
|
||||
double fMoved{ 0.0 }; // ile przesunięty (dotyczy punktu zatrzymania w peronie)
|
||||
Math3D::vector3 vPos; // współrzędne XYZ do liczenia odległości
|
||||
struct
|
||||
{
|
||||
TTrack *trTrack{ nullptr }; // wskaźnik na tor o zmiennej prędkości (zwrotnica, obrotnica)
|
||||
basic_event *evEvent{ nullptr }; // połączenie z eventem albo komórką pamięci
|
||||
};
|
||||
void CommandCheck();
|
||||
|
||||
public:
|
||||
TSpeedPos(TTrack *track, double dist, int flag);
|
||||
TSpeedPos(basic_event *event, double dist, double length, TOrders order);
|
||||
TSpeedPos() = default;
|
||||
void Clear();
|
||||
bool Update();
|
||||
// aktualizuje odległość we wpisie
|
||||
inline
|
||||
void
|
||||
UpdateDistance( double dist ) {
|
||||
fDist -= dist; }
|
||||
bool Set(basic_event *e, double d, double length, TOrders order = Wait_for_orders);
|
||||
void Set(TTrack *t, double d, int f);
|
||||
std::string TableText() const;
|
||||
std::string GetName() const;
|
||||
bool IsProperSemaphor(TOrders order = Wait_for_orders);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const bool Aggressive = true;
|
||||
static const bool Easyman = false;
|
||||
static const bool AIdriver = true;
|
||||
static const bool Humandriver = false;
|
||||
static const int maxorders = 64; // ilość rozkazów w tabelce
|
||||
static const int maxdriverfails = 4; // ile błędów może zrobić AI zanim zmieni nastawienie
|
||||
extern bool WriteLogFlag; // logowanie parametrów fizycznych
|
||||
static const int BrakeAccTableSize = 20;
|
||||
|
||||
static const int gbh_NP = -2; //odciecie w hamulcu ogolnym
|
||||
static const int gbh_RP = 0; //jazda w hamulcu ogolnym
|
||||
static const int gbh_FS = -1; //napelnianie uderzeniowe w hamulcu ogolnym
|
||||
static const int gbh_MIN = -2; //minimalna pozycja w hamulcu ogolnym
|
||||
static const int gbh_MAX = 6; //maksymalna pozycja w hamulcu ogolnym
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class TController {
|
||||
// TBD: few authorized inspectors, or bunch of public getters?
|
||||
friend class TTrain;
|
||||
friend class drivingaid_panel;
|
||||
friend class timetable_panel;
|
||||
friend class scenario_panel;
|
||||
friend class debug_panel;
|
||||
friend class whois_event;
|
||||
|
||||
public:
|
||||
TController( bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary = true );
|
||||
~TController();
|
||||
|
||||
// ai operations logic
|
||||
// types
|
||||
using hintpredicate = std::function<bool(float)>; // returns true if action hint can be removed
|
||||
|
||||
// methods
|
||||
public:
|
||||
void Update( double dt ); // uruchamiac przynajmniej raz na sekundę
|
||||
void MoveTo( TDynamicObject *to );
|
||||
void TakeControl( bool const Aidriver, bool const Forcevehiclecheck = false );
|
||||
inline
|
||||
bool primary( bool const Primary ) {
|
||||
SetFlag( iDrivigFlags, ( Primary ? movePrimary : -movePrimary ) );
|
||||
return primary(); }
|
||||
inline
|
||||
bool primary() const {
|
||||
return ( ( iDrivigFlags & movePrimary ) != 0 ); };
|
||||
inline
|
||||
TMoverParameters const *Controlling() const {
|
||||
return mvControlling; }
|
||||
inline
|
||||
TMoverParameters const *Occupied() const {
|
||||
return mvOccupied; }
|
||||
void DirectionInitial();
|
||||
void DirectionChange();
|
||||
inline
|
||||
int Direction() const {
|
||||
return iDirection; }
|
||||
inline
|
||||
TAction & action() {
|
||||
return eAction; }
|
||||
inline
|
||||
TAction const & action() const {
|
||||
return eAction; }
|
||||
inline
|
||||
bool is_active() const {
|
||||
return TestFlag( iDrivigFlags, moveActive ); }
|
||||
inline
|
||||
bool is_train() const {
|
||||
return TestFlag( mvOccupied->CategoryFlag, 1 ); }
|
||||
inline
|
||||
bool is_car() const {
|
||||
return TestFlag( mvOccupied->CategoryFlag, 2 ); }
|
||||
inline
|
||||
bool is_emu() const {
|
||||
return ( mvControlling->TrainType == dt_EZT ); }
|
||||
inline
|
||||
bool is_dmu() const {
|
||||
return ( mvControlling->TrainType == dt_DMU ); }
|
||||
inline
|
||||
bool has_diesel_engine() const {
|
||||
return ( ( mvControlling->EngineType == TEngineType::DieselElectric )
|
||||
|| ( mvControlling->EngineType == TEngineType::DieselEngine ) );
|
||||
}
|
||||
TBrakeSystem consist_brake_system() const;
|
||||
private:
|
||||
void Activation(); // umieszczenie obsady w odpowiednim członie
|
||||
void ControllingSet(); // znajduje człon do sterowania
|
||||
void SetDriverPsyche();
|
||||
bool IncBrake();
|
||||
bool DecBrake();
|
||||
void LapBrake();
|
||||
void ZeroLocalBrake();
|
||||
bool IncSpeed();
|
||||
bool DecSpeed( bool force = false );
|
||||
void ZeroSpeed( bool const Enforce = false );
|
||||
bool IncBrakeEIM();
|
||||
bool DecBrakeEIM();
|
||||
bool IncSpeedEIM();
|
||||
bool DecSpeedEIM( int const Amount = 1 );
|
||||
void BrakeLevelSet( double b );
|
||||
bool BrakeLevelAdd( double b );
|
||||
void SpeedSet();
|
||||
void SpeedCntrl( double DesiredSpeed );
|
||||
void SetTimeControllers(); /*setting state of time controllers depending of desired action*/
|
||||
void CheckTimeControllers(); /*checking state of time controllers to reset them to stable position*/
|
||||
double ESMVelocity( bool Main );
|
||||
void PrepareDirection();
|
||||
bool PrepareHeating();
|
||||
// uaktualnia informacje o prędkości
|
||||
void SetVelocity( double NewVel, double NewVelNext, TStopReason r = stopNone );
|
||||
int CheckDirection();
|
||||
void WaitingSet( double Seconds );
|
||||
void DirectionForward( bool forward );
|
||||
void ZeroDirection();
|
||||
int OrderDirectionChange( int newdir, TMoverParameters *Vehicle );
|
||||
void sync_consist_reversers();
|
||||
void Lights( int head, int rear );
|
||||
std::string StopReasonText() const;
|
||||
double BrakeAccFactor() const;
|
||||
// modifies brake distance for low target speeds, to ease braking rate in such situations
|
||||
float
|
||||
braking_distance_multiplier( float const Targetvelocity ) const;
|
||||
inline
|
||||
int DrivigFlags() const {
|
||||
return iDrivigFlags; };
|
||||
inline
|
||||
double DirectionalVel() const {
|
||||
return mvOccupied->Vel * sign( iDirection * mvOccupied->V ); }
|
||||
|
||||
void update_timers( double const dt );
|
||||
void update_logs( double const dt );
|
||||
void determine_consist_state();
|
||||
void determine_braking_distance();
|
||||
void determine_proximity_ranges();
|
||||
void scan_route( double const Range );
|
||||
void scan_obstacles( double const Range );
|
||||
void control_wheelslip();
|
||||
void control_pantographs();
|
||||
void control_horns( double const Timedelta );
|
||||
void control_security_system( double const Timedelta );
|
||||
void control_handles();
|
||||
void control_lights();
|
||||
void control_compartment_lights();
|
||||
void control_doors();
|
||||
void UpdateCommand();
|
||||
void handle_engine();
|
||||
void handle_orders();
|
||||
void UpdateNextStop();
|
||||
void check_load_exchange(); // returns: estimated remaining time of load exchange, in seconds
|
||||
void check_departure();
|
||||
void UpdateConnect();
|
||||
void UpdateDisconnect();
|
||||
int unit_count( int const Threshold ) const;
|
||||
void UpdateChangeDirection();
|
||||
void UpdateLooseShunt();
|
||||
void UpdateObeyTrain();
|
||||
void GuardOpenDoor();
|
||||
void pick_optimal_speed( double const Range );
|
||||
void adjust_desired_speed_for_obstacles();
|
||||
void adjust_desired_speed_for_limits();
|
||||
void adjust_desired_speed_for_target_speed( double const Range );
|
||||
void adjust_desired_speed_for_current_speed();
|
||||
void adjust_desired_speed_for_braking_test();
|
||||
void control_tractive_and_braking_force();
|
||||
void control_releaser();
|
||||
void control_main_pipe();
|
||||
void control_relays();
|
||||
void control_motor_connectors();
|
||||
void control_tractive_force();
|
||||
void increase_tractive_force();
|
||||
void control_braking_force();
|
||||
void apply_independent_brake_only();
|
||||
void check_route_ahead( double const Range );
|
||||
void check_route_behind( double const Range );
|
||||
void UpdateBrakingHelper();
|
||||
void hint( driver_hint const Value, hintpredicate const Predicate, float const Predicateparameter = 0.f );
|
||||
void update_hints();
|
||||
void remove_hint( driver_hint const Value );
|
||||
void remove_train_brake_hints();
|
||||
void remove_master_controller_hints();
|
||||
void remove_reverser_hints();
|
||||
void cue_action( driver_hint const Action, float const Actionparameter = 0.f );
|
||||
// members
|
||||
public:
|
||||
bool AIControllFlag = false; // rzeczywisty/wirtualny maszynista
|
||||
int iOverheadZero = 0; // suma bitowa jezdy bezprądowej, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||
int iOverheadDown = 0; // suma bitowa opuszczenia pantografów, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||
double BrakeCtrlPosition = 0.0; // intermediate position of main brake controller
|
||||
int UniversalBrakeButtons = 0.0; // flag of which universal buttons need to be pressed
|
||||
int DizelPercentage = 0; // oczekiwane procenty jazdy/hamowania szynobusem
|
||||
int DizelPercentage_Speed = 0; // oczekiwane procenty jazdy/hamowania szynobusem w związku z osiąganiem VelDesired
|
||||
double fMedAmax = 0.8; //maximum decceleration when using ep/med brake
|
||||
private:
|
||||
bool Psyche = false;
|
||||
int HelperState = 0; //stan pomocnika maszynisty
|
||||
TDynamicObject *pVehicle = nullptr; // pojazd w którym siedzi sterujący
|
||||
TMoverParameters *mvControlling = nullptr; // jakim pojazdem steruje (może silnikowym w EZT)
|
||||
TMoverParameters *mvOccupied = nullptr; // jakim pojazdem hamuje
|
||||
TMoverParameters *mvPantographUnit = nullptr; //pantograph equipped vehicle in the occupied/controlled set
|
||||
std::string VehicleName;
|
||||
std::array<int, 2> m_lighthints = { -1, -1 }; // suggested light patterns
|
||||
double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji)
|
||||
double AccDesired = 0.0; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj)
|
||||
double VelDesired = 0.0; // predkość, z jaką ma jechać, wynikająca z analizy tableki; <=VelSignal
|
||||
double fAccDesiredAv = 0.0; // uśrednione przyspieszenie z kolejnych przebłysków świadomości, żeby ograniczyć migotanie
|
||||
double VelforDriver = -1.0; // prędkość, używana przy zmianie kierunku (ograniczenie przy nieznajmości szlaku?)
|
||||
double VelSignal = 0.0; // ograniczenie prędkości z kompilacji znaków i sygnałów // normalnie na początku ma stać, no chyba że jedzie
|
||||
double VelLimit = -1.0; // predkość zadawana przez event jednokierunkowego ograniczenia prędkości // -1: brak ograniczenia prędkości
|
||||
double VelSignalLast = -1.0; // prędkość zadana na ostatnim semaforze // ostatni semafor też bez ograniczenia
|
||||
double VelSignalNext = 0.0; // prędkość zadana na następnym semaforze
|
||||
double VelLimitLast = -1.0; // prędkość zadana przez ograniczenie // ostatnie ograniczenie bez ograniczenia
|
||||
double VelRoad = -1.0; // aktualna prędkość drogowa (ze znaku W27) (PutValues albo komendą) // prędkość drogowa bez ograniczenia
|
||||
double VelNext = 120.0; // prędkość, jaka ma być po przejechaniu długości ProximityDist
|
||||
double VelRestricted = -1.0; // speed of travel after passing a permissive signal at stop
|
||||
double FirstSemaphorDist = 10000.0; // odległość do pierwszego znalezionego semafora
|
||||
double ActualProximityDist = 1.0; // odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia
|
||||
std::pair<double, double> VelLimitLastDist { 0.0, 0.0 }; // distance to velocity change point
|
||||
double SwitchClearDist { 0.0 }; // distance to point after farthest detected switch
|
||||
int iDirection = 0; // kierunek jazdy względem sprzęgów pojazdu, w którym siedzi AI (1=przód,-1=tył)
|
||||
int iDirectionOrder = 0; //żadany kierunek jazdy (służy do zmiany kierunku)
|
||||
std::optional<int> iDirectionBackup; // consist direction to be restored after coupling/uncoupling and similar direction-changing operations
|
||||
std::optional<std::pair<TDynamicObject*,int>> iCouplingVehicle; // <vehicle, coupler> to be coupled with another consist in current coupling operation
|
||||
int iVehicleCount = -2; // wartość neutralna // ilość pojazdów do odłączenia albo zabrania ze składu (-1=wszystkie)
|
||||
int iCoupler = 0; // maska sprzęgu, jaką należy użyć przy łączeniu (po osiągnięciu trybu Connect), 0 gdy jazda bez łączenia
|
||||
int iDriverFailCount = 0; // licznik błędów AI
|
||||
bool Need_TryAgain = false; // true, jeśli druga pozycja w elektryku nie załapała
|
||||
// bool Need_BrakeRelease = true;
|
||||
bool IsHeatingTemperatureOK{ true };
|
||||
bool IsHeatingTemperatureTooLow{ false };
|
||||
bool IsAtPassengerStop{ false }; // true if the consist is within acceptable range of w4 post
|
||||
bool IsScheduledPassengerStopVisible{ false };
|
||||
double fMinProximityDist = 30.0; // stawanie między 30 a 60 m przed przeszkodą // minimalna oległość do przeszkody, jaką należy zachować
|
||||
double fOverhead1 = 3000.0; // informacja o napięciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!)
|
||||
double fOverhead2 = -1.0; // informacja o sposobie jazdy (-1=normalnie, 0=bez prądu, >0=z opuszczonym i ograniczeniem prędkości)
|
||||
double fVoltage = 0.0; // uśrednione napięcie sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas
|
||||
double fMaxProximityDist = 50.0; // stawanie między 30 a 60 m przed przeszkodą // akceptowalna odległość stanięcia przed przeszkodą
|
||||
TStopReason eStopReason = stopSleep; // powód zatrzymania przy ustawieniu zerowej prędkości // na początku śpi
|
||||
double fVelPlus = 0.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
|
||||
double fVelMinus = 0.0; // margines obniżenia prędkości, powodujący załączenie napędu
|
||||
double fWarningDuration = 0.0; // ile czasu jeszcze trąbić
|
||||
double WaitingTime = 0.0; // zliczany czas oczekiwania do samoistnego ruszenia
|
||||
double WaitingExpireTime = 31.0; // tyle ma czekać, zanim się ruszy // maksymlany czas oczekiwania do samoistnego ruszenia
|
||||
double IdleTime{}; // keeps track of time spent at a stop
|
||||
double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku)
|
||||
float ExchangeTime{ 0.0 }; // time needed to finish current load exchange
|
||||
double fShuntVelocity = 40.0; // prędkość manewrowania, zależy m.in. od składu
|
||||
int iDrivigFlags = // flagi bitowe ruchu
|
||||
moveStopPoint | // podjedź do W4 możliwie blisko
|
||||
moveStopHere | // nie podjeżdżaj do semafora, jeśli droga nie jest wolna
|
||||
moveStartHorn; // podaj sygnał po podaniu wolnej drogi
|
||||
double fDriverBraking = 0.0; // po pomnożeniu przez v^2 [km/h] daje ~drogę hamowania [m]
|
||||
double fDriverDist = 0.0; // dopuszczalna odległość podjechania do przeszkody
|
||||
double fVelMax = -1.0; // maksymalna prędkość składu (sprawdzany każdy pojazd)
|
||||
double fBrakeDist = 0.0; // przybliżona droga hamowania
|
||||
double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h)
|
||||
double fNominalAccThreshold = 0.0; // nominalny próg opóźnienia dla zadziałania hamulca
|
||||
double fAccThreshold = 0.0; // aktualny próg opóźnienia dla zadziałania hamulca
|
||||
double AbsAccS = 0.0; // próg opóźnienia dla zadziałania hamulca
|
||||
// dla fBrake_aX:
|
||||
// indeks [0] - wartości odpowiednie dla aktualnej prędkości
|
||||
// a potem jest 20 wartości dla różnych prędkości zmieniających się co 5 % Vmax pojazdu obsadzonego
|
||||
double fBrake_a0[ BrakeAccTableSize + 1 ] = { 0.0 }; // opóźnienia hamowania przy ustawieniu zaworu maszynisty w pozycji 1.0
|
||||
double fBrake_a1[ BrakeAccTableSize + 1 ] = { 0.0 }; // przyrost opóźnienia hamowania po przestawieniu zaworu maszynisty o 0,25 pozycji
|
||||
double BrakingInitialLevel{ 1.0 };
|
||||
double BrakingLevelIncrease{ 0.25 };
|
||||
double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI
|
||||
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
|
||||
double BrakeChargingCooldown{}; // prevents the ai from trying to charge the train brake too frequently
|
||||
TBrakeSystem BrakeSystem = TBrakeSystem::Individual; //type of main brake
|
||||
bool ForcePNBrake = false; //is it necessary to use PN brake instead of EP brake
|
||||
int DynamicBrakeTest = 0; //is it necessary to make brake test while driving
|
||||
double DBT_VelocityBrake = 0;
|
||||
double DBT_VelocityRelease = 0;
|
||||
double DBT_VelocityFinish = 0;
|
||||
double DBT_BrakingTime = 0;
|
||||
double DBT_ReleasingTime = 0;
|
||||
double DBT_MidPointAcc = 0;
|
||||
int StaticBrakeTest = 0; //is it necessary to make brake test while standing
|
||||
double LastReactionTime = 0.0;
|
||||
double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi
|
||||
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations
|
||||
TAction eAction{ TAction::actUnknown }; // aktualny stan
|
||||
std::list< std::tuple<driver_hint, hintpredicate, float> > m_hints; // queued ai operations
|
||||
|
||||
// orders
|
||||
// methods
|
||||
public:
|
||||
void PutCommand( std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm );
|
||||
bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm );
|
||||
// defines assignment data
|
||||
inline auto assignment() -> std::string & { return m_assignment; }
|
||||
inline auto assignment() const -> std::string const & { return m_assignment; }
|
||||
std::string OrderCurrent() const;
|
||||
private:
|
||||
void RecognizeCommand(); // odczytuje komende przekazana lokomotywie
|
||||
void JumpToNextOrder( bool const Skipmergedchangedirection = false );
|
||||
void JumpToFirstOrder();
|
||||
void OrderPush( TOrders NewOrder );
|
||||
void OrderNext( TOrders NewOrder );
|
||||
inline TOrders OrderCurrentGet() const;
|
||||
inline TOrders OrderNextGet() const;
|
||||
void OrderCheck();
|
||||
void OrdersInit( double fVel );
|
||||
void OrdersClear();
|
||||
void OrdersDump( std::string const Neworder, bool const Verbose = true );
|
||||
std::string Order2Str( TOrders Order ) const;
|
||||
// members
|
||||
std::string m_assignment;
|
||||
Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda // NOTE: not used
|
||||
TOrders OrderList[ maxorders ]; // lista rozkazów
|
||||
int OrderPos = 0,
|
||||
OrderTop = 0; // rozkaz aktualny oraz wolne miejsce do wstawiania nowych
|
||||
|
||||
// scantable
|
||||
// methods
|
||||
public:
|
||||
int CrossRoute( TTrack *tr );
|
||||
inline void MoveDistanceAdd( double distance ) {
|
||||
dMoveLen += distance * iDirection;
|
||||
} //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna
|
||||
private:
|
||||
// Ra: metody obsługujące skanowanie toru
|
||||
std::vector<basic_event *> CheckTrackEvent( TTrack *Track, double const fDirection ) const;
|
||||
bool TableAddNew();
|
||||
bool TableNotFound( basic_event const *Event, double const Distance ) const;
|
||||
void TableTraceRoute( double fDistance, TDynamicObject *pVehicle );
|
||||
void TableCheck( double fDistance );
|
||||
TCommandType TableUpdate( double &fVelDes, double &fDist, double &fNext, double &fAcc );
|
||||
bool TableUpdateStopPoint( TCommandType &Command, TSpeedPos &Point, double const Signaldistance );
|
||||
bool TableUpdateEvent( double &Velocity, TCommandType &Command, TSpeedPos &Point, double &Signaldistance, int const Pointindex );
|
||||
// returns most recently calculated distance to potential obstacle ahead
|
||||
double TrackObstacle() const;
|
||||
void TablePurger();
|
||||
void TableSort();
|
||||
inline double MoveDistanceGet() const {
|
||||
return dMoveLen;
|
||||
}
|
||||
inline void MoveDistanceReset() {
|
||||
dMoveLen = 0.0;
|
||||
}
|
||||
std::size_t TableSize() const { return sSpeedTable.size(); }
|
||||
void TableClear();
|
||||
int TableDirection() { return iTableDirection; }
|
||||
// Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
|
||||
bool IsOccupiedByAnotherConsist( TTrack *Track, double const Distance );
|
||||
basic_event *CheckTrackEventBackward( double fDirection, TTrack *Track, TDynamicObject *Vehicle, int const Eventdirection = 1, end const End = end::rear );
|
||||
TTrack *BackwardTraceRoute( double &fDistance, double &fDirection, TDynamicObject *Vehicle, basic_event *&Event, int const Eventdirection = 1, end const End = end::rear, bool const Untiloccupied = true );
|
||||
void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos );
|
||||
TCommandType BackwardScan( double const Range );
|
||||
std::string TableText( std::size_t const Index ) const;
|
||||
/*
|
||||
void RouteSwitch(int d);
|
||||
*/
|
||||
// members
|
||||
int iLast{ 0 }; // ostatnia wypełniona pozycja w tabeli <iFirst (modulo iSpeedTableSize)
|
||||
int iTableDirection{ 0 }; // kierunek zapełnienia tabelki względem pojazdu z AI
|
||||
std::vector<TSpeedPos> sSpeedTable;
|
||||
double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze
|
||||
TTrack *tLast = nullptr; // ostatni analizowany tor
|
||||
basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
|
||||
std::size_t SemNextIndex{ std::size_t( -1 ) };
|
||||
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
||||
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
|
||||
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
|
||||
neighbour_data Obstacle; // nearest vehicle detected ahead on current route
|
||||
|
||||
// timetable
|
||||
// methods
|
||||
public:
|
||||
const std::string &TrainName() const;
|
||||
Mtable::TTrainParameters const & TrainTimetable() const;
|
||||
private:
|
||||
std::string Relation() const;
|
||||
int StationIndex() const;
|
||||
int StationCount() const;
|
||||
bool IsStop() const;
|
||||
std::string NextStop() const;
|
||||
// tests whether the train is delayed and sets accordingly a driving flag
|
||||
void UpdateDelayFlag();
|
||||
// members
|
||||
Mtable::TTrainParameters TrainParams; // rozkład jazdy zawsze jest, nawet jeśli pusty
|
||||
std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu
|
||||
// int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu
|
||||
std::string m_lastexchangestop; // HACK: safeguard to prevent multiple load exchanges per station
|
||||
int m_lastexchangeplatforms { 0 }; // cached station platforms for last exchange
|
||||
int m_lastexchangedirection { 0 }; //
|
||||
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
|
||||
int iRadioChannel = 1; // numer aktualnego kanału radiowego
|
||||
int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia)
|
||||
sound_source tsGuardSignal{ sound_placement::internal };
|
||||
announcement_t m_lastannouncement{ announcement_t::idle };
|
||||
bool m_makenextstopannouncement{ false };
|
||||
|
||||
// consist
|
||||
// methods
|
||||
public:
|
||||
bool CheckVehicles( TOrders user = Wait_for_orders );
|
||||
private:
|
||||
bool PrepareEngine();
|
||||
bool ReleaseEngine();
|
||||
void Doors( bool const Open, int const Side = 0 );
|
||||
// returns true if any vehicle in the consist has an open door
|
||||
bool doors_open() const;
|
||||
bool doors_permit_active() const;
|
||||
void AutoRewident(); // ustawia hamulce w składzie
|
||||
void announce( announcement_t const Announcement );
|
||||
// members
|
||||
double fLength = 0.0; // długość składu (do wyciągania z ograniczeń)
|
||||
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
|
||||
double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji
|
||||
int iVehicles = 0; // ilość pojazdów w składzie
|
||||
int ControlledEnginesCount{ 0 }; // number of powered vehicles under driver's control
|
||||
bool iEngineActive{ false }; // ABu: Czy silnik byl juz zalaczony
|
||||
bool IsPassengerTrain{ false };
|
||||
bool IsCargoTrain{ false };
|
||||
bool IsHeavyCargoTrain{ false };
|
||||
double fReady = 0.0; // poziom odhamowania wagonów
|
||||
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
|
||||
bool IsConsistBraked { false };
|
||||
double ConsistShade{ 1.0 }; // averaged amount of sunlight received by the consist
|
||||
TDynamicObject *pVehicles[ 2 ]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane)
|
||||
bool DoesAnyDoorNeedOpening{ false };
|
||||
bool IsAnyDoorOpen[ 2 ]; // state of door in the consist
|
||||
bool IsAnyDoorOnlyOpen[ 2 ]; // state of door in the consist regardless of step
|
||||
bool IsAnyDoorPermitActive[ 2 ]; // state of door permit in the consist
|
||||
bool IsAnyLineBreakerOpen{ false }; // state of line breaker in all powered vehicles under control
|
||||
bool IsAnyConverterOverloadRelayOpen{ false }; // state of converter overload relays in all vehicles under control
|
||||
bool IsAnyMotorOverloadRelayOpen{ false }; // state of motor overload relays in all vehicles under control
|
||||
bool IsAnyGroundRelayOpen{ false };
|
||||
bool IsAnyCompressorPresent { false };
|
||||
bool IsAnyCompressorEnabled{ false };
|
||||
bool IsAnyCompressorExplicitlyEnabled{ false }; // only takes into account manually controlled devices
|
||||
bool IsAnyConverterPresent{ false };
|
||||
bool IsAnyConverterEnabled{ false };
|
||||
bool IsAnyConverterExplicitlyEnabled{ false }; // only takes into account manually controlled devices
|
||||
bool IsAnyCouplerStretched{ false }; // whether there's a coupler in the consist stretched above limit
|
||||
|
||||
// logs
|
||||
// methods
|
||||
void PhysicsLog();
|
||||
void CloseLog();
|
||||
// members
|
||||
std::ofstream LogFile; // zapis parametrow fizycznych
|
||||
double LastUpdatedTime = 0.0; // czas od ostatniego logu
|
||||
double ElapsedTime = 0.0; // czas od poczatku logu
|
||||
|
||||
// getters
|
||||
public:
|
||||
TDynamicObject const *Vehicle() const {
|
||||
return pVehicle; }
|
||||
TDynamicObject *Vehicle( end const Side ) const {
|
||||
return pVehicles[ Side ]; }
|
||||
private:
|
||||
std::string OwnerName() const;
|
||||
|
||||
// leftovers
|
||||
/*
|
||||
int iRouteWanted = 3; // oczekiwany kierunek jazdy (0-stop,1-lewo,2-prawo,3-prosto) np. odpala migacz lub czeka na stan zwrotnicy
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
inline TOrders TController::OrderCurrentGet() const {
|
||||
return OrderList[ OrderPos ];
|
||||
}
|
||||
|
||||
inline TOrders TController::OrderNextGet() const {
|
||||
return OrderList[ OrderPos + 1 ];
|
||||
}
|
||||
8934
vehicle/DynObj.cpp
Normal file
8934
vehicle/DynObj.cpp
Normal file
File diff suppressed because it is too large
Load Diff
922
vehicle/DynObj.h
Normal file
922
vehicle/DynObj.h
Normal file
@@ -0,0 +1,922 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
#include "Classes.h"
|
||||
#include "interfaces/IMaterial.h"
|
||||
#include "MOVER.h"
|
||||
#include "TrkFoll.h"
|
||||
#include "Button.h"
|
||||
#include "AirCoupler.h"
|
||||
#include "interfaces/ITexture.h"
|
||||
#include "sound.h"
|
||||
#include "Spring.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define EU07_SOUND_BOGIESOUNDS
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
int const ANIM_WHEELS = 0; // koła
|
||||
int const ANIM_DOORS = 1; // drzwi
|
||||
int const ANIM_LEVERS = 2; // elementy obracane (wycieraczki, koła skrętne, przestawiacze, klocki ham.)
|
||||
int const ANIM_BUFFERS = 3; // elementy przesuwane (zderzaki)
|
||||
int const ANIM_BOOGIES = 4; // wózki (są skręcane w dwóch osiach)
|
||||
int const ANIM_PANTS = 5; // pantografy
|
||||
int const ANIM_STEAMS = 6; // napęd parowozu
|
||||
int const ANIM_DOORSTEPS = 7;
|
||||
int const ANIM_MIRRORS = 8;
|
||||
int const ANIM_WIPERS = 9;
|
||||
int const ANIM_TYPES = 10; // Ra: ilość typów animacji
|
||||
|
||||
class TAnim;
|
||||
//typedef void(__closure *TUpdate)(TAnim *pAnim); // typ funkcji aktualizującej położenie submodeli
|
||||
typedef std::function<void(TAnim *)> TUpdate; // __closure is Borland-specific extension
|
||||
|
||||
// McZapkie-250202
|
||||
int const MaxAxles = 16; // ABu 280105: zmienione z 8 na 16
|
||||
// const MaxAnimatedAxles=16; //i to tez.
|
||||
// const MaxAnimatedDoors=16; //NBMX wrzesien 2003
|
||||
/*
|
||||
Ra: Utworzyć klasę wyposażenia opcjonalnego, z której będą dziedziczyć klasy drzwi,
|
||||
pantografów, napędu parowozu i innych ruchomych części pojazdów. Klasy powinny być
|
||||
pseudo-wirtualne, bo wirtualne mogą obniżać wydajnosść.
|
||||
Przy wczytywaniu MMD utworzyć tabelę wskaźnikow na te dodatki. Przy wyświetlaniu
|
||||
pojazdu wykonywać Update() na kolejnych obiektach wyposażenia.
|
||||
Rozważyć użycie oddzielnych modeli dla niektórych pojazdów (np. lokomotywy), co
|
||||
zaoszczędziło by czas ustawiania animacji na modelu wspólnym dla kilku pojazdów,
|
||||
szczególnie dla pojazdów w danej chwili nieruchomych (przy dużym zagęszczeniu
|
||||
modeli na stacjach na ogół przewaga jest tych nieruchomych).
|
||||
*/
|
||||
class TAnimValveGear
|
||||
{ // współczynniki do animacji parowozu (wartości przykładowe dla Pt47)
|
||||
int iValues; // ilość liczb (wersja):
|
||||
float fKorbowodR; // długość korby (pół skoku tłoka) [m]: 0.35
|
||||
float fKorbowodL; // długość korbowodu [m]: 3.8
|
||||
float fDrazekR; // promień mimośrodu (drążka) [m]: 0.18
|
||||
float fDrazekL; // dł. drążka mimośrodowego [m]: 2.55889
|
||||
float fJarzmoV; // wysokość w pionie osi jarzma od osi koła [m]: 0.751
|
||||
float fJarzmoH; // odległość w poziomie osi jarzma od osi koła [m]: 2.550
|
||||
float fJarzmoR; // promień jarzma do styku z drążkiem [m]: 0.450
|
||||
float fJarzmoA; // kąt mimośrodu względem kąta koła [°]: -96.77416667
|
||||
float fWdzidloL; // długość wodzidła [m]: 2.0
|
||||
float fWahaczH; // długość wahacza (góra) [m]: 0.14
|
||||
float fSuwakH; // wysokość osi suwaka ponad osią koła [m]: 0.62
|
||||
float fWahaczL; // długość wahacza (dół) [m]: 0.84
|
||||
float fLacznikL; // długość łącznika wahacza [m]: 0.75072
|
||||
float fRamieL; // odległość ramienia krzyżulca od osi koła [m]: 0.192
|
||||
float fSuwakL; // odległość środka tłoka/suwaka od osi koła [m]: 5.650
|
||||
// dołożyć parametry drążka nastawnicy
|
||||
// albo nawet zrobić dynamiczną tablicę float[] i w nią pakować wszelkie współczynniki, potem
|
||||
// używać indeksów
|
||||
// współczynniki mogą być wspólne dla 2-4 tłoków, albo każdy tłok może mieć odrębne
|
||||
};
|
||||
|
||||
class TAnimPant
|
||||
{ // współczynniki do animacji pantografu
|
||||
public:
|
||||
Math3D::vector3 vPos; // Ra: współrzędne punktu zerowego pantografu (X dodatnie dla przedniego)
|
||||
double fLenL1; // długość dolnego ramienia 1, odczytana z modelu
|
||||
double fLenU1; // długość górnego ramienia 1, odczytana z modelu
|
||||
double fLenL2; // długość dolnego ramienia 2, odczytana z modelu
|
||||
double fLenU2; // długość górnego ramienia 2, odczytana z modelu
|
||||
double fHoriz; // przesunięcie ślizgu w długości pojazdu względem osi obrotu dolnego ramienia
|
||||
double fHeight; // wysokość ślizgu ponad oś obrotu, odejmowana od wysokości drutu
|
||||
double fWidth; // połowa szerokości roboczej ślizgu, do wykrycia ześlizgnięcia się drutu
|
||||
double fAngleL0; // Ra: początkowy kąt dolnego ramienia (odejmowany przy animacji)
|
||||
double fAngleU0; // Ra: początkowy kąt górnego ramienia (odejmowany przy animacji)
|
||||
double PantTraction; // Winger 170204: wysokość drutu ponad punktem na wysokości vPos.y p.g.s.
|
||||
double PantWys; // Ra: aktualna wysokość uniesienia ślizgu do porównania z wysokością drutu
|
||||
double fAngleL; // Winger 160204: aktualny kąt ramienia dolnego
|
||||
double fAngleU; // Ra: aktualny kąt ramienia górnego
|
||||
double NoVoltTime; // czas od utraty kontaktu z drutem
|
||||
TTraction *hvPowerWire; // aktualnie podczepione druty, na razie tu
|
||||
float fWidthExtra; // dodatkowy rozmiar poziomy poza część roboczą (fWidth)
|
||||
float fHeightExtra[5]; //łamana symulująca kształt nabieżnika
|
||||
// double fHorizontal; //Ra 2015-01: położenie drutu względem osi pantografu
|
||||
|
||||
// factory ktore mozna nadpisac z fiza
|
||||
float rd1rf{1.f}; // mnoznik obrotu ramienia dolnego 1
|
||||
float rd2rf{1.f}; // mnoznik obrotu ramienia dolnego 2
|
||||
float rg1rf{1.f}; // mnoznik obrotu ramienia gornego 1
|
||||
float rg2rf{1.f}; // mnoznik obrotu ramienia gornego 2
|
||||
float slizgrf{1.f}; // mnoznik obrotu slizgacza
|
||||
void AKP_4E();
|
||||
void WBL85();
|
||||
void DSAx();
|
||||
void EC160_200();
|
||||
};
|
||||
|
||||
class TAnim
|
||||
{ // klasa animowanej części pojazdu (koła, drzwi, pantografy, burty, napęd parowozu, siłowniki
|
||||
// itd.)
|
||||
public:
|
||||
// constructor
|
||||
TAnim() = default;
|
||||
// destructor
|
||||
~TAnim();
|
||||
// methods
|
||||
int TypeSet(int i, TMoverParameters currentMover, int fl = 0); // ustawienie typu
|
||||
// members
|
||||
union
|
||||
{
|
||||
TSubModel *smAnimated; // animowany submodel (jeśli tylko jeden, np. oś)
|
||||
TSubModel **smElement; // jeśli animowanych elementów jest więcej (pantograf, napęd
|
||||
// parowozu)
|
||||
int iShift; // przesunięcie przed przydzieleniem wskaźnika
|
||||
};
|
||||
union
|
||||
{ // parametry animacji
|
||||
TAnimValveGear *pValveGear; // współczynniki do animacji parowozu
|
||||
int dWheelAngle; // wskaźnik na kąt obrotu osi
|
||||
float *fParam; // różne parametry dla animacji
|
||||
TAnimPant *fParamPants; // różne parametry dla animacji
|
||||
};
|
||||
union
|
||||
{ // wskaźnik na obiekt odniesienia
|
||||
double *fDoubleBase; // jakiś double w fizyce
|
||||
float *fFloatBase; // jakiś float w fizyce
|
||||
int *iIntBase; // jakiś int w fizyce
|
||||
};
|
||||
// void _fastcall Update(); //wskaźnik do funkcji aktualizacji animacji
|
||||
int iFlags{ 0 }; // flagi animacji
|
||||
float fMaxDist; // do jakiej odległości wykonywana jest animacja NOTE: square of actual distance
|
||||
float fSpeed; // parametr szybkości animacji
|
||||
int iNumber; // numer kolejny obiektu
|
||||
|
||||
TUpdate yUpdate; // metoda TDynamicObject aktualizująca animację
|
||||
/*
|
||||
void Parovoz(); // wykonanie obliczeń animacji
|
||||
*/
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
enum class announcement_t : int {
|
||||
idle = 0,
|
||||
approaching,
|
||||
current,
|
||||
next,
|
||||
destination,
|
||||
chime,
|
||||
end
|
||||
};
|
||||
|
||||
// parameters for the material object, as currently used by various simulator models
|
||||
struct material_data {
|
||||
|
||||
int textures_alpha{ 0x30300030 }; // maska przezroczystości tekstur. default: tekstury wymienne nie mają przezroczystości
|
||||
material_handle replacable_skins[ 5 ] = { null_handle, null_handle, null_handle, null_handle, null_handle }; // McZapkie:zmienialne nadwozie
|
||||
int multi_textures{ 0 }; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna
|
||||
|
||||
// assigns specified texture or a group of textures to replacable texture slots
|
||||
void assign( std::string const &Replacableskin );
|
||||
};
|
||||
|
||||
class TDynamicObject { // klasa pojazdu
|
||||
|
||||
friend opengl_renderer;
|
||||
friend opengl33_renderer;
|
||||
|
||||
public:
|
||||
static bool bDynamicRemove; // moved from ground
|
||||
|
||||
//private: // położenie pojazdu w świecie oraz parametry ruchu
|
||||
Math3D::vector3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu
|
||||
Math3D::vector3 vCoulpler[ 2 ]; // współrzędne sprzęgów do liczenia zderzeń czołowych
|
||||
Math3D::vector3 vUp, vFront, vLeft; // wektory jednostkowe ustawienia pojazdu
|
||||
int iDirection; // kierunek pojazdu względem czoła składu (1=zgodny,0=przeciwny)
|
||||
TTrackShape ts; // parametry toru przekazywane do fizyki
|
||||
TTrackParam tp; // parametry toru przekazywane do fizyki
|
||||
TTrackFollower Axle0; // oś z przodu (od sprzęgu 0)
|
||||
TTrackFollower Axle1; // oś z tyłu (od sprzęgu 1)
|
||||
int iAxleFirst; // numer pierwszej osi w kierunku ruchu (oś wiążąca pojazd z torem i wyzwalająca eventy)
|
||||
float fAxleDist; // rozstaw wózków albo osi do liczenia proporcji zacienienia
|
||||
Math3D::vector3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!!
|
||||
TDynamicObject * ABuFindNearestObject(glm::vec3 pos, TTrack *Track, TDynamicObject *MyPointer, int &CouplNr );
|
||||
|
||||
glm::dvec3 m_future_movement;
|
||||
glm::dvec3 m_future_wheels_angle;
|
||||
|
||||
public:
|
||||
// parametry położenia pojazdu dostępne publicznie
|
||||
std::string asTrack; // nazwa toru początkowego; wywalić?
|
||||
std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)"
|
||||
Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli
|
||||
TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie
|
||||
inline TDynamicObject *NextConnected() { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||
inline TDynamicObject *PrevConnected() { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
inline TDynamicObject *NextConnected() const { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||
inline TDynamicObject *PrevConnected() const { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
inline int NextConnectedNo() const { return MoverParameters->Neighbours[ end::rear ].vehicle_end; }
|
||||
inline int PrevConnectedNo() const { return MoverParameters->Neighbours[ end::front ].vehicle_end; }
|
||||
|
||||
// Dev tools
|
||||
void Reload();
|
||||
|
||||
// double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
||||
|
||||
// modele składowe pojazdu
|
||||
TModel3d *mdModel; // model pudła
|
||||
TModel3d *mdLoad; // model zmiennego ładunku
|
||||
TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h
|
||||
TModel3d *mdLowPolyInt; // ABu 010305: wnetrze lowpoly
|
||||
std::array<TSubModel *, 3> LowPolyIntCabs {}; // pointers to low fidelity version of individual driver cabs
|
||||
bool JointCabs{ false }; // flag for vehicles with multiple virtual 'cabs' sharing location and 3d model(s)
|
||||
std::vector<TModel3d *> mdAttachments; // additional models attached to main body
|
||||
struct destination_data {
|
||||
TSubModel *sign { nullptr }; // submodel mapped with replacable texture -4
|
||||
bool has_light { false }; // the submodel was originally configured with self-illumination attribute
|
||||
material_handle destination { null_handle }; // most recently assigned non-blank destination texture
|
||||
material_handle destination_off { null_handle }; // blank destination sign
|
||||
std::string background; // potential default background texture override
|
||||
std::string script; // potential python script used to generate texture data
|
||||
int update_rate { 0 }; // -1: per stop, 0: none, >0: fps // TBD, TODO: implement?
|
||||
std::string instancing; // potential method to generate more than one texture per timetable
|
||||
std::string parameters; // potential extra parameters supplied by mmd file
|
||||
// methods
|
||||
void deserialize( cParser &Input );
|
||||
private:
|
||||
bool deserialize_mapping( cParser &Input );
|
||||
} DestinationSign;
|
||||
float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
|
||||
float LoadOffset { 0.f };
|
||||
std::unordered_map<std::string, std::string> LoadModelOverrides; // potential overrides of default load visualization models
|
||||
glm::vec3 InteriorLight { 0.9f * 255.f / 255.f, 0.9f * 216.f / 255.f, 0.9f * 176.f / 255.f }; // tungsten light. TODO: allow definition of light type?
|
||||
float InteriorLightLevel { 0.0f }; // current level of interior lighting
|
||||
struct vehicle_section {
|
||||
TSubModel *compartment;
|
||||
TSubModel *load;
|
||||
int load_chunks_visible;
|
||||
float light_level;
|
||||
};
|
||||
std::vector<vehicle_section> Sections; // table of recognized vehicle sections
|
||||
bool SectionLightsActive { false }; // flag indicating whether section lights were set.
|
||||
std::vector<vehicle_section *> SectionLoadOrder; // helper, activation/deactivation load chunk sequence
|
||||
|
||||
private:
|
||||
// zmienne i metody do animacji submodeli; Ra: sprzatam animacje w pojeździe
|
||||
material_data m_materialdata;
|
||||
|
||||
public:
|
||||
inline
|
||||
material_data const
|
||||
*Material() const {
|
||||
return &m_materialdata; }
|
||||
// tymczasowo udostępnione do wyszukiwania drutu
|
||||
std::array<int, ANIM_TYPES> iAnimType{ 0 }; // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
|
||||
private:
|
||||
int iAnimations; // liczba obiektów animujących
|
||||
std::vector<TAnim> pAnimations;
|
||||
TSubModel ** pAnimated; // lista animowanych submodeli (może być ich więcej niż obiektów animujących)
|
||||
double dWheelAngle[3]; // kąty obrotu kół: 0=przednie toczne, 1=napędzające i wiązary, 2=tylne toczne
|
||||
/*
|
||||
void UpdateNone(TAnim *pAnim){}; // animacja pusta (funkcje ustawiania submodeli, gdy blisko kamery)
|
||||
*/
|
||||
void UpdateAxle(TAnim *pAnim); // animacja osi
|
||||
void UpdateDoorTranslate(TAnim *pAnim); // animacja drzwi - przesuw
|
||||
void UpdateDoorRotate(TAnim *pAnim); // animacja drzwi - obrót
|
||||
void UpdateDoorFold(TAnim *pAnim); // animacja drzwi - składanie
|
||||
void UpdateDoorPlug(TAnim *pAnim); // animacja drzwi - odskokowo-przesuwne
|
||||
void UpdatePant(TAnim *pAnim); // animacja pantografu
|
||||
void UpdatePlatformTranslate(TAnim *pAnim); // doorstep animation, shift
|
||||
void UpdatePlatformRotate(TAnim *pAnim); // doorstep animation, rotate
|
||||
void UpdateMirror(TAnim *pAnim); // mirror animation
|
||||
void UpdateWiper(TAnim *pAnim); // wiper animation
|
||||
/*
|
||||
void UpdateLeverDouble(TAnim *pAnim); // animacja gałki zależna od double
|
||||
void UpdateLeverFloat(TAnim *pAnim); // animacja gałki zależna od float
|
||||
void UpdateLeverInt(TAnim *pAnim); // animacja gałki zależna od int (wartość)
|
||||
void UpdateLeverEnum(TAnim *pAnim); // animacja gałki zależna od int (lista kątów)
|
||||
*/
|
||||
void toggle_lights(); // switch light levels for registered interior sections
|
||||
private: // Ra: ciąg dalszy animacji, dopiero do ogarnięcia
|
||||
// ABuWozki 060504
|
||||
Math3D::vector3 bogieRot[2]; // Obroty wozkow w/m korpusu
|
||||
TSubModel *smBogie[2]; // Wyszukiwanie max 2 wozkow
|
||||
TSubModel *smWahacze[4]; // wahacze (np. nogi, dźwignia w drezynie)
|
||||
TSubModel *smBrakeMode; // Ra 15-01: nastawa hamulca też
|
||||
TSubModel *smLoadMode; // Ra 15-01: nastawa próżny/ładowny
|
||||
double fWahaczeAmp;
|
||||
// Winger 160204 - pantografy
|
||||
double pantspeedfactor;
|
||||
// animacje typu przesuw
|
||||
TSubModel *smBuforLewy[2];
|
||||
TSubModel *smBuforPrawy[2];
|
||||
TAnimValveGear *pValveGear;
|
||||
Math3D::vector3 vFloor; // podłoga dla ładunku
|
||||
public:
|
||||
TAnim *pants; // indeks obiektu animującego dla pantografu 0
|
||||
TAnim *wipers; // wycieraczki
|
||||
std::vector<double> wiperOutTimer = std::vector<double>(8, 0.0);
|
||||
std::vector<double> wiperParkTimer = std::vector<double>(8, 0.0);
|
||||
std::vector<int> workingSwitchPos = std::vector<int>(8, 0); // working switch position (to not break wipers when switching modes)
|
||||
std::vector<double> dWiperPos; // timing na osi czasu animacji wycieraczki
|
||||
std::vector<bool> wiperDirection = std::vector<bool>(8, false); // false - return direction; true - out direction
|
||||
std::vector<bool> wiper_playSoundFromStart = std::vector<bool>(8, false);
|
||||
std::vector<bool> wiper_playSoundToStart = std::vector<bool>(8, false);
|
||||
double NoVoltTime; // czas od utraty zasilania
|
||||
double dMirrorMoveL{ 0.0 };
|
||||
double dMirrorMoveR{ 0.0 };
|
||||
TSubModel *smBrakeSet; // nastawa hamulca (wajcha)
|
||||
TSubModel *smLoadSet; // nastawa ładunku (wajcha)
|
||||
TSubModel *smWiper; // wycieraczka (poniekąd też wajcha)
|
||||
// Ra: koneic animacji do ogarnięcia
|
||||
|
||||
//private:
|
||||
// types
|
||||
struct exchange_data {
|
||||
float unload_count { 0.f }; // amount to unload
|
||||
float load_count { 0.f }; // amount to load
|
||||
int platforms { 0 }; // platforms which may take part in the exchange
|
||||
float time { 0.f }; // time spent on the operation
|
||||
};
|
||||
|
||||
struct coupleradapter_data {
|
||||
glm::vec2 position; // adapter placement; offset from vehicle end and height
|
||||
std::string model; // 3d model of the adapter
|
||||
};
|
||||
|
||||
struct coupler_sounds {
|
||||
// TBD: change to an array with index-based access for easier initialization?
|
||||
sound_source attach_coupler { sound_placement::external };
|
||||
sound_source attach_brakehose { sound_placement::external };
|
||||
sound_source attach_mainhose { sound_placement::external };
|
||||
sound_source attach_control { sound_placement::external };
|
||||
sound_source attach_gangway { sound_placement::external };
|
||||
sound_source attach_heating { sound_placement::external };
|
||||
sound_source detach_coupler { sound_placement::external };
|
||||
sound_source detach_brakehose { sound_placement::external };
|
||||
sound_source detach_mainhose { sound_placement::external };
|
||||
sound_source detach_control { sound_placement::external };
|
||||
sound_source detach_gangway { sound_placement::external };
|
||||
sound_source detach_heating { sound_placement::external };
|
||||
sound_source dsbCouplerStretch { sound_placement::external }; // moved from cab
|
||||
sound_source dsbCouplerStretch_loud { sound_placement::external };
|
||||
sound_source dsbBufferClamp { sound_placement::external }; // moved from cab
|
||||
sound_source dsbBufferClamp_loud { sound_placement::external };
|
||||
sound_source dsbAdapterAttach { sound_placement::external };
|
||||
sound_source dsbAdapterRemove { sound_placement::external };
|
||||
};
|
||||
|
||||
struct pantograph_sounds {
|
||||
// TODO: split pantograph sound into one for contact of arm with the wire, and electric arc sound
|
||||
sound_source sPantUp { sound_placement::external };
|
||||
sound_source sPantDown { sound_placement::external };
|
||||
};
|
||||
|
||||
struct door_sounds {
|
||||
sound_source rsDoorOpen { sound_placement::general }; // Ra: przeniesione z kabiny
|
||||
sound_source rsDoorClose { sound_placement::general };
|
||||
sound_source lock { sound_placement::general };
|
||||
sound_source unlock { sound_placement::general };
|
||||
sound_source step_open { sound_placement::general };
|
||||
sound_source step_close { sound_placement::general };
|
||||
sound_source permit_granted { sound_placement::general };
|
||||
side placement {};
|
||||
};
|
||||
|
||||
struct exchange_sounds {
|
||||
sound_source loading { sound_placement::general };
|
||||
sound_source unloading { sound_placement::general };
|
||||
};
|
||||
|
||||
struct axle_sounds {
|
||||
double distance; // distance to rail joint
|
||||
double offset; // axle offset from centre of the vehicle
|
||||
sound_source clatter; // clatter emitter
|
||||
};
|
||||
|
||||
struct powertrain_sounds {
|
||||
sound_source inverter { sound_placement::engine };
|
||||
std::vector<sound_source> motorblowers;
|
||||
std::vector<sound_source> motors; // generic traction motor sounds
|
||||
std::vector<sound_source> acmotors; // inverter-specific traction motor sounds
|
||||
// bool dcmotors { true }; // traction dc motor(s)
|
||||
double motor_volume { 0.0 }; // MC: pomocnicze zeby gladziej silnik buczal
|
||||
float motor_momentum { 0.f }; // recent change in motor revolutions
|
||||
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 linebreaker_close { sound_placement::engine };
|
||||
sound_source linebreaker_open { sound_placement::engine };
|
||||
sound_source rsWentylator { sound_placement::engine }; // McZapkie-030302
|
||||
sound_source engine { sound_placement::engine }; // generally diesel engine
|
||||
sound_source fake_engine { sound_placement::engine };
|
||||
sound_source engine_ignition { sound_placement::engine }; // moved from cab
|
||||
sound_source engine_shutdown { sound_placement::engine };
|
||||
bool engine_state_last { false }; // helper, cached previous state of the engine
|
||||
double engine_volume { 0.0 }; // MC: pomocnicze zeby gladziej silnik buczal
|
||||
sound_source engine_revving { sound_placement::engine }; // youBy
|
||||
float engine_revs_last { -1.f }; // helper, cached rpm of the engine
|
||||
float engine_revs_change { 0.f }; // recent change in engine revolutions
|
||||
sound_source engine_turbo { sound_placement::engine };
|
||||
double engine_turbo_pitch { 1.0 };
|
||||
sound_source oil_pump { sound_placement::engine };
|
||||
sound_source fuel_pump { sound_placement::engine };
|
||||
sound_source water_pump { sound_placement::engine };
|
||||
sound_source water_heater { sound_placement::engine };
|
||||
sound_source radiator_fan { sound_placement::engine };
|
||||
sound_source radiator_fan_aux { sound_placement::engine };
|
||||
sound_source transmission { sound_placement::engine };
|
||||
sound_source rsEngageSlippery { sound_placement::engine }; // moved from cab
|
||||
sound_source retarder { sound_placement::engine };
|
||||
|
||||
void position( glm::vec3 const Location );
|
||||
void render( TMoverParameters const &Vehicle, double const Deltatime );
|
||||
};
|
||||
// single source per door (pair) on the centreline
|
||||
struct doorspeaker_sounds {
|
||||
glm::vec3 offset;
|
||||
sound_source departure_signal;
|
||||
};
|
||||
// single source per vehicle
|
||||
struct pasystem_sounds {
|
||||
std::array<sound_source, static_cast<int>( announcement_t::end )> announcements;
|
||||
std::optional< std::array<float, 6> > soundproofing;
|
||||
sound_source announcement;
|
||||
std::deque<sound_source> announcement_queue; // fifo queue
|
||||
};
|
||||
struct springbrake_sounds {
|
||||
sound_source activate { sound_placement::external };
|
||||
sound_source release { sound_placement::external };
|
||||
bool state { false };
|
||||
};
|
||||
|
||||
|
||||
// methods
|
||||
void ABuLittleUpdate(double ObjSqrDist);
|
||||
void ABuBogies();
|
||||
void ABuModelRoll();
|
||||
void TurnOff();
|
||||
// update state of load exchange operation
|
||||
void update_exchange( double const Deltatime );
|
||||
|
||||
// members
|
||||
AirCoupler btCoupler1; // sprzegi
|
||||
AirCoupler btCoupler2;
|
||||
std::array<TModel3d *, 2> m_coupleradapters = { nullptr, nullptr };
|
||||
AirCoupler btCPneumatic1; // sprzegi powietrzne //yB - zmienione z Button na AirCoupler - krzyzyki
|
||||
AirCoupler btCPneumatic2;
|
||||
AirCoupler btCPneumatic1r; // ABu: to zeby nie bylo problemow przy laczeniu wagonow,
|
||||
AirCoupler btCPneumatic2r; // jesli beda polaczone sprzegami 1<->1 lub 0<->0
|
||||
AirCoupler btPneumatic1; // ABu: sprzegi powietrzne zolte
|
||||
AirCoupler btPneumatic2;
|
||||
AirCoupler btPneumatic1r; // ABu: analogicznie jak 4 linijki wyzej
|
||||
AirCoupler btPneumatic2r;
|
||||
|
||||
TButton btCCtrl1; // sprzegi sterowania
|
||||
TButton btCCtrl2;
|
||||
TButton btCPass1; // mostki przejsciowe
|
||||
TButton btCPass2;
|
||||
char cp1, sp1, cp2, sp2; // ustawienia węży
|
||||
|
||||
TButton m_endsignal12; // sygnalu konca pociagu
|
||||
TButton m_endsignal13;
|
||||
TButton m_endsignal22;
|
||||
TButton m_endsignal23;
|
||||
TButton m_endsignals1; // zeby bylo kompatybilne ze starymi modelami...
|
||||
TButton m_endsignals2;
|
||||
TButton m_endtab1; // sygnaly konca pociagu (blachy)
|
||||
TButton m_endtab2;
|
||||
AirCoupler m_headlamp11; // oswietlenie czolowe - przod
|
||||
AirCoupler m_headlamp12;
|
||||
AirCoupler m_headlamp13;
|
||||
AirCoupler m_highbeam12; // dlugie
|
||||
AirCoupler m_highbeam13;
|
||||
AirCoupler m_headlamp21; // oswietlenie czolowe - tyl
|
||||
AirCoupler m_headlamp22;
|
||||
AirCoupler m_headlamp23;
|
||||
AirCoupler m_highbeam22;
|
||||
AirCoupler m_highbeam23;
|
||||
AirCoupler m_headsignal12;
|
||||
AirCoupler m_headsignal13;
|
||||
AirCoupler m_headsignal22;
|
||||
AirCoupler m_headsignal23;
|
||||
TButton btExteriorOnly;
|
||||
TButton btMechanik1;
|
||||
TButton btMechanik2;
|
||||
TButton btShutters1; // cooling shutters for primary water circuit
|
||||
TButton btShutters2; // cooling shutters for auxiliary water circuit
|
||||
|
||||
double dRailLength { 0.0 };
|
||||
std::vector<axle_sounds> m_axlesounds;
|
||||
// engine sounds
|
||||
powertrain_sounds m_powertrainsounds;
|
||||
sound_source sDirectionRelayD { sound_placement::engine }; // przekaznik kierunkowy do przodu
|
||||
sound_source sDirectionRelayN { sound_placement::engine }; // przekaznik kierunkowy neutral
|
||||
sound_source sDirectionRelayR { sound_placement::engine }; // przekaznik kierunkowy wstecz
|
||||
sound_source sConverter { sound_placement::engine };
|
||||
sound_source sBRVent {sound_placement::engine};
|
||||
sound_source sCompressor { sound_placement::engine }; // NBMX wrzesien 2003
|
||||
sound_source sCompressorIdle { sound_placement::engine };
|
||||
sound_source sSmallCompressor { sound_placement::engine };
|
||||
sound_source sHeater { sound_placement::engine };
|
||||
sound_source m_batterysound { sound_placement::engine };
|
||||
// braking sounds
|
||||
sound_source dsbPneumaticRelay { sound_placement::external };
|
||||
sound_source rsBrake { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
||||
sound_source sBrakeAcc { sound_placement::external };
|
||||
bool bBrakeAcc { false };
|
||||
sound_source rsPisk { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // McZapkie-260302
|
||||
sound_source rsUnbrake { sound_placement::external }; // yB - odglos luzowania
|
||||
sound_source m_brakecylinderpistonadvance { sound_placement::external };
|
||||
sound_source m_brakecylinderpistonrecede { sound_placement::external };
|
||||
float m_lastbrakepressure { -1.f }; // helper, cached level of pressure in the brake cylinder
|
||||
float m_brakepressurechange { 0.f }; // recent change of pressure in the brake cylinder
|
||||
sound_source m_epbrakepressureincrease{ sound_placement::external };
|
||||
sound_source m_epbrakepressuredecrease{ sound_placement::external };
|
||||
float m_lastepbrakepressure{ -1.f }; // helper, cached level of pressure in the brake cylinder
|
||||
float m_epbrakepressurechange{ 0.f }; // recent change of pressure in the brake cylinder
|
||||
float m_epbrakepressurechangeinctimer{ 0.f }; // last time of change of pressure in the brake cylinder - increase
|
||||
float m_epbrakepressurechangedectimer{ 0.f }; // last time of change of pressure in the brake cylinder - decrease
|
||||
sound_source m_emergencybrake { sound_placement::engine };
|
||||
double m_emergencybrakeflow{ 0.f };
|
||||
sound_source sReleaser { sound_placement::external };
|
||||
springbrake_sounds m_springbrakesounds;
|
||||
sound_source rsSlippery { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
||||
sound_source sSand { sound_placement::external };
|
||||
sound_source sWiperToPark { sound_placement::internal };
|
||||
bool sWiperToParkPlayed{false};
|
||||
sound_source sWiperFromPark { sound_placement::internal };
|
||||
bool sWiperFromParkPlayed{false};
|
||||
|
||||
// moving part and other external sounds
|
||||
sound_source m_startjolt { sound_placement::general }; // movement start jolt, played once on initial acceleration at slow enough speed
|
||||
bool m_startjoltplayed { false };
|
||||
std::array<coupler_sounds, 2> m_couplersounds; // always front and rear
|
||||
std::vector<pantograph_sounds> m_pantographsounds; // typically 2 but can be less (or more?)
|
||||
std::vector<door_sounds> m_doorsounds; // can expect symmetrical arrangement, but don't count on it
|
||||
bool m_doorlocks { false }; // sound helper, current state of door locks
|
||||
sound_source sHorn1 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
sound_source sHorn2 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
sound_source sHorn3 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
#ifdef EU07_SOUND_BOGIESOUNDS
|
||||
std::vector<sound_source> m_bogiesounds; // TBD, TODO: wrapper for all bogie-related sounds (noise, brakes, squeal etc)
|
||||
#else
|
||||
sound_source m_outernoise { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
#endif
|
||||
sound_source m_wheelflat { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||
sound_source rscurve { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
|
||||
sound_source rsDerailment { sound_placement::external, 2 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // McZapkie-051202
|
||||
|
||||
exchange_data m_exchange; // state of active load exchange procedure, if any
|
||||
exchange_sounds m_exchangesounds; // sounds associated with the load exchange
|
||||
|
||||
std::vector<doorspeaker_sounds> m_doorspeakers;
|
||||
pasystem_sounds m_pasystem;
|
||||
|
||||
std::array<
|
||||
std::array<float, 6> // listener: rear cab, engine, front cab, window, attached camera, free camera
|
||||
, 5> m_soundproofing = {{
|
||||
{{ EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_STRONG }}, // internal sounds
|
||||
{{ EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_SOME }}, // engine sounds
|
||||
{{ EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_NONE }}, // external sound
|
||||
{{ EU07_SOUNDPROOFING_VERYSTRONG, EU07_SOUNDPROOFING_VERYSTRONG, EU07_SOUNDPROOFING_VERYSTRONG, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_NONE }}, // external ambient sound
|
||||
{{ EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE }}, // custom sounds
|
||||
}};
|
||||
|
||||
coupleradapter_data m_coupleradapter;
|
||||
|
||||
bool renderme; // yB - czy renderowac
|
||||
float ModCamRot;
|
||||
int iInventory[ 2 ] { 0, 0 }; // flagi bitowe posiadanych submodeli (np. świateł)
|
||||
bool btnOn; // ABu: czy byly uzywane buttony, jesli tak, to po renderingu wylacz
|
||||
// bo ten sam model moze byc jeszcze wykorzystany przez inny obiekt!
|
||||
|
||||
public:
|
||||
int iHornWarning; // numer syreny do użycia po otrzymaniu sygnału do jazdy
|
||||
bool bEnabled; // Ra: wyjechał na portal i ma być usunięty
|
||||
protected:
|
||||
int iNumAxles; // ilość osi
|
||||
std::string asModel;
|
||||
|
||||
private:
|
||||
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler ) const;
|
||||
void ABuCheckMyTrack();
|
||||
|
||||
std::string rTypeName; // nazwa typu pojazdu
|
||||
std::string rReplacableSkin; // nazwa tekstury pojazdu
|
||||
|
||||
public:
|
||||
bool DimHeadlights{ false }; // status of the headlight dimming toggle. NOTE: single toggle for all lights is a simplification. TODO: separate per-light switches
|
||||
bool HighBeamLights { false }; // status of the highbeam toggle
|
||||
bool HeadlightsAoff{false}; // wygaszone swiatelki A
|
||||
bool HeadlightsBoff{false}; // wygaszone swiatelki B
|
||||
// checks whether there's unbroken connection of specified type to specified vehicle
|
||||
bool is_connected( TDynamicObject const *Vehicle, coupling const Coupling = coupling::coupler ) const;
|
||||
TDynamicObject * PrevAny() const;
|
||||
TDynamicObject * Prev(int C = -1) const;
|
||||
TDynamicObject * Next(int C = -1) const;
|
||||
void SetdMoveLen(double dMoveLen) {
|
||||
MoverParameters->dMoveLen = dMoveLen; }
|
||||
void ResetdMoveLen() {
|
||||
MoverParameters->dMoveLen = 0; }
|
||||
double GetdMoveLen() {
|
||||
return MoverParameters->dMoveLen; }
|
||||
|
||||
int GetPneumatic(bool front, bool red);
|
||||
void SetPneumatic(bool front, bool red);
|
||||
std::string asName;
|
||||
const std::string &name() const {
|
||||
return asName; }
|
||||
std::string asBaseDir;
|
||||
|
||||
// std::ofstream PneuLogFile; //zapis parametrow pneumatycznych
|
||||
// youBy - dym
|
||||
// TSmoke Smog;
|
||||
// float EmR;
|
||||
// vector3 smokeoffset;
|
||||
|
||||
TDynamicObject * ABuScanNearestObject(glm::vec3 pos, TTrack *Track, double ScanDir, double ScanDist,
|
||||
int &CouplNr);
|
||||
TDynamicObject * GetFirstDynamic(int cpl_type, int cf = 1);
|
||||
void ABuSetModelShake( Math3D::vector3 mShake);
|
||||
|
||||
// McZapkie-010302
|
||||
TController *Mechanik;
|
||||
TController *ctOwner; // wskażnik na obiekt zarządzający składem
|
||||
bool MechInside;
|
||||
// McZapkie-270202
|
||||
bool Controller;
|
||||
bool bDisplayCab; // czy wyswietlac kabine w train.cpp
|
||||
int iCabs; // maski bitowe modeli kabin
|
||||
TTrack *MyTrack; // McZapkie-030303: tor na ktorym stoi, ABu
|
||||
int iOverheadMask; // maska przydzielana przez AI pojazdom posiadającym pantograf, aby wymuszały jazdę bezprądową
|
||||
TTractionParam tmpTraction;
|
||||
double fAdjustment; // korekcja - docelowo przenieść do TrkFoll.cpp wraz z odległością od poprzedniego
|
||||
|
||||
TTrack *initial_track = nullptr;
|
||||
|
||||
TDynamicObject();
|
||||
~TDynamicObject();
|
||||
void place_on_track(TTrack *Track, double fDist, bool Reversed);
|
||||
// zwraca długość pojazdu albo 0, jeśli błąd
|
||||
double Init(
|
||||
std::string Name, std::string BaseDir, std::string asReplacableSkin, std::string Type_Name,
|
||||
TTrack *Track, double fDist, std::string DriverType, double fVel, std::string TrainName,
|
||||
float Load, std::string LoadType, bool Reversed, std::string);
|
||||
int init_sections( TModel3d const *Model, std::string const &Nameprefix, bool const Overrideselfillum );
|
||||
bool init_destination( TModel3d *Model );
|
||||
void create_controller( std::string const Type, bool const Trainset );
|
||||
void AttachNext(TDynamicObject *Object, int iType = 1);
|
||||
bool UpdateForce(double dt);
|
||||
// initiates load change by specified amounts, with a platform on specified side
|
||||
void LoadExchange( int const Disembark, int const Embark, int const Platforms );
|
||||
// calculates time needed to complete current load change, using specified platforms
|
||||
float LoadExchangeTime( int const Platforms );
|
||||
// calculates time needed to complete current load change, using previously specified platforms
|
||||
float LoadExchangeTime() const;
|
||||
// calculates current load exchange factor, where 1 = nominal rate, higher = faster
|
||||
float LoadExchangeSpeed() const; // TODO: make private when cleaning up
|
||||
void LoadUpdate();
|
||||
void update_load_sections();
|
||||
void update_load_visibility();
|
||||
void update_load_offset();
|
||||
void shuffle_load_order();
|
||||
void update_destinations();
|
||||
bool Update(double dt, double dt1);
|
||||
bool FastUpdate(double dt);
|
||||
void Move(double fDistance);
|
||||
void FastMove(double fDistance);
|
||||
void RenderSounds();
|
||||
inline Math3D::vector3 GetPosition() const {
|
||||
return vPosition; };
|
||||
// converts location from vehicle coordinates frame to world frame
|
||||
inline Math3D::vector3 GetWorldPosition( Math3D::vector3 const &Location ) const {
|
||||
return vPosition + mMatrix * Location; }
|
||||
// pobranie współrzędnych czoła
|
||||
inline Math3D::vector3 HeadPosition() const {
|
||||
return vCoulpler[iDirection ^ 1]; };
|
||||
// pobranie współrzędnych tyłu
|
||||
inline Math3D::vector3 RearPosition() const {
|
||||
return vCoulpler[iDirection]; };
|
||||
inline Math3D::vector3 CouplerPosition( end const End ) const {
|
||||
return vCoulpler[ End ]; }
|
||||
inline Math3D::vector3 AxlePositionGet() {
|
||||
return iAxleFirst ?
|
||||
Axle1.pPosition :
|
||||
Axle0.pPosition; };
|
||||
inline double Roll() {
|
||||
return ( ( Axle1.GetRoll() + Axle0.GetRoll() ) ); }
|
||||
/*
|
||||
// TODO: check if scanning takes into account direction when selecting axle
|
||||
// if it does, replace the version above
|
||||
// if it doesn't, fix it so it does
|
||||
inline Math3D::vector3 AxlePositionGet() {
|
||||
return (
|
||||
iDirection ?
|
||||
( iAxleFirst ? Axle1.pPosition : Axle0.pPosition ) :
|
||||
( iAxleFirst ? Axle0.pPosition : Axle1.pPosition ) ); }
|
||||
*/
|
||||
inline Math3D::vector3 VectorFront() const {
|
||||
return vFront; };
|
||||
inline Math3D::vector3 VectorUp() const {
|
||||
return vUp; };
|
||||
inline Math3D::vector3 VectorLeft() const {
|
||||
return vLeft; };
|
||||
inline double const * Matrix() const {
|
||||
return mMatrix.readArray(); };
|
||||
inline double * Matrix() {
|
||||
return mMatrix.getArray(); };
|
||||
inline double GetVelocity() const {
|
||||
return MoverParameters->Vel; };
|
||||
inline double GetLength() const {
|
||||
return MoverParameters->Dim.L; };
|
||||
inline double GetWidth() const {
|
||||
return MoverParameters->Dim.W; };
|
||||
double radius() const;
|
||||
// calculates distance between event-starting axle and front of the vehicle
|
||||
double tracing_offset() const;
|
||||
inline TTrack * GetTrack() {
|
||||
return (iAxleFirst ?
|
||||
Axle1.GetTrack() :
|
||||
Axle0.GetTrack()); };
|
||||
|
||||
// McZapkie-260202
|
||||
void LoadMMediaFile(std::string const &TypeName, std::string const &ReplacableSkin);
|
||||
TModel3d *LoadMMediaFile_mdload( std::string const &Name ) const;
|
||||
|
||||
inline double ABuGetDirection() const { // ABu.
|
||||
return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection()); };
|
||||
// zwraca kierunek pojazdu na torze z aktywną osą
|
||||
inline double RaDirectionGet() const {
|
||||
return iAxleFirst ?
|
||||
Axle1.GetDirection() :
|
||||
Axle0.GetDirection(); };
|
||||
// zwraca przesunięcie wózka względem Point1 toru z aktywną osią
|
||||
inline double RaTranslationGet() const {
|
||||
return iAxleFirst ?
|
||||
Axle1.GetTranslation() :
|
||||
Axle0.GetTranslation(); };
|
||||
// zwraca tor z aktywną osią
|
||||
inline TTrack const * RaTrackGet() const {
|
||||
return iAxleFirst ?
|
||||
Axle1.GetTrack() :
|
||||
Axle0.GetTrack(); };
|
||||
|
||||
void couple( int const Side );
|
||||
int uncouple( int const Side );
|
||||
bool attach_coupler_adapter( int const Side, bool const Enforce = false );
|
||||
bool remove_coupler_adapter( int const Side );
|
||||
void RadioStop();
|
||||
void Damage(char flag);
|
||||
void pants_up();
|
||||
void SetLights();
|
||||
void SetLightDimmings();
|
||||
void RaLightsSet(int head, int rear);
|
||||
int LightList( end const Side ) const { return iInventory[ Side ]; }
|
||||
bool has_signal_pc1_on() const;
|
||||
bool has_signal_pc2_on() const;
|
||||
bool has_signal_pc5_on() const;
|
||||
bool has_signal_on( int const Side, int const Pattern ) const;
|
||||
void set_cab_lights( int const Cab, float const Level );
|
||||
TDynamicObject * FirstFind(int &coupler_nr, int cf = 1);
|
||||
float GetEPP(); // wyliczanie sredniego cisnienia w PG
|
||||
int DirectionSet(int d); // ustawienie kierunku w składzie
|
||||
// odczyt kierunku w składzie; returns 1 if true, -1 otherwise
|
||||
int DirectionGet() const {
|
||||
return iDirection + iDirection - 1; };
|
||||
int DettachStatus(int dir);
|
||||
int Dettach(int dir);
|
||||
TDynamicObject * Neighbour(int &dir);
|
||||
// updates potential collision sources
|
||||
void update_neighbours();
|
||||
// locates potential collision source within specified range, scanning its route in specified direction
|
||||
auto find_vehicle( int const Direction, double const Range ) const -> std::tuple<TDynamicObject *, int, double, bool>;
|
||||
// locates potential vehicle connected with specific coupling type and satisfying supplied predicate
|
||||
template <typename Predicate_>
|
||||
auto find_vehicle( coupling const Coupling, Predicate_ const Predicate ) -> TDynamicObject *;
|
||||
TDynamicObject * FindPowered();
|
||||
TDynamicObject * FindPantographCarrier();
|
||||
template <typename UnaryFunction_>
|
||||
void for_each( coupling const Coupling, UnaryFunction_ const Function );
|
||||
void ParamSet(int what, int into);
|
||||
// zapytanie do AI, po którym segmencie skrzyżowania jechać
|
||||
int RouteWish(TTrack *tr);
|
||||
void DestinationSet(std::string to, std::string numer);
|
||||
material_handle DestinationFind( std::string Destination );
|
||||
void OverheadTrack(float o);
|
||||
glm::dvec3 get_future_movement() const;
|
||||
void move_set(double distance);
|
||||
// playes specified announcement, potentially preceding it with a chime
|
||||
void announce( announcement_t const Announcement, bool const Chime = true );
|
||||
// returns soundproofing for specified sound type and listener location
|
||||
float soundproofing( int const Placement, int const Listener ) const {
|
||||
return m_soundproofing[ Placement - 1 ][ Listener + 1 ]; }
|
||||
|
||||
double MED[9][8]; // lista zmiennych do debugowania hamulca ED
|
||||
static std::string const MED_labels[ 8 ];
|
||||
std::ofstream MEDLogFile; // zapis parametrów hamowania
|
||||
double MEDLogTime = 0;
|
||||
double MEDLogInactiveTime = 0;
|
||||
int MEDLogCount = 0;
|
||||
double MED_oldFED = 0;
|
||||
|
||||
// vehicle shaking calculations
|
||||
// TBD, TODO: make an object out of it
|
||||
public:
|
||||
// methods
|
||||
void update_shake( double const Timedelta );
|
||||
std::pair<double, double> shake_angles() const;
|
||||
// members
|
||||
struct baseshake_config {
|
||||
Math3D::vector3 angle_scale { 0.05, 0.0, 0.1 }; // roll, yaw, pitch
|
||||
Math3D::vector3 jolt_scale { 0.2, 0.2, 0.1 };
|
||||
double jolt_limit { 2.0f };
|
||||
} BaseShake;
|
||||
struct engineshake_config {
|
||||
float scale { 2.f };
|
||||
float fadein_offset { 1.5f }; // 90 rpm
|
||||
float fadein_factor { 0.3f };
|
||||
float fadeout_offset { 10.f }; // 600 rpm
|
||||
float fadeout_factor { 0.5f };
|
||||
} EngineShake;
|
||||
struct huntingshake_config {
|
||||
float scale { 1.f };
|
||||
float frequency { 1.f };
|
||||
float fadein_begin { 0.f }; // effect start speed in km/h
|
||||
float fadein_end { 0.f }; // full effect speed in km/h
|
||||
} HuntingShake;
|
||||
float HuntingAngle { 0.f }; // crude approximation of hunting oscillation; current angle of sine wave
|
||||
bool IsHunting { false };
|
||||
TSpring ShakeSpring;
|
||||
struct shake_state {
|
||||
Math3D::vector3 velocity {}; // current shaking vector
|
||||
Math3D::vector3 offset {}; // overall shake-driven offset from base position
|
||||
} ShakeState;
|
||||
|
||||
Math3D::vector3 modelShake;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class vehicle_table : public basic_table<TDynamicObject> {
|
||||
|
||||
public:
|
||||
// legacy method, calculates changes in simulation state over specified time
|
||||
void
|
||||
update( double dt, int iter );
|
||||
// legacy method, checks for presence and height of traction wire for specified vehicle
|
||||
void
|
||||
update_traction( TDynamicObject *Vehicle );
|
||||
// legacy method, sends list of vehicles over network
|
||||
void
|
||||
DynamicList( bool const Onlycontrolled = false ) const;
|
||||
|
||||
private:
|
||||
// maintenance; removes from tracks consists with vehicles marked as disabled
|
||||
bool
|
||||
erase_disabled();
|
||||
};
|
||||
|
||||
|
||||
template <typename Predicate_>
|
||||
auto
|
||||
TDynamicObject::find_vehicle( coupling const Coupling, Predicate_ const Predicate ) -> TDynamicObject * {
|
||||
|
||||
if( Predicate( this ) ) {
|
||||
return this; }
|
||||
// try first to look towards the rear
|
||||
auto *vehicle { this };
|
||||
while( ( vehicle = vehicle->Next( Coupling ) ) != nullptr ) {
|
||||
if( Predicate( vehicle ) ) {
|
||||
return vehicle; } }
|
||||
// if we didn't yet find a suitable vehicle try in the other direction
|
||||
vehicle = this;
|
||||
while( ( vehicle = vehicle->Prev( Coupling ) ) != nullptr ) {
|
||||
if( Predicate( vehicle ) ) {
|
||||
return vehicle; } }
|
||||
// if we still don't have a match give up
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename UnaryFunction_>
|
||||
void
|
||||
TDynamicObject::for_each( coupling const Coupling, UnaryFunction_ const Function ) {
|
||||
|
||||
Function( this );
|
||||
// walk first towards the rear
|
||||
auto *vehicle { this };
|
||||
while( ( vehicle = vehicle->Next( Coupling ) ) != nullptr ) {
|
||||
Function( vehicle ); }
|
||||
// then towards the front
|
||||
vehicle = this;
|
||||
while( ( vehicle = vehicle->Prev( Coupling ) ) != nullptr ) {
|
||||
Function( vehicle ); }
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
531
vehicle/Gauge.cpp
Normal file
531
vehicle/Gauge.cpp
Normal file
@@ -0,0 +1,531 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak
|
||||
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Gauge.h"
|
||||
#include "parser.h"
|
||||
#include "Model3d.h"
|
||||
#include "DynObj.h"
|
||||
#include "Timer.h"
|
||||
#include "Logs.h"
|
||||
#include "renderer.h"
|
||||
|
||||
TGauge::TGauge( sound_source const &Soundtemplate ) :
|
||||
m_soundtemplate( Soundtemplate )
|
||||
{
|
||||
m_soundfxincrease = m_soundtemplate;
|
||||
m_soundfxdecrease = m_soundtemplate;
|
||||
m_soundfxon = m_soundtemplate;
|
||||
m_soundfxoff = m_soundtemplate;
|
||||
}
|
||||
|
||||
void TGauge::Init(TSubModel *Submodel, TSubModel *Submodelon, TGaugeAnimation Type, float Scale, float Offset, float Friction, float Value, float const Endvalue, float const Endscale, bool const Interpolatescale )
|
||||
{ // ustawienie parametrów animacji submodelu
|
||||
SubModel = Submodel;
|
||||
SubModelOn = Submodelon;
|
||||
m_value = Value;
|
||||
m_animation = Type;
|
||||
m_scale = Scale;
|
||||
m_offset = Offset;
|
||||
m_friction = Friction;
|
||||
m_interpolatescale = Interpolatescale;
|
||||
m_endvalue = Endvalue;
|
||||
m_endscale = Endscale;
|
||||
|
||||
if( m_animation == TGaugeAnimation::gt_Digital ) {
|
||||
|
||||
auto *sm { ( SubModel ? SubModel->ChildGet() : nullptr ) };
|
||||
while( sm != nullptr ) {
|
||||
// pętla po submodelach potomnych i obracanie ich o kąt zależy od cyfry w (fValue)
|
||||
if( ( sm->pName.size() )// musi mieć niepustą nazwę
|
||||
&& ( std::isdigit( sm->pName[ 0 ] ) ) ) {
|
||||
sm->WillBeAnimated(); // wyłączenie optymalizacji
|
||||
}
|
||||
sm = sm->NextGet();
|
||||
}
|
||||
// do the same for the active version
|
||||
sm = ( SubModelOn ? SubModelOn->ChildGet() : nullptr );
|
||||
while( sm != nullptr ) {
|
||||
// pętla po submodelach potomnych i obracanie ich o kąt zależy od cyfry w (fValue)
|
||||
if( ( sm->pName.size() )// musi mieć niepustą nazwę
|
||||
&& ( std::isdigit( sm->pName[ 0 ] ) ) ) {
|
||||
sm->WillBeAnimated(); // wyłączenie optymalizacji
|
||||
}
|
||||
sm = sm->NextGet();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// wyłączenie ignowania jedynkowego transformu
|
||||
// a banan może być z optymalizacją?
|
||||
if( SubModel != nullptr ) { SubModel->WillBeAnimated(); }
|
||||
if( SubModelOn != nullptr ) { SubModelOn->WillBeAnimated(); }
|
||||
}
|
||||
// pass submodel location to defined sounds
|
||||
auto const nulloffset { glm::vec3{} };
|
||||
auto const offset { model_offset() };
|
||||
{
|
||||
std::vector<sound_source *> soundfxs = {
|
||||
&m_soundfxincrease,
|
||||
&m_soundfxdecrease,
|
||||
&m_soundfxon,
|
||||
&m_soundfxoff
|
||||
};
|
||||
for( auto *soundfx : soundfxs ) {
|
||||
if( soundfx->offset() == nulloffset ) {
|
||||
soundfx->offset( offset );
|
||||
}
|
||||
}
|
||||
}
|
||||
for( auto &soundfx : m_soundfxvalues ) {
|
||||
if( soundfx.second.offset() == nulloffset ) {
|
||||
soundfx.second.offset( offset );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void TGauge::Load( cParser &Parser, TDynamicObject const *Owner, double const mul ) {
|
||||
|
||||
std::string submodelname, gaugetypename;
|
||||
float scale, endscale, endvalue, offset, friction;
|
||||
endscale = -1;
|
||||
endvalue = -1;
|
||||
bool interpolatescale { false };
|
||||
|
||||
Parser.getTokens();
|
||||
if( Parser.peek() != "{" ) {
|
||||
// old fixed size config
|
||||
Parser >> submodelname;
|
||||
gaugetypename = Parser.getToken<std::string>( true );
|
||||
Parser.getTokens( 3, false );
|
||||
Parser
|
||||
>> scale
|
||||
>> offset
|
||||
>> friction;
|
||||
if( ( gaugetypename == "rotvar" )
|
||||
|| ( gaugetypename == "movvar" ) ) {
|
||||
interpolatescale = true;
|
||||
Parser.getTokens( 2, false );
|
||||
Parser
|
||||
>> endvalue
|
||||
>> endscale;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// new, block type config
|
||||
// TODO: rework the base part into yaml-compatible flow style mapping
|
||||
submodelname = Parser.getToken<std::string>( false );
|
||||
gaugetypename = Parser.getToken<std::string>( true );
|
||||
Parser.getTokens( 3, false );
|
||||
Parser
|
||||
>> scale
|
||||
>> offset
|
||||
>> friction;
|
||||
if( ( gaugetypename == "rotvar" )
|
||||
|| ( gaugetypename == "movvar" ) ) {
|
||||
interpolatescale = true;
|
||||
Parser.getTokens( 2, false );
|
||||
Parser
|
||||
>> endvalue
|
||||
>> endscale;
|
||||
}
|
||||
// new, variable length section
|
||||
{
|
||||
scratch_data scratchpad;
|
||||
while( true == Load_mapping( Parser, scratchpad ) ) {
|
||||
; // all work done by while()
|
||||
}
|
||||
// post-deserialization cleanup
|
||||
// set provided custom soundproofing to assigned sounds (for sounds without their own custom soundproofing)
|
||||
if( scratchpad.soundproofing ) {
|
||||
if( !m_soundfxincrease.soundproofing() ) {
|
||||
m_soundfxincrease.soundproofing() = scratchpad.soundproofing;
|
||||
}
|
||||
if( !m_soundfxdecrease.soundproofing() ) {
|
||||
m_soundfxdecrease.soundproofing() = scratchpad.soundproofing;
|
||||
}
|
||||
if( !m_soundfxon.soundproofing() ) {
|
||||
m_soundfxon.soundproofing() = scratchpad.soundproofing;
|
||||
}
|
||||
if( !m_soundfxoff.soundproofing() ) {
|
||||
m_soundfxoff.soundproofing() = scratchpad.soundproofing;
|
||||
}
|
||||
for( auto &soundfxrecord : m_soundfxvalues ) {
|
||||
if( !soundfxrecord.second.soundproofing() ) {
|
||||
soundfxrecord.second.soundproofing() = scratchpad.soundproofing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind defined sounds with the button owner
|
||||
m_soundfxincrease.owner( Owner );
|
||||
m_soundfxdecrease.owner( Owner );
|
||||
m_soundfxon.owner( Owner );
|
||||
m_soundfxoff.owner( Owner );
|
||||
for( auto &soundfxrecord : m_soundfxvalues ) {
|
||||
soundfxrecord.second.owner( Owner );
|
||||
}
|
||||
|
||||
scale *= mul;
|
||||
if( interpolatescale ) {
|
||||
endscale *= mul;
|
||||
}
|
||||
TSubModel *submodel { nullptr };
|
||||
std::array<TModel3d *, 2> sources { Owner->mdKabina, Owner->mdLowPolyInt };
|
||||
for( auto const *source : sources ) {
|
||||
if( ( source != nullptr )
|
||||
&& ( submodel = source->GetFromName( submodelname ) ) != nullptr ) {
|
||||
// got what we wanted, bail out
|
||||
break;
|
||||
}
|
||||
// there's a possibility the default submodel was named with _off suffix
|
||||
if( ( source != nullptr )
|
||||
&& ( submodel = source->GetFromName( submodelname + "_off" ) ) != nullptr ) {
|
||||
// got what we wanted, bail out
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( submodel == nullptr ) {
|
||||
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model(s) of \"" + Owner->name() + "\"", logtype::model );
|
||||
}
|
||||
// see if we can locate optional submodel for active state, with _on suffix
|
||||
TSubModel *submodelon { nullptr };
|
||||
for( auto const *source : sources ) {
|
||||
if( ( source != nullptr )
|
||||
&& ( submodelon = source->GetFromName( submodelname + "_on" ) ) != nullptr ) {
|
||||
// got what we wanted, bail out
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, TGaugeAnimation> gaugetypes {
|
||||
{ "rot", TGaugeAnimation::gt_Rotate },
|
||||
{ "rotvar", TGaugeAnimation::gt_Rotate },
|
||||
{ "mov", TGaugeAnimation::gt_Move },
|
||||
{ "movvar", TGaugeAnimation::gt_Move },
|
||||
{ "wip", TGaugeAnimation::gt_Wiper },
|
||||
{ "dgt", TGaugeAnimation::gt_Digital }
|
||||
};
|
||||
auto lookup = gaugetypes.find( gaugetypename );
|
||||
auto const type = (
|
||||
lookup != gaugetypes.end() ?
|
||||
lookup->second :
|
||||
TGaugeAnimation::gt_Unknown );
|
||||
|
||||
Init( submodel, submodelon, type, scale, offset, friction, 0, endvalue, endscale, interpolatescale );
|
||||
|
||||
// return md2 != nullptr; // true, gdy podany model zewnętrzny, a w kabinie nie było
|
||||
};
|
||||
|
||||
bool
|
||||
TGauge::Load_mapping( cParser &Input, TGauge::scratch_data &Scratchpad ) {
|
||||
|
||||
// token can be a key or block end
|
||||
auto const key { Input.getToken<std::string>( true, "\n\r\t ,;" ) };
|
||||
if( ( true == key.empty() ) || ( key == "}" ) ) { return false; }
|
||||
// if not block end then the key is followed by assigned value or sub-block
|
||||
if( key == "type:" ) {
|
||||
auto const gaugetype { Input.getToken<std::string>( true, "\n\r\t ,;" ) };
|
||||
m_type = (
|
||||
gaugetype == "push" ? TGaugeType::push :
|
||||
gaugetype == "impulse" ? TGaugeType::push :
|
||||
gaugetype == "return" ? TGaugeType::push :
|
||||
gaugetype == "delayed" ? TGaugeType::push_delayed :
|
||||
gaugetype == "pushtoggle" ? TGaugeType::pushtoggle :
|
||||
gaugetype == "toggle" ? TGaugeType::toggle :
|
||||
TGaugeType::toggle ); // default
|
||||
}
|
||||
else if( key == "soundinc:" ) {
|
||||
m_soundfxincrease.deserialize( Input, sound_type::single );
|
||||
}
|
||||
else if( key == "sounddec:" ) {
|
||||
m_soundfxdecrease.deserialize( Input, sound_type::single );
|
||||
}
|
||||
else if( key == "soundon:" ) {
|
||||
m_soundfxon.deserialize( Input, sound_type::single );
|
||||
}
|
||||
else if( key == "soundoff:" ) {
|
||||
m_soundfxoff.deserialize( Input, sound_type::single );
|
||||
}
|
||||
else if( key == "soundproofing:" ) {
|
||||
// custom soundproofing in format [ p1, p2, p3, p4, p5, p6 ]
|
||||
Input.getTokens( 6, false, "\n\r\t ,;[]" );
|
||||
std::array<float, 6> soundproofing;
|
||||
Input
|
||||
>> soundproofing[ 0 ]
|
||||
>> soundproofing[ 1 ]
|
||||
>> soundproofing[ 2 ]
|
||||
>> soundproofing[ 3 ]
|
||||
>> soundproofing[ 4 ]
|
||||
>> soundproofing[ 5 ];
|
||||
Scratchpad.soundproofing = soundproofing;
|
||||
}
|
||||
else if( starts_with( key, "sound" ) ) {
|
||||
// sounds assigned to specific gauge values, defined by key soundX: where X = value
|
||||
auto const indexstart { key.find_first_of( "-1234567890" ) };
|
||||
auto const indexend { key.find_first_not_of( "-1234567890", indexstart ) };
|
||||
if( indexstart != std::string::npos ) {
|
||||
m_soundfxvalues.emplace(
|
||||
std::stoi( key.substr( indexstart, indexend - indexstart ) ),
|
||||
sound_source( m_soundtemplate ).deserialize( Input, sound_type::single ) );
|
||||
}
|
||||
}
|
||||
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
|
||||
}
|
||||
|
||||
// ustawienie wartości docelowej. plays provided fallback sound, if no sound was defined in the control itself
|
||||
bool
|
||||
TGauge::UpdateValue( float fNewDesired, std::optional<sound_source> &Fallbacksound ) {
|
||||
|
||||
if( false == UpdateValue( fNewDesired ) ) {
|
||||
if( Fallbacksound ) {
|
||||
Fallbacksound->play( m_soundtype );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TGauge::UpdateValue( float fNewDesired ) {
|
||||
|
||||
auto const desiredtimes100 = static_cast<int>( std::round( 100.0 * fNewDesired ) );
|
||||
if( desiredtimes100 == static_cast<int>( std::round( 100.0 * m_targetvalue ) ) ) {
|
||||
return true;
|
||||
}
|
||||
m_targetvalue = fNewDesired;
|
||||
// if there's any sound associated with new requested value, play it
|
||||
// check value-specific table first...
|
||||
auto const fullinteger { desiredtimes100 % 100 == 0 };
|
||||
if( fullinteger ) {
|
||||
// filter out values other than full integers
|
||||
auto const lookup = m_soundfxvalues.find( desiredtimes100 / 100 );
|
||||
if( lookup != m_soundfxvalues.end() ) {
|
||||
lookup->second.play();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// toggle the control to continous range/exclusive sound mode from now on
|
||||
m_soundtype = sound_flags::exclusive;
|
||||
}
|
||||
// ...and if there isn't any, fall back on the basic set...
|
||||
auto const currentvalue = GetValue();
|
||||
// HACK: crude way to discern controls with continuous and quantized value range
|
||||
if( currentvalue < fNewDesired ) {
|
||||
// shift up
|
||||
if( false == m_soundfxincrease.empty() ) {
|
||||
m_soundfxincrease.play( m_soundtype );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( currentvalue > fNewDesired ) {
|
||||
// shift down
|
||||
if( false == m_soundfxdecrease.empty() ) {
|
||||
m_soundfxdecrease.play( m_soundtype );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // no suitable sound was found
|
||||
};
|
||||
|
||||
void TGauge::PutValue(float fNewDesired)
|
||||
{ // McZapkie-281102: natychmiastowe wpisanie wartosci
|
||||
m_targetvalue = fNewDesired;
|
||||
m_value = m_targetvalue;
|
||||
};
|
||||
|
||||
float TGauge::GetValue() const {
|
||||
// we feed value in range 0-1 so we should be getting it reported in the same range
|
||||
return m_value;
|
||||
}
|
||||
|
||||
float TGauge::GetDesiredValue() const {
|
||||
// we feed value in range 0-1 so we should be getting it reported in the same range
|
||||
return m_targetvalue;
|
||||
}
|
||||
|
||||
void TGauge::Update( bool const Power ) {
|
||||
// update value
|
||||
// TODO: remove passing manually power state when LD is in place
|
||||
if( m_value != m_targetvalue ) {
|
||||
float dt = Timer::GetDeltaTime();
|
||||
if( ( m_friction > 0 ) && ( dt < 0.5 * m_friction ) ) {
|
||||
// McZapkie-281102: zabezpieczenie przed oscylacjami dla dlugich czasow
|
||||
m_value += dt * ( m_targetvalue - m_value ) / m_friction;
|
||||
if( std::abs( m_targetvalue - m_value ) <= 0.0001 ) {
|
||||
// close enough, we can stop updating the model
|
||||
m_value = m_targetvalue; // set it exactly as requested just in case it matters
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_value = m_targetvalue;
|
||||
}
|
||||
}
|
||||
// update submodel visibility
|
||||
auto const state { Power && ( m_stateinput ? *m_stateinput : false ) };
|
||||
if( state != m_state ) {
|
||||
// on state change play assigned sound
|
||||
if( true == state ) { m_soundfxon.play(); }
|
||||
else { m_soundfxoff.play(); }
|
||||
}
|
||||
m_state = state;
|
||||
// toggle submodel visibility only if the active state submodel is present,
|
||||
// keep the default model always visible otherwise
|
||||
if( SubModelOn != nullptr ) {
|
||||
SubModelOn->iVisible = m_state;
|
||||
if( SubModel != nullptr ) {
|
||||
SubModel->iVisible = ( !m_state );
|
||||
}
|
||||
}
|
||||
// update submodel animations
|
||||
UpdateAnimation( SubModel );
|
||||
UpdateAnimation( SubModelOn );
|
||||
};
|
||||
|
||||
void TGauge::AssignFloat(float *fValue)
|
||||
{
|
||||
m_datatype = 'f';
|
||||
fData = fValue;
|
||||
};
|
||||
|
||||
void TGauge::AssignDouble(double *dValue)
|
||||
{
|
||||
m_datatype = 'd';
|
||||
dData = dValue;
|
||||
};
|
||||
|
||||
void TGauge::AssignInt(int *iValue)
|
||||
{
|
||||
m_datatype = 'i';
|
||||
iData = iValue;
|
||||
};
|
||||
|
||||
void TGauge::AssignBool(bool *bValue)
|
||||
{
|
||||
m_datatype = 'b';
|
||||
bData = bValue;
|
||||
};
|
||||
|
||||
void TGauge::UpdateValue()
|
||||
{ // ustawienie wartości docelowej z parametru
|
||||
switch (m_datatype)
|
||||
{ // to nie jest zbyt optymalne, można by zrobić osobne funkcje
|
||||
case 'f': {
|
||||
UpdateValue( *fData );
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
UpdateValue( *dData );
|
||||
break;
|
||||
}
|
||||
case 'i': {
|
||||
UpdateValue( *iData );
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
UpdateValue( ( *bData ? 1.f : 0.f ) );
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void TGauge::AssignState( bool const *State ) {
|
||||
|
||||
m_stateinput = State;
|
||||
}
|
||||
|
||||
float TGauge::GetScaledValue() const {
|
||||
|
||||
return (
|
||||
( false == m_interpolatescale ) ?
|
||||
m_value * m_scale + m_offset :
|
||||
m_value
|
||||
* interpolate(
|
||||
m_scale, m_endscale,
|
||||
clamp(
|
||||
m_value / m_endvalue,
|
||||
0.f, 1.f ) )
|
||||
+ m_offset );
|
||||
}
|
||||
|
||||
void
|
||||
TGauge::UpdateAnimation( TSubModel *Submodel ) {
|
||||
|
||||
if( Submodel == nullptr ) { return; }
|
||||
|
||||
switch (m_animation) {
|
||||
case TGaugeAnimation::gt_Rotate: {
|
||||
Submodel->SetRotate( float3( 0, 1, 0 ), GetScaledValue() * 360.0 );
|
||||
break;
|
||||
}
|
||||
case TGaugeAnimation::gt_Move: {
|
||||
Submodel->SetTranslate( float3( 0, 0, GetScaledValue() ) );
|
||||
break;
|
||||
}
|
||||
case TGaugeAnimation::gt_Wiper: {
|
||||
auto const scaledvalue { GetScaledValue() };
|
||||
Submodel->SetRotate( float3( 0, 1, 0 ), scaledvalue * 360.0 );
|
||||
auto *sm = Submodel->ChildGet();
|
||||
if( sm ) {
|
||||
sm->SetRotate( float3( 0, 1, 0 ), scaledvalue * 360.0 );
|
||||
sm = sm->ChildGet();
|
||||
if( sm )
|
||||
sm->SetRotate( float3( 0, 1, 0 ), scaledvalue * 360.0 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TGaugeAnimation::gt_Digital: {
|
||||
// Ra 2014-07: licznik cyfrowy
|
||||
auto *sm = Submodel->ChildGet();
|
||||
/* std::string n = FormatFloat( "0000000000", floor( fValue ) ); // na razie tak trochę bez sensu
|
||||
*/ std::string n( "000000000" + std::to_string( static_cast<int>( std::floor( GetScaledValue() ) ) ) );
|
||||
if( n.length() > 10 ) { n.erase( 0, n.length() - 10 ); } // also dumb but should work for now
|
||||
do { // pętla po submodelach potomnych i obracanie ich o kąt zależy od cyfry w (fValue)
|
||||
if( ( sm->pName.size() )
|
||||
&& ( std::isdigit( sm->pName[ 0 ] ) ) ) {
|
||||
sm->SetRotate(
|
||||
float3( 0, 1, 0 ),
|
||||
-36.0 * ( n[ '0' + 9 - sm->pName[ 0 ] ] - '0' ) );
|
||||
}
|
||||
sm = sm->NextGet();
|
||||
} while( sm );
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns offset of submodel associated with the button from the model centre
|
||||
glm::vec3
|
||||
TGauge::model_offset() const {
|
||||
|
||||
return (
|
||||
SubModel != nullptr ?
|
||||
SubModel->offset( 1.f ) :
|
||||
glm::vec3() );
|
||||
}
|
||||
|
||||
TGaugeType
|
||||
TGauge::type() const {
|
||||
return m_type;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
118
vehicle/Gauge.h
Normal file
118
vehicle/Gauge.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Classes.h"
|
||||
#include "sound.h"
|
||||
|
||||
enum class TGaugeAnimation {
|
||||
// typ ruchu
|
||||
gt_Unknown, // na razie nie znany
|
||||
gt_Rotate, // obrót
|
||||
gt_Move, // przesunięcie równoległe
|
||||
gt_Wiper, // obrót trzech kolejnych submodeli o ten sam kąt (np. wycieraczka, drzwi harmonijkowe)
|
||||
gt_Digital // licznik cyfrowy, np. kilometrów
|
||||
};
|
||||
|
||||
enum class TGaugeType : int {
|
||||
toggle = 1 << 0,
|
||||
push = 1 << 1,
|
||||
delayed = 1 << 2,
|
||||
pushtoggle = ( toggle | push ),
|
||||
push_delayed = ( push | delayed ),
|
||||
pushtoggle_delayed = ( toggle | push | delayed )
|
||||
};
|
||||
|
||||
// animowany wskaźnik, mogący przyjmować wiele stanów pośrednich
|
||||
class TGauge {
|
||||
|
||||
public:
|
||||
// methods
|
||||
TGauge() = default;
|
||||
explicit TGauge( sound_source const &Soundtemplate );
|
||||
|
||||
inline
|
||||
void Clear() {
|
||||
*this = TGauge(); }
|
||||
void Init(TSubModel *Submodel, TSubModel *Submodelon, TGaugeAnimation Type, float Scale = 1, float Offset = 0, float Friction = 0, float Value = 0, float const Endvalue = -1.0, float const Endscale = -1.0, bool const Interpolate = false );
|
||||
void Load(cParser &Parser, TDynamicObject const *Owner, double const mul = 1.0);
|
||||
bool UpdateValue( float fNewDesired );
|
||||
bool UpdateValue( float fNewDesired, std::optional<sound_source> &Fallbacksound );
|
||||
void PutValue(float fNewDesired);
|
||||
float GetValue() const;
|
||||
float GetDesiredValue() const;
|
||||
void Update( bool const Power = true );
|
||||
void AssignFloat(float *fValue);
|
||||
void AssignDouble(double *dValue);
|
||||
void AssignInt(int *iValue);
|
||||
void AssignBool(bool *bValue);
|
||||
void UpdateValue();
|
||||
void AssignState( bool const *State );
|
||||
// returns offset of submodel associated with the button from the model centre
|
||||
glm::vec3 model_offset() const;
|
||||
TGaugeType type() const;
|
||||
inline
|
||||
bool is_push() const {
|
||||
return ( static_cast<int>( type() ) & static_cast<int>( TGaugeType::push ) ) != 0; }
|
||||
inline
|
||||
bool is_toggle() const {
|
||||
return ( static_cast<int>( type() ) & static_cast<int>( TGaugeType::toggle ) ) != 0; }
|
||||
bool is_delayed() const {
|
||||
return ( static_cast<int>( type() ) & static_cast<int>( TGaugeType::delayed ) ) != 0; }
|
||||
// members
|
||||
TSubModel *SubModel { nullptr }, // McZapkie-310302: zeby mozna bylo sprawdzac czy zainicjowany poprawnie
|
||||
*SubModelOn { nullptr }; // optional submodel visible when the state input is set
|
||||
|
||||
private:
|
||||
// types
|
||||
struct scratch_data {
|
||||
std::optional< std::array<float, 6> > soundproofing;
|
||||
};
|
||||
// methods
|
||||
// imports member data pair from the config file
|
||||
bool
|
||||
Load_mapping( cParser &Input, TGauge::scratch_data &Scratchpad );
|
||||
float
|
||||
GetScaledValue() const;
|
||||
void
|
||||
UpdateAnimation( TSubModel *Submodel );
|
||||
|
||||
// members
|
||||
TGaugeAnimation m_animation { TGaugeAnimation::gt_Unknown }; // typ ruchu
|
||||
TGaugeType m_type { TGaugeType::toggle }; // switch type
|
||||
float m_friction { 0.f }; // hamowanie przy zliżaniu się do zadanej wartości
|
||||
float m_targetvalue { 0.f }; // wartość docelowa
|
||||
float m_value { 0.f }; // wartość obecna
|
||||
float m_offset { 0.f }; // wartość początkowa ("0")
|
||||
float m_scale { 1.f }; // scale applied to the value at the start of accepted value range
|
||||
float m_endscale { -1.f }; // scale applied to the value at the end of accepted value range
|
||||
float m_endvalue { -1.f }; // end value of accepted value range
|
||||
bool m_interpolatescale { false };
|
||||
char m_datatype; // typ zmiennej parametru: f-float, d-double, i-int
|
||||
union {
|
||||
// wskaźnik na parametr pokazywany przez animację
|
||||
float *fData;
|
||||
double *dData { nullptr };
|
||||
int *iData;
|
||||
bool *bData;
|
||||
};
|
||||
bool m_state { false }; // visibility of the control's submodel(s); false : default, true: active
|
||||
bool const *m_stateinput { nullptr }; // bound variable determining visibility of the control's submodel(s)
|
||||
int m_soundtype { 0 }; // toggle between exclusive and multiple sound generation
|
||||
sound_source m_soundtemplate { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // shared properties for control's sounds
|
||||
sound_source m_soundfxon { m_soundtemplate }; // sound associated with switching the control to active state
|
||||
sound_source m_soundfxoff { m_soundtemplate }; // sound associated with switching the control to default state
|
||||
sound_source m_soundfxincrease { m_soundtemplate }; // sound associated with increasing control's value
|
||||
sound_source m_soundfxdecrease { m_soundtemplate }; // sound associated with decreasing control's value
|
||||
std::map<int, sound_source> m_soundfxvalues; // sounds associated with specific values
|
||||
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
11243
vehicle/Train.cpp
Normal file
11243
vehicle/Train.cpp
Normal file
File diff suppressed because it is too large
Load Diff
940
vehicle/Train.h
Normal file
940
vehicle/Train.h
Normal file
@@ -0,0 +1,940 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "DynObj.h"
|
||||
#include "Driver.h"
|
||||
#include "Button.h"
|
||||
#include "Gauge.h"
|
||||
#include "sound.h"
|
||||
#include "PyInt.h"
|
||||
#include "command.h"
|
||||
#include "pythonscreenviewer.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
#undef snprintf // pyint.h->python
|
||||
|
||||
// typedef enum {st_Off, st_Starting, st_On, st_ShuttingDown} T4State;
|
||||
|
||||
const double fCzuwakBlink = 0.15;
|
||||
const float fConverterPrzekaznik = 1.5f; // hunter-261211: do przekaznika nadmiarowego przetwornicy
|
||||
// 0.33f
|
||||
// const double fBuzzerTime= 5.0f;
|
||||
const float fHaslerTime = 1.2f;
|
||||
|
||||
class TCab {
|
||||
|
||||
public:
|
||||
// methods
|
||||
void Load(cParser &Parser);
|
||||
void Update( bool const Power );
|
||||
TGauge &Gauge( int n = -1 ); // pobranie adresu obiektu
|
||||
TButton &Button( int n = -1 ); // pobranie adresu obiektu
|
||||
// members
|
||||
Math3D::vector3 CabPos1 { 0, 1, 1 };
|
||||
Math3D::vector3 CabPos2 { 0, 1, -1 };
|
||||
bool bEnabled { false };
|
||||
bool bOccupied { true };
|
||||
/*
|
||||
glm::vec3 dimm; // McZapkie-120503: tlumienie swiatla
|
||||
glm::vec3 intlit; // McZapkie-120503: oswietlenie kabiny
|
||||
glm::vec3 intlitlow; // McZapkie-120503: przyciemnione oswietlenie kabiny
|
||||
*/
|
||||
bool bLight { false }; // hunter-091012: czy swiatlo jest zapalone?
|
||||
bool bLightDim { false }; // hunter-091012: czy przyciemnienie kabiny jest zapalone?
|
||||
float LightLevel{ 0.f }; // last calculated interior light level
|
||||
|
||||
private:
|
||||
// members
|
||||
std::deque<TGauge> ggList; // need a container which doesn't invalidate references
|
||||
std::vector<TButton> btList;
|
||||
};
|
||||
|
||||
class control_mapper {
|
||||
typedef std::unordered_map< TSubModel const *, std::string> submodelstring_map;
|
||||
submodelstring_map m_controlnames;
|
||||
using stringset = std::unordered_set<std::string>;
|
||||
stringset m_names; // names of registered controls
|
||||
public:
|
||||
void
|
||||
clear();
|
||||
void
|
||||
insert( TGauge const &Gauge, std::string const &Label );
|
||||
std::string
|
||||
find( TSubModel const *Control ) const;
|
||||
bool
|
||||
contains( std::string const Control ) const;
|
||||
};
|
||||
|
||||
class TTrain {
|
||||
|
||||
friend class drivingaid_panel;
|
||||
|
||||
public:
|
||||
// types
|
||||
struct state_t {
|
||||
std::uint8_t shp;
|
||||
std::uint8_t alerter;
|
||||
std::uint8_t radio_stop;
|
||||
std::uint8_t motor_resistors;
|
||||
std::uint8_t line_breaker;
|
||||
std::uint8_t ground_relay;
|
||||
std::uint8_t motor_overload;
|
||||
std::uint8_t motor_connectors;
|
||||
std::uint8_t wheelslip;
|
||||
std::uint8_t converter_overload;
|
||||
std::uint8_t converter_off;
|
||||
std::uint8_t compressor_overload;
|
||||
std::uint8_t ventilator_overload;
|
||||
std::uint8_t motor_overload_threshold;
|
||||
std::uint8_t train_heating;
|
||||
std::uint8_t cab;
|
||||
std::uint8_t recorder_braking;
|
||||
std::uint8_t recorder_power;
|
||||
std::uint8_t alerter_sound;
|
||||
std::uint8_t coupled_hv_voltage_relays;
|
||||
float velocity;
|
||||
float reservoir_pressure;
|
||||
float pipe_pressure;
|
||||
float brake_pressure;
|
||||
float pantograph_pressure;
|
||||
float hv_voltage;
|
||||
std::array<float, 3> hv_current;
|
||||
float lv_voltage;
|
||||
double distance;
|
||||
std::uint8_t radio_channel;
|
||||
std::uint8_t springbrake_active;
|
||||
std::uint8_t epbrake_enabled;
|
||||
std::uint8_t dir_forward;
|
||||
std::uint8_t dir_backward;
|
||||
std::uint8_t doorleftallowed;
|
||||
std::uint8_t doorleftopened;
|
||||
std::uint8_t doorrightallowed;
|
||||
std::uint8_t doorrightopened;
|
||||
std::uint8_t doorstepallowed;
|
||||
std::uint8_t battery;
|
||||
std::uint8_t emergencybrake;
|
||||
std::uint8_t lockpipe;
|
||||
bool radiomessageindicator;
|
||||
};
|
||||
|
||||
struct screen_entry {
|
||||
|
||||
std::string script;
|
||||
std::string target;
|
||||
double updatetime = 0;
|
||||
double updatetimecounter = 0;
|
||||
std::shared_ptr<python_rt> rt;
|
||||
std::shared_ptr<python_screen_viewer> viewer;
|
||||
std::shared_ptr<std::vector<glm::vec2>> touch_list;
|
||||
|
||||
dictionary_source parameters; // cached pre-processed optional per-screen parameters
|
||||
|
||||
void deserialize( cParser &Input );
|
||||
bool deserialize_mapping( cParser &Input );
|
||||
};
|
||||
|
||||
typedef std::vector<screen_entry> screenentry_sequence;
|
||||
|
||||
// methods
|
||||
bool CabChange(int iDirection);
|
||||
bool ShowNextCurrent; // pokaz przd w podlaczonej lokomotywie (ET41)
|
||||
bool InitializeCab(int NewCabNo, std::string const &asFileName);
|
||||
TTrain();
|
||||
~TTrain();
|
||||
// McZapkie-010302
|
||||
bool Init(TDynamicObject *NewDynamicObject, bool e3d = false);
|
||||
|
||||
inline
|
||||
Math3D::vector3 GetDirection() const {
|
||||
return DynamicObject->VectorFront(); };
|
||||
inline
|
||||
Math3D::vector3 GetUp() const {
|
||||
return DynamicObject->VectorUp(); };
|
||||
inline
|
||||
std::string GetLabel( TSubModel const *Control ) const {
|
||||
return m_controlmapper.find( Control ); }
|
||||
void UpdateCab();
|
||||
bool Update( double const Deltatime );
|
||||
void UpdateDirectionRelays();
|
||||
void SetupDirectionRelays();
|
||||
bool prevBatState = false;
|
||||
int prevDirection = 0;
|
||||
void add_distance( double const Distance );
|
||||
// McZapkie-310302: ladowanie parametrow z pliku
|
||||
bool LoadMMediaFile(std::string const &asFileName);
|
||||
std::shared_ptr<dictionary_source> GetTrainState( dictionary_source const &Extraparameters );
|
||||
state_t get_state() const;
|
||||
inline float get_radiovolume() const { return m_radiovolume; }
|
||||
// basic_table interface
|
||||
inline
|
||||
std::string name() const {
|
||||
return Dynamic()->name(); }
|
||||
|
||||
private:
|
||||
// types
|
||||
typedef void( *command_handler )( TTrain *Train, command_data const &Command );
|
||||
typedef std::unordered_map<user_command, command_handler> commandhandler_map;
|
||||
// methods
|
||||
// clears state of all cabin controls
|
||||
void clear_cab_controls();
|
||||
// sets cabin controls based on current state of the vehicle
|
||||
// NOTE: we can get rid of this function once we have per-cab persistent state
|
||||
void set_cab_controls( int const Cab );
|
||||
// initializes a gauge matching provided label. returns: true if the label was found, false otherwise
|
||||
bool initialize_gauge(cParser &Parser, std::string const &Label, int const Cabindex);
|
||||
// initializes a button matching provided label. returns: true if the label was found, false otherwise
|
||||
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(bool freefly, glm::vec3 pos) const;
|
||||
// mover master controller to specified position
|
||||
void set_master_controller( double const Position );
|
||||
// moves train brake lever to specified position, potentially emits switch sound if conditions are met
|
||||
void set_train_brake( double const Position );
|
||||
// potentially moves train brake lever to neutral position
|
||||
void zero_charging_train_brake();
|
||||
// sets specified brake acting speed for specified vehicle, potentially updating state of cab controls to match
|
||||
void set_train_brake_speed( TDynamicObject *Vehicle, int const Speed );
|
||||
// sets the motor connector button in paired unit to specified state
|
||||
void set_paired_open_motor_connectors_button( bool const State );
|
||||
// helper, common part of pantograph selection methods
|
||||
void change_pantograph_selection( int const Change );
|
||||
// helper, common part of pantograh valves state update methods
|
||||
void update_pantograph_valves();
|
||||
// update function subroutines
|
||||
void update_sounds( double const Deltatime );
|
||||
void update_sounds_runningnoise( sound_source &Sound );
|
||||
void update_sounds_resonancenoise( sound_source &Sound );
|
||||
void update_sounds_radio();
|
||||
inline
|
||||
end cab_to_end( int const End ) const {
|
||||
return (
|
||||
End == 2 ?
|
||||
end::rear :
|
||||
end::front ); }
|
||||
inline
|
||||
end cab_to_end() const {
|
||||
return cab_to_end( iCabn ); }
|
||||
void update_screens(double dt);
|
||||
|
||||
// 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_lightsset(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_wiperswitchincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_wiperswitchdecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_aidriverenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_aidriverdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_jointcontrollerset( 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 );
|
||||
static void OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_secondcontrollerincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_secondcontrollerincreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_secondcontrollerdecreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_secondcontrollerset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_tempomattoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mucurrentindicatorothersourceactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakeincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakeincreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakedecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakedecreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakeset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakebailoff( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_universalbrakebutton1(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_universalbrakebutton2(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_universalbrakebutton3(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_trainbrakeincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakedecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakecharging( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakerelease( TTrain *Train, command_data const &Command );
|
||||
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 );
|
||||
static void OnCommand_alarmchainenable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_alarmchaindisable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_wheelspinbrakeactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_sandboxactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_autosandboxtoggle(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_autosandboxactivate(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_autosandboxdeactivate(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_epbrakecontrolenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_epbrakecontroldisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeoperationmodeincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_trainbrakeoperationmodedecrease(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_brakeactingspeedsetcargo( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeactingspeedsetpassenger( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeactingspeedsetrapid( 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 );
|
||||
static void OnCommand_reverserforwardhigh( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserforward( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserneutral( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserbackward( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_alerteracknowledge( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_cabsignalacknowledge( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_batterytoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_batteryenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_batterydisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_cabactivationtoggle(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_cabactivationenable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_cabactivationdisable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographcompressorvalveenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographcompressorvalvedisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographcompressoractivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographraisefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographraiserear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographlowerfront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographlowerrear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographselectnext( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographselectprevious( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographtoggleselected( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographraiseselected( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographlowerselected( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographvalvesupdate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographvalvesoff( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_linebreakeropen( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_linebreakerclose( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_fuelpumptoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_fuelpumpenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_fuelpumpdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_oilpumptoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_oilpumpenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_oilpumpdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterbreakertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterbreakerclose( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterbreakeropen( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheatertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpbreakertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpbreakerclose( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpbreakeropen( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumptoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_watercircuitslinktoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_watercircuitslinkenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_watercircuitslinkdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_converterenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_converterdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_convertertogglelocal( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressorenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressordisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressortogglelocal( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressorpresetactivatenext( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressorpresetactivateprevious( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressorpresetactivatedefault(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_motorblowerstogglefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersenablefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersdisablefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowerstogglerear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersenablerear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersdisablerear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersdisableall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_coolingfanstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorconnectorsclose( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motordisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motoroverloadrelaythresholdsetlow( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motoroverloadrelaythresholdsethigh( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motoroverloadrelayreset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_universalrelayreset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_heatingtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_heatingenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_heatingdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_lightspresetactivatenext( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_lightspresetactivateprevious( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenableleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisableleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttoggleright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenableright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisableright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttoggleupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenableupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisableupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerenableleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerdisableleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkertoggleright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerenableright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerdisableright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttogglerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenablerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisablerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttogglerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenablerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisablerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttogglerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenablerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisablerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_modernlightdimmerincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_modernlightdimmerdecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_redmarkertogglerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerenablerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerdisablerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkertogglerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerenablerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerdisablerearright( 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_headlightsdimenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightsdimdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdimenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdimdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compartmentlightstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compartmentlightsenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compartmentlightsdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_instrumentlighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_instrumentlightenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_instrumentlightdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dashboardlighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dashboardlightenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dashboardlightdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_timetablelighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_timetablelightenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_timetablelightdisable( TTrain *Train, command_data const &Command );
|
||||
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_doorpermitleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitpresetactivatenext( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitpresetactivateprevious( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dooropenleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dooropenright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorcloseleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorcloseright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dooropenall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorcloseall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doormodetoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mirrorstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_nearestcarcouplingincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_nearestcarcouplingdisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_nearestcarcoupleradapterattach( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_nearestcarcoupleradapterremove( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_occupiedcarcouplingdisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_occupiedcarcouplingdisconnectback( 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_whistleactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radioenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiodisable( 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_radiochannelset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiostopsend( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiostopenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiostopdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiocall3send( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiovolumeincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_radiovolumedecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_radiovolumeset(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 );
|
||||
static void OnCommand_vehiclemoveforwards( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_vehiclemovebackwards( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_vehicleboost( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_springbraketoggle(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_springbrakeenable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_springbrakedisable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_springbrakeshutofftoggle(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_springbrakeshutoffenable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_springbrakeshutoffdisable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_springbrakerelease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_distancecounteractivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_speedcontrolincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_speedcontroldecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_speedcontrolpowerincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_speedcontrolpowerdecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_speedcontrolbutton(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_inverterenable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_inverterdisable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_invertertoggle(TTrain *Train, command_data const &Command);
|
||||
|
||||
|
||||
// members
|
||||
TDynamicObject *DynamicObject { nullptr }; // przestawia zmiana pojazdu [F5]
|
||||
TMoverParameters *mvControlled { nullptr }; // człon, w którym sterujemy silnikiem
|
||||
TMoverParameters *mvOccupied { nullptr }; // człon, w którym sterujemy hamulcem
|
||||
TMoverParameters *mvSecond { nullptr }; // drugi człon (ET40, ET41, ET42, ukrotnienia)
|
||||
TMoverParameters *mvThird { nullptr }; // trzeci człon (SN61)
|
||||
TMoverParameters *mvPantographUnit { nullptr }; // nearest pantograph equipped unit
|
||||
// helper variable, to prevent immediate switch between closing and opening line breaker circuit
|
||||
int m_linebreakerstate { 0 }; // 0: open, 1: closed, 2: freshly closed (and yes this is awful way to go about it)
|
||||
static const commandhandler_map m_commandhandlers;
|
||||
control_mapper m_controlmapper;
|
||||
|
||||
public: // reszta może by?publiczna
|
||||
|
||||
// McZapkie: definicje wskaźników
|
||||
// Ra 2014-08: częsciowo przeniesione do tablicy w TCab
|
||||
TGauge ggClockSInd;
|
||||
TGauge ggClockMInd;
|
||||
TGauge ggClockHInd;
|
||||
TGauge ggLVoltage;
|
||||
TGauge ggMainGearStatus;
|
||||
|
||||
TGauge ggEngineVoltage;
|
||||
TGauge ggI1B; // drugi człon w postaci jawnej
|
||||
TGauge ggI2B;
|
||||
TGauge ggI3B;
|
||||
TGauge ggItotalB;
|
||||
|
||||
TGauge ggOilPressB; // other unit oil pressure indicator
|
||||
TGauge ggWater1TempB;
|
||||
|
||||
// McZapkie: definicje regulatorow
|
||||
TGauge ggJointCtrl;
|
||||
TGauge ggMainCtrl;
|
||||
TGauge ggMainCtrlAct;
|
||||
TGauge ggScndCtrl;
|
||||
TGauge ggScndCtrlButton;
|
||||
TGauge ggScndCtrlOffButton;
|
||||
TGauge ggDirKey;
|
||||
TGauge ggDirForwardButton;
|
||||
TGauge ggDirNeutralButton;
|
||||
TGauge ggDirBackwardButton;
|
||||
TGauge ggBrakeCtrl;
|
||||
TGauge ggLocalBrake;
|
||||
TGauge ggAlarmChain;
|
||||
TGauge ggBrakeProfileCtrl; // nastawiacz GPR - przelacznik obrotowy
|
||||
TGauge ggBrakeProfileG; // nastawiacz GP - hebelek towarowy
|
||||
TGauge ggBrakeProfileR; // nastawiacz PR - hamowanie dwustopniowe
|
||||
TGauge ggBrakeOperationModeCtrl; //przełącznik trybu pracy PS/PN/EP/MED
|
||||
|
||||
TGauge ggWiperSw; // przelacznik wycieraczek
|
||||
|
||||
TGauge ggMaxCurrentCtrl;
|
||||
|
||||
TGauge ggMainOffButton;
|
||||
TGauge ggMainOnButton;
|
||||
TGauge ggMainButton; // EZT
|
||||
TGauge ggSecurityResetButton;
|
||||
TGauge ggSHPResetButton;
|
||||
TGauge ggReleaserButton;
|
||||
TGauge ggSpringBrakeOnButton;
|
||||
TGauge ggSpringBrakeOffButton;
|
||||
TGauge ggUniveralBrakeButton1;
|
||||
TGauge ggUniveralBrakeButton2;
|
||||
TGauge ggUniveralBrakeButton3;
|
||||
TGauge ggEPFuseButton;
|
||||
TGauge ggSandButton; // guzik piasecznicy
|
||||
TGauge ggAutoSandButton; // przełącznik piasecznicy
|
||||
TGauge ggAntiSlipButton;
|
||||
TGauge ggFuseButton;
|
||||
TGauge ggConverterFuseButton; // hunter-261211: przycisk odblokowania nadmiarowego przetwornic i ogrzewania
|
||||
TGauge ggStLinOffButton;
|
||||
TGauge ggRadioChannelSelector;
|
||||
TGauge ggRadioChannelPrevious;
|
||||
TGauge ggRadioChannelNext;
|
||||
TGauge ggRadioTest;
|
||||
TGauge ggRadioStop;
|
||||
TGauge ggRadioCall3;
|
||||
TGauge ggRadioVolumeSelector;
|
||||
TGauge ggRadioVolumePrevious;
|
||||
TGauge ggRadioVolumeNext;
|
||||
TGauge ggUpperLightButton;
|
||||
TGauge ggLeftLightButton;
|
||||
TGauge ggRightLightButton;
|
||||
TGauge ggLeftEndLightButton;
|
||||
TGauge ggRightEndLightButton;
|
||||
TGauge ggLightsButton; // przelacznik reflektorow (wszystkich)
|
||||
TGauge ggDimHeadlightsButton; // headlights dimming switch
|
||||
TGauge ggModernLightDimSw; // modern lights dimmer
|
||||
|
||||
// hunter-230112: przelacznik swiatel tylnich
|
||||
TGauge ggRearUpperLightButton;
|
||||
TGauge ggRearLeftLightButton;
|
||||
TGauge ggRearRightLightButton;
|
||||
TGauge ggRearLeftEndLightButton;
|
||||
TGauge ggRearRightEndLightButton;
|
||||
|
||||
TGauge ggIgnitionKey;
|
||||
|
||||
TGauge ggCompressorButton;
|
||||
TGauge ggCompressorLocalButton; // controls only compressor of its own unit (et42-specific)
|
||||
TGauge ggCompressorListButton; // controls compressors with various settings
|
||||
TGauge ggConverterButton;
|
||||
TGauge ggConverterLocalButton; // controls only converter of its own unit (et42-specific)
|
||||
TGauge ggConverterOffButton;
|
||||
|
||||
// ABu 090305 - syrena i prad nastepnego czlonu
|
||||
TGauge ggHornButton;
|
||||
TGauge ggHornLowButton;
|
||||
TGauge ggHornHighButton;
|
||||
TGauge ggWhistleButton;
|
||||
TGauge ggHelperButton;
|
||||
TGauge ggNextCurrentButton;
|
||||
|
||||
// yB 191005 - tempomat
|
||||
TGauge ggSpeedControlIncreaseButton;
|
||||
TGauge ggSpeedControlDecreaseButton;
|
||||
TGauge ggSpeedControlPowerIncreaseButton;
|
||||
TGauge ggSpeedControlPowerDecreaseButton;
|
||||
std::array<TGauge, 10> ggSpeedCtrlButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
|
||||
std::array<TGauge, 30> ggUniversals; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
std::array<TGauge, 3> ggRelayResetButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
std::array<TGauge, 12> ggInverterEnableButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
std::array<TGauge, 12> ggInverterDisableButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
std::array<TGauge, 12> ggInverterToggleButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
|
||||
TGauge ggInstrumentLightButton;
|
||||
TGauge ggDashboardLightButton;
|
||||
TGauge ggTimetableLightButton;
|
||||
// TGauge ggCabLightButton; // hunter-091012: przelacznik oswietlania kabiny
|
||||
TGauge ggCabLightDimButton; // hunter-091012: przelacznik przyciemnienia
|
||||
// oswietlenia kabiny
|
||||
TGauge ggCompartmentLightsButton;
|
||||
TGauge ggCompartmentLightsOnButton;
|
||||
TGauge ggCompartmentLightsOffButton;
|
||||
TGauge ggBatteryButton; // Stele 161228 hebelek baterii
|
||||
TGauge ggBatteryOnButton;
|
||||
TGauge ggBatteryOffButton;
|
||||
TGauge ggCabActivationButton; // Stele 161228 hebelek baterii
|
||||
|
||||
// NBMX wrzesien 2003 - obsluga drzwi
|
||||
TGauge ggDoorLeftPermitButton;
|
||||
TGauge ggDoorRightPermitButton;
|
||||
TGauge ggDoorPermitPresetButton;
|
||||
TGauge ggDoorLeftButton;
|
||||
TGauge ggDoorRightButton;
|
||||
TGauge ggDoorLeftOnButton;
|
||||
TGauge ggDoorRightOnButton;
|
||||
TGauge ggDoorLeftOffButton;
|
||||
TGauge ggDoorRightOffButton;
|
||||
TGauge ggDoorAllOnButton;
|
||||
TGauge ggDoorAllOffButton;
|
||||
TGauge ggDepartureSignalButton;
|
||||
TGauge ggDoorStepButton;
|
||||
|
||||
// Winger 160204 - obsluga pantografow - ZROBIC
|
||||
/*
|
||||
TGauge ggPantFrontButton;
|
||||
TGauge ggPantRearButton;
|
||||
TGauge ggPantFrontButtonOff; // EZT
|
||||
TGauge ggPantRearButtonOff;
|
||||
*/
|
||||
TGauge ggPantAllDownButton;
|
||||
TGauge ggPantSelectedButton;
|
||||
TGauge ggPantSelectedDownButton;
|
||||
TGauge ggPantValvesButton;
|
||||
TGauge ggPantCompressorButton;
|
||||
TGauge ggPantCompressorValve;
|
||||
TGauge ggPantValvesUpdate;
|
||||
TGauge ggPantValvesOff;
|
||||
// Winger 020304 - wlacznik ogrzewania
|
||||
TGauge ggTrainHeatingButton;
|
||||
TGauge ggSignallingButton;
|
||||
TGauge ggDoorSignallingButton;
|
||||
|
||||
TGauge ggWaterPumpBreakerButton; // water pump breaker switch
|
||||
TGauge ggWaterPumpButton; // water pump switch
|
||||
TGauge ggWaterHeaterBreakerButton; // water heater breaker switch
|
||||
TGauge ggWaterHeaterButton; // water heater switch
|
||||
TGauge ggWaterCircuitsLinkButton;
|
||||
TGauge ggFuelPumpButton; // fuel pump switch
|
||||
TGauge ggOilPumpButton; // fuel pump switch
|
||||
TGauge ggMotorBlowersFrontButton; // front traction motor fan switch
|
||||
TGauge ggMotorBlowersRearButton; // rear traction motor fan switch
|
||||
TGauge ggMotorBlowersAllOffButton; // motor fans shutdown switch
|
||||
|
||||
TGauge ggDistanceCounterButton; // distance meter activation button
|
||||
|
||||
TButton btLampkaPoslizg;
|
||||
TButton btLampkaStyczn;
|
||||
TButton btLampkaNadmPrzetw;
|
||||
TButton btLampkaPrzetw;
|
||||
TButton btLampkaPrzetwOff;
|
||||
TButton btLampkaPrzekRozn; // TODO: implement
|
||||
TButton btLampkaPrzekRoznPom; // TODO: implement
|
||||
TButton btLampkaNadmSil;
|
||||
TButton btLampkaWylSzybki;
|
||||
TButton btLampkaWylSzybkiOff;
|
||||
TButton btLampkaMainBreakerReady;
|
||||
TButton btLampkaMainBreakerBlinkingIfReady;
|
||||
TButton btLampkaNadmWent;
|
||||
TButton btLampkaNadmSpr; // TODO: implement
|
||||
// yB: drugie lampki dla EP05 i ET42
|
||||
TButton btLampkaOporyB;
|
||||
TButton btLampkaStycznB;
|
||||
TButton btLampkaWylSzybkiB;
|
||||
TButton btLampkaWylSzybkiBOff;
|
||||
TButton btLampkaNadmPrzetwB;
|
||||
TButton btLampkaPrzetwB;
|
||||
TButton btLampkaPrzetwBOff;
|
||||
TButton btLampkaHVoltageB; // TODO: implement
|
||||
// KURS90 lampki jazdy bezoporowej dla EU04
|
||||
TButton btLampkaBezoporowaB;
|
||||
TButton btLampkaBezoporowa;
|
||||
TButton btLampkaUkrotnienie;
|
||||
TButton btLampkaHamPosp;
|
||||
TButton btLampkaRadio;
|
||||
TButton btLampkaRadioMessage;
|
||||
TButton btLampkaRadioStop;
|
||||
TButton btLampkaHamowanie1zes;
|
||||
TButton btLampkaHamowanie2zes;
|
||||
TButton btLampkaOpory;
|
||||
TButton btLampkaWysRozr;
|
||||
std::array<TButton, 10> btUniversals; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
TButton btInstrumentLight;
|
||||
TButton btDashboardLight;
|
||||
TButton btTimetableLight;
|
||||
int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw., 3-rozrzad, 4-external lights
|
||||
bool InstrumentLightActive{ false };
|
||||
bool DashboardLightActive{ false };
|
||||
bool TimetableLightActive{ false };
|
||||
TButton btLampkaWentZaluzje; // ET22 // TODO: implement
|
||||
TButton btLampkaOgrzewanieSkladu;
|
||||
TButton btLampkaSHP;
|
||||
TButton btLampkaCzuwaka; // McZapkie-141102
|
||||
TButton btLampkaCzuwakaSHP;
|
||||
TButton btLampkaRezerwa;
|
||||
// youBy - jakies dodatkowe lampki
|
||||
TButton btLampkaNapNastHam;
|
||||
TButton btLampkaSprezarka;
|
||||
TButton btLampkaSprezarkaB;
|
||||
TButton btLampkaSprezarkaOff;
|
||||
TButton btLampkaSprezarkaBOff;
|
||||
TButton btLampkaFuelPumpOff;
|
||||
TButton btLampkaBocznik1;
|
||||
TButton btLampkaBocznik2;
|
||||
TButton btLampkaBocznik3;
|
||||
TButton btLampkaBocznik4;
|
||||
TButton btLampkaRadiotelefon; // TODO: implement
|
||||
TButton btLampkaHamienie;
|
||||
TButton btLampkaBrakingOff;
|
||||
TButton btLampkaED; // Stele 161228 hamowanie elektrodynamiczne
|
||||
TButton btLampkaBrakeProfileG; // cargo train brake acting speed
|
||||
TButton btLampkaBrakeProfileP; // passenger train brake acting speed
|
||||
TButton btLampkaBrakeProfileR; // rapid brake acting speed
|
||||
TButton btLampkaSpringBrakeActive;
|
||||
TButton btLampkaSpringBrakeInactive;
|
||||
// KURS90
|
||||
TButton btLampkaBoczniki;
|
||||
TButton btLampkaMaxSila;
|
||||
TButton btLampkaPrzekrMaxSila;
|
||||
TButton btLampkaDoorLeft;
|
||||
TButton btLampkaDoorRight;
|
||||
TButton btLampkaDepartureSignal;
|
||||
TButton btLampkaBlokadaDrzwi;
|
||||
TButton btLampkaDoorLockOff;
|
||||
TButton btLampkaHamulecReczny;
|
||||
TButton btLampkaForward; // Ra: lampki w przód i w ty?dla komputerowych kabin
|
||||
TButton btLampkaNeutral; // Kierunek neutralny
|
||||
TButton btLampkaBackward;
|
||||
// light indicators
|
||||
TButton btLampkaUpperLight;
|
||||
TButton btLampkaLeftLight;
|
||||
TButton btLampkaRightLight;
|
||||
TButton btLampkaLeftEndLight;
|
||||
TButton btLampkaRightEndLight;
|
||||
TButton btLampkaRearUpperLight;
|
||||
TButton btLampkaRearLeftLight;
|
||||
TButton btLampkaRearRightLight;
|
||||
TButton btLampkaRearLeftEndLight;
|
||||
TButton btLampkaRearRightEndLight;
|
||||
TButton btCabActived;
|
||||
TButton btAKLVents;
|
||||
TButton btCompressors; // lampka pracy jakiejkolwiek sprezarki
|
||||
TButton btEDenabled; // czy wlaczony jest hamulec ED (czy dostepny)
|
||||
// other
|
||||
TButton btLampkaMalfunction;
|
||||
TButton btLampkaMalfunctionB;
|
||||
TButton btLampkaMotorBlowers;
|
||||
TButton btLampkaCoolingFans;
|
||||
TButton btLampkaTempomat;
|
||||
TButton btLampkaDistanceCounter;
|
||||
|
||||
// TButton btCabLight; // hunter-171012: lampa oswietlajaca kabine
|
||||
// Ra 2013-12: wirtualne "lampki" do odbijania na haslerze w PoKeys
|
||||
TButton btHaslerBrakes; // ciśnienie w cylindrach
|
||||
TButton btHaslerCurrent; // prąd na silnikach
|
||||
|
||||
std::optional<sound_source>
|
||||
dsbNastawnikJazdy,
|
||||
dsbNastawnikBocz,
|
||||
dsbReverserKey,
|
||||
dsbBuzzer, dsbBuzzerShp,
|
||||
m_radiostop,
|
||||
dsbSlipAlarm,
|
||||
m_distancecounterclear,
|
||||
dsbHasler,
|
||||
dsbSwitch,
|
||||
dsbPneumaticSwitch,
|
||||
rsHiss,
|
||||
rsHissU,
|
||||
rsHissE,
|
||||
rsHissX,
|
||||
rsHissT,
|
||||
rsSBHiss,
|
||||
rsSBHissU,
|
||||
rsBrake,
|
||||
rsFadeSound,
|
||||
rsRunningNoise,
|
||||
rsResonanceNoise,
|
||||
rsWindSound,
|
||||
rsHuntingNoise,
|
||||
m_rainsound;
|
||||
sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages
|
||||
std::vector<std::pair<int, std::shared_ptr<sound_source>>> m_radiomessages; // list of currently played radio messages
|
||||
std::vector<std::pair<std::reference_wrapper<std::optional<sound_source>>, glm::vec3>> CabSoundLocations; // list of offsets for manually located sounds;
|
||||
float m_lastlocalbrakepressure { -1.f }; // helper, cached level of pressure in local brake cylinder
|
||||
float m_localbrakepressurechange { 0.f }; // recent change of pressure in local brake cylinder
|
||||
/*
|
||||
int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
|
||||
bool bCabLight; // hunter-091012: czy swiatlo jest zapalone?
|
||||
bool bCabLightDim; // hunter-091012: czy przyciemnienie kabiny jest zapalone?
|
||||
*/
|
||||
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
|
||||
std::array<TCab, 3> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
|
||||
int iCabn { 0 }; // 0: mid, 1: front, 2: rear
|
||||
bool is_cab_initialized { false };
|
||||
// McZapkie: do poruszania sie po kabinie
|
||||
Math3D::vector3 pMechSittingPosition; // ABu 180404
|
||||
Math3D::vector3 MirrorPosition( bool lewe );
|
||||
Math3D::vector3 pMechOffset; // base position of the driver in the cab
|
||||
glm::vec2 pMechViewAngle { 0.0, 0.0 }; // camera pitch and yaw values, preserved while in external view
|
||||
|
||||
private:
|
||||
double fBlinkTimer;
|
||||
float fHaslerTimer;
|
||||
float fConverterTimer; // hunter-261211: dla przekaznika
|
||||
float fMainRelayTimer; // hunter-141211: zalaczanie WSa z opoznieniem
|
||||
float fBatteryTimer = {-1.f}; // Hirek: zalaczanie baterii z opoznieniem (tylko gdy zdefiniowano takie zachowanie w fiz)
|
||||
bool allowBatteryToggle = true; // Hirek: zabezpieczenie przed przelaczaniem bateri on/off
|
||||
int ScreenUpdateRate { 0 }; // vehicle specific python screen update rate override
|
||||
|
||||
// McZapkie-240302 - przyda sie do tachometru
|
||||
float fTachoVelocity{ 0.0f };
|
||||
float fTachoVelocityJump{ 0.0f }; // ze skakaniem
|
||||
float fTachoTimer{ 0.0f };
|
||||
float fTachoCount{ 0.0f };
|
||||
float fHVoltage{ 0.0f }; // napi?cie dla dynamicznych ga?ek
|
||||
float fHCurrent[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f }; // pr?dy: suma i amperomierze 1,2,3
|
||||
float fEngine[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f }; // obroty te? trzeba pobra?
|
||||
int iCarNo, iPowerNo, iUnitNo; // liczba pojazdow, czlonow napednych i jednostek spiętych ze sobą
|
||||
bool bDoors[20][5]; // drzwi dla wszystkich czlonow; left+right, left, right, step_left, step_right
|
||||
int iUnits[20]; // numer jednostki
|
||||
int iDoorNo[20]; // liczba drzwi
|
||||
char cCode[20]; // kod pojazdu
|
||||
bool bSlip[20]; // poślizg kół pojazdu
|
||||
std::string asCarName[20]; // nazwa czlonu
|
||||
bool bMains[8]; // WSy
|
||||
float fCntVol[8]; // napiecie NN
|
||||
bool bPants[8][2]; // podniesienie pantografow
|
||||
bool bFuse[8]; // nadmiarowe
|
||||
bool bBatt[8]; // baterie
|
||||
bool bConv[8]; // przetwornice
|
||||
bool bComp[8][2]; // sprezarki
|
||||
std::vector<std::tuple<bool, bool, int>> bCompressors;
|
||||
bool bHeat[8]; // grzanie
|
||||
// McZapkie: do syczenia
|
||||
float fPPress, fNPress;
|
||||
bool m_mastercontrollerinuse { false };
|
||||
float m_mastercontrollerreturndelay { 0.f };
|
||||
screenentry_sequence m_screens;
|
||||
uint16_t vid { 0 }; // train network recipient id
|
||||
float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive
|
||||
double m_brakehandlecp{ 0.0 };
|
||||
bool m_doors{ false }; // helper, true if any door is open
|
||||
bool m_doorspermitleft{ false }; // helper, true if door is open, blinking if door is pemitted
|
||||
bool m_doorspermitright{ false }; // helper, true if door is open, blinking if door is pemitted
|
||||
bool m_dirforward{ false }; // helper, true if direction set to forward
|
||||
bool m_dirneutral{ false }; // helper, true if direction set to neutral
|
||||
bool m_dirbackward{ false }; // helper, true if direction set to backward
|
||||
bool m_doorpermits{ false }; // helper, true if any door permit is active
|
||||
float m_doorpermittimers[2] = { -1.f, -1.f };
|
||||
float trainLenghtMeasureTimer = { -1.f };
|
||||
// ld substitute
|
||||
bool m_couplingdisconnect { false };
|
||||
bool m_couplingdisconnectback { false };
|
||||
float m_radiovolume { Global.DefaultRadioVolume };
|
||||
|
||||
public:
|
||||
float fPress[20][7]; // cisnienia dla wszystkich czlonow
|
||||
bool bBrakes[20][2]; // zalaczenie i dzialanie hamulcow
|
||||
static std::vector<std::string> const fPress_labels;
|
||||
float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych
|
||||
float fDieselParams[9][10]; // parametry dla silnikow asynchronicznych
|
||||
// plays provided sound from position of the radio
|
||||
bool radio_message_played;
|
||||
void radio_message( sound_source *Message, int const Channel );
|
||||
inline auto const RadioChannel() const { return ( Dynamic()->Mechanik ? Dynamic()->Mechanik->iRadioChannel : 1 ); }
|
||||
inline auto &RadioChannel() { return Dynamic()->Mechanik->iRadioChannel; }
|
||||
inline TDynamicObject *Dynamic() { return DynamicObject; };
|
||||
inline TDynamicObject const *Dynamic() const { return DynamicObject; };
|
||||
inline TMoverParameters *Controlled() { return mvControlled; };
|
||||
inline TMoverParameters const *Controlled() const { return mvControlled; };
|
||||
inline TMoverParameters *Occupied() { return mvOccupied; };
|
||||
inline TMoverParameters const *Occupied() const { return mvOccupied; };
|
||||
void DynamicSet(TDynamicObject *d);
|
||||
void MoveToVehicle( TDynamicObject *target );
|
||||
// checks whether specified point is within boundaries of the active cab
|
||||
bool point_inside( Math3D::vector3 const Point ) const;
|
||||
Math3D::vector3 clamp_inside( Math3D::vector3 const &Point ) const;
|
||||
const screenentry_sequence & get_screens();
|
||||
|
||||
uint16_t id();
|
||||
bool pending_delete = false;
|
||||
};
|
||||
|
||||
class train_table : public basic_table<TTrain> {
|
||||
public:
|
||||
void update( double dt );
|
||||
void updateAsync( double dt );
|
||||
TTrain *find_id( std::uint16_t const Id ) const;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user