mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 05:09:20 +02:00
Fix/sonar maintainability rebased (#209)
* refactor(sonar): use override instead of redundant virtual (cpp:S3471) * refactor(sonar): remove empty statements, one declaration per statement (cpp:S1116, cpp:S1659) * refactor(sonar): drop redundant lambda return types (cpp:S3574) * refactor(sonar): prefer using over typedef (cpp:S5416) * refactor(sonar): use =default for trivial special members (cpp:S3490) * refactor(sonar): use nullptr literal (cpp:S4962) * refactor(sonar): remove redundant access specifiers (cpp:S3539) * refactor(sonar): remove redundant casts (cpp:S1905) * refactor(sonar): use std::scoped_lock instead of std::lock_guard (cpp:S5997) * refactor(sonar): construct elements in place with emplace_back (cpp:S6003) * refactor(sonar): make narrowing conversions explicit (cpp:S5276) * refactor(sonar): mark unused parameters (cpp:S1172) Unused names are commented out; parameters used only on some platforms are marked [[maybe_unused]]. * refactor(sonar): declare non-mutating member functions const (cpp:S5817) Virtual functions are left untouched so overrides keep matching. * refactor(sonar): merge collapsible nested if statements (cpp:S1066) Comments that preceded the inner if are kept above the merged statement. * refactor(sonar): scope single-use variables in if init-statements (cpp:S6004) * fix(sonar): give polymorphic base classes virtual destructors (cpp:S1235) * refactor(sonar): use try_emplace for map insertion (cpp:S6030) * refactor(sonar): use auto where the type is spelled out on the right (cpp:S5827) * refactor(sonar): remove redundant parentheses (cpp:S1110) * refactor(sonar): document intentionally empty functions (cpp:S1186) * refactor(sonar): remove dead stores (cpp:S1854) Side effects (e.g. LISTLINE++) are kept. * refactor(sonar): remove unused variables, captures and private fields (cpp:S1481, cpp:S1068) * refactor(sonar): use structured bindings for pair access (cpp:S6005) * refactor(sonar): use range-based loops and ranges algorithms (cpp:S5566) * refactor(sonar): split chained assignments (cpp:S1121) * refactor(sonar): add default cases to switch statements (cpp:S3562) * refactor(sonar): use std::size for array lengths (cpp:S7127) * refactor(sonar): use std::ranges algorithms and std::erase(_if) (cpp:S6197) * refactor(sonar): access static members through the class (cpp:S2209) * refactor(sonar): add braces around nested if-else (cpp:S5261) * refactor(sonar): avoid side effects inside typeid operands (cpp:S5279) * refactor(sonar): drop top-level const from by-value return types (cpp:S5951) * refactor(sonar): declare variables separately from their type definitions (cpp:S3646) * refactor(sonar): declare loop counters in the for statement (cpp:S5955) * refactor(sonar): rely on class template argument deduction (cpp:S6012) * refactor(sonar): inherit base constructors instead of forwarding them (cpp:S5952) * refactor(sonar): rename locals that shadow outer declarations (cpp:S1117) Only local variables and definition parameters are renamed; shadowing struct fields and enumerators in headers are left for a separate change. * refactor(sonar): reduce enum qualification with using enum (cpp:S6177) Applied only where no unqualified name in the block could be captured by the introduced enumerators. * refactor(sonar): mark converting constructors explicit (cpp:S1709) sound_source and the gl::object conversion operators stay implicit; they are relied upon by copy-list-initialisation and GL calls. * refactor(sonar): initialise members in initialiser lists or declarations (cpp:S3230) * refactor(sonar): make read-only local references and pointers const (cpp:S5350) * refactor(sonar): take read-only pointer and reference parameters as const (cpp:S995) TTrain command handlers keep their signature, it is fixed by the handler table. * refactor(sonar): pass expensive-to-copy parameters by const reference (cpp:S1238) Signatures declared in files touched by PR 206 (Driver.h, EU07.cpp) and virtual overrides are left unchanged. * refactor(sonar): use transparent comparators for string-keyed maps (cpp:S6045) std::unordered_map instances and map types exposed in headers used by other modules are left as they are. * fix(sonar): do not use UI text as a printf format string (cpp:S5281) Text lines containing '%' would otherwise be interpreted as format specifiers by ImGui::TextColored. * refactor(sonar): use std::bind_front for callbacks (cpp:S5995) * refactor(sonar): drop const_cast on string literals passed to the Python C API (cpp:S859) * refactor(sonar): take read-only string parameters as std::string_view (cpp:S6009) The Windows messaging helpers keep std::string, they need c_str(). * refactor(sonar): make read-only global tables const (cpp:S5421) Mutable global state (flags, timers, singletons) is left as is. * refactor(sonar): replace single-case switch statements with if (cpp:S1301) * refactor(sonar): format UUIDs and log timestamps with std::format (cpp:S6494, cpp:S5945) * refactor(sonar): use std::array for local fixed-size arrays (cpp:S5945) Arrays that are class members or part of headers are left unchanged. * fix(sonar): test the bearing damage bit, not bit 0 (cpp:S872) 'DamageFlag & dtrain_bearing > 0' parsed as 'DamageFlag & (dtrain_bearing > 0)', i.e. DamageFlag & 1, so bearing friction reacted to the wrong damage flag. * refactor(sonar): assorted small fixes - empty() instead of size() comparisons (cpp:S1155) - member initialisers in declaration order (cpp:S3229) - no redundant c_str() when a std::string is accepted (cpp:S7121) - contains() on associative containers (cpp:S6171) - const reference instead of a copying range-for (cpp:S6032) - starts_with() for prefix checks (cpp:S6178) - no std::move on temporaries (cpp:S5274) - has_value() on std::optional (cpp:S7172) - bool literals for bool members (cpp:S5820) - inline only on the definition (cpp:S3548) - explicit base access specifier (cpp:S5965) - explicit element access instead of dereferencing an array (cpp:S7116) - rely on the C++20 rewritten operator!= (cpp:S6186) * refactor(sonar): more small fixes - std::format instead of iostream manipulators in to_string/to_hex_str (cpp:S6495); output verified identical, negative hex values keep the unsigned form - remove an empty compound statement (cpp:S108) - drop an always-false unsigned < 0 branch (cpp:S1768) - explicit lambda capture (cpp:S3608) - std::make_unique (cpp:S5950) * chore: strip stray carriage returns left in TTrain constructor comments * fix: keep quantize() in its own value type The S5276 change cast the result of the generic quantize<Type_>() to unsigned int, which truncated float/double callers (shadow angle slider, editor rotation snapping, AI speed control steps) and broke negative values. * fix(sonar): use integer loop counters in segment sampling (cpp:S2193) * refactor(sonar): clean up issues reported on PR 209 - remove locals left unused after the dead-store cleanup (cpp:S1481, cpp:S1854) - unnamed unused parameter (cpp:S1172) - single-use declarations moved into if init-statements (cpp:S6004) - auto for casted initialisers (cpp:S5827) - const references and pointers where nothing is modified (cpp:S5350) - rename structured bindings shadowed by inner declarations (cpp:S1117)
This commit is contained in:
@@ -34,14 +34,14 @@ int vk_to_glfw_key( int const Keycode ) {
|
||||
char key = 0;
|
||||
|
||||
if (Keycode < 'A') {
|
||||
key = Keycode;
|
||||
key = static_cast<char>(Keycode);
|
||||
} else if (Keycode <= 'Z') {
|
||||
key = Keycode;
|
||||
key = static_cast<char>(Keycode);
|
||||
modifier = GLFW_MOD_SHIFT;
|
||||
} else if (Keycode < 'a') {
|
||||
key = Keycode;
|
||||
key = static_cast<char>(Keycode);
|
||||
} else if (Keycode <= 'z') {
|
||||
key = Keycode - 32;
|
||||
key = static_cast<char>(Keycode - 32);
|
||||
} else {
|
||||
ErrorLog("unknown key: " + std::to_string(Keycode));
|
||||
}
|
||||
@@ -66,7 +66,7 @@ bool TEventLauncher::Load(cParser *parser)
|
||||
}
|
||||
else {
|
||||
// this launcher may be activated by radio message
|
||||
std::map<std::string, int> messages {
|
||||
std::map<std::string, int, std::less<>> messages {
|
||||
{ "radio_call1", radio_message::call1 },
|
||||
{ "radio_call3", radio_message::call3 }
|
||||
};
|
||||
@@ -138,8 +138,7 @@ bool TEventLauncher::Load(cParser *parser)
|
||||
iHour = int( DeltaTime - iMinute ) / 100; // godzina to setki
|
||||
DeltaTime = 0; // bez powtórzeń
|
||||
// potentially shift the provided time by requested offset
|
||||
auto const timeoffset{ static_cast<int>( Global.ScenarioTimeOffset * 60 ) };
|
||||
if( timeoffset != 0 ) {
|
||||
if( auto const timeoffset{ static_cast<int>( Global.ScenarioTimeOffset * 60 ) }; timeoffset != 0 ) {
|
||||
auto const adjustedtime{ clamp_circular( iHour * 60 + iMinute + timeoffset, 24 * 60 ) };
|
||||
iHour = adjustedtime / 60 % 24;
|
||||
iMinute = adjustedtime % 60;
|
||||
@@ -156,7 +155,7 @@ bool TEventLauncher::Load(cParser *parser)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TEventLauncher::check_activation_key() {
|
||||
bool TEventLauncher::check_activation_key() const {
|
||||
if (iKey <= 0)
|
||||
return false;
|
||||
|
||||
@@ -164,7 +163,7 @@ bool TEventLauncher::check_activation_key() {
|
||||
|
||||
bool result = Console::Pressed(key);
|
||||
|
||||
char modifier = iKey >> 8;
|
||||
auto modifier = static_cast<char>(iKey >> 8);
|
||||
if (modifier & GLFW_MOD_SHIFT)
|
||||
result &= Global.shiftState;
|
||||
if (modifier & GLFW_MOD_CONTROL)
|
||||
@@ -195,12 +194,10 @@ bool TEventLauncher::check_activation() {
|
||||
else {
|
||||
// jeśli nie cykliczny, to sprawdzić czas
|
||||
if( simulation::Time.data().wHour == iHour ) {
|
||||
if( simulation::Time.data().wMinute == iMinute ) {
|
||||
// zgodność czasu uruchomienia
|
||||
if( UpdatedTime < 10 ) {
|
||||
UpdatedTime = 20; // czas do kolejnego wyzwolenia?
|
||||
bCond = true;
|
||||
}
|
||||
// zgodność czasu uruchomienia
|
||||
if (simulation::Time.data().wMinute == iMinute && UpdatedTime < 10) {
|
||||
UpdatedTime = 20; // czas do kolejnego wyzwolenia?
|
||||
bCond = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -211,7 +208,7 @@ bool TEventLauncher::check_activation() {
|
||||
return bCond;
|
||||
}
|
||||
|
||||
bool TEventLauncher::check_conditions() {
|
||||
bool TEventLauncher::check_conditions() const {
|
||||
|
||||
auto bCond { true };
|
||||
|
||||
@@ -239,7 +236,7 @@ bool TEventLauncher::IsRadioActivated() const {
|
||||
float
|
||||
TEventLauncher::radius_() {
|
||||
|
||||
return std::sqrt( dRadius );
|
||||
return static_cast<float>(std::sqrt( dRadius ));
|
||||
}
|
||||
|
||||
// serialize() subclass details, sends content of the subclass to provided stream
|
||||
@@ -271,9 +268,8 @@ TEventLauncher::export_as_text_( std::ostream &Output ) const {
|
||||
// activation key
|
||||
if( iKey != 0 ) {
|
||||
auto key { iKey & 0xff };
|
||||
auto const modifier { iKey >> 8 };
|
||||
|
||||
if (key >= 'A' && key <= 'Z' && !(modifier & GLFW_MOD_SHIFT))
|
||||
if (auto const modifier { iKey >> 8 }; key >= 'A' && key <= 'Z' && !(modifier & GLFW_MOD_SHIFT))
|
||||
key += 32;
|
||||
|
||||
Output << (char)key;
|
||||
|
||||
@@ -30,10 +30,10 @@ public:
|
||||
|
||||
// methods
|
||||
bool Load( cParser *parser );
|
||||
bool check_activation_key();
|
||||
bool check_activation_key() const;
|
||||
bool check_activation();
|
||||
// checks conditions associated with the event. returns: true if the conditions are met
|
||||
bool check_conditions();
|
||||
bool check_conditions() const;
|
||||
inline
|
||||
auto key() const {
|
||||
return iKey; }
|
||||
@@ -53,13 +53,13 @@ public:
|
||||
private:
|
||||
// methods
|
||||
// radius() subclass details, calculates node's bounding radius
|
||||
float radius_();
|
||||
float radius_() override;
|
||||
// serialize() subclass details, sends content of the subclass to provided stream
|
||||
void serialize_( std::ostream &Output ) const;
|
||||
void serialize_( std::ostream &Output ) const override;
|
||||
// deserialize() subclass details, restores content of the subclass from provided stream
|
||||
void deserialize_( std::istream &Input );
|
||||
void deserialize_( std::istream &Input ) override;
|
||||
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
|
||||
void export_as_text_( std::ostream &Output ) const;
|
||||
void export_as_text_( std::ostream &Output ) const override;
|
||||
|
||||
// members
|
||||
int iKey { 0 };
|
||||
|
||||
@@ -25,7 +25,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
TMemCell::TMemCell( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
|
||||
|
||||
void TMemCell::UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask )
|
||||
void TMemCell::UpdateValues( std::string_view szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask )
|
||||
{
|
||||
if (CheckMask & basic_event::flags::mode_add)
|
||||
{ // dodawanie wartości
|
||||
@@ -51,48 +51,49 @@ void TMemCell::UpdateValues( std::string const &szNewText, double const fNewValu
|
||||
|
||||
TCommandType TMemCell::CommandCheck()
|
||||
{ // rozpoznanie komendy
|
||||
using enum TCommandType;
|
||||
if( szText == "SetVelocity" ) // najpopularniejsze
|
||||
{
|
||||
eCommand = TCommandType::cm_SetVelocity;
|
||||
eCommand = cm_SetVelocity;
|
||||
bCommand = false; // ta komenda nie jest wysyłana
|
||||
}
|
||||
else if( szText == "ShuntVelocity" ) // w tarczach manewrowych
|
||||
{
|
||||
eCommand = TCommandType::cm_ShuntVelocity;
|
||||
eCommand = cm_ShuntVelocity;
|
||||
bCommand = false; // ta komenda nie jest wysyłana
|
||||
}
|
||||
else if( szText == "Change_direction" ) // zdarza się
|
||||
{
|
||||
eCommand = TCommandType::cm_ChangeDirection;
|
||||
eCommand = cm_ChangeDirection;
|
||||
bCommand = true; // do wysłania
|
||||
}
|
||||
else if( szText == "OutsideStation" ) // zdarza się
|
||||
{
|
||||
eCommand = TCommandType::cm_OutsideStation;
|
||||
eCommand = cm_OutsideStation;
|
||||
bCommand = false; // tego nie powinno być w komórce
|
||||
}
|
||||
else if( szText.starts_with("PassengerStopPoint:") ) // porównanie początków
|
||||
{
|
||||
eCommand = TCommandType::cm_PassengerStopPoint;
|
||||
eCommand = cm_PassengerStopPoint;
|
||||
bCommand = false; // tego nie powinno być w komórce
|
||||
}
|
||||
else if( szText == "SetProximityVelocity" ) // nie powinno tego być
|
||||
{
|
||||
eCommand = TCommandType::cm_SetProximityVelocity;
|
||||
eCommand = cm_SetProximityVelocity;
|
||||
bCommand = false; // ta komenda nie jest wysyłana
|
||||
}
|
||||
else if( szText == "Emergency_brake" )
|
||||
{
|
||||
eCommand = TCommandType::cm_EmergencyBrake;
|
||||
eCommand = cm_EmergencyBrake;
|
||||
bCommand = false;
|
||||
}
|
||||
else if( szText == "CabSignal" ) {
|
||||
eCommand = TCommandType::cm_SecuritySystemMagnet;
|
||||
eCommand = cm_SecuritySystemMagnet;
|
||||
bCommand = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
eCommand = TCommandType::cm_Unknown; // ciąg nierozpoznany (nie jest komendą)
|
||||
eCommand = cm_Unknown; // ciąg nierozpoznany (nie jest komendą)
|
||||
bCommand = true; // do wysłania
|
||||
}
|
||||
return eCommand;
|
||||
@@ -157,11 +158,11 @@ bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1,
|
||||
|
||||
if( TestFlag( CheckMask, basic_event::flags::text ) ) {
|
||||
// porównać teksty
|
||||
auto range = szTestText.find( '*' );
|
||||
auto wildcardpos = szTestText.find( '*' );
|
||||
auto const result { (
|
||||
range == std::string::npos ?
|
||||
wildcardpos == std::string::npos ?
|
||||
compare( szText, szTestText, TextOperator ) :
|
||||
compare( szText.substr( 0, range ), szTestText.substr( 0, range ), TextOperator ) ) };
|
||||
compare( szText.substr( 0, wildcardpos ), szTestText.substr( 0, wildcardpos ), TextOperator ) ) };
|
||||
checkpassed |= result;
|
||||
checkfailed |= !result;
|
||||
}
|
||||
@@ -177,20 +178,22 @@ bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1,
|
||||
}
|
||||
|
||||
switch( Pass ) {
|
||||
case comparison_pass::all: { return checkfailed == false; }
|
||||
case comparison_pass::any: { return checkpassed == true; }
|
||||
case comparison_pass::none: { return checkpassed == false; }
|
||||
using enum comparison_pass;
|
||||
case all: { return checkfailed == false; }
|
||||
case any: { return checkpassed == true; }
|
||||
case none: { return checkpassed == false; }
|
||||
default: { return false; }
|
||||
}
|
||||
};
|
||||
|
||||
bool TMemCell::IsVelocity() const
|
||||
{ // sprawdzenie, czy event odczytu tej komórki ma być do skanowania, czy do kolejkowania
|
||||
if (eCommand == TCommandType::cm_SetVelocity)
|
||||
using enum TCommandType;
|
||||
if (eCommand == cm_SetVelocity)
|
||||
return true;
|
||||
if (eCommand == TCommandType::cm_ShuntVelocity)
|
||||
if (eCommand == cm_ShuntVelocity)
|
||||
return true;
|
||||
return eCommand == TCommandType::cm_SetProximityVelocity;
|
||||
return eCommand == cm_SetProximityVelocity;
|
||||
};
|
||||
|
||||
void TMemCell::StopCommandSent()
|
||||
@@ -258,7 +261,7 @@ TMemCell::export_as_text_( std::ostream &Output ) const {
|
||||
|
||||
// legacy method, initializes traction after deserialization from scenario file
|
||||
void
|
||||
memory_table::InitCells() {
|
||||
memory_table::InitCells() const {
|
||||
|
||||
for( auto *cell : m_items ) {
|
||||
// Ra: eventy komórek pamięci, wykonywane po wysłaniu komendy do zatrzymanego pojazdu
|
||||
@@ -275,9 +278,9 @@ memory_table::InitCells() {
|
||||
|
||||
// legacy method, sends content of all cells to the log
|
||||
void
|
||||
memory_table::log_all() {
|
||||
memory_table::log_all() const {
|
||||
|
||||
for( auto *cell : m_items ) {
|
||||
for( auto const *cell : m_items ) {
|
||||
cell->LogValues();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
explicit TMemCell( scene::node_data const &Nodedata );
|
||||
// methods
|
||||
void
|
||||
UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask );
|
||||
UpdateValues( std::string_view szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask );
|
||||
bool
|
||||
Load(cParser *parser);
|
||||
void
|
||||
@@ -61,11 +61,11 @@ public:
|
||||
private:
|
||||
// methods
|
||||
// serialize() subclass details, sends content of the subclass to provided stream
|
||||
void serialize_( std::ostream &Output ) const;
|
||||
void serialize_( std::ostream &Output ) const override;
|
||||
// deserialize() subclass details, restores content of the subclass from provided stream
|
||||
void deserialize_( std::istream &Input );
|
||||
void deserialize_( std::istream &Input ) override;
|
||||
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
|
||||
void export_as_text_( std::ostream &Output ) const;
|
||||
void export_as_text_( std::ostream &Output ) const override;
|
||||
|
||||
// members
|
||||
// content
|
||||
@@ -85,10 +85,10 @@ class memory_table : public basic_table<TMemCell> {
|
||||
public:
|
||||
// legacy method, initializes traction after deserialization from scenario file
|
||||
void
|
||||
InitCells();
|
||||
InitCells() const;
|
||||
// legacy method, sends content of all cells to the log
|
||||
void
|
||||
log_all();
|
||||
log_all() const;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -67,8 +67,8 @@ bool TSegment::Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 N
|
||||
CPointIn = NewCPointIn;
|
||||
Point2 = NewPoint2;
|
||||
// poprawienie przechyłki
|
||||
fRoll1 = glm::radians(fNewRoll1); // Ra: przeliczone jest bardziej przydatne do obliczeń
|
||||
fRoll2 = glm::radians(fNewRoll2);
|
||||
fRoll1 = static_cast<float>(glm::radians(fNewRoll1)); // Ra: przeliczone jest bardziej przydatne do obliczeń
|
||||
fRoll2 = static_cast<float>(glm::radians(fNewRoll2));
|
||||
bCurve = bIsCurve;
|
||||
if (Global.bRollFix)
|
||||
{ // Ra: poprawianie przechyłki
|
||||
@@ -85,7 +85,7 @@ bool TSegment::Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 N
|
||||
Point1.y += w1; // modyfikacja musi być przed policzeniem dalszych parametrów
|
||||
if (bCurve)
|
||||
CPointOut.y += w1; // prosty ma wektory jednostkowe
|
||||
pOwner->MovedUp1(w1); // zwrócić trzeba informację o podwyższeniu podsypki
|
||||
pOwner->MovedUp1(static_cast<float>(w1)); // zwrócić trzeba informację o podwyższeniu podsypki
|
||||
}
|
||||
if (fRoll2 != 0.f)
|
||||
{
|
||||
@@ -125,7 +125,7 @@ bool TSegment::Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 N
|
||||
fStep = fLength / ( 3.0 * Global.SplineFidelity );
|
||||
}
|
||||
// iSegCount = static_cast<int>( std::ceil( fLength / fStep ) ); // potrzebne do VBO
|
||||
iSegCount = pOwner->eType == tt_Switch ? 6 * Global.SplineFidelity : static_cast<int>(std::ceil(fLength / fStep)); // potrzebne do VBO
|
||||
iSegCount = pOwner->eType == tt_Switch ? static_cast<int>(6 * Global.SplineFidelity) : static_cast<int>(std::ceil(fLength / fStep)); // potrzebne do VBO
|
||||
|
||||
fStep = fLength / iSegCount; // update step to equalize size of individual pieces
|
||||
|
||||
@@ -242,7 +242,7 @@ double TSegment::FastGetTFromS(double const s) const
|
||||
double const h01 = -2.0 * u3 + 3.0 * u2;
|
||||
double const t = ( ( 1.0 - h01 ) * fTsBuffer[ i ] +
|
||||
( u3 - 2.0 * u2 + u ) * fTsSlope [ i ] +
|
||||
( h01 ) * fTsBuffer[ i + 1 ] +
|
||||
h01 * fTsBuffer[ i + 1 ] +
|
||||
( u3 - u2 ) * fTsSlope [ i + 1 ] );
|
||||
return t;
|
||||
}
|
||||
@@ -263,10 +263,11 @@ double TSegment::ComputeLength() const // McZapkie-150503: dlugosc miedzy punkta
|
||||
// Ra: koniec rekurencji jeśli po podziale suma długości nie różni się więcej niż 0.5mm od
|
||||
// poprzedniej
|
||||
// Ra: ewentualnie rozpoznać łuk okręgu płaskiego i liczyć ze wzoru na długość łuku
|
||||
double t, l = 0;
|
||||
double t;
|
||||
double l = 0;
|
||||
glm::dvec3 last{0, 0, 0}; // długość liczona po przesunięciu odcinka do początku układu
|
||||
glm::dvec3 tmp = Point2 - Point1;
|
||||
int m = 20.0 * glm::length(tmp); // było zawsze do 10000, teraz jest liczone odcinkami po około 5cm
|
||||
auto m = static_cast<int>(20.0 * glm::length(tmp)); // było zawsze do 10000, teraz jest liczone odcinkami po około 5cm
|
||||
for (int i = 1; i <= m; i++)
|
||||
{
|
||||
t = double(i) / double(m); // wyznaczenie parametru na krzywej z przedziału (0,1>
|
||||
@@ -334,7 +335,7 @@ glm::dvec3 TSegment::GetDirection(double const fDistance) const
|
||||
return FastGetPoint(t2) - FastGetPoint(t1);
|
||||
}
|
||||
|
||||
glm::dvec3 TSegment::FastGetDirection(double fDistance, double fOffset)
|
||||
glm::dvec3 TSegment::FastGetDirection(double fDistance, double fOffset) const
|
||||
{ // takie toporne liczenie pochodnej dla parametru 0.0÷1.0
|
||||
double t1 = fDistance - fOffset;
|
||||
if (t1 <= 0.0)
|
||||
@@ -371,22 +372,22 @@ void TSegment::RaPositionGet(double const fDistance, glm::dvec3 &position, glm::
|
||||
auto const t = FastGetTFromS(fDistance); // aproksymacja dystansu na krzywej Beziera na parametr (t)
|
||||
position = FastGetPoint( t );
|
||||
// przechyłka w danym miejscu (zmienia się liniowo)
|
||||
rotation.x = std::lerp( fRoll1, fRoll2, t );
|
||||
rotation.x = static_cast<float>(std::lerp( fRoll1, fRoll2, t ));
|
||||
// pochodna
|
||||
auto const tangent = GetFirstDerivative( t );
|
||||
// pochylenie krzywej (w pionie)
|
||||
rotation.y = std::atan( tangent.y );
|
||||
rotation.y = static_cast<float>(std::atan( tangent.y ));
|
||||
// kierunek krzywej w planie
|
||||
rotation.z = -std::atan2( tangent.x, tangent.z );
|
||||
rotation.z = static_cast<float>(-std::atan2( tangent.x, tangent.z ));
|
||||
}
|
||||
else {
|
||||
// wyliczenie dla odcinka prostego jest prostsze
|
||||
auto const t = fDistance / fLength; // zerowych torów nie ma
|
||||
position = FastGetPoint( t );
|
||||
// przechyłka w danym miejscu (zmienia się liniowo)
|
||||
rotation.x = std::lerp( fRoll1, fRoll2, t );
|
||||
rotation.y = fStoop; // pochylenie toru prostego
|
||||
rotation.z = fDirection; // kierunek toru w planie
|
||||
rotation.x = static_cast<float>(std::lerp( fRoll1, fRoll2, t ));
|
||||
rotation.y = static_cast<float>(fStoop); // pochylenie toru prostego
|
||||
rotation.z = static_cast<float>(fDirection); // kierunek toru w planie
|
||||
}
|
||||
};
|
||||
|
||||
@@ -404,20 +405,35 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
if( fTsBuffer.empty() )
|
||||
return false; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
|
||||
glm::vec3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
||||
float s, step, fOffset, tv1, tv2, t, fEnd;
|
||||
glm::vec3 pos1;
|
||||
glm::vec3 pos2;
|
||||
glm::vec3 dir;
|
||||
glm::vec3 parallel1;
|
||||
glm::vec3 parallel2;
|
||||
glm::vec3 pt;
|
||||
glm::vec3 norm;
|
||||
float s;
|
||||
float step;
|
||||
float fOffset;
|
||||
float tv1;
|
||||
float tv2;
|
||||
float t;
|
||||
float fEnd;
|
||||
auto const iNumShapePoints = Transition ? ShapePoints.size() / 2 : ShapePoints.size();
|
||||
float const texturelength = fTextureLength * Texturescale;
|
||||
float const texturescale = Texturescale;
|
||||
auto const texturelength = static_cast<float>(fTextureLength * Texturescale);
|
||||
auto const texturescale = static_cast<float>(Texturescale);
|
||||
|
||||
float m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step = fStep;
|
||||
float m1;
|
||||
float jmm1;
|
||||
float m2;
|
||||
float jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step = static_cast<float>(fStep);
|
||||
tv1 = 1.0; // Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
|
||||
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
|
||||
s = static_cast<float>(fStep * iSkip); // iSkip - ile odcinków z początku pominąć
|
||||
int i = iSkip; // domyślnie 0
|
||||
t = fTsBuffer[ i ]; // tabela wattości t dla segmentów
|
||||
t = static_cast<float>(fTsBuffer[ i ]); // tabela wattości t dla segmentów
|
||||
// BUG: length of spline can be 0, we should skip geometry generation for such cases
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
fOffset = static_cast<float>(0.1 / fLength); // pierwsze 10cm
|
||||
pos1 = glm::dvec3{ FastGetPoint( t ) - Origin }; // wektor początku segmentu
|
||||
dir = glm::dvec3{ FastGetDirection( t, fOffset ) }; // wektor kierunku
|
||||
parallel1 = glm::vec3{ -dir.z, 0.f, dir.x }; // wektor poprzeczny
|
||||
@@ -428,11 +444,11 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
parallel1 = glm::normalize( parallel1 );
|
||||
if( iEnd == 0 )
|
||||
iEnd = iSegCount;
|
||||
fEnd = fLength * double( iEnd ) / double( iSegCount );
|
||||
fEnd = static_cast<float>(fLength * double( iEnd ) / double( iSegCount ));
|
||||
/*
|
||||
m2 = s / fEnd;
|
||||
*/
|
||||
m2 = static_cast<float>( i - iSkip ) / ( iEnd - iSkip );
|
||||
m2 = static_cast<float>( i - iSkip ) / ( static_cast<float>(iEnd - iSkip) );
|
||||
|
||||
jmm2 = 1.f - m2;
|
||||
|
||||
@@ -445,7 +461,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
/*
|
||||
m2 = s / fEnd;
|
||||
*/
|
||||
m2 = static_cast<float>( i - iSkip ) / ( iEnd - iSkip );
|
||||
m2 = static_cast<float>( i - iSkip ) / ( static_cast<float>(iEnd - iSkip) );
|
||||
|
||||
jmm2 = 1.f - m2; // nowa pozycja
|
||||
if( i == iEnd ) { // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
@@ -462,7 +478,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
tv1 = clamp_circular( tv1, 1.0f );
|
||||
tv2 = tv1 - step / texturelength; // mapowanie na końcu segmentu
|
||||
|
||||
t = fTsBuffer[ i ]; // szybsze od GetTFromS(s);
|
||||
t = static_cast<float>(fTsBuffer[ i ]); // szybsze od GetTFromS(s);
|
||||
pos2 = glm::dvec3{ FastGetPoint( t ) - Origin };
|
||||
dir = glm::dvec3{ FastGetDirection( t, fOffset ) }; // nowy wektor kierunku
|
||||
parallel2 = glm::vec3{ -dir.z, 0.f, dir.x }; // wektor poprzeczny
|
||||
@@ -486,13 +502,12 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
glm::normalize( norm ),
|
||||
glm::vec2 { ( jmm1 * ShapePoints[ j ].texture.x + m1 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv1 } );
|
||||
}
|
||||
if( p ) // jeśli jest wskaźnik do tablicy
|
||||
if( *p )
|
||||
if( !j ) // to dla pierwszego punktu
|
||||
{
|
||||
**p = pt;
|
||||
( *p )++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
// jeśli jest wskaźnik do tablicy
|
||||
if (p && *p && !j) // to dla pierwszego punktu
|
||||
{
|
||||
**p = pt;
|
||||
( *p )++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
pt = parallel2 * ( jmm2 * ( ShapePoints[ j ].position.x - fOffsetX.first ) + m2 * ( ShapePoints[ j + iNumShapePoints ].position.x - fOffsetX.second ) ) + pos2;
|
||||
pt.y += jmm2 * ShapePoints[ j ].position.y + m2 * ShapePoints[ j + iNumShapePoints ].position.y;
|
||||
@@ -505,13 +520,12 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
glm::normalize( norm ),
|
||||
glm::vec2 { ( jmm2 * ShapePoints[ j ].texture.x + m2 * ShapePoints[ j + iNumShapePoints ].texture.x ) / texturescale, tv2 } );
|
||||
}
|
||||
if( p ) // jeśli jest wskaźnik do tablicy
|
||||
if( *p )
|
||||
if( !j ) // to dla pierwszego punktu
|
||||
if( i == iSegCount ) {
|
||||
**p = pt;
|
||||
( *p )++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
// jeśli jest wskaźnik do tablicy
|
||||
// to dla pierwszego punktu
|
||||
if (p && *p && !j && i == iSegCount) {
|
||||
**p = pt;
|
||||
( *p )++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -549,39 +563,38 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin,
|
||||
|
||||
void TSegment::render_lines(std::vector<gfx::basic_vertex> &out, float quality) const
|
||||
{
|
||||
float step = 1.0f / iSegCount / quality;
|
||||
float step = 1.0f / static_cast<float>(iSegCount) / quality;
|
||||
|
||||
float x;
|
||||
|
||||
glm::vec3 previous = FastGetPoint(0.0);
|
||||
|
||||
for (x = step; x <= 1.0f; x += step) {
|
||||
out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f)));
|
||||
for (int i = 1; static_cast<float>(i) * step <= 1.0f; ++i) {
|
||||
float const x = static_cast<float>(i) * step;
|
||||
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
|
||||
|
||||
previous = glm::vec3(FastGetPoint(x));
|
||||
out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f)));
|
||||
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
|
||||
}
|
||||
|
||||
out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f)));
|
||||
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
|
||||
|
||||
previous = glm::vec3(FastGetPoint(1.0));
|
||||
out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f)));
|
||||
out.emplace_back(previous, glm::vec3(0.0f), glm::vec2(0.0f));
|
||||
}
|
||||
|
||||
glm::vec3 TSegment::get_nearest_point(const glm::dvec3 &point, float quality) const
|
||||
{
|
||||
float step = 1.0f / iSegCount / quality;
|
||||
float step = 1.0f / static_cast<float>(iSegCount) / quality;
|
||||
|
||||
float x;
|
||||
|
||||
glm::vec3 nearest;
|
||||
float min = std::numeric_limits<float>::max();
|
||||
|
||||
for (x = step; x <= 1.0f; x += step) {
|
||||
for (int i = 1; static_cast<float>(i) * step <= 1.0f; ++i) {
|
||||
float const x = static_cast<float>(i) * step;
|
||||
glm::vec3 p1 = FastGetPoint(x);
|
||||
glm::vec3 p2 = FastGetPoint(glm::min(1.0f, x + step));
|
||||
|
||||
if (p1 != p2) {
|
||||
if (glm::vec3 p2 = FastGetPoint(glm::min(1.0f, x + step)); p1 != p2) {
|
||||
float l2 = glm::distance2(p1, p2);
|
||||
float t = glm::max(0.0f, glm::min(1.0f, glm::dot((glm::vec3)point - p1, p2 - p1) / l2));
|
||||
glm::vec3 proj = p1 + t * (p2 - p1);
|
||||
|
||||
@@ -41,10 +41,12 @@ struct segment_data {
|
||||
class TSegment
|
||||
{ // aproksymacja toru (zwrotnica ma dwa takie, jeden z nich jest aktywny)
|
||||
private:
|
||||
glm::dvec3 Point1, CPointOut, CPointIn, Point2;
|
||||
float
|
||||
fRoll1 { 0.f },
|
||||
fRoll2 { 0.f }; // przechyłka na końcach
|
||||
glm::dvec3 Point1;
|
||||
glm::dvec3 CPointOut;
|
||||
glm::dvec3 CPointIn;
|
||||
glm::dvec3 Point2;
|
||||
float fRoll1 { 0.f };
|
||||
float fRoll2 { 0.f }; // przechyłka na końcach
|
||||
double fLength { -1.0 }; // długość policzona
|
||||
std::vector<double> fTsBuffer; // wartości parametru krzywej t dla równych odcinków s
|
||||
std::vector<double> fTsSlope; // nachylenie dt/du (= dt/ds * fStep) w tych samych punktach
|
||||
@@ -52,7 +54,9 @@ class TSegment
|
||||
int iSegCount = 0; // ilość odcinków do rysowania krzywej
|
||||
double fDirection = 0.0; // Ra: kąt prostego w planie; dla łuku kąt od Point1
|
||||
double fStoop = 0.0; // Ra: kąt wzniesienia; dla łuku od Point1
|
||||
glm::dvec3 vA, vB, vC; // współczynniki wielomianów trzeciego stopnia vD==Point1
|
||||
glm::dvec3 vA;
|
||||
glm::dvec3 vB;
|
||||
glm::dvec3 vC; // współczynniki wielomianów trzeciego stopnia vD==Point1
|
||||
TTrack *pOwner = nullptr; // wskaźnik na właściciela
|
||||
|
||||
glm::dvec3 GetFirstDerivative(double const fTime) const;
|
||||
@@ -66,7 +70,7 @@ class TSegment
|
||||
public:
|
||||
bool bCurve = false;
|
||||
|
||||
TSegment(TTrack *owner);
|
||||
explicit TSegment(TTrack *owner);
|
||||
bool Init(glm::dvec3 NewPoint1, glm::dvec3 NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0);
|
||||
bool Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 NewCPointIn, glm::dvec3 &NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0, bool bIsCurve = true);
|
||||
double
|
||||
@@ -89,7 +93,7 @@ public:
|
||||
GetDirection() const {
|
||||
return CPointOut; };
|
||||
glm::dvec3
|
||||
FastGetDirection(double const fDistance, double const fOffset);
|
||||
FastGetDirection(double const fDistance, double const fOffset) const;
|
||||
/*
|
||||
Math3D::vector3
|
||||
GetPoint(double const fDistance) const;
|
||||
|
||||
@@ -13,19 +13,18 @@ http://mozilla.org/MPL/2.0/.
|
||||
void TSpring::Init(double nKs, double nKd) {
|
||||
Ks = nKs;
|
||||
Kd = nKd;
|
||||
ks = Ks;
|
||||
kd = Kd;
|
||||
ks = static_cast<float>(Ks);
|
||||
kd = static_cast<float>(Kd);
|
||||
}
|
||||
|
||||
glm::dvec3 TSpring::ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2) {
|
||||
glm::dvec3 TSpring::ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2) const {
|
||||
glm::vec3 springForce;
|
||||
// p1 = &system[spring->p1];
|
||||
// p2 = &system[spring->p2];
|
||||
// VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance
|
||||
auto deltaP = pPosition1 - pPosition2;
|
||||
// dist = VectorLength(&deltaP); // Magnitude of deltaP
|
||||
auto dist = glm::length(deltaP);
|
||||
if( dist > restLen ) {
|
||||
if( auto dist = glm::length(deltaP); dist > restLen ) {
|
||||
|
||||
// Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest)
|
||||
auto Hterm = ( dist - restLen ) * Ks; // Ks * (dist - rest)
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
// void Init(TParticnp1, TParticle *np2, double nKs= 0.5f, double nKd= 0.002f,
|
||||
// double nrestLen= -1.0f);
|
||||
void Init(double nKs = 0.5f, double nKd = 0.002f);
|
||||
glm::dvec3 ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2);
|
||||
glm::dvec3 ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2) const;
|
||||
//private:
|
||||
// members
|
||||
double restLen { 0.01 }; // LENGTH OF SPRING AT REST
|
||||
|
||||
@@ -114,10 +114,9 @@ TTraction::Load( cParser *parser, glm::dvec3 const &pOrigin ) {
|
||||
// SKB70-C, CuCd70-2C, KB95-2C, C95-C, C95-2C, YC95-2C, YpC95-2C, YC120-2C
|
||||
// YpC120-2C, YzC120-2C, YwsC120-2C, YC150-C150, YC150-2C150, C150-C150
|
||||
// C120-2C, 2C120-2C, 2C120-2C-1, 2C120-2C-2, 2C120-2C-3, 2C120-2C-4
|
||||
auto const material = parser->getToken<std::string>();
|
||||
// 1=miedziana, rysuje się na zielono albo czerwono
|
||||
// 2=aluminiowa, rysuje się na czarno
|
||||
if( material == "none" ) { Material = 0; }
|
||||
if( auto const material = parser->getToken<std::string>(); material == "none" ) { Material = 0; }
|
||||
else if( material == "al" ) { Material = 2; }
|
||||
else { Material = 1; }
|
||||
parser->getTokens( 2 );
|
||||
@@ -131,7 +130,7 @@ TTraction::Load( cParser *parser, glm::dvec3 const &pOrigin ) {
|
||||
auto const minheight { parser->getToken<double>() };
|
||||
fHeightDifference = ( pPoint3.y - pPoint1.y + pPoint4.y - pPoint2.y ) * 0.5 - minheight;
|
||||
auto const segmentlength { parser->getToken<double>() };
|
||||
iNumSections = segmentlength ? glm::length(pPoint1 - pPoint2) / segmentlength : 0;
|
||||
iNumSections = segmentlength != 0.0 ? static_cast<int>(glm::length(pPoint1 - pPoint2) / segmentlength) : 0;
|
||||
parser->getTokens( 2 );
|
||||
*parser
|
||||
>> Wires
|
||||
@@ -164,7 +163,7 @@ TTraction::endpoints() const {
|
||||
}
|
||||
|
||||
std::size_t
|
||||
TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
TTraction::create_geometry( gfx::geometrybank_handle const &Geometrybank ) {
|
||||
if( m_geometry != null_handle ) {
|
||||
return GfxRenderer->Vertices( m_geometry ).size() / 2;
|
||||
}
|
||||
@@ -175,7 +174,8 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
if( Wires == 2 )
|
||||
WireOffset = 0;
|
||||
// jezdny
|
||||
gfx::basic_vertex startvertex, endvertex;
|
||||
gfx::basic_vertex startvertex;
|
||||
gfx::basic_vertex endvertex;
|
||||
startvertex.position =
|
||||
glm::vec3(
|
||||
pPoint1.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - m_origin.x,
|
||||
@@ -189,7 +189,12 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
vertices.emplace_back( startvertex );
|
||||
vertices.emplace_back( endvertex );
|
||||
// Nie wiem co 'Marcin
|
||||
glm::dvec3 pt1, pt2, pt3, pt4, v1, v2;
|
||||
glm::dvec3 pt1;
|
||||
glm::dvec3 pt2;
|
||||
glm::dvec3 pt3;
|
||||
glm::dvec3 pt4;
|
||||
glm::dvec3 v1;
|
||||
glm::dvec3 v2;
|
||||
v1 = pPoint4 - pPoint3;
|
||||
v2 = pPoint2 - pPoint1;
|
||||
float step = 0;
|
||||
@@ -207,7 +212,7 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
pPoint3.z - m_origin.z );
|
||||
for( int i = 0; i < iNumSections - 1; ++i ) {
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
t = 1 - std::fabs(f - mid) * 2;
|
||||
t = static_cast<float>(1 - std::fabs(f - mid) * 2);
|
||||
if( Wires < 4
|
||||
|| ( i != 0
|
||||
&& i != iNumSections - 2 ) ) {
|
||||
@@ -256,7 +261,7 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
pPoint3.z - m_origin.z );
|
||||
for( int i = 0; i < iNumSections - 1; ++i ) {
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
t = 1 - std::fabs(f - mid) * 2;
|
||||
t = static_cast<float>(1 - std::fabs(f - mid) * 2);
|
||||
endvertex.position =
|
||||
glm::vec3(
|
||||
pt3.x - m_origin.x,
|
||||
@@ -288,7 +293,7 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
for( int i = 0; i < iNumSections - 1; ++i ) {
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
pt4 = pPoint1 + v2 * f;
|
||||
t = 1 - std::fabs(f - mid) * 2;
|
||||
t = static_cast<float>(1 - std::fabs(f - mid) * 2);
|
||||
if( i % 2 == 0 ) {
|
||||
startvertex.position =
|
||||
glm::vec3(
|
||||
@@ -338,12 +343,12 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
|
||||
auto const elementcount = vertices.size() / 2;
|
||||
|
||||
gfx::userdata_array empty_userdata{};
|
||||
m_geometry = GfxRenderer->Insert( vertices, empty_userdata, Bank, GL_LINES );
|
||||
m_geometry = GfxRenderer->Insert( vertices, empty_userdata, Geometrybank, GL_LINES );
|
||||
|
||||
return elementcount;
|
||||
}
|
||||
|
||||
int TTraction::TestPoint(glm::dvec3 const &Point)
|
||||
int TTraction::TestPoint(glm::dvec3 const &Point) const
|
||||
{ // sprawdzanie, czy przęsła można połączyć
|
||||
if( hvNext[0] == nullptr
|
||||
&& glm::all(glm::epsilonEqual(Point, pPoint1, 0.025)) ) {
|
||||
@@ -410,7 +415,8 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
|
||||
{ //(this) jest przęsłem zasilanym, o rezystancji (r), policzyć rezystancję zastępczą sąsiednich
|
||||
if (d >= 0)
|
||||
{ // podążanie we wskazanym kierunku
|
||||
TTraction *t = hvNext[d], *p;
|
||||
TTraction *t = hvNext[d];
|
||||
TTraction const *p;
|
||||
if (ps)
|
||||
psPower[d ^ 1] = ps; // podłączenie podanego
|
||||
else
|
||||
@@ -432,7 +438,7 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
|
||||
}
|
||||
}
|
||||
t->psPower[d] = ps; // skopiowanie wskaźnika zasilacza od danej strony
|
||||
t->fResistance[d] = r; // wpisanie rezystancji w kierunku tego zasilacza
|
||||
t->fResistance[d] = static_cast<float>(r); // wpisanie rezystancji w kierunku tego zasilacza
|
||||
r += t->fResistivity * glm::length(t->vParametric); // doliczenie oporu kolejnego odcinka
|
||||
p = t; // zapamiętanie dotychczasowego
|
||||
t = p->hvNext[d ^ 1]; // podążanie w tę samą stronę
|
||||
@@ -457,17 +463,18 @@ void TTraction::PowerSet(TTractionPowerSource *ps)
|
||||
else
|
||||
{ // ustalenie punktu zasilania (nie ma jeszcze połączeń między przęsłami)
|
||||
psPowered = ps; // ustawienie bezpośredniego zasilania dla przęsła
|
||||
psPower[0] = psPower[1] = ps; // a to chyba nie jest dobry pomysł, bo nawet zasilane przęsło
|
||||
psPower[0] = ps; // a to chyba nie jest dobry pomysł, bo nawet zasilane przęsło
|
||||
psPower[1] = ps;
|
||||
// powinno mieć wskazania na inne
|
||||
fResistance[0] = fResistance[1] = 0.0; // a liczy się tylko rezystancja zasilacza
|
||||
fResistance[0] = 0.0; // a liczy się tylko rezystancja zasilacza
|
||||
fResistance[1] = 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
double TTraction::VoltageGet(double u, double i)
|
||||
{ // pobranie napięcia na przęśle po podłączeniu do niego rezystancji (res) - na razie jest to prąd
|
||||
if (!psSection)
|
||||
if (!psPowered)
|
||||
return NominalVoltage; // jak nie ma zasilacza, to napięcie podane w przęśle
|
||||
if (!psSection && !psPowered)
|
||||
return NominalVoltage; // jak nie ma zasilacza, to napięcie podane w przęśle
|
||||
// na początek można założyć, że wszystkie podstacje mają to samo napięcie i nie płynie prąd
|
||||
// pomiędzy nimi
|
||||
// dla danego przęsła mamy 3 źródła zasilania
|
||||
@@ -485,8 +492,12 @@ double TTraction::VoltageGet(double u, double i)
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double r0t, r1t, r0g, r1g;
|
||||
double i0, i1;
|
||||
double r0t;
|
||||
double r1t;
|
||||
double r0g;
|
||||
double r1g;
|
||||
double i0;
|
||||
double i1;
|
||||
r0t = fResistance[0]; //średni pomysł, ale lepsze niż nic
|
||||
r1t = fResistance[1]; // bo nie uwzględnia spadków z innych pojazdów
|
||||
if (psPower[0] && psPower[1])
|
||||
@@ -729,29 +740,25 @@ traction_table::InitTraction() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( traction->hvNext[ 0 ] ) {
|
||||
// jeśli został podłączony
|
||||
if( traction->psSection != nullptr
|
||||
&& matchingtraction->psSection != nullptr ) {
|
||||
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
|
||||
if( traction->psSection != matchingtraction->psSection ) {
|
||||
// połączone odcinki mają różne zasilacze
|
||||
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
|
||||
if( true == traction->psSection->bSection
|
||||
&& false == matchingtraction->psSection->bSection ) {
|
||||
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
|
||||
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
|
||||
}
|
||||
else if( false == traction->psSection->bSection
|
||||
&& true == matchingtraction->psSection->bSection ) {
|
||||
//(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
|
||||
traction->PowerSet( matchingtraction->psSection ); // zastąpienie wskazaniem sekcji
|
||||
}
|
||||
else {
|
||||
// jeśli obie to sekcje albo obie podstacje, to będzie błąd
|
||||
ErrorLog( "Bad scenario: faulty traction power connection at location " + to_string( traction->pPoint1 ) );
|
||||
}
|
||||
}
|
||||
// jeśli został podłączony
|
||||
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
|
||||
if (traction->hvNext[ 0 ] && traction->psSection != nullptr
|
||||
&& matchingtraction->psSection != nullptr && traction->psSection != matchingtraction->psSection) {
|
||||
// połączone odcinki mają różne zasilacze
|
||||
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
|
||||
if( true == traction->psSection->bSection
|
||||
&& false == matchingtraction->psSection->bSection ) {
|
||||
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
|
||||
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
|
||||
}
|
||||
else if( false == traction->psSection->bSection
|
||||
&& true == matchingtraction->psSection->bSection ) {
|
||||
//(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
|
||||
traction->PowerSet( matchingtraction->psSection ); // zastąpienie wskazaniem sekcji
|
||||
}
|
||||
else {
|
||||
// jeśli obie to sekcje albo obie podstacje, to będzie błąd
|
||||
ErrorLog( "Bad scenario: faulty traction power connection at location " + to_string( traction->pPoint1 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -768,28 +775,24 @@ traction_table::InitTraction() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( traction->hvNext[ 1 ] ) {
|
||||
// jeśli został podłączony
|
||||
if( traction->psSection != nullptr
|
||||
&& matchingtraction->psSection != nullptr ) {
|
||||
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
|
||||
if( traction->psSection != matchingtraction->psSection ) {
|
||||
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
|
||||
if( true == traction->psSection->bSection
|
||||
&& false == matchingtraction->psSection->bSection ) {
|
||||
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
|
||||
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
|
||||
}
|
||||
else if( false == traction->psSection->bSection
|
||||
&& true == matchingtraction->psSection->bSection ) {
|
||||
//(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
|
||||
traction->PowerSet( matchingtraction->psSection ); // zastąpienie wskazaniem sekcji
|
||||
}
|
||||
else {
|
||||
// jeśli obie to sekcje albo obie podstacje, to będzie błąd
|
||||
ErrorLog( "Bad scenario: faulty traction power connection at location " + to_string( traction->pPoint2 ) );
|
||||
}
|
||||
}
|
||||
// jeśli został podłączony
|
||||
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
|
||||
if (traction->hvNext[ 1 ] && traction->psSection != nullptr
|
||||
&& matchingtraction->psSection != nullptr && traction->psSection != matchingtraction->psSection) {
|
||||
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
|
||||
if( true == traction->psSection->bSection
|
||||
&& false == matchingtraction->psSection->bSection ) {
|
||||
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
|
||||
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
|
||||
}
|
||||
else if( false == traction->psSection->bSection
|
||||
&& true == matchingtraction->psSection->bSection ) {
|
||||
//(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
|
||||
traction->PowerSet( matchingtraction->psSection ); // zastąpienie wskazaniem sekcji
|
||||
}
|
||||
else {
|
||||
// jeśli obie to sekcje albo obie podstacje, to będzie błąd
|
||||
ErrorLog( "Bad scenario: faulty traction power connection at location " + to_string( traction->pPoint2 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -822,8 +825,7 @@ traction_table::InitTraction() {
|
||||
}
|
||||
else if( traction->hvParallel == nullptr ) {
|
||||
// jeśli jeszcze nie został włączony w kółko
|
||||
auto *nTemp = find( traction->asParallel );
|
||||
if( nTemp != nullptr ) {
|
||||
if( auto *nTemp = find( traction->asParallel ); nTemp != nullptr ) {
|
||||
// o ile zostanie znalezione przęsło o takiej nazwie
|
||||
if( nTemp->hvParallel == nullptr ) {
|
||||
// jeśli tamten jeszcze nie ma wskaźnika bieżni wspólnej
|
||||
|
||||
@@ -29,8 +29,10 @@ class TTraction : public scene::basic_node
|
||||
TTraction *hvNext[ 2 ] { nullptr, nullptr }; //łączenie drutów w sieć
|
||||
int iNext[ 2 ] { 0, 0 }; // do którego końca się łączy
|
||||
int iLast { 0 }; //że niby ostatni drut // ustawiony bit 0, jeśli jest ostatnim drutem w sekcji; bit1 - przedostatni
|
||||
public:
|
||||
glm::dvec3 pPoint1, pPoint2, pPoint3, pPoint4;
|
||||
glm::dvec3 pPoint1;
|
||||
glm::dvec3 pPoint2;
|
||||
glm::dvec3 pPoint3;
|
||||
glm::dvec3 pPoint4;
|
||||
glm::dvec3 vParametric; // współczynniki równania parametrycznego odcinka
|
||||
double fHeightDifference { 0.0 };
|
||||
int iNumSections { 0 };
|
||||
@@ -66,7 +68,7 @@ class TTraction : public scene::basic_node
|
||||
// creates geometry data in specified geometry bank. returns: number of created elements, or NULL
|
||||
// NOTE: deleting nodes doesn't currently release geometry data owned by the node. TODO: implement erasing individual geometry chunks and banks
|
||||
std::size_t create_geometry( gfx::geometrybank_handle const &Bank );
|
||||
int TestPoint(glm::dvec3 const &Point);
|
||||
int TestPoint(glm::dvec3 const &Point) const;
|
||||
void Connect(int my, TTraction *with, int to);
|
||||
void Init();
|
||||
bool WhereIs();
|
||||
@@ -78,13 +80,13 @@ private:
|
||||
// methods
|
||||
glm::vec3 wire_color() const;
|
||||
// radius() subclass details, calculates node's bounding radius
|
||||
float radius_();
|
||||
float radius_() override;
|
||||
// serialize() subclass details, sends content of the subclass to provided stream
|
||||
void serialize_( std::ostream &Output ) const;
|
||||
void serialize_( std::ostream &Output ) const override;
|
||||
// deserialize() subclass details, restores content of the subclass from provided stream
|
||||
void deserialize_( std::istream &Input );
|
||||
void deserialize_( std::istream &Input ) override;
|
||||
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
|
||||
void export_as_text_( std::ostream &Output ) const;
|
||||
void export_as_text_( std::ostream &Output ) const override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ double TTractionPowerSource::CurrentGet(double res)
|
||||
}
|
||||
if (res > 0 || (res < 0 && (Recuperation || true)))
|
||||
TotalAdmitance += 1.0 / res; // połączenie równoległe rezystancji jest równoważne sumie admitancji
|
||||
float NomVolt = TotalPreviousAdmitance < 0 ? NominalVoltage * 1.083 : NominalVoltage;
|
||||
float NomVolt = TotalPreviousAdmitance < 0 ? static_cast<float>(NominalVoltage * 1.083) : static_cast<float>(NominalVoltage);
|
||||
TotalCurrent = TotalPreviousAdmitance != 0.0 ?
|
||||
NomVolt / (InternalRes + 1.0 / TotalPreviousAdmitance) :
|
||||
0.0; // napięcie dzielone przez sumę rezystancji wewnętrznej i obciążenia
|
||||
|
||||
@@ -19,7 +19,7 @@ class TTractionPowerSource : public scene::basic_node {
|
||||
|
||||
public:
|
||||
// constructor
|
||||
TTractionPowerSource( scene::node_data const &Nodedata );
|
||||
explicit TTractionPowerSource( scene::node_data const &Nodedata );
|
||||
// methods
|
||||
void Init(double const u, double const i);
|
||||
bool Load(cParser *parser);
|
||||
@@ -38,11 +38,11 @@ public:
|
||||
private:
|
||||
// methods
|
||||
// serialize() subclass details, sends content of the subclass to provided stream
|
||||
void serialize_( std::ostream &Output ) const;
|
||||
void serialize_( std::ostream &Output ) const override;
|
||||
// deserialize() subclass details, restores content of the subclass from provided stream
|
||||
void deserialize_( std::istream &Input );
|
||||
void deserialize_( std::istream &Input ) override;
|
||||
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
|
||||
void export_as_text_( std::ostream &Output ) const;
|
||||
void export_as_text_( std::ostream &Output ) const override;
|
||||
|
||||
// members
|
||||
double NominalVoltage = 0.0;
|
||||
|
||||
@@ -14,7 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "utilities/dictionary.h"
|
||||
#include "utilities/utilities.h"
|
||||
|
||||
double TTrainParameters::CheckTrainLatency()
|
||||
double TTrainParameters::CheckTrainLatency() const
|
||||
{
|
||||
if (LastStationLatency > 1.0 || LastStationLatency < 0)
|
||||
return LastStationLatency; /*spoznienie + lub do przodu - z tolerancja 1 min*/
|
||||
@@ -22,7 +22,7 @@ double TTrainParameters::CheckTrainLatency()
|
||||
return 0;
|
||||
}
|
||||
|
||||
double TTrainParameters::WatchMTable(double DistCounter)
|
||||
double TTrainParameters::WatchMTable(double DistCounter) const
|
||||
{ // zwraca odleglość do najblizszej stacji z zatrzymaniem
|
||||
double dist;
|
||||
|
||||
@@ -105,7 +105,7 @@ bool TTrainParameters::UpdateMTable( scenario_time const &Time, std::string cons
|
||||
return UpdateMTable( Time.data().wHour, Time.data().wMinute + Time.data().wSecond * 0.0167, NewName );
|
||||
}
|
||||
|
||||
bool TTrainParameters::UpdateMTable(double hh, double mm, std::string const &NewName)
|
||||
bool TTrainParameters::UpdateMTable(double hh, double mm, std::string_view NewName)
|
||||
/*odfajkowanie dojechania do stacji (NewName) i przeliczenie opóźnienia*/
|
||||
{
|
||||
bool OK;
|
||||
@@ -163,7 +163,7 @@ void TTrainParameters::StationIndexInc()
|
||||
++StationIndex;
|
||||
}
|
||||
|
||||
bool TTrainParameters::IsTimeToGo(double hh, double mm)
|
||||
bool TTrainParameters::IsTimeToGo(double hh, double mm) const
|
||||
// sprawdzenie, czy można już odjechać z aktualnego zatrzymania
|
||||
// StationIndex to numer następnego po dodarciu do aktualnego
|
||||
{
|
||||
@@ -205,7 +205,7 @@ TTrainParameters::TTrainParameters(std::string const &NewTrainName)
|
||||
NewName(NewTrainName);
|
||||
}
|
||||
|
||||
void TTrainParameters::NewName(std::string const &NewTrainName)
|
||||
void TTrainParameters::NewName(std::string_view NewTrainName)
|
||||
/*wstępne ustawienie parametrów rozkładu jazdy*/
|
||||
{
|
||||
TrainName = NewTrainName;
|
||||
@@ -217,9 +217,9 @@ void TTrainParameters::NewName(std::string const &NewTrainName)
|
||||
Direction = 1;
|
||||
Relation1 = "";
|
||||
Relation2 = "";
|
||||
for (int i = 0; i < MaxTTableSize + 1; ++i)
|
||||
for (auto &tableline : TimeTable)
|
||||
{
|
||||
TimeTable[ i ] = TMTableLine();
|
||||
tableline = TMTableLine();
|
||||
}
|
||||
TTVmax = 100; /*wykasowac*/
|
||||
BrakeRatio = 0;
|
||||
@@ -227,7 +227,7 @@ void TTrainParameters::NewName(std::string const &NewTrainName)
|
||||
LocLoad = 0;
|
||||
}
|
||||
|
||||
void TTrainParameters::UpdateVelocity(int StationCount, double vActual)
|
||||
void TTrainParameters::UpdateVelocity(int /*Stationcount*/, double vActual)
|
||||
// zapisywanie prędkości maksymalnej do wcześniejszych odcinków
|
||||
// wywoływane z numerem ostatniego przetworzonego przystanku
|
||||
{
|
||||
@@ -235,7 +235,7 @@ void TTrainParameters::UpdateVelocity(int StationCount, double vActual)
|
||||
// TTVmax:=vActual; {PROWIZORKA!!!}
|
||||
while (i >= 0 && TimeTable[i].vmax == -1)
|
||||
{
|
||||
TimeTable[i].vmax = vActual; // prędkość dojazdu do przystanku i
|
||||
TimeTable[i].vmax = static_cast<float>(vActual); // prędkość dojazdu do przystanku i
|
||||
--i; // ewentualnie do poprzedniego też
|
||||
}
|
||||
}
|
||||
@@ -245,7 +245,7 @@ void TTrainParameters::UpdateVelocity(int StationCount, double vActual)
|
||||
// return false;
|
||||
//}
|
||||
|
||||
bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
bool TTrainParameters::LoadTTfile(std::string const &scnpath, int iPlus, double vmax)
|
||||
// wczytanie pliku-tabeli z rozkładem przesuniętym o (fPlus); (vMax) nie ma znaczenia
|
||||
{
|
||||
std::string lines;
|
||||
@@ -254,7 +254,7 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
bool EndTable;
|
||||
double vActual;
|
||||
|
||||
int ConversionError = 0;
|
||||
int conversionerror = 0;
|
||||
EndTable = false;
|
||||
if (TrainName == "")
|
||||
{ // jeśli pusty rozkład
|
||||
@@ -262,7 +262,6 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
}
|
||||
else
|
||||
{
|
||||
ConversionError = 666;
|
||||
vActual = -1;
|
||||
s = scnpath + TrainName + ".txt";
|
||||
replace_slashes(s);
|
||||
@@ -278,15 +277,15 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
{
|
||||
TTVmax = vmax; // Ra 2014-07: zamiast rozkładu można podać Vmax
|
||||
UpdateVelocity(StationCount, vmax); // ograniczenie do prędkości startowej
|
||||
ConversionError = 0;
|
||||
conversionerror = 0;
|
||||
}
|
||||
else
|
||||
ConversionError = -8; /*Ra: ten błąd jest niepotrzebny*/
|
||||
conversionerror = -8; /*Ra: ten błąd jest niepotrzebny*/
|
||||
}
|
||||
else
|
||||
{ /*analiza rozkładu jazdy*/
|
||||
ConversionError = 0;
|
||||
while (fin.good() && !(ConversionError != 0 || EndTable))
|
||||
conversionerror = 0;
|
||||
while (fin.good() && !(conversionerror != 0 || EndTable))
|
||||
{
|
||||
std::getline(fin, lines); /*wczytanie linii*/
|
||||
if (contains( lines, "___________________") ) /*linia pozioma górna*/
|
||||
@@ -354,7 +353,7 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
win1250_to_ascii( Relation1 );
|
||||
}
|
||||
else
|
||||
ConversionError = -5;
|
||||
conversionerror = -5;
|
||||
while (fin >> s || !fin.bad())
|
||||
{
|
||||
if (s == "Relacja")
|
||||
@@ -409,10 +408,10 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
if (s == "[")
|
||||
fin >> s;
|
||||
else
|
||||
ConversionError = -4;
|
||||
conversionerror = -4;
|
||||
if (false == contains( s,"|") )
|
||||
{
|
||||
record->km = atof(s.c_str());
|
||||
record->km = static_cast<float>(atof(s.c_str()));
|
||||
fin >> s;
|
||||
}
|
||||
if (contains( s,"|_____|")) /*zmiana predkosci szlakowej*/
|
||||
@@ -439,12 +438,12 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
if (contains( s, hrsd) )
|
||||
{
|
||||
record->Ah = atoi( s.substr(0, s.find(hrsd)).c_str()); // godzina przyjazdu
|
||||
record->Am = atof(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta przyjazdu
|
||||
record->Am = static_cast<float>(atof(s.substr(s.find(hrsd) + 1, s.length()).c_str())); // minuta przyjazdu
|
||||
}
|
||||
else
|
||||
{
|
||||
record->Ah = TimeTable[StationCount - 1].Ah; // godzina z poprzedniej pozycji
|
||||
record->Am = atof(s.c_str()); // bo tylko minuty podane
|
||||
record->Am = static_cast<float>(atof(s.c_str())); // bo tylko minuty podane
|
||||
}
|
||||
}
|
||||
do
|
||||
@@ -452,7 +451,7 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
fin >> s;
|
||||
} while (!(s != "|" || fin.bad()));
|
||||
if (s != "]")
|
||||
record->tm = atof(s.c_str());
|
||||
record->tm = static_cast<float>(atof(s.c_str()));
|
||||
do
|
||||
{
|
||||
fin >> s;
|
||||
@@ -490,10 +489,10 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
if( entry.front() != 'R' ) {
|
||||
continue;
|
||||
}
|
||||
auto const entrysplit { split_string_and_number( entry ) };
|
||||
if( entrysplit.first == "R"
|
||||
&& entrysplit.second <= 10 ) {
|
||||
auto const radiochannel { entrysplit.second };
|
||||
auto const [entrytype, entrynumber]{ split_string_and_number( entry ) };
|
||||
if( entrytype == "R"
|
||||
&& entrynumber <= 10 ) {
|
||||
auto const radiochannel { entrynumber };
|
||||
if( record->radio_channel == -1
|
||||
|| radiochannel != activeradiochannel ) {
|
||||
// if the station has more than one radiochannel listed,
|
||||
@@ -514,12 +513,12 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
if (contains( s, hrsd) )
|
||||
{
|
||||
record->Dh = atoi(s.substr(0, s.find(hrsd)).c_str()); // godzina odjazdu
|
||||
record->Dm = atof(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta odjazdu
|
||||
record->Dm = static_cast<float>(atof(s.substr(s.find(hrsd) + 1, s.length()).c_str())); // minuta odjazdu
|
||||
}
|
||||
else
|
||||
{
|
||||
record->Dh = TimeTable[StationCount - 1].Dh; // godzina z poprzedniej pozycji
|
||||
record->Dm = atof(s.c_str()); // bo tylko minuty podane
|
||||
record->Dm = static_cast<float>(atof(s.c_str())); // bo tylko minuty podane
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -532,7 +531,7 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
fin >> s;
|
||||
} while (!(s != "|" || fin.bad()));
|
||||
if (s != "]")
|
||||
record->tm = atof(s.c_str());
|
||||
record->tm = static_cast<float>(atof(s.c_str()));
|
||||
do
|
||||
{
|
||||
fin >> s;
|
||||
@@ -565,20 +564,16 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
fin.close();
|
||||
}
|
||||
}
|
||||
if (ConversionError == 0)
|
||||
{
|
||||
if (TimeTable[1].StationName == Relation1) // jeśli nazwa pierwszego zgodna z relacją
|
||||
if (TimeTable[1].Ah < 0) // a nie podany czas przyjazdu
|
||||
{ // to mamy zatrzymanie na pierwszym, a nie przelot
|
||||
TimeTable[1].Ah = TimeTable[1].Dh;
|
||||
TimeTable[1].Am = TimeTable[1].Dm;
|
||||
}
|
||||
// jeśli nazwa pierwszego zgodna z relacją
|
||||
if (conversionerror == 0 && TimeTable[1].StationName == Relation1 && TimeTable[1].Ah < 0) // a nie podany czas przyjazdu
|
||||
{ // to mamy zatrzymanie na pierwszym, a nie przelot
|
||||
TimeTable[1].Ah = TimeTable[1].Dh;
|
||||
TimeTable[1].Am = TimeTable[1].Dm;
|
||||
}
|
||||
//
|
||||
load_sounds();
|
||||
// potentially offset table times
|
||||
auto const timeoffset { static_cast<int>( Global.ScenarioTimeOffset * 60 ) + iPlus };
|
||||
if( timeoffset != 0 ) // jeżeli jest przesunięcie rozkładu
|
||||
if( auto const timeoffset { static_cast<int>( Global.ScenarioTimeOffset * 60 ) + iPlus }; timeoffset != 0 ) // jeżeli jest przesunięcie rozkładu
|
||||
{
|
||||
long i_end = StationCount + 1;
|
||||
float adjustedtime; // do zwiększania czasu
|
||||
@@ -586,19 +581,19 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
{
|
||||
if (TimeTable[i].Ah >= 0)
|
||||
{
|
||||
adjustedtime = clamp_circular<float>( TimeTable[i].Ah * 60 + TimeTable[i].Am + timeoffset, 24 * 60 ); // nowe minuty
|
||||
adjustedtime = clamp_circular<float>( static_cast<float>(TimeTable[i].Ah * 60) + TimeTable[i].Am + static_cast<float>(timeoffset), 24 * 60 ); // nowe minuty
|
||||
TimeTable[i].Am = int(60 * adjustedtime) % 3600 / 60.f;
|
||||
TimeTable[i].Ah = int(adjustedtime / 60) % 24;
|
||||
}
|
||||
if (TimeTable[i].Dh >= 0)
|
||||
{
|
||||
adjustedtime = clamp_circular<float>( TimeTable[i].Dh * 60 + TimeTable[i].Dm + timeoffset, 24 * 60 ); // nowe minuty
|
||||
adjustedtime = clamp_circular<float>( static_cast<float>(TimeTable[i].Dh * 60) + TimeTable[i].Dm + static_cast<float>(timeoffset), 24 * 60 ); // nowe minuty
|
||||
TimeTable[i].Dm = int(60 * adjustedtime) % 3600 / 60.f;
|
||||
TimeTable[i].Dh = int(adjustedtime / 60) % 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ConversionError == 0;
|
||||
return conversionerror == 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -615,26 +610,26 @@ TTrainParameters::load_sounds() {
|
||||
station.StationName.substr( 0, station.StationName.size() - 3 ) :
|
||||
station.StationName ) };
|
||||
|
||||
auto const lookup {
|
||||
auto const [filepath, fileextension]{
|
||||
FileExists(
|
||||
{ Global.asCurrentSceneryPath + stationname, std::string{ paths::sounds } + "sip/" + stationname },
|
||||
{ ".ogg", ".flac", ".wav" } ) };
|
||||
if( lookup.first.empty() ) {
|
||||
if( filepath.empty() ) {
|
||||
continue;
|
||||
}
|
||||
// wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
|
||||
station.name_sound =
|
||||
sound_source{ sound_placement::engine, EU07_SOUND_CABANNOUNCEMENTCUTOFFRANGE }
|
||||
.deserialize( lookup.first + lookup.second, sound_type::single );
|
||||
.deserialize( filepath + fileextension, sound_type::single );
|
||||
}
|
||||
}
|
||||
|
||||
bool TTrainParameters::DirectionChange()
|
||||
bool TTrainParameters::DirectionChange() const
|
||||
// sprawdzenie, czy po zatrzymaniu wykonać kolejne komendy
|
||||
{
|
||||
if (StationIndex > 0 && StationIndex < StationCount) // dla ostatniej stacji nie
|
||||
if (contains( TimeTable[StationIndex].StationWare, '@') )
|
||||
return true;
|
||||
// dla ostatniej stacji nie
|
||||
if (StationIndex > 0 && StationIndex < StationCount && contains( TimeTable[StationIndex].StationWare, '@'))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Mtable
|
||||
{
|
||||
|
||||
static int const MaxTTableSize = 100; // można by to robić dynamicznie
|
||||
static char const *hrsd = ".";
|
||||
static char const *const hrsd = ".";
|
||||
|
||||
// Ra: pozycja zerowa rozkładu chyba nie ma sensu
|
||||
// Ra: numeracja przystanków jest 1..StationCount
|
||||
@@ -42,7 +42,7 @@ struct TMTableLine
|
||||
sound_source name_sound{ sound_placement::engine };
|
||||
};
|
||||
|
||||
typedef TMTableLine TMTable[MaxTTableSize + 1];
|
||||
using TMTable = TMTableLine[MaxTTableSize + 1];
|
||||
|
||||
// typedef TTrainParameters *PTrainParameters;
|
||||
|
||||
@@ -65,27 +65,27 @@ class TTrainParameters
|
||||
std::string NextStationName;
|
||||
double LastStationLatency;
|
||||
int Direction; /*kierunek jazdy w/g kilometrazu*/
|
||||
double CheckTrainLatency();
|
||||
double CheckTrainLatency() const;
|
||||
/*todo: str hh:mm to int i z powrotem*/
|
||||
std::string ShowRelation() const;
|
||||
double WatchMTable(double DistCounter);
|
||||
double WatchMTable(double DistCounter) const;
|
||||
std::string NextStop() const;
|
||||
sound_source next_stop_sound() const;
|
||||
sound_source last_stop_sound() const;
|
||||
bool IsStop() const;
|
||||
bool IsLastStop() const;
|
||||
bool IsMaintenance() const;
|
||||
bool IsTimeToGo(double hh, double mm);
|
||||
bool IsTimeToGo(double hh, double mm) const;
|
||||
// returns: difference between specified time and scheduled departure from current stop, in seconds
|
||||
double seconds_until_departure( double const Hour, double const Minute ) const;
|
||||
bool UpdateMTable(double hh, double mm, std::string const &NewName);
|
||||
bool UpdateMTable(double hh, double mm, std::string_view NewName);
|
||||
bool UpdateMTable( scenario_time const &Time, std::string const &NewName );
|
||||
bool RewindTimeTable( std::string actualStationName );
|
||||
TTrainParameters( std::string const &NewTrainName = "none" );
|
||||
void NewName(std::string const &NewTrainName);
|
||||
explicit TTrainParameters( std::string const &NewTrainName = "none" );
|
||||
void NewName(std::string_view NewTrainName);
|
||||
void UpdateVelocity(int StationCount, double vActual);
|
||||
bool LoadTTfile(std::string scnpath, int iPlus, double vmax);
|
||||
bool DirectionChange();
|
||||
bool LoadTTfile(std::string const &scnpath, int iPlus, double vmax);
|
||||
bool DirectionChange() const;
|
||||
void StationIndexInc();
|
||||
void serialize( dictionary_source *Output ) const;
|
||||
// returns: radio channel associated with current station, or -1
|
||||
|
||||
@@ -22,7 +22,7 @@ basic_station Station;
|
||||
|
||||
// exchanges load with consist attached to specified vehicle, operating on specified schedule
|
||||
double
|
||||
basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform ) {
|
||||
basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform ) const {
|
||||
|
||||
// TODO: filter out maintenance stops when determining first and last stop
|
||||
auto const firststop { Schedule.StationIndex == 1 };
|
||||
@@ -63,7 +63,7 @@ basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Sch
|
||||
maintenancestop ? 0 :
|
||||
std::min<float>(
|
||||
parameters.LoadAmount,
|
||||
Random( parameters.MaxLoad * 0.15f * stationsizemodifier ) ) );
|
||||
static_cast<float>(Random( parameters.MaxLoad * 0.15f * stationsizemodifier )) ) );
|
||||
auto loadcount = static_cast<int>(
|
||||
TestFlag( parameters.DamageFlag, dtrain_out ) ? 0 :
|
||||
laststop ? 0 :
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
// methods
|
||||
// exchanges load with consist attached to specified vehicle, operating on specified schedule; returns: time needed for exchange, in seconds
|
||||
double
|
||||
update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform );
|
||||
update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform ) const;
|
||||
};
|
||||
|
||||
namespace simulation {
|
||||
|
||||
Reference in New Issue
Block a user