mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 20:59:19 +02:00
continued refacoring: vehicles, events, memcells, tracks, traction, traction power sources; minor readability enhancements and bug fixes
This commit is contained in:
17
AdvSound.cpp
17
AdvSound.cpp
@@ -19,12 +19,7 @@ TAdvancedSound::~TAdvancedSound()
|
|||||||
// SoundShut.Stop();
|
// SoundShut.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TAdvancedSound::Free()
|
void TAdvancedSound::Init( std::string const &NameOn, std::string const &Name, std::string const &NameOff, double DistanceAttenuation, Math3D::vector3 const &pPosition)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void TAdvancedSound::Init( std::string const &NameOn, std::string const &Name, std::string const &NameOff, double DistanceAttenuation,
|
|
||||||
vector3 const &pPosition)
|
|
||||||
{
|
{
|
||||||
SoundStart.Init(NameOn, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
|
SoundStart.Init(NameOn, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
|
||||||
SoundCommencing.Init(Name, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
|
SoundCommencing.Init(Name, DistanceAttenuation, pPosition.x, pPosition.y, pPosition.z, true);
|
||||||
@@ -47,7 +42,7 @@ void TAdvancedSound::Init( std::string const &NameOn, std::string const &Name, s
|
|||||||
SoundShut.FA = 0.0;
|
SoundShut.FA = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TAdvancedSound::Load(cParser &Parser, vector3 const &pPosition)
|
void TAdvancedSound::Load(cParser &Parser, Math3D::vector3 const &pPosition)
|
||||||
{
|
{
|
||||||
std::string nameon, name, nameoff;
|
std::string nameon, name, nameoff;
|
||||||
double attenuation;
|
double attenuation;
|
||||||
@@ -62,7 +57,7 @@ void TAdvancedSound::Load(cParser &Parser, vector3 const &pPosition)
|
|||||||
Init( nameon, name, nameoff, attenuation, pPosition );
|
Init( nameon, name, nameoff, attenuation, pPosition );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TAdvancedSound::TurnOn(bool ListenerInside, vector3 NewPosition)
|
void TAdvancedSound::TurnOn(bool ListenerInside, Math3D::vector3 NewPosition)
|
||||||
{
|
{
|
||||||
// hunter-311211: nie trzeba czekac na ponowne odtworzenie dzwieku, az sie wylaczy
|
// hunter-311211: nie trzeba czekac na ponowne odtworzenie dzwieku, az sie wylaczy
|
||||||
if ((State == ss_Off || State == ss_ShuttingDown) && (SoundStart.AM > 0))
|
if ((State == ss_Off || State == ss_ShuttingDown) && (SoundStart.AM > 0))
|
||||||
@@ -76,7 +71,7 @@ void TAdvancedSound::TurnOn(bool ListenerInside, vector3 NewPosition)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TAdvancedSound::TurnOff(bool ListenerInside, vector3 NewPosition)
|
void TAdvancedSound::TurnOff(bool ListenerInside, Math3D::vector3 NewPosition)
|
||||||
{
|
{
|
||||||
if ((State == ss_Commencing || State == ss_Starting) && (SoundShut.AM > 0))
|
if ((State == ss_Commencing || State == ss_Starting) && (SoundShut.AM > 0))
|
||||||
{
|
{
|
||||||
@@ -90,7 +85,7 @@ void TAdvancedSound::TurnOff(bool ListenerInside, vector3 NewPosition)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TAdvancedSound::Update(bool ListenerInside, vector3 NewPosition)
|
void TAdvancedSound::Update(bool ListenerInside, Math3D::vector3 NewPosition)
|
||||||
{
|
{
|
||||||
if ((State == ss_Commencing) && (SoundCommencing.AM > 0))
|
if ((State == ss_Commencing) && (SoundCommencing.AM > 0))
|
||||||
{
|
{
|
||||||
@@ -126,7 +121,7 @@ void TAdvancedSound::Update(bool ListenerInside, vector3 NewPosition)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TAdvancedSound::UpdateAF(double A, double F, bool ListenerInside, vector3 NewPosition)
|
void TAdvancedSound::UpdateAF(double A, double F, bool ListenerInside, Math3D::vector3 NewPosition)
|
||||||
{ // update, ale z amplituda i czestotliwoscia
|
{ // update, ale z amplituda i czestotliwoscia
|
||||||
if( State == ss_Off ) {
|
if( State == ss_Off ) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
19
AdvSound.h
19
AdvSound.h
@@ -13,13 +13,13 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "RealSound.h"
|
#include "RealSound.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
typedef enum
|
enum TSoundState {
|
||||||
{
|
|
||||||
ss_Off,
|
ss_Off,
|
||||||
ss_Starting,
|
ss_Starting,
|
||||||
ss_Commencing,
|
ss_Commencing,
|
||||||
ss_ShuttingDown
|
ss_ShuttingDown
|
||||||
} TSoundState;
|
};
|
||||||
|
|
||||||
class TAdvancedSound
|
class TAdvancedSound
|
||||||
{ // klasa dźwięków mających początek, dowolnie długi środek oraz zakończenie (np. Rp1)
|
{ // klasa dźwięków mających początek, dowolnie długi środek oraz zakończenie (np. Rp1)
|
||||||
@@ -36,13 +36,12 @@ class TAdvancedSound
|
|||||||
public:
|
public:
|
||||||
TAdvancedSound() = default;
|
TAdvancedSound() = default;
|
||||||
~TAdvancedSound();
|
~TAdvancedSound();
|
||||||
void Init( std::string const &NameOn, std::string const &Name, std::string const &NameOff, double DistanceAttenuation, vector3 const &pPosition);
|
void Init( std::string const &NameOn, std::string const &Name, std::string const &NameOff, double DistanceAttenuation, Math3D::vector3 const &pPosition);
|
||||||
void Load(cParser &Parser, vector3 const &pPosition);
|
void Load(cParser &Parser, Math3D::vector3 const &pPosition);
|
||||||
void TurnOn(bool ListenerInside, vector3 NewPosition);
|
void TurnOn(bool ListenerInside, Math3D::vector3 NewPosition);
|
||||||
void TurnOff(bool ListenerInside, vector3 NewPosition);
|
void TurnOff(bool ListenerInside, Math3D::vector3 NewPosition);
|
||||||
void Free();
|
void Update(bool ListenerInside, Math3D::vector3 NewPosition);
|
||||||
void Update(bool ListenerInside, vector3 NewPosition);
|
void UpdateAF(double A, double F, bool ListenerInside, Math3D::vector3 NewPosition);
|
||||||
void UpdateAF(double A, double F, bool ListenerInside, vector3 NewPosition);
|
|
||||||
void CopyIfEmpty(TAdvancedSound &s);
|
void CopyIfEmpty(TAdvancedSound &s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -759,21 +759,27 @@ void TAnimModel::LightSet(int n, float v)
|
|||||||
{ // ustawienie światła (n) na wartość (v)
|
{ // ustawienie światła (n) na wartość (v)
|
||||||
if (n >= iMaxNumLights)
|
if (n >= iMaxNumLights)
|
||||||
return; // przekroczony zakres
|
return; // przekroczony zakres
|
||||||
lsLights[n] = TLightState(int(v));
|
lsLights[ n ] = TLightState( static_cast<int>( v ) );
|
||||||
switch (lsLights[n])
|
switch( lsLights[ n ] ) {
|
||||||
{ // interpretacja ułamka zależnie od typu
|
// interpretacja ułamka zależnie od typu
|
||||||
case 0: // ustalenie czasu migotania, t<1s (f>1Hz), np. 0.1 => t=0.1 (f=10Hz)
|
case ls_Off: {
|
||||||
break;
|
// ustalenie czasu migotania, t<1s (f>1Hz), np. 0.1 => t=0.1 (f=10Hz)
|
||||||
case 1: // ustalenie wypełnienia ułamkiem, np. 1.25 => zapalony przez 1/4 okresu
|
break;
|
||||||
break;
|
}
|
||||||
case 2: // ustalenie częstotliwości migotania, f<1Hz (t>1s), np. 2.2 => f=0.2Hz (t=5s)
|
case ls_On: {
|
||||||
break;
|
// ustalenie wypełnienia ułamkiem, np. 1.25 => zapalony przez 1/4 okresu
|
||||||
case 3: // zapalenie świateł zależne od oświetlenia scenerii
|
break;
|
||||||
if (v > 3.0)
|
}
|
||||||
fDark = v - 3.0; // ustawienie indywidualnego progu zapalania
|
case ls_Blink: {
|
||||||
else
|
// ustalenie częstotliwości migotania, f<1Hz (t>1s), np. 2.2 => f=0.2Hz (t=5s)
|
||||||
fDark = 0.25; // standardowy próg zaplania
|
break;
|
||||||
break;
|
}
|
||||||
|
case ls_Dark: {
|
||||||
|
// zapalenie świateł zależne od oświetlenia scenerii
|
||||||
|
if( v > 3.0 ) { fDark = v - 3.0; } // ustawienie indywidualnego progu zapalania
|
||||||
|
else { fDark = 0.25; } // standardowy próg zaplania
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -176,7 +176,9 @@ private:
|
|||||||
unsigned int m_framestamp { 0 }; // id of last rendered gfx frame
|
unsigned int m_framestamp { 0 }; // id of last rendered gfx frame
|
||||||
};
|
};
|
||||||
|
|
||||||
class instance_manager : public basic_table<TAnimModel> {
|
|
||||||
|
|
||||||
|
class instance_table : public basic_table<TAnimModel> {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class TMtableTime; // czas dla danego posterunku
|
|||||||
|
|
||||||
class TController; // obiekt sterujący pociągiem (AI)
|
class TController; // obiekt sterujący pociągiem (AI)
|
||||||
|
|
||||||
typedef enum
|
enum TCommandType
|
||||||
{ // binarne odpowiedniki komend w komórce pamięci
|
{ // binarne odpowiedniki komend w komórce pamięci
|
||||||
cm_Unknown, // ciąg nierozpoznany (nie jest komendą)
|
cm_Unknown, // ciąg nierozpoznany (nie jest komendą)
|
||||||
cm_Ready, // W4 zezwala na odjazd, ale semafor może zatrzymać
|
cm_Ready, // W4 zezwala na odjazd, ale semafor może zatrzymać
|
||||||
@@ -51,6 +51,6 @@ typedef enum
|
|||||||
cm_OutsideStation,
|
cm_OutsideStation,
|
||||||
cm_Shunt,
|
cm_Shunt,
|
||||||
cm_Command // komenda pobierana z komórki
|
cm_Command // komenda pobierana z komórki
|
||||||
} TCommandType;
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
70
DynObj.cpp
70
DynObj.cpp
@@ -4150,7 +4150,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
// Ra 15-01: gałka nastawy hamulca
|
// Ra 15-01: gałka nastawy hamulca
|
||||||
parser.getTokens();
|
parser.getTokens();
|
||||||
parser >> asAnimName;
|
parser >> asAnimName;
|
||||||
smBrakeMode = mdModel->GetFromName(asAnimName.c_str());
|
smBrakeMode = mdModel->GetFromName(asAnimName);
|
||||||
// jeszcze wczytać kąty obrotu dla poszczególnych ustawień
|
// jeszcze wczytać kąty obrotu dla poszczególnych ustawień
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4158,7 +4158,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
// Ra 15-01: gałka nastawy hamulca
|
// Ra 15-01: gałka nastawy hamulca
|
||||||
parser.getTokens();
|
parser.getTokens();
|
||||||
parser >> asAnimName;
|
parser >> asAnimName;
|
||||||
smLoadMode = mdModel->GetFromName(asAnimName.c_str());
|
smLoadMode = mdModel->GetFromName(asAnimName);
|
||||||
// jeszcze wczytać kąty obrotu dla poszczególnych ustawień
|
// jeszcze wczytać kąty obrotu dla poszczególnych ustawień
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4170,7 +4170,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
for (i = 0; i < iAnimType[ANIM_WHEELS]; ++i) // liczba osi
|
for (i = 0; i < iAnimType[ANIM_WHEELS]; ++i) // liczba osi
|
||||||
{ // McZapkie-050402: wyszukiwanie kol o nazwie str*
|
{ // McZapkie-050402: wyszukiwanie kol o nazwie str*
|
||||||
asAnimName = token + std::to_string(i + 1);
|
asAnimName = token + std::to_string(i + 1);
|
||||||
pAnimations[i].smAnimated = mdModel->GetFromName(asAnimName.c_str()); // ustalenie submodelu
|
pAnimations[i].smAnimated = mdModel->GetFromName(asAnimName); // ustalenie submodelu
|
||||||
if (pAnimations[i].smAnimated)
|
if (pAnimations[i].smAnimated)
|
||||||
{ //++iAnimatedAxles;
|
{ //++iAnimatedAxles;
|
||||||
pAnimations[i].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu
|
pAnimations[i].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu
|
||||||
@@ -4311,8 +4311,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ErrorLog("Bad model: " + asFileName + " - missed submodel " +
|
ErrorLog("Bad model: " + asFileName + " - missed submodel " + asAnimName); // brak ramienia
|
||||||
asAnimName); // brak ramienia
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4346,10 +4345,9 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ErrorLog( "Bad model: " + asFileName + " - missed submodel " +
|
ErrorLog( "Bad model: " + asFileName + " - missed submodel " + asAnimName ); // brak ramienia
|
||||||
asAnimName ); // brak ramienia
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( token == "animpantrg1prefix:" ) {
|
else if( token == "animpantrg1prefix:" ) {
|
||||||
@@ -5393,3 +5391,59 @@ TDynamicObject::ConnectedEnginePowerSource( TDynamicObject const *Caller ) const
|
|||||||
// ...if we're still here, report lack of power source
|
// ...if we're still here, report lack of power source
|
||||||
return MoverParameters->EnginePowerSource.SourceType;
|
return MoverParameters->EnginePowerSource.SourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
|
void
|
||||||
|
vehicle_table::update( double Deltatime, int Iterationcount ) {
|
||||||
|
// Ra: w zasadzie to trzeba by utworzyć oddzielną listę taboru do liczenia fizyki
|
||||||
|
// na którą by się zapisywały wszystkie pojazdy będące w ruchu
|
||||||
|
// pojazdy stojące nie potrzebują aktualizacji, chyba że np. ktoś im zmieni nastawę hamulca
|
||||||
|
// oddzielną listę można by zrobić na pojazdy z napędem, najlepiej posortowaną wg typu napędu
|
||||||
|
for( auto *vehicle : m_items ) {
|
||||||
|
// Ra: zmienić warunek na sprawdzanie pantografów w jednej zmiennej: czy pantografy i czy podniesione
|
||||||
|
if( vehicle->MoverParameters->EnginePowerSource.SourceType == CurrentCollector ) {
|
||||||
|
/*
|
||||||
|
// TODO: re-implement
|
||||||
|
GetTraction( vehicle );
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
vehicle->MoverParameters->ComputeConstans();
|
||||||
|
vehicle->CoupleDist();
|
||||||
|
}
|
||||||
|
if( Iterationcount > 1 ) {
|
||||||
|
// ABu: ponizsze wykonujemy tylko jesli wiecej niz jedna iteracja
|
||||||
|
for( int iteration = 0; iteration < ( Iterationcount - 1 ); ++iteration ) {
|
||||||
|
for( auto *vehicle : m_items ) {
|
||||||
|
vehicle->UpdateForce( Deltatime, Deltatime, false );
|
||||||
|
}
|
||||||
|
for( auto *vehicle : m_items ) {
|
||||||
|
vehicle->FastUpdate( Deltatime );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const totaltime { Deltatime * Iterationcount }; // całkowity czas
|
||||||
|
|
||||||
|
for( auto *vehicle : m_items ) {
|
||||||
|
vehicle->UpdateForce( Deltatime, totaltime, true );
|
||||||
|
}
|
||||||
|
for( auto *vehicle : m_items ) {
|
||||||
|
// Ra 2015-01: tylko tu przelicza sieć trakcyjną
|
||||||
|
vehicle->Update( Deltatime, totaltime );
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// TODO: re-implement
|
||||||
|
if (bDynamicRemove)
|
||||||
|
{ // jeśli jest coś do usunięcia z listy, to trzeba na końcu
|
||||||
|
for (TGroundNode *Current = nRootDynamic; Current; Current = Current->nNext)
|
||||||
|
if ( false == Current->DynamicObject->bEnabled)
|
||||||
|
{
|
||||||
|
DynamicRemove(Current->DynamicObject); // usunięcie tego i podłączonych
|
||||||
|
Current = nRootDynamic; // sprawdzanie listy od początku
|
||||||
|
}
|
||||||
|
bDynamicRemove = false; // na razie koniec
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|||||||
187
DynObj.h
187
DynObj.h
@@ -160,19 +160,17 @@ private: // położenie pojazdu w świecie oraz parametry ruchu
|
|||||||
TTrackParam tp; // parametry toru przekazywane do fizyki
|
TTrackParam tp; // parametry toru przekazywane do fizyki
|
||||||
TTrackFollower Axle0; // oś z przodu (od sprzęgu 0)
|
TTrackFollower Axle0; // oś z przodu (od sprzęgu 0)
|
||||||
TTrackFollower Axle1; // oś z tyłu (od sprzęgu 1)
|
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
|
int iAxleFirst; // numer pierwszej osi w kierunku ruchu (oś wiążąca pojazd z torem i wyzwalająca eventy)
|
||||||
// eventy)
|
|
||||||
float fAxleDist; // rozstaw wózków albo osi do liczenia proporcji zacienienia
|
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!!!
|
Math3D::vector3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!!
|
||||||
// bool bCameraNear; //blisko kamer są potrzebne dodatkowe obliczenia szczegółów
|
|
||||||
TDynamicObject * ABuFindNearestObject( TTrack *Track, TDynamicObject *MyPointer, int &CouplNr );
|
TDynamicObject * ABuFindNearestObject( TTrack *Track, TDynamicObject *MyPointer, int &CouplNr );
|
||||||
|
|
||||||
public: // parametry położenia pojazdu dostępne publicznie
|
public:
|
||||||
|
// parametry położenia pojazdu dostępne publicznie
|
||||||
std::string asTrack; // nazwa toru początkowego; wywalić?
|
std::string asTrack; // nazwa toru początkowego; wywalić?
|
||||||
std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)"
|
std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)"
|
||||||
Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli
|
Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli
|
||||||
TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie
|
TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie
|
||||||
// TMoverParameters *pControlled; //wskaźnik do sterowanego członu silnikowego
|
|
||||||
TDynamicObject *NextConnected; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
TDynamicObject *NextConnected; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||||
TDynamicObject *PrevConnected; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
TDynamicObject *PrevConnected; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||||
int NextConnectedNo; // numer sprzęgu podłączonego z tyłu
|
int NextConnectedNo; // numer sprzęgu podłączonego z tyłu
|
||||||
@@ -182,7 +180,7 @@ public: // parametry położenia pojazdu dostępne publicznie
|
|||||||
|
|
||||||
TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
|
TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
|
||||||
|
|
||||||
public: // modele składowe pojazdu
|
// modele składowe pojazdu
|
||||||
TModel3d *mdModel; // model pudła
|
TModel3d *mdModel; // model pudła
|
||||||
TModel3d *mdLoad; // model zmiennego ładunku
|
TModel3d *mdLoad; // model zmiennego ładunku
|
||||||
TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h
|
TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h
|
||||||
@@ -201,28 +199,26 @@ public: // modele składowe pojazdu
|
|||||||
bool SectionLightsActive { false }; // flag indicating whether section lights were set.
|
bool SectionLightsActive { false }; // flag indicating whether section lights were set.
|
||||||
float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
|
float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
|
||||||
|
|
||||||
private: // zmienne i metody do animacji submodeli; Ra: sprzatam animacje w pojeździe
|
private:
|
||||||
|
// zmienne i metody do animacji submodeli; Ra: sprzatam animacje w pojeździe
|
||||||
material_data m_materialdata;
|
material_data m_materialdata;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline
|
inline
|
||||||
material_data const
|
material_data const
|
||||||
*Material() const {
|
*Material() const {
|
||||||
return &m_materialdata; }
|
return &m_materialdata; }
|
||||||
// tymczasowo udostępnione do wyszukiwania drutu
|
// tymczasowo udostępnione do wyszukiwania drutu
|
||||||
int iAnimType[ ANIM_TYPES ]; // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
|
int iAnimType[ ANIM_TYPES ]; // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
|
||||||
private:
|
private:
|
||||||
int iAnimations; // liczba obiektów animujących
|
int iAnimations; // liczba obiektów animujących
|
||||||
/*
|
/*
|
||||||
TAnim *pAnimations; // obiekty animujące (zawierają wskaźnik do funkcji wykonującej animację)
|
TAnim *pAnimations; // obiekty animujące (zawierają wskaźnik do funkcji wykonującej animację)
|
||||||
*/
|
*/
|
||||||
std::vector<TAnim> pAnimations;
|
std::vector<TAnim> pAnimations;
|
||||||
TSubModel **
|
TSubModel ** pAnimated; // lista animowanych submodeli (może być ich więcej niż obiektów animujących)
|
||||||
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
|
||||||
double dWheelAngle[3]; // kąty obrotu kół: 0=przednie toczne, 1=napędzające i wiązary, 2=tylne
|
void UpdateNone(TAnim *pAnim){}; // animacja pusta (funkcje ustawiania submodeli, gdy blisko kamery)
|
||||||
// toczne
|
|
||||||
void
|
|
||||||
UpdateNone(TAnim *pAnim){}; // animacja pusta (funkcje ustawiania submodeli, gdy blisko kamery)
|
|
||||||
void UpdateAxle(TAnim *pAnim); // animacja osi
|
void UpdateAxle(TAnim *pAnim); // animacja osi
|
||||||
void UpdateBoogie(TAnim *pAnim); // animacja wózka
|
void UpdateBoogie(TAnim *pAnim); // animacja wózka
|
||||||
void UpdateDoorTranslate(TAnim *pAnim); // animacja drzwi - przesuw
|
void UpdateDoorTranslate(TAnim *pAnim); // animacja drzwi - przesuw
|
||||||
@@ -268,8 +264,7 @@ public: // modele składowe pojazdu
|
|||||||
|
|
||||||
TButton btCoupler1; // sprzegi
|
TButton btCoupler1; // sprzegi
|
||||||
TButton btCoupler2;
|
TButton btCoupler2;
|
||||||
TAirCoupler
|
TAirCoupler btCPneumatic1; // sprzegi powietrzne //yB - zmienione z Button na AirCoupler - krzyzyki
|
||||||
btCPneumatic1; // sprzegi powietrzne //yB - zmienione z Button na AirCoupler - krzyzyki
|
|
||||||
TAirCoupler btCPneumatic2;
|
TAirCoupler btCPneumatic2;
|
||||||
TAirCoupler btCPneumatic1r; // ABu: to zeby nie bylo problemow przy laczeniu wagonow,
|
TAirCoupler btCPneumatic1r; // ABu: to zeby nie bylo problemow przy laczeniu wagonow,
|
||||||
TAirCoupler btCPneumatic2r; // jesli beda polaczone sprzegami 1<->1 lub 0<->0
|
TAirCoupler btCPneumatic2r; // jesli beda polaczone sprzegami 1<->1 lub 0<->0
|
||||||
@@ -300,8 +295,6 @@ public: // modele składowe pojazdu
|
|||||||
TButton btHeadSignals23;
|
TButton btHeadSignals23;
|
||||||
TButton btMechanik1;
|
TButton btMechanik1;
|
||||||
TButton btMechanik2;
|
TButton btMechanik2;
|
||||||
//TSubModel *smMechanik0; // Ra: mechanik wbudowany w model jako submodel?
|
|
||||||
//TSubModel *smMechanik1; // mechanik od strony sprzęgu 1
|
|
||||||
double enginevolume; // MC: pomocnicze zeby gladziej silnik buczal
|
double enginevolume; // MC: pomocnicze zeby gladziej silnik buczal
|
||||||
|
|
||||||
int iAxles; // McZapkie: to potem mozna skasowac i zastapic iNumAxles
|
int iAxles; // McZapkie: to potem mozna skasowac i zastapic iNumAxles
|
||||||
@@ -325,7 +318,6 @@ public: // modele składowe pojazdu
|
|||||||
TAdvancedSound sReleaser;
|
TAdvancedSound sReleaser;
|
||||||
|
|
||||||
// Winger 010304
|
// Winger 010304
|
||||||
// TRealSound rsPanTup; //PSound sPantUp;
|
|
||||||
TRealSound sPantUp;
|
TRealSound sPantUp;
|
||||||
TRealSound sPantDown;
|
TRealSound sPantDown;
|
||||||
TRealSound rsDoorOpen; // Ra: przeniesione z kabiny
|
TRealSound rsDoorOpen; // Ra: przeniesione z kabiny
|
||||||
@@ -352,8 +344,6 @@ public: // modele składowe pojazdu
|
|||||||
int iHornWarning; // numer syreny do użycia po otrzymaniu sygnału do jazdy
|
int iHornWarning; // numer syreny do użycia po otrzymaniu sygnału do jazdy
|
||||||
bool bEnabled; // Ra: wyjechał na portal i ma być usunięty
|
bool bEnabled; // Ra: wyjechał na portal i ma być usunięty
|
||||||
protected:
|
protected:
|
||||||
// TTrackFollower Axle2; //dwie osie z czterech (te są protected)
|
|
||||||
// TTrackFollower Axle3; //Ra: wyłączyłem, bo kąty są liczone w Segment.cpp
|
|
||||||
int iNumAxles; // ilość osi
|
int iNumAxles; // ilość osi
|
||||||
std::string asModel;
|
std::string asModel;
|
||||||
|
|
||||||
@@ -373,26 +363,18 @@ public: // modele składowe pojazdu
|
|||||||
TDynamicObject * PrevC(int C);
|
TDynamicObject * PrevC(int C);
|
||||||
TDynamicObject * NextC(int C);
|
TDynamicObject * NextC(int C);
|
||||||
double NextDistance(double d = -1.0);
|
double NextDistance(double d = -1.0);
|
||||||
void SetdMoveLen(double dMoveLen)
|
void SetdMoveLen(double dMoveLen) {
|
||||||
{
|
MoverParameters->dMoveLen = dMoveLen; }
|
||||||
MoverParameters->dMoveLen = dMoveLen;
|
void ResetdMoveLen() {
|
||||||
}
|
MoverParameters->dMoveLen = 0; }
|
||||||
void ResetdMoveLen()
|
double GetdMoveLen() {
|
||||||
{
|
return MoverParameters->dMoveLen; }
|
||||||
MoverParameters->dMoveLen = 0;
|
|
||||||
}
|
|
||||||
double GetdMoveLen()
|
|
||||||
{
|
|
||||||
return MoverParameters->dMoveLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetPneumatic(bool front, bool red);
|
int GetPneumatic(bool front, bool red);
|
||||||
void SetPneumatic(bool front, bool red);
|
void SetPneumatic(bool front, bool red);
|
||||||
std::string asName;
|
std::string asName;
|
||||||
std::string GetName()
|
std::string name() const {
|
||||||
{
|
return this ? asName : std::string(); };
|
||||||
return this ? asName : std::string("");
|
|
||||||
};
|
|
||||||
|
|
||||||
TRealSound rsDiesielInc; // youBy
|
TRealSound rsDiesielInc; // youBy
|
||||||
TRealSound rscurve; // youBy
|
TRealSound rscurve; // youBy
|
||||||
@@ -405,7 +387,6 @@ public: // modele składowe pojazdu
|
|||||||
TDynamicObject * ABuScanNearestObject(TTrack *Track, double ScanDir, double ScanDist,
|
TDynamicObject * ABuScanNearestObject(TTrack *Track, double ScanDir, double ScanDist,
|
||||||
int &CouplNr);
|
int &CouplNr);
|
||||||
TDynamicObject * GetFirstDynamic(int cpl_type, int cf = 1);
|
TDynamicObject * GetFirstDynamic(int cpl_type, int cf = 1);
|
||||||
// TDynamicObject* GetFirstCabDynamic(int cpl_type);
|
|
||||||
void ABuSetModelShake( Math3D::vector3 mShake);
|
void ABuSetModelShake( Math3D::vector3 mShake);
|
||||||
|
|
||||||
// McZapkie-010302
|
// McZapkie-010302
|
||||||
@@ -437,99 +418,65 @@ public: // modele składowe pojazdu
|
|||||||
void Move(double fDistance);
|
void Move(double fDistance);
|
||||||
void FastMove(double fDistance);
|
void FastMove(double fDistance);
|
||||||
void RenderSounds();
|
void RenderSounds();
|
||||||
inline Math3D::vector3 GetPosition() const
|
inline Math3D::vector3 GetPosition() const {
|
||||||
{
|
return vPosition; };
|
||||||
return vPosition;
|
// pobranie współrzędnych czoła
|
||||||
};
|
inline Math3D::vector3 HeadPosition() {
|
||||||
inline Math3D::vector3 HeadPosition()
|
return vCoulpler[iDirection ^ 1]; };
|
||||||
{
|
// pobranie współrzędnych tyłu
|
||||||
return vCoulpler[iDirection ^ 1];
|
inline Math3D::vector3 RearPosition() {
|
||||||
}; // pobranie współrzędnych czoła
|
return vCoulpler[iDirection]; };
|
||||||
inline Math3D::vector3 RearPosition()
|
inline Math3D::vector3 AxlePositionGet() {
|
||||||
{
|
return iAxleFirst ? Axle1.pPosition : Axle0.pPosition; };
|
||||||
return vCoulpler[iDirection];
|
inline Math3D::vector3 VectorFront() const {
|
||||||
}; // pobranie współrzędnych tyłu
|
return vFront; };
|
||||||
inline Math3D::vector3 AxlePositionGet()
|
inline Math3D::vector3 VectorUp() {
|
||||||
{
|
return vUp; };
|
||||||
return iAxleFirst ? Axle1.pPosition : Axle0.pPosition;
|
inline Math3D::vector3 VectorLeft() const {
|
||||||
};
|
return vLeft; };
|
||||||
inline Math3D::vector3 VectorFront() const
|
inline double * Matrix() {
|
||||||
{
|
return mMatrix.getArray(); };
|
||||||
return vFront;
|
inline double GetVelocity() {
|
||||||
};
|
return MoverParameters->Vel; };
|
||||||
inline Math3D::vector3 VectorUp()
|
inline double GetLength() const {
|
||||||
{
|
return MoverParameters->Dim.L; };
|
||||||
return vUp;
|
inline double GetWidth() const {
|
||||||
};
|
return MoverParameters->Dim.W; };
|
||||||
inline Math3D::vector3 VectorLeft() const
|
inline TTrack * GetTrack() {
|
||||||
{
|
return (iAxleFirst ? Axle1.GetTrack() : Axle0.GetTrack()); };
|
||||||
return vLeft;
|
|
||||||
};
|
|
||||||
inline double * Matrix()
|
|
||||||
{
|
|
||||||
return mMatrix.getArray();
|
|
||||||
};
|
|
||||||
inline double GetVelocity()
|
|
||||||
{
|
|
||||||
return MoverParameters->Vel;
|
|
||||||
};
|
|
||||||
inline double GetLength() const
|
|
||||||
{
|
|
||||||
return MoverParameters->Dim.L;
|
|
||||||
};
|
|
||||||
inline double GetWidth() const
|
|
||||||
{
|
|
||||||
return MoverParameters->Dim.W;
|
|
||||||
};
|
|
||||||
inline TTrack * GetTrack()
|
|
||||||
{
|
|
||||||
return (iAxleFirst ? Axle1.GetTrack() : Axle0.GetTrack());
|
|
||||||
};
|
|
||||||
// void UpdatePos();
|
|
||||||
|
|
||||||
// McZapkie-260202
|
// McZapkie-260202
|
||||||
void LoadMMediaFile(std::string BaseDir, std::string TypeName, std::string ReplacableSkin);
|
void LoadMMediaFile(std::string BaseDir, std::string TypeName, std::string ReplacableSkin);
|
||||||
|
|
||||||
inline double ABuGetDirection() const // ABu.
|
inline double ABuGetDirection() const { // ABu.
|
||||||
{
|
return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection()); };
|
||||||
return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection());
|
// zwraca kierunek pojazdu na torze z aktywną osą
|
||||||
};
|
inline double RaDirectionGet() {
|
||||||
// inline double ABuGetTranslation() //ABu.
|
return iAxleFirst ? Axle1.GetDirection() : Axle0.GetDirection(); };
|
||||||
// {//zwraca przesunięcie wózka względem Point1 toru
|
// zwraca przesunięcie wózka względem Point1 toru z aktywną osią
|
||||||
// return (Axle1.GetTrack()==MyTrack?Axle1.GetTranslation():Axle0.GetTranslation());
|
inline double RaTranslationGet() {
|
||||||
// };
|
return iAxleFirst ? Axle1.GetTranslation() : Axle0.GetTranslation(); };
|
||||||
inline double RaDirectionGet()
|
// zwraca tor z aktywną osią
|
||||||
{ // zwraca kierunek pojazdu na torze z aktywną osą
|
inline TTrack * RaTrackGet() {
|
||||||
return iAxleFirst ? Axle1.GetDirection() : Axle0.GetDirection();
|
return iAxleFirst ? Axle1.GetTrack() : Axle0.GetTrack(); };
|
||||||
};
|
|
||||||
inline double RaTranslationGet()
|
|
||||||
{ // zwraca przesunięcie wózka względem Point1 toru z aktywną osią
|
|
||||||
return iAxleFirst ? Axle1.GetTranslation() : Axle0.GetTranslation();
|
|
||||||
};
|
|
||||||
inline TTrack * RaTrackGet()
|
|
||||||
{ // zwraca tor z aktywną osią
|
|
||||||
return iAxleFirst ? Axle1.GetTrack() : Axle0.GetTrack();
|
|
||||||
};
|
|
||||||
void CouplersDettach(double MinDist, int MyScanDir);
|
void CouplersDettach(double MinDist, int MyScanDir);
|
||||||
void RadioStop();
|
void RadioStop();
|
||||||
void Damage(char flag);
|
void Damage(char flag);
|
||||||
void RaLightsSet(int head, int rear);
|
void RaLightsSet(int head, int rear);
|
||||||
// void RaAxleEvent(TEvent *e);
|
|
||||||
TDynamicObject * FirstFind(int &coupler_nr, int cf = 1);
|
TDynamicObject * FirstFind(int &coupler_nr, int cf = 1);
|
||||||
float GetEPP(); // wyliczanie sredniego cisnienia w PG
|
float GetEPP(); // wyliczanie sredniego cisnienia w PG
|
||||||
int DirectionSet(int d); // ustawienie kierunku w składzie
|
int DirectionSet(int d); // ustawienie kierunku w składzie
|
||||||
int DirectionGet()
|
// odczyt kierunku w składzie
|
||||||
{
|
int DirectionGet() {
|
||||||
return iDirection + iDirection - 1;
|
return iDirection + iDirection - 1; };
|
||||||
}; // odczyt kierunku w składzie
|
|
||||||
int DettachStatus(int dir);
|
int DettachStatus(int dir);
|
||||||
int Dettach(int dir);
|
int Dettach(int dir);
|
||||||
TDynamicObject * Neightbour(int &dir);
|
TDynamicObject * Neightbour(int &dir);
|
||||||
void CoupleDist();
|
void CoupleDist();
|
||||||
TDynamicObject * ControlledFind();
|
TDynamicObject * ControlledFind();
|
||||||
void ParamSet(int what, int into);
|
void ParamSet(int what, int into);
|
||||||
int RouteWish(TTrack *tr); // zapytanie do AI, po którym segmencie skrzyżowania
|
// zapytanie do AI, po którym segmencie skrzyżowania jechać
|
||||||
// jechać
|
int RouteWish(TTrack *tr);
|
||||||
void DestinationSet(std::string to, std::string numer);
|
void DestinationSet(std::string to, std::string numer);
|
||||||
std::string TextureTest(std::string const &name);
|
std::string TextureTest(std::string const &name);
|
||||||
void OverheadTrack(float o);
|
void OverheadTrack(float o);
|
||||||
@@ -537,4 +484,14 @@ public: // modele składowe pojazdu
|
|||||||
static std::string const MED_labels[ 8 ];
|
static std::string const MED_labels[ 8 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class vehicle_table : public basic_table<TDynamicObject> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
|
void
|
||||||
|
update( double dt, int iter );
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
248
Event.cpp
248
Event.cpp
@@ -74,10 +74,6 @@ TEvent::~TEvent() {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TEvent::Init(){
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void TEvent::Conditions(cParser *parser, std::string s)
|
void TEvent::Conditions(cParser *parser, std::string s)
|
||||||
{ // przetwarzanie warunków, wspólne dla Multiple i UpdateValues
|
{ // przetwarzanie warunków, wspólne dla Multiple i UpdateValues
|
||||||
if (s == "condition")
|
if (s == "condition")
|
||||||
@@ -949,7 +945,7 @@ event_manager::CheckQuery() {
|
|||||||
// TODO: re-enable when messaging module is in place
|
// TODO: re-enable when messaging module is in place
|
||||||
if( Global::iMultiplayer ) {
|
if( Global::iMultiplayer ) {
|
||||||
// potwierdzenie wykonania dla serwera (odczyt semafora już tak nie działa)
|
// potwierdzenie wykonania dla serwera (odczyt semafora już tak nie działa)
|
||||||
WyslijEvent( tmpEvent->asName, tmpEvent->Activator->GetName() );
|
WyslijEvent( tmpEvent->asName, tmpEvent->Activator->name() );
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
m_workevent->Params[ 9 ].asMemCell->PutCommand(
|
m_workevent->Params[ 9 ].asMemCell->PutCommand(
|
||||||
@@ -984,61 +980,105 @@ event_manager::CheckQuery() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_Lights:
|
case tp_Lights: {
|
||||||
if (m_workevent->Params[9].asModel)
|
if( m_workevent->Params[ 9 ].asModel ) {
|
||||||
for (i = 0; i < iMaxNumLights; i++)
|
for( i = 0; i < iMaxNumLights; ++i ) {
|
||||||
if (m_workevent->Params[i].asdouble >= 0) //-1 zostawia bez zmiany
|
if( m_workevent->Params[ i ].asdouble >= 0 ) {
|
||||||
m_workevent->Params[9].asModel->LightSet(
|
// -1 zostawia bez zmiany
|
||||||
i, m_workevent->Params[i].asdouble); // teraz też ułamek
|
m_workevent->Params[ 9 ].asModel->LightSet(
|
||||||
break;
|
i,
|
||||||
case tp_Visible:
|
m_workevent->Params[ i ].asdouble );
|
||||||
if (m_workevent->Params[9].nGroundNode)
|
}
|
||||||
m_workevent->Params[9].nGroundNode->bVisible = (m_workevent->Params[i].asInt > 0);
|
}
|
||||||
break;
|
|
||||||
case tp_Velocity:
|
|
||||||
Error("Not implemented yet :(");
|
|
||||||
break;
|
|
||||||
case tp_Exit:
|
|
||||||
MessageBox(0, m_workevent->asNodeName.c_str(), " THE END ", MB_OK);
|
|
||||||
Global::iTextMode = -1; // wyłączenie takie samo jak sekwencja F10 -> Y
|
|
||||||
return false;
|
|
||||||
case tp_Sound:
|
|
||||||
switch (m_workevent->Params[0].asInt)
|
|
||||||
{ // trzy możliwe przypadki:
|
|
||||||
case 0:
|
|
||||||
m_workevent->Params[9].tsTextSound->Stop();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
m_workevent->Params[9].tsTextSound->Play(
|
|
||||||
1, 0, true, m_workevent->Params[9].tsTextSound->vSoundPosition);
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
m_workevent->Params[9].tsTextSound->Play(
|
|
||||||
1, DSBPLAY_LOOPING, true, m_workevent->Params[9].tsTextSound->vSoundPosition);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case tp_Visible: {
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
if( m_workevent->Params[ 9 ].nGroundNode )
|
||||||
|
m_workevent->Params[ 9 ].nGroundNode->bVisible = ( m_workevent->Params[ i ].asInt > 0 );
|
||||||
|
#else
|
||||||
|
if( m_workevent->Params[ 9 ].asEditorNode )
|
||||||
|
m_workevent->Params[ 9 ].asEditorNode->visible( m_workevent->Params[ i ].asInt > 0 );
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case tp_Velocity: {
|
||||||
|
Error( "Not implemented yet :(" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case tp_Exit: {
|
||||||
|
MessageBox( 0, m_workevent->asNodeName.c_str(), " THE END ", MB_OK );
|
||||||
|
Global::iTextMode = -1; // wyłączenie takie samo jak sekwencja F10 -> Y
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case tp_Sound: {
|
||||||
|
switch( m_workevent->Params[ 0 ].asInt ) {
|
||||||
|
// trzy możliwe przypadki:
|
||||||
|
case 0: {
|
||||||
|
m_workevent->Params[ 9 ].tsTextSound->Stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
m_workevent->Params[ 9 ].tsTextSound->Play(
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
m_workevent->Params[ 9 ].tsTextSound->vSoundPosition );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case -1: {
|
||||||
|
m_workevent->Params[ 9 ].tsTextSound->Play(
|
||||||
|
1,
|
||||||
|
DSBPLAY_LOOPING,
|
||||||
|
true,
|
||||||
|
m_workevent->Params[ 9 ].tsTextSound->vSoundPosition );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case tp_Disable:
|
case tp_Disable:
|
||||||
Error("Not implemented yet :(");
|
Error("Not implemented yet :(");
|
||||||
break;
|
break;
|
||||||
case tp_Animation: // Marcin: dorobic translacje - Ra: dorobiłem ;-)
|
case tp_Animation: {
|
||||||
if (m_workevent->Params[0].asInt == 1)
|
switch( m_workevent->Params[ 0 ].asInt ) {
|
||||||
m_workevent->Params[9].asAnimContainer->SetRotateAnim(
|
case 1: {
|
||||||
Math3D::vector3(m_workevent->Params[1].asdouble, m_workevent->Params[2].asdouble,
|
m_workevent->Params[ 9 ].asAnimContainer->SetRotateAnim(
|
||||||
m_workevent->Params[3].asdouble),
|
Math3D::vector3 {
|
||||||
m_workevent->Params[4].asdouble);
|
m_workevent->Params[ 1 ].asdouble,
|
||||||
else if (m_workevent->Params[0].asInt == 2)
|
m_workevent->Params[ 2 ].asdouble,
|
||||||
m_workevent->Params[9].asAnimContainer->SetTranslateAnim(
|
m_workevent->Params[ 3 ].asdouble },
|
||||||
Math3D::vector3(m_workevent->Params[1].asdouble, m_workevent->Params[2].asdouble,
|
m_workevent->Params[ 4 ].asdouble );
|
||||||
m_workevent->Params[3].asdouble),
|
break;
|
||||||
m_workevent->Params[4].asdouble);
|
}
|
||||||
else if (m_workevent->Params[0].asInt == 4)
|
case 2: {
|
||||||
m_workevent->Params[9].asModel->AnimationVND(
|
m_workevent->Params[ 9 ].asAnimContainer->SetTranslateAnim(
|
||||||
m_workevent->Params[8].asPointer,
|
Math3D::vector3 {
|
||||||
m_workevent->Params[1].asdouble, // tu mogą być dodatkowe parametry, np. od-do
|
m_workevent->Params[ 1 ].asdouble,
|
||||||
m_workevent->Params[2].asdouble, m_workevent->Params[3].asdouble,
|
m_workevent->Params[ 2 ].asdouble,
|
||||||
m_workevent->Params[4].asdouble);
|
m_workevent->Params[ 3 ].asdouble },
|
||||||
|
m_workevent->Params[ 4 ].asdouble );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
m_workevent->Params[ 9 ].asModel->AnimationVND(
|
||||||
|
m_workevent->Params[ 8 ].asPointer,
|
||||||
|
m_workevent->Params[ 1 ].asdouble, // tu mogą być dodatkowe parametry, np. od-do
|
||||||
|
m_workevent->Params[ 2 ].asdouble,
|
||||||
|
m_workevent->Params[ 3 ].asdouble,
|
||||||
|
m_workevent->Params[ 4 ].asdouble );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case tp_Switch: {
|
case tp_Switch: {
|
||||||
if( m_workevent->Params[ 9 ].asTrack ) {
|
if( m_workevent->Params[ 9 ].asTrack ) {
|
||||||
m_workevent->Params[ 9 ].asTrack->Switch(
|
m_workevent->Params[ 9 ].asTrack->Switch(
|
||||||
@@ -1057,13 +1097,15 @@ event_manager::CheckQuery() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_TrackVel:
|
case tp_TrackVel:
|
||||||
if (m_workevent->Params[9].asTrack)
|
if (m_workevent->Params[9].asTrack) {
|
||||||
{ // prędkość na zwrotnicy może być ograniczona z góry we wpisie, większej się nie
|
// prędkość na zwrotnicy może być ograniczona z góry we wpisie, większej się nie ustawi eventem
|
||||||
// ustawi eventem
|
|
||||||
WriteLog("Type: TrackVel");
|
|
||||||
m_workevent->Params[9].asTrack->VelocitySet(m_workevent->Params[0].asdouble);
|
m_workevent->Params[9].asTrack->VelocitySet(m_workevent->Params[0].asdouble);
|
||||||
if (DebugModeFlag) // wyświetlana jest ta faktycznie ustawiona
|
// wyświetlana jest ta faktycznie ustawiona
|
||||||
WriteLog(" - velocity: ", m_workevent->Params[9].asTrack->VelocityGet());
|
WriteLog( "Type: TrackVel - ["
|
||||||
|
+ to_string( m_workevent->Params[ 0 ].asdouble, 2 ) + "]"
|
||||||
|
+ ( DebugModeFlag ?
|
||||||
|
", actual [ " + to_string( m_workevent->Params[ 9 ].asTrack->VelocityGet(), 2 ) + "]" :
|
||||||
|
"" ) );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tp_DynVel:
|
case tp_DynVel:
|
||||||
@@ -1097,7 +1139,7 @@ event_manager::CheckQuery() {
|
|||||||
if( ( m_workevent->iFlags & conditional_anyelse ) == 0 ) {
|
if( ( m_workevent->iFlags & conditional_anyelse ) == 0 ) {
|
||||||
// jednoznaczne tylko, gdy nie było else
|
// jednoznaczne tylko, gdy nie było else
|
||||||
if( m_workevent->Activator ) {
|
if( m_workevent->Activator ) {
|
||||||
WyslijEvent( m_workevent->asName, m_workevent->Activator->GetName() );
|
WyslijEvent( m_workevent->asName, m_workevent->Activator->name() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WyslijEvent( m_workevent->asName, "" );
|
WyslijEvent( m_workevent->asName, "" );
|
||||||
@@ -1175,8 +1217,9 @@ event_manager::CheckQuery() {
|
|||||||
m_workevent->Params[ 9 ].asMemCell->UpdateValues(
|
m_workevent->Params[ 9 ].asMemCell->UpdateValues(
|
||||||
m_workevent->Activator->Mechanik->TrainName(),
|
m_workevent->Activator->Mechanik->TrainName(),
|
||||||
m_workevent->Activator->Mechanik->StationCount() - m_workevent->Activator->Mechanik->StationIndex(), // ile przystanków do końca
|
m_workevent->Activator->Mechanik->StationCount() - m_workevent->Activator->Mechanik->StationIndex(), // ile przystanków do końca
|
||||||
m_workevent->Activator->Mechanik->IsStop() ? 1 :
|
m_workevent->Activator->Mechanik->IsStop() ?
|
||||||
0, // 1, gdy ma tu zatrzymanie
|
1 :
|
||||||
|
0, // 1, gdy ma tu zatrzymanie
|
||||||
m_workevent->iFlags);
|
m_workevent->iFlags);
|
||||||
WriteLog("Train detected: " + m_workevent->Activator->Mechanik->TrainName());
|
WriteLog("Train detected: " + m_workevent->Activator->Mechanik->TrainName());
|
||||||
}
|
}
|
||||||
@@ -1186,10 +1229,10 @@ event_manager::CheckQuery() {
|
|||||||
// zapisanie zawartości komórki pamięci do logu
|
// zapisanie zawartości komórki pamięci do logu
|
||||||
if( m_workevent->Params[ 9 ].asMemCell ) {
|
if( m_workevent->Params[ 9 ].asMemCell ) {
|
||||||
// jeśli była podana nazwa komórki
|
// jeśli była podana nazwa komórki
|
||||||
WriteLog( "Memcell \"" + m_workevent->asNodeName + "\": "
|
WriteLog( "Memcell \"" + m_workevent->asNodeName + "\": ["
|
||||||
+ m_workevent->Params[ 9 ].asMemCell->Text() + " "
|
+ m_workevent->Params[ 9 ].asMemCell->Text() + "] ["
|
||||||
+ std::to_string( m_workevent->Params[ 9 ].asMemCell->Value1() ) + " "
|
+ to_string( m_workevent->Params[ 9 ].asMemCell->Value1(), 2 ) + "] ["
|
||||||
+ std::to_string( m_workevent->Params[ 9 ].asMemCell->Value2() ) );
|
+ to_string( m_workevent->Params[ 9 ].asMemCell->Value2(), 2 ) + "]" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: re-enable when cell manager is in place
|
// TODO: re-enable when cell manager is in place
|
||||||
@@ -1237,7 +1280,7 @@ event_manager::InitEvents() {
|
|||||||
case tp_AddValues: // sumowanie wartości
|
case tp_AddValues: // sumowanie wartości
|
||||||
case tp_UpdateValues: { // zmiana wartości
|
case tp_UpdateValues: { // zmiana wartości
|
||||||
auto *cell = simulation::Memory.find( Current->asNodeName ); // nazwa komórki powiązanej z eventem
|
auto *cell = simulation::Memory.find( Current->asNodeName ); // nazwa komórki powiązanej z eventem
|
||||||
if( cell ) { // McZapkie-100302
|
if( cell != nullptr ) { // McZapkie-100302
|
||||||
if( Current->iFlags & ( conditional_trackoccupied | conditional_trackfree ) ) {
|
if( Current->iFlags & ( conditional_trackoccupied | conditional_trackfree ) ) {
|
||||||
// jeśli chodzi o zajetosc toru (tor może być inny, niż wpisany w komórce)
|
// jeśli chodzi o zajetosc toru (tor może być inny, niż wpisany w komórce)
|
||||||
// nazwa toru ta sama, co nazwa komórki
|
// nazwa toru ta sama, co nazwa komórki
|
||||||
@@ -1281,7 +1324,7 @@ event_manager::InitEvents() {
|
|||||||
case tp_GetValues:
|
case tp_GetValues:
|
||||||
case tp_WhoIs: {
|
case tp_WhoIs: {
|
||||||
auto *cell = simulation::Memory.find( Current->asNodeName );
|
auto *cell = simulation::Memory.find( Current->asNodeName );
|
||||||
if( cell ) {
|
if( cell != nullptr ) {
|
||||||
Current->Params[ 8 ].asLocation = &( cell->location() );
|
Current->Params[ 8 ].asLocation = &( cell->location() );
|
||||||
Current->Params[ 9 ].asMemCell = cell;
|
Current->Params[ 9 ].asMemCell = cell;
|
||||||
if( ( Current->Type == tp_GetValues )
|
if( ( Current->Type == tp_GetValues )
|
||||||
@@ -1301,7 +1344,7 @@ event_manager::InitEvents() {
|
|||||||
case tp_CopyValues: {
|
case tp_CopyValues: {
|
||||||
// skopiowanie komórki do innej
|
// skopiowanie komórki do innej
|
||||||
auto *cell = simulation::Memory.find( Current->asNodeName ); // komórka docelowa
|
auto *cell = simulation::Memory.find( Current->asNodeName ); // komórka docelowa
|
||||||
if( cell ) {
|
if( cell != nullptr ) {
|
||||||
Current->Params[ 4 ].asLocation = &( cell->location() );
|
Current->Params[ 4 ].asLocation = &( cell->location() );
|
||||||
Current->Params[ 5 ].asMemCell = cell; // komórka docelowa
|
Current->Params[ 5 ].asMemCell = cell; // komórka docelowa
|
||||||
if( false == cell->asTrackName.empty() ) {
|
if( false == cell->asTrackName.empty() ) {
|
||||||
@@ -1338,7 +1381,7 @@ event_manager::InitEvents() {
|
|||||||
SafeDeleteArray( Current->Params[ 9 ].asText );
|
SafeDeleteArray( Current->Params[ 9 ].asText );
|
||||||
// egzemplarz modelu do animowania
|
// egzemplarz modelu do animowania
|
||||||
auto *instance = simulation::Instances.find( Current->asNodeName );
|
auto *instance = simulation::Instances.find( Current->asNodeName );
|
||||||
if( instance ) {
|
if( instance != nullptr ) {
|
||||||
if( Current->Params[ 0 ].asInt == 4 ) {
|
if( Current->Params[ 0 ].asInt == 4 ) {
|
||||||
// model dla całomodelowych animacji
|
// model dla całomodelowych animacji
|
||||||
Current->Params[ 9 ].asModel = instance;
|
Current->Params[ 9 ].asModel = instance;
|
||||||
@@ -1365,33 +1408,35 @@ event_manager::InitEvents() {
|
|||||||
case tp_Lights: {
|
case tp_Lights: {
|
||||||
// zmiana świeteł modelu
|
// zmiana świeteł modelu
|
||||||
auto *instance = simulation::Instances.find( Current->asNodeName );
|
auto *instance = simulation::Instances.find( Current->asNodeName );
|
||||||
if( instance )
|
if( instance != nullptr )
|
||||||
Current->Params[ 9 ].asModel = instance;
|
Current->Params[ 9 ].asModel = instance;
|
||||||
else
|
else
|
||||||
ErrorLog( "Bad event: lights event \"" + Current->asName + "\" cannot find model instance \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: lights event \"" + Current->asName + "\" cannot find model instance \"" + Current->asNodeName + "\"" );
|
||||||
Current->asNodeName = "";
|
Current->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
case tp_Visible: {
|
case tp_Visible: {
|
||||||
// ukrycie albo przywrócenie obiektu
|
// ukrycie albo przywrócenie obiektu
|
||||||
tmp = FindGroundNode( Current->asNodeName, TP_MODEL ); // najpierw model
|
editor::basic_node *node = simulation::Instances.find( Current->asNodeName ); // najpierw model
|
||||||
if( !tmp )
|
if( node == nullptr ) {
|
||||||
tmp = FindGroundNode( Current->asNodeName, TP_TRACK ); // albo tory?
|
// albo tory?
|
||||||
if( !tmp )
|
node = simulation::Paths.find( Current->asNodeName );
|
||||||
tmp = FindGroundNode( Current->asNodeName, TP_TRACTION ); // może druty?
|
}
|
||||||
if( tmp )
|
if( node == nullptr ) {
|
||||||
Current->Params[ 9 ].nGroundNode = tmp;
|
// może druty?
|
||||||
|
node = simulation::Traction.find( Current->asNodeName );
|
||||||
|
}
|
||||||
|
if( node != nullptr )
|
||||||
|
Current->Params[ 9 ].asEditorNode = node;
|
||||||
else
|
else
|
||||||
ErrorLog( "Bad event: visibility event \"" + Current->asName + "\" cannot find item \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: visibility event \"" + Current->asName + "\" cannot find item \"" + Current->asNodeName + "\"" );
|
||||||
Current->asNodeName = "";
|
Current->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
case tp_Switch: {
|
case tp_Switch: {
|
||||||
// przełożenie zwrotnicy albo zmiana stanu obrotnicy
|
// przełożenie zwrotnicy albo zmiana stanu obrotnicy
|
||||||
auto *track = simulation::Paths.find( Current->asNodeName );
|
auto *track = simulation::Paths.find( Current->asNodeName );
|
||||||
if( track ) {
|
if( track != nullptr ) {
|
||||||
// dowiązanie toru
|
// dowiązanie toru
|
||||||
if( track->iAction == NULL ) {
|
if( track->iAction == NULL ) {
|
||||||
// jeśli nie jest zwrotnicą ani obrotnicą to będzie się zmieniał stan uszkodzenia
|
// jeśli nie jest zwrotnicą ani obrotnicą to będzie się zmieniał stan uszkodzenia
|
||||||
@@ -1414,23 +1459,21 @@ event_manager::InitEvents() {
|
|||||||
Current->asNodeName = "";
|
Current->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
case tp_Sound: {
|
case tp_Sound: {
|
||||||
// odtworzenie dźwięku
|
// odtworzenie dźwięku
|
||||||
tmp = FindGroundNode( Current->asNodeName, TP_SOUND );
|
auto *sound = simulation::Sounds.find( Current->asNodeName );
|
||||||
if( tmp )
|
if( sound != nullptr )
|
||||||
Current->Params[ 9 ].tsTextSound = tmp->tsStaticSound;
|
Current->Params[ 9 ].tsTextSound = sound;
|
||||||
else
|
else
|
||||||
ErrorLog( "Bad event: sound event \"" + Current->asName + "\" cannot find static sound \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: sound event \"" + Current->asName + "\" cannot find static sound \"" + Current->asNodeName + "\"" );
|
||||||
Current->asNodeName = "";
|
Current->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
case tp_TrackVel: {
|
case tp_TrackVel: {
|
||||||
// ustawienie prędkości na torze
|
// ustawienie prędkości na torze
|
||||||
if( false == Current->asNodeName.empty() ) {
|
if( false == Current->asNodeName.empty() ) {
|
||||||
auto *track = simulation::Paths.find( Current->asNodeName );
|
auto *track = simulation::Paths.find( Current->asNodeName );
|
||||||
if( track ) {
|
if( track != nullptr ) {
|
||||||
// flaga zmiany prędkości toru jest istotna dla skanowania
|
// flaga zmiany prędkości toru jest istotna dla skanowania
|
||||||
track->iAction |= 0x200;
|
track->iAction |= 0x200;
|
||||||
Current->Params[ 9 ].asTrack = track;
|
Current->Params[ 9 ].asTrack = track;
|
||||||
@@ -1442,22 +1485,20 @@ event_manager::InitEvents() {
|
|||||||
Current->asNodeName = "";
|
Current->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
case tp_DynVel: {
|
case tp_DynVel: {
|
||||||
// komunikacja z pojazdem o konkretnej nazwie
|
// komunikacja z pojazdem o konkretnej nazwie
|
||||||
if( Current->asNodeName == "activator" )
|
if( Current->asNodeName == "activator" )
|
||||||
Current->Params[ 9 ].asDynamic = nullptr;
|
Current->Params[ 9 ].asDynamic = nullptr;
|
||||||
else {
|
else {
|
||||||
tmp = FindGroundNode( Current->asNodeName, TP_DYNAMIC );
|
auto *vehicle = simulation::Vehicles.find( Current->asNodeName );
|
||||||
if( tmp )
|
if( vehicle != nullptr )
|
||||||
Current->Params[ 9 ].asDynamic = tmp->DynamicObject;
|
Current->Params[ 9 ].asDynamic = vehicle;
|
||||||
else
|
else
|
||||||
Error( "Bad event: vehicle velocity event \"" + Current->asName + "\" cannot find vehicle \"" + Current->asNodeName + "\"" );
|
Error( "Bad event: vehicle velocity event \"" + Current->asName + "\" cannot find vehicle \"" + Current->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
Current->asNodeName = "";
|
Current->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
case tp_Multiple: {
|
case tp_Multiple: {
|
||||||
std::string cellastext;
|
std::string cellastext;
|
||||||
if( Current->Params[ 9 ].asText != nullptr ) { // przepisanie nazwy do bufora
|
if( Current->Params[ 9 ].asText != nullptr ) { // przepisanie nazwy do bufora
|
||||||
@@ -1494,36 +1535,27 @@ event_manager::InitEvents() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
case tp_Voltage: {
|
case tp_Voltage: {
|
||||||
// zmiana napięcia w zasilaczu (TractionPowerSource)
|
// zmiana napięcia w zasilaczu (TractionPowerSource)
|
||||||
if( !Current->asNodeName.empty() ) {
|
if( false == Current->asNodeName.empty() ) {
|
||||||
tmp = FindGroundNode( Current->asNodeName, TP_TRACTIONPOWERSOURCE ); // podłączenie zasilacza
|
auto *powersource = simulation::Powergrid.find( Current->asNodeName ); // podłączenie zasilacza
|
||||||
if( tmp )
|
if( powersource != nullptr )
|
||||||
Current->Params[ 9 ].psPower = tmp->psTractionPowerSource;
|
Current->Params[ 9 ].psPower = powersource;
|
||||||
else
|
else
|
||||||
ErrorLog( "Bad event: voltage event \"" + Current->asName + "\" cannot find power source \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: voltage event \"" + Current->asName + "\" cannot find power source \"" + Current->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
Current->asNodeName = "";
|
Current->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
case tp_Message: {
|
case tp_Message: {
|
||||||
// wyświetlenie komunikatu
|
// wyświetlenie komunikatu
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // switch
|
} // switch
|
||||||
if( Current->fDelay < 0 ) {
|
|
||||||
AddToQuery( Current, nullptr );
|
if( Current->fDelay < 0 ) { AddToQuery( Current, nullptr ); }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
for (TGroundNode *Current = nRootOfType[TP_MEMCELL]; Current; Current = Current->nNext)
|
|
||||||
{ // Ra: eventy komórek pamięci, wykonywane po wysłaniu komendy do zatrzymanego pojazdu
|
|
||||||
Current->MemCell->AssignEvents( FindEvent( Current->asName + ":sent" ) );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy method, verifies condition for specified event
|
// legacy method, verifies condition for specified event
|
||||||
|
|||||||
14
Event.h
14
Event.h
@@ -12,6 +12,9 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "dumb3d.h"
|
#include "dumb3d.h"
|
||||||
#include "classes.h"
|
#include "classes.h"
|
||||||
|
#include "names.h"
|
||||||
|
#include "scenenode.h"
|
||||||
|
#include "evlaunch.h"
|
||||||
|
|
||||||
enum TEventType {
|
enum TEventType {
|
||||||
tp_Unknown,
|
tp_Unknown,
|
||||||
@@ -61,6 +64,7 @@ union TParam
|
|||||||
void *asPointer;
|
void *asPointer;
|
||||||
TMemCell *asMemCell;
|
TMemCell *asMemCell;
|
||||||
TGroundNode *nGroundNode;
|
TGroundNode *nGroundNode;
|
||||||
|
editor::basic_node *asEditorNode;
|
||||||
glm::dvec3 const *asLocation;
|
glm::dvec3 const *asLocation;
|
||||||
TTrack *asTrack;
|
TTrack *asTrack;
|
||||||
TAnimModel *asModel;
|
TAnimModel *asModel;
|
||||||
@@ -104,7 +108,6 @@ public:
|
|||||||
// metody
|
// metody
|
||||||
TEvent(std::string const &m = "");
|
TEvent(std::string const &m = "");
|
||||||
~TEvent();
|
~TEvent();
|
||||||
void Init();
|
|
||||||
void Load(cParser *parser, Math3D::vector3 const &org);
|
void Load(cParser *parser, Math3D::vector3 const &org);
|
||||||
static void AddToQuery( TEvent *Event, TEvent *&Start );
|
static void AddToQuery( TEvent *Event, TEvent *&Start );
|
||||||
std::string CommandGet();
|
std::string CommandGet();
|
||||||
@@ -123,9 +126,12 @@ public:
|
|||||||
~event_manager();
|
~event_manager();
|
||||||
// methods
|
// methods
|
||||||
// adds provided event to the collection. returns: true on success
|
// adds provided event to the collection. returns: true on success
|
||||||
// TODO: return handle instead of pointer
|
// TBD, TODO: return handle to the event
|
||||||
bool
|
bool
|
||||||
insert( TEvent *Event );
|
insert( TEvent *Event );
|
||||||
|
bool
|
||||||
|
insert( TEventLauncher *Launcher ) {
|
||||||
|
return m_launchers.insert( Launcher ); }
|
||||||
// legacy method, returns pointer to specified event, or null
|
// legacy method, returns pointer to specified event, or null
|
||||||
TEvent *
|
TEvent *
|
||||||
FindEvent( std::string const &Name );
|
FindEvent( std::string const &Name );
|
||||||
@@ -143,6 +149,7 @@ private:
|
|||||||
// types
|
// types
|
||||||
using event_sequence = std::deque<TEvent *>;
|
using event_sequence = std::deque<TEvent *>;
|
||||||
using event_map = std::unordered_map<std::string, std::size_t>;
|
using event_map = std::unordered_map<std::string, std::size_t>;
|
||||||
|
using eventlauncher_sequence = std::vector<TEventLauncher *>;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
// legacy method, verifies condition for specified event
|
// legacy method, verifies condition for specified event
|
||||||
@@ -158,8 +165,9 @@ private:
|
|||||||
// legacy version of the above
|
// legacy version of the above
|
||||||
TEvent *QueryRootEvent { nullptr };
|
TEvent *QueryRootEvent { nullptr };
|
||||||
TEvent *m_workevent { nullptr };
|
TEvent *m_workevent { nullptr };
|
||||||
|
|
||||||
event_map m_eventmap;
|
event_map m_eventmap;
|
||||||
|
basic_table<TEventLauncher> m_launchers;
|
||||||
|
eventlauncher_sequence m_launcherqueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
9
Gauge.h
9
Gauge.h
@@ -12,15 +12,14 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Classes.h"
|
#include "Classes.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
|
||||||
typedef enum
|
enum TGaugeType {
|
||||||
{ // typ ruchu
|
// typ ruchu
|
||||||
gt_Unknown, // na razie nie znany
|
gt_Unknown, // na razie nie znany
|
||||||
gt_Rotate, // obrót
|
gt_Rotate, // obrót
|
||||||
gt_Move, // przesunięcie równoległe
|
gt_Move, // przesunięcie równoległe
|
||||||
gt_Wiper, // obrót trzech kolejnych submodeli o ten sam kąt (np. wycieraczka, drzwi
|
gt_Wiper, // obrót trzech kolejnych submodeli o ten sam kąt (np. wycieraczka, drzwi harmonijkowe)
|
||||||
// harmonijkowe)
|
|
||||||
gt_Digital // licznik cyfrowy, np. kilometrów
|
gt_Digital // licznik cyfrowy, np. kilometrów
|
||||||
} TGaugeType;
|
};
|
||||||
|
|
||||||
// animowany wskaźnik, mogący przyjmować wiele stanów pośrednich
|
// animowany wskaźnik, mogący przyjmować wiele stanów pośrednich
|
||||||
class TGauge {
|
class TGauge {
|
||||||
|
|||||||
@@ -996,10 +996,12 @@ void Global::TrainDelete(TDynamicObject *d)
|
|||||||
pWorld->TrainDelete(d);
|
pWorld->TrainDelete(d);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TDynamicObject *Global::DynamicNearest()
|
TDynamicObject *Global::DynamicNearest()
|
||||||
{ // ustalenie pojazdu najbliższego kamerze
|
{ // ustalenie pojazdu najbliższego kamerze
|
||||||
return pGround->DynamicNearest(pCamera->Pos);
|
return pGround->DynamicNearest(pCamera->Pos);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
TDynamicObject *Global::CouplerNearest()
|
TDynamicObject *Global::CouplerNearest()
|
||||||
{ // ustalenie pojazdu najbliższego kamerze
|
{ // ustalenie pojazdu najbliższego kamerze
|
||||||
|
|||||||
@@ -297,7 +297,9 @@ class Global
|
|||||||
static void TrainDelete(TDynamicObject *d);
|
static void TrainDelete(TDynamicObject *d);
|
||||||
static void ConfigParse(cParser &parser);
|
static void ConfigParse(cParser &parser);
|
||||||
static std::string GetNextSymbol();
|
static std::string GetNextSymbol();
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
static TDynamicObject * DynamicNearest();
|
static TDynamicObject * DynamicNearest();
|
||||||
|
#endif
|
||||||
static TDynamicObject * CouplerNearest();
|
static TDynamicObject * CouplerNearest();
|
||||||
static bool AddToQuery(TEvent *event, TDynamicObject *who);
|
static bool AddToQuery(TEvent *event, TDynamicObject *who);
|
||||||
static bool DoEvents();
|
static bool DoEvents();
|
||||||
|
|||||||
189
Ground.cpp
189
Ground.cpp
@@ -586,7 +586,7 @@ void TGround::Free()
|
|||||||
// RootNode=NULL;
|
// RootNode=NULL;
|
||||||
nRootDynamic = NULL;
|
nRootDynamic = NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TGroundNode * TGround::DynamicFindAny(std::string const &Name)
|
TGroundNode * TGround::DynamicFindAny(std::string const &Name)
|
||||||
{ // wyszukanie pojazdu o podanej nazwie, szukanie po wszystkich (użyć drzewa!)
|
{ // wyszukanie pojazdu o podanej nazwie, szukanie po wszystkich (użyć drzewa!)
|
||||||
for (TGroundNode *Current = nRootDynamic; Current; Current = Current->nNext)
|
for (TGroundNode *Current = nRootDynamic; Current; Current = Current->nNext)
|
||||||
@@ -603,7 +603,7 @@ TGroundNode * TGround::DynamicFind(std::string const &Name)
|
|||||||
return Current;
|
return Current;
|
||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
void
|
void
|
||||||
TGround::DynamicList(bool all)
|
TGround::DynamicList(bool all)
|
||||||
{ // odesłanie nazw pojazdów dostępnych na scenerii (nazwy, szczególnie wagonów, mogą się
|
{ // odesłanie nazw pojazdów dostępnych na scenerii (nazwy, szczególnie wagonów, mogą się
|
||||||
@@ -694,6 +694,7 @@ int iTrainSetWehicleNumber = 0;
|
|||||||
TGroundNode *nTrainSetNode = NULL; // poprzedni pojazd do łączenia
|
TGroundNode *nTrainSetNode = NULL; // poprzedni pojazd do łączenia
|
||||||
TGroundNode *nTrainSetDriver = NULL; // pojazd, któremu zostanie wysłany rozkład
|
TGroundNode *nTrainSetDriver = NULL; // pojazd, któremu zostanie wysłany rozkład
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void TGround::RaTriangleDivider(TGroundNode *node)
|
void TGround::RaTriangleDivider(TGroundNode *node)
|
||||||
{ // tworzy dodatkowe trójkąty i zmiejsza podany
|
{ // tworzy dodatkowe trójkąty i zmiejsza podany
|
||||||
// to jest wywoływane przy wczytywaniu trójkątów
|
// to jest wywoływane przy wczytywaniu trójkątów
|
||||||
@@ -814,7 +815,7 @@ void TGround::RaTriangleDivider(TGroundNode *node)
|
|||||||
RaTriangleDivider(node); // rekurencja, bo nawet na TD raz nie wystarczy
|
RaTriangleDivider(node); // rekurencja, bo nawet na TD raz nie wystarczy
|
||||||
RaTriangleDivider(ntri);
|
RaTriangleDivider(ntri);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
TGroundNode * TGround::AddGroundNode(cParser *parser)
|
TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||||
{ // wczytanie wpisu typu "node"
|
{ // wczytanie wpisu typu "node"
|
||||||
std::string str, str1, str2, str3, str4, Skin, DriverType, asNodeName;
|
std::string str, str1, str2, str3, str4, Skin, DriverType, asNodeName;
|
||||||
@@ -889,7 +890,8 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
|
|
||||||
switch (tmp->iType)
|
switch (tmp->iType)
|
||||||
{
|
{
|
||||||
case TP_TRACTION:
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
case TP_TRACTION:
|
||||||
tmp->hvTraction = new TTraction( tmp->asName );
|
tmp->hvTraction = new TTraction( tmp->asName );
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
@@ -983,7 +985,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
>> tmp->pCenter.y
|
>> tmp->pCenter.y
|
||||||
>> tmp->pCenter.z;
|
>> tmp->pCenter.z;
|
||||||
tmp->pCenter += pOrigin;
|
tmp->pCenter += pOrigin;
|
||||||
tmp->psTractionPowerSource = new TTractionPowerSource(tmp);
|
tmp->psTractionPowerSource = new TTractionPowerSource( tmp->asName );
|
||||||
tmp->psTractionPowerSource->Load(parser);
|
tmp->psTractionPowerSource->Load(parser);
|
||||||
break;
|
break;
|
||||||
case TP_MEMCELL:
|
case TP_MEMCELL:
|
||||||
@@ -1004,6 +1006,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case TP_EVLAUNCH:
|
case TP_EVLAUNCH:
|
||||||
parser->getTokens(3);
|
parser->getTokens(3);
|
||||||
*parser
|
*parser
|
||||||
@@ -1015,6 +1018,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
tmp->EvLaunch = new TEventLauncher();
|
tmp->EvLaunch = new TEventLauncher();
|
||||||
tmp->EvLaunch->Load(parser);
|
tmp->EvLaunch->Load(parser);
|
||||||
break;
|
break;
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
case TP_TRACK:
|
case TP_TRACK:
|
||||||
tmp->pTrack = new TTrack( tmp->asName );
|
tmp->pTrack = new TTrack( tmp->asName );
|
||||||
if (Global::iWriteLogEnabled & 4)
|
if (Global::iWriteLogEnabled & 4)
|
||||||
@@ -1191,57 +1195,8 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case TP_MODEL: {
|
case TP_MODEL: {
|
||||||
#ifdef EU07_USE_OLD_TERRAINCODE
|
|
||||||
if( rmin < 0 ) {
|
|
||||||
tmp->iType = TP_TERRAIN;
|
|
||||||
tmp->fSquareMinRadius = 0; // to w ogóle potrzebne?
|
|
||||||
}
|
|
||||||
parser->getTokens( 3 );
|
|
||||||
*parser >> tmp->pCenter.x >> tmp->pCenter.y >> tmp->pCenter.z;
|
|
||||||
parser->getTokens();
|
|
||||||
*parser >> tf1;
|
|
||||||
// OlO_EU&KAKISH-030103: obracanie punktow zaczepien w modelu
|
|
||||||
tmp->pCenter.RotateY( aRotate.y / 180.0 * M_PI );
|
|
||||||
// McZapkie-260402: model tez ma wspolrzedne wzgledne
|
|
||||||
tmp->pCenter += pOrigin;
|
|
||||||
|
|
||||||
tmp->Model = new TAnimModel();
|
|
||||||
tmp->Model->RaAnglesSet( aRotate.x, tf1 + aRotate.y, aRotate.z ); // dostosowanie do pochylania linii
|
|
||||||
if( tmp->Model->Load( parser, tmp->iType == TP_TERRAIN ) ) {
|
|
||||||
// wczytanie modelu, tekstury i stanu świateł...
|
|
||||||
tmp->iFlags = tmp->Model->Flags() | 0x200; // ustalenie, czy przezroczysty; flaga usuwania
|
|
||||||
}
|
|
||||||
else if( tmp->iType != TP_TERRAIN ) { // model nie wczytał się - ignorowanie node
|
|
||||||
delete tmp;
|
|
||||||
tmp = NULL; // nie może być tu return
|
|
||||||
break; // nie może być tu return?
|
|
||||||
}
|
|
||||||
if( tmp->iType == TP_TERRAIN ) { // jeśli model jest terenem, trzeba utworzyć dodatkowe obiekty
|
|
||||||
// po wczytaniu model ma już utworzone DL albo VBO
|
|
||||||
Global::pTerrainCompact = tmp->Model; // istnieje co najmniej jeden obiekt terenu
|
|
||||||
tmp->pCenter = Math3D::vector3( 0.0, 0.0, 0.0 ); // enforce placement in the world center
|
|
||||||
tmp->iCount = Global::pTerrainCompact->TerrainCount() + 1; // zliczenie submodeli
|
|
||||||
tmp->nNode = new TGroundNode[ tmp->iCount ]; // sztuczne node dla kwadratów
|
|
||||||
tmp->nNode[ 0 ].iType = TP_MODEL; // pierwszy zawiera model (dla delete)
|
|
||||||
tmp->nNode[ 0 ].Model = Global::pTerrainCompact;
|
|
||||||
tmp->nNode[ 0 ].iFlags = 0x200; // nie wyświetlany, ale usuwany
|
|
||||||
for( int i = 1; i < tmp->iCount; ++i ) { // a reszta to submodele
|
|
||||||
tmp->nNode[ i ].iType = TP_SUBMODEL;
|
|
||||||
tmp->nNode[ i ].smTerrain = Global::pTerrainCompact->TerrainSquare( i - 1 );
|
|
||||||
tmp->nNode[ i ].iFlags = 0x10; // nieprzezroczyste; nie usuwany
|
|
||||||
tmp->nNode[ i ].bVisible = true;
|
|
||||||
tmp->nNode[ i ].pCenter = tmp->pCenter; // nie przesuwamy w inne miejsce
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( !tmp->asName.empty() ) // jest pusta gdy "none"
|
|
||||||
{ // dodanie do wyszukiwarki
|
|
||||||
if( false == m_nodemap.Add( TP_MODEL, tmp->asName, tmp ) ) {
|
|
||||||
// przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna)
|
|
||||||
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if( rmin < 0 ) {
|
if( rmin < 0 ) {
|
||||||
// legacy leftover: special case, terrain provided as 3d model
|
// legacy leftover: special case, terrain provided as 3d model
|
||||||
tmp->iType = TP_TERRAIN;
|
tmp->iType = TP_TERRAIN;
|
||||||
@@ -1274,6 +1229,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
// regular 3d model
|
// regular 3d model
|
||||||
parser->getTokens( 3 );
|
parser->getTokens( 3 );
|
||||||
*parser
|
*parser
|
||||||
@@ -1304,10 +1260,11 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
|
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
// case TP_GEOMETRY :
|
// case TP_GEOMETRY :
|
||||||
case GL_TRIANGLES:
|
case GL_TRIANGLES:
|
||||||
case GL_TRIANGLE_STRIP:
|
case GL_TRIANGLE_STRIP:
|
||||||
@@ -1510,6 +1467,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
} // koniec wczytywania trójkątów
|
} // koniec wczytywania trójkątów
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
case GL_LINES:
|
case GL_LINES:
|
||||||
case GL_LINE_STRIP:
|
case GL_LINE_STRIP:
|
||||||
case GL_LINE_LOOP: {
|
case GL_LINE_LOOP: {
|
||||||
@@ -1802,7 +1760,7 @@ bool TGround::Init(std::string File)
|
|||||||
else { // jeśli jest pojazdem
|
else { // jeśli jest pojazdem
|
||||||
if( ( LastNode->DynamicObject->Mechanik != nullptr )
|
if( ( LastNode->DynamicObject->Mechanik != nullptr )
|
||||||
&& ( LastNode->DynamicObject->Mechanik->Primary() ) ) {
|
&& ( LastNode->DynamicObject->Mechanik->Primary() ) ) {
|
||||||
// jeśli jest głównym (pasażer nie jest)
|
// jeśli jest głównym (pasażer nie jest)
|
||||||
nTrainSetDriver = LastNode; // pojazd, któremu zostanie wysłany rozkład
|
nTrainSetDriver = LastNode; // pojazd, któremu zostanie wysłany rozkład
|
||||||
}
|
}
|
||||||
LastNode->nNext = nRootDynamic;
|
LastNode->nNext = nRootDynamic;
|
||||||
@@ -1859,8 +1817,7 @@ bool TGround::Init(std::string File)
|
|||||||
if (nTrainSetDriver) // pojazd, któremu zostanie wysłany rozkład
|
if (nTrainSetDriver) // pojazd, któremu zostanie wysłany rozkład
|
||||||
{ // wysłanie komendy "Timetable" ustawia odpowiedni tryb jazdy
|
{ // wysłanie komendy "Timetable" ustawia odpowiedni tryb jazdy
|
||||||
nTrainSetDriver->DynamicObject->Mechanik->DirectionInitial();
|
nTrainSetDriver->DynamicObject->Mechanik->DirectionInitial();
|
||||||
nTrainSetDriver->DynamicObject->Mechanik->PutCommand("Timetable:" + asTrainName,
|
nTrainSetDriver->DynamicObject->Mechanik->PutCommand("Timetable:" + asTrainName, fTrainSetVel, 0, NULL);
|
||||||
fTrainSetVel, 0, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( LastNode ) {
|
if( LastNode ) {
|
||||||
@@ -1926,7 +1883,7 @@ bool TGround::Init(std::string File)
|
|||||||
{
|
{
|
||||||
ErrorLog("Duplicated event: " + tmp->asName);
|
ErrorLog("Duplicated event: " + tmp->asName);
|
||||||
found->Append(tmp); // doczepka (taki wirtualny multiple bez warunków)
|
found->Append(tmp); // doczepka (taki wirtualny multiple bez warunków)
|
||||||
found->Type = tp_Ignored; // dezaktywacja pierwotnego - taka proteza na
|
found->m_ignored = true; // dezaktywacja pierwotnego - taka proteza na
|
||||||
// wsteczną zgodność
|
// wsteczną zgodność
|
||||||
// SafeDelete(tmp); //bezlitośnie usuwamy wszelkie duplikaty, żeby nie
|
// SafeDelete(tmp); //bezlitośnie usuwamy wszelkie duplikaty, żeby nie
|
||||||
// zaśmiecać drzewka
|
// zaśmiecać drzewka
|
||||||
@@ -1938,7 +1895,7 @@ bool TGround::Init(std::string File)
|
|||||||
RootEvent = tmp;
|
RootEvent = tmp;
|
||||||
if (!found)
|
if (!found)
|
||||||
{ // jeśli nazwa wystąpiła, to do kolejki i wyszukiwarki dodawany jest tylko pierwszy
|
{ // jeśli nazwa wystąpiła, to do kolejki i wyszukiwarki dodawany jest tylko pierwszy
|
||||||
if( ( RootEvent->Type != tp_Ignored )
|
if( ( RootEvent->m_ignored == false )
|
||||||
&& ( RootEvent->asName.find( "onstart" ) != std::string::npos ) ) {
|
&& ( RootEvent->asName.find( "onstart" ) != std::string::npos ) ) {
|
||||||
// event uruchamiany automatycznie po starcie
|
// event uruchamiany automatycznie po starcie
|
||||||
AddToQuery( RootEvent, NULL ); // dodanie do kolejki
|
AddToQuery( RootEvent, NULL ); // dodanie do kolejki
|
||||||
@@ -2217,7 +2174,7 @@ bool TGround::InitEvents()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // nie ma komórki, to nie będzie działał poprawnie
|
{ // nie ma komórki, to nie będzie działał poprawnie
|
||||||
Current->Type = tp_Ignored; // deaktywacja
|
Current->m_ignored = true; // deaktywacja
|
||||||
ErrorLog("Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
|
ErrorLog("Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2241,7 +2198,7 @@ bool TGround::InitEvents()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // nie ma komórki, to nie będzie działał poprawnie
|
{ // nie ma komórki, to nie będzie działał poprawnie
|
||||||
Current->Type = tp_Ignored; // deaktywacja
|
Current->m_ignored = true; // deaktywacja
|
||||||
ErrorLog("Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
|
ErrorLog("Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2637,7 +2594,7 @@ void TGround::InitTraction()
|
|||||||
nTemp = new TGroundNode();
|
nTemp = new TGroundNode();
|
||||||
nTemp->iType = TP_TRACTIONPOWERSOURCE;
|
nTemp->iType = TP_TRACTIONPOWERSOURCE;
|
||||||
nTemp->asName = Traction->asPowerSupplyName;
|
nTemp->asName = Traction->asPowerSupplyName;
|
||||||
nTemp->psTractionPowerSource = new TTractionPowerSource(nTemp);
|
nTemp->psTractionPowerSource = new TTractionPowerSource(nTemp->asName);
|
||||||
nTemp->psTractionPowerSource->Init(Traction->NominalVoltage, Traction->MaxCurrent);
|
nTemp->psTractionPowerSource->Init(Traction->NominalVoltage, Traction->MaxCurrent);
|
||||||
nTemp->nNext = nRootOfType[nTemp->iType]; // ostatni dodany dołączamy na końcu
|
nTemp->nNext = nRootOfType[nTemp->iType]; // ostatni dodany dołączamy na końcu
|
||||||
// nowego
|
// nowego
|
||||||
@@ -2826,8 +2783,11 @@ void TGround::TrackJoin(TGroundNode *Current)
|
|||||||
int iConnection;
|
int iConnection;
|
||||||
if (!Track->CurrentPrev())
|
if (!Track->CurrentPrev())
|
||||||
{
|
{
|
||||||
tmp = FindTrack(Track->CurrentSegment()->FastGetPoint_0(), iConnection,
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Current); // Current do pominięcia
|
tmp = FindTrack(Track->CurrentSegment()->FastGetPoint_0(), iConnection, Current); // Current do pominięcia
|
||||||
|
#else
|
||||||
|
std::tie( tmp, iConnection ) = simulation::Region->find_path( Track->CurrentSegment()->FastGetPoint_0(), Track );
|
||||||
|
#endif
|
||||||
switch (iConnection)
|
switch (iConnection)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@@ -2840,7 +2800,11 @@ void TGround::TrackJoin(TGroundNode *Current)
|
|||||||
}
|
}
|
||||||
if (!Track->CurrentNext())
|
if (!Track->CurrentNext())
|
||||||
{
|
{
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
tmp = FindTrack(Track->CurrentSegment()->FastGetPoint_1(), iConnection, Current);
|
tmp = FindTrack(Track->CurrentSegment()->FastGetPoint_1(), iConnection, Current);
|
||||||
|
#else
|
||||||
|
std::tie( tmp, iConnection ) = simulation::Region->find_path( Track->CurrentSegment()->FastGetPoint_1(), Track );
|
||||||
|
#endif
|
||||||
switch (iConnection)
|
switch (iConnection)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@@ -2892,6 +2856,7 @@ bool TGround::InitLaunchers()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TTrack * TGround::FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude)
|
TTrack * TGround::FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude)
|
||||||
{ // wyszukiwanie innego toru kończącego się w (Point)
|
{ // wyszukiwanie innego toru kończącego się w (Point)
|
||||||
TTrack *tmp;
|
TTrack *tmp;
|
||||||
@@ -2978,49 +2943,36 @@ TTraction * TGround::TractionNearestFind(glm::dvec3 &p, int dir, TGroundNode *n)
|
|||||||
if ((sr = FastGetSubRect(c + i, r + j)) != NULL) // o ile w ogóle sektor jest
|
if ((sr = FastGetSubRect(c + i, r + j)) != NULL) // o ile w ogóle sektor jest
|
||||||
for (nCurrent = sr->nRenderWires; nCurrent; nCurrent = nCurrent->nNext3)
|
for (nCurrent = sr->nRenderWires; nCurrent; nCurrent = nCurrent->nNext3)
|
||||||
if (nCurrent->iType == TP_TRACTION)
|
if (nCurrent->iType == TP_TRACTION)
|
||||||
if (nCurrent->hvTraction->psSection ==
|
if (nCurrent->hvTraction->psSection == n->hvTraction->psSection) // jeśli ta sama sekcja
|
||||||
n->hvTraction->psSection) // jeśli ta sama sekcja
|
|
||||||
if (nCurrent != n) // ale nie jest tym samym
|
if (nCurrent != n) // ale nie jest tym samym
|
||||||
if (nCurrent->hvTraction !=
|
if (nCurrent->hvTraction != n->hvTraction->hvNext[0]) // ale nie jest bezpośrednio podłączonym
|
||||||
n->hvTraction
|
|
||||||
->hvNext[0]) // ale nie jest bezpośrednio podłączonym
|
|
||||||
if (nCurrent->hvTraction != n->hvTraction->hvNext[1])
|
if (nCurrent->hvTraction != n->hvTraction->hvNext[1])
|
||||||
if (nCurrent->hvTraction->psPower
|
if (nCurrent->hvTraction->psPower
|
||||||
[k = (glm::dot(
|
[k = (glm::dot(
|
||||||
n->hvTraction->vParametric,
|
n->hvTraction->vParametric,
|
||||||
nCurrent->hvTraction->vParametric) >= 0 ?
|
nCurrent->hvTraction->vParametric) >= 0 ?
|
||||||
dir ^ 1 :
|
dir ^ 1 :
|
||||||
dir)]) // ma zasilanie z odpowiedniej
|
dir)]) // ma zasilanie z odpowiedniej strony
|
||||||
// strony
|
if (nCurrent->hvTraction->fResistance[k] >= 0.0) { // żeby się nie propagowały jakieś ujemne
|
||||||
if (nCurrent->hvTraction->fResistance[k] >=
|
// znaleziony kandydat do połączenia
|
||||||
0.0) //żeby się nie propagowały jakieś ujemne
|
|
||||||
{ // znaleziony kandydat do połączenia
|
|
||||||
d = glm::length2( p - glm::dvec3{ nCurrent->pCenter } ); // kwadrat odległości środków
|
d = glm::length2( p - glm::dvec3{ nCurrent->pCenter } ); // kwadrat odległości środków
|
||||||
if (dist > d)
|
if (dist > d) {
|
||||||
{ // zapamiętanie nowego najbliższego
|
// zapamiętanie nowego najbliższego
|
||||||
dist = d; // nowy rekord odległości
|
dist = d; // nowy rekord odległości
|
||||||
nBest = nCurrent;
|
nBest = nCurrent;
|
||||||
zg = k; // z którego końca brać wskaźnik
|
zg = k; // z którego końca brać wskaźnik zasilacza
|
||||||
// zasilacza
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nBest) // jak znalezione przęsło z zasilaniem, to podłączenie "równoległe"
|
if (nBest) {
|
||||||
{
|
// jak znalezione przęsło z zasilaniem, to podłączenie "równoległe"
|
||||||
n->hvTraction->ResistanceCalc(dir, nBest->hvTraction->fResistance[zg],
|
n->hvTraction->ResistanceCalc(dir, nBest->hvTraction->fResistance[zg], nBest->hvTraction->psPower[zg]);
|
||||||
nBest->hvTraction->psPower[zg]);
|
|
||||||
// testowo skrzywienie przęsła tak, aby pokazać skąd ma zasilanie
|
|
||||||
// if (dir) //1 gdy ciąg dalszy jest od strony Point2
|
|
||||||
// n->hvTraction->pPoint3=0.25*(nBest->pCenter+3*(zg?nBest->hvTraction->pPoint4:nBest->hvTraction->pPoint3));
|
|
||||||
// else
|
|
||||||
// n->hvTraction->pPoint4=0.25*(nBest->pCenter+3*(zg?nBest->hvTraction->pPoint4:nBest->hvTraction->pPoint3));
|
|
||||||
}
|
}
|
||||||
return (nBest ? nBest->hvTraction : nullptr);
|
return (nBest ? nBest->hvTraction : nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
bool TGround::AddToQuery(TEvent *Event, TDynamicObject *Node)
|
bool TGround::AddToQuery(TEvent *Event, TDynamicObject *Node)
|
||||||
{
|
{
|
||||||
if( Event->bEnabled ) {
|
if( ( false == Event->m_ignored ) && ( true == Event->bEnabled ) ) {
|
||||||
// jeśli może być dodany do kolejki (nie używany w skanowaniu)
|
// jeśli może być dodany do kolejki (nie używany w skanowaniu)
|
||||||
if( !Event->iQueued ) // jeśli nie dodany jeszcze do kolejki
|
if( !Event->iQueued ) // jeśli nie dodany jeszcze do kolejki
|
||||||
{ // kolejka eventów jest posortowana względem (fStartTime)
|
{ // kolejka eventów jest posortowana względem (fStartTime)
|
||||||
@@ -3169,8 +3121,8 @@ bool TGround::CheckQuery()
|
|||||||
}
|
}
|
||||||
else // a jak nazwa jest unikalna, to kolejka idzie dalej
|
else // a jak nazwa jest unikalna, to kolejka idzie dalej
|
||||||
QueryRootEvent = QueryRootEvent->evNext; // NULL w skrajnym przypadku
|
QueryRootEvent = QueryRootEvent->evNext; // NULL w skrajnym przypadku
|
||||||
if (tmpEvent->bEnabled)
|
if( ( false == tmpEvent->m_ignored ) && ( true == tmpEvent->bEnabled ) ) {
|
||||||
{ // w zasadzie te wyłączone są skanowane i nie powinny się nigdy w kolejce znaleźć
|
// w zasadzie te wyłączone są skanowane i nie powinny się nigdy w kolejce znaleźć
|
||||||
--tmpEvent->iQueued; // teraz moze być ponownie dodany do kolejki
|
--tmpEvent->iQueued; // teraz moze być ponownie dodany do kolejki
|
||||||
WriteLog( "EVENT LAUNCHED" + ( tmpEvent->Activator ? ( " by " + tmpEvent->Activator->asName ) : "" ) + ": " + tmpEvent->asName );
|
WriteLog( "EVENT LAUNCHED" + ( tmpEvent->Activator ? ( " by " + tmpEvent->Activator->asName ) : "" ) + ": " + tmpEvent->asName );
|
||||||
switch (tmpEvent->Type)
|
switch (tmpEvent->Type)
|
||||||
@@ -3222,7 +3174,7 @@ bool TGround::CheckQuery()
|
|||||||
// loc.Z= tmpEvent->Params[8].nGroundNode->pCenter.y;
|
// loc.Z= tmpEvent->Params[8].nGroundNode->pCenter.y;
|
||||||
if (Global::iMultiplayer) // potwierdzenie wykonania dla serwera (odczyt
|
if (Global::iMultiplayer) // potwierdzenie wykonania dla serwera (odczyt
|
||||||
// semafora już tak nie działa)
|
// semafora już tak nie działa)
|
||||||
WyslijEvent(tmpEvent->asName, tmpEvent->Activator->GetName());
|
WyslijEvent(tmpEvent->asName, tmpEvent->Activator->name());
|
||||||
// tmpEvent->Params[9].asMemCell->PutCommand(tmpEvent->Activator->Mechanik,loc);
|
// tmpEvent->Params[9].asMemCell->PutCommand(tmpEvent->Activator->Mechanik,loc);
|
||||||
tmpEvent->Params[9].asMemCell->PutCommand(
|
tmpEvent->Params[9].asMemCell->PutCommand(
|
||||||
tmpEvent->Activator->Mechanik, &tmpEvent->Params[8].nGroundNode->pCenter);
|
tmpEvent->Activator->Mechanik, &tmpEvent->Params[8].nGroundNode->pCenter);
|
||||||
@@ -3355,7 +3307,7 @@ bool TGround::CheckQuery()
|
|||||||
0) // jednoznaczne tylko, gdy nie było else
|
0) // jednoznaczne tylko, gdy nie było else
|
||||||
{
|
{
|
||||||
if (tmpEvent->Activator)
|
if (tmpEvent->Activator)
|
||||||
WyslijEvent(tmpEvent->asName, tmpEvent->Activator->GetName());
|
WyslijEvent(tmpEvent->asName, tmpEvent->Activator->name());
|
||||||
else
|
else
|
||||||
WyslijEvent(tmpEvent->asName, "");
|
WyslijEvent(tmpEvent->asName, "");
|
||||||
}
|
}
|
||||||
@@ -3468,7 +3420,6 @@ bool TGround::CheckQuery()
|
|||||||
} // while
|
} // while
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void TGround::UpdatePhys(double dt, int iter)
|
void TGround::UpdatePhys(double dt, int iter)
|
||||||
{ // aktualizacja fizyki stałym krokiem: dt=krok czasu [s], dt*iter=czas od ostatnich przeliczeń
|
{ // aktualizacja fizyki stałym krokiem: dt=krok czasu [s], dt*iter=czas od ostatnich przeliczeń
|
||||||
@@ -3587,9 +3538,8 @@ TGround::Update_Hidden() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// Winger 170204 - szukanie trakcji nad pantografami
|
// Winger 170204 - szukanie trakcji nad pantografami
|
||||||
bool TGround::GetTraction(TDynamicObject *model)
|
bool TGround::GetTraction(TDynamicObject *model)
|
||||||
{ // aktualizacja drutu zasilającego dla każdego pantografu, żeby odczytać napięcie
|
{ // aktualizacja drutu zasilającego dla każdego pantografu, żeby odczytać napięcie
|
||||||
@@ -3709,35 +3659,29 @@ bool TGround::GetTraction(TDynamicObject *model)
|
|||||||
{ // dany sektor może nie mieć nic w środku
|
{ // dany sektor może nie mieć nic w środku
|
||||||
for (node = tmp->nRenderWires; node;
|
for (node = tmp->nRenderWires; node;
|
||||||
node = node->nNext3) // następny z grupy
|
node = node->nNext3) // następny z grupy
|
||||||
if (node->iType ==
|
if (node->iType == TP_TRACTION) // w grupie tej są druty oraz inne linie
|
||||||
TP_TRACTION) // w grupie tej są druty oraz inne linie
|
|
||||||
{
|
{
|
||||||
vParam =
|
// współczynniki równania parametrycznego
|
||||||
node->hvTraction
|
vParam = node->hvTraction->vParametric;
|
||||||
->vParametric; // współczynniki równania parametrycznego
|
|
||||||
fRaParam = -glm::dot(pant0, vFront);
|
fRaParam = -glm::dot(pant0, vFront);
|
||||||
auto const paramfrontdot = glm::dot( vParam, vFront );
|
auto const paramfrontdot = glm::dot( vParam, vFront );
|
||||||
fRaParam =
|
fRaParam =
|
||||||
-( glm::dot( node->hvTraction->pPoint1, vFront ) + fRaParam )
|
-( glm::dot( node->hvTraction->pPoint1, vFront ) + fRaParam )
|
||||||
/ ( paramfrontdot != 0.0 ? paramfrontdot : 0.001 ); // div0 trap
|
/ ( paramfrontdot != 0.0 ? paramfrontdot : 0.001 ); // div0 trap
|
||||||
if ((fRaParam >= -0.001) ? (fRaParam <= 1.001) : false)
|
if ((fRaParam >= -0.001) ? (fRaParam <= 1.001) : false)
|
||||||
{ // jeśli tylko jest w przedziale, wyznaczyć odległość wzdłuż
|
{ // jeśli tylko jest w przedziale, wyznaczyć odległość wzdłuż wektorów vUp i vLeft
|
||||||
// wektorów vUp i vLeft
|
// punkt styku płaszczyzny z drutem (dla generatora łuku el.)
|
||||||
vStyk = node->hvTraction->pPoint1 +
|
vStyk = node->hvTraction->pPoint1 + fRaParam * vParam;
|
||||||
fRaParam * vParam; // punkt styku płaszczyzny z
|
// wektor musi się mieścić w przedziale ruchu pantografu
|
||||||
// drutem (dla generatora łuku
|
vGdzie = vStyk - pant0;
|
||||||
// el.)
|
fVertical = glm::dot( vGdzie, vUp);
|
||||||
vGdzie = vStyk - pant0; // wektor
|
|
||||||
fVertical = glm::dot(
|
|
||||||
vGdzie,
|
|
||||||
vUp); // musi się mieścić w przedziale ruchu pantografu
|
|
||||||
if (fVertical >= 0.0) // jeśli ponad pantografem (bo może
|
if (fVertical >= 0.0) // jeśli ponad pantografem (bo może
|
||||||
// łapać druty spod wiaduktu)
|
// łapać druty spod wiaduktu)
|
||||||
if (Global::bEnableTraction ?
|
if (Global::bEnableTraction ?
|
||||||
fVertical < p->PantWys - 0.15 :
|
fVertical < p->PantWys - 0.15 :
|
||||||
false) // jeśli drut jest niżej niż 15cm pod
|
false) {
|
||||||
// ślizgiem
|
// jeśli drut jest niżej niż 15cm pod ślizgiem
|
||||||
{ // przełączamy w tryb połamania, o ile jedzie;
|
// przełączamy w tryb połamania, o ile jedzie;
|
||||||
// (bEnableTraction) aby dało się jeździć na
|
// (bEnableTraction) aby dało się jeździć na
|
||||||
// koślawych
|
// koślawych
|
||||||
// sceneriach
|
// sceneriach
|
||||||
@@ -3827,18 +3771,7 @@ bool TGround::GetTraction(TDynamicObject *model)
|
|||||||
else
|
else
|
||||||
p->hvPowerWire = NULL; // pantograf opuszczony
|
p->hvPowerWire = NULL; // pantograf opuszczony
|
||||||
}
|
}
|
||||||
// if (model->fWahaczeAmp<model->MoverParameters->DistCounter)
|
|
||||||
//{//nieużywana normalnie zmienna ogranicza powtórzone logowania
|
|
||||||
// model->fWahaczeAmp=model->MoverParameters->DistCounter;
|
|
||||||
// ErrorLog(FloatToStrF(1000.0*model->MoverParameters->DistCounter,ffFixed,7,3)+","+FloatToStrF(p->PantTraction,ffFixed,7,3)+","+FloatToStrF(p->fHorizontal,ffFixed,7,3)+","+FloatToStrF(p->PantWys,ffFixed,7,3)+","+AnsiString(p->hvPowerWire?1:0));
|
|
||||||
// //
|
|
||||||
// if (p->fHorizontal>1.0)
|
|
||||||
//{
|
|
||||||
// //Global::iPause|=1; //zapauzowanie symulacji
|
|
||||||
// Global::fTimeSpeed=1; //spowolnienie czasu do obejrzenia pantografu
|
|
||||||
// return true; //łapacz
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
8
Ground.h
8
Ground.h
@@ -285,20 +285,24 @@ class TGround
|
|||||||
bool InitEvents();
|
bool InitEvents();
|
||||||
#endif
|
#endif
|
||||||
bool InitLaunchers();
|
bool InitLaunchers();
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TTrack * FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude);
|
TTrack * FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude);
|
||||||
TTraction * FindTraction(glm::dvec3 const &Point, int &iConnection, TGroundNode *Exclude);
|
TTraction * FindTraction(glm::dvec3 const &Point, int &iConnection, TGroundNode *Exclude);
|
||||||
TTraction * TractionNearestFind(glm::dvec3 &p, int dir, TGroundNode *n);
|
TTraction * TractionNearestFind(glm::dvec3 &p, int dir, TGroundNode *n);
|
||||||
|
#endif
|
||||||
TGroundNode * AddGroundNode(cParser *parser);
|
TGroundNode * AddGroundNode(cParser *parser);
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
||||||
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
||||||
void Update_Hidden(); // updates invisible elements of the scene
|
void Update_Hidden(); // updates invisible elements of the scene
|
||||||
|
#endif
|
||||||
bool GetTraction(TDynamicObject *model);
|
bool GetTraction(TDynamicObject *model);
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
bool AddToQuery( TEvent *Event, TDynamicObject *Node );
|
bool AddToQuery( TEvent *Event, TDynamicObject *Node );
|
||||||
bool CheckQuery();
|
bool CheckQuery();
|
||||||
#endif
|
|
||||||
TGroundNode * DynamicFindAny(std::string const &Name);
|
TGroundNode * DynamicFindAny(std::string const &Name);
|
||||||
TGroundNode * DynamicFind(std::string const &Name);
|
TGroundNode * DynamicFind(std::string const &Name);
|
||||||
|
#endif
|
||||||
void DynamicList(bool all = false);
|
void DynamicList(bool all = false);
|
||||||
TGroundNode * FindGroundNode(std::string const &asNameToFind, TGroundNodeType const iNodeType);
|
TGroundNode * FindGroundNode(std::string const &asNameToFind, TGroundNodeType const iNodeType);
|
||||||
TGroundRect * GetRect( double x, double z );
|
TGroundRect * GetRect( double x, double z );
|
||||||
@@ -325,7 +329,9 @@ class TGround
|
|||||||
// convert tp_terrain model to a series of triangle nodes
|
// convert tp_terrain model to a series of triangle nodes
|
||||||
void convert_terrain( TGroundNode const *Terrain );
|
void convert_terrain( TGroundNode const *Terrain );
|
||||||
void convert_terrain( TSubModel const *Submodel );
|
void convert_terrain( TSubModel const *Submodel );
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void RaTriangleDivider(TGroundNode *node);
|
void RaTriangleDivider(TGroundNode *node);
|
||||||
|
#endif
|
||||||
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
12
MemCell.cpp
12
MemCell.cpp
@@ -180,3 +180,15 @@ void TMemCell::AssignEvents(TEvent *e)
|
|||||||
{ // powiązanie eventu
|
{ // powiązanie eventu
|
||||||
OnSent = e;
|
OnSent = e;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// legacy method, initializes traction after deserialization from scenario file
|
||||||
|
void
|
||||||
|
memory_table::InitCells() {
|
||||||
|
|
||||||
|
for( auto *cell : m_items ) {
|
||||||
|
// Ra: eventy komórek pamięci, wykonywane po wysłaniu komendy do zatrzymanego pojazdu
|
||||||
|
cell->AssignEvents( simulation::Events.FindEvent( cell->name() + ":sent" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -61,8 +61,14 @@ class TMemCell : public editor::basic_node {
|
|||||||
void AssignEvents(TEvent *e);
|
void AssignEvents(TEvent *e);
|
||||||
};
|
};
|
||||||
|
|
||||||
class memory_manager : public basic_table<TMemCell> {
|
|
||||||
|
|
||||||
|
|
||||||
|
class memory_table : public basic_table<TMemCell> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// legacy method, initializes traction after deserialization from scenario file
|
||||||
|
void
|
||||||
|
InitCells();
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1641,7 +1641,7 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad model: reference to non-existent texture index in sub-model" + ( pName.empty() ? "" : " \"" + pName + "\"" ) );
|
ErrorLog( "Bad model: reference to nonexistent texture index in sub-model" + ( pName.empty() ? "" : " \"" + pName + "\"" ) );
|
||||||
m_material = null_handle;
|
m_material = null_handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "mczapkie/mctools.h"
|
#include "mczapkie/mctools.h"
|
||||||
#include "usefull.h"
|
#include "usefull.h"
|
||||||
|
|
||||||
TRealSound::TRealSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic,
|
TRealSound::TRealSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod, double rmin)
|
||||||
bool freqmod, double rmin)
|
|
||||||
{
|
{
|
||||||
Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
|
Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
|
||||||
}
|
}
|
||||||
@@ -32,12 +31,7 @@ TRealSound::~TRealSound()
|
|||||||
// if (this) if (pSound) pSound->Stop();
|
// if (this) if (pSound) pSound->Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TRealSound::Free()
|
void TRealSound::Init(std::string const &SoundName, double DistanceAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod, double rmin)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRealSound::Init(std::string const &SoundName, double DistanceAttenuation, double X, double Y, double Z,
|
|
||||||
bool Dynamic, bool freqmod, double rmin)
|
|
||||||
{
|
{
|
||||||
// Nazwa=SoundName; //to tak raczej nie zadziała, (SoundName) jest tymczasowe
|
// Nazwa=SoundName; //to tak raczej nie zadziała, (SoundName) jest tymczasowe
|
||||||
pSound = TSoundsManager::GetFromName(SoundName, Dynamic, &fFrequency);
|
pSound = TSoundsManager::GetFromName(SoundName, Dynamic, &fFrequency);
|
||||||
@@ -71,7 +65,7 @@ void TRealSound::Init(std::string const &SoundName, double DistanceAttenuation,
|
|||||||
dSoundAtt = -1;
|
dSoundAtt = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
double TRealSound::ListenerDistance(vector3 ListenerPosition)
|
double TRealSound::ListenerDistance( Math3D::vector3 ListenerPosition)
|
||||||
{
|
{
|
||||||
if (dSoundAtt == -1)
|
if (dSoundAtt == -1)
|
||||||
{
|
{
|
||||||
@@ -83,7 +77,7 @@ double TRealSound::ListenerDistance(vector3 ListenerPosition)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TRealSound::Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition)
|
void TRealSound::Play(double Volume, int Looping, bool ListenerInside, Math3D::vector3 NewPosition)
|
||||||
{
|
{
|
||||||
if (!pSound)
|
if (!pSound)
|
||||||
return;
|
return;
|
||||||
@@ -155,11 +149,6 @@ void TRealSound::Play(double Volume, int Looping, bool ListenerInside, vector3 N
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void TRealSound::Start(){
|
|
||||||
// włączenie dźwięku
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void TRealSound::Stop()
|
void TRealSound::Stop()
|
||||||
{
|
{
|
||||||
DWORD stat;
|
DWORD stat;
|
||||||
@@ -231,17 +220,14 @@ void TRealSound::ResetPosition()
|
|||||||
pSound->SetCurrentPosition(0);
|
pSound->SetCurrentPosition(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TTextSound::TTextSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z,
|
TTextSound::TTextSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod, double rmin) :
|
||||||
bool Dynamic, bool freqmod, double rmin)
|
TRealSound(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin)
|
||||||
: TRealSound(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin)
|
|
||||||
{
|
{
|
||||||
Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
|
Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTextSound::Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z,
|
void TTextSound::Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod, double rmin)
|
||||||
bool Dynamic, bool freqmod, double rmin)
|
|
||||||
{ // dodatkowo doczytuje plik tekstowy
|
{ // dodatkowo doczytuje plik tekstowy
|
||||||
//TRealSound::Init(SoundName, SoundAttenuation, X, Y, Z, Dynamic, freqmod, rmin);
|
|
||||||
fTime = GetWaveTime();
|
fTime = GetWaveTime();
|
||||||
std::string txt(SoundName);
|
std::string txt(SoundName);
|
||||||
txt.erase( txt.rfind( '.' ) ); // obcięcie rozszerzenia
|
txt.erase( txt.rfind( '.' ) ); // obcięcie rozszerzenia
|
||||||
@@ -253,15 +239,11 @@ void TTextSound::Init(std::string const &SoundName, double SoundAttenuation, dou
|
|||||||
txt = "sounds\\" + txt; //ścieżka może nie być podana
|
txt = "sounds\\" + txt; //ścieżka może nie być podana
|
||||||
if (FileExists(txt))
|
if (FileExists(txt))
|
||||||
{ // wczytanie
|
{ // wczytanie
|
||||||
/* TFileStream *ts = new TFileStream(txt, fmOpenRead);
|
std::ifstream inputfile( txt );
|
||||||
asText = AnsiString::StringOfChar(' ', ts->Size);
|
|
||||||
ts->Read(asText.c_str(), ts->Size);
|
|
||||||
delete ts;
|
|
||||||
*/ std::ifstream inputfile( txt );
|
|
||||||
asText.assign( std::istreambuf_iterator<char>( inputfile ), std::istreambuf_iterator<char>() );
|
asText.assign( std::istreambuf_iterator<char>( inputfile ), std::istreambuf_iterator<char>() );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
void TTextSound::Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition)
|
void TTextSound::Play(double Volume, int Looping, bool ListenerInside, Math3D::vector3 NewPosition)
|
||||||
{
|
{
|
||||||
if (false == asText.empty())
|
if (false == asText.empty())
|
||||||
{ // jeśli ma powiązany tekst
|
{ // jeśli ma powiązany tekst
|
||||||
|
|||||||
75
RealSound.h
75
RealSound.h
@@ -7,24 +7,25 @@ obtain one at
|
|||||||
http://mozilla.org/MPL/2.0/.
|
http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef RealSoundH
|
#pragma once
|
||||||
#define RealSoundH
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Sound.h"
|
|
||||||
#include "Geometry.h"
|
|
||||||
|
|
||||||
class TRealSound
|
#include "Sound.h"
|
||||||
{
|
#include "dumb3d.h"
|
||||||
protected:
|
#include "names.h"
|
||||||
|
|
||||||
|
class TRealSound {
|
||||||
|
|
||||||
|
protected:
|
||||||
PSound pSound = nullptr;
|
PSound pSound = nullptr;
|
||||||
// char *Nazwa; // dla celow odwszawiania NOTE: currently not used anywhere
|
double fDistance = 0.0;
|
||||||
double fDistance = 0.0,
|
double fPreviousDistance = 0.0; // dla liczenia Dopplera
|
||||||
fPreviousDistance = 0.0; // dla liczenia Dopplera
|
|
||||||
float fFrequency = 22050.0; // częstotliwość samplowania pliku
|
float fFrequency = 22050.0; // częstotliwość samplowania pliku
|
||||||
int iDoppler = 0; // Ra 2014-07: możliwość wyłączenia efektu Dopplera np. dla śpiewu ptaków
|
int iDoppler = 0; // Ra 2014-07: możliwość wyłączenia efektu Dopplera np. dla śpiewu ptaków
|
||||||
public:
|
public:
|
||||||
vector3 vSoundPosition; // polozenie zrodla dzwieku
|
std::string m_name;
|
||||||
|
Math3D::vector3 vSoundPosition; // polozenie zrodla dzwieku
|
||||||
double dSoundAtt = -1.0; // odleglosc polowicznego zaniku dzwieku
|
double dSoundAtt = -1.0; // odleglosc polowicznego zaniku dzwieku
|
||||||
double AM = 0.0; // mnoznik amplitudy
|
double AM = 0.0; // mnoznik amplitudy
|
||||||
double AA = 0.0; // offset amplitudy
|
double AA = 0.0; // offset amplitudy
|
||||||
@@ -32,37 +33,43 @@ class TRealSound
|
|||||||
double FA = 0.0; // offset czestotliwosci
|
double FA = 0.0; // offset czestotliwosci
|
||||||
bool bLoopPlay = false; // czy zapętlony dźwięk jest odtwarzany
|
bool bLoopPlay = false; // czy zapętlony dźwięk jest odtwarzany
|
||||||
TRealSound() = default;
|
TRealSound() = default;
|
||||||
TRealSound( std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic,
|
TRealSound( std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod = false, double rmin = 0.0 );
|
||||||
bool freqmod = false, double rmin = 0.0);
|
|
||||||
~TRealSound();
|
~TRealSound();
|
||||||
void Free();
|
void Init( std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod = false, double rmin = 0.0 );
|
||||||
void Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic,
|
double ListenerDistance( Math3D::vector3 ListenerPosition);
|
||||||
bool freqmod = false, double rmin = 0.0);
|
void Play(double Volume, int Looping, bool ListenerInside, Math3D::vector3 NewPosition);
|
||||||
double ListenerDistance(vector3 ListenerPosition);
|
|
||||||
void Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition);
|
|
||||||
void Start();
|
|
||||||
void Stop();
|
void Stop();
|
||||||
void AdjFreq(double Freq, double dt);
|
void AdjFreq(double Freq, double dt);
|
||||||
void SetPan(int Pan);
|
void SetPan(int Pan);
|
||||||
double GetWaveTime(); // McZapkie TODO: dorobic dla roznych bps
|
double GetWaveTime(); // McZapkie TODO: dorobic dla roznych bps
|
||||||
int GetStatus();
|
int GetStatus();
|
||||||
void ResetPosition();
|
void ResetPosition();
|
||||||
// void FreqReset(float f=22050.0) {fFrequency=f;};
|
|
||||||
bool Empty() { return ( pSound == nullptr ); }
|
bool Empty() { return ( pSound == nullptr ); }
|
||||||
|
void
|
||||||
|
name( std::string Name ) {
|
||||||
|
m_name = Name; }
|
||||||
|
std::string const &
|
||||||
|
name() const {
|
||||||
|
return m_name; }
|
||||||
|
glm::dvec3
|
||||||
|
location() const {
|
||||||
|
return vSoundPosition; };
|
||||||
};
|
};
|
||||||
|
|
||||||
class TTextSound : public TRealSound
|
|
||||||
{ // dźwięk ze stenogramem
|
|
||||||
|
class TTextSound : public TRealSound {
|
||||||
|
// dźwięk ze stenogramem
|
||||||
std::string asText;
|
std::string asText;
|
||||||
float fTime; // czas trwania
|
float fTime; // czas trwania
|
||||||
public:
|
public:
|
||||||
TTextSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z,
|
TTextSound(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod = false, double rmin = 0.0);
|
||||||
bool Dynamic, bool freqmod = false, double rmin = 0.0);
|
void Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z, bool Dynamic, bool freqmod = false, double rmin = 0.0);
|
||||||
void Init(std::string const &SoundName, double SoundAttenuation, double X, double Y, double Z,
|
void Play(double Volume, int Looping, bool ListenerInside, Math3D::vector3 NewPosition);
|
||||||
bool Dynamic, bool freqmod = false, double rmin = 0.0);
|
|
||||||
void Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TSynthSound
|
class TSynthSound
|
||||||
{ // klasa generująca sygnał odjazdu (Rp12, Rp13), potem rozbudować o pracę manewrowego...
|
{ // klasa generująca sygnał odjazdu (Rp12, Rp13), potem rozbudować o pracę manewrowego...
|
||||||
int iIndex[44]; // indeksy początkowe, gdy mamy kilka wariantów dźwięków składowych
|
int iIndex[44]; // indeksy początkowe, gdy mamy kilka wariantów dźwięków składowych
|
||||||
@@ -74,10 +81,16 @@ class TSynthSound
|
|||||||
// 41 - "tysiące"
|
// 41 - "tysiące"
|
||||||
// 42 - indeksy początkowe dla "odjazd"
|
// 42 - indeksy początkowe dla "odjazd"
|
||||||
// 43 - indeksy początkowe dla "gotów"
|
// 43 - indeksy początkowe dla "gotów"
|
||||||
PSound *sSound; // posortowana tablica dźwięków, rozmiar zależny od liczby znalezionych plików
|
PSound sSound; // posortowana tablica dźwięków, rozmiar zależny od liczby znalezionych plików
|
||||||
// a może zamiast wielu plików/dźwięków zrobić jeden połączony plik i posługiwać się czasem
|
// a może zamiast wielu plików/dźwięków zrobić jeden połączony plik i posługiwać się czasem
|
||||||
// od..do?
|
// od..do?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// collection of generators for power grid present in the scene
|
||||||
|
class sound_table : public basic_table<TTextSound> {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#endif
|
|
||||||
|
|||||||
39
Segment.cpp
39
Segment.cpp
@@ -103,7 +103,7 @@ bool TSegment::Init( Math3D::vector3 &NewPoint1, Math3D::vector3 NewCPointOut, M
|
|||||||
fStep = fNewStep;
|
fStep = fNewStep;
|
||||||
if (fLength <= 0) {
|
if (fLength <= 0) {
|
||||||
|
|
||||||
ErrorLog( "Bad geometry: zero length spline \"" + pOwner->NameGet() + "\" (location: " + to_string( glm::dvec3{ Point1 } ) + ")" );
|
ErrorLog( "Bad geometry: zero length spline \"" + pOwner->name() + "\" (location: " + to_string( glm::dvec3{ Point1 } ) + ")" );
|
||||||
fLength = 0.01; // crude workaround TODO: fix this properly
|
fLength = 0.01; // crude workaround TODO: fix this properly
|
||||||
/*
|
/*
|
||||||
return false; // zerowe nie mogą być
|
return false; // zerowe nie mogą być
|
||||||
@@ -205,7 +205,7 @@ double TSegment::GetTFromS(double const s) const
|
|||||||
// Newton's method failed. If this happens, increase iterations or
|
// Newton's method failed. If this happens, increase iterations or
|
||||||
// tolerance or integration accuracy.
|
// tolerance or integration accuracy.
|
||||||
// return -1; //Ra: tu nigdy nie dojdzie
|
// return -1; //Ra: tu nigdy nie dojdzie
|
||||||
ErrorLog( "Bad geometry: shape estimation failed for spline \"" + pOwner->NameGet() + "\" (location: " + to_string( glm::dvec3{ Point1 } ) + ")" );
|
ErrorLog( "Bad geometry: shape estimation failed for spline \"" + pOwner->name() + "\" (location: " + to_string( glm::dvec3{ Point1 } ) + ")" );
|
||||||
// MessageBox(0,"Too many iterations","GetTFromS",MB_OK);
|
// MessageBox(0,"Too many iterations","GetTFromS",MB_OK);
|
||||||
return fTime;
|
return fTime;
|
||||||
};
|
};
|
||||||
@@ -323,23 +323,28 @@ Math3D::vector3 TSegment::GetPoint(double const fDistance) const
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void TSegment::RaPositionGet(double const fDistance, Math3D::vector3 &p, Math3D::vector3 &a) const
|
// ustalenie pozycji osi na torze, przechyłki, pochylenia i kierunku jazdy
|
||||||
{ // ustalenie pozycji osi na torze, przechyłki, pochylenia i kierunku jazdy
|
void TSegment::RaPositionGet(double const fDistance, Math3D::vector3 &p, Math3D::vector3 &a) const {
|
||||||
if (bCurve)
|
|
||||||
{ // można by wprowadzić uproszczony wzór dla okręgów płaskich
|
if (bCurve) {
|
||||||
double t = GetTFromS(fDistance); // aproksymacja dystansu na krzywej Beziera na parametr (t)
|
// można by wprowadzić uproszczony wzór dla okręgów płaskich
|
||||||
p = RaInterpolate(t);
|
auto const t = GetTFromS(fDistance); // aproksymacja dystansu na krzywej Beziera na parametr (t)
|
||||||
a.x = (1.0 - t) * fRoll1 + (t)*fRoll2; // przechyłka w danym miejscu (zmienia się liniowo)
|
p = FastGetPoint( t );
|
||||||
|
// przechyłka w danym miejscu (zmienia się liniowo)
|
||||||
|
a.x = interpolate<double>( fRoll1, fRoll2, t );
|
||||||
// pochodna jest 3*A*t^2+2*B*t+C
|
// pochodna jest 3*A*t^2+2*B*t+C
|
||||||
a.y = atan(t * (t * 3.0 * vA.y + vB.y + vB.y) + vC.y); // pochylenie krzywej (w pionie)
|
auto const tangent = t * ( t * 3.0 * vA + vB + vB ) + vC;
|
||||||
a.z = -atan2(t * (t * 3.0 * vA.x + vB.x + vB.x) + vC.x,
|
// pochylenie krzywej (w pionie)
|
||||||
t * (t * 3.0 * vA.z + vB.z + vB.z) + vC.z); // kierunek krzywej w planie
|
a.y = std::atan( tangent.y );
|
||||||
|
// kierunek krzywej w planie
|
||||||
|
a.z = -std::atan2( tangent.x, tangent.z );
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{ // wyliczenie dla odcinka prostego jest prostsze
|
// wyliczenie dla odcinka prostego jest prostsze
|
||||||
double t = fDistance / fLength; // zerowych torów nie ma
|
auto const t = fDistance / fLength; // zerowych torów nie ma
|
||||||
p = ((1.0 - t) * Point1 + (t)*Point2);
|
p = FastGetPoint( t );
|
||||||
a.x = (1.0 - t) * fRoll1 + (t)*fRoll2; // przechyłka w danym miejscu (zmienia się liniowo)
|
// przechyłka w danym miejscu (zmienia się liniowo)
|
||||||
|
a.x = interpolate<double>( fRoll1, fRoll2, t );
|
||||||
a.y = fStoop; // pochylenie toru prostego
|
a.y = fStoop; // pochylenie toru prostego
|
||||||
a.z = fDirection; // kierunek toru w planie
|
a.z = fDirection; // kierunek toru w planie
|
||||||
}
|
}
|
||||||
|
|||||||
36
Segment.h
36
Segment.h
@@ -14,37 +14,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Classes.h"
|
#include "Classes.h"
|
||||||
#include "usefull.h"
|
#include "usefull.h"
|
||||||
|
|
||||||
// 110405 Ra: klasa punktów przekroju z normalnymi
|
|
||||||
/*
|
|
||||||
class vector6 : public Math3D::vector3
|
|
||||||
{ // punkt przekroju wraz z wektorem normalnym
|
|
||||||
public:
|
|
||||||
Math3D::vector3 n;
|
|
||||||
vector6()
|
|
||||||
{
|
|
||||||
x = y = z = n.x = n.z = 0.0;
|
|
||||||
n.y = 1.0;
|
|
||||||
};
|
|
||||||
vector6(double a, double b, double c, double d, double e, double f)
|
|
||||||
{
|
|
||||||
x = a;
|
|
||||||
y = b;
|
|
||||||
z = c;
|
|
||||||
n.x = 0.0;
|
|
||||||
n.y = 1.0;
|
|
||||||
n.z = 0.0;
|
|
||||||
}; // Ra: bo na razie są z tym problemy
|
|
||||||
vector6(double a, double b, double c)
|
|
||||||
{
|
|
||||||
x = a;
|
|
||||||
y = b;
|
|
||||||
z = c;
|
|
||||||
n.x = 0.0;
|
|
||||||
n.y = 1.0;
|
|
||||||
n.z = 0.0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
class TSegment
|
class TSegment
|
||||||
{ // aproksymacja toru (zwrotnica ma dwa takie, jeden z nich jest aktywny)
|
{ // aproksymacja toru (zwrotnica ma dwa takie, jeden z nich jest aktywny)
|
||||||
private:
|
private:
|
||||||
@@ -60,7 +29,6 @@ class TSegment
|
|||||||
double fStoop = 0.0; // Ra: kąt wzniesienia; dla łuku od Point1
|
double fStoop = 0.0; // Ra: kąt wzniesienia; dla łuku od Point1
|
||||||
Math3D::vector3 vA, vB, vC; // współczynniki wielomianów trzeciego stopnia vD==Point1
|
Math3D::vector3 vA, vB, vC; // współczynniki wielomianów trzeciego stopnia vD==Point1
|
||||||
TTrack *pOwner = nullptr; // wskaźnik na właściciela
|
TTrack *pOwner = nullptr; // wskaźnik na właściciela
|
||||||
double fAngle[ 2 ] = { 0.0, 0.0 }; // kąty zakończenia drogi na przejazdach
|
|
||||||
|
|
||||||
Math3D::vector3
|
Math3D::vector3
|
||||||
GetFirstDerivative(double const fTime) const;
|
GetFirstDerivative(double const fTime) const;
|
||||||
@@ -140,10 +108,6 @@ public:
|
|||||||
int
|
int
|
||||||
RaSegCount() const {
|
RaSegCount() const {
|
||||||
return fTsBuffer ? iSegCount : 1; };
|
return fTsBuffer ? iSegCount : 1; };
|
||||||
inline
|
|
||||||
void
|
|
||||||
AngleSet(int const i, double const a) {
|
|
||||||
fAngle[i] = a; };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
63
Track.cpp
63
Track.cpp
@@ -26,6 +26,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "AnimModel.h"
|
#include "AnimModel.h"
|
||||||
#include "MemCell.h"
|
#include "MemCell.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
|
#include "simulation.h"
|
||||||
|
|
||||||
// 101206 Ra: trapezoidalne drogi i tory
|
// 101206 Ra: trapezoidalne drogi i tory
|
||||||
// 110720 Ra: rozprucie zwrotnicy i odcinki izolowane
|
// 110720 Ra: rozprucie zwrotnicy i odcinki izolowane
|
||||||
@@ -2651,6 +2652,31 @@ int TTrack::TestPoint(vector3 *Point)
|
|||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// retrieves list of the track's end points
|
||||||
|
std::vector<glm::dvec3>
|
||||||
|
TTrack::endpoints() const {
|
||||||
|
|
||||||
|
switch( eType ) {
|
||||||
|
case tt_Normal:
|
||||||
|
case tt_Table: {
|
||||||
|
return {
|
||||||
|
glm::dvec3{ Segment->FastGetPoint_0() },
|
||||||
|
glm::dvec3{ Segment->FastGetPoint_1() } };
|
||||||
|
}
|
||||||
|
case tt_Switch:
|
||||||
|
case tt_Cross: {
|
||||||
|
return {
|
||||||
|
glm::dvec3{ SwitchExtension->Segments[ 0 ]->FastGetPoint_0() },
|
||||||
|
glm::dvec3{ SwitchExtension->Segments[ 0 ]->FastGetPoint_1() },
|
||||||
|
glm::dvec3{ SwitchExtension->Segments[ 1 ]->FastGetPoint_0() },
|
||||||
|
glm::dvec3{ SwitchExtension->Segments[ 1 ]->FastGetPoint_1() } };
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTrack::MovedUp1(float const dh)
|
void TTrack::MovedUp1(float const dh)
|
||||||
{ // poprawienie przechyłki wymaga wydłużenia podsypki
|
{ // poprawienie przechyłki wymaga wydłużenia podsypki
|
||||||
fTexHeight1 += dh;
|
fTexHeight1 += dh;
|
||||||
@@ -2745,11 +2771,11 @@ TTrack * TTrack::Connected(int s, double &d) const
|
|||||||
// legacy method, initializes tracks after deserialization from scenario file
|
// legacy method, initializes tracks after deserialization from scenario file
|
||||||
void
|
void
|
||||||
path_table::InitTracks() {
|
path_table::InitTracks() {
|
||||||
/*
|
|
||||||
TGroundNode *Model;
|
|
||||||
int iConnection;
|
|
||||||
|
|
||||||
for( auto *track : m_paths ) {
|
int connection { -1 };
|
||||||
|
TTrack *matchingtrack { nullptr };
|
||||||
|
|
||||||
|
for( auto *track : m_items ) {
|
||||||
|
|
||||||
track->AssignEvents(
|
track->AssignEvents(
|
||||||
simulation::Events.FindEvent( track->asEvent0Name ),
|
simulation::Events.FindEvent( track->asEvent0Name ),
|
||||||
@@ -2776,30 +2802,32 @@ path_table::InitTracks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (track->eType) {
|
switch (track->eType) {
|
||||||
|
/*
|
||||||
|
// TODO: re-enable
|
||||||
case tt_Table: {
|
case tt_Table: {
|
||||||
// obrotnicę też łączymy na starcie z innymi torami
|
// obrotnicę też łączymy na starcie z innymi torami
|
||||||
// szukamy modelu o tej samej nazwie
|
// szukamy modelu o tej samej nazwie
|
||||||
Model = FindGroundNode(Current->asName, TP_MODEL);
|
auto *instance = simulation::Instances.find( trackname );
|
||||||
// wiązanie toru z modelem obrotnicy
|
// wiązanie toru z modelem obrotnicy
|
||||||
track->RaAssign(
|
track->RaAssign(
|
||||||
Current,
|
Current,
|
||||||
( Model ?
|
instance,
|
||||||
Model->Model :
|
|
||||||
nullptr ),
|
|
||||||
simulation::Events.FindEvent( trackname + ":done" ),
|
simulation::Events.FindEvent( trackname + ":done" ),
|
||||||
simulation::Events.FindEvent( trackname + ":joined" ) );
|
simulation::Events.FindEvent( trackname + ":joined" ) );
|
||||||
if( Model == nullptr ) {
|
if( instance == nullptr ) {
|
||||||
// jak nie ma modelu to pewnie jest wykolejnica, a ta jest domyślnie zamknięta i wykoleja
|
// jak nie ma modelu to pewnie jest wykolejnica, a ta jest domyślnie zamknięta i wykoleja
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// no break on purpose:
|
||||||
// jak coś pójdzie źle, to robimy z tego normalny tor
|
// jak coś pójdzie źle, to robimy z tego normalny tor
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
case tt_Normal: {
|
case tt_Normal: {
|
||||||
// tylko proste są podłączane do rozjazdów, stąd dwa rozjazdy się nie połączą ze sobą
|
// tylko proste są podłączane do rozjazdów, stąd dwa rozjazdy się nie połączą ze sobą
|
||||||
if( track->CurrentPrev() == nullptr ) {
|
if( track->CurrentPrev() == nullptr ) {
|
||||||
// tylko jeśli jeszcze nie podłączony
|
// tylko jeśli jeszcze nie podłączony
|
||||||
auto *matchingtrack = simulation::Region.FindTrack( track->CurrentSegment()->FastGetPoint_0(), iConnection, track );
|
std::tie( matchingtrack, connection ) = simulation::Region->find_path( track->CurrentSegment()->FastGetPoint_0(), track );
|
||||||
switch( iConnection ) {
|
switch( connection ) {
|
||||||
case -1: // Ra: pierwsza koncepcja zawijania samochodów i statków
|
case -1: // Ra: pierwsza koncepcja zawijania samochodów i statków
|
||||||
// if ((Track->iCategoryFlag&1)==0) //jeśli nie jest torem szynowym
|
// if ((Track->iCategoryFlag&1)==0) //jeśli nie jest torem szynowym
|
||||||
// Track->ConnectPrevPrev(Track,0); //łączenie końca odcinka do samego siebie
|
// Track->ConnectPrevPrev(Track,0); //łączenie końca odcinka do samego siebie
|
||||||
@@ -2830,12 +2858,14 @@ path_table::InitTracks() {
|
|||||||
matchingtrack->SetConnections( 1 ); // robi też Switch(0)
|
matchingtrack->SetConnections( 1 ); // robi też Switch(0)
|
||||||
matchingtrack->Switch( 0 );
|
matchingtrack->Switch( 0 );
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( track->CurrentNext() == nullptr ) {
|
if( track->CurrentNext() == nullptr ) {
|
||||||
// tylko jeśli jeszcze nie podłączony
|
// tylko jeśli jeszcze nie podłączony
|
||||||
auto *matchingtrack = simulation::Region.FindTrack( track->CurrentSegment()->FastGetPoint_1(), iConnection, track );
|
std::tie( matchingtrack, connection ) = simulation::Region->find_path( track->CurrentSegment()->FastGetPoint_1(), track );
|
||||||
switch( iConnection ) {
|
switch( connection ) {
|
||||||
case -1: // Ra: pierwsza koncepcja zawijania samochodów i statków
|
case -1: // Ra: pierwsza koncepcja zawijania samochodów i statków
|
||||||
// if ((Track->iCategoryFlag&1)==0) //jeśli nie jest torem szynowym
|
// if ((Track->iCategoryFlag&1)==0) //jeśli nie jest torem szynowym
|
||||||
// Track->ConnectNextNext(Track,1); //łączenie końca odcinka do samego siebie
|
// Track->ConnectNextNext(Track,1); //łączenie końca odcinka do samego siebie
|
||||||
@@ -2866,6 +2896,8 @@ path_table::InitTracks() {
|
|||||||
matchingtrack->SetConnections( 1 ); // robi też Switch(0)
|
matchingtrack->SetConnections( 1 ); // robi też Switch(0)
|
||||||
// tmp->Switch(0);
|
// tmp->Switch(0);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2910,11 +2942,12 @@ path_table::InitTracks() {
|
|||||||
else {
|
else {
|
||||||
// utworzenie automatycznej komórki
|
// utworzenie automatycznej komórki
|
||||||
// TODO: determine suitable location for this one, create and add world reference node
|
// TODO: determine suitable location for this one, create and add world reference node
|
||||||
auto *memorycell = new TMemCell( isolated->asName ); // to nie musi mieć nazwy, nazwa w wyszukiwarce wystarczy
|
scene::node_data nodedata;
|
||||||
|
nodedata.name = isolated->asName;
|
||||||
|
auto *memorycell = new TMemCell( nodedata ); // to nie musi mieć nazwy, nazwa w wyszukiwarce wystarczy
|
||||||
simulation::Memory.insert( memorycell );
|
simulation::Memory.insert( memorycell );
|
||||||
isolated->pMemCell = memorycell; // wskaźnik komóki przekazany do odcinka izolowanego
|
isolated->pMemCell = memorycell; // wskaźnik komóki przekazany do odcinka izolowanego
|
||||||
}
|
}
|
||||||
isolated = isolated->Next();
|
isolated = isolated->Next();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
4
Track.h
4
Track.h
@@ -119,7 +119,6 @@ class TTrack : public editor::basic_node {
|
|||||||
friend class opengl_renderer;
|
friend class opengl_renderer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// TGroundNode * pMyNode = nullptr; // Ra: proteza, żeby tor znał swoją nazwę TODO: odziedziczyć TTrack z TGroundNode
|
|
||||||
TIsolated * pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów
|
TIsolated * pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów
|
||||||
std::shared_ptr<TSwitchExtension> SwitchExtension; // dodatkowe dane do toru, który jest zwrotnicą
|
std::shared_ptr<TSwitchExtension> SwitchExtension; // dodatkowe dane do toru, który jest zwrotnicą
|
||||||
std::shared_ptr<TSegment> Segment;
|
std::shared_ptr<TSegment> Segment;
|
||||||
@@ -234,6 +233,9 @@ public:
|
|||||||
void
|
void
|
||||||
origin( glm::dvec3 Origin ) {
|
origin( glm::dvec3 Origin ) {
|
||||||
m_origin = Origin; }
|
m_origin = Origin; }
|
||||||
|
// retrieves list of the track's end points
|
||||||
|
std::vector<glm::dvec3>
|
||||||
|
endpoints() const;
|
||||||
|
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void create_geometry( geometrybank_handle const &Bank, glm::dvec3 const &Origin ); // wypełnianie VBO
|
void create_geometry( geometrybank_handle const &Bank, glm::dvec3 const &Origin ); // wypełnianie VBO
|
||||||
|
|||||||
322
Traction.cpp
322
Traction.cpp
@@ -91,7 +91,6 @@ sekcji z sąsiedniego przęsła).
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
TTraction::TTraction( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
|
TTraction::TTraction( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
|
||||||
|
|
||||||
// legacy constructor
|
// legacy constructor
|
||||||
TTraction::TTraction( std::string Name ) {
|
TTraction::TTraction( std::string Name ) {
|
||||||
|
|
||||||
@@ -173,6 +172,13 @@ TTraction::Load( cParser *parser, glm::dvec3 const &pOrigin ) {
|
|||||||
m_location = interpolate( pPoint2, pPoint1, 0.5 );
|
m_location = interpolate( pPoint2, pPoint1, 0.5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// retrieves list of the track's end points
|
||||||
|
std::vector<glm::dvec3>
|
||||||
|
TTraction::endpoints() const {
|
||||||
|
|
||||||
|
return { pPoint1, pPoint2 };
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t
|
std::size_t
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TTraction::create_geometry( geometrybank_handle const &Bank, glm::dvec3 const &Origin ) {
|
TTraction::create_geometry( geometrybank_handle const &Bank, glm::dvec3 const &Origin ) {
|
||||||
@@ -621,205 +627,213 @@ TTraction::wire_color() const {
|
|||||||
// legacy method, initializes traction after deserialization from scenario file
|
// legacy method, initializes traction after deserialization from scenario file
|
||||||
void
|
void
|
||||||
traction_table::InitTraction() {
|
traction_table::InitTraction() {
|
||||||
/*
|
|
||||||
//łączenie drutów ze sobą oraz z torami i eventami
|
//łączenie drutów ze sobą oraz z torami i eventami
|
||||||
// TGroundNode *nCurrent, *nTemp;
|
// TGroundNode *nCurrent, *nTemp;
|
||||||
// TTraction *tmp; // znalezione przęsło
|
// TTraction *tmp; // znalezione przęsło
|
||||||
int iConnection;
|
|
||||||
std::string name;
|
int connection { -1 };
|
||||||
|
TTraction *matchingtraction { nullptr };
|
||||||
|
|
||||||
for( auto *traction : m_items ) {
|
for( auto *traction : m_items ) {
|
||||||
// podłączenie do zasilacza, żeby można było sumować prąd kilku pojazdów
|
// podłączenie do zasilacza, żeby można było sumować prąd kilku pojazdów
|
||||||
// a jednocześnie z jednego miejsca zmieniać napięcie eventem
|
// a jednocześnie z jednego miejsca zmieniać napięcie eventem
|
||||||
// wykonywane najpierw, żeby można było logować podłączenie 2 zasilaczy do jednego drutu
|
// wykonywane najpierw, żeby można było logować podłączenie 2 zasilaczy do jednego drutu
|
||||||
// izolator zawieszony na przęśle jest ma być osobnym odcinkiem drutu o długości ok. 1m,
|
// izolator zawieszony na przęśle jest ma być osobnym odcinkiem drutu o długości ok. 1m,
|
||||||
// podłączonym do zasilacza o nazwie "*" (gwiazka); "none" nie będzie odpowiednie
|
// podłączonym do zasilacza o nazwie "*" (gwiazka); "none" nie będzie odpowiednie
|
||||||
nTemp = FindGroundNode(traction->asPowerSupplyName, TP_TRACTIONPOWERSOURCE);
|
auto *powersource = simulation::Powergrid.find( traction->asPowerSupplyName );
|
||||||
if (nTemp) // jak zasilacz znaleziony
|
if( powersource ) {
|
||||||
traction->PowerSet(nTemp->psTractionPowerSource); // to podłączyć do przęsła
|
// jak zasilacz znaleziony to podłączyć do przęsła
|
||||||
else if (traction->asPowerSupplyName != "*") // gwiazdka dla przęsła z izolatorem
|
traction->PowerSet( powersource );
|
||||||
if (traction->asPowerSupplyName != "none") // dopuszczamy na razie brak podłączenia?
|
}
|
||||||
{ // logowanie błędu i utworzenie zasilacza o domyślnej zawartości
|
else {
|
||||||
ErrorLog("Missed TractionPowerSource: " + traction->asPowerSupplyName);
|
if( ( traction->asPowerSupplyName != "*" ) // gwiazdka dla przęsła z izolatorem
|
||||||
nTemp = new TGroundNode();
|
&& ( traction->asPowerSupplyName != "none" ) ) { // dopuszczamy na razie brak podłączenia?
|
||||||
nTemp->iType = TP_TRACTIONPOWERSOURCE;
|
// logowanie błędu i utworzenie zasilacza o domyślnej zawartości
|
||||||
nTemp->asName = traction->asPowerSupplyName;
|
ErrorLog( "Bad scenario: traction piece connected to nonexistent power source \"" + traction->asPowerSupplyName + "\"" );
|
||||||
nTemp->psTractionPowerSource = new TTractionPowerSource(nTemp);
|
scene::node_data nodedata;
|
||||||
nTemp->psTractionPowerSource->Init(traction->NominalVoltage, traction->MaxCurrent);
|
nodedata.name = traction->asPowerSupplyName;
|
||||||
nTemp->nNext = nRootOfType[nTemp->iType]; // ostatni dodany dołączamy na końcu
|
powersource = new TTractionPowerSource( nodedata );
|
||||||
// nowego
|
powersource->Init( traction->NominalVoltage, traction->MaxCurrent );
|
||||||
nRootOfType[nTemp->iType] = nTemp; // ustawienie nowego na początku listy
|
simulation::Powergrid.insert( powersource );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( auto *traction : m_items ) {
|
for( auto *traction : m_items ) {
|
||||||
|
|
||||||
if (!traction->hvNext[0]) // tylko jeśli jeszcze nie podłączony
|
if (!traction->hvNext[0]) {
|
||||||
{
|
// tylko jeśli jeszcze nie podłączony
|
||||||
tmp = FindTraction(traction->pPoint1, iConnection, nCurrent);
|
std::tie( matchingtraction, connection ) = simulation::Region->find_traction( traction->pPoint1, traction );
|
||||||
switch (iConnection)
|
switch (connection) {
|
||||||
{
|
case 0: {
|
||||||
case 0:
|
traction->Connect( 0, matchingtraction, 0 );
|
||||||
traction->Connect(0, tmp, 0);
|
break;
|
||||||
break;
|
}
|
||||||
case 1:
|
case 1: {
|
||||||
traction->Connect(0, tmp, 1);
|
traction->Connect( 0, matchingtraction, 1 );
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (traction->hvNext[0]) // jeśli został podłączony
|
if( traction->hvNext[ 0 ] ) {
|
||||||
if (traction->psSection && tmp->psSection) // tylko przęsło z izolatorem może nie
|
// jeśli został podłączony
|
||||||
// mieć zasilania, bo ma 2, trzeba
|
if( ( traction->psSection != nullptr )
|
||||||
// sprawdzać sąsiednie
|
&& ( matchingtraction->psSection != nullptr ) ) {
|
||||||
if (traction->psSection !=
|
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
|
||||||
tmp->psSection) // połączone odcinki mają różne zasilacze
|
if( traction->psSection != matchingtraction->psSection ) {
|
||||||
{ // to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo
|
// połączone odcinki mają różne zasilacze
|
||||||
// błąd
|
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
|
||||||
if (traction->psSection->bSection && !tmp->psSection->bSection)
|
if( ( true == traction->psSection->bSection )
|
||||||
{ //(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
|
&& ( false == matchingtraction->psSection->bSection ) ) {
|
||||||
tmp->PowerSet(traction->psSection); // zastąpienie wskazaniem sekcji
|
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
|
||||||
|
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
|
||||||
}
|
}
|
||||||
else if (!traction->psSection->bSection && tmp->psSection->bSection)
|
else if( ( false == traction->psSection->bSection ) &&
|
||||||
{ //(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
|
( true == matchingtraction->psSection->bSection ) ) {
|
||||||
traction->PowerSet(tmp->psSection); // zastąpienie wskazaniem sekcji
|
//(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 ) );
|
||||||
}
|
}
|
||||||
else // jeśli obie to sekcje albo obie podstacje, to będzie błąd
|
|
||||||
ErrorLog("Bad power: at " +
|
|
||||||
to_string(traction->pPoint1.x, 2, 6) + " " +
|
|
||||||
to_string(traction->pPoint1.y, 2, 6) + " " +
|
|
||||||
to_string(traction->pPoint1.z, 2, 6));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!traction->hvNext[1]) // tylko jeśli jeszcze nie podłączony
|
if (!traction->hvNext[1]) {
|
||||||
{
|
// tylko jeśli jeszcze nie podłączony
|
||||||
tmp = FindTraction(traction->pPoint2, iConnection, nCurrent);
|
std::tie( matchingtraction, connection ) = simulation::Region->find_traction( traction->pPoint2, traction );
|
||||||
switch (iConnection)
|
switch (connection) {
|
||||||
{
|
case 0: {
|
||||||
case 0:
|
traction->Connect( 1, matchingtraction, 0 );
|
||||||
traction->Connect(1, tmp, 0);
|
break;
|
||||||
break;
|
}
|
||||||
case 1:
|
case 1: {
|
||||||
traction->Connect(1, tmp, 1);
|
traction->Connect( 1, matchingtraction, 1 );
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (traction->hvNext[1]) // jeśli został podłączony
|
if( traction->hvNext[ 1 ] ) {
|
||||||
if (traction->psSection && tmp->psSection) // tylko przęsło z izolatorem może nie
|
// jeśli został podłączony
|
||||||
// mieć zasilania, bo ma 2, trzeba
|
if( ( traction->psSection != nullptr )
|
||||||
// sprawdzać sąsiednie
|
&& ( matchingtraction->psSection != nullptr ) ) {
|
||||||
if (traction->psSection != tmp->psSection)
|
// tylko przęsło z izolatorem może nie mieć zasilania, bo ma 2, trzeba sprawdzać sąsiednie
|
||||||
{ // to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo
|
if( traction->psSection != matchingtraction->psSection ) {
|
||||||
// błąd
|
// to może być albo podłączenie podstacji lub kabiny sekcyjnej do sekcji, albo błąd
|
||||||
if (traction->psSection->bSection && !tmp->psSection->bSection)
|
if( ( true == traction->psSection->bSection )
|
||||||
{ //(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
|
&& ( false == matchingtraction->psSection->bSection ) ) {
|
||||||
tmp->PowerSet(traction->psSection); // zastąpienie wskazaniem sekcji
|
//(tmp->psSection) jest podstacją, a (Traction->psSection) nazwą sekcji
|
||||||
|
matchingtraction->PowerSet( traction->psSection ); // zastąpienie wskazaniem sekcji
|
||||||
}
|
}
|
||||||
else if (!traction->psSection->bSection && tmp->psSection->bSection)
|
else if( ( false == traction->psSection->bSection )
|
||||||
{ //(Traction->psSection) jest podstacją, a (tmp->psSection) nazwą sekcji
|
&& ( true == matchingtraction->psSection->bSection ) ) {
|
||||||
traction->PowerSet(tmp->psSection); // zastąpienie wskazaniem sekcji
|
//(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 ) );
|
||||||
}
|
}
|
||||||
else // jeśli obie to sekcje albo obie podstacje, to będzie błąd
|
|
||||||
ErrorLog("Bad power: at " +
|
|
||||||
to_string(traction->pPoint2.x, 2, 6) + " " +
|
|
||||||
to_string(traction->pPoint2.y, 2, 6) + " " +
|
|
||||||
to_string(traction->pPoint2.z, 2, 6));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iConnection = 0; // teraz będzie licznikiem końców
|
auto endcount { 0 };
|
||||||
for( auto *traction : m_items ) {
|
for( auto *traction : m_items ) {
|
||||||
// operacje mające na celu wykrywanie bieżni wspólnych i łączenie przęseł naprążania
|
// operacje mające na celu wykrywanie bieżni wspólnych i łączenie przęseł naprążania
|
||||||
if (traction->WhereIs()) // oznakowanie przedostatnich przęseł
|
if( traction->WhereIs() ) {
|
||||||
{ // poszukiwanie bieżni wspólnej dla przedostatnich przęseł, również w celu połączenia
|
// true for outer pieces of the traction section
|
||||||
// zasilania
|
|
||||||
// to się nie sprawdza, bo połączyć się mogą dwa niezasilane odcinki jako najbliższe
|
|
||||||
// sobie
|
|
||||||
// nCurrent->hvTraction->hvParallel=TractionNearestFind(nCurrent->pCenter,0,nCurrent);
|
|
||||||
// //szukanie najbliższego przęsła
|
|
||||||
// trzeba by zliczać końce, a potem wpisać je do tablicy, aby sukcesywnie podłączać do
|
|
||||||
// zasilaczy
|
|
||||||
traction->iTries = 5; // oznaczanie końcowych
|
traction->iTries = 5; // oznaczanie końcowych
|
||||||
++iConnection;
|
++endcount;
|
||||||
}
|
}
|
||||||
if (traction->fResistance[0] == 0.0)
|
if (traction->fResistance[0] == 0.0) {
|
||||||
{
|
// obliczanie przęseł w segmencie z bezpośrednim zasilaniem
|
||||||
traction->ResistanceCalc(); // obliczanie przęseł w segmencie z bezpośrednim zasilaniem
|
traction->ResistanceCalc();
|
||||||
// ErrorLog("Section "+nCurrent->hvTraction->asPowerSupplyName+" connected"); //jako
|
|
||||||
// niby błąd będzie bardziej widoczne
|
|
||||||
traction->iTries = 0; // nie potrzeba mu szukać zasilania
|
traction->iTries = 0; // nie potrzeba mu szukać zasilania
|
||||||
}
|
}
|
||||||
// if (!Traction->hvParallel) //jeszcze utworzyć pętle z bieżni wspólnych
|
|
||||||
}
|
}
|
||||||
int zg = 0; // zgodność kierunku przęseł, tymczasowo iterator do tabeli końców
|
|
||||||
// końców jest ok. 10 razy mniej niż wszystkich przęseł (Quark: 216)
|
std::vector<TTraction *> ends; ends.reserve( endcount );
|
||||||
TGroundNode **nEnds = new TGroundNode *[iConnection];
|
|
||||||
for( auto *traction : m_items ) {
|
for( auto *traction : m_items ) {
|
||||||
//łączenie bieżni wspólnych, w tym oznaczanie niepodanych jawnie
|
//łączenie bieżni wspólnych, w tym oznaczanie niepodanych jawnie
|
||||||
if (!traction->asParallel.empty()) // będzie wskaźnik na inne przęsło
|
if( false == traction->asParallel.empty() ) {
|
||||||
|
// będzie wskaźnik na inne przęsło
|
||||||
if( ( traction->asParallel == "none" )
|
if( ( traction->asParallel == "none" )
|
||||||
|| ( traction->asParallel == "*" ) ) {
|
|| ( traction->asParallel == "*" ) ) {
|
||||||
// jeśli nieokreślone
|
// jeśli nieokreślone
|
||||||
traction->iLast = 2; // jakby przedostatni - niech po prostu szuka (iLast już przeliczone)
|
traction->iLast = 2; // jakby przedostatni - niech po prostu szuka (iLast już przeliczone)
|
||||||
}
|
}
|
||||||
else if (!traction->hvParallel) // jeśli jeszcze nie został włączony w kółko
|
else if( traction->hvParallel == nullptr ) {
|
||||||
{
|
// jeśli jeszcze nie został włączony w kółko
|
||||||
auto *nTemp = find( traction->asParallel );
|
auto *nTemp = find( traction->asParallel );
|
||||||
if (nTemp)
|
if( nTemp != nullptr ) {
|
||||||
{ // o ile zostanie znalezione przęsło o takiej nazwie
|
// o ile zostanie znalezione przęsło o takiej nazwie
|
||||||
if (!nTemp->hvParallel) // jeśli tamten jeszcze nie ma wskaźnika bieżni wspólnej
|
if( nTemp->hvParallel == nullptr ) {
|
||||||
|
// jeśli tamten jeszcze nie ma wskaźnika bieżni wspólnej
|
||||||
traction->hvParallel = nTemp; // wpisać siebie i dalej dać mu wskaźnik zwrotny
|
traction->hvParallel = nTemp; // wpisać siebie i dalej dać mu wskaźnik zwrotny
|
||||||
else // a jak ma, to albo dołączyć się do kółeczka
|
}
|
||||||
|
else {
|
||||||
|
// a jak ma, to albo dołączyć się do kółeczka
|
||||||
traction->hvParallel = nTemp->hvParallel; // przjąć dotychczasowy wskaźnik od niego
|
traction->hvParallel = nTemp->hvParallel; // przjąć dotychczasowy wskaźnik od niego
|
||||||
|
}
|
||||||
nTemp->hvParallel = traction; // i na koniec ustawienie wskaźnika zwrotnego
|
nTemp->hvParallel = traction; // i na koniec ustawienie wskaźnika zwrotnego
|
||||||
}
|
}
|
||||||
if (!traction->hvParallel)
|
if( traction->hvParallel == nullptr ) {
|
||||||
ErrorLog("Missed overhead: " + traction->asParallel); // logowanie braku
|
ErrorLog( "Missed overhead: " + traction->asParallel ); // logowanie braku
|
||||||
}
|
|
||||||
if (traction->iTries > 0) // jeśli zaznaczony do podłączenia
|
|
||||||
// if (!nCurrent->hvTraction->psPower[0]||!nCurrent->hvTraction->psPower[1])
|
|
||||||
if (zg < iConnection) // zabezpieczenie
|
|
||||||
nEnds[zg++] = nCurrent; // wypełnianie tabeli końców w celu szukania im połączeń
|
|
||||||
}
|
|
||||||
while( zg < iConnection ) {
|
|
||||||
// zapełnienie do końca tablicy, jeśli by jakieś końce wypadły
|
|
||||||
nEnds[ zg++ ] = nullptr;
|
|
||||||
}
|
|
||||||
zg = 1; // nieefektywny przebieg kończy łączenie
|
|
||||||
while (zg)
|
|
||||||
{ // ustalenie zastępczej rezystancji dla każdego przęsła
|
|
||||||
zg = 0; // flaga podłączonych przęseł końcowych: -1=puste wskaźniki, 0=coś zostało,
|
|
||||||
// 1=wykonano łączenie
|
|
||||||
for (int i = 0; i < iConnection; ++i)
|
|
||||||
if (nEnds[i]) // załatwione będziemy zerować
|
|
||||||
{ // każdy przebieg to próba podłączenia końca segmentu naprężania do innego zasilanego
|
|
||||||
// przęsła
|
|
||||||
if (nEnds[i]->hvTraction->hvNext[0])
|
|
||||||
{ // jeśli końcowy ma ciąg dalszy od strony 0 (Point1), szukamy odcinka najbliższego
|
|
||||||
// do Point2
|
|
||||||
if (TractionNearestFind(nEnds[i]->hvTraction->pPoint2, 0,
|
|
||||||
nEnds[i])) // poszukiwanie przęsła
|
|
||||||
{
|
|
||||||
nEnds[i] = NULL;
|
|
||||||
zg = 1; // jak coś zostało podłączone, to może zasilanie gdzieś dodatkowo
|
|
||||||
// dotrze
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (nEnds[i]->hvTraction->hvNext[1])
|
|
||||||
{ // jeśli końcowy ma ciąg dalszy od strony 1 (Point2), szukamy odcinka najbliższego
|
|
||||||
// do Point1
|
|
||||||
if (TractionNearestFind(nEnds[i]->hvTraction->pPoint1, 1,
|
|
||||||
nEnds[i])) // poszukiwanie przęsła
|
|
||||||
{
|
|
||||||
nEnds[i] = NULL;
|
|
||||||
zg = 1; // jak coś zostało podłączone, to może zasilanie gdzieś dodatkowo
|
|
||||||
// dotrze
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // gdy koniec jest samotny, to na razie nie zostanie podłączony (nie powinno
|
|
||||||
// takich być)
|
|
||||||
nEnds[i] = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if( traction->iTries > 0 ) {
|
||||||
|
// jeśli zaznaczony do podłączenia
|
||||||
|
// wypełnianie tabeli końców w celu szukania im połączeń
|
||||||
|
ends.emplace_back( traction );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delete[] nEnds; // nie potrzebne już
|
|
||||||
*/
|
bool connected; // nieefektywny przebieg kończy łączenie
|
||||||
|
do {
|
||||||
|
// ustalenie zastępczej rezystancji dla każdego przęsła
|
||||||
|
// flaga podłączonych przęseł końcowych: -1=puste wskaźniki, 0=coś zostało, 1=wykonano łączenie
|
||||||
|
connected = false;
|
||||||
|
for( auto &end : ends ) {
|
||||||
|
// załatwione będziemy zerować
|
||||||
|
if( end == nullptr ) { continue; }
|
||||||
|
// każdy przebieg to próba podłączenia końca segmentu naprężania do innego zasilanego przęsła
|
||||||
|
if( end->hvNext[ 0 ] != nullptr ) {
|
||||||
|
// jeśli końcowy ma ciąg dalszy od strony 0 (Point1), szukamy odcinka najbliższego do Point2
|
||||||
|
std::tie( matchingtraction, connection ) = simulation::Region->find_traction( end->pPoint2, end, 0 );
|
||||||
|
if( matchingtraction != nullptr ) {
|
||||||
|
// jak znalezione przęsło z zasilaniem, to podłączenie "równoległe"
|
||||||
|
end->ResistanceCalc( 0, matchingtraction->fResistance[ connection ], matchingtraction->psPower[ connection ] );
|
||||||
|
// jak coś zostało podłączone, to może zasilanie gdzieś dodatkowo dotrze
|
||||||
|
connected = true;
|
||||||
|
end = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( end->hvNext[ 1 ] != nullptr ) {
|
||||||
|
// jeśli końcowy ma ciąg dalszy od strony 1 (Point2), szukamy odcinka najbliższego do Point1
|
||||||
|
std::tie( matchingtraction, connection ) = simulation::Region->find_traction( end->pPoint1, end, 1 );
|
||||||
|
if( matchingtraction != nullptr ) {
|
||||||
|
// jak znalezione przęsło z zasilaniem, to podłączenie "równoległe"
|
||||||
|
end->ResistanceCalc( 1, matchingtraction->fResistance[ connection ], matchingtraction->psPower[ connection ] );
|
||||||
|
// jak coś zostało podłączone, to może zasilanie gdzieś dodatkowo dotrze
|
||||||
|
connected = true;
|
||||||
|
end = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// gdy koniec jest samotny, to na razie nie zostanie podłączony (nie powinno takich być)
|
||||||
|
end = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while( true == connected );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,13 +55,16 @@ class TTraction : public editor::basic_node {
|
|||||||
TTraction( scene::node_data const &Nodedata );
|
TTraction( scene::node_data const &Nodedata );
|
||||||
// legacy constructor
|
// legacy constructor
|
||||||
TTraction( std::string Name );
|
TTraction( std::string Name );
|
||||||
virtual ~TTraction() = default;
|
|
||||||
|
|
||||||
void Load( cParser *parser, glm::dvec3 const &pOrigin );
|
void Load( cParser *parser, glm::dvec3 const &pOrigin );
|
||||||
// set origin point
|
// set origin point
|
||||||
void
|
void
|
||||||
origin( glm::dvec3 Origin ) {
|
origin( glm::dvec3 Origin ) {
|
||||||
m_origin = Origin; }
|
m_origin = Origin; }
|
||||||
|
// retrieves list of the track's end points
|
||||||
|
std::vector<glm::dvec3>
|
||||||
|
endpoints() const;
|
||||||
|
|
||||||
// creates geometry data in specified geometry bank. returns: number of created elements, or NULL
|
// 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
|
// NOTE: deleting nodes doesn't currently release geometry data owned by the node. TODO: implement erasing individual geometry chunks and banks
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
|||||||
@@ -20,14 +20,12 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
TTractionPowerSource::TTractionPowerSource(TGroundNode const *node) :
|
TTractionPowerSource::TTractionPowerSource( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
|
||||||
gMyNode( node )
|
// legacy constructor
|
||||||
{
|
TTractionPowerSource::TTractionPowerSource( std::string Name ) {
|
||||||
psNode[0] = nullptr; // sekcje zostaną podłączone do zasilaczy
|
|
||||||
psNode[1] = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
TTractionPowerSource::~TTractionPowerSource(){};
|
m_name = Name;
|
||||||
|
}
|
||||||
|
|
||||||
void TTractionPowerSource::Init(double const u, double const i)
|
void TTractionPowerSource::Init(double const u, double const i)
|
||||||
{ // ustawianie zasilacza przy braku w scenerii
|
{ // ustawianie zasilacza przy braku w scenerii
|
||||||
@@ -36,61 +34,67 @@ void TTractionPowerSource::Init(double const u, double const i)
|
|||||||
MaxOutputCurrent = i;
|
MaxOutputCurrent = i;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TTractionPowerSource::Load(cParser *parser)
|
bool TTractionPowerSource::Load(cParser *parser) {
|
||||||
{
|
|
||||||
std::string token;
|
|
||||||
// AnsiString str;
|
|
||||||
// str= Parser->GetNextSymbol()LowerCase();
|
|
||||||
// asName= str;
|
|
||||||
parser->getTokens(5);
|
|
||||||
*parser >> NominalVoltage >> VoltageFrequency >> InternalRes >> MaxOutputCurrent >>
|
|
||||||
FastFuseTimeOut;
|
|
||||||
parser->getTokens();
|
|
||||||
*parser >> FastFuseRepetition;
|
|
||||||
parser->getTokens();
|
|
||||||
*parser >> SlowFuseTimeOut;
|
|
||||||
parser->getTokens();
|
|
||||||
*parser >> token;
|
|
||||||
if (token.compare("recuperation") == 0)
|
|
||||||
Recuperation = true;
|
|
||||||
else if (token.compare("section") == 0) // odłącznik sekcyjny
|
|
||||||
bSection = true; // nie jest źródłem zasilania, a jedynie informuje o prądzie odłączenia
|
|
||||||
// sekcji z obwodu
|
|
||||||
parser->getTokens();
|
|
||||||
*parser >> token;
|
|
||||||
if (token.compare("end") != 0)
|
|
||||||
Error("tractionpowersource end statement missing");
|
|
||||||
// if (!bSection) //odłącznik sekcji zasadniczo nie ma impedancji (0.01 jest OK)
|
|
||||||
if (InternalRes < 0.1) // coś mała ta rezystancja była...
|
|
||||||
InternalRes = 0.2; // tak około 0.2, wg
|
|
||||||
// http://www.ikolej.pl/fileadmin/user_upload/Seminaria_IK/13_05_07_Prezentacja_Kruczek.pdf
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool TTractionPowerSource::Render()
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
{
|
parser->getTokens( 7, false );
|
||||||
|
*parser
|
||||||
|
#else
|
||||||
|
parser->getTokens( 10, false );
|
||||||
|
*parser
|
||||||
|
>> m_location.x
|
||||||
|
>> m_location.y
|
||||||
|
>> m_location.z
|
||||||
|
#endif
|
||||||
|
>> NominalVoltage
|
||||||
|
>> VoltageFrequency
|
||||||
|
>> InternalRes
|
||||||
|
>> MaxOutputCurrent
|
||||||
|
>> FastFuseTimeOut
|
||||||
|
>> FastFuseRepetition
|
||||||
|
>> SlowFuseTimeOut;
|
||||||
|
|
||||||
|
std::string token { parser->getToken<std::string>() };
|
||||||
|
if( token == "recuperation" ) {
|
||||||
|
Recuperation = true;
|
||||||
|
}
|
||||||
|
else if( token == "section" ) {
|
||||||
|
// odłącznik sekcyjny
|
||||||
|
// nie jest źródłem zasilania, a jedynie informuje o prądzie odłączenia sekcji z obwodu
|
||||||
|
bSection = true;
|
||||||
|
}
|
||||||
|
// skip rest of the section
|
||||||
|
while( ( false == token.empty() )
|
||||||
|
&& ( token != "end" ) ) {
|
||||||
|
|
||||||
|
token = parser->getToken<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( InternalRes < 0.1 ) {
|
||||||
|
// coś mała ta rezystancja była...
|
||||||
|
// tak około 0.2, wg
|
||||||
|
// http://www.ikolej.pl/fileadmin/user_upload/Seminaria_IK/13_05_07_Prezentacja_Kruczek.pdf
|
||||||
|
InternalRes = 0.2;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TTractionPowerSource::Update(double dt)
|
bool TTractionPowerSource::Update(double dt)
|
||||||
{ // powinno być wykonane raz na krok fizyki
|
{ // powinno być wykonane raz na krok fizyki
|
||||||
// if (NominalVoltage * TotalPreviousAdmitance >
|
// iloczyn napięcia i admitancji daje prąd
|
||||||
// MaxOutputCurrent * 0.00000005) // iloczyn napięcia i admitancji daje prąd
|
if (NominalVoltage * TotalPreviousAdmitance > MaxOutputCurrent) {
|
||||||
// ErrorLog("Power overload: \"" + gMyNode->asName + "\" with current " + AnsiString(NominalVoltage * TotalPreviousAdmitance) + "A");
|
|
||||||
if (NominalVoltage * TotalPreviousAdmitance >
|
|
||||||
MaxOutputCurrent) // iloczyn napięcia i admitancji daje prąd
|
|
||||||
{
|
|
||||||
FastFuse = true;
|
FastFuse = true;
|
||||||
FuseCounter += 1;
|
FuseCounter += 1;
|
||||||
if (FuseCounter > FastFuseRepetition)
|
if (FuseCounter > FastFuseRepetition) {
|
||||||
{
|
|
||||||
SlowFuse = true;
|
SlowFuse = true;
|
||||||
ErrorLog("Power overload: \"" + gMyNode->asName + "\" disabled for " +
|
ErrorLog( "Power overload: \"" + m_name + "\" disabled for " + std::to_string( SlowFuseTimeOut ) + "s" );
|
||||||
std::to_string(SlowFuseTimeOut) + "s");
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
ErrorLog("Power overload: \"" + gMyNode->asName + "\" disabled for " +
|
ErrorLog( "Power overload: \"" + m_name + "\" disabled for " + std::to_string( FastFuseTimeOut ) + "s" );
|
||||||
std::to_string(FastFuseTimeOut) + "s");
|
}
|
||||||
|
|
||||||
FuseTimer = 0;
|
FuseTimer = 0;
|
||||||
}
|
}
|
||||||
if (FastFuse || SlowFuse)
|
if (FastFuse || SlowFuse)
|
||||||
@@ -145,4 +149,15 @@ void TTractionPowerSource::PowerSet(TTractionPowerSource *ps)
|
|||||||
// else ErrorLog("nie może być więcej punktów zasilania niż dwa");
|
// else ErrorLog("nie może być więcej punktów zasilania niż dwa");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
|
void
|
||||||
|
powergridsource_table::update( double const Deltatime ) {
|
||||||
|
|
||||||
|
for( auto *powersource : m_items ) {
|
||||||
|
powersource->Update( Deltatime );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ obtain one at
|
|||||||
http://mozilla.org/MPL/2.0/.
|
http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TractionPowerH
|
#pragma once
|
||||||
#define TractionPowerH
|
|
||||||
|
#include "scenenode.h"
|
||||||
#include "parser.h" //Tolaris-010603
|
#include "parser.h" //Tolaris-010603
|
||||||
|
#include "names.h"
|
||||||
|
|
||||||
class TGroundNode;
|
class TTractionPowerSource : public editor::basic_node {
|
||||||
|
|
||||||
class TTractionPowerSource
|
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
double NominalVoltage = 0.0;
|
double NominalVoltage = 0.0;
|
||||||
double VoltageFrequency = 0.0;
|
double VoltageFrequency = 0.0;
|
||||||
@@ -33,27 +33,34 @@ class TTractionPowerSource
|
|||||||
bool SlowFuse = false;
|
bool SlowFuse = false;
|
||||||
double FuseTimer = 0.0;
|
double FuseTimer = 0.0;
|
||||||
int FuseCounter = 0;
|
int FuseCounter = 0;
|
||||||
TGroundNode const *gMyNode = nullptr; // wskaźnik na węzeł rodzica
|
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
public: // zmienne publiczne
|
// zmienne publiczne
|
||||||
TTractionPowerSource *psNode[2]; // zasilanie na końcach dla sekcji
|
TTractionPowerSource *psNode[ 2 ] = { nullptr, nullptr }; // zasilanie na końcach dla sekcji
|
||||||
bool bSection = false; // czy jest sekcją
|
bool bSection = false; // czy jest sekcją
|
||||||
public:
|
|
||||||
// AnsiString asName;
|
TTractionPowerSource( scene::node_data const &Nodedata );
|
||||||
TTractionPowerSource(TGroundNode const *node);
|
// legacy constructor
|
||||||
~TTractionPowerSource();
|
TTractionPowerSource( std::string Name );
|
||||||
|
|
||||||
void Init(double const u, double const i);
|
void Init(double const u, double const i);
|
||||||
bool Load(cParser *parser);
|
bool Load(cParser *parser);
|
||||||
bool Render();
|
|
||||||
bool Update(double dt);
|
bool Update(double dt);
|
||||||
double CurrentGet(double res);
|
double CurrentGet(double res);
|
||||||
void VoltageSet(double const v)
|
void VoltageSet(double const v) {
|
||||||
{
|
NominalVoltage = v; };
|
||||||
NominalVoltage = v;
|
|
||||||
};
|
|
||||||
void PowerSet(TTractionPowerSource *ps);
|
void PowerSet(TTractionPowerSource *ps);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// collection of generators for power grid present in the scene
|
||||||
|
class powergridsource_table : public basic_table<TTractionPowerSource> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
|
void
|
||||||
|
update( double const Deltatime );
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#endif
|
|
||||||
|
|||||||
12
Train.cpp
12
Train.cpp
@@ -357,14 +357,6 @@ TTrain::TTrain() {
|
|||||||
fPress[ i ][ j ] = 0.0;
|
fPress[ i ][ j ] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTrain::~TTrain()
|
|
||||||
{
|
|
||||||
if (DynamicObject)
|
|
||||||
if (DynamicObject->Mechanik)
|
|
||||||
DynamicObject->Mechanik->TakeControl(
|
|
||||||
true); // likwidacja kabiny wymaga przejęcia przez AI
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d)
|
bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d)
|
||||||
{ // powiązanie ręcznego sterowania kabiną z pojazdem
|
{ // powiązanie ręcznego sterowania kabiną z pojazdem
|
||||||
// Global::pUserDynamic=NewDynamicObject; //pojazd renderowany bez trzęsienia
|
// Global::pUserDynamic=NewDynamicObject; //pojazd renderowany bez trzęsienia
|
||||||
@@ -3587,7 +3579,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
iDoorNo[i] = p->iAnimType[ANIM_DOORS];
|
iDoorNo[i] = p->iAnimType[ANIM_DOORS];
|
||||||
iUnits[i] = iUnitNo;
|
iUnits[i] = iUnitNo;
|
||||||
cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.length()];
|
cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.length()];
|
||||||
asCarName[i] = p->GetName();
|
asCarName[i] = p->name();
|
||||||
bPants[iUnitNo - 1][0] = (bPants[iUnitNo - 1][0] || p->MoverParameters->PantFrontUp);
|
bPants[iUnitNo - 1][0] = (bPants[iUnitNo - 1][0] || p->MoverParameters->PantFrontUp);
|
||||||
bPants[iUnitNo - 1][1] = (bPants[iUnitNo - 1][1] || p->MoverParameters->PantRearUp);
|
bPants[iUnitNo - 1][1] = (bPants[iUnitNo - 1][1] || p->MoverParameters->PantRearUp);
|
||||||
bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow);
|
bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow);
|
||||||
@@ -6259,7 +6251,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
|||||||
}
|
}
|
||||||
else if (token == "pyscreen:")
|
else if (token == "pyscreen:")
|
||||||
{
|
{
|
||||||
pyScreens.init(*parser, DynamicObject->mdKabina, DynamicObject->GetName(),
|
pyScreens.init(*parser, DynamicObject->mdKabina, DynamicObject->name(),
|
||||||
NewCabNo);
|
NewCabNo);
|
||||||
}
|
}
|
||||||
// btLampkaUnknown.Init("unknown",mdKabina,false);
|
// btLampkaUnknown.Init("unknown",mdKabina,false);
|
||||||
|
|||||||
1
Train.h
1
Train.h
@@ -80,7 +80,6 @@ class TTrain
|
|||||||
bool ShowNextCurrent; // pokaz przd w podlaczonej lokomotywie (ET41)
|
bool ShowNextCurrent; // pokaz przd w podlaczonej lokomotywie (ET41)
|
||||||
bool InitializeCab(int NewCabNo, std::string const &asFileName);
|
bool InitializeCab(int NewCabNo, std::string const &asFileName);
|
||||||
TTrain();
|
TTrain();
|
||||||
~TTrain();
|
|
||||||
// McZapkie-010302
|
// McZapkie-010302
|
||||||
bool Init(TDynamicObject *NewDynamicObject, bool e3d = false);
|
bool Init(TDynamicObject *NewDynamicObject, bool e3d = false);
|
||||||
void OnKeyDown(int cKey);
|
void OnKeyDown(int cKey);
|
||||||
|
|||||||
201
World.cpp
201
World.cpp
@@ -207,6 +207,13 @@ void TWorld::TrainDelete(TDynamicObject *d)
|
|||||||
if (Train)
|
if (Train)
|
||||||
if (Train->Dynamic() != d)
|
if (Train->Dynamic() != d)
|
||||||
return; // nie tego usuwać
|
return; // nie tego usuwać
|
||||||
|
#ifdef EU07_SCENERY_EDITOR
|
||||||
|
if( ( Train->DynamicObject )
|
||||||
|
&& ( Train->DynamicObject->Mechanik ) ) {
|
||||||
|
// likwidacja kabiny wymaga przejęcia przez AI
|
||||||
|
Train->DynamicObject->Mechanik->TakeControl( true );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
delete Train; // i nie ma czym sterować
|
delete Train; // i nie ma czym sterować
|
||||||
Train = NULL;
|
Train = NULL;
|
||||||
Controlled = NULL; // tego też już nie ma
|
Controlled = NULL; // tego też już nie ma
|
||||||
@@ -263,13 +270,25 @@ bool TWorld::Init( GLFWwindow *Window ) {
|
|||||||
UILayer.set_progress( "Preparing train / Przygotowanie kabiny" );
|
UILayer.set_progress( "Preparing train / Przygotowanie kabiny" );
|
||||||
WriteLog( "Player train init: " + Global::asHumanCtrlVehicle );
|
WriteLog( "Player train init: " + Global::asHumanCtrlVehicle );
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TGroundNode *nPlayerTrain = NULL;
|
TGroundNode *nPlayerTrain = NULL;
|
||||||
if (Global::asHumanCtrlVehicle != "ghostview")
|
#else
|
||||||
nPlayerTrain = Ground.DynamicFind(Global::asHumanCtrlVehicle); // szukanie w tych z obsadą
|
TDynamicObject *nPlayerTrain;
|
||||||
|
#endif
|
||||||
|
if( Global::asHumanCtrlVehicle != "ghostview" )
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
nPlayerTrain = Ground.DynamicFind( Global::asHumanCtrlVehicle ); // szukanie w tych z obsadą
|
||||||
|
#else
|
||||||
|
nPlayerTrain = simulation::Vehicles.find( Global::asHumanCtrlVehicle );
|
||||||
|
#endif
|
||||||
if (nPlayerTrain)
|
if (nPlayerTrain)
|
||||||
{
|
{
|
||||||
Train = new TTrain();
|
Train = new TTrain();
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
if (Train->Init(nPlayerTrain->DynamicObject))
|
if (Train->Init(nPlayerTrain->DynamicObject))
|
||||||
|
#else
|
||||||
|
if( Train->Init( nPlayerTrain ) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
Controlled = Train->Dynamic();
|
Controlled = Train->Dynamic();
|
||||||
mvControlled = Controlled->ControlledFind()->MoverParameters;
|
mvControlled = Controlled->ControlledFind()->MoverParameters;
|
||||||
@@ -522,7 +541,11 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TDynamicObject *tmp = Ground.DynamicNearest( Camera.Pos, 50, true ); //łapiemy z obsadą
|
TDynamicObject *tmp = Ground.DynamicNearest( Camera.Pos, 50, true ); //łapiemy z obsadą
|
||||||
|
#else
|
||||||
|
TDynamicObject *tmp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 50, true ) );
|
||||||
|
#endif
|
||||||
if( ( tmp != nullptr )
|
if( ( tmp != nullptr )
|
||||||
&& ( tmp != Controlled ) ) {
|
&& ( tmp != Controlled ) ) {
|
||||||
|
|
||||||
@@ -700,7 +723,11 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
*/
|
*/
|
||||||
if (cKey == Global::Keys[k_Heating]) // Ra: klawisz nie jest najszczęśliwszy
|
if (cKey == Global::Keys[k_Heating]) // Ra: klawisz nie jest najszczęśliwszy
|
||||||
{ // zmiana próżny/ładowny; Ra: zabrane z kabiny
|
{ // zmiana próżny/ładowny; Ra: zabrane z kabiny
|
||||||
TDynamicObject *temp = Global::DynamicNearest();
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
TDynamicObject *temp = Global::DynamicNearest();
|
||||||
|
#else
|
||||||
|
TDynamicObject *temp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false ) );
|
||||||
|
#endif
|
||||||
if (temp)
|
if (temp)
|
||||||
{
|
{
|
||||||
if (Global::shiftState ? temp->MoverParameters->IncBrakeMult() :
|
if (Global::shiftState ? temp->MoverParameters->IncBrakeMult() :
|
||||||
@@ -743,7 +770,11 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
}
|
}
|
||||||
else if (cKey == Global::Keys[k_IncLocalBrakeLevel])
|
else if (cKey == Global::Keys[k_IncLocalBrakeLevel])
|
||||||
{ // zahamowanie dowolnego pojazdu
|
{ // zahamowanie dowolnego pojazdu
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TDynamicObject *temp = Global::DynamicNearest();
|
TDynamicObject *temp = Global::DynamicNearest();
|
||||||
|
#else
|
||||||
|
TDynamicObject *temp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false ) );
|
||||||
|
#endif
|
||||||
if (temp)
|
if (temp)
|
||||||
{
|
{
|
||||||
if (Global::ctrlState)
|
if (Global::ctrlState)
|
||||||
@@ -762,7 +793,11 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
}
|
}
|
||||||
else if (cKey == Global::Keys[k_DecLocalBrakeLevel])
|
else if (cKey == Global::Keys[k_DecLocalBrakeLevel])
|
||||||
{ // odhamowanie dowolnego pojazdu
|
{ // odhamowanie dowolnego pojazdu
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TDynamicObject *temp = Global::DynamicNearest();
|
TDynamicObject *temp = Global::DynamicNearest();
|
||||||
|
#else
|
||||||
|
TDynamicObject *temp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false ) );
|
||||||
|
#endif
|
||||||
if (temp)
|
if (temp)
|
||||||
{
|
{
|
||||||
if (Global::ctrlState)
|
if (Global::ctrlState)
|
||||||
@@ -915,20 +950,7 @@ void TWorld::FollowView(bool wycisz) {
|
|||||||
DistantView();
|
DistantView();
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TWorld::Update()
|
bool TWorld::Update() {
|
||||||
{
|
|
||||||
#ifdef USE_SCENERY_MOVING
|
|
||||||
vector3 tmpvector = Global::GetCameraPosition();
|
|
||||||
tmpvector = vector3(-int(tmpvector.x) + int(tmpvector.x) % 10000,
|
|
||||||
-int(tmpvector.y) + int(tmpvector.y) % 10000,
|
|
||||||
-int(tmpvector.z) + int(tmpvector.z) % 10000);
|
|
||||||
if (tmpvector.x || tmpvector.y || tmpvector.z)
|
|
||||||
{
|
|
||||||
WriteLog("Moving scenery");
|
|
||||||
Ground.MoveGroundNode(tmpvector);
|
|
||||||
WriteLog("Scenery moved");
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Timer::UpdateTimers(Global::iPause != 0);
|
Timer::UpdateTimers(Global::iPause != 0);
|
||||||
|
|
||||||
@@ -955,7 +977,7 @@ bool TWorld::Update()
|
|||||||
/*
|
/*
|
||||||
fTimeBuffer += dt; //[s] dodanie czasu od poprzedniej ramki
|
fTimeBuffer += dt; //[s] dodanie czasu od poprzedniej ramki
|
||||||
*/
|
*/
|
||||||
m_primaryupdateaccumulator += dt;
|
// m_primaryupdateaccumulator += dt; // unused for the time being
|
||||||
m_secondaryupdateaccumulator += dt;
|
m_secondaryupdateaccumulator += dt;
|
||||||
/*
|
/*
|
||||||
if (fTimeBuffer >= fMaxDt) // jest co najmniej jeden krok; normalnie 0.01s
|
if (fTimeBuffer >= fMaxDt) // jest co najmniej jeden krok; normalnie 0.01s
|
||||||
@@ -999,21 +1021,26 @@ bool TWorld::Update()
|
|||||||
dt = dt / iterations; // Ra: fizykę lepiej by było przeliczać ze stałym krokiem
|
dt = dt / iterations; // Ra: fizykę lepiej by było przeliczać ze stałym krokiem
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
auto const stepdeltatime { dt / updatecount };
|
||||||
// NOTE: updates are limited to 20, but dt is distributed over potentially many more iterations
|
// NOTE: updates are limited to 20, but dt is distributed over potentially many more iterations
|
||||||
// this means at count > 20 simulation and render are going to desync. is that right?
|
// this means at count > 20 simulation and render are going to desync. is that right?
|
||||||
// NOTE: experimentally changing this to prevent the desync.
|
// NOTE: experimentally changing this to prevent the desync.
|
||||||
// TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps
|
// TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
if( true == Global::FullPhysics ) {
|
if( true == Global::FullPhysics ) {
|
||||||
// default calculation mode, each step calculated separately
|
// mixed calculation mode, steps calculated in ~0.05s chunks
|
||||||
for( int updateidx = 0; updateidx < updatecount; ++updateidx ) {
|
while( updatecount >= 5 ) {
|
||||||
Ground.Update( dt / updatecount, 1 );
|
Ground.Update( stepdeltatime, 5 );
|
||||||
|
updatecount -= 5;
|
||||||
|
}
|
||||||
|
if( updatecount ) {
|
||||||
|
Ground.Update( stepdeltatime, updatecount );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// slightly simplified calculation mode; can lead to errors
|
// simplified calculation mode; faster but can lead to errors
|
||||||
Ground.Update( dt / updatecount, updatecount );
|
Ground.Update( stepdeltatime, updatecount );
|
||||||
}
|
}
|
||||||
|
|
||||||
// yB dodał przyspieszacz fizyki
|
// yB dodał przyspieszacz fizyki
|
||||||
if( (true == DebugModeFlag)
|
if( (true == DebugModeFlag)
|
||||||
&& (true == Global::bActive) // nie przyspieszać, gdy jedzie w tle :)
|
&& (true == Global::bActive) // nie przyspieszać, gdy jedzie w tle :)
|
||||||
@@ -1024,8 +1051,24 @@ bool TWorld::Update()
|
|||||||
Ground.Update( dt, 1 );
|
Ground.Update( dt, 1 );
|
||||||
Ground.Update( dt, 1 ); // 5 razy
|
Ground.Update( dt, 1 ); // 5 razy
|
||||||
}
|
}
|
||||||
// secondary fixed step simulation time routines
|
#else
|
||||||
|
if( true == Global::FullPhysics ) {
|
||||||
|
// mixed calculation mode, steps calculated in ~0.05s chunks
|
||||||
|
while( updatecount >= 5 ) {
|
||||||
|
simulation::State.update( stepdeltatime, 5 );
|
||||||
|
updatecount -= 5;
|
||||||
|
}
|
||||||
|
if( updatecount ) {
|
||||||
|
simulation::State.update( stepdeltatime, updatecount );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// simplified calculation mode; faster but can lead to errors
|
||||||
|
simulation::State.update( stepdeltatime, updatecount );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// secondary fixed step simulation time routines
|
||||||
while( m_secondaryupdateaccumulator >= m_secondaryupdaterate ) {
|
while( m_secondaryupdateaccumulator >= m_secondaryupdaterate ) {
|
||||||
|
|
||||||
Global::tranTexts.Update(); // obiekt obsługujący stenogramy dźwięków na ekranie
|
Global::tranTexts.Update(); // obiekt obsługujący stenogramy dźwięków na ekranie
|
||||||
@@ -1065,11 +1108,12 @@ bool TWorld::Update()
|
|||||||
|
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Ground.CheckQuery();
|
Ground.CheckQuery();
|
||||||
|
Ground.Update_Hidden();
|
||||||
#else
|
#else
|
||||||
simulation::Events.CheckQuery();
|
simulation::Events.CheckQuery();
|
||||||
|
simulation::Region->update();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Ground.Update_Hidden();
|
|
||||||
simulation::Lights.update();
|
simulation::Lights.update();
|
||||||
|
|
||||||
// render time routines follow:
|
// render time routines follow:
|
||||||
@@ -1119,10 +1163,15 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
Camera.LookAt = Controlled->GetPosition();
|
Camera.LookAt = Controlled->GetPosition();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TDynamicObject *d =
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Ground.DynamicNearest( Camera.Pos, 300 ); // szukaj w promieniu 300m
|
TDynamicObject *d = Ground.DynamicNearest( Camera.Pos, 300 ); // szukaj w promieniu 300m
|
||||||
if( !d )
|
if( !d )
|
||||||
d = Ground.DynamicNearest( Camera.Pos, 1000 ); // dalej szukanie, jesli bliżej nie ma
|
d = Ground.DynamicNearest( Camera.Pos, 1000 ); // dalej szukanie, jesli bliżej nie ma
|
||||||
|
#else
|
||||||
|
TDynamicObject *d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 300, false ) );
|
||||||
|
if( !d )
|
||||||
|
d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 1000, false ) ); // dalej szukanie, jesli bliżej nie ma
|
||||||
|
#endif
|
||||||
if( d && pDynamicNearest ) {
|
if( d && pDynamicNearest ) {
|
||||||
// jeśli jakiś jest znaleziony wcześniej
|
// jeśli jakiś jest znaleziony wcześniej
|
||||||
if( 100.0 * LengthSquared3( d->GetPosition() - Camera.Pos ) > LengthSquared3( pDynamicNearest->GetPosition() - Camera.Pos ) ) {
|
if( 100.0 * LengthSquared3( d->GetPosition() - Camera.Pos ) > LengthSquared3( pDynamicNearest->GetPosition() - Camera.Pos ) ) {
|
||||||
@@ -1305,7 +1354,11 @@ TWorld::Update_UI() {
|
|||||||
// timetable
|
// timetable
|
||||||
TDynamicObject *tmp =
|
TDynamicObject *tmp =
|
||||||
( FreeFlyModeFlag ?
|
( FreeFlyModeFlag ?
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Ground.DynamicNearest( Camera.Pos ) :
|
Ground.DynamicNearest( Camera.Pos ) :
|
||||||
|
#else
|
||||||
|
std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 20, false ) ) :
|
||||||
|
#endif
|
||||||
Controlled ); // w trybie latania lokalizujemy wg mapy
|
Controlled ); // w trybie latania lokalizujemy wg mapy
|
||||||
|
|
||||||
if( tmp == nullptr ) { break; }
|
if( tmp == nullptr ) { break; }
|
||||||
@@ -1386,8 +1439,12 @@ TWorld::Update_UI() {
|
|||||||
|
|
||||||
TDynamicObject *tmp =
|
TDynamicObject *tmp =
|
||||||
( FreeFlyModeFlag ?
|
( FreeFlyModeFlag ?
|
||||||
Ground.DynamicNearest( Camera.Pos ) :
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Controlled ); // w trybie latania lokalizujemy wg mapy
|
Ground.DynamicNearest( Camera.Pos ) :
|
||||||
|
#else
|
||||||
|
std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 20, false ) ) :
|
||||||
|
#endif
|
||||||
|
Controlled ); // w trybie latania lokalizujemy wg mapy
|
||||||
|
|
||||||
if( tmp != nullptr ) {
|
if( tmp != nullptr ) {
|
||||||
//
|
//
|
||||||
@@ -1403,7 +1460,7 @@ TWorld::Update_UI() {
|
|||||||
uitextline1 +=
|
uitextline1 +=
|
||||||
"; C0:" +
|
"; C0:" +
|
||||||
( tmp->PrevConnected ?
|
( tmp->PrevConnected ?
|
||||||
tmp->PrevConnected->GetName() + ":" + to_string( tmp->MoverParameters->Couplers[ 0 ].CouplingFlag ) + (
|
tmp->PrevConnected->name() + ":" + to_string( tmp->MoverParameters->Couplers[ 0 ].CouplingFlag ) + (
|
||||||
tmp->MoverParameters->Couplers[ 0 ].CouplingFlag == 0 ?
|
tmp->MoverParameters->Couplers[ 0 ].CouplingFlag == 0 ?
|
||||||
" (" + to_string( tmp->MoverParameters->Couplers[ 0 ].CoupleDist, 1 ) + " m)" :
|
" (" + to_string( tmp->MoverParameters->Couplers[ 0 ].CoupleDist, 1 ) + " m)" :
|
||||||
"" ) :
|
"" ) :
|
||||||
@@ -1411,7 +1468,7 @@ TWorld::Update_UI() {
|
|||||||
uitextline1 +=
|
uitextline1 +=
|
||||||
" C1:" +
|
" C1:" +
|
||||||
( tmp->NextConnected ?
|
( tmp->NextConnected ?
|
||||||
tmp->NextConnected->GetName() + ":" + to_string( tmp->MoverParameters->Couplers[ 1 ].CouplingFlag ) + (
|
tmp->NextConnected->name() + ":" + to_string( tmp->MoverParameters->Couplers[ 1 ].CouplingFlag ) + (
|
||||||
tmp->MoverParameters->Couplers[ 1 ].CouplingFlag == 0 ?
|
tmp->MoverParameters->Couplers[ 1 ].CouplingFlag == 0 ?
|
||||||
" (" + to_string( tmp->MoverParameters->Couplers[ 1 ].CoupleDist, 1 ) + " m)" :
|
" (" + to_string( tmp->MoverParameters->Couplers[ 1 ].CoupleDist, 1 ) + " m)" :
|
||||||
"" ) :
|
"" ) :
|
||||||
@@ -1653,7 +1710,11 @@ TWorld::Update_UI() {
|
|||||||
|
|
||||||
TDynamicObject *tmp =
|
TDynamicObject *tmp =
|
||||||
( FreeFlyModeFlag ?
|
( FreeFlyModeFlag ?
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Ground.DynamicNearest( Camera.Pos ) :
|
Ground.DynamicNearest( Camera.Pos ) :
|
||||||
|
#else
|
||||||
|
std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 20, false ) ) :
|
||||||
|
#endif
|
||||||
Controlled ); // w trybie latania lokalizujemy wg mapy
|
Controlled ); // w trybie latania lokalizujemy wg mapy
|
||||||
if( tmp == nullptr ) {
|
if( tmp == nullptr ) {
|
||||||
break;
|
break;
|
||||||
@@ -1867,6 +1928,7 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz)
|
|||||||
Now() + " " + to_string(pRozkaz->iComm) + " " +
|
Now() + " " + to_string(pRozkaz->iComm) + " " +
|
||||||
std::string(pRozkaz->cString + 11 + i, (unsigned)(pRozkaz->cString[10 + i])) +
|
std::string(pRozkaz->cString + 11 + i, (unsigned)(pRozkaz->cString[10 + i])) +
|
||||||
" rcvd");
|
" rcvd");
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TGroundNode *t = Ground.DynamicFind(
|
TGroundNode *t = Ground.DynamicFind(
|
||||||
std::string(pRozkaz->cString + 11 + i,
|
std::string(pRozkaz->cString + 11 + i,
|
||||||
(unsigned)pRozkaz->cString[10 + i])); // nazwa pojazdu jest druga
|
(unsigned)pRozkaz->cString[10 + i])); // nazwa pojazdu jest druga
|
||||||
@@ -1878,6 +1940,19 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz)
|
|||||||
NULL, stopExt); // floaty są z przodu
|
NULL, stopExt); // floaty są z przodu
|
||||||
WriteLog("AI command: " + std::string(pRozkaz->cString + 9, i));
|
WriteLog("AI command: " + std::string(pRozkaz->cString + 9, i));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// nazwa pojazdu jest druga
|
||||||
|
auto *vehicle = simulation::Vehicles.find( { pRozkaz->cString + 11 + i, (unsigned)pRozkaz->cString[ 10 + i ] } );
|
||||||
|
if( ( vehicle != nullptr )
|
||||||
|
&& ( vehicle->Mechanik != nullptr ) ) {
|
||||||
|
vehicle->Mechanik->PutCommand(
|
||||||
|
{ pRozkaz->cString + 9, static_cast<std::size_t>(i) },
|
||||||
|
pRozkaz->fPar[0], pRozkaz->fPar[1],
|
||||||
|
nullptr,
|
||||||
|
stopExt ); // floaty są z przodu
|
||||||
|
WriteLog("AI command: " + std::string(pRozkaz->cString + 9, i));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4: // badanie zajętości toru
|
case 4: // badanie zajętości toru
|
||||||
@@ -1920,6 +1995,7 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz)
|
|||||||
" rcvd");
|
" rcvd");
|
||||||
if (pRozkaz->cString[0]) // jeśli długość nazwy jest niezerowa
|
if (pRozkaz->cString[0]) // jeśli długość nazwy jest niezerowa
|
||||||
{ // szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #7
|
{ // szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #7
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TGroundNode *t;
|
TGroundNode *t;
|
||||||
if (pRozkaz->cString[1] == '*')
|
if (pRozkaz->cString[1] == '*')
|
||||||
t = Ground.DynamicFind(
|
t = Ground.DynamicFind(
|
||||||
@@ -1929,6 +2005,9 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz)
|
|||||||
pRozkaz->cString + 1, (unsigned)pRozkaz->cString[0])); // nazwa pojazdu
|
pRozkaz->cString + 1, (unsigned)pRozkaz->cString[0])); // nazwa pojazdu
|
||||||
if (t)
|
if (t)
|
||||||
Ground.WyslijNamiary(t); // wysłanie informacji o pojeździe
|
Ground.WyslijNamiary(t); // wysłanie informacji o pojeździe
|
||||||
|
#else
|
||||||
|
// TODO: implement
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // dla pustego wysyłamy ramki 6 z nazwami pojazdów AI (jeśli potrzebne wszystkie,
|
{ // dla pustego wysyłamy ramki 6 z nazwami pojazdów AI (jeśli potrzebne wszystkie,
|
||||||
@@ -1964,34 +2043,34 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz)
|
|||||||
CommLog(Now() + " " + to_string(pRozkaz->iComm) + " " +
|
CommLog(Now() + " " + to_string(pRozkaz->iComm) + " " +
|
||||||
std::string(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])) +
|
std::string(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])) +
|
||||||
" rcvd");
|
" rcvd");
|
||||||
if (pRozkaz->cString[1]) // jeśli długość nazwy jest niezerowa
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
{ // szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #13
|
if( pRozkaz->cString[ 1 ] ) // jeśli długość nazwy jest niezerowa
|
||||||
TGroundNode *t;
|
{ // szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #13
|
||||||
if (pRozkaz->cString[2] == '*')
|
TGroundNode *t;
|
||||||
t = Ground.DynamicFind(
|
if( pRozkaz->cString[ 2 ] == '*' )
|
||||||
Global::asHumanCtrlVehicle); // nazwa pojazdu użytkownika
|
t = Ground.DynamicFind(
|
||||||
else
|
Global::asHumanCtrlVehicle ); // nazwa pojazdu użytkownika
|
||||||
t = Ground.DynamicFindAny(
|
else
|
||||||
std::string(pRozkaz->cString + 2,
|
t = Ground.DynamicFindAny(
|
||||||
(unsigned)pRozkaz->cString[1])); // nazwa pojazdu
|
std::string( pRozkaz->cString + 2,
|
||||||
if (t)
|
(unsigned)pRozkaz->cString[ 1 ] ) ); // nazwa pojazdu
|
||||||
{
|
if( t ) {
|
||||||
TDynamicObject *d = t->DynamicObject;
|
TDynamicObject *d = t->DynamicObject;
|
||||||
while (d)
|
while( d ) {
|
||||||
{
|
d->Damage( pRozkaz->cString[ 0 ] );
|
||||||
d->Damage(pRozkaz->cString[0]);
|
d = d->Next(); // pozostałe też
|
||||||
d = d->Next(); // pozostałe też
|
}
|
||||||
}
|
d = t->DynamicObject->Prev();
|
||||||
d = t->DynamicObject->Prev();
|
while( d ) {
|
||||||
while (d)
|
d->Damage( pRozkaz->cString[ 0 ] );
|
||||||
{
|
d = d->Prev(); // w drugą stronę też
|
||||||
d->Damage(pRozkaz->cString[0]);
|
}
|
||||||
d = d->Prev(); // w drugą stronę też
|
Ground.WyslijUszkodzenia( t->asName, t->DynamicObject->MoverParameters->EngDmgFlag ); // zwrot informacji o pojeździe
|
||||||
}
|
}
|
||||||
Ground.WyslijUszkodzenia(t->asName, t->DynamicObject->MoverParameters->EngDmgFlag); // zwrot informacji o pojeździe
|
}
|
||||||
}
|
#else
|
||||||
}
|
// TODO: implement
|
||||||
// Ground.IsolatedBusy(AnsiString(pRozkaz->cString+1,(unsigned)(pRozkaz->cString[0])));
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2143,7 +2222,7 @@ void TWorld::ChangeDynamic() {
|
|||||||
Train->DynamicSet( temp );
|
Train->DynamicSet( temp );
|
||||||
Controlled = temp;
|
Controlled = temp;
|
||||||
mvControlled = Controlled->ControlledFind()->MoverParameters;
|
mvControlled = Controlled->ControlledFind()->MoverParameters;
|
||||||
Global::asHumanCtrlVehicle = Train->Dynamic()->GetName();
|
Global::asHumanCtrlVehicle = Train->Dynamic()->name();
|
||||||
if( Train->Dynamic()->Mechanik ) // AI może sobie samo pójść
|
if( Train->Dynamic()->Mechanik ) // AI może sobie samo pójść
|
||||||
if( !Train->Dynamic()->Mechanik->AIControllFlag ) // tylko jeśli ręcznie prowadzony
|
if( !Train->Dynamic()->Mechanik->AIControllFlag ) // tylko jeśli ręcznie prowadzony
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ struct basic_vertex {
|
|||||||
glm::vec2 texture; // uv space
|
glm::vec2 texture; // uv space
|
||||||
|
|
||||||
basic_vertex() = default;
|
basic_vertex() = default;
|
||||||
basic_vertex( glm::vec3 const &Position, glm::vec3 const &Normal, glm::vec2 const &Texture ) :
|
basic_vertex( glm::vec3 Position, glm::vec3 Normal, glm::vec2 Texture ) :
|
||||||
position( Position ), normal( Normal ), texture( Texture )
|
position( Position ), normal( Normal ), texture( Texture )
|
||||||
{}
|
{}
|
||||||
void serialize( std::ostream& ) const;
|
void serialize( std::ostream& ) const;
|
||||||
void deserialize( std::istream& );
|
void deserialize( std::istream& );
|
||||||
@@ -58,8 +58,8 @@ struct geometry_handle {
|
|||||||
geometry_handle() :
|
geometry_handle() :
|
||||||
bank( 0 ), chunk( 0 )
|
bank( 0 ), chunk( 0 )
|
||||||
{}
|
{}
|
||||||
geometry_handle( std::uint32_t const Bank, std::uint32_t const Chunk ) :
|
geometry_handle( std::uint32_t Bank, std::uint32_t Chunk ) :
|
||||||
bank( Bank ), chunk( Chunk )
|
bank( Bank ), chunk( Chunk )
|
||||||
{}
|
{}
|
||||||
// methods
|
// methods
|
||||||
inline
|
inline
|
||||||
@@ -121,8 +121,8 @@ protected:
|
|||||||
unsigned int type; // kind of geometry used by the chunk
|
unsigned int type; // kind of geometry used by the chunk
|
||||||
vertex_array vertices; // geometry data
|
vertex_array vertices; // geometry data
|
||||||
// NOTE: constructor doesn't copy provided vertex data, but moves it
|
// NOTE: constructor doesn't copy provided vertex data, but moves it
|
||||||
geometry_chunk( vertex_array &Vertices, unsigned int const Type ) :
|
geometry_chunk( vertex_array &Vertices, unsigned int Type ) :
|
||||||
type( Type )
|
type( Type )
|
||||||
{
|
{
|
||||||
vertices.swap( Vertices );
|
vertices.swap( Vertices );
|
||||||
}
|
}
|
||||||
|
|||||||
14
parser.cpp
14
parser.cpp
@@ -205,23 +205,21 @@ std::string cParser::readToken(bool ToLower, const char *Break)
|
|||||||
if (token.compare("include") == 0)
|
if (token.compare("include") == 0)
|
||||||
{ // obsługa include
|
{ // obsługa include
|
||||||
std::string includefile = readToken(ToLower); // nazwa pliku
|
std::string includefile = readToken(ToLower); // nazwa pliku
|
||||||
if (LoadTraction ? true : ((includefile.find("tr/") == std::string::npos) &&
|
if( ( true == LoadTraction )
|
||||||
(includefile.find("tra/") == std::string::npos)))
|
|| ( ( includefile.find( "tr/" ) == std::string::npos )
|
||||||
{
|
&& ( includefile.find( "tra/" ) == std::string::npos ) ) ) {
|
||||||
// std::string trtest2="niemaproblema"; //nazwa odporna na znalezienie "tr/"
|
|
||||||
// if (trtest=="x") //jeśli nie wczytywać drutów
|
|
||||||
// trtest2=includefile; //kopiowanie ścieżki do pliku
|
|
||||||
std::string parameter = readToken(false); // w parametrach nie zmniejszamy
|
std::string parameter = readToken(false); // w parametrach nie zmniejszamy
|
||||||
while( (parameter.empty() == false)
|
while( (parameter.empty() == false)
|
||||||
&& (parameter.compare("end") != 0) )
|
&& (parameter.compare("end") != 0) )
|
||||||
{
|
{
|
||||||
parameters.push_back(parameter);
|
parameters.emplace_back(parameter);
|
||||||
parameter = readToken(false);
|
parameter = readToken(false);
|
||||||
}
|
}
|
||||||
// if (trtest2.find("tr/")!=0)
|
// if (trtest2.find("tr/")!=0)
|
||||||
mIncludeParser = std::make_shared<cParser>(includefile, buffer_FILE, mPath, LoadTraction);
|
mIncludeParser = std::make_shared<cParser>(includefile, buffer_FILE, mPath, LoadTraction);
|
||||||
if (mIncludeParser->mSize <= 0)
|
if (mIncludeParser->mSize <= 0)
|
||||||
ErrorLog("Missed include: " + includefile);
|
ErrorLog("Bad include: can't open file \"" + includefile + "\"" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while( token.compare( "end" ) != 0 ) {
|
while( token.compare( "end" ) != 0 ) {
|
||||||
|
|||||||
36
renderer.cpp
36
renderer.cpp
@@ -1602,7 +1602,17 @@ opengl_renderer::Render( scene::basic_region *Region ) {
|
|||||||
|
|
||||||
m_sectionqueue.clear();
|
m_sectionqueue.clear();
|
||||||
m_cellqueue.clear();
|
m_cellqueue.clear();
|
||||||
|
/*
|
||||||
|
for( auto *section : Region->sections( m_renderpass.camera.position(), m_renderpass.draw_range * Global::fDistanceFactor ) ) {
|
||||||
|
#ifdef EU07_USE_DEBUG_CULLING
|
||||||
|
if( m_worldcamera.camera.visible( section->m_area ) ) {
|
||||||
|
#else
|
||||||
|
if( m_renderpass.camera.visible( section->m_area ) ) {
|
||||||
|
#endif
|
||||||
|
m_sectionqueue.emplace_back( section );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
// build a list of region sections to render
|
// build a list of region sections to render
|
||||||
glm::vec3 const cameraposition { m_renderpass.camera.position() };
|
glm::vec3 const cameraposition { m_renderpass.camera.position() };
|
||||||
auto const camerax = static_cast<int>( std::floor( cameraposition.x / scene::EU07_SECTIONSIZE + scene::EU07_REGIONSIDESECTIONCOUNT / 2 ) );
|
auto const camerax = static_cast<int>( std::floor( cameraposition.x / scene::EU07_SECTIONSIZE + scene::EU07_REGIONSIDESECTIONCOUNT / 2 ) );
|
||||||
@@ -1903,11 +1913,22 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
case rendermode::shadows:
|
case rendermode::shadows: {
|
||||||
case rendermode::pickscenery: {
|
|
||||||
// render
|
|
||||||
// opaque parts of instanced models
|
// opaque parts of instanced models
|
||||||
for( auto *instance : cell->m_instancesopaque ) { Render( instance ); }
|
for( auto *instance : cell->m_instancesopaque ) { Render( instance ); }
|
||||||
|
// opaque parts of vehicles
|
||||||
|
for( auto *path : cell->m_paths ) {
|
||||||
|
for( auto *dynamic : path->Dynamics ) {
|
||||||
|
Render( dynamic );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case rendermode::pickscenery: {
|
||||||
|
// opaque parts of instanced models
|
||||||
|
for( auto *instance : cell->m_instancesopaque ) {
|
||||||
|
::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) );
|
||||||
|
Render( instance );
|
||||||
|
}
|
||||||
// TODO: add remaining content types
|
// TODO: add remaining content types
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2863,7 +2884,12 @@ opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_seque
|
|||||||
|
|
||||||
// translucent parts of instanced models
|
// translucent parts of instanced models
|
||||||
for( auto *instance : cell->m_instancetranslucent ) { Render_Alpha( instance ); }
|
for( auto *instance : cell->m_instancetranslucent ) { Render_Alpha( instance ); }
|
||||||
// TODO: add remaining content types
|
// translucent parts of vehicles
|
||||||
|
for( auto *path : cell->m_paths ) {
|
||||||
|
for( auto *dynamic : path->Dynamics ) {
|
||||||
|
Render_Alpha( dynamic );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
++first;
|
++first;
|
||||||
}
|
}
|
||||||
|
|||||||
425
scene.cpp
425
scene.cpp
@@ -10,11 +10,28 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
|
|
||||||
namespace scene {
|
namespace scene {
|
||||||
|
|
||||||
|
// legacy method, updates sounds and polls event launchers within radius around specified point
|
||||||
|
void
|
||||||
|
basic_cell::update() {
|
||||||
|
/*
|
||||||
|
// renderowanie obiektów aktywnych a niewidocznych
|
||||||
|
for( auto node = subcell->nRenderHidden; node; node = node->nNext3 ) {
|
||||||
|
node->RenderHidden();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// TBD, TODO: move to sound renderer
|
||||||
|
for( auto *path : m_paths ) {
|
||||||
|
// dźwięki pojazdów, również niewidocznych
|
||||||
|
path->RenderDynSounds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// adds provided shape to the cell
|
// adds provided shape to the cell
|
||||||
void
|
void
|
||||||
basic_cell::insert( shape_node Shape ) {
|
basic_cell::insert( shape_node Shape ) {
|
||||||
@@ -90,6 +107,131 @@ basic_cell::insert( TAnimModel *Instance ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// registers provided path in the lookup directory of the cell
|
||||||
|
void
|
||||||
|
basic_cell::register_end( TTrack *Path ) {
|
||||||
|
|
||||||
|
m_directories.paths.emplace( Path );
|
||||||
|
}
|
||||||
|
|
||||||
|
// registers provided traction piece in the lookup directory of the cell
|
||||||
|
void
|
||||||
|
basic_cell::register_end( TTraction *Traction ) {
|
||||||
|
|
||||||
|
m_directories.traction.emplace( Traction );
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
||||||
|
std::tuple<TDynamicObject *, float>
|
||||||
|
basic_cell::find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled ) {
|
||||||
|
|
||||||
|
TDynamicObject *vehiclenearest { nullptr };
|
||||||
|
float leastdistance { std::numeric_limits<float>::max() };
|
||||||
|
float distance;
|
||||||
|
float const distancecutoff { Radius * Radius }; // we'll ignore vehicles farther than this
|
||||||
|
|
||||||
|
for( auto *path : m_paths ) {
|
||||||
|
for( auto *vehicle : path->Dynamics ) {
|
||||||
|
if( ( true == Onlycontrolled )
|
||||||
|
&& ( vehicle->Mechanik == nullptr ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
distance = glm::length2( glm::dvec3{ vehicle->GetPosition() } - Point );
|
||||||
|
if( ( distance > distancecutoff )
|
||||||
|
|| ( distance > leastdistance ) ){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::tie( vehiclenearest, leastdistance ) = std::tie( vehicle, distance );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::tie( vehiclenearest, leastdistance );
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
||||||
|
std::tuple<TTrack *, int>
|
||||||
|
basic_cell::find( glm::dvec3 const &Point, TTrack const *Exclude ) {
|
||||||
|
|
||||||
|
Math3D::vector3 point { Point.x, Point.y, Point.z }; // sad workaround until math classes unification
|
||||||
|
int endpointid;
|
||||||
|
|
||||||
|
for( auto *path : m_directories.paths ) {
|
||||||
|
|
||||||
|
if( path == Exclude ) { continue; }
|
||||||
|
|
||||||
|
endpointid = path->TestPoint( &point );
|
||||||
|
if( endpointid >= 0 ) {
|
||||||
|
|
||||||
|
return std::tie( path, endpointid );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { nullptr, -1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint
|
||||||
|
std::tuple<TTraction *, int>
|
||||||
|
basic_cell::find( glm::dvec3 const &Point, TTraction const *Exclude ) {
|
||||||
|
|
||||||
|
int endpointid;
|
||||||
|
|
||||||
|
for( auto *traction : m_directories.traction ) {
|
||||||
|
|
||||||
|
if( traction == Exclude ) { continue; }
|
||||||
|
|
||||||
|
endpointid = traction->TestPoint( Point );
|
||||||
|
if( endpointid >= 0 ) {
|
||||||
|
|
||||||
|
return std::tie( traction, endpointid );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { nullptr, -1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece
|
||||||
|
std::tuple<TTraction *, int, float>
|
||||||
|
basic_cell::find( glm::dvec3 const &Point, TTraction const *Other, int const Currentdirection ) {
|
||||||
|
|
||||||
|
TTraction
|
||||||
|
*tractionnearest { nullptr };
|
||||||
|
float
|
||||||
|
distance,
|
||||||
|
distancenearest { std::numeric_limits<float>::max() };
|
||||||
|
int endpoint,
|
||||||
|
endpointnearest { -1 };
|
||||||
|
|
||||||
|
for( auto *traction : m_directories.traction ) {
|
||||||
|
|
||||||
|
if( ( traction == Other )
|
||||||
|
|| ( traction->psSection != Other->psSection )
|
||||||
|
|| ( traction == Other->hvNext[ 0 ] )
|
||||||
|
|| ( traction == Other->hvNext[ 1 ] ) ) {
|
||||||
|
// ignore pieces from different sections, and ones connected to the other piece
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
endpoint = (
|
||||||
|
glm::dot( traction->vParametric, Other->vParametric ) >= 0.0 ?
|
||||||
|
Currentdirection ^ 1 :
|
||||||
|
Currentdirection );
|
||||||
|
if( ( traction->psPower[ endpoint ] == nullptr )
|
||||||
|
|| ( traction->fResistance[ endpoint ] < 0.0 ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
distance = glm::length2( traction->location() - Point );
|
||||||
|
if( distance < distancenearest ) {
|
||||||
|
std::tie( tractionnearest, endpointnearest, distancenearest ) = std::tie( traction, endpoint, distance );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { tractionnearest, endpointnearest, distancenearest };
|
||||||
|
}
|
||||||
|
|
||||||
|
// sets center point of the section
|
||||||
|
void
|
||||||
|
basic_cell::center( glm::dvec3 Center ) {
|
||||||
|
|
||||||
|
m_area.center = Center;
|
||||||
|
// NOTE: we should also update origin point for the contained nodes, but in practice we can skip this
|
||||||
|
// as all nodes will be added only after the proper center point was set, and won't change
|
||||||
|
}
|
||||||
|
|
||||||
// generates renderable version of held non-instanced geometry
|
// generates renderable version of held non-instanced geometry
|
||||||
void
|
void
|
||||||
basic_cell::create_geometry( geometrybank_handle const &Bank ) {
|
basic_cell::create_geometry( geometrybank_handle const &Bank ) {
|
||||||
@@ -104,17 +246,23 @@ basic_cell::create_geometry( geometrybank_handle const &Bank ) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets center point of the section
|
|
||||||
|
|
||||||
|
// legacy method, updates sounds and polls event launchers within radius around specified point
|
||||||
void
|
void
|
||||||
basic_cell::center( glm::dvec3 Center ) {
|
basic_section::update( glm::dvec3 const &Location, float const Radius ) {
|
||||||
|
|
||||||
m_area.center = Center;
|
auto const squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) + Radius, 2 ) };
|
||||||
// NOTE: we should also update origin point for the contained nodes, but in practice we can skip this
|
|
||||||
// as all nodes will be added only after the proper center point was set, and won't change
|
for( auto &cell : m_cells ) {
|
||||||
|
|
||||||
|
if( glm::length2( cell.area().center - Location ) < squaredradii ) {
|
||||||
|
// we reject cells which aren't within our area of interest
|
||||||
|
cell.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// adds provided shape to the section
|
// adds provided shape to the section
|
||||||
void
|
void
|
||||||
basic_section::insert( shape_node Shape ) {
|
basic_section::insert( shape_node Shape ) {
|
||||||
@@ -168,6 +316,96 @@ basic_section::insert( TAnimModel *Instance ) {
|
|||||||
cell( Instance->location() ).insert( Instance );
|
cell( Instance->location() ).insert( Instance );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// registers specified end point of the provided path in the lookup directory of the region
|
||||||
|
void
|
||||||
|
basic_section::register_end( TTrack *Path, glm::dvec3 const &Point ) {
|
||||||
|
|
||||||
|
cell( Point ).register_end( Path );
|
||||||
|
}
|
||||||
|
|
||||||
|
// registers specified end point of the provided traction piece in the lookup directory of the region
|
||||||
|
void
|
||||||
|
basic_section::register_end( TTraction *Traction, glm::dvec3 const &Point ) {
|
||||||
|
|
||||||
|
cell( Point ).register_end( Traction );
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
||||||
|
std::tuple<TDynamicObject *, float>
|
||||||
|
basic_section::find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled ) {
|
||||||
|
|
||||||
|
// go through sections within radius of interest, and pick the nearest candidate
|
||||||
|
TDynamicObject
|
||||||
|
*vehiclefound,
|
||||||
|
*vehiclenearest { nullptr };
|
||||||
|
float
|
||||||
|
distancefound,
|
||||||
|
distancenearest { std::numeric_limits<float>::max() };
|
||||||
|
|
||||||
|
auto const squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) + Radius, 2 ) };
|
||||||
|
|
||||||
|
for( auto &cell : m_cells ) {
|
||||||
|
// we reject early cells which aren't within our area of interest
|
||||||
|
if( glm::length2( cell.area().center - Point ) > squaredradii ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::tie( vehiclefound, distancefound ) = cell.find( Point, Radius, Onlycontrolled );
|
||||||
|
if( ( vehiclefound != nullptr )
|
||||||
|
&& ( distancefound < distancenearest ) ) {
|
||||||
|
|
||||||
|
std::tie( vehiclenearest, distancenearest ) = std::tie( vehiclefound, distancefound );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::tie( vehiclenearest, distancenearest );
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
||||||
|
std::tuple<TTrack *, int>
|
||||||
|
basic_section::find( glm::dvec3 const &Point, TTrack const *Exclude ) {
|
||||||
|
|
||||||
|
return cell( Point ).find( Point, Exclude );
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint
|
||||||
|
std::tuple<TTraction *, int>
|
||||||
|
basic_section::find( glm::dvec3 const &Point, TTraction const *Exclude ) {
|
||||||
|
|
||||||
|
return cell( Point ).find( Point, Exclude );
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece
|
||||||
|
std::tuple<TTraction *, int, float>
|
||||||
|
basic_section::find( glm::dvec3 const &Point, TTraction const *Other, int const Currentdirection ) {
|
||||||
|
|
||||||
|
// go through sections within radius of interest, and pick the nearest candidate
|
||||||
|
TTraction
|
||||||
|
*tractionfound,
|
||||||
|
*tractionnearest { nullptr };
|
||||||
|
float
|
||||||
|
distancefound,
|
||||||
|
distancenearest { std::numeric_limits<float>::max() };
|
||||||
|
int
|
||||||
|
endpointfound,
|
||||||
|
endpointnearest { -1 };
|
||||||
|
|
||||||
|
auto const radius { 0.0 }; // { EU07_CELLSIZE * 0.5 }; // experimentally limited, check if it has any negative effect
|
||||||
|
auto const squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) + radius, 2 ) };
|
||||||
|
|
||||||
|
for( auto &cell : m_cells ) {
|
||||||
|
// we reject early cells which aren't within our area of interest
|
||||||
|
if( glm::length2( cell.area().center - Point ) > squaredradii ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::tie( tractionfound, endpointfound, distancefound ) = cell.find( Point, Other, Currentdirection );
|
||||||
|
if( ( tractionfound != nullptr )
|
||||||
|
&& ( distancefound < distancenearest ) ) {
|
||||||
|
|
||||||
|
std::tie( tractionnearest, endpointnearest, distancenearest ) = std::tie( tractionfound, endpointfound, distancefound );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { tractionnearest, endpointnearest, distancenearest };
|
||||||
|
}
|
||||||
|
|
||||||
// sets center point of the section
|
// sets center point of the section
|
||||||
void
|
void
|
||||||
basic_section::center( glm::dvec3 Center ) {
|
basic_section::center( glm::dvec3 Center ) {
|
||||||
@@ -251,6 +489,17 @@ basic_region::~basic_region() {
|
|||||||
for( auto section : m_sections ) { if( section != nullptr ) { delete section; } }
|
for( auto section : m_sections ) { if( section != nullptr ) { delete section; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, updates sounds and polls event launchers around camera
|
||||||
|
void
|
||||||
|
basic_region::update() {
|
||||||
|
// render events and sounds from sectors near enough to the viewer
|
||||||
|
auto const range = 2750.f; // audible range of 100 db sound
|
||||||
|
auto const §ionlist = sections( Global::pCameraPosition, range );
|
||||||
|
for( auto *section : sectionlist ) {
|
||||||
|
section->update( Global::pCameraPosition, range );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad ) {
|
basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
@@ -327,6 +576,11 @@ basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) {
|
|||||||
// tracks are guaranteed to hava a name so we can skip the check
|
// tracks are guaranteed to hava a name so we can skip the check
|
||||||
ErrorLog( "Bad scenario: track node \"" + Path->name() + "\" placed in location outside region bounds (" + to_string( center ) + ")" );
|
ErrorLog( "Bad scenario: track node \"" + Path->name() + "\" placed in location outside region bounds (" + to_string( center ) + ")" );
|
||||||
}
|
}
|
||||||
|
// also register path ends in appropriate sections, for path merging lookups
|
||||||
|
// TODO: clean this up during track refactoring
|
||||||
|
for( auto &point : Path->endpoints() ) {
|
||||||
|
register_path( Path, point );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// inserts provided track in the region
|
// inserts provided track in the region
|
||||||
@@ -344,6 +598,11 @@ basic_region::insert_traction( TTraction *Traction, scratch_data &Scratchpad ) {
|
|||||||
// tracks are guaranteed to hava a name so we can skip the check
|
// tracks are guaranteed to hava a name so we can skip the check
|
||||||
ErrorLog( "Bad scenario: traction node \"" + Traction->name() + "\" placed in location outside region bounds (" + to_string( center ) + ")" );
|
ErrorLog( "Bad scenario: traction node \"" + Traction->name() + "\" placed in location outside region bounds (" + to_string( center ) + ")" );
|
||||||
}
|
}
|
||||||
|
// also register traction ends in appropriate sections, for path merging lookups
|
||||||
|
// TODO: clean this up during track refactoring
|
||||||
|
for( auto &point : Traction->endpoints() ) {
|
||||||
|
register_traction( Traction, point );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// inserts provided instance of 3d model in the region
|
// inserts provided instance of 3d model in the region
|
||||||
@@ -363,6 +622,154 @@ basic_region::insert_instance( TAnimModel *Instance, scratch_data &Scratchpad )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inserts provided sound in the region
|
||||||
|
void
|
||||||
|
basic_region::insert_sound( TTextSound *Sound, scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TODO: implement
|
||||||
|
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||||
|
auto center = Sound->location();
|
||||||
|
|
||||||
|
if( point_inside( center ) ) {
|
||||||
|
// NOTE: nodes placed outside of region boundaries are discarded
|
||||||
|
section( center ).insert( Instance );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// tracks are guaranteed to hava a name so we can skip the check
|
||||||
|
ErrorLog( "Bad scenario: model node \"" + Instance->name() + "\" placed in location outside region bounds (" + to_string( center ) + ")" );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a vehicle located neares to specified location, within specified radius, optionally discarding vehicles without drivers
|
||||||
|
std::tuple<TDynamicObject *, float>
|
||||||
|
basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled ) {
|
||||||
|
|
||||||
|
auto const §ionlist = sections( Point, Radius );
|
||||||
|
// go through sections within radius of interest, and pick the nearest candidate
|
||||||
|
TDynamicObject
|
||||||
|
*foundvehicle,
|
||||||
|
*nearestvehicle { nullptr };
|
||||||
|
float
|
||||||
|
founddistance,
|
||||||
|
nearestdistance { std::numeric_limits<float>::max() };
|
||||||
|
|
||||||
|
for( auto *section : sectionlist ) {
|
||||||
|
std::tie( foundvehicle, founddistance ) = section->find( Point, Radius, Onlycontrolled );
|
||||||
|
if( ( foundvehicle != nullptr )
|
||||||
|
&& ( founddistance < nearestdistance ) ) {
|
||||||
|
|
||||||
|
std::tie( nearestvehicle, nearestdistance ) = std::tie( foundvehicle, founddistance );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::tie( nearestvehicle, nearestdistance );
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
||||||
|
std::tuple<TTrack *, int>
|
||||||
|
basic_region::find_path( glm::dvec3 const &Point, TTrack const *Exclude ) {
|
||||||
|
|
||||||
|
// TBD: throw out of bounds exception instead of checks all over the place..?
|
||||||
|
if( point_inside( Point ) ) {
|
||||||
|
|
||||||
|
return section( Point ).find( Point, Exclude );
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_tuple<TTrack *, int>( nullptr, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint
|
||||||
|
std::tuple<TTraction *, int>
|
||||||
|
basic_region::find_traction( glm::dvec3 const &Point, TTraction const *Exclude ) {
|
||||||
|
|
||||||
|
// TBD: throw out of bounds exception instead of checks all over the place..?
|
||||||
|
if( point_inside( Point ) ) {
|
||||||
|
|
||||||
|
return section( Point ).find( Point, Exclude );
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_tuple<TTraction *, int>( nullptr, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece
|
||||||
|
std::tuple<TTraction *, int>
|
||||||
|
basic_region::find_traction( glm::dvec3 const &Point, TTraction const *Other, int const Currentdirection ) {
|
||||||
|
|
||||||
|
auto const §ionlist = sections( Point, 0.f );
|
||||||
|
// go through sections within radius of interest, and pick the nearest candidate
|
||||||
|
TTraction
|
||||||
|
*tractionfound,
|
||||||
|
*tractionnearest { nullptr };
|
||||||
|
float
|
||||||
|
distancefound,
|
||||||
|
distancenearest { std::numeric_limits<float>::max() };
|
||||||
|
int
|
||||||
|
endpointfound,
|
||||||
|
endpointnearest { -1 };
|
||||||
|
|
||||||
|
for( auto *section : sectionlist ) {
|
||||||
|
std::tie( tractionfound, endpointfound, distancefound ) = section->find( Point, Other, Currentdirection );
|
||||||
|
if( ( tractionfound != nullptr )
|
||||||
|
&& ( distancefound < distancenearest ) ) {
|
||||||
|
|
||||||
|
std::tie( tractionnearest, endpointnearest, distancenearest ) = std::tie( tractionfound, endpointfound, distancefound );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { tractionnearest, endpointnearest };
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds sections inside specified sphere. returns: list of sections
|
||||||
|
std::vector<basic_section *> const &
|
||||||
|
basic_region::sections( glm::dvec3 const &Point, float const Radius ) {
|
||||||
|
|
||||||
|
m_scratchpad.sections.clear();
|
||||||
|
|
||||||
|
auto const centerx { static_cast<int>( std::floor( Point.x / EU07_SECTIONSIZE + EU07_REGIONSIDESECTIONCOUNT / 2 ) ) };
|
||||||
|
auto const centerz { static_cast<int>( std::floor( Point.z / EU07_SECTIONSIZE + EU07_REGIONSIDESECTIONCOUNT / 2 ) ) };
|
||||||
|
auto const sectioncount { 2 * static_cast<int>( std::ceil( Radius / EU07_SECTIONSIZE ) ) };
|
||||||
|
|
||||||
|
int const originx = centerx - sectioncount / 2;
|
||||||
|
int const originz = centerz - sectioncount / 2;
|
||||||
|
|
||||||
|
auto const squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_SECTIONSIZE + 0.25 * EU07_SECTIONSIZE ) + Radius, 2 ) };
|
||||||
|
|
||||||
|
for( int row = originz; row <= originz + sectioncount; ++row ) {
|
||||||
|
if( row < 0 ) { continue; }
|
||||||
|
if( row >= EU07_REGIONSIDESECTIONCOUNT ) { break; }
|
||||||
|
for( int column = originx; column <= originx + sectioncount; ++column ) {
|
||||||
|
if( column < 0 ) { continue; }
|
||||||
|
if( column >= EU07_REGIONSIDESECTIONCOUNT ) { break; }
|
||||||
|
|
||||||
|
auto *section { m_sections[ row * EU07_REGIONSIDESECTIONCOUNT + column ] };
|
||||||
|
if( ( section != nullptr )
|
||||||
|
&& ( glm::length2( section->area().center - Point ) < squaredradii ) ) {
|
||||||
|
|
||||||
|
m_scratchpad.sections.emplace_back( section );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_scratchpad.sections;
|
||||||
|
}
|
||||||
|
|
||||||
|
// registers specified path in the lookup directory of a cell enclosing specified point
|
||||||
|
void
|
||||||
|
basic_region::register_path( TTrack *Path, glm::dvec3 const &Point ) {
|
||||||
|
|
||||||
|
if( point_inside( Point ) ) {
|
||||||
|
section( Point ).register_end( Path, Point );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// registers specified end point of the provided traction piece in the lookup directory of the region
|
||||||
|
void
|
||||||
|
basic_region::register_traction( TTraction *Traction, glm::dvec3 const &Point ) {
|
||||||
|
|
||||||
|
if( point_inside( Point ) ) {
|
||||||
|
section( Point ).register_end( Traction, Point );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// checks whether specified point is within boundaries of the region
|
// checks whether specified point is within boundaries of the region
|
||||||
bool
|
bool
|
||||||
basic_region::point_inside( glm::dvec3 const &Location ) {
|
basic_region::point_inside( glm::dvec3 const &Location ) {
|
||||||
@@ -566,8 +973,8 @@ basic_region::RaTriangleDivider( shape_node &Shape, std::deque<shape_node> &Shap
|
|||||||
basic_section &
|
basic_section &
|
||||||
basic_region::section( glm::dvec3 const &Location ) {
|
basic_region::section( glm::dvec3 const &Location ) {
|
||||||
|
|
||||||
auto const column = static_cast<int>( std::floor( Location.x / EU07_SECTIONSIZE + EU07_REGIONSIDESECTIONCOUNT / 2 ) );
|
auto const column { static_cast<int>( std::floor( Location.x / EU07_SECTIONSIZE + EU07_REGIONSIDESECTIONCOUNT / 2 ) ) };
|
||||||
auto const row = static_cast<int>( std::floor( Location.z / EU07_SECTIONSIZE + EU07_REGIONSIDESECTIONCOUNT / 2 ) );
|
auto const row { static_cast<int>( std::floor( Location.z / EU07_SECTIONSIZE + EU07_REGIONSIDESECTIONCOUNT / 2 ) ) };
|
||||||
|
|
||||||
auto §ion =
|
auto §ion =
|
||||||
m_sections[
|
m_sections[
|
||||||
|
|||||||
115
scene.h
115
scene.h
@@ -30,6 +30,18 @@ struct scratch_data {
|
|||||||
|
|
||||||
std::stack<glm::dvec3> location_offset;
|
std::stack<glm::dvec3> location_offset;
|
||||||
glm::vec3 location_rotation;
|
glm::vec3 location_rotation;
|
||||||
|
|
||||||
|
struct trainset_data {
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
std::string track;
|
||||||
|
float offset { 0.f };
|
||||||
|
float velocity { 0.f };
|
||||||
|
std::vector<TDynamicObject *> vehicles;
|
||||||
|
std::vector<std::int8_t> couplings;
|
||||||
|
TDynamicObject * driver { nullptr };
|
||||||
|
bool is_open { false };
|
||||||
|
} trainset;
|
||||||
};
|
};
|
||||||
|
|
||||||
// basic element of rudimentary partitioning scheme for the section. fixed size, no further subdivision
|
// basic element of rudimentary partitioning scheme for the section. fixed size, no further subdivision
|
||||||
@@ -40,6 +52,9 @@ class basic_cell {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// methods
|
// methods
|
||||||
|
// legacy method, updates sounds and polls event launchers within radius around specified point
|
||||||
|
void
|
||||||
|
update();
|
||||||
// adds provided shape to the cell
|
// adds provided shape to the cell
|
||||||
void
|
void
|
||||||
insert( shape_node Shape );
|
insert( shape_node Shape );
|
||||||
@@ -52,18 +67,42 @@ public:
|
|||||||
// adds provided model instance to the cell
|
// adds provided model instance to the cell
|
||||||
void
|
void
|
||||||
insert( TAnimModel *Instance );
|
insert( TAnimModel *Instance );
|
||||||
|
// registers provided path in the lookup directory of the cell
|
||||||
|
void
|
||||||
|
register_end( TTrack *Path );
|
||||||
|
// registers provided traction piece in the lookup directory of the cell
|
||||||
|
void
|
||||||
|
register_end( TTraction *Traction );
|
||||||
|
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
||||||
|
std::tuple<TDynamicObject *, float>
|
||||||
|
find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled );
|
||||||
|
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
||||||
|
std::tuple<TTrack *, int>
|
||||||
|
find( glm::dvec3 const &Point, TTrack const *Exclude );
|
||||||
|
// finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint
|
||||||
|
std::tuple<TTraction *, int>
|
||||||
|
find( glm::dvec3 const &Point, TTraction const *Exclude );
|
||||||
|
// finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece
|
||||||
|
std::tuple<TTraction *, int, float>
|
||||||
|
find( glm::dvec3 const &Point, TTraction const *Other, int const Currentdirection );
|
||||||
|
// sets center point of the cell
|
||||||
|
void
|
||||||
|
center( glm::dvec3 Center );
|
||||||
// generates renderable version of held non-instanced geometry in specified geometry bank
|
// generates renderable version of held non-instanced geometry in specified geometry bank
|
||||||
void
|
void
|
||||||
create_geometry( geometrybank_handle const &Bank );
|
create_geometry( geometrybank_handle const &Bank );
|
||||||
// sets center point of the cell
|
// provides access to bounding area data
|
||||||
void
|
bounding_area const &
|
||||||
center( glm::dvec3 Center );
|
area() const {
|
||||||
|
return m_area; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
using shapenode_sequence = std::vector<shape_node>;
|
using shapenode_sequence = std::vector<shape_node>;
|
||||||
using path_sequence = std::vector<TTrack *>;
|
using path_sequence = std::vector<TTrack *>;
|
||||||
|
using path_set = std::set<TTrack *>;
|
||||||
using traction_sequence = std::vector<TTraction *>;
|
using traction_sequence = std::vector<TTraction *>;
|
||||||
|
using traction_set = std::set<TTraction *>;
|
||||||
using instance_sequence = std::vector<TAnimModel *>;
|
using instance_sequence = std::vector<TAnimModel *>;
|
||||||
// members
|
// members
|
||||||
scene::bounding_area m_area { glm::dvec3(), static_cast<float>( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) };
|
scene::bounding_area m_area { glm::dvec3(), static_cast<float>( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) };
|
||||||
@@ -75,6 +114,11 @@ private:
|
|||||||
instance_sequence m_instancesopaque;
|
instance_sequence m_instancesopaque;
|
||||||
instance_sequence m_instancetranslucent;
|
instance_sequence m_instancetranslucent;
|
||||||
traction_sequence m_traction;
|
traction_sequence m_traction;
|
||||||
|
// search helpers
|
||||||
|
struct lookup_data {
|
||||||
|
path_set paths;
|
||||||
|
traction_set traction;
|
||||||
|
} m_directories;
|
||||||
};
|
};
|
||||||
|
|
||||||
// basic scene partitioning structure, holds terrain geometry and collection of cells
|
// basic scene partitioning structure, holds terrain geometry and collection of cells
|
||||||
@@ -84,6 +128,9 @@ class basic_section {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// methods
|
// methods
|
||||||
|
// legacy method, updates sounds and polls event launchers within radius around specified point
|
||||||
|
void
|
||||||
|
update( glm::dvec3 const &Location, float const Radius );
|
||||||
// adds provided shape to the section
|
// adds provided shape to the section
|
||||||
void
|
void
|
||||||
insert( shape_node Shape );
|
insert( shape_node Shape );
|
||||||
@@ -96,12 +143,34 @@ public:
|
|||||||
// adds provided model instance to the section
|
// adds provided model instance to the section
|
||||||
void
|
void
|
||||||
insert( TAnimModel *Instance );
|
insert( TAnimModel *Instance );
|
||||||
// generates renderable version of held non-instanced geometry
|
// registers specified end point of the provided path in the lookup directory of the region
|
||||||
void
|
void
|
||||||
create_geometry();
|
register_end( TTrack *Path, glm::dvec3 const &Point );
|
||||||
|
// registers specified end point of the provided traction piece in the lookup directory of the region
|
||||||
|
void
|
||||||
|
register_end( TTraction *Traction, glm::dvec3 const &Point );
|
||||||
|
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
||||||
|
std::tuple<TDynamicObject *, float>
|
||||||
|
find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled );
|
||||||
|
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
||||||
|
std::tuple<TTrack *, int>
|
||||||
|
find( glm::dvec3 const &Point, TTrack const *Exclude );
|
||||||
|
// finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint
|
||||||
|
std::tuple<TTraction *, int>
|
||||||
|
find( glm::dvec3 const &Point, TTraction const *Exclude );
|
||||||
|
// finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece
|
||||||
|
std::tuple<TTraction *, int, float>
|
||||||
|
find( glm::dvec3 const &Point, TTraction const *Other, int const Currentdirection );
|
||||||
// sets center point of the section
|
// sets center point of the section
|
||||||
void
|
void
|
||||||
center( glm::dvec3 Center );
|
center( glm::dvec3 Center );
|
||||||
|
// generates renderable version of held non-instanced geometry
|
||||||
|
void
|
||||||
|
create_geometry();
|
||||||
|
// provides access to bounding area data
|
||||||
|
bounding_area const &
|
||||||
|
area() const {
|
||||||
|
return m_area; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
@@ -134,6 +203,9 @@ public:
|
|||||||
// destructor
|
// destructor
|
||||||
~basic_region();
|
~basic_region();
|
||||||
// methods
|
// methods
|
||||||
|
// legacy method, updates sounds and polls event launchers around camera
|
||||||
|
void
|
||||||
|
update();
|
||||||
// inserts provided shape in the region
|
// inserts provided shape in the region
|
||||||
void
|
void
|
||||||
insert_shape( shape_node Shape, scratch_data &Scratchpad );
|
insert_shape( shape_node Shape, scratch_data &Scratchpad );
|
||||||
@@ -146,17 +218,45 @@ public:
|
|||||||
// inserts provided instance of 3d model in the region
|
// inserts provided instance of 3d model in the region
|
||||||
void
|
void
|
||||||
insert_instance( TAnimModel *Instance, scratch_data &Scratchpad );
|
insert_instance( TAnimModel *Instance, scratch_data &Scratchpad );
|
||||||
|
// inserts provided sound in the region
|
||||||
|
void
|
||||||
|
insert_sound( TTextSound *Sound, scratch_data &Scratchpad );
|
||||||
|
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
||||||
|
std::tuple<TDynamicObject *, float>
|
||||||
|
find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled );
|
||||||
|
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
||||||
|
std::tuple<TTrack *, int>
|
||||||
|
find_path( glm::dvec3 const &Point, TTrack const *Exclude );
|
||||||
|
// finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint
|
||||||
|
std::tuple<TTraction *, int>
|
||||||
|
find_traction( glm::dvec3 const &Point, TTraction const *Exclude );
|
||||||
|
// finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece
|
||||||
|
std::tuple<TTraction *, int>
|
||||||
|
find_traction( glm::dvec3 const &Point, TTraction const *Other, int const Currentdirection );
|
||||||
|
// finds sections inside specified sphere. returns: list of sections
|
||||||
|
std::vector<basic_section *> const &
|
||||||
|
sections( glm::dvec3 const &Point, float const Radius );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
using section_array = std::array<basic_section *, EU07_REGIONSIDESECTIONCOUNT * EU07_REGIONSIDESECTIONCOUNT>;
|
using section_array = std::array<basic_section *, EU07_REGIONSIDESECTIONCOUNT * EU07_REGIONSIDESECTIONCOUNT>;
|
||||||
|
|
||||||
|
struct region_scratchpad {
|
||||||
|
|
||||||
|
std::vector<basic_section *> sections;
|
||||||
|
};
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
|
// registers specified end point of the provided path in the lookup directory of the region
|
||||||
|
void
|
||||||
|
register_path( TTrack *Path, glm::dvec3 const &Point );
|
||||||
|
// registers specified end point of the provided traction piece in the lookup directory of the region
|
||||||
|
void
|
||||||
|
register_traction( TTraction *Traction, glm::dvec3 const &Point );
|
||||||
// checks whether specified point is within boundaries of the region
|
// checks whether specified point is within boundaries of the region
|
||||||
bool
|
bool
|
||||||
point_inside( glm::dvec3 const &Location );
|
point_inside( glm::dvec3 const &Location );
|
||||||
// trims provided shape to fit into a section, adds trimmed part at the end of provided list
|
// legacy method, trims provided shape to fit into a section. adds trimmed part at the end of provided list, returns true if changes were made
|
||||||
bool
|
bool
|
||||||
RaTriangleDivider( shape_node &Shape, std::deque<shape_node> &Shapes );
|
RaTriangleDivider( shape_node &Shape, std::deque<shape_node> &Shapes );
|
||||||
// provides access to section enclosing specified point
|
// provides access to section enclosing specified point
|
||||||
@@ -165,6 +265,7 @@ private:
|
|||||||
|
|
||||||
// members
|
// members
|
||||||
section_array m_sections;
|
section_array m_sections;
|
||||||
|
region_scratchpad m_scratchpad;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace scene {
|
|||||||
|
|
||||||
// restores content of the node from provded input stream
|
// restores content of the node from provded input stream
|
||||||
shape_node &
|
shape_node &
|
||||||
shape_node::deserialize( cParser &Input, node_data const &Nodedata ) {
|
shape_node::deserialize( cParser &Input, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
// import common data
|
// import common data
|
||||||
m_name = Nodedata.name;
|
m_name = Nodedata.name;
|
||||||
@@ -291,6 +291,5 @@ basic_node::basic_node( scene::node_data const &Nodedata ) :
|
|||||||
std::numeric_limits<double>::max() );
|
std::numeric_limits<double>::max() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // editor
|
} // editor
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
15
scenenode.h
15
scenenode.h
@@ -72,7 +72,7 @@ class node_manager {
|
|||||||
struct node_data {
|
struct node_data {
|
||||||
|
|
||||||
double range_min { 0.0 };
|
double range_min { 0.0 };
|
||||||
double range_max { 0.0 };
|
double range_max { std::numeric_limits<double>::max() };
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string type;
|
std::string type;
|
||||||
};
|
};
|
||||||
@@ -86,7 +86,7 @@ public:
|
|||||||
// types
|
// types
|
||||||
struct shapenode_data {
|
struct shapenode_data {
|
||||||
// placement and visibility
|
// placement and visibility
|
||||||
bounding_area area; // bounding area, in world coordinates
|
scene::bounding_area area; // bounding area, in world coordinates
|
||||||
bool visible { true }; // visibility flag
|
bool visible { true }; // visibility flag
|
||||||
double rangesquared_min { 0.0 }; // visibility range, min
|
double rangesquared_min { 0.0 }; // visibility range, min
|
||||||
double rangesquared_max { 0.0 }; // visibility range, max
|
double rangesquared_max { 0.0 }; // visibility range, max
|
||||||
@@ -103,7 +103,7 @@ public:
|
|||||||
// methods
|
// methods
|
||||||
// restores content of the node from provded input stream
|
// restores content of the node from provded input stream
|
||||||
shape_node &
|
shape_node &
|
||||||
deserialize( cParser &Input, node_data const &Nodedata );
|
deserialize( cParser &Input, scene::node_data const &Nodedata );
|
||||||
// adds content of provided node to already enclosed geometry. returns: true if merge could be performed
|
// adds content of provided node to already enclosed geometry. returns: true if merge could be performed
|
||||||
bool
|
bool
|
||||||
merge( shape_node &Shape );
|
merge( shape_node &Shape );
|
||||||
@@ -229,12 +229,15 @@ public:
|
|||||||
std::string const &
|
std::string const &
|
||||||
name() const {
|
name() const {
|
||||||
return m_name; }
|
return m_name; }
|
||||||
glm::dvec3 const &
|
|
||||||
location() {
|
|
||||||
return m_location; };
|
|
||||||
void
|
void
|
||||||
location( glm::dvec3 const Location ) {
|
location( glm::dvec3 const Location ) {
|
||||||
m_location = Location; }
|
m_location = Location; }
|
||||||
|
glm::dvec3 const &
|
||||||
|
location() const {
|
||||||
|
return m_location; };
|
||||||
|
void
|
||||||
|
visible( bool const Visible ) {
|
||||||
|
m_visible = Visible; }
|
||||||
bool
|
bool
|
||||||
visible() const {
|
visible() const {
|
||||||
return m_visible; }
|
return m_visible; }
|
||||||
|
|||||||
326
simulation.cpp
326
simulation.cpp
@@ -12,15 +12,19 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
|
#include "uilayer.h"
|
||||||
|
|
||||||
namespace simulation {
|
namespace simulation {
|
||||||
|
|
||||||
state_manager State;
|
state_manager State;
|
||||||
event_manager Events;
|
event_manager Events;
|
||||||
memory_manager Memory;
|
memory_table Memory;
|
||||||
path_table Paths;
|
path_table Paths;
|
||||||
traction_table Traction;
|
traction_table Traction;
|
||||||
instance_manager Instances;
|
powergridsource_table Powergrid;
|
||||||
|
sound_table Sounds;
|
||||||
|
instance_table Instances;
|
||||||
|
vehicle_table Vehicles;
|
||||||
light_array Lights;
|
light_array Lights;
|
||||||
|
|
||||||
scene::basic_region *Region { nullptr };
|
scene::basic_region *Region { nullptr };
|
||||||
@@ -44,6 +48,23 @@ state_manager::deserialize( std::string const &Scenariofile ) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
|
void
|
||||||
|
state_manager::update( double const Deltatime, int Iterationcount ) {
|
||||||
|
// aktualizacja animacji krokiem FPS: dt=krok czasu [s], dt*iter=czas od ostatnich przeliczeń
|
||||||
|
if (Deltatime == 0.0) {
|
||||||
|
// jeśli załączona jest pauza, to tylko obsłużyć ruch w kabinie trzeba
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const totaltime { Deltatime * Iterationcount };
|
||||||
|
// NOTE: we perform animations first, as they can determine factors like contact with powergrid
|
||||||
|
TAnimModel::AnimUpdate( totaltime ); // wykonanie zakolejkowanych animacji
|
||||||
|
|
||||||
|
simulation::Powergrid.update( totaltime );
|
||||||
|
simulation::Vehicles.update( Deltatime, Iterationcount );
|
||||||
|
}
|
||||||
|
|
||||||
// restores class data from provided stream
|
// restores class data from provided stream
|
||||||
void
|
void
|
||||||
state_manager::deserialize( cParser &Input ) {
|
state_manager::deserialize( cParser &Input ) {
|
||||||
@@ -79,7 +100,11 @@ state_manager::deserialize( cParser &Input ) {
|
|||||||
for( auto &function : functionlist ) {
|
for( auto &function : functionlist ) {
|
||||||
functionmap.emplace( function.first, std::bind( function.second, this, std::ref( Input ), std::ref( importscratchpad ) ) );
|
functionmap.emplace( function.first, std::bind( function.second, this, std::ref( Input ), std::ref( importscratchpad ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// deserialize content from the provided input
|
// deserialize content from the provided input
|
||||||
|
auto
|
||||||
|
timelast { std::chrono::steady_clock::now() },
|
||||||
|
timenow { timelast };
|
||||||
std::string token { Input.getToken<std::string>() };
|
std::string token { Input.getToken<std::string>() };
|
||||||
while( false == token.empty() ) {
|
while( false == token.empty() ) {
|
||||||
|
|
||||||
@@ -91,6 +116,14 @@ state_manager::deserialize( cParser &Input ) {
|
|||||||
ErrorLog( "Bad scenario: unexpected token \"" + token + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" );
|
ErrorLog( "Bad scenario: unexpected token \"" + token + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timenow = std::chrono::steady_clock::now();
|
||||||
|
if( std::chrono::duration_cast<std::chrono::milliseconds>( timenow - timelast ).count() >= 200 ) {
|
||||||
|
timelast = timenow;
|
||||||
|
glfwPollEvents();
|
||||||
|
UILayer.set_progress( Input.getProgress(), Input.getFullProgress() );
|
||||||
|
GfxRenderer.Render();
|
||||||
|
}
|
||||||
|
|
||||||
token = Input.getToken<std::string>();
|
token = Input.getToken<std::string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,6 +251,7 @@ state_manager::deserialize_firstinit( cParser &Input, scene::scratch_data &Scrat
|
|||||||
simulation::Paths.InitTracks();
|
simulation::Paths.InitTracks();
|
||||||
simulation::Traction.InitTraction();
|
simulation::Traction.InitTraction();
|
||||||
simulation::Events.InitEvents();
|
simulation::Events.InitEvents();
|
||||||
|
simulation::Memory.InitCells();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -230,6 +264,8 @@ state_manager::deserialize_light( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
void
|
void
|
||||||
state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
|
auto const inputline = Input.Line(); // cache in case we need to report error
|
||||||
|
|
||||||
scene::node_data nodedata;
|
scene::node_data nodedata;
|
||||||
// common data and node type indicator
|
// common data and node type indicator
|
||||||
Input.getTokens( 4 );
|
Input.getTokens( 4 );
|
||||||
@@ -240,13 +276,27 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
>> nodedata.type;
|
>> nodedata.type;
|
||||||
// type-based deserialization. not elegant but it'll do
|
// type-based deserialization. not elegant but it'll do
|
||||||
if( nodedata.type == "dynamic" ) {
|
if( nodedata.type == "dynamic" ) {
|
||||||
// TODO: implement
|
|
||||||
skip_until( Input, "enddynamic" );
|
auto *vehicle { deserialize_dynamic( Input, Scratchpad, nodedata ) };
|
||||||
|
// vehicle import can potentially fail
|
||||||
|
if( vehicle == nullptr ) { return; }
|
||||||
|
|
||||||
|
if( false == simulation::Vehicles.insert( vehicle ) ) {
|
||||||
|
|
||||||
|
ErrorLog( "Bad scenario: vehicle with duplicate name, \"" + vehicle->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( vehicle->MoverParameters->CategoryFlag == 1 ) // trains only
|
||||||
|
&& ( ( vehicle->MoverParameters->SecuritySystem.SystemType != 0 )
|
||||||
|
|| ( vehicle->MoverParameters->SandCapacity > 0.0 ) ) ) {
|
||||||
|
// we check for presence of security system or sand load, as a way to determine whether the vehicle is a controllable engine
|
||||||
|
// NOTE: this isn't 100% precise, e.g. middle EZT module comes with security system, while it has no lights, and some engines
|
||||||
|
// don't have security systems fitted
|
||||||
|
simulation::Lights.insert( vehicle );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "track" ) {
|
else if( nodedata.type == "track" ) {
|
||||||
|
|
||||||
auto const inputline = Input.Line(); // cache in case we need to report error
|
|
||||||
|
|
||||||
auto *path { deserialize_path( Input, Scratchpad, nodedata ) };
|
auto *path { deserialize_path( Input, Scratchpad, nodedata ) };
|
||||||
// duplicates of named tracks are currently experimentally allowed
|
// duplicates of named tracks are currently experimentally allowed
|
||||||
if( simulation::Paths.insert( path ) ) {
|
if( simulation::Paths.insert( path ) ) {
|
||||||
@@ -262,10 +312,10 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
}
|
}
|
||||||
else if( nodedata.type == "traction" ) {
|
else if( nodedata.type == "traction" ) {
|
||||||
|
|
||||||
auto const inputline = Input.Line(); // cache in case we need to report error
|
|
||||||
|
|
||||||
auto *traction { deserialize_traction( Input, Scratchpad, nodedata ) };
|
auto *traction { deserialize_traction( Input, Scratchpad, nodedata ) };
|
||||||
// duplicates of named tracks are currently discarded
|
// traction loading is optional
|
||||||
|
if( traction == nullptr ) { return; }
|
||||||
|
|
||||||
if( simulation::Traction.insert( traction ) ) {
|
if( simulation::Traction.insert( traction ) ) {
|
||||||
simulation::Region->insert_traction( traction, Scratchpad );
|
simulation::Region->insert_traction( traction, Scratchpad );
|
||||||
}
|
}
|
||||||
@@ -274,18 +324,29 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "tractionpowersource" ) {
|
else if( nodedata.type == "tractionpowersource" ) {
|
||||||
// TODO: implement
|
|
||||||
skip_until( Input, "end" );
|
auto *powersource { deserialize_tractionpowersource( Input, Scratchpad, nodedata ) };
|
||||||
|
// traction loading is optional
|
||||||
|
if( powersource == nullptr ) { return; }
|
||||||
|
|
||||||
|
if( simulation::Powergrid.insert( powersource ) ) {
|
||||||
|
/*
|
||||||
|
// TODO: implement this
|
||||||
|
simulation::Region.insert_powersource( powersource, Scratchpad );
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog( "Bad scenario: power grid source with duplicate name, \"" + powersource->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "model" ) {
|
else if( nodedata.type == "model" ) {
|
||||||
|
|
||||||
if( nodedata.range_min < 0.0 ) {
|
if( nodedata.range_min < 0.0 ) {
|
||||||
// convert and import 3d terrain
|
// convert and import 3d terrain
|
||||||
|
// TODO: implement this
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// regular instance of 3d mesh
|
// regular instance of 3d mesh
|
||||||
auto const inputline = Input.Line(); // cache in case we need to report error
|
|
||||||
|
|
||||||
auto *instance { deserialize_model( Input, Scratchpad, nodedata ) };
|
auto *instance { deserialize_model( Input, Scratchpad, nodedata ) };
|
||||||
// model import can potentially fail
|
// model import can potentially fail
|
||||||
if( instance == nullptr ) { return; }
|
if( instance == nullptr ) { return; }
|
||||||
@@ -313,10 +374,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
}
|
}
|
||||||
else if( nodedata.type == "memcell" ) {
|
else if( nodedata.type == "memcell" ) {
|
||||||
|
|
||||||
auto const inputline = Input.Line(); // cache in case we need to report error
|
|
||||||
|
|
||||||
auto *memorycell { deserialize_memorycell( Input, Scratchpad, nodedata ) };
|
auto *memorycell { deserialize_memorycell( Input, Scratchpad, nodedata ) };
|
||||||
// duplicates of named tracks are currently discarded
|
|
||||||
if( simulation::Memory.insert( memorycell ) ) {
|
if( simulation::Memory.insert( memorycell ) ) {
|
||||||
/*
|
/*
|
||||||
// TODO: implement this
|
// TODO: implement this
|
||||||
@@ -325,10 +383,6 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad scenario: memory cell with duplicate name, \"" + memorycell->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
ErrorLog( "Bad scenario: memory cell with duplicate name, \"" + memorycell->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
/*
|
|
||||||
delete memorycell;
|
|
||||||
delete memorycellnode;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "eventlauncher" ) {
|
else if( nodedata.type == "eventlauncher" ) {
|
||||||
@@ -336,8 +390,14 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
skip_until( Input, "end" );
|
skip_until( Input, "end" );
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "sound" ) {
|
else if( nodedata.type == "sound" ) {
|
||||||
// TODO: implement
|
|
||||||
skip_until( Input, "endsound" );
|
auto *sound { deserialize_sound( Input, Scratchpad, nodedata ) };
|
||||||
|
if( simulation::Sounds.insert( sound ) ) {
|
||||||
|
simulation::Region->insert_sound( sound, Scratchpad );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog( "Bad scenario: sound node with duplicate name, \"" + sound->m_name + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -417,14 +477,68 @@ state_manager::deserialize_time( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
void
|
void
|
||||||
state_manager::deserialize_trainset( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_manager::deserialize_trainset( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// TODO: implement
|
if( true == Scratchpad.trainset.is_open ) {
|
||||||
skip_until( Input, "endtrainset" );
|
// shouldn't happen but if it does wrap up currently open trainset and report an error
|
||||||
|
deserialize_endtrainset( Input, Scratchpad );
|
||||||
|
ErrorLog( "Bad scenario: encountered nested trainset definitions in file \"" + Input.Name() + "\" (line " + to_string( Input.Line() ) + ")" );
|
||||||
|
}
|
||||||
|
|
||||||
|
Scratchpad.trainset = scene::scratch_data::trainset_data();
|
||||||
|
Scratchpad.trainset.is_open = true;
|
||||||
|
|
||||||
|
Input.getTokens( 4 );
|
||||||
|
Input
|
||||||
|
>> Scratchpad.trainset.name
|
||||||
|
>> Scratchpad.trainset.track
|
||||||
|
>> Scratchpad.trainset.offset
|
||||||
|
>> Scratchpad.trainset.velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_endtrainset( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_manager::deserialize_endtrainset( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// TODO: implement
|
if( ( false == Scratchpad.trainset.is_open )
|
||||||
|
|| ( true == Scratchpad.trainset.vehicles.empty() ) ) {
|
||||||
|
// not bloody likely but we better check for it just the same
|
||||||
|
ErrorLog( "Bad trainset: empty trainset defined in file \"" + Input.Name() + "\" (line " + to_string( Input.Line() - 1 ) + ")" );
|
||||||
|
Scratchpad.trainset.is_open = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t vehicleindex { 0 };
|
||||||
|
for( auto *vehicle : Scratchpad.trainset.vehicles ) {
|
||||||
|
// go through list of vehicles in the trainset, coupling them together and checking for potential driver
|
||||||
|
if( ( vehicle->Mechanik != nullptr )
|
||||||
|
&& ( vehicle->Mechanik->Primary() ) ) {
|
||||||
|
// primary driver will receive the timetable for this trainset
|
||||||
|
Scratchpad.trainset.driver = vehicle;
|
||||||
|
}
|
||||||
|
if( vehicleindex > 0 ) {
|
||||||
|
// from second vehicle on couple it with the previous one
|
||||||
|
Scratchpad.trainset.vehicles[ vehicleindex - 1 ]->AttachPrev(
|
||||||
|
vehicle,
|
||||||
|
Scratchpad.trainset.couplings[ vehicleindex - 1 ] );
|
||||||
|
}
|
||||||
|
++vehicleindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Scratchpad.trainset.driver != nullptr ) {
|
||||||
|
// if present, send timetable to the driver
|
||||||
|
// wysłanie komendy "Timetable" ustawia odpowiedni tryb jazdy
|
||||||
|
auto *controller = Scratchpad.trainset.driver->Mechanik;
|
||||||
|
controller->DirectionInitial();
|
||||||
|
controller->PutCommand(
|
||||||
|
"Timetable:" + Scratchpad.trainset.name,
|
||||||
|
Scratchpad.trainset.velocity,
|
||||||
|
0,
|
||||||
|
nullptr );
|
||||||
|
}
|
||||||
|
if( Scratchpad.trainset.couplings.back() == coupling::faux ) {
|
||||||
|
// jeśli ostatni pojazd ma sprzęg 0 to założymy mu końcówki blaszane (jak AI się odpali, to sobie poprawi)
|
||||||
|
Scratchpad.trainset.vehicles.back()->RaLightsSet( -1, TMoverParameters::light::rearendsignals );
|
||||||
|
}
|
||||||
|
// all done
|
||||||
|
Scratchpad.trainset.is_open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates path and its wrapper, restoring class data from provided stream
|
// creates path and its wrapper, restoring class data from provided stream
|
||||||
@@ -448,6 +562,10 @@ state_manager::deserialize_path( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
TTraction *
|
TTraction *
|
||||||
state_manager::deserialize_traction( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_manager::deserialize_traction( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
|
if( false == Global::bLoadTraction ) {
|
||||||
|
skip_until( Input, "endtraction" );
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
// TODO: refactor track and wrapper classes and their de/serialization. do offset and rotation after deserialization is done
|
// TODO: refactor track and wrapper classes and their de/serialization. do offset and rotation after deserialization is done
|
||||||
auto *traction = new TTraction( Nodedata );
|
auto *traction = new TTraction( Nodedata );
|
||||||
auto offset = (
|
auto offset = (
|
||||||
@@ -459,6 +577,22 @@ state_manager::deserialize_traction( cParser &Input, scene::scratch_data &Scratc
|
|||||||
return traction;
|
return traction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TTractionPowerSource *
|
||||||
|
state_manager::deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
|
if( false == Global::bLoadTraction ) {
|
||||||
|
skip_until( Input, "end" );
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *powersource = new TTractionPowerSource( Nodedata );
|
||||||
|
powersource->Load( &Input );
|
||||||
|
// adjust location
|
||||||
|
powersource->location( transform( powersource->location(), Scratchpad ) );
|
||||||
|
|
||||||
|
return powersource;
|
||||||
|
}
|
||||||
|
|
||||||
TMemCell *
|
TMemCell *
|
||||||
state_manager::deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_manager::deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
@@ -481,7 +615,6 @@ state_manager::deserialize_model( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
>> location.y
|
>> location.y
|
||||||
>> location.z
|
>> location.z
|
||||||
>> rotation.y;
|
>> rotation.y;
|
||||||
// adjust location
|
|
||||||
|
|
||||||
auto *instance = new TAnimModel( Nodedata );
|
auto *instance = new TAnimModel( Nodedata );
|
||||||
instance->RaAnglesSet( Scratchpad.location_rotation + rotation ); // dostosowanie do pochylania linii
|
instance->RaAnglesSet( Scratchpad.location_rotation + rotation ); // dostosowanie do pochylania linii
|
||||||
@@ -495,6 +628,147 @@ state_manager::deserialize_model( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TDynamicObject *
|
||||||
|
state_manager::deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
|
if( false == Scratchpad.trainset.is_open ) {
|
||||||
|
// part of trainset data is used when loading standalone vehicles, so clear it just in case
|
||||||
|
Scratchpad.trainset = scene::scratch_data::trainset_data();
|
||||||
|
}
|
||||||
|
auto const inputline { Input.Line() }; // cache in case of errors
|
||||||
|
// basic attributes
|
||||||
|
auto const datafolder { Input.getToken<std::string>() };
|
||||||
|
auto const skinfile { Input.getToken<std::string>() };
|
||||||
|
auto const mmdfile { Input.getToken<std::string>() };
|
||||||
|
auto const pathname = (
|
||||||
|
Scratchpad.trainset.is_open ?
|
||||||
|
Scratchpad.trainset.track :
|
||||||
|
Input.getToken<std::string>() );
|
||||||
|
auto const offset { Input.getToken<double>( false ) };
|
||||||
|
auto const drivertype { Input.getToken<std::string>() };
|
||||||
|
auto const couplingparams = (
|
||||||
|
Scratchpad.trainset.is_open ?
|
||||||
|
Input.getToken<std::string>() :
|
||||||
|
"3" );
|
||||||
|
auto const velocity = (
|
||||||
|
Scratchpad.trainset.is_open ?
|
||||||
|
Scratchpad.trainset.velocity :
|
||||||
|
Input.getToken<float>( false ) );
|
||||||
|
// extract coupling type and optional parameters
|
||||||
|
auto const couplingparamsplit = couplingparams.find( '.' );
|
||||||
|
auto coupling = (
|
||||||
|
couplingparamsplit != std::string::npos ?
|
||||||
|
std::atoi( couplingparams.substr( 0, couplingparamsplit ).c_str() ) :
|
||||||
|
std::atoi( couplingparams.c_str() ) );
|
||||||
|
if( coupling < 0 ) {
|
||||||
|
// sprzęg zablokowany (pojazdy nierozłączalne przy manewrach)
|
||||||
|
coupling = ( -coupling ) | coupling::permanent;
|
||||||
|
}
|
||||||
|
if( ( offset != -1.0 )
|
||||||
|
&& ( std::abs( offset ) > 0.5 ) ) { // maksymalna odległość między sprzęgami - do przemyślenia
|
||||||
|
// likwidacja sprzęgu, jeśli odległość zbyt duża - to powinno być uwzględniane w fizyce sprzęgów...
|
||||||
|
coupling = 0;
|
||||||
|
}
|
||||||
|
auto const params = (
|
||||||
|
couplingparamsplit != std::string::npos ?
|
||||||
|
couplingparams.substr( couplingparamsplit + 1 ) :
|
||||||
|
"" );
|
||||||
|
// load amount and type
|
||||||
|
auto loadcount { Input.getToken<int>( false ) };
|
||||||
|
auto loadtype = (
|
||||||
|
loadcount ?
|
||||||
|
Input.getToken<std::string>() :
|
||||||
|
"" );
|
||||||
|
if( loadtype == "enddynamic" ) {
|
||||||
|
// idiotoodporność: ładunek bez podanego typu nie liczy się jako ładunek
|
||||||
|
loadcount = 0;
|
||||||
|
loadtype = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *path = simulation::Paths.find( pathname );
|
||||||
|
if( path == nullptr ) {
|
||||||
|
|
||||||
|
ErrorLog( "Bad scenario: vehicle \"" + Nodedata.name + "\" placed on nonexistent path \"" + pathname + "\" in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
|
skip_until( Input, "enddynamic" );
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( true == Scratchpad.trainset.vehicles.empty() ) // jeśli pierwszy pojazd,
|
||||||
|
&& ( false == path->asEvent0Name.empty() ) // tor ma Event0
|
||||||
|
&& ( std::abs( velocity ) <= 1.f ) // a skład stoi
|
||||||
|
&& ( Scratchpad.trainset.offset >= 0.0 ) // ale może nie sięgać na owy tor
|
||||||
|
&& ( Scratchpad.trainset.offset < 8.0 ) ) { // i raczej nie sięga
|
||||||
|
// przesuwamy około pół EU07 dla wstecznej zgodności
|
||||||
|
Scratchpad.trainset.offset = 8.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *vehicle = new TDynamicObject();
|
||||||
|
|
||||||
|
auto const length =
|
||||||
|
vehicle->Init(
|
||||||
|
Nodedata.name,
|
||||||
|
datafolder, skinfile, mmdfile,
|
||||||
|
path,
|
||||||
|
( offset == -1.0 ?
|
||||||
|
Scratchpad.trainset.offset :
|
||||||
|
Scratchpad.trainset.offset - offset ),
|
||||||
|
drivertype,
|
||||||
|
velocity,
|
||||||
|
Scratchpad.trainset.name,
|
||||||
|
loadcount, loadtype,
|
||||||
|
( offset == -1.0 ),
|
||||||
|
params );
|
||||||
|
|
||||||
|
if( length != 0.0 ) { // zero oznacza błąd
|
||||||
|
// przesunięcie dla kolejnego, minus bo idziemy w stronę punktu 1
|
||||||
|
Scratchpad.trainset.offset -= length;
|
||||||
|
// automatically establish permanent connections for couplers which specify them in their definitions
|
||||||
|
if( ( coupling != 0 )
|
||||||
|
&& ( vehicle->MoverParameters->Couplers[ ( offset == -1.0 ? 0 : 1 ) ].AllowedFlag & coupling::permanent ) ) {
|
||||||
|
coupling |= coupling::permanent;
|
||||||
|
}
|
||||||
|
if( true == Scratchpad.trainset.is_open ) {
|
||||||
|
Scratchpad.trainset.vehicles.emplace_back( vehicle );
|
||||||
|
Scratchpad.trainset.couplings.emplace_back( coupling );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete vehicle;
|
||||||
|
skip_until( Input, "enddynamic" );
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const destination { Input.getToken<std::string>() };
|
||||||
|
if( destination != "enddynamic" ) {
|
||||||
|
// optional vehicle destination parameter
|
||||||
|
vehicle->asDestination = Input.getToken<std::string>();
|
||||||
|
skip_until( Input, "enddynamic" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return vehicle;
|
||||||
|
}
|
||||||
|
|
||||||
|
TTextSound *
|
||||||
|
state_manager::deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
|
glm::dvec3 location;
|
||||||
|
Input.getTokens( 3 );
|
||||||
|
Input
|
||||||
|
>> location.x
|
||||||
|
>> location.y
|
||||||
|
>> location.z;
|
||||||
|
// adjust location
|
||||||
|
location = transform( location, Scratchpad );
|
||||||
|
|
||||||
|
auto const soundname { Input.getToken<std::string>() };
|
||||||
|
auto *sound = new TTextSound( soundname, Nodedata.range_max, location.x, location.y, location.z, false, false, Nodedata.range_min );
|
||||||
|
sound->name( Nodedata.name );
|
||||||
|
|
||||||
|
skip_until( Input, "endsound" );
|
||||||
|
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
// skips content of stream until specified token
|
// skips content of stream until specified token
|
||||||
void
|
void
|
||||||
state_manager::skip_until( cParser &Input, std::string const &Token ) {
|
state_manager::skip_until( cParser &Input, std::string const &Token ) {
|
||||||
|
|||||||
21
simulation.h
21
simulation.h
@@ -9,14 +9,18 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "parser.h"
|
||||||
|
#include "scene.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "memcell.h"
|
#include "memcell.h"
|
||||||
#include "track.h"
|
#include "track.h"
|
||||||
#include "traction.h"
|
#include "traction.h"
|
||||||
|
#include "tractionpower.h"
|
||||||
|
#include "realsound.h"
|
||||||
#include "animmodel.h"
|
#include "animmodel.h"
|
||||||
#include "scene.h"
|
#include "dynobj.h"
|
||||||
|
#include "driver.h"
|
||||||
#include "lightarray.h"
|
#include "lightarray.h"
|
||||||
#include "parser.h"
|
|
||||||
|
|
||||||
namespace simulation {
|
namespace simulation {
|
||||||
|
|
||||||
@@ -26,6 +30,9 @@ public:
|
|||||||
// types
|
// types
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
|
void
|
||||||
|
update( double dt, int iter );
|
||||||
bool
|
bool
|
||||||
deserialize( std::string const &Scenariofile );
|
deserialize( std::string const &Scenariofile );
|
||||||
|
|
||||||
@@ -51,8 +58,11 @@ private:
|
|||||||
void deserialize_endtrainset( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_endtrainset( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
TTrack * deserialize_path( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TTrack * deserialize_path( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TTraction * deserialize_traction( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TTraction * deserialize_traction( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
|
TTractionPowerSource * deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TMemCell * deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TMemCell * deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
|
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
|
TTextSound * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
// skips content of stream until specified token
|
// skips content of stream until specified token
|
||||||
void skip_until( cParser &Input, std::string const &Token );
|
void skip_until( cParser &Input, std::string const &Token );
|
||||||
// transforms provided location by specifed rotation and offset
|
// transforms provided location by specifed rotation and offset
|
||||||
@@ -61,10 +71,13 @@ private:
|
|||||||
|
|
||||||
extern state_manager State;
|
extern state_manager State;
|
||||||
extern event_manager Events;
|
extern event_manager Events;
|
||||||
extern memory_manager Memory;
|
extern memory_table Memory;
|
||||||
extern path_table Paths;
|
extern path_table Paths;
|
||||||
extern traction_table Traction;
|
extern traction_table Traction;
|
||||||
extern instance_manager Instances;
|
extern powergridsource_table Powergrid;
|
||||||
|
extern sound_table Sounds;
|
||||||
|
extern instance_table Instances;
|
||||||
|
extern vehicle_table Vehicles;
|
||||||
extern light_array Lights;
|
extern light_array Lights;
|
||||||
|
|
||||||
extern scene::basic_region *Region;
|
extern scene::basic_region *Region;
|
||||||
|
|||||||
Reference in New Issue
Block a user